BREW中支持的音頻格式主要分為兩類:基于MIDI的文件格式和特殊編碼的音頻文件格式?;贛IDI的文件格式有.mid,.dls..xmf和.pmd,其中的DLS文件是由設備定義的,自身是不能被播放的,XMF文件將MIDI和DLS結合起來進行播放。PMD文件與XMF類似是一種文件容器,可以包含MIDI, DLS和其他編碼格式的音頻,還可以包含圖像,文本,LED或者振動同步信息等。編碼的音頻格式主要有QCELP,PCM和ADPCM三種,QCELP一個語音壓縮的編譯碼器,并不適合音樂的播放。PCM是一種16 bit未壓縮的波形抽樣原始數據,非常適合播放音樂,但文件的尺寸非常大。ADPCM 只有四分之一的PCM的文件大小,比較適合手機上的音樂和聲音效果。就采樣率而言,QCELP只是8kHz 的采樣率,而PCM支持4, 8, 11.025, 12, 16, 22.05, 24, 32, 44.1kHz的采用率,ADPCM支持從4.0 到44.1kHz的任何采用率。

??????????? 以播放QCP文件為例,播放一個音頻文件非常簡單,首先創建AEECLSID_MEDIAQCP的IMedia接口,然后調用IMEDIA_SetMediaData()加載音頻文件,最后調用IMEDIA_Play() 播放即可。

??????????? 在循環播放的時候,在文件播放結束和文件重新播放之間通常會存在短暫的空白,BREW 3.1.5及以后的版本支持QCP, PCM和ADPCM的無間隙播放。例如,在加載QCP文件之前先調用IMEDIA_SetMediaParm(pIMediaQCPObject,MM_PARM_PLAY_REPEAT, repeatCount, 0)和IMEDIA_EnableChannelShare(),然后在調用IMEDIA_Play() 就可以實現QCP音頻效果的無間隔循環播放。

??????????? 在某些情況下,需要實現混合的音頻效果。在BREW 2.1及以后的版本中,實現了4 個MIDI文件的混合,4 QCP文件的混合或者4 個ADPCM 文件的混合。需要注意的是,混合的文件必須為相同的文件格式,例如全部的QCP文件或者全部的ADPCM文件,而不能將QCP文件與PCM或者ADPCM文件進行混頻,只有在07年以后(在中國市場)的部分手機才開始支持不同音頻格式文件的混合播放。音頻混合播放的過程與無間隙循環播放的過程類似,首先創建接口,然后通過IMEDIA_SetMediaData()來加載每一個音頻文件,并且在創建媒體對象后立即調用IMEDIA_EnableChannelShare() ,最后就能夠使用IMEDIA_Play()來進行混音播放了。3.1.4 以前的版本IMEDIA_EnableChannelShare()可能會有問題。另外,使用AEECLSID_MEDIAMIDIOUTQCP創建的接口可以兼顧QCP或者ADPCM文件。

??????????? 實現混音播放的另一種簡單方法就是將所需的各種音頻文件嵌入到一個CMX的文件中,然后只播放這個CMX文件就可以了。這種方法的局限在于需要手機對CMX的支持。

??????????? 可下載的音頻(DLS)實際上是一種面向MIDI合成器的定制化波形表,可以通過MIDI指令來完成播放或停止,定調和音量調整等操作。在CMX 4.4 及其以后版本中,這種可下載的音頻也可以嵌入到 .pmd 或者 .xmf 文件中。在SDK 3.1.4 之后的版本中,可以通過IDLS API 來加載或卸載這種可下載的音頻。表14-2介紹了DLS的音效類型及適用的情形。

類型

?描述

?示例

?DLS 優勢

?

單次音效

?在最大的采樣周期長度內播放音效

?開槍的聲音t

開關門的聲音

?音準的確定可以通過按上下鍵來實現

?

循環音效

?一個連續聲音效果的循環播放

?駿馬奔馳的聲音,溪水潺潺的聲音

?音準可變,可以保持在文件中

?

片段音效

?將較短的音效循環播放,或者合成為新的音效

?物品肢解的聲音,機械引擎的聲音

?音準可變,可以保持在文件中,能夠通過基本的音效產生較為復雜的音效

?

表 14-2:DLS的音效類型及適用的情形

使用IDLS的時候,首先要創建DLS 的對象:

ISHELL_CreateInstance(m_pIShell, AEECLSID_MEDIADLS,(void**)&m_pIDLS);

接下來設定DLS 文件的媒體數據屬性:

AEEMediaData MediaData;

MediaData.clsData = MMD_FILE_NAME;

MediaData.pData = DLS_FILE;

MediaData.dwSize = 0;

然后初始化DLS的回調函數,并加載DLS文件

CALLBACK_Init(&m_cbDLSLoad, LoadDLSCB, (void*)this);

iReturn = IDLS_Load(m_pIDLS, &MediaData, &m_cbDLSLoad, &m_LoadDLSRet);

如果DLS是全局性的加載,就可以使用IMediaMIDI的接口對象來播放MIDI文件了

boolean fIsGlobal = false;

iReturn = IDLS_IsGlobal(m_pIDLS, &fIsGlobal);

if(fIsGlobal){

PlayOneMidi(MIDI_FILE, &m_pIMediaMIDI);

return;

}

由于XMF/DLS并沒有應用的很廣泛,所以需要專門的工具來制作和生成此類文件,例如

Faith West Inc.的 “mXMFTool”工具等。

??????????? 對中斷和恢復操作時,應用程序的聲音在被中斷后要求能重新播放,但在某些手機可能無法恢復聲音。這其中最主要的原因就是,當該手機接到一條短消息同時會產生提示用戶接收的聲音,而這種聲音是不能在應用中禁止的,因為這種提示短消息的音樂會占用手機中聲音資源的芯片。某些手機在收到短消息不能觸發EVT_APP_SUSPEND 事件, 所以應用程序就不知道應用中所使用的聲音已停止播放。通常情況下有兩種解決辦法,一種是設定計時器,讓應用程序階段性的設定音樂。以下就是用這種方法時應用所作的處理:

if (pApp - >J udgeMusicOpen) / / 判斷要播放的音樂

 {MusicPlayer (pApp ,pApp - > m- p ISoundPlayer , “musicname”) ;/ / 播放當前音樂

/ / 在音樂播放完后繼續播放

ISHELL - Set Timer ( pApp - > a. m- p IShell ,3000 , (PFNNOTIFY) BackMusicPlay , (void 3 ) pApp) ; }

在應用程序中斷時作的操作是IsoundPlayer_Stop(m-pISoundPlayer) ;恢復時的操作是

if (pApp - > J udgeMusicOpen) / / 判斷要播放的音樂

BackMusicPlay (pApp - > m-p ISoundPlayer) ;/ / 循環播放

另一種辦法就是調用回調函數如IMEDIA_RegisterNotify或ISOUNDPLAYER_ RegisterNotify。當音樂被短消息中斷時,應用會得到AEE_SOUNDPLAYER_DONE 或MM_STATUS_DONE 狀態的提示,一旦獲得這種狀態提示,就需要重新播放。特殊的情況,應用程序被中斷后音樂不能在某些手機播放,用上述兩種方法可以解決這些問題。

?

?