alsa 編程
轉載自:http://blog.csdn.net/spygg/article/details/7824750
?
ALSA(Advanced Linux Sound Architecture)是由內核驅動,標準的API庫和一系列實用程序組成.因為涉及到版權和BUG的問題Linux 2.6內核拋棄了舊的OSS,ALSA作為聲音編程的生力軍被作為了合并到了內核中.
?
數字音頻基礎:
音頻是由電器設備(麥克風等)將空氣的變化轉化成的電信號.模數轉換器(A/D)將模擬電壓轉化成一系列不連續的值稱之為采樣,然后將采樣值送往數模轉化器(D/A)從而將聲音還原.采樣的頻率是影響數字聲音質量的一個關鍵因素,由Nyquist采樣定理知,采樣的頻率至少是信號中最高頻率的2倍方能的還原原始信號.
ALSA基礎知識:
?ALSA由許多聲卡的聲卡驅動程序組成,同時它也提供一個稱為libasound的API庫。應用程序開發者應該使用libasound而不是內核中的ALSA接口。因為libasound提供最高級并且編程方便的編程接口。并且提供一個設備邏輯命名功能,這樣開發者甚至不需要知道類似設備文件這樣的低層接口。相反,OSS/Free驅動是在內核系統調用級上編程,它要求開發者提供設備文件名并且利用ioctrl來實現相應的功能。為了向后兼容,ALSA提供內核模塊來模擬OSS,這樣之前的許多在OSS基礎上開發的應用程序不需要任何改動就可以在ALSA上運行。另外,libaoss庫也可以模擬OSS,而它不需要內核模塊。ALSA包含插件功能,使用插件可以擴展新的聲卡驅動,包括完全用軟件實現的虛擬聲卡。ALSA提供一系列基于命令行的工具集,比如混音器(mixer),音頻文件播放器(aplay),以及控制特定聲卡特定屬性的工具.
?
ALSA接口:
控制接口:用來管理已注冊的聲卡并檢查其可用的設備
?
PCM接口:用來管理數字音頻的錄音和回放,這是一個用的最廣泛的接口,我們將在下文中著重介紹.
?
原始 MIDI 接口:支持標準MIDI(Musical Instrument Digital Interface),提供了訪問聲卡MIDI的接口.
?
時間接口:用來聲卡的計時聲音事件的同步
?
Sequencer接口:高級MIDI和聲音合成接口,可以處理更多的MIDI協議
?
混音接口:用來聲卡設備的信號處理和音量,建立在控制接口之上
?
設備命名:
?API庫使用邏輯設備名而不是設備文件。設備名字可以是真實的硬件名字也可以是插件名字。硬件名字使用hw:i,j這樣的格式。其中i是卡號,j是這塊聲卡上的設備號。第一個聲音設備是hw:0,0.這個別名默認引用第一塊聲音設備并且在本文示例中一直會被用到。插件使用另外的唯一名字。比如plughw:,表示一個插件,這個插件不提供對硬件設備的訪問,而是提供像采樣率轉換這樣的軟件特性,硬件本身并不支持這樣的特性。
?
聲音緩存和數據傳輸:
??每個聲卡都有一個硬件緩存區來保存記錄下來的樣本。當緩存區足夠滿時,聲卡將產生一個中斷。內核聲卡驅動然后使用直接內存(DMA)訪問通道將樣本傳送到內存中的應用程序緩存區。類似地,對于回放,任何應用程序使用DMA將自己的緩存區數據傳送到聲卡的硬件緩存區中。
?? ? ?這樣硬件緩存區是環緩存。也就是說當數據到達緩存區末尾時將重新回到緩存區的起始位置。ALSA維護一個指針來指向硬件緩存以及應用程序緩存區中數據操作的當前位置。從內核外部看,我們只對應用程序的緩存區感興趣,所以本文只討論應用程序緩存區。
?
?? ? ?應用程序緩存區的大小可以通過ALSA庫函數調用來控制。緩存區可以很大,一次傳輸操作可能會導致不可接受的延遲,我們把它稱為延時(latency)。為了解決這個問題,ALSA將緩存區拆分成一系列周期(period)(OSS/Free中叫片斷fragments).ALSA以period為單元來傳送數據。
?
?? ? ?一個周期(period)存儲一些幀(frames)。每一幀包含時間上一個點所抓取的樣本。對于立體聲設備,一個幀會包含兩個信道上的樣本。圖1展示了分解過程:一個緩存區分解成周期,然后是幀,然后是樣本。圖中包含一些假定的數值。圖中左右信道信息被交替地存儲在一個幀內。這稱為交錯(interleaved)模式。在非交錯模式中,一個信道的所有樣本數據存儲在另外一個信道的數據之后。
設置參數,參數設置不當將會導致音頻設備無法正常工作。在設置參數前,我們需要了解一下各個參數的含義以及一些基本概念。
樣本長度(sample):樣本是記錄音頻數據最基本的單位,常見的有8位和16位。
?
通道數(channel):該參數為1表示單聲道,2則是立體聲。
楨(frame):楨記錄了一個聲音單元,其長度為樣本長度與通道數的乘積。
采樣率(rate):每秒鐘采樣次數,該次數是針對楨而言。
周期(period):音頻設備一次處理所需要的楨數,對于音頻設備的數據訪問以及音頻數據的存儲,都是以此為單位。