2011-04-12 21:10:24| 分類: Linux音頻-ALSA S |字號(hào) 訂閱
關(guān)于ALSA(Advanced Linux Sound Architecture)中文資料真的很少,可能是國(guó)人很少真的從零開(kāi)始做驅(qū)動(dòng)開(kāi)發(fā)的原因。畢竟像wolfson或者realtek這樣的公司多還是老外在做開(kāi)發(fā)。ALSA 對(duì)SOC支持,更是ALSA在嵌入式領(lǐng)域的應(yīng)用,也是后來(lái)才加入到ALSA中的,那資料更是少了。我花了一個(gè)星期也幾乎沒(méi)有任何發(fā)現(xiàn),而后通過(guò)零星資料的蛛絲馬跡,終于對(duì)ALSA有感覺(jué)了。對(duì)今后的繼續(xù)學(xué)習(xí)是非常有幫助的。
按通常的三層分類方式,從下到上,依次是ALSA driver、ALSA lib、ALSA application。
ALSA application包括aplay、arecord,他們屬于ALSA utils的工具。這些工具用于測(cè)試驅(qū)動(dòng)非常的好。
ALSA lib提供諸如打開(kāi),關(guān)閉,播放的函數(shù)庫(kù)
ALSA driver是后來(lái)才加入了對(duì)SOC的支持,并且將hardware audio codec的控制抽象出來(lái),放在sound/soc/codecs的目錄里。而和SOC硬件相關(guān)的代碼抽象出來(lái)放在omap目錄里(加入SOC是omap)。這種分離式的設(shè)計(jì)使得一個(gè)codec的代碼,在不做任何修改的情況下,可以對(duì)應(yīng)很多的SOC。(把通用的代碼盡量抽象出來(lái)是驅(qū)動(dòng)程序架構(gòu)設(shè)計(jì)一直追求的目標(biāo))
ALSA的SOC中的一個(gè)大家伙,就是DAPM (Dynamic Audio Power Management),它將電源劃分為4個(gè)域:
Codec domain - VREF, VMID (core codec and audio power) Usually controlled at codec probe/remove and suspend/resume, although can be set at stream time if power is not needed for sidetone, etc.
Platform/Machine domain - physically connected inputs and outputs Is platform/machine and user action specific, is configured by the machine driver and responds to asynchronous events e.g when HP are inserted
Path domain - audio susbsystem signal paths Automatically set when mixer and mux settings are changed by the user. e.g. alsamixer, amixer.
Stream domain - DACs and ADCs. Enabled and disabled when stream playback/capture is started and stopped respectively. e.g. aplay, arecord.
對(duì)于codec domain,它位于sound/soc/codecs目錄下,例如wm9713.c。
對(duì)于Platform/Machine domain,他放在machine名字的目錄里,如sound/soc/s3c24xx目錄下neo1973_wm9753.c,以機(jī)器名和codec的名字同時(shí)命名。
在定義codec的audio path的時(shí)候,你需要知道這樣的背景知識(shí),DAPM在概念上分為以下部件,
Mixer - Mixes several analog signals into a single analog signal.
Mux - An analog switch that outputs only one of many inputs.
PGA - A programmable gain amplifier or attenuation widget.
ADC - Analog to Digital Converter
DAC - Digital to Analog Converter
Switch - An analog switch
Input - A codec input pin
Output - A codec output pin
Headphone - Headphone (and optional Jack)
Mic - Mic (and optional Jack)
Line - Line Input/Output (and optional Jack)
Speaker - Speaker
Pre - Special PRE widget (exec before all others)
Post - Special POST widget (exec after all others)
可以看出這些部件主要也是抽象了codec內(nèi)部的硬件構(gòu)件。audio path是路徑,所以有輸入,輸出的概念。除了path的終點(diǎn),每個(gè)部件都包含輸入口,和輸出口。
對(duì)于path上輸入的開(kāi)始端點(diǎn),它只需要輸出到下一個(gè)部件就好。同理對(duì)于path上輸出的端點(diǎn),它只需要從前一個(gè)部件輸入就好。path的頭尾端點(diǎn)就是用SND_SOC_DAPM_INPUT或者SND_SOC_DAPM_OUTPUT定義這個(gè)部件。
codec中都有混音器,它總是把多個(gè)輸入加和為一個(gè)輸出信號(hào),他就由SND_SOC_DAPM_MIXER定義。
同樣,codec中也會(huì)有一些多路開(kāi)關(guān),他是有多個(gè)輸入,但是只有一個(gè)輸入可以和輸出接通,這樣的部件由SND_SOC_DAPM_MUX定義。
PGA就如它在硬件中的名字,一般就是一個(gè)輸入,和一個(gè)輸出。用SND_SOC_DAPM_PGA定義
OK,你的codec代碼中將所有可能的path全部連接起來(lái),問(wèn)題來(lái)了,對(duì)于每一個(gè)audio path都有一個(gè)頭,和一個(gè)尾。但是這條path中間可以走的路那就很多了,也不是一定的。尤其對(duì)于手機(jī)里的場(chǎng)景中audio path,可以有speaker路徑,headphone路徑,A2DP路徑,GSM phone路徑或者M(jìn)IC路徑,很多了,我要根據(jù)需要打開(kāi)或者關(guān)閉這些路徑。我被這個(gè)問(wèn)題困惑了很久,ALSA的設(shè)計(jì)中到底由哪個(gè)部分負(fù)責(zé)。一開(kāi)始我還懷疑是不是codec的audio path沒(méi)有定義完整?或者ALSA有切換這種場(chǎng)景的函數(shù)?再或者由machine代碼來(lái)定義這樣的路徑?
后來(lái)我的猜想都不正確。Audio Codec中有許多部件,并且可以是任意的名字,ALSA怎么可能知道該如何操作這些部件來(lái)切換到你想要的路徑,即時(shí)ALSA lib也不會(huì)關(guān)心這部分內(nèi)容,這些細(xì)微的切換又ALSA application以上來(lái)完成,ALSA lib也最多提供各種操作mixer或者M(jìn)ux的函數(shù),如果切換是你應(yīng)用的事情。
對(duì)部件的操作函數(shù)是snd_mixer_selem_set_enum_item(),alsamixer也是通過(guò)這個(gè)函數(shù)達(dá)到切換的目的
本文來(lái)自CSDN博客,轉(zhuǎn)載請(qǐng)標(biāo)明出處:http://blog.csdn.net/cpuwolf/archive/2009/10/17/4686830.aspx
聯(lián)系客服