當(dāng)前位置:首頁 > 電源 > 數(shù)字電源
[導(dǎo)讀]■前言在上一講中我們講述的是如何制作JAVA手機多媒體功能中的動畫,本講中我們將介紹如何制作JAVA手機的另一個多媒體功能——聲音,即N800的音樂播放功能。若是在動畫上再配以音樂播放功能,就能制作出具

■前言

在上一講中我們講述的是如何制作JAVA手機多媒體功能中的動畫,本講中我們將介紹如何制作JAVA手機的另一個多媒體功能——聲音,即N800的音樂播放功能。若是在動畫上再配以音樂播放功能,就能制作出具有豐富表現(xiàn)力的應(yīng)用程序了。

■音樂播放

現(xiàn)在我們利用MIDP應(yīng)用程序播放音樂。但是,MIDP標(biāo)準API不支持聲音播放功能。機種不同,則聲音播放方法也不同,所以每個廠商都會使用他們各自擴展的API。N800使用NEC擴展的API,所以能用MIDP應(yīng)用程序播放聲音。

■N800的音樂播放功能

N800只能播放SMF(format0)格式的音樂數(shù)據(jù),最大文件尺寸為10Kbyte。SMF格式即StandardMIDIFile的縮略語,就是為了能實現(xiàn)互換性而設(shè)定的文件形式,互換性是指在不同的應(yīng)用程序中也具有能處理數(shù)據(jù)的特性。SMF分為format0和format1兩種格式。N800所采用的是format0格式。這兩種格式具有以下不同特點。(表1)

表1

■播放音樂

接下來我們實際操作讀取文件播放音樂的功能。

●音樂數(shù)據(jù)的讀取

利用擴展API上的Media類的static方法讀取音樂數(shù)據(jù)。自變量中記述了音樂數(shù)據(jù)文件的通過。AudioClipaudio=Media.getAudioClip(“/test.mid”);

另外,能夠從web上獲得音樂數(shù),并且能夠從RMS中得到音樂數(shù)據(jù)。但,由于形式相同,這里就不特別講述了。詳細情況請參考擴展API文檔。

●播放

播放讀取的音樂數(shù)據(jù)。使用AudioClip例子(在這稱為audio)play方法播放。

audio.play();

而且也能同時播放兩個以上的音樂數(shù)據(jù)。此時,使用AudioClip例子(在這稱為audio1、audio2)play方法播放。

audio1.play();

audio2.play();

上述情況下能夠同時播放audio1,audio2。

●停止

能夠暫停音樂的播放。使用AudioClip例子的stop方法能夠停止。

audio.stop();

●其他功能

AudioClip定義了讀取其他音樂數(shù)據(jù)信息的方法和決定反復(fù)播放次數(shù)的方法。(表2)

表2

■音頻事件

音頻演奏過程中,演奏開始時、停止時、結(jié)束時都會發(fā)生音頻事件,能定義此時的處理。要定義音頻事件發(fā)生時的處理,有必要安裝AudioListener接口和記述audioAction方法內(nèi)的處理。

然后,使用AudioClip對象的addAudioListener方法進入AudioListener。

publicclassAudioTestimplementsAudioListener{

/**

*構(gòu)造函數(shù)

**/

publicAudioTest(){

AudioClipaudio=Media.getAudioClip("/test.mid");//讀取音樂數(shù)據(jù)

audio.addAudioListener(this);//注冊audio事務(wù)監(jiān)聽器

}

/**

*音頻事件的處理

**/

publicvoidaudioAction(AudioClipsound,intevent,intparam){

//記述處理

}

}

ex.1

記述處理的audioAction方法的自變量如下所示。

表3

此外,事件的種類(audioAction方法的自變量、事件)在AudioListener接口文件夾中定義如下。(表4)

表4

以下展示的是只播放音頻數(shù)據(jù)的簡單范例。

importjavax.microedition.lcdui.Display;

importjavax.microedition.midlet.MIDlet;

importjavax.microedition.midlet.MIDletStateChangeException;

/**

*音樂播放的簡單范例

*/

publicclassAudioextendsMIDlet{

Displaydisplay;

AudioCanvascanvas;

/**

*構(gòu)造函數(shù)

*/

publicAudio(){

canvas=newAudioCanvas();

display=Display.getDisplay(this);

}

protectedvoidstartApp()throwsMIDletStateChangeException{

display.setCurrent(canvas);

}

protectedvoidpauseApp(){}

protectedvoiddestroyApp(booleanarg0)throwsMIDletStateChangeException{}

}

