主要內容來之參考文檔,對一些描述作了些修正.
ALSA 的基本架構能夠用上圖表示,組成部分主要有:linux
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 與內核空間交互,儘管各類 Library 在實現上差異很大,但最終都是經過 Kernel 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流操做集
各數據結構的關係以下,編碼
核心驅動的通常實現步驟以下,spa
爲了簡化 SoC 芯片上 ALSA 驅動的開發,在覈心層的基礎上構建了 ASoC(ALSA System on Chip) 層。ASoC 層主要由以下三部分組成:設計
ASoC Layer 主要負責驅動音頻硬件設備,對外表現爲一個總體的 Machine。Platform 控制 SoC 芯片中數字音頻傳輸。Codec 控制音頻編解碼器,可能爲內置或外置,一般使用 I2C 進行控制。3d
ASoC 支持三種主流的數字音頻接口(Digital Audio Interfaces):AC9七、I2S 和 PCM。注意這裏的 PCM 表示只有硬件接口協議,與上面所說的軟件 PCM 接口不一樣。code
AC97: 一般用於PC聲卡, 爲5線接口, 每一個AC97幀爲21uS長, 被分爲13個時隙
I2S是HiFi、STB和便攜式設備中經常使用的4線DAI
PCM是另外一種4線接口, 與I2S很是類似, 能夠支持更靈活的協議
Codec驅動用於配置編解碼器、FM、MODEM、BT 或外部 DSP, 以提供 playback 和 capture。每一個Codec驅動必須提供以下功能: