標籤:

ALSA編程指南

硬體概覽?

計算機中音效卡的設計幾乎從來沒有過統一標準,所以,音效卡的自身的設計本身是變化多端的。但是,通常常見的音效卡都可以抽象出幾個部分:

  • 輸入設備:比如麥克風(模擬/電子),從其他音響設備結果來的LINE IN;
  • ADC:模擬信號到數字信號轉換器;音效卡可以處理的信號是數字信號,當有輸入進入音效卡時,輸入通常是模擬信號,比如傳統的麥克風給出的信號就是模擬信號,這是就需要ADC將模擬信號轉換成聲音信號;
  • 信號處理和控制核心:這部分是音效卡的核心,一般由一個或者多個codec實現;
  • DAC:數字信號到模擬信號的轉換器;它的功能就是將處理好的數字信號轉化成模擬信號;
  • MIXER:俗稱混音器;這個設備主要的功能是將不同輸入來源的聲音信號混合起來並且轉發到不同的輸出設備上去;比如,想像一下一邊聽音樂一邊音頻聊天的情景,混音器需要將從麥克風過來的語音內容和播放器傳說過來的音樂混合起來轉發到耳機上;而當耳機拔出脫離音效卡時,混音器需要將聲音信號轉發的計算機的喇叭上去;等等;
  • 輸出設備:喇叭,LINE OUT和麥克風都是輸出設備;放大器也可以被看作輸出設備,通常放大器不需要軟體控制,也就是不需要有驅動程序就可以動作;放大器的主要功能就是將聲音信號放大,增加響度等等。
  • ↑Audio Interface?

    Audio Interface主要是指可以將聲音數據從計算機中傳入傳出的介面。常見的Audio Interface有I2S和AC97兩種。其中,I2S多用與嵌入式設備上的聲音數據傳輸,而AC97介面則多見於傳統PC。這兩種介面有什麼不同呢?這裡暫且擱置不談。對聲音程序的開發者來說,跟重要的是理解Audio Inferface的概念而非細節。細節就留給硬體工程師和驅動開發者吧。

    在計算機內部,聲音被表示成為位元組流(stream bit),與其他類型的數據並沒有差異。而在計算機的外部世界,通常,聲音可以被表示成為數字形式(一個或這多個位元組流)或者模擬形式(按照時間表示的電壓變化)。Audio Interface的主要任務就是將計算機內部外部世界的不同數據類型進行轉化。Audio Inferface的構成當然和它的功能有著必然的聯繫。當聲音通過Audio Inferface傳入計算機內部時,經過轉化的數據(位元組)將被暫時存儲在一個硬體上的緩衝區中,當緩衝區已滿,Audio Interface就會觸發一個中斷,要求CPU協調將數據從緩衝區移動到適當的地方去,通常,這種數據移動都是以DMA的方式進行,而且,通常數據移動的目的地就是主存。

    +---------------------------------+ |Audio +----------------+ |Audio Signal ----|Interface-----+ HW BUFFER | | | +----------------+ | +---------------------------------+

    將數據從計算機傳出的過程於此類似,只是方向正好相反,中斷觸發的時機也不同。Audio Interface會在硬體緩衝區被搬走後清空的情況下觸發終端,要求CPU協調傳送新的數據進入緩衝區。

    從上面的描述就可以看出,Audio Interface有幾個要素需要開發者注意。

  • 數據轉換的格式;
  • 數據轉換的速率;
  • 需要多少數據/空閑空間來觸發中斷;
  • 硬體緩衝區的大小;
  • 以上要素中,前兩個決定了聲音信號/數據的質量,而後兩者決定了「延遲」。一般延遲有「輸入延遲」和「輸出延遲」兩種。輸入延遲指的是數據開始傳輸進入硬體緩衝區的時刻和CPU得到完成數據移動的那個時刻之間的時間差;輸出延遲與次類似,方向相反。

    ↑ALSA是什麼??

    ALSA是Advanced Linux Sound Architecture的縮寫。回答完畢。

    這樣答未免太無聊了,但畢竟有了一個給傻瓜寫的教科書一樣開頭。ALSA是為Linux並且不限於Linux操作系統而設計的一套軟體棧,它為聲音相關的硬體提供了硬體抽象;應用程序可以通過一個統一的介面操作音效卡的硬體而不需要關係具體的細節;

    ↑ALSA程序的結構?

    ALSA程序的結構非常簡單。

    open_the_device(); /* 打開聲音輸入/輸出設備 */set_the_parameters_of_the_device(); /* 設置該設備的參數,最終要的就是前文提到的四個參數 */while(!done) { /* one or both of these */ receive_audio_data_from_the_dev(); /* 從設備接收數據 */ deliver_audio_data_to_the_dev(); /* 向設備發送數據 */}close_the_device(); /* 關閉聲音輸入輸出設備 */

    ↑與ALSA相關的資源?

  • ALSA項目的主頁
  • http://www.alsa-project.org/main/index.php/Main_Page

    這裡是ALSA相關的所有內容的源頭,包括代碼和文檔,如果想要弄懂聲音如何在Linux中工作,狠狠扎進這一堆財富裡面吧!

  • Documentation/sound/alsa/*
  • 內核源碼中的文檔也是相當的言簡意賅,這裡要著重推薦。其中,推於嵌入式設備或者Android開發者來說,soc目錄中的文檔堪稱字字珠璣。ASoC主要是由Wolfson公司的開發人員推動和撰寫的,這幾個文檔詳細講述了如何開發ASoC驅動的幾乎所有內容。

  • http://www.alsa-project.org/alsa-doc/alsa-lib/index.html
  • 這是用doxygen從代碼注釋中產生的ALSA用戶空間庫文檔,相當的翔實,建議加入收藏夾中。

    ↑ALSA的體系結構?

    上圖之中,Control和PCM部分是理解ALSA如何工作的關鍵。

    ↑PCM?

    PCM是最常見的數字音頻信號形式之一,ALSA驅動提供了一些對PCM進行操作和配置的介面函數;雖然PCM可以廣泛用於音頻信號傳輸以外的很多應用上,在編寫ALSA驅動和應用時,可以簡單的認為它就是依時間軸上不斷變化的聲音的樣本;

    比如,下面這個典型的聲音信號,

    轉化成PCM之後變成了這樣:

    很顯然,PCM上聲音的質量取決於兩個方面,

  • 第一就是採樣的密度,也就是時間軸上的間隔;時間間隔越小,聲音的質量越好;
  • 第二就是它可以表示的電壓的粒度;電壓級別劃分越細緻,聲音的質量越好;
  • ↑Control介面?

    Control是ALSA為用戶空間應用程序提供的控制音效卡的頻頻路徑(輸入輸出重定向),音量大小,輸入輸出設備選擇和配置的介面。ALSA控制介面可以控制的兩類主要元素是聲音的路徑和音量的大小;其中,在嵌入式設備上,聲音的路徑控制是通過驅動程序提供的DAPM介面實現的;而音量控制,是通過介面控制MIXER做到的。

    ↑ALSA用戶空間C庫概覽?

    http://www.alsa-project.org/alsa-doc/alsa-lib/index.html

    ↑PCM操作相關?

    http://www.alsa-project.org/alsa-doc/alsa-lib/pcm.html

    ↑Audio Clips?

    Audio sample rate conversion (SRC) or audio resampling is the process of changing the audio sample rate without affecting the quality. Broadcast audio infrastructure equipment typically requires 48-kHz synchronous sampling rate audio signals. However, the audio inputs to the audio equipment can be from sources with different sampling rates. For example, CD audio signals have a sampling rate of 44.1 kHz, while other audio sources have sampling rates from 32 kHz to 192 kHz.


    推薦閱讀:

    C語言基礎:指針與數組
    技術真的沒用嗎
    走少有人走的路:編程真TM難學
    一張圖告訴你該選哪種編程語言

    TAG:編程 |