0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

ALSA高級(jí)Linux聲音架構(gòu)淺析

Linux閱碼場(chǎng) ? 來源:Leo Linux ? 2023-03-25 16:52 ? 次閱讀

一、數(shù)字音頻背景

1.1 數(shù)字音頻簡(jiǎn)介

聲音在自然界以聲波的形式存在,是一系列連續(xù)變化的模擬信號(hào),聲音的三個(gè)要素是音調(diào)、音強(qiáng)和音色。聲波有三個(gè)重要參數(shù):頻率 ω0、幅度A n 和相位ψn ,這也就決定了音頻信號(hào)的特征。根據(jù)聲波的特征,可把音頻信息分類為規(guī)則音頻和不規(guī)則聲音。其中規(guī)則音頻又可以分為語(yǔ)音、音樂和音效。音頻信號(hào)是(Audio)帶有語(yǔ)音、音樂和音效的有規(guī)律的聲波的頻率、幅度變化信息載體。

1.1.1 數(shù)字音頻

數(shù)字音頻是一種利用數(shù)字化手段對(duì)聲音進(jìn)行錄制、存放、編輯、壓縮或播放的技術(shù),它是隨著數(shù)字信字音頻號(hào)處理技術(shù)、計(jì)算機(jī)技術(shù)、多媒體技術(shù)的發(fā)展而形成的一種全新的聲音處理手段。數(shù)字音頻計(jì)算機(jī)數(shù)據(jù)的存儲(chǔ)是以0、1的形式存取的,那么數(shù)字音頻就是首先將音頻文件轉(zhuǎn)化,接著再將這些電平信號(hào)轉(zhuǎn)化成二進(jìn)制數(shù)據(jù)保存,播放的時(shí)候就把這些數(shù)據(jù)轉(zhuǎn)換為模擬的電平信號(hào)再送到喇叭播出,數(shù)字聲音和一般磁帶、廣播、電視中的聲音就存儲(chǔ)播放方式而言有著本質(zhì)區(qū)別。相比而言,它具有存儲(chǔ)方便、存儲(chǔ)成本低廉、存儲(chǔ)和傳輸?shù)倪^程中沒有聲音的失真、編輯和處理非常方便等特點(diǎn)。

1.1.2 數(shù)字音頻文件

數(shù)字音頻文件是通過聲音錄入設(shè)備錄制的原始聲音,直接記錄了真實(shí)聲音的二進(jìn)制采樣數(shù)據(jù),有些文件并對(duì)原始數(shù)據(jù)進(jìn)行了頻率過濾和存儲(chǔ)格式壓縮,音頻文件格式主要分有損和無損兩類。有損文件格式是基于聲學(xué)心理學(xué)的模型,除去人類很難或根本聽不到的聲音。

無損格式如:PCM,WAV,ALS,ALAC,TAK,F(xiàn)LAC,APE,WavPack(WV) ;

有損格式如:MP3,AAC,WMA,Ogg ;

數(shù)字音頻文件幾個(gè)重要參數(shù):采樣頻率、量化位寬、聲道數(shù)。

1.1.3 采樣頻率

采樣頻率是指將模擬聲音波形進(jìn)行數(shù)字化時(shí),每秒鐘抽取聲波幅度樣本的次數(shù)。采樣頻率的選擇應(yīng)該遵循奈奎斯特(Harry Nyquist)采樣理論:如果對(duì)某一模擬信號(hào)進(jìn)行采樣,則采樣后可還原的最高信號(hào)頻率只有采樣頻率的一半,或者說只要采樣頻率高于輸入信號(hào)最高頻率的兩倍,就能從采樣信號(hào)系列重構(gòu)原始信號(hào)。正常人聽覺的頻率范圍大約在20Hz~20kHz之間,根據(jù)奈奎斯特采樣理論,為了保證聲音不失真,采樣頻率應(yīng)該在40kHz左右,常用的采樣率有:

8,000 Hz - 電話所用采樣率,對(duì)于人的說話已經(jīng)足夠;

11,025 Hz ;

22,050 Hz - 無線電廣播所用采樣率;

32,000 Hz - miniDV 數(shù)碼視頻camcorder、DAT(LP mode)所用采樣率;

44,100 Hz - 音頻CD,也常用于MPEG-1音頻(VCD, SVCD, MP3)所用采樣率;

47,250 Hz - 商用 PCM 錄音機(jī)所用采樣率;

48,000 Hz - miniDV、數(shù)字電視、DVD、DAT、電影和專業(yè)音頻所用的數(shù)字聲音所用采樣率;

50,000 Hz - 商用數(shù)字錄音機(jī)所用采樣率;

96,000192,000Hz - DVD Audio、一些LPCMDVD音軌、BD-OM(藍(lán)光盤)音軌、和HDDVD(高清晰度DVD)音軌所用所用采樣率;

2.8224 MHz - Direct Stream Digital的1位sigma-delta modulation過程所用采樣率。

1.1.4 量化位寬

量化位寬是對(duì)模擬音頻信號(hào)的幅度進(jìn)行數(shù)字化,它決定了模擬信號(hào)數(shù)字化以后的動(dòng)態(tài)范圍,常用的有8位、12位、16位、24位和32位。量化位越高,信號(hào)的動(dòng)態(tài)范圍越大,數(shù)字化后的音頻信號(hào)就越可能接近原始信號(hào),但所需要的存貯空間也越大。

1.1.5 聲道數(shù)

