MTK FAQ:如何實現連續的PCM流播放
實現這類PCM的播放(類似於TTS)思路及samplecode如下:
使用雙buffer的機制,TTS使用一個,DSP使用另一個,兩個大小一樣。其中DSP使用的由DSP自行管理,TTS使用的由TTS自行管理。建議TTS使用ringbuffer的機制,設定一個寫指標和一個讀指標,分別指示TTS可以寫入的開始位置和DSP可以讀出的開始位置,兩者的差為可以寫入和可以讀出的長度。
使用流程:
1.開始TTS合成.
2.合成出來第一段PCM資料後呼叫tts_media_play函式,開始播放,設定callback函式Pcm_play_callback。(在開始播放後,tts_media_play只應被呼叫一次,後面喂資料應該是由Pcm_play_callback來完成)
3.TTS繼續合成資料,合成完後就放合適大小(透過計算讀指標與寫指標的差)的PCM資料到TTSbuffer寫指標指示的位置中,並暫停下來等待DSP的event發生。TTSenging如果不能暫停就只能把多出來的資料丟棄。
4.等DSP有event發生底層就會自動呼叫Pcm_play_callback,如果是MEDIA_DATA_REQUEST的event,就從TTSbuffer裡面複製合適大小(透過GetWriteBuffer獲知DSP可以接受的資料,和TTSbuffer的寫指標與讀指標的差做比較,取其中的小者)的資料到DSPbuffer.如果DSP的event上來時TTS還來不及合成資料就立刻返回。
5.如果TTS把所有資料都合成完畢並全部傳給了DSP的buffer,或者從DSP收到MEDIA_END,MEDIA_ERROR,MEDIA_TERMINATED,就呼叫Stop,Close,DataFinished停止播放。
下面是samplecode,供參考:
#defineTTS_BUFFER_LEN1*1024
typedefunsignedcharuint8;
typedefsignedcharint8;
typedefunsignedshortintuint16;
typedefsignedshortintint16;
typedefunsignedintuint32;
typedefsignedintint32;
structVParam
{
uint8*buf_p;
uint32buf_len;
uint32offset;
FS_HANDLEfilehandle;
MHdl*mhdl_handle;
}TTSParam;
kal_uint16tts_ring_buf[TTS_BUFFER_LEN];
voidtts_init(void)
{
TTSParam.buf_p=tts_ring_buf;
TTSParam.buf_len=0;
}
staticvoidPcm_play_callback(MHdl*mhdl,Media_Eventevent)
{
switch(event){
caseMEDIA_END:
caseMEDIA_ERROR:
caseMEDIA_TERMINATED:
{
TTSParam.mhdl_handle->Stop(TTSParam.mhdl_handle);
TTSParam.mhdl_handle->Close(TTSParam.mhdl_handle);
/*closethefile*/
FS_Close(TTSParam.filehandle);
break;
}
caseMEDIA_DATA_REQUEST:
{
kal_uint32read_size=0;
TTSParam.mhdl_handle->GetWriteBuffer(
TTSParam.mhdl_handle,
&TTSParam.buf_p,
&TTSParam.buf_len);
FS_Read(TTSParam.filehandle,TTSParam.buf_p,TTSParam.buf_len,&read_size);
if(read_size>0)
{
TTSParam.mhdl_handle->WriteDataDone(
TTSParam.mhdl_handle,
read_size);
TTSParam.mhdl_handle->FinishWriteData(TTSParam.mhdl_handle);
}
else
{
/*closethefile*/
FS_Close(TTSParam.filehandle);
}
}
}
}
kal_int32tts_media_play(void)
{
/*----------------------------------------------------------------*/
/*LocalVariables*/
/*----------------------------------------------------------------*/
kal_uint32read_size=0;
kal_int32audio_format;
kal_int32result;
Media_Statusaud_ret;
Media_PCM_Stream_ParamvpFormat;
void*param=NULL;
/*----------------------------------------------------------------*/
/*CodeBody*/
/*----------------------------------------------------------------*/
{
vpFormat.isStereo=0;
vpFormat.bitPerSample=16;
vpFormat.sampleFreq=8000;
param=&vpFormat;
TTSParam.filehandle=FS_Open(L"C:\\Images\\OutPcm.pcm",FS_READ_ONLY);
if((TTSParam.mhdl_handle=PCM_Strm_Open(Pcm_play_callback,param))==NULL)
{
return;
}
TTSParam.mhdl_handle->SetBuffer(
TTSParam.mhdl_handle,
(kal_uint8*)tts_ring_buf,
TTS_BUFFER_LEN*2);
TTSParam.mhdl_handle->GetWriteBuffer(
TTSParam.mhdl_handle,
&TTSParam.buf_p,
&TTSParam.buf_len);
FS_Read(TTSParam.filehandle,TTSParam.buf_p,TTSParam.buf_len*2,&read_size);
//hereshouldbeerrorhandlingforFS_Read
if(read_size>0)
{
TTSParam.mhdl_handle->WriteDataDone(
TTSParam.mhdl_handle,
read_size);
aud_ret=TTSParam.mhdl_handle->Play(TTSParam.mhdl_handle);
}
else
{
/*closethefile*/
FS_Close(TTSParam.filehandle);
}
}
}
voidtts_test1(void)
{
tts_init();
tts_media_play();
}
因為在singlebankflash的情況下,為了防止同時讀寫一個bank的情況發生,需要把wavetable的資料搬到RAM上,所以設定為RW資料。但如果你的flash本身是multibank,卻開啟了singlebanksupport,那麼只要保證wavetable放在和FAT不相同的一個bank上,就可以不必搬到RAM上,亦即可以修改為const.
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/31529038/viewspace-2654280/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- WPS演示透過打包實現連續播放檔案
- [FAQ09717]如何去掉mtk自行開發的OOBE快速嚮導 功能中的某段操作引導影片的播放?
- Tinyalsa PCM API 實現深度剖析API
- ffmpeg+nginx 實現拉流轉碼播放Nginx
- 如何實現 Android 短影片跨頁面的流暢續播?Android
- 實時流(直播流)播放、上牆(大屏播放)解決方案
- 最大連續子陣列和的實現陣列
- 連續插值,用forall實現。
- 【播放器SDK–FAQ】點播播放器和直播播放器衝突如何解決?播放器
- mtk faq:聽筒用小喇叭,外放用大喇叭的軟體配置
- MTK_on_line_FAQ_SW_ALPS_Framework+-+Resource+ManagerTheme+ManagerFramework
- iOS開發 整合ijkplayer實現直播#拉流#播放iOS
- web 頁面如何實現不同分組資料的連續序號?Web
- iOS AVPlayer之後臺連續播放視訊iOS
- 音訊開發之錄製播放pcm檔案音訊
- iOS播放PCM,NSData流程式碼(Audio Queue Services)iOS
- C#中呼叫libvlc實現本地、網路節目流的播放C#
- Nginx+FFmpeg實現rtsp流轉hls流,在WEB通過H5 video實現視訊播放NginxWebH5IDE
- Mac實用技巧:如何設定長按delete實現連續刪除小技巧!Macdelete
- APP是如何實現自動續費的?APP
- MTK FAQ:在檔案管理器中刪除某首歌,再次進入音樂播放器列表,被刪除的歌曲依然顯示播放器
- JMeter流媒體線上播放HLS外掛BlazeMeter - HLS Plugin實現視訊線上播放壓測JMeterPlugin
- 如何實現視訊加密全平臺播放加密
- mp3的自動連續播放以及探測是否可以播放、並對可以播放的結果進行儲存
- Flink SQL 如何實現資料流的 Join?SQL
- 如何實現 Android 應用的持續部署?Android
- jdbc如何連續查詢?JDBC
- Android多媒體之SoundPool+pcm流的音訊操作Android音訊
- NGINX如何實現rtmp推流服務Nginx
- 如何實現自動化工作流?
- 如何使用 pyqt 實現 Groove 音樂播放器QT播放器
- 【CONNECT BY】使用connect by level/rownum實現連續數字的插入
- FFmpeg 播放 RTSP/Webcam 流Web
- 各種命令,以及FAQ..持續更新.....
- 會員自動續費該如何實現
- ofbiz 連線池如何實現?
- Android多媒體之認識聲音、錄音與播放(PCM)Android
- java文件線上播放實現Java