康敬欣,張 田
(北京化工大學(xué) 機(jī)電工程學(xué)院,北京 100029)
嵌入式Linux下音頻采集與遠(yuǎn)程回放的實(shí)現(xiàn)
康敬欣,張 田
(北京化工大學(xué) 機(jī)電工程學(xué)院,北京 100029)
為了實(shí)現(xiàn)遠(yuǎn)程通信發(fā)射系統(tǒng)的音頻遠(yuǎn)程發(fā)射,提出了一種嵌入式Linux下音頻的本地采集并傳輸至遠(yuǎn)端進(jìn)行回放的設(shè)計(jì)方案。該方案采用ALSA完成本地音頻數(shù)據(jù)的采集,然后利用FFmpeg將其編碼為適合遠(yuǎn)程傳輸?shù)腁AC格式數(shù)據(jù),通過以太網(wǎng)基于UDP協(xié)議傳輸至遠(yuǎn)端;同時(shí)在遠(yuǎn)端對(duì)接收到的音頻數(shù)據(jù),利用FFmpeg和ALSA分別完成音頻的解碼和回放。實(shí)驗(yàn)結(jié)果表明,遠(yuǎn)端回放的音頻信號(hào)流暢清晰,該方案執(zhí)行穩(wěn)定、可靠性高。
Linux;FFmpeg;UDP;ALSA
遠(yuǎn)程通信發(fā)射系統(tǒng)通常包括本地控制單元和遠(yuǎn)程發(fā)射單元,本地控制單元需要完成待發(fā)射音頻數(shù)據(jù)的采集,然后發(fā)送給遠(yuǎn)程發(fā)射單元進(jìn)行數(shù)據(jù)解碼、信號(hào)轉(zhuǎn)換和調(diào)制輸出,實(shí)現(xiàn)音頻信號(hào)的遠(yuǎn)程發(fā)射。嵌入式Linux系統(tǒng)具有功耗低、較易開發(fā)和運(yùn)行穩(wěn)定等特點(diǎn),以及較多成熟的技術(shù)應(yīng)用[1],使之在通信領(lǐng)域的應(yīng)用不斷擴(kuò)展。因此,文中給出了一種嵌入式Linux下音頻信號(hào)的采集、傳輸和回放的解決方案,為遠(yuǎn)程通信發(fā)射系統(tǒng)的音頻遠(yuǎn)程發(fā)射提供一種新的實(shí)現(xiàn)方法。
隨著嵌入式解決方案和數(shù)字多媒體技術(shù)的不斷發(fā)展,嵌入式音頻信號(hào)處理相關(guān)技術(shù)得到廣泛應(yīng)用。目前嵌入式操作系統(tǒng)中,處理音頻數(shù)據(jù)所采用的體系架構(gòu)多數(shù)為 ALSA(Advanced Linux Sound Architecture)[2]。周鵬等在Linux系統(tǒng)環(huán)境下,基于ALSA框架完成了音頻處理芯片WM8976的驅(qū)動(dòng)程序設(shè)計(jì),得到了較好測試結(jié)果[3]。顏瑋等在CORTEX-A8平臺(tái)上,研究了編解碼芯片TLV320AIC3110基于ALSA框架的驅(qū)動(dòng)實(shí)現(xiàn),最后完成了音頻編解碼的穩(wěn)定驅(qū)動(dòng)[4]。不同芯片生產(chǎn)商按照相同的ALSA所定義的調(diào)用接口開發(fā)音頻接口驅(qū)動(dòng),此時(shí)應(yīng)用程序只需要調(diào)用ALSA庫中提供的API,就可以實(shí)現(xiàn)對(duì)底層不同音頻硬件的控制。
通常情況下,直接利用ALSA獲得的音頻數(shù)據(jù)量較大,不利于嵌入式環(huán)境下的存儲(chǔ)和遠(yuǎn)程傳輸。此時(shí)需要使用編解碼功能,對(duì)采集到的原始音頻數(shù)據(jù)進(jìn)行壓縮,并在音頻回放前解碼還原。目前最常用的音視頻編解碼技術(shù)為FFmpeg,它是一個(gè)技術(shù)領(lǐng)先的、多平臺(tái)的開源多媒體處理框架[5]。胡聰?shù)壤肍Fmpeg首先在嵌入式ARM9客戶端上采集數(shù)據(jù)并完成編碼工作,然后發(fā)送給Windows服務(wù)端進(jìn)行解碼與回放,取得了較好實(shí)驗(yàn)結(jié)果[6]。李軍延基于FFmpeg技術(shù)搭建了集音視頻轉(zhuǎn)換和上傳發(fā)布為一體的轉(zhuǎn)換與發(fā)布系統(tǒng),經(jīng)實(shí)驗(yàn)證明,該系統(tǒng)的音視頻轉(zhuǎn)換速度非常高,接近實(shí)時(shí)轉(zhuǎn)換,提高了網(wǎng)絡(luò)傳輸速率[7]。由此可見,F(xiàn)Fmpeg用于音視頻編解碼具有較好的性能,得到了廣大應(yīng)用研究者的認(rèn)可。
音頻數(shù)據(jù)的網(wǎng)絡(luò)傳輸具有數(shù)據(jù)量大、實(shí)時(shí)性要求高等特點(diǎn),與之對(duì)應(yīng)的網(wǎng)絡(luò)傳輸協(xié)議也要具備高實(shí)時(shí)性的能力[8,9]。UDP協(xié)議常用于基于網(wǎng)絡(luò)的語音傳輸,收發(fā)雙方不用事先建立連接,只需知道收方IP地址即可[10,11]。禹華鋼等在電臺(tái)通信中,給出了一種基于UDP協(xié)議的多線程語音通信方法,實(shí)現(xiàn)了兩種電臺(tái)工作模式的仿真[12]。趙付軒等實(shí)現(xiàn)一種WiFi語音通信方法,該方法基于UDP協(xié)議發(fā)送音頻數(shù)據(jù),利用Qt完成了實(shí)時(shí)音頻傳輸軟件的開發(fā)[13]。由上可知,UDP協(xié)議廣泛用于音頻數(shù)據(jù)的網(wǎng)絡(luò)傳輸。
綜上所述,利用ALSA完成音頻信號(hào)的采集與回放,利用FFmpeg完成音頻數(shù)據(jù)的編解碼,基于UDP協(xié)議完成數(shù)字音頻的網(wǎng)絡(luò)傳輸,每種技術(shù)都得到了廣泛的實(shí)際應(yīng)用。因此,本文將3種技術(shù)結(jié)合在一起,得到一種可靠的音頻采集、傳輸和回放的解決方案。
實(shí)現(xiàn)整個(gè)功能包括兩部分軟件設(shè)計(jì):一個(gè)是本地機(jī)軟件設(shè)計(jì),需要實(shí)現(xiàn)音頻信號(hào)采集、編碼和基于UDP協(xié)議的客戶端的功能;一個(gè)是遠(yuǎn)地機(jī)軟件設(shè)計(jì),需要實(shí)現(xiàn)基于UDP協(xié)議的服務(wù)器、音頻數(shù)據(jù)的解碼和音頻的回放的功能。
2.1 本地機(jī)軟件設(shè)計(jì)
本地機(jī)軟件采用多線程編程,其軟件流程圖如圖1所示。包括三種不同狀態(tài),首先是模塊初始化,包括建立遠(yuǎn)程連接、音頻設(shè)備和編碼器初始化打開;然后定義相關(guān)變量,執(zhí)行音頻采集、編碼和傳輸;最后在模塊關(guān)閉前,清除定義的相關(guān)變量,釋放內(nèi)存空間。
圖1 本地機(jī)軟件流程圖
2.2 遠(yuǎn)地機(jī)軟件設(shè)計(jì)
為了提高信號(hào)質(zhì)量,降低誤碼率,遠(yuǎn)地機(jī)軟件采用多線程與緩沖池的方法,開啟了三個(gè)線程。一個(gè)線程用于監(jiān)聽是否接收到數(shù)據(jù),并將其放入待解碼隊(duì)列。一個(gè)線程用于解碼,一旦待解碼隊(duì)列有數(shù)據(jù)時(shí),就開始解碼并將數(shù)據(jù)放入已解碼隊(duì)列中。一個(gè)線程用于音頻回放,該線程一直等候已解碼隊(duì)列中的數(shù)據(jù)并及時(shí)進(jìn)行回放,其工作流程如圖2所示。
圖2 遠(yuǎn)地機(jī)軟件流程圖
2.3 音頻信號(hào)的采集與回放
在PCM接口下,開發(fā)音頻信號(hào)處理的程序流程一般可用圖3表示。首先打開待操作的音頻設(shè)備獲得句柄,根據(jù)實(shí)際情況設(shè)置工作參數(shù),需要設(shè)置的硬件參數(shù)包括樣本長度、采樣率、聲道數(shù)、幀大小和周期等。完成相關(guān)設(shè)置后,音頻接口便可當(dāng)做流來使用,錄音即為讀數(shù)據(jù),回放即為寫數(shù)據(jù)。
圖3 PCM接口下音頻處理軟件流程圖
根據(jù)上述開發(fā)流程,具體的實(shí)現(xiàn)步驟如下
第一步打開音頻設(shè)備接口
利用結(jié)構(gòu)體snd_pcm_t定義設(shè)備句柄指針*handle,使用ALSA提供的設(shè)備打開函數(shù)
snd_pcm_open(&handle,"default",mode,0);
參數(shù)mode本文使用了代表回放的SND_PCM_STREAM_PLAYBACK,以及代表錄音的SND_PCM_STREAM_CAPTURE,該函數(shù)表示以某種模式,打開系統(tǒng)中默認(rèn)的音頻設(shè)備,若成功打開則獲得設(shè)備的操作句柄保存到參數(shù)handle中。
第二步設(shè)置音頻設(shè)備硬件參數(shù)
首先用結(jié)構(gòu)體snd_pcm_hw_params_t定義設(shè)備參數(shù)描述變量 *params,并用snd_pcm_hw_params_alloca函數(shù)給該變量分配內(nèi)存空間,再使用snd_pcm_hw_params_any函數(shù)初始化該變量。對(duì)于各參數(shù)的設(shè)置,ALSA中對(duì)應(yīng)的API分別如下所示
參數(shù)Para1為設(shè)備操作句柄handle,參數(shù)Para2為設(shè)備參數(shù)描述變量params,參數(shù)Para3對(duì)應(yīng)了不同變量具體的參考值。調(diào)用snd_pcm_hw_params(handle,params)函數(shù),作用到實(shí)際音頻設(shè)備完成參數(shù)設(shè)置工作。
第三步 音頻設(shè)備的錄音/回放
Linux系統(tǒng)中每個(gè)具體硬件的操作等同為文件操作,PCM音頻設(shè)備的錄音就等同于讀取PCM音頻流到內(nèi)存,回放就對(duì)應(yīng)于內(nèi)存音頻數(shù)據(jù)輸出給PCM音頻流。ALSA中音頻設(shè)備的錄音和回放對(duì)應(yīng)的API接口分別如下
snd_pcm_readi(handle,abuffer,frame_size);
snd_pcm_writei(handle,inbuf,frame_size);
參數(shù)abuffer開始錄音前事先定義的數(shù)據(jù)緩沖區(qū),它的大小可根據(jù)錄音或回放的時(shí)間、采樣率和楨長度確定,參數(shù)inbuf為解碼后待回放的音頻數(shù)據(jù),參數(shù)frame_size表示一次處理的楨數(shù)。
第四步關(guān)閉音頻設(shè)備接口
模塊運(yùn)行結(jié)束前,需要將所有掛起沒有傳輸完的數(shù)據(jù)傳輸結(jié)束,然后關(guān)閉音頻流釋放之前動(dòng)態(tài)分配的緩沖區(qū),ALSA中對(duì)應(yīng)的接口API分別如下
snd_pcm_drain(handle);/完成數(shù)據(jù)傳輸
snd_pcm_close(handle);/關(guān)閉音頻流,清除緩沖區(qū)
2.4 音頻數(shù)據(jù)的編解碼
基于FFmpeg實(shí)現(xiàn)音頻數(shù)據(jù)從PCM編碼轉(zhuǎn)換為AAC[14]編碼的程序流程可用圖4表示,整個(gè)流程主要分為3個(gè)階段:編碼器初始化打開,流程為查找編碼器,定義AVCodecContext變量設(shè)置編碼器相關(guān)參數(shù),然后打開編碼器;編碼前相關(guān)變量的定義,包括用于存儲(chǔ)編碼前音頻數(shù)據(jù)的AVFrame類型變量,并指向音頻數(shù)據(jù)緩沖區(qū),以及用于存儲(chǔ)編碼后音頻數(shù)據(jù)的AVPacket類型變量;關(guān)閉編碼器,清除定義的相關(guān)變量并釋放相應(yīng)的內(nèi)存空間。
圖4 FFmpeg音頻編碼流程圖
根據(jù)以上開發(fā)流程,基于FFmpeg的音頻編碼程序具體的實(shí)現(xiàn)步驟如下
第一步,編碼器初始化打開,其關(guān)鍵代碼如下
參數(shù)AV_CODEC_ID_AAC表示編碼器以AAC協(xié)議進(jìn)行編碼;給avcodecontext分配內(nèi)存后,需要對(duì)其相關(guān)參數(shù)設(shè)置,一般情況下需要設(shè)置的變量有平均采樣率、采樣模式、聲道布局等;avcodec_open2是指以avcodecontext的設(shè)置打開AAC編碼器。
第二步,定義編碼前相關(guān)變量并執(zhí)行編碼,其關(guān)鍵代碼如下
同樣給avframe分配內(nèi)存后,需要設(shè)置其參數(shù),包括 nb_samples(一次處理的幀數(shù))、format(原始數(shù)據(jù)類型)、channel_layout,該參數(shù)設(shè)置好后利用avcodec_fill_Audio_frame使之與存儲(chǔ)原始音頻數(shù)據(jù)的緩沖區(qū)abuffer相關(guān)聯(lián);avcodec_encode_Audio2利用編碼器avcodecontext將輸入的avframe音頻數(shù)據(jù)編碼后輸出給avpacket,成功編碼后output輸出為1否則為0。
第三步,通過調(diào)用 av_free_packet、av_frame_free、avcodec_close和av_free,清除相關(guān)變量同時(shí)關(guān)閉編碼器。
音頻數(shù)據(jù)的解碼流程和編碼流程相同,只是對(duì)應(yīng)于不同功能調(diào)用的API不同。但解碼得到的數(shù)據(jù)類型與ALSA用于回放的數(shù)據(jù)類型不符,這里用到了libswresample庫中swr_convert函數(shù)進(jìn)行數(shù)據(jù)轉(zhuǎn)換。整個(gè)轉(zhuǎn)換過程的具體實(shí)現(xiàn)如下
SwrContext*swr;
swr_convert(swr,p_buffer,out_cout,decodeddata,in_count)/轉(zhuǎn)換
swr_convert中第二個(gè)參數(shù)p_buffer待輸出緩沖區(qū)的指針,decodeddata表示解碼后的音頻數(shù)據(jù),參數(shù)in_count和out_count分別表示轉(zhuǎn)換前后的音頻數(shù)據(jù)單個(gè)聲道的空間大小。
2.5 基于UDP協(xié)議的客戶端與服務(wù)器
文中利用Boost.Asio網(wǎng)絡(luò)庫[15]實(shí)現(xiàn)基于UDP客戶端與服務(wù)器的建立,得益于網(wǎng)絡(luò)庫中包含了大量網(wǎng)絡(luò)相關(guān)API,開發(fā)難度大大降低??蛻舳私㈥P(guān)鍵步驟如下:
這種獲得服務(wù)器端點(diǎn)的方法為Asio給出的標(biāo)準(zhǔn)方法,在一些網(wǎng)絡(luò)通信程序中參數(shù)serverip為服務(wù)器域名,其IP地址并不唯一比如谷歌。此時(shí)利用解釋器resolver調(diào)用其成員函數(shù)query查找服務(wù)器IP和Port,并將得到的結(jié)果存入端點(diǎn)迭代器隊(duì)列,然后定義端點(diǎn)指針指向迭代器隊(duì)列方便后續(xù)使用。得到服務(wù)器端點(diǎn)后,調(diào)用socket.open與socket.set函數(shù)進(jìn)行socket的打開與相關(guān)參數(shù)設(shè)置。當(dāng)有音頻數(shù)據(jù)需要傳輸時(shí),調(diào)用socket.send函數(shù)完成數(shù)據(jù)的發(fā)送。
基于UDP的服務(wù)器建立與上述過程類似,相關(guān)參數(shù)設(shè)置包括協(xié)議類型、端口號(hào)、緩沖區(qū)大小等。初始化完成后開始異步接收,將接收到的數(shù)據(jù)放入待解碼隊(duì)列FIFO1中,并按照圖2中的所示的流程開始執(zhí)行解碼與回放。
該音頻采集與遠(yuǎn)程回放軟件應(yīng)用于遠(yuǎn)程控制短波發(fā)射系統(tǒng),適用于軍事、航空和航海等領(lǐng)域。在遠(yuǎn)程控制短波發(fā)射系統(tǒng)中,采用的是帶有Intel N455處理器的嵌入式主控板。待發(fā)射數(shù)據(jù)從音頻接口進(jìn)入主控板,設(shè)置音頻采樣參數(shù),包括采樣頻率44.1KHz、雙聲道采樣、采樣精度為16位,每次采集1024個(gè)樣本,于是每次采集音頻數(shù)據(jù)大小為4 KB。同時(shí)設(shè)置編碼器比特率為64 kbps,則編碼壓縮后的數(shù)據(jù)大小約為185B。從而滿足實(shí)時(shí)性要求,遠(yuǎn)地機(jī)回放流暢。如遇重大災(zāi)情,遠(yuǎn)程控制短波發(fā)射系統(tǒng)可快速組建緊急通信網(wǎng)絡(luò),及時(shí)傳播現(xiàn)場狀況,其處理具有實(shí)時(shí)可操作性。
文中將ALSA、FFmpeg和UDP傳輸協(xié)議結(jié)合在一起,有效地實(shí)現(xiàn)了嵌入式Linux下音頻信號(hào)的采集與回放、音頻數(shù)據(jù)的編碼與解碼以及音頻數(shù)據(jù)的網(wǎng)絡(luò)傳輸。實(shí)驗(yàn)測試表明,該方案執(zhí)行效率高,滿足設(shè)計(jì)目標(biāo),具有一定的實(shí)際參考價(jià)值。
[1]周濤,項(xiàng)嶸,李浩,等.基于嵌入式Linux的工業(yè)控制系統(tǒng)設(shè)計(jì)與實(shí)現(xiàn)[J].電子設(shè)計(jì)工程,2016(7):23-25.
[2]余棉水,解曉萌.嵌入式系統(tǒng)ALSA聲卡驅(qū)動(dòng)設(shè)計(jì)和實(shí)現(xiàn) [J].計(jì)算機(jī)光盤軟件與應(yīng)用,2012(10):180-181.
[3]周鵬,王承,湯銀煥,等.基于ALSA的WM8976音頻驅(qū)動(dòng)的設(shè)計(jì)[J].武漢理工大學(xué)學(xué)報(bào)(信息與管理工程版),2011,33(4):517-520.
[4]顏瑋,鄭晉.基于TCC8801的嵌入式Linux ALSA音頻驅(qū)動(dòng)設(shè)計(jì)與研究[J].科技信息,2013(23):100-102.
[5]LeiXiaohua,JiangXiuhua,WangCaihong.Design and Implementation of a Real-time Video Stream Analysis System Based on FFMPEG[C]//2013 Fourth World Congress on Software Engineering,2013(18):37-46.
[6]胡聰,周甜,唐璐丹.基于FFMPEG的跨平臺(tái)視頻編解碼研究[J].武漢理工大學(xué)學(xué)報(bào),2011,33(11):139-142.
[7]李軍延.利用FFMPEG技術(shù)搭建流媒體服務(wù)器[J].現(xiàn)代電子技術(shù),2014,37(18):23-25.
[8]黃云.基于CobraNet的網(wǎng)絡(luò)音頻傳輸?shù)脑O(shè)計(jì)與實(shí)現(xiàn)[J].計(jì)算機(jī)與網(wǎng)絡(luò),2015(24):66-69.
[9]王銳,趙紅東.一種網(wǎng)絡(luò)傳輸中實(shí)時(shí)音頻數(shù)據(jù)丟包恢復(fù)的方法[J].電子設(shè)計(jì)工程,2011(9):16-18.
[10]Botta A,Pescape A.IP packet interleaving for UDP bursty losses [J].Journal of Systems and Software,2015(109):177-191.
[11]B otta A,Pescape A.IP packet interleaving for UDP bursty losses [J].Journal of Systems and Software,2015,109:177-191.
[12]禹華鋼,周安棟,劉宏波.多線程語音通信在模擬電臺(tái)通信中的應(yīng)用[J].火力與指揮控制,2010,35(3):42-45.
[13]趙付軒,楊斌.基于QT的WiFi語音通信系統(tǒng)[J].單片機(jī)與嵌入式系統(tǒng)應(yīng)用,2012,12(9):63-66.
[14]Vladimir B.New fast algorithms for the low delay MDCT computation in theMPEG-4 AAC enhanced low delay Audio coding standard[J].Signal Processing,2014(105):410-418.
[15]吳克松,陳浩然,董建平.基于IOCP的Boost.Asio的研究及在高清MCU中的應(yīng)用 [J].數(shù)據(jù)通信,2015(2):11-14.
Implementation of audio capture and playback remotely base on embedded Linux system
KANG Jing-xin,ZHANG Tian
(Mechanical and Electrical Engineering Institute,Beijing University of Chemical Technology,Beijing 100029,China)
In order to achieve the audio transmission remotely of the remote communication transmission system,the design of local audio capturing and transmitting to remote system to playback based on Embedded Linux system is designed in this paper.The ALSA is used to complete the local audio data collection,and the data will be encoded to AAC format which is suitable for remote transmission by using FFmpeg,then the AAC data will be transmitted to remote system via Ethernet based on UDP protocol.At the remote system,the FFmpeg and ALSA are used to complete the audio decoding and playback respectively.The experiment result show that the playback of audio signals is naturally and clearly,and the implementation of the program is steady and highly reliable.
Linux;FFmpeg;UDP;ALSA
TN919
:A
:1674-6236(2017)13-0130-05
2016-05-31稿件編號(hào):201605308
康敬欣(1972—),女,河北定州人,博士,講師。研究方向:傳感與測控技術(shù)、武器系統(tǒng)仿真、信號(hào)分析與處理。