聲道數(shù)是反映音頻數(shù)字化質(zhì)量的另一個(gè)重要因素,聲道技術(shù)已廣泛運(yùn)用于各類傳統(tǒng)影院和家庭影院中:

單聲道的聲道數(shù)為1個(gè)聲道;

雙聲道的聲道數(shù)為2個(gè)聲道,立體聲道的聲道數(shù)默認(rèn)為2個(gè)聲道;

四聲道環(huán)繞規(guī)定了4個(gè)發(fā)音點(diǎn):前左、前右,后左、后右,4.1聲道音箱系統(tǒng)其中“.1”聲道,則是一個(gè)專門設(shè)計(jì)的超低音聲道,這一聲道可以產(chǎn)生頻響范圍20~120Hz的超低音;

5.1聲音系統(tǒng)其實(shí)來源于4.1環(huán)繞,不同之處在于它增加了一個(gè)中置單元。這個(gè)中置單元負(fù)責(zé)傳送低于80Hz的聲音信號(hào),在欣賞影片時(shí)有利于加強(qiáng)人聲,把對(duì)話集中在整個(gè)聲場(chǎng)的中部,以增加整體效果;

7.1系統(tǒng)已經(jīng)出現(xiàn),它在5.1的基礎(chǔ)上又增加了中左和中右兩個(gè)發(fā)音點(diǎn),以求達(dá)到更加完美的境界。

1.2 linux音頻子系統(tǒng)介紹

Linux音頻系統(tǒng)比較復(fù)雜,各層間有很多交叉,可能是最無序的子系統(tǒng),并且它有兩套音頻驅(qū)動(dòng)框架: OSS (Open Sound System)和ALSA (Advanced Linux Sound Architechture),所以底層驅(qū)動(dòng)有OSS和ALSA兩套API。ALSA經(jīng)過多年的發(fā)展,基本統(tǒng)一了Linux聲卡硬件驅(qū)動(dòng)層的接口,OSS日漸退出,但是在ALSA之上的各個(gè)應(yīng)用層,方案和軟件繁多復(fù)雜,ESD,PulseAudio, JACK,GStreamer, 這些系統(tǒng)組件各個(gè)為戰(zhàn),實(shí)現(xiàn)了不同的功能。

bf09c95c-cae8-11ed-bfe3-dac502259ad0.jpg

圖1.2

上圖1.2描述了Linux音頻系統(tǒng)各部分調(diào)用關(guān)系,下面簡(jiǎn)要介紹各部分。

1.2.1 ALSA和OSS

ALSA 是 Advanced Linux Sound Architecture 的縮寫,即高級(jí) Linux聲音架構(gòu),在 Linux 操作系統(tǒng)上提供了對(duì)音頻和 MIDI(Musical InstrumentDigital Interface,音樂設(shè)備數(shù)字化接口)的支持。在 Linux2.6 版本內(nèi)核以后,ALSA 已經(jīng)成為默認(rèn)的聲音子系統(tǒng),用來替換 2.4 版本內(nèi)核中的OSS(Open Sound System,開放聲音系統(tǒng))。

ALSA 是一個(gè)完全開放源碼的音頻驅(qū)動(dòng)程序集,是由志愿者維護(hù)的開源項(xiàng)目,而 OSS 則是由公司提供的商業(yè)產(chǎn)品。ALSA 系統(tǒng)包括驅(qū)動(dòng)包alsa-driver(集成在內(nèi)核源碼),開發(fā)包 alsa-libs,開發(fā)包插件 alsalibplugins,設(shè)置管理工具包 alsa-utils,其他聲音相關(guān)處理小程序包alsa-tools,特殊音頻固件支持包 alsa-firmware,OSS 接口兼容模擬層工具 alsa-oss 共 7 個(gè)子項(xiàng)目,其中只有 alsa-driver 是必須的。

1.2.2 FFADO

很多專業(yè)音樂設(shè)備都是通過“火線”連接到pc的。FFADO項(xiàng)目旨在通過提供一個(gè)通用的火線上,支持基于Linux平臺(tái)的開源音頻設(shè)備解決方案。FFADO項(xiàng)目是的FreeBOB項(xiàng)目的繼任者。FFADO在志愿者為基礎(chǔ)的社區(qū)的努力下,試圖提供Linux至少是存在于其他操作系統(tǒng)功能相同的水平,并且希望支持的火線音頻設(shè)備的范圍非常廣泛:從混合音頻控制設(shè)備到DSP算法設(shè)備的純音頻接口。然而,能夠支持的是設(shè)備供應(yīng)商的合作。優(yōu)先考慮提供信息和測(cè)試設(shè)備的制造商。

FFADO另一個(gè)特性是整合了dsp芯片的混音驅(qū)動(dòng),你可以通過圖形界面設(shè)置輸入輸出,以及音效等。不同于alsa的軟混音,你可以真正的對(duì)硬件進(jìn) 行控制,做到真正的0延時(shí),這對(duì)現(xiàn)場(chǎng)錄音等需求大大有助。和alsa等其他架構(gòu)不同,jack僅僅對(duì)其支持的硬件進(jìn)行處理,沒有對(duì)alsa或者pulse提供接口,除非你用alsa替代jack,否則你無 法使用jack正常的進(jìn)行音頻播放。但是很多專業(yè)設(shè)備對(duì)jack支持良好,所以jack是你的最優(yōu)選擇。

1.2.3 PulseAudio

