音頻處理介紹(Linux手機)
轉(zhuǎn)載時請注明出處和作者聯(lián)系方式
作者聯(lián)系方式:李先靜 <xianjimli at hotmail dot com>
昨天從整體上介紹了一下音頻處理流程,讓大家對音頻處理有個大致的概念,以便進行深入的研究。
整個音頻處理可以分為三個部分:
用戶空間
Mplayerservice 它是一個獨立的服務進程,其主要作用有;
- 首先是充當一個抽象層,隔離下層的軟件和硬件平臺,讓應用程序不受下層變化的影響,比如以前我們用mplayer,現(xiàn)在改為用gstreamer,上層應用程序不需要做任何修改。
- 其次是負責播放任務的調(diào)度,上層有很多個應用程序要播放聲音,像SMS,MMS,EMAIL,電話,媒體播放器和GUI等等,它們之間如何協(xié)調(diào),這是很重要的。
- 最后它在MVC模型中充當模型的作用,播放狀態(tài)可以由此轉(zhuǎn)發(fā)給關心這些事件的應用程序。
Gstreamer 它是Mplayerservice的實現(xiàn),其主要負責音視頻的編解碼,對此不太熟悉,而且已經(jīng)有很多資料介紹,這里就不多說了。
ALSA lib 現(xiàn)在播放聲音用的ALSA,而不是OSS了,ALSA內(nèi)核提供的接口比較底層,ALSA lib把它們包裝成易用的接口函數(shù)。
內(nèi)核空間
ALSA接口: 通過/dev/snd下的設備文件與用戶空間進行交互,對于聲音數(shù)據(jù),它提供了兩種交互方式,一種是基于文件IO的讀寫方式,播放時向里面寫數(shù)據(jù),錄音時從里面讀數(shù)據(jù)。另外一種是基于內(nèi)存映射的方式,通過mmap把DMA內(nèi)存映射到用戶空間,直接從里面讀寫數(shù)據(jù)。
ALSA core: 這塊是比較復雜的,它主要的功能是抽取各種不同驅(qū)動的公共代碼;為上層提供統(tǒng)一的接口;為下層提供一個框架。不過我們主要關心的是PCM數(shù)據(jù)的播放和讀寫,以及對硬件的控制。
ALSA driver: 這一部分就是實際的驅(qū)動程序,包括與上面對應的PCM和Control兩部分。
硬件
音頻芯片我們用的是WM9713,它的主要功能其實就是A/D轉(zhuǎn)換和D/A轉(zhuǎn)換,播放時把數(shù)字信號轉(zhuǎn)換成模擬信號,錄音時把模擬信號轉(zhuǎn)換成數(shù)字信號。因為觸摸屏也用到了A/D轉(zhuǎn)換,為了重用這個功能,所以WM9713集成了音頻處理和觸摸屏處理兩部分功能。
WM9713支持AC97標準,通過64個寄存器對它進行控制,這個在WM9713的datasheet里有詳細的描述。
WM9713與PXA300之間通過同步串號SSP通信。PXA300在硬件上對AC97有支持,它提供了FIFO,所以音頻數(shù)據(jù)可以通過DMA方式讀寫。
驅(qū)動程序?qū)ёx
sound/arm/codec/ac97acodec.c包裝了對AC97寄存器的讀寫操作,zy_ac97_acodec_write向指定的偏移量寫入數(shù)據(jù),zy_ac97_acodec_read從指定的偏移量讀取數(shù)據(jù)。&(p_ac97_reg->codec_regs_primary_aud[0])是寄存器的基址。
sound/arm/codec/acodec.c 提供codec的初始化和~初始化以及電源管理的suspend和resume函數(shù)。AC97的PIN配置可以參考arch/arm/mach-pxa/zylonite.c:zylonite_ac97_pins。
sound/arm/codec/lt*是marvell另外一個硬件平臺Littleton的驅(qū)動。
sound/arm/codec/wm9713.c,這里面主要是對AC97控制功能的包裝,提供比如像設置音量之類的函數(shù),zy_acodec_set_pen_down_interrupt/zy_wm9713_enable_touch/zy_wm9713_disable_touch/zy_wm9713_disable_touch幾個函數(shù)用于觸摸屏控制和采樣。
sound/arm/codec/wm9713_bb.c好像是用于BaseBand的,里面的內(nèi)容與wm9713類似,具體差別還不是很清楚, 希望哪位高手能告知。 有時間再研究一下。
sound/arm/mhn_audio_card.c 聲卡驅(qū)動入口,提供audio_codec_zy_driver結(jié)構(gòu),通過driver_register注冊到內(nèi)核里去,在audio_codec_zy_probe函數(shù)中創(chuàng)建聲卡對象,并注冊到ALSA框架中。
sound/arm/mhn_audio_control.c 對codec/wm9713.c中的函數(shù)進一步包裝,通過audio_codec_control_new為聲卡創(chuàng)建一個控制對象。
sound/arm/mhn_audio_pcm.c 對PCM對象進行包裝,audio_codec_pcm_new中可以創(chuàng)建HIFI PCM和Voice PCM,兩個的差別,我不太清楚,希望哪位高手能告知。SSP的初始化和~初始化也是在這里做的。
sound/arm/mhn_audio_voice_pcm.c 實現(xiàn)了voice PCM對象,其核心就是結(jié)構(gòu)voice_pcm_ops,該結(jié)構(gòu)中最重要的成員是voice_pcm_trigger,voice_pcm_trigger負責DMA傳輸?shù)钠饎雍屯V埂?
sound/core/pcm_native.c 對下層的PCM驅(qū)動提供包裝,為上層提供統(tǒng)一的接口,snd_pcm_f_ops_playback文件操作結(jié)構(gòu)提供播放功能的函數(shù),snd_pcm_f_ops_capture文件操作結(jié)構(gòu)提供錄音功能的函數(shù)。
sound/core/control.c對下層的Control驅(qū)動提供包裝,為上層提供統(tǒng)一的接口,snd_ctl_f_ops文件操作結(jié)構(gòu)提供控制功能函數(shù),其中主要是snd_ctl_ioctl函數(shù)。
播放的過程大致如下:
Snd_pcm_f_ops_playback.write即snd_pcm_write調(diào)用snd_pcm_lib_write
snd_pcm_lib_write調(diào)用Snd_pcm_lib_write1
Snd_pcm_lib_write1通過snd_pcm_lib_write_transfer把數(shù)據(jù)寫入DMA buffer中,然后調(diào)用snd_pcm_start開始DMA傳輸數(shù)據(jù)到WM9713里去。
錄音的過程大致如下:
Snd_pcm_f_ops_capture.read即snd_pcm_read調(diào)用snd_pcm_lib_read
snd_pcm_lib_read調(diào)用snd_pcm_lib_read1
snd_pcm_lib_read1調(diào)用snd_pcm_start從WM9713傳輸數(shù)據(jù)到DMA內(nèi)存中,然后調(diào)用snd_pcm_lib_read_transfer拷貝數(shù)據(jù)到用戶的buffer.
~~end~~
?
Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=1872258
更多文章、技術(shù)交流、商務合作、聯(lián)系博主
微信掃碼或搜索:z360901061
微信掃一掃加我為好友
QQ號聯(lián)系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元