importjavax.microedition.lcdui.*;

importcom.nec.media.*;

/**

*音頻canvas

**/

publicclassAudioCanvas

extendsCanvas

implementsRunnable,CommandListener,AudioListener{

CommandSTART=newCommand("play",Command.OK,0);

CommandSTOP=newCommand("stop",Command.OK,0);

AudioClipa;//音樂數(shù)據(jù)

Threadth;

/**

*構(gòu)造函數(shù)

**/

publicAudioCanvas(){

a=Media.getAudioClip("/_test.mid");//讀取音樂數(shù)據(jù)

a.addAudioListener(this);//注冊AudioListener

this.addCommand(START);

this.addCommand(STOP);

this.setCommandListener(this);

th=newThread(this);

th.start();

}

/**

*音頻事件的處理

*/

publicvoidaudioAction(AudioClipsound,intevent,intparam){

if(sound==a){

if(event==AudioListener.AUDIO_COMPLETE){

sound.play();

}

}[!--empirenews.page--]

}

/**

*描繪處理

*/

protectedvoidpaint(Graphicsg){

g.setColor(255,255,255);

g.fillRect(0,0,getHeight(),getWidth());

g.setColor(0,0,0);

g.drawString("MusicPlay?",50,52,Graphics.TOP|Graphics.LEFT);

g.drawString(

"channel="+a.getChannel(),

30,

64,

Graphics.TOP|Graphics.LEFT);

g.drawString(

"lapsedtime="+a.getLapsedTime(),

30,

76,

Graphics.TOP|Graphics.LEFT);

g.drawString(

"tempo="+a.getTempo(),

30,

88,

Graphics.TOP|Graphics.LEFT);

g.drawString(

"time="+a.getTime(),

30,

100,

Graphics.TOP|Graphics.LEFT);

}

/**

*命令事件的處理

*/

publicvoidcommandAction(Commandc,Displayabled){

System.out.println("test");

if(c.equals(START)){

a.play();

}elseif(c.equals(STOP)){

a.stop();

}

}

/**

*線程的處理

*刷新查看

*/

publicvoidrun(){

while(true){

repaint();

try{

Thread.sleep(500);

}catch(Exceptione){

}

}

}

}

ex.2

接受表示音樂播放結(jié)束的事件后,根據(jù)明確的開始播放音樂菜單可以無限循環(huán)地播放音樂。下面的演示詳細記述了上述例子中的audioAction方法,能夠?qū)崿F(xiàn)無限循環(huán)播放。(ex.3)

/**

*音頻事件的處理

*/

publicvoidaudioAction(AudioClipsound,intevent,intparam){

if(sound==a){

if(event==AudioListener.AUDIO_COMPLETE){

sound.play();

}

}

}

ex.3

制作應(yīng)用程序

接下來制作實際的發(fā)聲應(yīng)用程序。

本講中制作的是簡單的“泡泡龍”游戲。

■游戲方法

移動小棒接住反彈的球使其不掉下去,使上方的彩球逐漸消失的游戲。彩球完全消失并清除后,球再落下則此游戲通過。

■準備工作

準備游戲必備的圖片和音效。

準備以下圖片。

圖1球的圖片

圖2小棒的圖片

圖3彩球的圖片

·背景音樂(bgm.mid)

·球反彈時的音效(ball.mid)

·彩球破碎時的音效(block.mid)

■設(shè)計

以下是狀態(tài)連接圖(図4)

本講中為了簡單化,在啟動應(yīng)用程序的同時立刻就啟動游戲。形成游戲開始、球落下后游戲結(jié)束、全部清除彩球后游戲過關(guān)。

Figure4

■制作應(yīng)用程序

現(xiàn)在我們按照以下順序制作應(yīng)用程序。

1.類結(jié)構(gòu)

2.變量、常量的定義

3.查看圖片和音效

4.使圖片運動

5.球的反彈

6.音樂的播放

1.類結(jié)構(gòu)

下表內(nèi)容是類結(jié)構(gòu)。(表5)

表5

2.變量、常量的定義

將下面的應(yīng)用變量、定量作為BlockCanvas例子的屬性并定義。(ex.4)

//狀態(tài)設(shè)定

privateintstate;//狀態(tài)

privatefinalintACTIVE=1;

privatefinalintGAME_OVER=2;

privatefinalintCLEAR=3;

//彩球的設(shè)定

privatefinalintBLOCK_H=7;//彩球橫向的個數(shù)

privatefinalintBLOCK_V=5;//彩球縱向的個數(shù)

privatefinalintBLOCK_WIDTH=getWidth()/BLOCK_H;

privatefinalintBLOCK_HEIGHT=BLOCK_WIDTH/2;

privatebooleanblock[][]=newboolean[BLOCK_H][BLOCK_V];

privateintblockCount;//彩球個數(shù)

//小棒的設(shè)定

privatefinalintBAR_HEIGHT=11;

privatefinalintBAR_WIDTH=23;

privateintbarX=0;

privateintbarY=getHeight()-BAR_HEIGHT;

privateintbarMovCodeExample=0;

//球的設(shè)定

privatefinalintBALL_HEIGHT=10;

privatefinalintBALL_WIDTH=10;

privateintballX;

privateintballY;

privateintballMovCodeExample=5;

privateintballMoveY=5;

privateThreadth;

//畫面類

privateImagebarImg=null;

privateImageballImg=null;

privateImageblockImg=null;

//音效類

privateAudioClipbgm;//Backgroundmusic

privateAudioClipballSound;//Soundofbouncingball

privateAudioClipblockSound;//Soundofdestroyingblocks

ex.4

3.查看圖片和音效

查看準備好的圖片和音效。BlockCanvas的構(gòu)造函數(shù)內(nèi)分別讀取小棒、球、彩球的圖片。(ex.5)

//讀取圖片

try{

barImg=Image.createImage("/bar.png");

ballImg=Image.createImage("/ball.png");

blockImg=Image.createImage("/block.png");

}catch(CodeExampleceptione){

e.printStackTrace();

}

ex.5

能查看讀取后的圖片。

彩球在圖中的分配為橫7縱5,讀取彩球圖片并描畫在畫面中。用旗表示彩球的狀態(tài)。保持原來的排列。將一個一個的彩球使用原來的排列并計算出坐標(biāo),安排在畫面中。(ex.6)

//查看彩球

g.setColor(0,0,255);

for(inti=0;i

for(intj=0;j[!--empirenews.page--]

if(block[i][j]){

g.drawImage(

blockImg,

i*BLOCK_WIDTH,

(j+1)*BLOCK_HEIGHT,

Graphics.LEFT|Graphics.TOP);

}

}

}

ex.6

接著查看球和小棒。在paint方法中有以下敘述。(ex.7)

//查看球

g.drawImage(ballImg,ballX,ballY,Graphics.LEFT|Graphics.TOP);

//查看小棒

g.drawImage(barImg,barX,barY,Graphics.LEFT|Graphics.TOP);

ex.7

圖片安裝完成后出現(xiàn)如下畫面。

4.使圖片運動

接下來使用線程和按鍵事件移動球和小棒。為了使用線程就得在AudioCanvas類中安裝Runnable接口、記述run方法。使用球和小棒定義的移動速度分別變化球和小棒的坐標(biāo)。此外,小棒的移動速度根據(jù)按鍵處理而變化。以下記述了run方法。(ex.8)

/**

*線程的運行處理

*/

publicvoidrun(){

while(state==ACTIVE){

moveBall();//使球運動

moveBar();//移動小棒

repaint();//再次描畫

try{

Thread.sleep(50);

}catch(InterruptedCodeExampleceptione){

e.printStackTrace();

break;

}

}

}

/**

//使球運動

*/

publicvoidmoveBall(){

ballX+=ballMovCodeExample;

ballY+=ballMoveY;

}

/**

*移動小棒

*/

publicvoidmoveBar(){

barX+=barMovCodeExample;

//不能向畫面外移動

if(barX<0){

barX=0;

}elseif(barX+BAR_WIDTH>getWidth()){

barX=getWidth()-BAR_WIDTH;

}

}

ex.8

以下表示的是按鍵處理。(ex.9)

/*****************************************

*按鍵處理

*****************************************/

/**

*按按鍵時

*/