PulseAudio是內(nèi)置POSIX的操作系統(tǒng)是一個(gè)完善的機(jī)制,它是聲音的應(yīng)用程序代理。它允許應(yīng)用程序和硬件之間傳遞聲音數(shù)據(jù)上的高級(jí)操作。諸如將音頻傳輸?shù)讲煌臋C(jī)器、改變采樣格式或通道計(jì)數(shù)以及將多個(gè)聲音混合成一個(gè),這些都很容易使用聲音服務(wù)器實(shí)現(xiàn)。內(nèi)置專為L(zhǎng)inux系統(tǒng)。它也被移植到Solaris、FreeBSD,NetBSD,MacOS X的測(cè)試,Windows 2000和Windows XP。內(nèi)置是所有有關(guān)linux系統(tǒng)的一個(gè)組成部分,用于由多個(gè)供應(yīng)商的各種移動(dòng)設(shè)備。

1.2.4 GStreamer

GStreamer是一個(gè)開源的多媒體框架庫(kù)。利用它,可以構(gòu)建一系列的媒體處理模塊,包括從簡(jiǎn)單的ogg播放功能到復(fù)雜的音頻(混音)和視頻(非線性編輯)的處理。應(yīng)用程序可以透明的利用解碼和過濾技術(shù)。開發(fā)者可以使用簡(jiǎn)潔通用的接口來編寫一個(gè)簡(jiǎn)單的插件來添加新的解碼器或?yàn)V鏡。

1.2.5 JACK

Jack(JACK Audio Connection Kit 的遞歸縮寫)是一個(gè)專業(yè)級(jí)的聲音服務(wù)(守護(hù)進(jìn)程),它為聲音和MIDI數(shù)據(jù)提供實(shí)時(shí)的、低延時(shí)的連接,有關(guān)的程序使用JACK的API。

JACK能使用ALSA、PortAudio、CoreAudio、FFADO和OSS作為硬件層的后端。此外, 還有一個(gè)虛擬的驅(qū)動(dòng)(當(dāng)不需要聲音輸出時(shí)是很有用的,例如離線渲染)和一個(gè)通過UDP協(xié)議的音頻驅(qū)動(dòng)(Audio-over-UDP driver)。它可以運(yùn)行在Linux、Mac OS X、Solaris、Windows、FreeBSD、OpenBSD和NetBSD上。JACK的API被標(biāo)準(zhǔn)化,并且存在兩種可融合的實(shí)現(xiàn):jack1,由簡(jiǎn)單的C實(shí)現(xiàn)并且已經(jīng)維護(hù)了一段時(shí)間;至于jack2(原來的jackdmp),由Stéphane Letz領(lǐng)導(dǎo)的用C++重寫的實(shí)現(xiàn),jack2在積極開發(fā)中,目標(biāo)是支持多處理器和對(duì)其它非Linux操作系統(tǒng)。

1.2.6 Xin

如果說linux音頻發(fā)展像地球史,那xine就處在白堊紀(jì)。它就像個(gè)遺老,你仍能從很多播放器中發(fā)現(xiàn)它的身影,所以很多l(xiāng)inux發(fā)行版仍然捆綁 著xine。xine創(chuàng)立之初,設(shè)計(jì)分為前端和后端,前端用于和用戶交互,后端處理多媒體。得益于封裝的解碼庫(kù),它可以播放包括AVI、Matroska和 Ogg以及它們 包含的數(shù)十種格式,例如AAC、Flack、MP3、Vorbis和WMA。因?yàn)樗蕾囉趲?kù)實(shí)現(xiàn),所以xine被開發(fā)成一個(gè)多媒體框架,庫(kù)的開發(fā),使得xine在法律允許范圍內(nèi)對(duì)多媒體文件提供最好的支持。xine可以和 alsa,pulse通信,很多程序也可以調(diào)用xine,例如totme-xine。同時(shí)xine也是kde的Phonon默認(rèn)后端,所以不論是 Amarok 還是 Kaffeine,都能看到他的蹤跡。

1.2.7 Phonon

Phonon是KDE 4的多媒體API 。Phonon提供一個(gè)穩(wěn)定的API允許KDE 4獨(dú)立于任何一個(gè)聲音系統(tǒng)服務(wù)器如xine。Phonon讓各種后端提供界面給開發(fā)者所謂的”引擎”;每個(gè)引擎運(yùn)作在一個(gè)具體的后端。每個(gè)后端都可讓Phonon控制基本功能,如播放、暫停和搜尋。Phonon也支持更高層次的功能,如讓音軌轉(zhuǎn)化之間變微弱。使用Solid,Phonon將給予用戶更多配件的控制能力如耳機(jī)、揚(yáng)聲器、麥克風(fēng)。一個(gè)例子是,因?yàn)槟憧赡苤挥幸粋€(gè)VoIP會(huì)話使用您的耳機(jī),但所有其他的聲音通過揚(yáng)聲器出來。支援 Unix-like 系統(tǒng)下的后端xine、VLC、MPlayer。支援 Windows 下的后端 DirectShow、VLC和MPlayer.支持 Mac OS X下的后端QuickTime。QT4.4和之后版本使用了Phonon,作為跨平臺(tái)的音頻/視頻播放。

1.2.8、其他

其他有一些很多小眾的音頻技術(shù),例如ESD、SDL和 PortAudio。

ESD

