萬網(wǎng)域名備案網(wǎng)站網(wǎng)推拉新app推廣平臺
ALPHA I.MX6U 開發(fā)板支持音頻,板上搭載了音頻編解碼芯片 WM8960,支持播放以及錄音功能!本章我們來學習 Linux 下的音頻應用編程,音頻應用編程相比于前面幾個章節(jié)所介紹的內(nèi)容、其難度有所上升,但是筆者僅向大家介紹 Linux 音頻應用編程中的基礎(chǔ)知識,而更多細節(jié)、更加深入的內(nèi)容需要大家自己去學習。
本章將會討論如下主題內(nèi)容。
? Linux 下 ALSA 框架概述;
? alsa-lib 庫介紹;
? alsa-lib 庫移植;
? alsa-lib 庫的使用;
? 音頻應用編程之播放;
? 音頻應用編程之錄音。
ALSA 概述
ALSA 是 Advanced Linux Sound Architecture(高級的 Linux 聲音體系)的縮寫,目前已經(jīng)成為了 linux下的主流音頻體系架構(gòu),提供了音頻和 MIDI 的支持,替代了原先舊版本中的 OSS(開發(fā)聲音系統(tǒng));學習過 Linux 音頻驅(qū)動開發(fā)的讀者肯定知道這個;事實上,ALSA 是 Linux 系統(tǒng)下一套標準的、先進的音頻驅(qū)動框架,那么這套框架的設(shè)計本身是比較復雜的,采用分離、分層思想設(shè)計而成,具體的細節(jié)便不給大家介紹了!作為音頻應用編程,我們不用去研究這個。
在應用層,ALSA 為我們提供了一套標準的 API,應用程序只需要調(diào)用這些 API 就可完成對底層音頻硬件設(shè)備的控制,譬如播放、錄音等,這一套 API 稱為 alsa-lib。如下圖所示:
alsa-lib 簡介
如上所述,alsa-lib 是一套 Linux 應用層的 C 語言函數(shù)庫,為音頻應用程序開發(fā)提供了一套統(tǒng)一、標準的接口,應用程序只需調(diào)用這一套 API 即可完成對底層聲卡設(shè)備的操控,譬如播放與錄音。
用戶空間的 alsa-lib 對應用程序提供了統(tǒng)一的 API 接口,這樣可以隱藏驅(qū)動層的實現(xiàn)細節(jié),簡化了應用程序的實現(xiàn)難度、無需應用程序開發(fā)人員直接去讀寫音頻設(shè)備節(jié)點。所以本章,對于我們來說,學習音頻應用編程其實就是學習 alsa-lib 庫函數(shù)的使用、如何基于 alsa-lib 庫函數(shù)開發(fā)音頻應用程序。
ALSA 提供了關(guān)于 alsa-lib 的使用說明文檔,其鏈接地址為:https://www.alsa-project.org/alsa-doc/alsa-lib/,
進入到該鏈接地址后,如下所示:
alsa-lib 庫支持功能比較多,提供了豐富的 API 接口供應用程序開發(fā)人員調(diào)用,根據(jù)函數(shù)的功能、作用將這些 API 進行了分類,可以點擊上圖中 Modules 按鈕查看其模塊劃分,如下所示:
一個分類就是一個模塊(module),有些模塊下可能該包含了子模塊,譬如上圖中,模塊名稱前面有三角箭頭的表示該模塊包含有子模塊。
? Global defines and functions:包括一些全局的定義,譬如函數(shù)、宏等;
? Constants for Digital Audio Interfaces:數(shù)字音頻接口相關(guān)的常量;
? Input Interface:輸入接口;
? Output Interface:輸出接口;
? Error handling:錯誤處理相關(guān)接口;
? Configuration Interface:配置接口;
? Control Interface:控制接口;
? PCM Interface:PCM 設(shè)備接口;
? RawMidi Interface:RawMidi 接口;
? Timer Interface:定時器接口;
? Hardware Dependant Interface:硬件相關(guān)接口;
? MIDI Sequencer:MIDI 音序器;
? External PCM plugin SDK:外部 PCM 插件 SDK;
? External Control Plugin SDK:外部控制插件 SDK;
? Mixer Interface:混音器接口;
? Use Case Interface:用例接口;
? Topology Interface:拓撲接口。
可以看到,alsa-lib 提供的接口確實非常多、模塊很多,以上所列舉出來的這些模塊,很多模塊筆者也不是很清楚它們的具體功能、作用,但是本章我們僅涉及到三個模塊下的 API 函數(shù),包括:PCM Interface、Error Interface 以及 Mixer Interface。
PCM Interface
PCM Interface,提供了 PCM 設(shè)備相關(guān)的操作接口,譬如打開/關(guān)閉 PCM 設(shè)備、配置 PCM 設(shè)備硬件或軟件參數(shù)、控制 PCM 設(shè)備(啟動、暫停、恢復、寫入/讀取數(shù)據(jù)),該模塊下還包含了一些子模塊,如下所示:
點擊模塊名稱可以查看到該模塊提供的API接口有哪些以及相應的函數(shù)說明,這里就不給大家演示了!
Error Interface
該模塊提供了關(guān)于錯誤處理相關(guān)的接口,譬如函數(shù)調(diào)用發(fā)生錯誤時,可調(diào)用該模塊下提供的函數(shù)打印錯誤描述信息。
Mixer Interface
提供了關(guān)于混音器相關(guān)的一系列操作接口,譬如音量、聲道控制、增益等等。
sound 設(shè)備節(jié)點
在 Linux 內(nèi)核設(shè)備驅(qū)動層、基于 ALSA 音頻驅(qū)動框架注冊的 sound 設(shè)備會在/dev/snd 目錄下生成相應的設(shè)備節(jié)點文件,譬如 ALPHA I.MX6U 開發(fā)板出廠系統(tǒng)/dev/snd 目錄下有如下文件:
Tips:注意,Mini I.MX6U 開發(fā)板出廠系統(tǒng)/dev/snd 目錄下是沒有這些文件的,因為 Mini 板不支持音頻、沒有板載音頻編解碼芯片,所以本章實驗例程無法在 Mini 板上進行測試,請悉知!
從上圖可以看到有如下設(shè)備文件:
? controlC0:用于聲卡控制的設(shè)備節(jié)點,譬如通道選擇、混音器、麥克風的控制等,C0 表示聲卡 0(card0);
? pcmC0D0c:用于錄音的 PCM 設(shè)備節(jié)點。其中 C0 表示 card0,也就是聲卡 0;而 D0 表示 device0,也就是設(shè)備 0;最后一個字母 c 是 capture 的縮寫,表示錄音;所以 pcmC0D0c 便是系統(tǒng)的聲卡0 中的錄音設(shè)備 0;
? pcmC0D0p:用于播放(或叫放音、回放)的 PCM 設(shè)備節(jié)點。其中 C0 表示 card0,也就是聲卡 0;而 D0 表示 device 0,也就是設(shè)備 0;最后一個字母 p 是 playback 的縮寫,表示播放;所以 pcmC0D0p便是系統(tǒng)的聲卡 0 中的播放設(shè)備 0;
? pcmC0D1c:用于錄音的 PCM 設(shè)備節(jié)點。對應系統(tǒng)的聲卡 0 中的錄音設(shè)備 1;
? pcmC0D1p:用于播放的 PCM 設(shè)備節(jié)點。對應系統(tǒng)的聲卡 0 中的播放設(shè)備 1。
? timer:定時器。
本章我們編寫的應用程序,雖然是調(diào)用 alsa-lib 庫函數(shù)去控制底層音頻硬件,但最終也是落實到對 sound設(shè)備節(jié)點的 I/O 操作,只不過 alsa-lib 已經(jīng)幫我們封裝好了。在 Linux 系統(tǒng)的/proc/asound 目錄下,有很多的文件,這些文件記錄了系統(tǒng)中聲卡相關(guān)的信息,如下所示:
cards:
通過"cat /proc/asound/cards"命令、查看 cards 文件的內(nèi)容,可列出系統(tǒng)中可用的、注冊的聲卡,如下所示:
cat /proc/asound/cards
我們的阿爾法板子上只有一個聲卡(WM8960 音頻編解碼器),所以它的編號為 0,也就是 card0。系統(tǒng)中注冊的所有聲卡都會在/proc/asound/目錄下存在一個相應的目錄,該目錄的命名方式為 cardX(X 表示 聲卡的編號),譬如圖 28.3.2 中的 card0;card0 目錄下記錄了聲卡 0 相關(guān)的信息,譬如聲卡的名字以及聲卡注冊的 PCM 設(shè)備,如下所示:
devices:
列出系統(tǒng)中所有聲卡注冊的設(shè)備,包括 control、pcm、timer、seq 等等。如下所示:
cat /proc/asound/devices
pcm:
列出系統(tǒng)中的所有 PCM 設(shè)備,包括 playback 和 capture:
cat /proc/asound/pcm
alsa-lib 移植
因為 alsa-lib 是 ALSA 提供的一套 Linux 下的 C 語言函數(shù)庫,需要將 alsa-lib 移植到開發(fā)板上,這樣基于 alsa-lib 編寫的應用程序才能成功運行,除了移植 alsa-lib 庫之外,通常還需要移植 alsa-utils,alsa-utils 包含了一些用于測試、配置聲卡的工具。
事實上,ALPHA I.MX6U 開發(fā)板出廠系統(tǒng)中已經(jīng)移植了 alsa-lib 和 alsa-utils,本章我們直接使用出廠系統(tǒng)移植好的 alsa-lib 和 alsa-utils 進行測試,筆者也就不再介紹移植過程了。其實它們的移植方法也非常簡單,如果你想自己嘗試移植,網(wǎng)上有很多參考,大家可以自己去看看。
alsa-utils 提供了一些用于測試、配置聲卡的工具,譬如 aplay、arecord、alsactl、alsaloop、alsamixer、amixer 等,在開發(fā)板出廠系統(tǒng)上可以直接使用這些工具,這些應用程序也都是基于 alsa-lib 編寫的。
aplay
aplay 是一個用于測試音頻播放功能程序,可以使用 aplay 播放 wav 格式的音頻文件,如下所示:
程序運行之后就會開始播放音樂,因為 ALPHA 開發(fā)板支持喇叭和耳機自動切換,如果不插耳機默認從喇叭播放音樂,插上耳機以后喇叭就會停止播放,切換為耳機播放音樂,這個大家可以自己進行測試。
需要注意的是,aplay 工具只能解析 wav 格式音頻文件,不支持 mp3 格式解碼,所以無法使用 aplay 工具播放 mp3 音頻文件。稍后筆者會向大家介紹如何基于 alsa-lib 編寫一個簡單地音樂播放器,實現(xiàn)與 aplay相同的效果。
更多命令參考正電原子應用開發(fā)手冊即可。
暫略。
編寫一個簡單的alsa-lib應用程序
本小節(jié)開始,我們來學習如何基于 alsa-lib 編寫音頻應用程序,alsa-lib 提供的庫函數(shù)也別多,筆者肯定不會全部給大家介紹,只介紹基礎(chǔ)的使用方法,關(guān)于更加深入、更加詳細的使用方法需要大家自己去研究、學習。
對于 alsa-lib 庫的使用,ALSA 提供了一些參考資料來幫助應用程序開發(fā)人員快速上手 alsa-lib、基于alsa-lib 進行應用編程,以下筆者給出了鏈接:
https://users.suse.com/~mana/alsa090_howto.html
https://www.alsa-project.org/alsa-doc/alsa-lib/examples.html
第一份文檔向用戶介紹了如何使用 alsa-lib 編寫簡單的音頻應用程序,包括 PCM 播放音頻、PCM 錄音等,筆者也是參考了這份文檔來編寫本章教程,對應初學者,建議大家看一看。
第二個鏈接地址是 ALSA 提供的一些示例代碼,如下所示:
點擊對應源文件即可查看源代碼。
以上便是 ALSA 提供的幫助文檔以及參考代碼,鏈接地址已經(jīng)給出了,大家有興趣可以看一下。
本小節(jié)筆者將向大家介紹如何基于 alsa-lib 編寫一個簡單地音頻應用程序,譬如播放音樂、錄音等;但在此之前,首先我們需要先來了解一些基本的概念,為后面的學習打下一個堅實的基礎(chǔ)!
一些基本概念
主要是與音頻相關(guān)的基本概念,因為在 alsa-lib 應用編程中會涉及到這些概念,所以先給大家進行一個簡單地介紹。
樣本長度(Sample)
樣本是記錄音頻數(shù)據(jù)最基本的單元,樣本長度就是采樣位數(shù),也稱為位深度(Bit Depth、Sample Size、Sample Width)。是指計算機在采集和播放聲音文件時,所使用數(shù)字聲音信號的二進制位數(shù),或者說每個采樣樣本所包含的位數(shù)(計算機對每個通道采樣量化時數(shù)字比特位數(shù)),通常有 8bit、16bit、24bit 等。
聲道數(shù)(channel)
分為單聲道(Mono)和雙聲道/立體聲(Stereo)。1 表示單聲道、2 表示立體聲。
幀(frame)
幀記錄了一個聲音單元,其長度為樣本長度與聲道數(shù)的乘積,一段音頻數(shù)據(jù)就是由苦干幀組成的。
把所有聲道中的數(shù)據(jù)加在一起叫做一幀,對于單聲道:一幀 = 樣本長度 * 1;雙聲道:一幀 = 樣本長度 * 2。譬如對于樣本長度為 16bit 的雙聲道來說,一幀的大小等于:16 * 2 / 8 = 4 個字節(jié)。
更多命令參考正電原子應用開發(fā)手冊即可。
暫略。
關(guān)于音頻,先了解吧。
后面如果要接觸,再來深入學習。
補充
什么是PCM設(shè)備?
脈沖編碼調(diào)制(Pulse Code Modulation,簡稱PCM)是一種將模擬信號轉(zhuǎn)換為數(shù)字信號的技術(shù)。這種轉(zhuǎn)換過程是通過測量模擬信號的特征點(例如電壓或電流)并將其編碼為二進制數(shù)字數(shù)據(jù)來實現(xiàn)的。
在通信系統(tǒng)中,PCM設(shè)備的作用主要體現(xiàn)在以下幾個方面:
低速業(yè)務轉(zhuǎn)換:PCM設(shè)備可以將各種低速業(yè)務轉(zhuǎn)換成數(shù)字信號,并裝入64kbit/s通道。這些低速業(yè)務包括但不限于語音電話、熱線電話、磁石電話等,以及2W/4W模擬音頻、RS-232、RS-422、RS-485、V.35、G.703同向64kbit/s以太網(wǎng)等。
多路復用:PCM設(shè)備具有將30路64kbit/s通道復接成2Mbit/s的能力,從而實現(xiàn)了多路復用的功能。這意味著在同一條物理線路上可以同時傳輸多路信號,提高了線路的利用率和通信效率。
信號傳輸:在光纖通信系統(tǒng)中,PCM設(shè)備發(fā)揮著重要作用。光纖中傳輸?shù)亩M制光脈沖“0”碼和“1”碼,就是由二進制數(shù)字信號對光源進行通斷調(diào)制產(chǎn)生的,而數(shù)字信號正是通過對連續(xù)變化的模擬信號進行抽樣、量化和編碼得到的,這就是PCM的過程。
接口類型多樣:PCM設(shè)備的接口類型豐富多樣,包括環(huán)路中繼接口、用戶線接口、二線音頻接口、四線音頻接口、異步RS232/V.24接口、同步RS232、RS422接口、RS485接口、V.35接口、G.703 64Kb/s同向數(shù)據(jù)接口等。
總的來說,PCM設(shè)備在現(xiàn)代通信系統(tǒng)中扮演著重要角色,它不僅能夠?qū)崿F(xiàn)模擬信號到數(shù)字信號的轉(zhuǎn)換,還能夠通過多路復用技術(shù)提高通信效率,滿足不同用戶對數(shù)據(jù)傳輸速率的需求。