一、原理
Hi3520D音頻(AUDIO)模塊包括音頻輸入、音頻輸出、音頻編碼、音頻編碼和音頻解碼模塊。音頻輸入和輸出模塊通過對Hi3520D芯片SIO設備的控制實現相應的音頻輸入輸出功能;編碼和解碼模塊則提供對ADPCM、G726、G711、PCM格式的音頻編解碼功能。
讀取本地音頻進行輸出播放,主要原理如下:芯片利用DMA將內存中的數據傳輸到AO設備。AO設備通過I2S時序或PCM時序向AudioCodec發送數據。AudioCodec完成數字信號到模擬信號的轉換過程,並輸出模擬信號。
Hi3520D音頻解碼播放流程:
1、 音頻輸出屬性初始化(通過結構體AIO_ATTR_S來進行設置);
2、 配置音頻編解碼模塊(ACODEC);
3、 根據音頻編碼協議創建音頻解碼通道;
4、 設置AO設備屬性;啓用AO設備;啓用AO通道(啓用AO重採樣,此項可選);
5、 綁定音頻輸出通道到音頻解碼通道;
6、 向每包待發送的音頻數據頭添加4字節的海思音頻協議頭;
7、 向音頻解碼通道發送組合後的音頻數據包;
8、 播放聲音。
二、調試過程
1、 製作原始音頻數據(raw data)文件
Hi35XX系列芯片編解碼所支持的音頻格式主要是ADPCM、G726、G711、PCM等原始音頻格式,常見的音頻格式無法直接播放。因此若要輸出播放本地音頻,需先將音頻轉化成原始音頻格式。
圖1Adobe Audition啓動界面
這裏使用的是AdobeAudition音頻處理軟件(支持將音頻轉化成pcm raw data格式)。安裝破解後,打開軟件(不要在破解前打開),界面如圖1所示。
在載入音頻文件之前,打開Edit->Preferences->Media & Disk Cache,勾選DLMS使能,如圖2所示。否則軟件無法正常載入音頻文件。
圖2打開DLMS使能
通過File->Open或者File->Import->File載入音頻文件。載入音頻後,會出現如圖3所示的界面。如果不出現右側的波形圖,則說明音頻文件沒有正確載入。載入後,可以播放試聽。
圖3載入音頻文件
通過File->Saveas或File->Export->File導出特定格式的音頻文件。導出前設置好導出格式即可,具體如下:Format選擇libsndfile;在 Sample Type中設置SampleRate、Channels、BiteDepth等(按圖示進行設置即可);在FormatSetting中,Format選擇RawData,Encoding中選擇16bit-PCM,ByteOrder選擇默認即可。
設置完OK即可導出pcm格式的原始音頻文件。
圖4 輸出格式設置
2、 系統和AUDIO模塊的初始化
調用sample_comm_sys.c文件中的HI_S32SAMPLE_COMM_SYS_Init(VB_CONF_S*pstVbConf)接口即可。
3、 音頻輸出屬性初始化
音頻輸出屬性通過結構體AIO_ATTR_S進行配置,配置時調用HI_S32SAMPLE_COMM_AUDIO_CfgAcodec(AIO_ATTR_S*pstAioAttr)接口即可,由於我們用到的解碼芯片是nvp6124,所以我們只需在該接口定義所在的文件sample_comm_audio.c增加宏定義#define HI_ACODEC_TYPE_NVP6124即可,也即實際調用的是HI_S32 SAMPLE_NVP6124_CfgAudio(constAIO_ATTR_S *pstAioAttr)接口,而這個接口實際是通過nvp6124驅動中的nvp6124_audio_format結構體和ioctl()接口來實現的。
4、 創建音頻解碼通道
音頻解碼通道的創建通過調用系統函數HI_S32HI_MPI_ADEC_CreateChn(AdChn,&stAdecAttr)實現,具體可參考HI_S32SAMPLE_COMM_AUDIO_StartAdec (ADEC_CHN AdChn, PAYLOAD_TYPE_E enType)的實現。指定好解碼通道和解碼文件的類型即可,這裏分別爲0和PT_LPCM。
5、 啓動AO設備和AO通道
具體可參照HI_S32 SAMPLE_COMM_AUDIO_StartAo(AUDIO_DEVAoDevId, HI_S32 s32AoChnCnt, AIO_ATTR_S* pstAioAttr, AUDIO_SAMPLE_RATE_EenInSampleRate, HI_BOOL bResampleEn)。
HI_S32 HI_MPI_AO_SetPubAttr (AUDIO_DEVAoDevId, const AIO_ATTR_S *pstAttr)設置AO設備屬性。注意pstAttr音頻中設置的參數AO設備可支持且和音頻文件的參數保持一致。
HI_S32 HI_MPI_AO_Enable(AUDIO_DEV AoDevId)設置AO設備使能。
HI_S32 HI_MPI_AO_EnableChn(AUDIO_DEV AoDevId,AO_CHN AoChn)設置解碼通道使能。
這裏不需要再像例程裏那樣進行重採樣。
6、 綁定輸出通道和音頻解碼通道
直接調用系統函數HI_S32 HI_MPI_SYS_Bind(MPP_CHN_S*pstSrcChn, MPP_CHN_S *pstDestChn)進行綁定即可。
具體可參考HI_S32SAMPLE_COMM_AUDIO_AoBindAdec(AUDIO_DEVAoDev, AO_CHN AoChn, ADEC_CHN AdChn)接口的實現。
7、 向音頻文件添加海思音頻協議頭並向音頻解碼通道發送音頻數據包
首先需要打開本地音頻文件,直接調用fopen()函數即可,具體可參考或使用staticFILE *SAMPLE_AUDIO_OpenAdecFile(ADEC_CHNAdChn, PAYLOAD_TYPE_E enType)函數即可。
原始音頻文件放在和應用同級目錄下,這裏默認命名爲audio_chn0.pcm(與OpenAdecFile() 函數中設定的文件名稱和類型相同即可)。
創建線程向解碼器傳輸音頻文件流解碼,具體可參考和使用HI_S32SAMPLE_COMM_AUDIO_CreatTrdFileAdec(ADEC_CHNAdChn, FILE *pAdcFd) 主要是通過調用系統接口HI_S32HI_MPI_ADEC_SendStream(ADEC_CHN AdChn,const AUDIO_STREAM_S *pstStream, HI_BOOL bBlock)來實現的,在發送音頻流數據前會添加4個字節的海思音頻協議頭{0,1,160,0}。
至此,即可實現對本地文件的播放。注意:需要避免整個程序退出,才能實現持續的播放,可通過getchar()等函數來實現(類似於opencv中圖片的顯示需要藉助於waitKey());
8、 其他
設置音量和靜音:在實現以上環節以後,可通過HI_S32HI_MPI_AO_SetVolume (AUDIO_DEVAoDevId, HI_S32 s32VolumeDb)和HI_S32HI_MPI_AO_SetMute (AUDIO_DEV AoDevId,HI_BOOL bEnable, AUDIO_FADE_S *pstFade)進行音量和靜音設置
播放退出:退出播放時,需要將上面創建的通道、打開的設備、創建的關聯等關閉釋放和解除,具體可參考例程。
三、參考
1、主要參考文檔:《HiMPPV3.0 媒體處理軟件開發參考》,含有原理、API、錯誤碼等。
2、參考sample_audio.c中的HI_S32SAMPLE_AUDIO_AdecAo(HI_VOID)接口函數。
3、 hi3520d音頻輸出調試成功(http://bbs.ebaina.com/forum.php?mod=viewthread&tid=9155)。
4、HI3520D音頻(http://blog.csdn.net/dagefeijiqumeiguo/article/details/51763903)