ESD是聲音啟發(fā)守護(hù)進(jìn)程(Enlightenment Sound Daemon),它在曾經(jīng)很長(zhǎng)的一段時(shí)間里曾是Gnome桌面的默認(rèn)聲音服務(wù)。后來,Gnome開始使用libcanberra(它本身可以和ALSA、 GStreamer、OSS和PulseAudio通信),ESD在2009年4月被徹底放棄支持。在kde上esd也是杯具。因?yàn)榇蟛糠秩硕际鞘褂?kde4,所以phonon替代了esd。

SDL

SDL依然欣欣向榮的發(fā)展著。因?yàn)橐呀?jīng)是用他開發(fā)了上百款跨平臺(tái)游戲, 所以SDL庫(kù)的音頻輸出組件依然支持良好,具有大量新的特性,并且成熟而穩(wěn)定。

PortAudio

PortAudio也是一個(gè)跨平臺(tái)音頻庫(kù),它把 SGI、Unix和Beos加入到可能的終端混音器中。使用PortAudio的最知名的應(yīng)用程序就是Audacity音頻編輯器了,因?yàn)槭褂昧?portaudio,使得它音頻輸出遇到了問題,jack支持也遇到了bug。

二、ALSA框架分析

2.1 ALSA框架介紹

2.1.1 ALSA簡(jiǎn)介

ALSA 是 Advanced Linux Sound Architecture 的縮寫,即高級(jí) Linux聲音架構(gòu),在 Linux 操作系統(tǒng)上提供了對(duì)音頻和 MIDI(Musical InstrumentDigital Interface,音樂設(shè)備數(shù)字化接口)的支持。在 Linux2.6 版本內(nèi)核以后,ALSA 已經(jīng)成為默認(rèn)的聲音子系統(tǒng),用來替換 2.4 版本內(nèi)核中的OSS(Open Sound System,開放聲音系統(tǒng))。

ALSA 是一個(gè)完全開放源碼的音頻驅(qū)動(dòng)程序集,是由志愿者維護(hù)的開源項(xiàng)目,而OSS則是由公司提供的商業(yè)產(chǎn)品。ALSA系統(tǒng)包括驅(qū)動(dòng)包alsa-driver(集成在內(nèi)核源碼),開發(fā)包 alsa-libs,開發(fā)包插件 alsalibplugins,設(shè)置管理工具包 alsa-utils,其他聲音相關(guān)處理小程序包alsa-tools,特殊音頻固件支持包 alsa-firmware,OSS 接口兼容模擬層工具 alsa-oss 共 7 個(gè)子項(xiàng)目,其中只有 alsa-driver 是必須的。除了 alsa-driver,ALSA 包含在用戶空間的 alsa-lib 函數(shù)庫(kù),具有更加友好的編程接口,并且完全兼容于 OSS,開發(fā)者可以通過這些高級(jí) API 使用驅(qū)動(dòng),不必直接與內(nèi)核驅(qū)動(dòng) API 進(jìn)行交互。
ALSA 主要有如下特點(diǎn):

支持多種聲卡設(shè)備;

模塊化的內(nèi)核驅(qū)動(dòng)程序;

支持 SMP(對(duì)稱多處理)和多線程;

提供應(yīng)用開發(fā)函數(shù)庫(kù) ;

兼容 OSS 應(yīng)用程序 。

2.1.2 ALSA整體框架

ALSA 在 Linux 系統(tǒng)中可以主要分兩部分,在Kernel空間的設(shè)備驅(qū)動(dòng)層,ALSA 提供了 ALSA-driver,它是整個(gè) ALSA 框架的核心部分;同時(shí)在Linux User空間,ALSA 提供了alsa-lib,對(duì) ALSA-driver的系統(tǒng)調(diào)用API進(jìn)行封裝,應(yīng)用程序只要調(diào)用 alsa-lib 提供的 API,即可以完成對(duì)底層音頻硬件的控制。下圖2.1.2是基于ALSA框架的Linux音頻系統(tǒng)架構(gòu)圖:

bf14d112-cae8-11ed-bfe3-dac502259ad0.jpg

圖2.1.2

2.1.2.1 alsa-lib

User空間的 alsa-lib 對(duì)應(yīng)用程序提供統(tǒng)一的 alsa-lib-API 接口,簡(jiǎn)化了應(yīng)用程序的實(shí)現(xiàn)難度。alsa-lib 主要以 plugin 插件的形式體現(xiàn)。詳細(xì)信息詳見http://www.alsa-project.org/alsa-doc/alsa-lib/ 。

2.1.2.2 ALSA-driver

Linux 內(nèi)核空間中,ALSA-driver 其大致可分為三層:聲卡對(duì)象描述層、ALSA 核心層 ASLA Core 和 Audio 設(shè)備驅(qū)動(dòng)層 Audio device driver。

最上層的是聲卡對(duì)象描述層,是聲卡硬件的抽象描述,是一個(gè)虛擬層,用戶空間通過這些描述可以得知該聲卡硬件的功能、設(shè)備組件和操作方法等。

中間層是 ASLA Croe,是 ALSA 的標(biāo)準(zhǔn)框架,是 ALSA-driver 的核心部分,提供了各種音頻設(shè)備驅(qū)動(dòng)的通用方法和數(shù)據(jù)結(jié)構(gòu),為 Audio driver提供 ALSA Driver API。

最底層是 Audio device driver,根據(jù) ALSA-driver 提供的 ALSA Driver API 和相應(yīng)音頻設(shè)備的初始化及工作流程,實(shí)現(xiàn)具體的功能組件函數(shù),這也是驅(qū)動(dòng)開發(fā)人員需要具體實(shí)現(xiàn)的部分。

