ALSA 架構

ALSA 架構

主要內容來之參考文檔,對一些描述作了些修正.

alsa.png

ALSA 的基本架構能夠用上圖表示,組成部分主要有:linux

  • ALSA 應用:多是 Native Application 或 Server,用戶經過調用 ALSA 庫來實現聲音的播放、錄製和控制。
  • ALSA Library :ALSA 用戶空間庫,提供統一的API,常見有 tinyalsa、alsa-lib等。
  • ALSA Layer:內核中 ALSA 核心層,與應用層的 ALSA Library 進行交互。向上提供邏輯設備系統調用,向下驅動硬件設備。主要內容爲 ALSA core 和一些輔助驅動。
  • ASoC Layer:ASoC 是爲支持 SoC 芯片設計的。SoC 芯片的集成度較高,傳輸總線、DSP、甚至 Codec 都有可能集成在一個芯片上。ASoC 層提供了一個嵌入式系統的設備管理框架,由三個部分組成:Machine、Platform、Codec。

ALSA 應用

ALSA 應用調用 ALSA 庫提供的 API 來實現本身的需求。ALSA 庫不一樣,代碼實現差異也很大,這裏不會作過多介紹。咱們只是以 tinyalsa 爲例,介紹一下聲音播放的簡單流程。git

struct pcm_config config;
    struct pcm *pcm;
    char *buffer;
    int size;
    int num_read;

    /* 設置音頻的配置,通道、採樣率、採樣週期、編碼格式等等 */
    config.channels = xxx;
    config.rate = xxx;
    config.period_size = xxx;
    config.period_count = xxx;
    config.format = xxx;
    
    /* 打開 PCM 設備 */
    pcm = pcm_open(card, device, PCM_OUT, &config); 

    /* 根據音頻配置計算須要的 buffer */
    size = pcm_frames_to_bytes(pcm, pcm_get_buffer_size(pcm));
    buffer = malloc(size);

    /* 讀取數據,寫入到 PCM 設備中 */
    do {
        num_read = fread(buffer, 1, size, file);
        if (num_read > 0) 
            pcm_write(pcm, buffer, num_read));
    } while (num_read > 0);

    /* 釋放 buffer,關閉設備 */
    free(buffer);
    pcm_close(pcm);
}

ALSA Library

應用通常經過 ALSA Library 與內核空間交互,儘管各類 Library 在實現上差異很大,但最終都是經過 Kernel ALSA Layer 提供系統調用完成調用。數據結構

  • alsa-lib:ALSA 項目中提供的應用接口庫,能夠提供所有的接口支持,包括 PCM、Control、MIDI、Mixer、Sequencer、Timer等。同時在軟件層面支持採樣率轉換、軟件混音等複雜的實現。
  • tinyalsa:tinyalsa 是一個簡化的 ALSA Library,在 Android 中被使用。tinyalsa 僅支持 PCM 和 Control 接口,軟件層面也很是簡單。正由於其簡單,因此很適合在嵌入式系統中使用。

ALSA Layer

ALSA Layer 是 ALSA 架構的核心層,在內核空間實現。它爲用戶空間提供邏輯設備接口,如PCM、Control、Mixer等等。同時爲驅動提供接口來驅動硬件設備,如總線接口、DMA、Codec等等。架構

該層的主要數據結構包括,框架

- snd_card      表示一個聲卡實例, 包含多個聲卡設備
- snd_device    表示一個聲卡設備部件
- snd_pcm       表示一個PCM設備, 聲卡設備的一種, 用於播放和錄音
- snd_control   表示Control設備, 聲卡設備的一種, 用於控制聲卡
- snd_pcm_str   表示PCM流, 分爲playback和capture
- snd_pcm_substream PCM子流, 用於音頻的播放或錄製
- snd_pcm_ops   PCM流操做集

各數據結構的關係以下,編碼

alsa_codes.png

核心驅動的通常實現步驟以下,spa

  1. 調用snd_card_create建立聲卡實例(struct snd_card)。
  2. 定義聲卡的私有結構體用於存放該聲卡的一些資源信息, 如中斷資源、IO資源、DMA資源等。
  3. 硬件初始化, 包括數字音頻接口初始化、DMA控制器初始化、編解碼器初始化。
  4. 調用snd_pcm_new建立邏輯設備, 並實現其操做集snd_pcm_ops。
  5. 調用snd_card_register註冊聲卡實例及聲卡設備

ASoC Layer

爲了簡化 SoC 芯片上 ALSA 驅動的開發,在覈心層的基礎上構建了 ASoC(ALSA System on Chip) 層。ASoC 層主要由以下三部分組成:設計

  • Codec:控制音頻編解碼器,完成音頻採集和播放過程當中模擬與數字間的轉換。
  • Platform:主要負責 SoC 芯片上音頻 DMA 的傳輸控制,和數字音頻接口的配置和控制,如I2S、PCM、AC97等。
  • Machine:作爲 Codec 和 Platform 的載體,將硬件設備關聯起來,造成完整的硬件通路。

ASoC Layer 主要負責驅動音頻硬件設備,對外表現爲一個總體的 Machine。Platform 控制 SoC 芯片中數字音頻傳輸。Codec 控制音頻編解碼器,可能爲內置或外置,一般使用 I2C 進行控制。3d

ASoC 支持三種主流的數字音頻接口(Digital Audio Interfaces):AC9七、I2S 和 PCM。注意這裏的 PCM 表示只有硬件接口協議,與上面所說的軟件 PCM 接口不一樣。code

AC97: 一般用於PC聲卡, 爲5線接口, 每一個AC97幀爲21uS長, 被分爲13個時隙

  • BCLK: 由AC97驅動, 爲12.288 MHz
  • SYNC: 同步信號, 由Controler驅動, 爲48 kHz
  • SDATDIN: 用於capture, AC97->Controler
  • SDATAOUT: 用於playback, Controler->AC97
  • RESET: 由Controler生成, 用於喚醒AC97

I2S是HiFi、STB和便攜式設備中經常使用的4線DAI

  • SCLK: 串行時鐘
  • LRCK: 也稱WS, 聲道選擇線
  • Tx: 用於傳輸音頻數據
  • Rx: 用於接收音頻數據

PCM是另外一種4線接口, 與I2S很是類似, 能夠支持更靈活的協議

  • BCLK: 位時鐘, 根據採樣率而變化
  • SYNC: 同步信號
  • Tx: 用於傳輸音頻數據
  • Rx: 用於接收音頻數據

Codec驅動用於配置編解碼器、FM、MODEM、BT 或外部 DSP, 以提供 playback 和 capture。每一個Codec驅動必須提供以下功能:

  1. Codec DAI和PCM配置
  2. 使用RegMap實現的Codec控制IO
  3. Mixers和Audio控制
  4. Codec音頻操做
  5. DAPM描述
  6. DAPM事件處理
  7. DAC靜音控制(可選)
參考文檔:

Linux ALSA詳解

相關文章
相關標籤/搜索