宋 剛
(重慶城市管理職業(yè)學(xué)院,重慶 401331)
ALSA聲卡驅(qū)動程序設(shè)計
宋剛
(重慶城市管理職業(yè)學(xué)院,重慶401331)
文章介紹了Linux 操作系統(tǒng)中負(fù)責(zé)聲音處理的ALSA音頻子系統(tǒng),以及它包含的聲卡驅(qū)動程序和編程步驟。通過對聲卡設(shè)備的驅(qū)動程序?qū)嵗治觯恼驴偨Y(jié)出ALSA聲卡設(shè)備驅(qū)動的通用編程框架。
ALSA;驅(qū)動程序;音頻子系統(tǒng)
高級Linux聲音架構(gòu)(Advanced Linux Sound Architecture, ALSA)是Linux操作系統(tǒng)內(nèi)核中,用來為聲音設(shè)備提供編程輔助和硬件驅(qū)動的子系統(tǒng)。如圖1所示,它包含兩個組成部分,一個是在用戶空間中用來簡化編程的ALSA-Lib函數(shù)庫。功能是用戶請求轉(zhuǎn)換為對內(nèi)核空間中設(shè)備字符文件的調(diào)用。另外一個是在內(nèi)核空間中負(fù)責(zé)硬件控制的驅(qū)動程序。它通過對設(shè)備字符設(shè)備的注冊與回調(diào),實現(xiàn)ALSA驅(qū)動核心(core.c, pcm.c)。核心再通過回調(diào)具體聲卡的ALSA驅(qū)動,實現(xiàn)對聲卡硬件的操作。
圖1 ALSA音頻驅(qū)動結(jié)構(gòu)層次
文章通過一個只包含話音采集功能的PCI總線聲卡,來描述內(nèi)核中ALSA驅(qū)動程序的調(diào)用步驟和編程框架。具體可分為聲卡記錄的創(chuàng)建,PCM設(shè)備的創(chuàng)建,PCM操作函數(shù)的建立3個部分。
這里假設(shè)聲卡的Linux內(nèi)核模塊(Module)框架和PCI總線結(jié)構(gòu)初始化已經(jīng)完成。這兩部分通用結(jié)構(gòu)可由《Linux設(shè)備驅(qū)動程序》一書中詳細(xì)給出,本文只關(guān)注書中欠缺的ALSA驅(qū)動部分。
2.1聲卡記錄的創(chuàng)建
聲卡記錄是整個驅(qū)動的核心,所有與聲卡相關(guān)的數(shù)據(jù)結(jié)構(gòu)和控制代碼都保存在聲卡記錄名下。它的具體結(jié)構(gòu)定義在include/sound/core.h,由函數(shù)snd_card_create()來創(chuàng)建和初始化,如圖2所示。
圖2 聲卡的創(chuàng)建
idx:聲卡的編號,如為1,則由系統(tǒng)自動分配。
xid:聲卡標(biāo)識符,如為NULL,則以snd_card的shortname或longname代替。
0:聲卡私有數(shù)據(jù)區(qū)大小。
card_ret:返回所創(chuàng)建的聲卡實例的指針。
2.2設(shè)置驅(qū)動名和設(shè)備號等信息(見圖3)
圖3 設(shè)置驅(qū)動程序信息
圖3創(chuàng)建了聲卡驅(qū)動程序名,還有聲卡的短描述符和長描述符,以及使用的PCI總線信息。因為用戶空間編程時ALSA-LIB需要明確調(diào)用的聲卡名稱,所以聲卡的命名必須具備關(guān)鍵字特性。
2.3聲卡的私有數(shù)據(jù)注冊為一個低階設(shè)備
這樣做的目的在于當(dāng)聲卡被注銷時,芯片私有數(shù)據(jù)所占用的內(nèi)存可以隨著聲卡的注銷被自動地釋放。如圖4所示,私有數(shù)據(jù)為空。
圖4 將專有數(shù)據(jù)注冊為一個低階設(shè)備
2.4聲卡的注冊和注銷(見圖5)
圖5 向ALSA注冊聲卡
注冊成功會生產(chǎn)色卡的設(shè)備文件,一般是dev/snd/ pcmCxxDxxp,pcmCxxDxxc,供用戶空間中的ALSALib庫調(diào)用。如果注冊失敗,可通過snd_card_free函數(shù)釋放聲卡所占有的所有資源。
通常一塊聲卡包含多個功能設(shè)備,如PCM,Control,Mixer,MIDI等。為便于學(xué)習(xí),這里只討論聲卡中必須擁有的PCM設(shè)備。在ALSA驅(qū)動框架中,每塊聲卡最多可以包含4個PCM設(shè)備。PCM設(shè)備由一個Playback stream和一個Capture stream組成,每個Stream又由一個或多個Substreams組成。
3.1聲卡中采集PCM設(shè)備硬件描述信息(見圖6)
圖6 采集卡硬件描述
該聲卡設(shè)備硬件為一簡單話音采集卡。結(jié)構(gòu)體中定義了使用U8格式的PCM編碼,采樣率為8KHz,單聲道,緩存區(qū)大小為48頁,每頁32個字節(jié)。
3.2創(chuàng)建PCM設(shè)備(見圖7)
圖7 PCM設(shè)備的創(chuàng)建
第三個參數(shù),表示聲卡第一個PCM設(shè)備,從0開始計算。
第四個參數(shù),表示P C M設(shè)備有幾個回放子流substream,本例中為0。
第五個參數(shù)nr_subdevs,為PCM設(shè)備下采集子流數(shù)量。
3.3定義PCM設(shè)備操作函數(shù)(見圖8)
圖8 PCM操作函數(shù)定義
該采集卡中的PCM設(shè)備只有Capture stream。一般聲卡中PCM Playback stream的設(shè)計與之相似。函數(shù)參數(shù)中的my_pcm_ops是函數(shù)的操作結(jié)構(gòu)體地址,該操作函數(shù)集定義如圖9所示。
圖9 操作函數(shù)集
該函數(shù)操作集的操作需要使用snd_pcm_sucstream_ chip()來獲得操作指針。具體功能為:open(),在PCM子流打開時分配相應(yīng)的資源;close(),在PCM之流關(guān)閉時釋放相應(yīng)的資源。
ioctl(),完成一些特殊的控制功能;hw_params(),完成硬件參數(shù)的設(shè)置,如數(shù)據(jù)格式、緩沖大小等;hw_ free(),用來釋放hw_params()函數(shù)占用的系統(tǒng)資源;prepare(),在PCM子流開始傳輸數(shù)據(jù)前,需要完成的操作;trigger(),在PCM子流開始、停止、暫停時被調(diào)用;pointer(),給出當(dāng)前PCM之流緩沖區(qū)地址;copy(),提供內(nèi)存空間管理需要的數(shù)據(jù)拷貝功能。下一步是編寫單個函數(shù)的實現(xiàn),如圖10所示。
圖10 操作函數(shù)實現(xiàn)
3.4 為操作函數(shù)預(yù)分配緩沖空間(見圖11)
圖11 分配DMA緩沖數(shù)據(jù)區(qū)
需要注意的是對緩沖空間的數(shù)據(jù)填充一定要采用DMA方式存取,否則數(shù)據(jù)的接收有可能產(chǎn)生中斷現(xiàn)象。
3.5PCM子流中斷的處理
最后是添加中斷處理函數(shù)。中斷處理的作用是當(dāng)緩沖區(qū)傳輸完成、硬件復(fù)位、總線操作的時候通知PCM中間層??梢酝ㄟ^調(diào)用函數(shù)snd_pcm_period_elapsed()來通知。中斷請求代碼為 snd_pcm_period_elapsed(my_ dev->ss)。
本文介紹了一個簡單的聲卡設(shè)備的ALSA驅(qū)動編制流程,詳細(xì)地討論了ALSA架構(gòu)中驅(qū)動程序的架構(gòu)與編程框架。以此為基礎(chǔ)設(shè)計的Linux平臺多路話音采集卡ALSA驅(qū)動程序已用于實踐教學(xué)中。從學(xué)習(xí)效果反饋上看,該驅(qū)動框架對ALSA架構(gòu)音頻驅(qū)動的學(xué)習(xí)和深入研究具備一定的指導(dǎo)意義。
[1]ALSA development team.ALSA開源項目[EB/OL].(2016-09-15)[2013-10-31].http://www.alsa-project.org/.
[2]TAKASHI IWAI.Writing an ALSA Driver[EB/OL].(2016-09-10)[2005-02-10].http://www.alsa-project.org/~tiwai/writing-an-alsa-driver/.
[3]科波特.Linux設(shè)備驅(qū)動程序[M].3版.魏永明,耿岳,鐘書毅,譯.北京:中國電力出版社,2006.
Design of ALSA sound card driver
Song Gang
(Chongqing City Management College, Chongqing 401331, China)
This article described the audio subsystem which is responsible for the ALSA sound processing in Linux operating system,sound card drivers and programming steps contained in it. By the analysis of sound device driver instance, the common programming framework of ALSA device driver was summed up in this paper.
ALSA; driver; audio subsystem
宋剛(1975— ),男,四川資中,專科,實驗師;研究方向:計算機(jī)操作系統(tǒng)。