2.2 ALSA的硬件抽象

ALSA 用 cards,device 和 subdevices 的分層結(jié)構(gòu)表示 Audio 硬件設(shè)備和他們的組件。這個(gè)分層結(jié)構(gòu)是 ALSA 看待硬件設(shè)備結(jié)構(gòu)和能力的視角,是對(duì)實(shí)體硬件的抽象化實(shí)例。見圖2.2:

bf33803a-cae8-11ed-bfe3-dac502259ad0.jpg

圖2.2 ALSA設(shè)備抽象圖

目前 ALSA 內(nèi)核提供給用戶空間的 device 文件接口有:

InformationInterface(/proc/asound)信息接口;
ControlInterface(/dev/snd/controlCX)控制接口;
MixerInterface(/dev/snd/mixerCXDX)混音器接口;
PCMInterface(/dev/snd/pcmCXDX) PCM 接口;
RawMIDIInterface(/dev/snd/midiCXDX) Raw 迷笛接口;
SequencerInterface(/dev/snd/seq)音序器接口;
TimerInterface(/dev/snd/timer)定時(shí)器接口;

2.2.1 PCM設(shè)備

ALSA 已經(jīng)為我們實(shí)現(xiàn)了功能強(qiáng)勁的 PCM 中間層,自己的驅(qū)動(dòng)中只要實(shí)現(xiàn)一些底層的需要訪問硬件的函數(shù)即可。要訪問 PCM 的中間層代碼,你首先要包含頭文件,另外,如果需要訪問一些與hw_param 相關(guān)的函數(shù),可能也要包含。每個(gè) pcm 實(shí)例對(duì)應(yīng)一個(gè) pcm 設(shè)備文件。一個(gè) pcm 實(shí)例由一個(gè)playback stream 和一個(gè) capture stream 組成,這兩個(gè) stream 又分別有一個(gè)或多個(gè) substreams 組成,見圖2.2.1。

bf49c5a2-cae8-11ed-bfe3-dac502259ad0.png

圖2.2.1 聲卡中的pcm結(jié)構(gòu)圖

2.2.2 Control設(shè)備

Control 接口主要讓用戶空間的應(yīng)用程序(alsa-lib)可以訪問和控制音頻 codec 芯片中的多路開關(guān),滑動(dòng)控件等。用戶空間通過對(duì) Control設(shè)備的操作,從而達(dá)到操作 CODEC 相關(guān)寄存器的目的。

2.2.3 ALSA設(shè)備文件命名規(guī)則

ALSA cards和聲卡硬件是一一對(duì)應(yīng)的,ALSA cards主要保存每塊卡上的設(shè)備列表,一個(gè)card可以通過一個(gè)ID(字符串)或者從0開始的數(shù)字表示。大部分 ALSA 硬件訪問發(fā)生在 device 級(jí)別,可以從 0 開始枚舉每個(gè)卡的 devices,不同的 devices 可以獨(dú)立的打開和使用。

典型的,聲卡和設(shè)備這兩個(gè)標(biāo)識(shí)足以決定聲音信號(hào)從哪里讀取,送到哪里。Subdevices 是 ALSA 能夠區(qū)分的更細(xì)粒度的對(duì)象。最常見的場(chǎng)景是一個(gè) device 的每個(gè) channel 都對(duì)應(yīng)一個(gè) subdevice 或者總共只有一個(gè)subdevice。一個(gè) device 的 subdevice 理論上可以單獨(dú)使用,但是在一個(gè)subdevice 上播放 multi-channel 信號(hào)時(shí),也會(huì)使用其余的 subdevices。和 device 一樣,subdevices 索引標(biāo)識(shí)從 0 開始。

2.2.4 ALSA 設(shè)備文件實(shí)例說明

下面舉例查看某 Linux 系統(tǒng)中 dev/snd 路徑下 alsa 驅(qū)動(dòng)設(shè)備文件:

crw-rw—-+ 1 root audio 116, 2 4 月 7 18:14 controlC0
crw-rw—-+ 1 root audio 116, 5 4月 7 18:14 controlC1
crw-rw—-+ 1 root audio 116, 3 4 月 7 18:15 pcmC0D3p
crw-rw—-+ 1 root audio 116, 7 4 月 7 18:15 pcmC1D0c
crw-rw—-+ 1 root audio 116, 6 4 月 18 10:38 pcmC1D0p


crw-rw—-+ 1 root audio 116, 8 4 月 7 18:14 pcmC1D2c
crw-rw—-+ 1 root audio 116, 1 4 月 7 18:14 seq
crw-rw—-+ 1 root audio 116, 33 4 月 7 18:14 timer

我們可以看到以下設(shè)備文件:

controlCX –>     用于聲卡的控制,例如通道選擇,混音,麥克風(fēng)的控制等
pcmCXDXc –>      用于錄音的 pcm 設(shè)備
pcmCXDXp –>      用于播放的 pcm 設(shè)備
seq–>音序器
timer–>定時(shí)器

其中,CXDX 代表的是聲卡 X 中的設(shè)備 X,pcmC1D0c 最后一個(gè) c 代表 capture,pcmC1D0p 最后一個(gè) p 代表 playback,這些都是 alsa-driver中的命名規(guī)則。從上面的列表可以看出,聲卡下掛了 8 個(gè)設(shè)備,根據(jù)聲卡的實(shí)際能力,驅(qū)動(dòng)實(shí)際上可以掛上更多種類的設(shè)備。通常最重要的兩個(gè)設(shè)備是 PCM 和 control。