protectedvoidkeyPressed(intkey){

if(state==ACTIVE){//正在運動

if(getGameAction(key)==Canvas.RIGHT){

barMovCodeExample=6;

}elseif(getGameAction(key)==Canvas.LEFT){

barMovCodeExample=-6;

}

repaint();

}else{//停止運動后

//再次啟動

this.initialize();

}

}

/**

*釋放按鍵時

*/

protectedvoidkeyReleased(intkey){

barMovCodeExample=0;

}

ex.9

5.球的反彈

下面是球的反彈。

球的反彈形式有以下3種。

·碰邊壁后反彈

·碰小棒后反彈

·碰彩球后反彈

記述了每個moveBall方法。(ex.10)

碰彩球的反彈時

block[i][j]=false;

blockCount--;

彩球立刻就破碎。彩球破碎后余下的彩球數(shù)量blockCount將有所減少。

另外,球掉落時,改變游戲狀態(tài)后游戲結(jié)束。

/**

//使球運動

*/

publicvoidmoveBall(){

ballX+=ballMovCodeExample;

ballY+=ballMoveY;

//反彈

//碰邊壁后反彈

if(ballX<0){

ballMovCodeExample*=-1;

ballX=0;

}elseif(getWidth()

ballX=getWidth()-BALL_HEIGHT;

ballMovCodeExample*=-1;

}

if(ballY<0){

ballMoveY*=-1;

ballY=0;

}elseif(ballY>getHeight()){//球落下后

//游戲結(jié)束

state=GAME_OVER;

}

//碰上小棒后反彈

if(ballY+BALL_HEIGHT>barY

&&ballX+BALL_WIDTH>barX

&&ballX

ballMoveY*=-1;

ballY=barY-BALL_HEIGHT;

if(barMovCodeExample<0){

ballMovCodeExample-=2;

}elseif(barMovCodeExample>0){

ballMovCodeExample+=2;

}

}

//碰上彩球后反彈

for(inti=0;i

for(intj=0;j

if(block[i][j]){

if(ballX+BALL_WIDTH>i*BLOCK_WIDTH

&&ballX<(i+1)*BLOCK_WIDTH){

if(ballY+BALL_HEIGHT>(j+1)*BLOCK_HEIGHT

&&ballY<(j+2)*BLOCK_HEIGHT){

//清除彩球

block[i][j]=false;

blockCount--;

ballMoveY*=-1;}

}

}

}

}

}

}

ex.10

碰小棒后反彈情況如下所示:向右按鍵時,球就會讓右方快速移動,反之,向左按鍵時,球則向左方快速移動。(ex.11)

if(barMoveX<0){

ballMoveX-=2;

}elseif(barMoveX>0){

ballMoveX+=2;

}

ex.11

·清除檢查

至此安裝完畢游戲就有雛形了。但是,在現(xiàn)在的程序中即使彩球全部消失,游戲也不能清除。那么,球與彩球相撞時,數(shù)出彩球的剩余數(shù)。當(dāng)該數(shù)值為0時,則游戲清除。以下記述的是該處理。(ex.12)

//清除彩球

block[i][j]=false;

blockCount--;

ballMoveY*=-1;

//播放音效

blockSound.play();

//檢查游戲清除

if(blockCount==0){

state=CLEAR;

}

ex.12

6.音樂播放

在本講中的泡泡龍游戲的應(yīng)用程序中最好使用BGM和音效。游戲開始的同時演奏BGM,音效則是球在碰壁、碰小棒反彈時,以及彩球破碎時才播放的。

·讀取

用BlockApplication構(gòu)造函數(shù)讀取音樂數(shù)據(jù)。而且,這里的BGM能夠循環(huán)播放,所以可以使用音頻事件處理。(ex.13)

[!--empirenews.page--]

//聲音數(shù)據(jù)的讀取

bgm=Media.getAudioClip("/bgm.mid");//背景音樂

ballSound=Media.getAudioClip("/ball.mid");//球反彈后的音效

blockSound=Media.getAudioClip("/block.mid");//球破碎的音效

bgm.addAudioListener(this);//增加AudioListener

ex.13

·播放

讀取音樂數(shù)據(jù)后,接下來進行播放。BGM在游戲開始的同時能夠播放,所以在AudioCanvas類的start方法中記述播放處理并能夠播放出來。

球的音效:用moveBall方法進行下面反彈判斷時,能夠播放音效。(ex.14)

//反彈

//碰邊壁后反彈

if(ballX<0){

ballMoveX*=-1;

ballX=0;

//播放音效

ballSound.play();

}elseif(getWidth()

ballX=getWidth()-BALL_HEIGHT;

ballMoveX*=-1;

//播放音效

ballSound.play();

}

if(ballY<0){

ballMoveY*=-1;

ballY=0;

//播放音效

ballSound.play();

}elseif(ballY>getHeight()){//球落下后

//游戲結(jié)束

state=GAME_OVER;

}

//碰上小棒反彈

if(ballY+BALL_HEIGHT>barY

&&ballX+BALL_WIDTH>barX

&&ballX

ballMoveY*=-1;

ballY=barY-BALL_HEIGHT;

if(barMoveX<0){

ballMoveX-=2;

}elseif(barMoveX>0){

ballMoveX+=2;

}

//播放音效

ballSound.play();

}

ex.14

彩球的音效:用moveBall方法判定彩球的碰撞時,如下記述并能夠播放。(ex.15)

//碰上彩球后反彈

for(inti=0;i

for(intj=0;j

if(block[i][j]){

if(ballX+BALL_WIDTH>i*BLOCK_WIDTH

&&ballX<(i+1)*BLOCK_WIDTH){

if(ballY+BALL_HEIGHT>(j+1)*BLOCK_HEIGHT

&&ballY<(j+2)*BLOCK_HEIGHT){

block[i][j]=false;

ballMoveY*=-1;

//播放音效

blockSound.play();

}

}

}

}

}

ex.15

■完成

下面是實際制作的程序一式。(BlockApplication.zip)

運行結(jié)果如下所示。

游戲進行中游戲結(jié)束

游戲結(jié)束

總結(jié)

在本講的講解中能夠自由播放音樂數(shù)據(jù)了。因此,能夠制作成創(chuàng)造性的應(yīng)用程序。但是,擴展應(yīng)用程序時,不能保存高分、數(shù)據(jù)等。在下講我們將學(xué)習(xí)如何使用固定存儲器保存數(shù)據(jù)的方法。

查看png格式的畫面文件

播放smf格式的音樂文件

http通信,socket通信

逆光、雙感光板控制

Sprite功能

ImageMap功能

各種各樣的制圖擴展功能

3D引擎

由于N820具有256Kbyte的較大存儲空間,所以能制作容量稍大、自由度較高的手機應(yīng)用程序。另外,也能制作對應(yīng)http、socket通信的自由度較高網(wǎng)絡(luò)應(yīng)用程序。因此,也能夠搭載3D引擎、3D描畫。而且還能安裝N800對應(yīng)的Sprite功能、ImageMap功能的描畫功能。

■與N800的比較

下表是N800和N820的比較。(表6)

項目N800N820

顯示屏尺寸180x162(縱x橫)255x240(縱x橫)

JAD文件尺寸最大2KB最大2KB

JAR文件尺寸最大50KB最大1MB

RMS尺寸最大10KB最大10KB

記錄存儲數(shù)量最大3records最大3records

通信協(xié)議只有httpHTTPandsocket

畫像文件PNGPNG

音樂文件SMF(format0)最大10KbyteSMF(format0)最大10Kbyte

表6

■NECN820Application模擬器

下面是模擬N820工作的模擬器,稱為「NEC820ApplicationEmulator」。與以前我們所介紹的「NECN800ApplicationEmulator」在外觀上沒有什么區(qū)別。(図5)

圖5

打開模擬器,就是現(xiàn)在的手機畫面表示。與N800相比,手機設(shè)計多少有些變化,手機的內(nèi)顯示屏變大了。下圖是用N820ApplicationEmulator制作的“泡泡龍”游戲畫面。“泡泡龍”游戲由于是假定在N800的屏幕上應(yīng)用的。因此畫面尺寸要比N820中的內(nèi)屏尺寸稍小。因此,彩球之間存有空隙。(図6)

図6

■總結(jié)

N820的優(yōu)點是具有256Kbyte的大容量存儲空間,而且使用3D圖表引擎、3D圖表應(yīng)用程序、能夠制作成對應(yīng)socket通信的TCP/IP網(wǎng)絡(luò)應(yīng)用程序。對于應(yīng)用開發(fā)者而言,N820是一部制作JAVA應(yīng)用程序非常有價值的終端。對于尋求高級機種的用戶而言,應(yīng)該是一部高精細畫面、高功能的極大滿足用戶需要的終端。今后N820的用戶應(yīng)該會大幅度增加的。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