2.3 HDA Driver分析

2.3.1 HDA硬件系統(tǒng)框架

HDA(High Definition Audio)是intel設(shè)計(jì)的用來取代AC97的音頻標(biāo)準(zhǔn),硬件架構(gòu)上由hda dodec和hda controller組成見圖2.3.1:

bf56a5b0-cae8-11ed-bfe3-dac502259ad0.png

圖2.3.1

2.3.2 Stream的概念

HAD 引入了 Streams 的概念來組織數(shù)據(jù),并通過 HDA Link 總線進(jìn)行數(shù)據(jù)傳輸。Stream 是一個(gè)在系統(tǒng)內(nèi)存緩沖區(qū)和 codec 之間創(chuàng)建的邏輯的或虛擬的連接用以來呈現(xiàn)數(shù)據(jù),該連接由單個(gè) DMA 通道通過 Link總線驅(qū)動(dòng)。一個(gè) Stream 包含一個(gè)或多個(gè)相關(guān)的組件或數(shù)據(jù) channels,每個(gè) channel 都被動(dòng)態(tài)綁定到 codec 中的一個(gè)單一 converter 上來呈現(xiàn)。

例如,一個(gè)立體聲 Stream 包括兩個(gè) channels:左和右,在此 Stream 中的每一個(gè)采樣點(diǎn)應(yīng)該包括兩個(gè)采樣數(shù)據(jù):左和右。這些采樣在緩沖區(qū)中和在鏈路上傳輸?shù)臅r(shí)候是組合在一起的,但是卻在 codec 中連接不同的DA 轉(zhuǎn)換器。

2.3.3 HDA driver模型介紹

2.3.3.1 重要結(jié)構(gòu)體azx

azx 是hda controller的結(jié)構(gòu)體,其中struct hda_bus bus、struct snd_card *card、struct pci_dev *pci是三個(gè)重要結(jié)構(gòu)體,分別表示總線、卡、設(shè)備。其kernel4.6版的結(jié)構(gòu)體見下:

struct azx {
struct hda_bus bus;


struct snd_card *card;
struct pci_dev *pci;
int dev_index;


/* chip type specific */
int driver_type;  
unsigned int driver_caps;  
int playback_streams;  
int playback_index_offset;  
int capture_streams;  
int capture_index_offset;  
int num_streams;  
const int *jackpoll_ms; /* per-card jack poll interval */


/* Register interaction. */
const struct hda_controller_ops *ops;


/* position adjustment callbacks */
azx_get_pos_callback_t get_position[2];  
azx_get_delay_callback_t get_delay[2];


/* locks */
struct mutex open_mutex; /* Prevents concurrent open/close operations */


/* PCM */
struct list_head pcm_list; /* azx_pcm list */


/* HD codec */
int  codec_probe_mask; /* copied from probe_mask option */
unsigned int beep_mode;


#ifdef CONFIG_SND_HDA_PATCH_LOADER  
const struct firmware *fw;
#endif


/* flags */
int bdl_pos_adj;  
int poll_count;  
unsigned int running:1;  
unsigned int single_cmd:1;  
unsigned int polling_mode:1;  
unsigned int msi:1;  
unsigned int probing:1; /* codec probing phase */
unsigned int snoop:1;  
unsigned int align_buffer_size:1;  
unsigned int region_requested:1;  
unsigned int disabled:1; /* disabled by vga_switcheroo */


#ifdef CONFIG_SND_HDA_DSP_LOADER  
struct azx_dev saved_azx_dev;
#endif
};

2.3.3.2 hda dirver需要實(shí)現(xiàn)的操作功能函數(shù)

操作函數(shù)主要有兩類,一個(gè)是IO級(jí)操作函數(shù),即寄存器讀寫;一個(gè)是功能級(jí)操作函數(shù);

IO級(jí)操作:

structhdac_io_ops{
/*mappedregisteraccesses*/
void(*reg_writel)(u32value,u32__iomem*addr);
u32(*reg_readl)(u32__iomem*addr);
void(*reg_writew)(u16value,u16__iomem*addr);
u16(*reg_readw)(u16__iomem*addr);
void(*reg_writeb)(u8value,u8__iomem*addr);
u8(*reg_readb)(u8__iomem*addr);
/*Allocationops*/
int(*dma_alloc_pages)(structhdac_bus*bus,inttype,size_tsize,structsnd_dma_buffer*buf);
void(*dma_free_pages)(structhdac_bus*bus,structsnd_dma_buffer*buf);};

功能級(jí)操作:

struct hda_controller_ops {
/* Disable msi if supported, PCI only */
int (*disable_msi_reset_irq)(struct azx *);  
int (*substream_alloc_pages)(struct azx *chip,  
structsnd_pcm_substream*substream,
                     size_t size);  
int (*substream_free_pages)(struct azx *chip,  
struct snd_pcm_substream *substream);  
void (*pcm_mmap_prepare)(struct snd_pcm_substream *substream,  
struct vm_area_struct *area);  
/* Check if current position is acceptable */
int (*position_check)(struct azx *chip, struct azx_dev *azx_dev);  
/* enable/disable the link power */
int (*link_power)(struct azx *chip, bool enable);  
};

2.3.3.3 HDA dirver初始化流程

hda dirver的初始化流程見圖2.3.3.3:

bf705938-cae8-11ed-bfe3-dac502259ad0.png

圖2.3.3.3

三、ALSA-lib嵌入式平臺(tái)移植

雖然linux下alsa框架給用戶空間提供了系統(tǒng)調(diào)用,但alsa-lib對(duì)系統(tǒng)調(diào)用進(jìn)行進(jìn)一步封裝,并實(shí)現(xiàn)了很多插件,例如多音頻源進(jìn)行混音播放時(shí),調(diào)用的就是 dmix 插件。

3.1 軟件包下載

進(jìn)入網(wǎng)站選擇下載合適版本的軟件包,見圖3.1:

bf8aadba-cae8-11ed-bfe3-dac502259ad0.png

圖3.1

其中,alsa-lib是ALSA 應(yīng)用庫(kù)(必需基礎(chǔ)庫(kù)),alsa-utils包含一些ALSA小的測(cè)試工具.如aplay、arecord 、amixer播放、錄音和調(diào)節(jié)音量小程序,對(duì)于一些應(yīng)用開發(fā)者只需要以上兩個(gè)軟件包就可以了。

3.2 配置和編譯

3.2.1 alsa-lib

準(zhǔn)備

解壓alsa-lib-x.x.x.tar.bz2,進(jìn)入解壓后目錄:

cd alsa-lib-x.x.x

配置

./configure --host=aarch64-linux-gnu 
--prefix=/usr/local/share/arm64-alsa 
--enable-static=yes --enable-shared=no 
--enable-python=no 
--with-configdir=/usr/local/share/alsa 
--with-plugindir=/usr/local/lib/alsa_lib 
--with-pcm-plugins=hw

其中配置參數(shù)–prefix=/usr/local/share/arm64-alsa 是編譯后結(jié)果的輸出路徑,–with-configdir=/usr/local/share/alsa它將影響 include/config.h中的 ALSA_CONFIG_DIR 目錄。

編譯

make 

安裝

make install

3.2.2 alsa-utils

準(zhǔn)備

解壓alsa-utils-x.x.x.tar.bz2,進(jìn)入解壓后目錄:

cd alsa-utils-x.x.x

配置

./configure 
--host=aarch64-linux-gnu 
--prefix=/usr/local/share/arm64-alsa CFLAGS="-I/usr/local/share/arm64-alsa/include" LDFLAGS="-L/usr/local/share/arm64-alsa/lib 
--lasound" 
--disable-alsamixer 
--disable-xmlto

編譯

make  

安裝

make install

3.2.3 移植

準(zhǔn)備:

復(fù)制目標(biāo)文件夾下的文件到嵌入式系統(tǒng)的根文件系統(tǒng):