本站聲明: 本文章由作者或相關(guān)機構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點,本站亦不保證或承諾內(nèi)容真實性等。需要轉(zhuǎn)載請聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請及時聯(lián)系本站刪除。
換一批
延伸閱讀

9月2日消息,不造車的華為或?qū)⒋呱龈蟮莫毥谦F公司,隨著阿維塔和賽力斯的入局,華為引望愈發(fā)顯得引人矚目。

關(guān)鍵字: 阿維塔 塞力斯 華為

加利福尼亞州圣克拉拉縣2024年8月30日 /美通社/ -- 數(shù)字化轉(zhuǎn)型技術(shù)解決方案公司Trianz今天宣布,該公司與Amazon Web Services (AWS)簽訂了...

關(guān)鍵字: AWS AN BSP 數(shù)字化

倫敦2024年8月29日 /美通社/ -- 英國汽車技術(shù)公司SODA.Auto推出其旗艦產(chǎn)品SODA V,這是全球首款涵蓋汽車工程師從創(chuàng)意到認證的所有需求的工具,可用于創(chuàng)建軟件定義汽車。 SODA V工具的開發(fā)耗時1.5...

關(guān)鍵字: 汽車 人工智能 智能驅(qū)動 BSP

北京2024年8月28日 /美通社/ -- 越來越多用戶希望企業(yè)業(yè)務(wù)能7×24不間斷運行,同時企業(yè)卻面臨越來越多業(yè)務(wù)中斷的風(fēng)險,如企業(yè)系統(tǒng)復(fù)雜性的增加,頻繁的功能更新和發(fā)布等。如何確保業(yè)務(wù)連續(xù)性,提升韌性,成...

關(guān)鍵字: 亞馬遜 解密 控制平面 BSP

8月30日消息,據(jù)媒體報道,騰訊和網(wǎng)易近期正在縮減他們對日本游戲市場的投資。

關(guān)鍵字: 騰訊 編碼器 CPU

8月28日消息,今天上午,2024中國國際大數(shù)據(jù)產(chǎn)業(yè)博覽會開幕式在貴陽舉行,華為董事、質(zhì)量流程IT總裁陶景文發(fā)表了演講。

關(guān)鍵字: 華為 12nm EDA 半導(dǎo)體

8月28日消息,在2024中國國際大數(shù)據(jù)產(chǎn)業(yè)博覽會上,華為常務(wù)董事、華為云CEO張平安發(fā)表演講稱,數(shù)字世界的話語權(quán)最終是由生態(tài)的繁榮決定的。

關(guān)鍵字: 華為 12nm 手機 衛(wèi)星通信

要點: 有效應(yīng)對環(huán)境變化,經(jīng)營業(yè)績穩(wěn)中有升 落實提質(zhì)增效舉措,毛利潤率延續(xù)升勢 戰(zhàn)略布局成效顯著,戰(zhàn)新業(yè)務(wù)引領(lǐng)增長 以科技創(chuàng)新為引領(lǐng),提升企業(yè)核心競爭力 堅持高質(zhì)量發(fā)展策略,塑強核心競爭優(yōu)勢...

關(guān)鍵字: 通信 BSP 電信運營商 數(shù)字經(jīng)濟

北京2024年8月27日 /美通社/ -- 8月21日,由中央廣播電視總臺與中國電影電視技術(shù)學(xué)會聯(lián)合牽頭組建的NVI技術(shù)創(chuàng)新聯(lián)盟在BIRTV2024超高清全產(chǎn)業(yè)鏈發(fā)展研討會上宣布正式成立。 活動現(xiàn)場 NVI技術(shù)創(chuàng)新聯(lián)...

關(guān)鍵字: VI 傳輸協(xié)議 音頻 BSP

北京2024年8月27日 /美通社/ -- 在8月23日舉辦的2024年長三角生態(tài)綠色一體化發(fā)展示范區(qū)聯(lián)合招商會上,軟通動力信息技術(shù)(集團)股份有限公司(以下簡稱"軟通動力")與長三角投資(上海)有限...

關(guān)鍵字: BSP 信息技術(shù)
關(guān)閉
關(guān)閉