cp -rfa /usr/local/share/arm64-alsa/lib/*  /initramfs/lib/ 
cp -rfa /usr/local/share/arm64-alsa/bin/*  /initramfs/sbin/ 
cp -rfa /usr/local/share/arm64-alsa/sbin/* /initramfs/sbin/
cp -rfa /usr/local/share/alsa/*  /initramfs/usr/local/share/

配置環(huán)境變量:

在rootfs/etc/profile,添加如下兩行:

alsa_init
export ALSA_CONFIG_PATH=/usr/local/share/alsa/alsa.conf

生成跟文件系統(tǒng):

find .|cpio -o -H newc|gzip -9 > $(pwd)/initramfs.img.gz

3.3 相關(guān)軟件應(yīng)用

在alsa-utils包含一些ALSA小的測(cè)試工具,這些工具軟件都是基于alsa-lib的API實(shí)現(xiàn)的,其中amixer可以進(jìn)行音頻通道選通和音量調(diào)節(jié),aplay是播放音頻軟件,arecord是錄音軟件。





審核編輯:劉清

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • PCM
    PCM
    +關(guān)注

    關(guān)注

    1

    文章

    195

    瀏覽量

    53230
  • Linux系統(tǒng)
    +關(guān)注

    關(guān)注

    4

    文章

    593

    瀏覽量

    27397
  • 電平信號(hào)
    +關(guān)注

    關(guān)注

    3

    文章

    24

    瀏覽量

    9142
  • alsa
    +關(guān)注

    關(guān)注

    0

    文章

    19

    瀏覽量

    3618

原文標(biāo)題:ALSA(高級(jí)Linux聲音架構(gòu))淺析

文章出處:【微信號(hào):LinuxDev,微信公眾號(hào):Linux閱碼場(chǎng)】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

收藏 人收藏

    評(píng)論

    相關(guān)推薦

    百問網(wǎng)全志系列開發(fā)板音頻ALSA配置步驟詳解

    數(shù)字音頻系統(tǒng)中,A/D轉(zhuǎn)換器帶來的量化噪聲是不可避免的。 8.2 ALSA架構(gòu) ?ALSA全稱是Advanced Linux Sound Architecture,中文音譯是
    發(fā)表于 08-13 09:56

    linux alsa編譯錯(cuò)誤,急等大俠解救

    /../arm-none-linux-gnueabi//sys-root/usr/include/sys/types.h:220,from /usr/include/stdlib.h:314,from /usr/include/alsa
    發(fā)表于 04-05 17:30

    迅為-4418開發(fā)板移植ALSA聲卡

    高級(jí)Linux 聲音體系(Advanced Linux Sound Architecture,縮寫為 ALSA)是
    發(fā)表于 12-08 10:20

    測(cè)試環(huán)境ubuntu12與其他linux系統(tǒng)有何異同

    測(cè)試環(huán)境 ubuntu12 與其他linux 系統(tǒng)大同小異 高級(jí)Linux聲音體系(英語(yǔ):Advanced Linux Sound Arch
    發(fā)表于 07-29 07:17

    alsa-lib實(shí)現(xiàn)聲音數(shù)據(jù)捕獲保存與播放的方法

    內(nèi)核: Linux3.5二、下載alsa-lib庫(kù)項(xiàng)目主頁(yè)下載地址:https://www.alsa-project.org/wiki/Main_PageFTP服務(wù)器下載地址(可下載歷史版本):ftp://ftp.
    發(fā)表于 12-24 08:17

    ALSA-lib移植的相關(guān)資料分享

    Linux ALSA音頻框架分析六:ALSA-lib移植 雖然linuxalsa框架給用戶空間提供了系統(tǒng)調(diào)用,但
    發(fā)表于 12-24 07:35

    LINUX音頻驅(qū)動(dòng)架構(gòu)相關(guān)資料分享

    1、LINUX音頻驅(qū)動(dòng)架構(gòu)  LINUX下音頻驅(qū)動(dòng)開發(fā),要遵循標(biāo)準(zhǔn)的ALSA架構(gòu),  下面分別從硬件架構(gòu)
    發(fā)表于 11-04 15:57

    Linux下聲卡的安裝(ALSA

    Advanced Linux Sound Architecture (ALSA) 的網(wǎng)站: http://www.alsa-project.org/ 1、現(xiàn)在最新版的的驅(qū)動(dòng)
    發(fā)表于 11-07 10:28 ?0次下載

    Linux ALSA聲卡驅(qū)動(dòng)之ALSA架構(gòu)簡(jiǎn)介

    ALSA是Advanced Linux Sound Architecture 的縮寫,目前已經(jīng)成為了linux的主流音頻體系結(jié)構(gòu),想了解更多的關(guān)于ALSA的這一開源項(xiàng)目的信息和知識(shí)
    發(fā)表于 04-26 15:55 ?1149次閱讀
    <b class='flag-5'>Linux</b> <b class='flag-5'>ALSA</b>聲卡驅(qū)動(dòng)之<b class='flag-5'>ALSA</b><b class='flag-5'>架構(gòu)</b>簡(jiǎn)介

    Linux ALSA聲卡驅(qū)動(dòng)之一:ALSA架構(gòu)簡(jiǎn)介

    ALSA是Advanced Linux Sound Architecture 的縮寫,目前已經(jīng)成為了linux的主流音頻體系結(jié)構(gòu),想了解更多的關(guān)于ALSA的這一開源項(xiàng)目的信息和知識(shí)
    發(fā)表于 05-10 13:44 ?1602次閱讀
    <b class='flag-5'>Linux</b> <b class='flag-5'>ALSA</b>聲卡驅(qū)動(dòng)之一:<b class='flag-5'>ALSA</b><b class='flag-5'>架構(gòu)</b>簡(jiǎn)介

    學(xué)習(xí)Linux操作系統(tǒng)中Alsa音頻編程

    ALSA項(xiàng)目發(fā)起的起因是Linux下的聲卡驅(qū)動(dòng)(OSS/Free drivers)沒有得到積極的維護(hù)。并且落后于新的聲卡技術(shù)。Jaroslav Kysela早先寫了一個(gè)聲卡驅(qū)動(dòng),并由此開始了ALSA項(xiàng)目,隨便,更多的開發(fā)者加入到
    發(fā)表于 05-10 14:27 ?5497次閱讀

    你知道Linux audio(OSS)子系統(tǒng)是怎樣?

    linux聲卡的驅(qū)動(dòng)中存在兩種架構(gòu),一種是OSS(開放聲音系統(tǒng)),一種是ALSA(先進(jìn)Linux聲音
    發(fā)表于 05-16 15:12 ?2033次閱讀
    你知道<b class='flag-5'>Linux</b> audio(OSS)子系統(tǒng)是怎樣?

    Linux應(yīng)用開發(fā)【第八章】ALSA應(yīng)用開發(fā)

    文章目錄 8 ALSA應(yīng)用開發(fā) 8.1 音頻相關(guān)概念 8.1.1 采樣頻率 8.1.2 量化位數(shù) 8.2 ALSA架構(gòu) 8.2.1 ALSA架構(gòu)
    的頭像 發(fā)表于 12-10 19:19 ?931次閱讀
    <b class='flag-5'>Linux</b>應(yīng)用開發(fā)【第八章】<b class='flag-5'>ALSA</b>應(yīng)用開發(fā)

    高級(jí)linux聲卡架構(gòu)ALSA概述及特點(diǎn)

    ALSA(Advanced Linux Sound Architecture )是高級(jí) linux 聲卡架構(gòu)簡(jiǎn)稱,是目前
    發(fā)表于 10-17 10:35 ?4304次閱讀

    Sitara Linux ALSA DSP麥克風(fēng)陣列語(yǔ)音識(shí)別

    電子發(fā)燒友網(wǎng)站提供《Sitara Linux ALSA DSP麥克風(fēng)陣列語(yǔ)音識(shí)別.pdf》資料免費(fèi)下載
    發(fā)表于 10-10 09:13 ?0次下載
    Sitara <b class='flag-5'>Linux</b> <b class='flag-5'>ALSA</b> DSP麥克風(fēng)陣列語(yǔ)音識(shí)別