linux 音訊採集基礎知識普及
雖然目前Linux的優勢主要體現在網路服務方面,但事實上同樣也有著非常豐富的媒體功能,本文就是以多媒體應用中最基本的聲音為物件,介紹如何在Linux平臺下開發實際的音訊應用程式,同時還給出了一些常用的音訊程式設計框架。
一、數字音訊
音訊訊號是一種連續變化的模擬訊號,但計算機只能處理和記錄二進位制的數字訊號,由自然音源得到的音訊訊號必須經過一定的變換,成為數字音訊訊號之後,才能送到計算機中作進一步的處理。
數字音訊系統通過將聲波的波型轉換成一系列二進位制資料,來實現對原始聲音的重現,實現這一步驟的裝置常被稱為模/數轉換器(A/D)。A/D轉換器以每秒鐘上萬次的速率對聲波進行取樣,每個取樣點都記錄下了原始模擬聲波在某一時刻的狀態,通常稱之為樣本(sample),而每一秒鐘所取樣的數目則稱為取樣頻率,通過將一串連續的樣本連線起來,就可以在計算機中描述一段聲音了。對於取樣過程中的每一個樣本來說,數字音訊系統會分配一定儲存位來記錄聲波的振幅,一般稱之為取樣分辯率或者取樣精度,取樣精度越高,聲音還原時就會越細膩。
數字音訊涉及到的概念非常多,對於在Linux下進行音訊程式設計的程式設計師來說,最重要的是理解聲音數字化的兩個關鍵步驟:取樣和量化。取樣就是每隔一定時間就讀一次聲音訊號的幅度,而量化則是將取樣得到的聲音訊號幅度轉換為數字值,從本質上講,取樣是時間上的數字化,而量化則是幅度上的數字化。下面介紹幾個在進行音訊程式設計時經常需要用到的技術指標:
- 取樣頻率
取樣頻率是指將模擬聲音波形進行數字化時,每秒鐘抽取聲波幅度樣本的次數。取樣頻率的選擇應該遵循奈奎斯特(Harry Nyquist)取樣理論:如果對某一模擬訊號進行取樣,則取樣後可還原的最高訊號頻率只有取樣頻率的一半,或者說只要取樣頻率高於輸入訊號最高頻率的兩倍,就能從取樣訊號系列重構原始訊號。正常人聽覺的頻率範圍大約在20Hz~20kHz之間,根據奈奎斯特取樣理論,為了保證聲音不失真,取樣頻率應該在40kHz左右。常用的音訊取樣頻率有8kHz、11.025kHz、22.05kHz、16kHz、37.8kHz、44.1kHz、48kHz等,如果採用更高的取樣頻率,還可以達到DVD的音質。 - 量化位數
量化位數是對模擬音訊訊號的幅度進行數字化,它決定了模擬訊號數字化以後的動態範圍,常用的有8位、12位和16位。量化位越高,訊號的動態範圍越大,數字化後的音訊訊號就越可能接近原始訊號,但所需要的存貯空間也越大。 - 聲道數
聲道數是反映音訊數字化質量的另一個重要因素,它有單聲道和雙聲道之分。雙聲道又稱為立體聲,在硬體中有兩條線路,音質和音色都要優於單聲道,但數字化後佔據的儲存空間的大小要比單聲道多一倍。
二、音效卡驅動
出於對安全性方面的考慮,Linux下的應用程式無法直接對音效卡這類硬體裝置進行操作,而是必須通過核心提供的驅動程式才能完成。在Linux上進行音訊程式設計的本質就是要藉助於驅動程式,來完成對音效卡的各種操作。
對硬體的控制涉及到暫存器中各個位元位的操作,通常這是與裝置直接相關並且對時序的要求非常嚴格,如果這些工作都交由應用程式設計師來負責,那麼對音效卡的程式設計將變得異常複雜而困難起來,驅動程式的作用正是要遮蔽硬體的這些底層細節,從而簡化應用程式的編寫。目前Linux下常用的音效卡驅動程式主要有兩種:OSS和ALSA。
最早出現在Linux上的音訊程式設計介面是OSS(Open Sound System),它由一套完整的核心驅動程式模組組成,可以為絕大多數音效卡提供統一的程式設計介面。OSS出現的歷史相對較長,這些核心模組中的一部分(OSS/Free)是與Linux核心原始碼共同免費釋出的,另外一些則以二進位制的形式由4Front Technologies公司提供。由於得到了商業公司的鼎力支援,OSS已經成為在Linux下進行音訊程式設計的事實標準,支援OSS的應用程式能夠在絕大多數音效卡上工作良好。
雖然OSS已經非常成熟,但它畢竟是一個沒有完全開放原始碼的商業產品,ALSA(Advanced Linux Sound Architecture)恰好彌補了這一空白,它是在Linux下進行音訊程式設計時另一個可供選擇的音效卡驅動程式。ALSA除了像OSS那樣提供了一組核心驅動程式模組之外,還專門為簡化應用程式的編寫提供了相應的函式庫,與OSS提供的基於ioctl的原始程式設計介面相比,ALSA函式庫使用起來要更加方便一些。ALSA的主要特點有:
支援多種音效卡裝置<br>
模組化的核心驅動程式<br>
支援SMP和多執行緒<br>
提供應用開發函式庫<br>
相容OSS應用程式<br>
ALSA和OSS最大的不同之處在於ALSA是由志願者維護的自由專案,而OSS則是由公司提供的商業產品,因此在對硬體的適應程度上OSS要優於ALSA,它能夠支援的音效卡種類更多。ALSA雖然不及OSS運用得廣泛,但卻具有更加友好的程式設計介面,並且完全兼容於OSS,對應用程式設計師來講無疑是一個更佳的選擇。
三、程式設計介面
如何對各種音訊裝置進行操作是在Linux上進行音訊程式設計的關鍵,通過核心提供的一組系統呼叫,應用程式能夠訪問音效卡驅動程式提供的各種音訊裝置介面,這是在Linux下進行音訊程式設計最簡單也是最直接的方法。
3.1 訪問音訊裝置
無論是OSS還是ALSA,都是以核心驅動程式的形式執行在Linux核心空間中的,應用程式要想訪問音效卡這一硬體裝置,必須藉助於Linux核心所提供的系統呼叫(system call)。從程式設計師的角度來說,對音效卡的操作在很大程度上等同於對磁碟檔案的操作:首先使用open系統呼叫建立起與硬體間的聯絡,此時返回的檔案描述符將作為隨後操作的標識;接著使用read系統呼叫從裝置接收資料,或者使用write系統呼叫向裝置寫入資料,而其它所有不符合讀/寫這一基本模式的操作都可以由ioctl系統呼叫來完成;最後,使用close系統呼叫告訴Linux核心不會再對該裝置做進一步的處理。
open系統呼叫
系統呼叫open可以獲得對音效卡的訪問權,同時還能為隨後的系統呼叫做好準備,其函式原型如下所示:
int open(const char *pathname, int flags, int mode);
引數pathname是將要被開啟的裝置檔案的名稱,對於音效卡來講一般是/dev/dsp。引數flags用來指明應該以什麼方式開啟裝置檔案,它可以是O_RDONLY、O_WRONLY或者O_RDWR,分別表示以只讀、只寫或者讀寫的方式開啟裝置檔案;引數mode通常是可選的,它只有在指定的裝置檔案不存在時才會用到,指明新建立的檔案應該具有怎樣的許可權。如果open系統呼叫能夠成功完成,它將返回一個正整數作為檔案識別符號,在隨後的系統呼叫中需要用到該識別符號。如果open系統呼叫失敗,它將返回-1,同時還會設定全域性變數errno,指明是什麼原因導致了錯誤的發生。
read系統呼叫
系統呼叫read用來從音效卡讀取資料,其函式原型如下所示:
int read(int fd, char *buf, size_t count);
引數fd是裝置檔案的識別符號,它是通過之前的open系統呼叫獲得的;引數buf是指向緩衝區的字元指標,它用來儲存從音效卡獲得的資料;引數count則用來限定從音效卡獲得的最大位元組數。如果read系統呼叫成功完成,它將返回從音效卡實際讀取的位元組數,通常情況會比count的值要小一些;如果read系統呼叫失敗,它將返回-1,同時還會設定全域性變數errno,來指明是什麼原因導致了錯誤的發生。
write系統呼叫
系統呼叫write用來向音效卡寫入資料,其函式原型如下所示:
size_t write(int fd, const char *buf, size_t count);
系統呼叫write和系統呼叫read在很大程度是類似的,差別只在於write是向音效卡寫入資料,而read則是從音效卡讀入資料。引數fd同樣是裝置檔案的識別符號,它也是通過之前的open系統呼叫獲得的;引數buf是指向緩衝區的字元指標,它儲存著即將向音效卡寫入的資料;引數count則用來限定向音效卡寫入的最大位元組數。如果write系統呼叫成功完成,它將返回向音效卡實際寫入的位元組數;如果read系統呼叫失敗,它將返回-1,同時還會設定全域性變數errno,來指明是什麼原因導致了錯誤的發生。無論是read還是write,一旦呼叫之後Linux核心就會阻塞當前應用程式,直到資料成功地從音效卡讀出或者寫入為止。
ioctl系統呼叫
系統呼叫ioctl可以對音效卡進行控制,凡是對裝置檔案的操作不符合讀/寫基本模式的,都是通過ioctl來完成的,它可以影響裝置的行為,或者返回裝置的狀態,其函式原型如下所示:
int ioctl(int fd, int request, …);
引數fd是裝置檔案的識別符號,它是在裝置開啟時獲得的;如果裝置比較複雜,那麼對它的控制請求相應地也會有很多種,引數request的目的就是用來區分不同的控制請求;通常說來,在對裝置進行控制時還需要有其它引數,這要根據不同的控制請求才能確定,並且可能是與硬體裝置直接相關的。
close系統呼叫
當應用程式使用完音效卡之後,需要用close系統呼叫將其關閉,以便及時釋放佔用的硬體資源,其函式原型如下所示:
int close(int fd);
引數fd是裝置檔案的識別符號,它是在裝置開啟時獲得的。一旦應用程式呼叫了close系統呼叫,Linux核心就會釋放與之相關的各種資源,因此建議在不需要的時候儘量及時關閉已經開啟的裝置。
3.2 音訊裝置檔案
對於Linux應用程式設計師來講,音訊程式設計介面實際上就是一組音訊裝置檔案,通過它們可以從音效卡讀取資料,或者向音效卡寫入資料,並且能夠對音效卡進行控制,設定取樣頻率和聲道數目等等。
/dev/sndstat
裝置檔案/dev/sndstat是音效卡驅動程式提供的最簡單的介面,通常它是一個只讀檔案,作用也僅僅只限於彙報音效卡的當前狀態。一般說來,/dev/sndstat是提供給終端使用者來檢測音效卡的,不宜用於程式當中,因為所有的資訊都可以通過ioctl系統呼叫來獲得。 Linux提供的cat命令可以很方便地從/dev/sndstat獲得音效卡的當前狀態:
[[email protected] sound]$ cat /dev/sndstat
/dev/dsp
音效卡驅動程式提供的/dev/dsp是用於數字取樣(sampling)和數字錄音(recording)的裝置檔案,它對於Linux下的音訊程式設計來講非常重要:向該裝置寫資料即意味著啟用音效卡上的D/A轉換器進行放音,而向該裝置讀資料則意味著啟用音效卡上的A/D轉換器進行錄音。目前許多音效卡都提供有多個數字取樣裝置,它們在Linux下可以通過/dev/dsp1等裝置檔案進行訪問。
DSP是數字訊號處理器(Digital Signal Processor)的簡稱,它是用來進行數字訊號處理的特殊晶片,音效卡使用它來實現模擬訊號和數字訊號的轉換。音效卡中的DSP裝置實際上包含兩個組成部分:在以只讀方式開啟時,能夠使用A/D轉換器進行聲音的輸入;而在以只寫方式開啟時,則能夠使用D/A轉換器進行聲音的輸出。嚴格說來,Linux下的應用程式要麼以只讀方式開啟/dev/dsp輸入聲音,要麼以只寫方式開啟/dev/dsp輸出聲音,但事實上某些音效卡驅動程式仍允許以讀寫的方式開啟/dev/dsp,以便同時進行聲音的輸入和輸出,這對於某些應用場合(如IP電話)來講是非常關鍵的。
在從DSP裝置讀取資料時,從音效卡輸入的模擬訊號經過A/D轉換器變成數字取樣後的樣本(sample),儲存在音效卡驅動程式的核心緩衝區中,當應用程式通過read系統呼叫從音效卡讀取資料時,儲存在核心緩衝區中的數字取樣結果將被複制到應用程式所指定的使用者緩衝區中。需要指出的是,音效卡取樣頻率是由核心中的驅動程式所決定的,而不取決於應用程式從音效卡讀取資料的速度。如果應用程式讀取資料的速度過慢,以致低於音效卡的取樣頻率,那麼多餘的資料將會被丟棄;如果讀取資料的速度過快,以致高於音效卡的取樣頻率,那麼音效卡驅動程式將會阻塞那些請求資料的應用程式,直到新的資料到來為止。
在向DSP裝置寫入資料時,數字訊號會經過D/A轉換器變成模擬訊號,然後產生出聲音。應用程式寫入資料的速度同樣應該與音效卡的取樣頻率相匹配,否則過慢的話會產生聲音暫停或者停頓的現象,過快的話又會被核心中的音效卡驅動程式阻塞,直到硬體有能力處理新的資料為止。與其它裝置有所不同,音效卡通常不會支援非阻塞(non-blocking)的I/O操作。
無論是從音效卡讀取資料,或是向音效卡寫入資料,事實上都具有特定的格式(format),預設為8位無符號資料、單聲道、8KHz取樣率,如果預設值無法達到要求,可以通過ioctl系統呼叫來改變它們。通常說來,在應用程式中開啟裝置檔案/dev/dsp之後,接下去就應該為其設定恰當的格式,然後才能從音效卡讀取或者寫入資料。
/dev/audio
/dev/audio類似於/dev/dsp,它兼容於Sun工作站上的音訊裝置,使用的是mu-law編碼方式。如果音效卡驅動程式提供了對/dev/audio的支援,那麼在Linux上就可以通過cat命令,來播放在Sun工作站上用mu-law進行編碼的音訊檔案:
[[email protected] sound]$ cat audio.au /dev/audio
由於裝置檔案/dev/audio主要出於對相容性的考慮,所以在新開發的應用程式中最好不要嘗試用它,而應該以/dev/dsp進行替代。對於應用程式來說,同一時刻只能使用/dev/audio或者/dev/dsp其中之一,因為它們是相同硬體的不同軟體介面。
/dev/mixer
在音效卡的硬體電路中,混音器(mixer)是一個很重要的組成部分,它的作用是將多個訊號組合或者疊加在一起,對於不同的音效卡來說,其混音器的作用可能各不相同。執行在Linux核心中的音效卡驅動程式一般都會提供/dev/mixer這一裝置檔案,它是應用程式對混音器進行操作的軟體介面。混音器電路通常由兩個部分組成:輸入混音器(input mixer)和輸出混音器(output mixer)。
輸入混音器負責從多個不同的訊號源接收模擬訊號,這些訊號源有時也被稱為混音通道或者混音裝置。模擬訊號通過增益控制器和由軟體控制的音量調節器後,在不同的混音通道中進行級別(level)調製,然後被送到輸入混音器中進行聲音的合成。混音器上的電子開關可以控制哪些通道中有訊號與混音器相連,有些音效卡只允許連線一個混音通道作為錄音的音源,而有些音效卡則允許對混音通道做任意的連線。經過輸入混音器處理後的訊號仍然為模擬訊號,它們將被送到A/D轉換器進行數字化處理。
輸出混音器的工作原理與輸入混音器類似,同樣也有多個訊號源與混音器相連,並且事先都經過了增益調節。當輸出混音器對所有的模擬訊號進行了混合之後,通常還會有一個總控增益調節器來控制輸出聲音的大小,此外還有一些音調控制器來調節輸出聲音的音調。經過輸出混音器處理後的訊號也是模擬訊號,它們最終會被送給喇叭或者其它的模擬輸出裝置。對混音器的程式設計包括如何設定增益控制器的級別,以及怎樣在不同的音源間進行切換,這些操作通常來講是不連續的,而且不會像錄音或者放音那樣需要佔用大量的計算機資源。由於混音器的操作不符合典型的讀/寫操作模式,因此除了open和close兩個系統呼叫之外,大部分的操作都是通過ioctl系統呼叫來完成的。與/dev/dsp不同,/dev/mixer允許多個應用程式同時訪問,並且混音器的設定值會一直保持到對應的裝置檔案被關閉為止。
為了簡化應用程式的設計,Linux上的音效卡驅動程式大多都支援將混音器的ioctl操作直接應用到聲音裝置上,也就是說如果已經打開了/dev/dsp,那麼就不用再開啟/dev/mixer來對混音器進行操作,而是可以直接用開啟/dev/dsp時得到的檔案識別符號來設定混音器。
/dev/sequencer
目前大多數音效卡驅動程式還會提供/dev/sequencer這一裝置檔案,用來對音效卡內建的波表合成器進行操作,或者對MIDI總線上的樂器進行控制,一般只用於計算機音樂軟體中。
四、應用框架
在Linux下進行音訊程式設計時,重點在於如何正確地操作音效卡驅動程式所提供的各種裝置檔案,由於涉及到的概念和因素比較多,所以遵循一個通用的框架無疑將有助於簡化應用程式的設計。
4.1 DSP程式設計
對音效卡進行程式設計時首先要做的是開啟與之對應的硬體裝置,這是藉助於open系統呼叫來完成的,並且一般情況下使用的是/dev/dsp檔案。採用何種模式對音效卡進行操作也必須在開啟裝置時指定,對於不支援全雙工的音效卡來說,應該使用只讀或者只寫的方式開啟,只有那些支援全雙工的音效卡,才能以讀寫的方式開啟,並且還要依賴於驅動程式的具體實現。Linux允許應用程式多次開啟或者關閉與音效卡對應的裝置檔案,從而能夠很方便地在放音狀態和錄音狀態之間進行切換,建議在進行音訊程式設計時只要有可能就儘量使用只讀或者只寫的方式開啟裝置檔案,因為這樣不僅能夠充分利用音效卡的硬體資源,而且還有利於驅動程式的優化。下面的程式碼示範瞭如何以只寫方式開啟音效卡進行放音(playback)操作:
int handle = open("/dev/dsp", O_WRONLY);
if (handle == -1) {
perror("open /dev/dsp");
return -1;
}
執行在Linux核心中的音效卡驅動程式專門維護了一個緩衝區,其大小會影響到放音和錄音時的效果,使用ioctl系統呼叫可以對它的尺寸進行恰當的設定。調節驅動程式中緩衝區大小的操作不是必須的,如果沒有特殊的要求,一般採用預設的緩衝區大小也就可以了。但需要注意的是,緩衝區大小的設定通常應緊跟在裝置檔案開啟之後,這是因為對音效卡的其它操作有可能會導致驅動程式無法再修改其緩衝區的大小。下面的程式碼示範了怎樣設定音效卡驅動程式中的核心緩衝區的大小:
int setting = 0xnnnnssss;
int result = ioctl(handle, SNDCTL_DSP_SETFRAGMENT, &setting);
if (result == -1) {
perror("ioctl buffer size");
return -1;
}
// 檢查設定值的正確性
在設定緩衝區大小時,引數setting實際上由兩部分組成,其低16位標明緩衝區的尺寸,相應的計算公式為buffer_size = 2^ssss,即若引數setting低16位的值為16,那麼相應的緩衝區的大小會被設定為65536位元組。引數setting的高16位則用來標明分片(fragment)的最大序號,它的取值範圍從2一直到0x7FFF,其中0x7FFF表示沒有任何限制。
接下來要做的是設定音效卡工作時的聲道(channel)數目,根據硬體裝置和驅動程式的具體情況,可以將其設定為0(單聲道,mono)或者1(立體聲,stereo)。下面的程式碼示範了應該怎樣設定聲道數目:
int channels = 0; // 0=mono 1=stereo
int result = ioctl(handle, SNDCTL_DSP_STEREO, &channels);
if ( result == -1 ) {
perror("ioctl channel number");
return -1;
}
if (channels != 0) {
// 只支援立體聲
}
取樣格式和取樣頻率是在進行音訊程式設計時需要考慮的另一個問題,音效卡支援的所有采樣格式可以在標頭檔案soundcard.h中找到,而通過ioctl系統呼叫則可以很方便地更改當前所使用的取樣格式。下面的程式碼示範瞭如何設定音效卡的取樣格式:
int format = AFMT_U8;
int result = ioctl(handle, SNDCTL_DSP_SETFMT, &format);
if ( result == -1 ) {
perror("ioctl sample format");
return -1;
}
// 檢查設定值的正確性
音效卡取樣頻率的設定也非常容易,只需在呼叫ioctl時將第二個引數的值設定為SNDCTL_DSP_SPEED,同時在第三個引數中指定取樣頻率的數值就行了。對於大多數音效卡來說,其支援的取樣頻率範圍一般為5kHz到44.1kHz或者48kHz,但並不意味著該範圍內的所有頻率都會被硬體支援,在Linux下進行音訊程式設計時最常用到的幾種取樣頻率是11025Hz、16000Hz、22050Hz、32000Hz和44100Hz。下面的程式碼示範瞭如何設定音效卡的取樣頻率:
int rate = 22050;
int result = ioctl(handle, SNDCTL_DSP_SPEED, &rate);
if ( result == -1 ) {
perror("ioctl sample format");
return -1;
}
// 檢查設定值的正確性
4.2 Mixer程式設計
音效卡上的混音器由多個混音通道組成,它們可以通過驅動程式提供的裝置檔案/dev/mixer進行程式設計。對混音器的操作是通過ioctl系統呼叫來完成的,並且所有控制命令都由SOUND_MIXER或者MIXER開頭,表1列出了常用的幾個混音器控制命令:
名 稱 作 用
SOUND_MIXER_VOLUME 主音量調節
SOUND_MIXER_BASS 低音控制
SOUND_MIXER_TREBLE 高音控制
SOUND_MIXER_SYNTH FM合成器
SOUND_MIXER_PCM 主D/A轉換器
SOUND_MIXER_SPEAKER PC喇叭
SOUND_MIXER_LINE 音訊線輸入
SOUND_MIXER_MIC 麥克風輸入
SOUND_MIXER_CD CD輸入
SOUND_MIXER_IMIX 回放音量
SOUND_MIXER_ALTPCM 從D/A 轉換器
SOUND_MIXER_RECLEV 錄音音量
SOUND_MIXER_IGAIN 輸入增益
SOUND_MIXER_OGAIN 輸出增益
SOUND_MIXER_LINE1 音效卡的第1輸入
SOUND_MIXER_LINE2 音效卡的第2輸入
SOUND_MIXER_LINE3 音效卡的第3輸入
表1 混音器命令
對音效卡的輸入增益和輸出增益進行調節是混音器的一個主要作用,目前大部分音效卡採用的是8位或者16位的增益控制器,但作為程式設計師來講並不需要關心這些,因為音效卡驅動程式會負責將它們變換成百分比的形式,也就是說無論是輸入增益還是輸出增益,其取值範圍都是從0到100。在進行混音器程式設計時,可以使用SOUND_MIXER_READ巨集來讀取混音通道的增益大小,例如在獲取麥克風的輸入增益時,可以使用如下的程式碼:
int vol;
ioctl(fd, SOUND_MIXER_READ(SOUND_MIXER_MIC), &vol);
printf("Mic gain is at %d %%\n", vol);
對於只有一個混音通道的單聲道裝置來說,返回的增益大小儲存在低位位元組中。而對於支援多個混音通道的雙聲道裝置來說,返回的增益大小實際上包括兩個部分,分別代表左、右兩個聲道的值,其中低位位元組儲存左聲道的音量,而高位位元組則儲存右聲道的音量。下面的程式碼可以從返回值中依次提取左右聲道的增益大小:
int left, right;
left = vol & 0xff;
right = (vol & 0xff00) >8;
printf("Left gain is %d %%, Right gain is %d %%\n", left, right);
類似地,如果想設定混音通道的增益大小,則可以通過SOUND_MIXER_WRITE巨集來實現,此時遵循的原則與獲取增益值時的原則基本相同,例如下面的語句可以用來設定麥克風的輸入增益:
vol = (right << 8) + left;
ioctl(fd, SOUND_MIXER_WRITE(SOUND_MIXER_MIC), &vol);
在編寫實用的音訊程式時,混音器是在涉及到相容性時需要重點考慮的一個物件,這是因為不同的音效卡所提供的混音器資源是有所區別的。音效卡驅動程式提供了多個ioctl系統呼叫來獲得混音器的資訊,它們通常返回一個整型的位掩碼(bitmask),其中每一位分別代表一個特定的混音通道,如果相應的位為1,則說明與之對應的混音通道是可用的。例如通過SOUND_MIXER_READ_DEVMASK返回的位掩碼,可以查詢出能夠被音效卡支援的每一個混音通道,而通過SOUND_MIXER_READ_RECMAS返回的位掩碼,則可以查詢出能夠被當作錄音源的每一個通道。下面的程式碼可以用來檢查CD輸入是否是一個有效的混音通道:
ioctl(fd, SOUND_MIXER_READ_DEVMASK, &devmask);
if (devmask & SOUND_MIXER_CD)
printf("The CD input is supported");
如果進一步還想知道其是否是一個有效的錄音源,則可以使用如下語句:
ioctl(fd, SOUND_MIXER_READ_RECMASK, &recmask);
if (recmask & SOUND_MIXER_CD)
printf("The CD input can be a recording source");
目前大多數音效卡提供多個錄音源,通過SOUND_MIXER_READ_RECSRC可以查詢出當前正在使用的錄音源,同一時刻能夠使用幾個錄音源是由音效卡硬體決定的。類似地,使用SOUND_MIXER_WRITE_RECSRC可以設定音效卡當前使用的錄音源,例如下面的程式碼可以將CD輸入作為音效卡的錄音源使用:
devmask = SOUND_MIXER_CD;
ioctl(fd, SOUND_MIXER_WRITE_DEVMASK, &devmask);
附:
WAV檔案作為最經典的Windows多媒體音訊格式,應用非常廣泛,它使用三個引數來表示聲音:取樣位數、取樣頻率和聲道數。
聲道有單聲道和立體聲之分,取樣頻率一般有11025Hz(11kHz)、22050Hz(22kHz)和44100Hz(44kHz)三種。WAV檔案所佔容量=(取樣頻率×取樣位數×聲道)×時間/8(1位元組=8bit)。
相關推薦
linux 音訊採集基礎知識普及
雖然目前Linux的優勢主要體現在網路服務方面,但事實上同樣也有著非常豐富的媒體功能,本文就是以多媒體應用中最基本的聲音為物件,介紹如何在Linux平臺下開發實際的音訊應用程式,同時還給出了一些常用的音訊程式設計框架。 一、數字音訊 音訊訊號是一種連
Linux操作系統基礎知識part4
linux操作系統 表示 占用內存 lin part 子進程 df -h sed use top僵屍進程 失去了父進程的子進程,占用內存不占用cpucpu的利用率:實際單位時間內計算的工作量cpu的負載:cpu被安排的工作量 freebuffers 表示內存往硬盤存寫的數據
Linux操作系統基礎知識(五)
狀態 -exec acer res ifconfig 查找 mas 配置文件 update ifconfig 命令查看網絡信息eth0 eth1em1 em2p2p2 p2p3 systemctl status network 查看網絡狀態systemctl start n
Vue.js 運行環境搭建詳解(基於windows的手把手安裝教學)及vue、node基礎知識普及
頁面 沒有 全能 服務器程序 重載 帶來 size 耐心 編程 Vue.js 是一套構建用戶界面的漸進式框架。他自身不是一個全能框架——只聚焦於視圖層。因此它非常容易學習,非常容易與其它庫或已有項目整合。在與相關工具和支持庫一起使用時,Vue.j
Linux入門及基礎知識
linux如果操作系統發展史出一部美國大片,那一定是三國硝煙的味道。上世界末的一群西方人,雖沒有西部牛仔的放蕩不羈,也成就了一段令後人難望其項背的歷史。而且,身為Unix之父,Linux之父,計算機開源運動之父,Windows之父,無一例外,都還好好的活在這個他們親眼見證的,不斷發展壯大的信息技術時代。197
linux網絡基礎知識(幹貨)
linux 網絡運維 IPNETMASKGATEWAYHOSTNAMEDNS1DNS2DNS3動態地址:DHCP:Dynamic Host Configuration Protocol路由linux:網絡屬於內核RedHat5: /etc/modprobe.confaliasRedHat6: /e
HTML第一課——基礎知識普及【2】
成績 eqv apt awr .com UC S4B 搜索引擎 dib 關註公眾號:自動化測試實戰 img標簽 我們先看一下文檔結構: 這裏我們文件當前位置就是lesson.html,所以現在我們img屬性src給的值要進入imgs文件夾,所以我們可以用相
Linux防火墻基礎知識及應用;設置SNAT策略,局域網共享上網;DNAT策略,發布內部服務器
開啟 提供web服務 port 使用 配置 網頁 遵從 internet 個數 防火墻,通俗地打個比方就相當於城池周圍的護城河,開放和管理服務的提供一般電腦系統的安全主要取決於:1)第三方監控殺毒軟件 如360殺毒軟件2)系統策略 防火墻規則設定3)文件的權限設定 Lin
嵌入式linux學習之基礎知識(一) linux檔案許可權
linux 檔案許可權相關 Linux使用者分為: 擁有者、組群(Group)、其他(Other) linux檔案的許可權總共有10位,如 -rwxrwxr-x ,分為4段。 第一段 佔1位 表示檔案的型別 - :表示普通檔案 d :表示資料夾、目錄 l :表示連結檔案,類似window
Linux驅動開發基礎知識
常用命令 lsmod: list module,將模組列表顯示),功能是打印出當前核心中已經安裝的模組列表 insmod: install module,安裝模組,功能是向當前核心中去安裝一個模組,用法是insmod xxx.ko modinfo: module information,模組資
13 Linux裝置驅動基礎知識
Linux裝置驅動基礎知識 驅動是硬體與使用者程序之間的通訊橋樑。 使用者程序是不可以直接訪問硬體的。 資料是驅動先接收到硬體反饋的資料處理後再移交給使用者程序的。 驅動不屬於任何一個使用者程序,可以給多個使用者程序呼叫。 驅動是常駐於記憶體裡,等待使用者程序呼叫。
13-linux核心管理基礎知識
1.man uname可以檢視kernel的系統資訊。 2.檢視由核心裝載的相關模組資訊使用lsmod。lsmod其顯示的是/proc/modules 下的內容。為了便於閱讀和理解,使用lsmod指令。modinfo可以顯示具體模組的詳細資訊。注意:lsmod只能檢視已安裝某塊,mo
嵌入式linux學習之基礎知識(一)
1)linux檔案的許可權 Linux使用者分為: 擁有者、組群(Group)、其他(Other) linux檔案的許可權總共有10位,如 -rwxrwxr-x ,分為4段,有4種含義。 ## 第一段 佔1位 表示檔案的型別 - :表示檔案 d :
最全 Linux 磁碟管理基礎知識全彙總
一、儲存裝置的掛載和解除安裝 儲存裝置的掛載和解除安裝常用操作命令:fdisk -l、df、du、mount、umount。 fdisk -l 命令 1.作用 檢視所有硬碟的分割槽資訊,包括沒有掛上的分割槽和USB裝置,掛載時需要用這條命令來檢視分割槽或USB裝置的名稱,比如掛載U盤時
Linux學習之基礎知識——網路管理的基本命令
概述 隨著網際網路和物聯網的不斷髮展,網路已經成為人們生活中必不可少的配置。而在Linux中,網路管理也是必不可少的技能之一,沒有網路,系統所提供的各項服務就無從施展。本篇重點從ifconfig、route、netstat、三個命令,介紹Linux中的網路配置。最後再實驗用
unix/linux檔案系統基礎知識
1、linux檔案系統分配策略: 塊分配( block allocation ) 和 擴充套件分配 ( extent allocation ) 塊分配:磁碟上的檔案塊根據需要分配給檔案,避免了儲存空間的浪費。但當檔案擴充時,會造成檔案中檔案塊的不連續,從而導致過多的磁
Android Multimedia框架總結(十七)音訊開發基礎知識
近年來,唱吧,全民K歌,QQ音樂,等成為音頻軟體的主流力量,音訊開發一直是多媒體開發中不可或缺的部分,如為什麼這個聲音這麼不清楚,為什麼耳機裡有電流聲,為什麼錄音時,有時會碰到奇怪的回聲,先看下今天的A
Vue.js 執行環境搭建詳解(基於windows的手把手安裝教學)及vue、node基礎知識普及
Vue.js 是一套構建使用者介面的漸進式框架。他自身不是一個全能框架——只聚焦於檢視層。因此它非常容易學習,非常容易與其它庫或已有專案整合。在與相關工具和支援庫一起使用時,Vue.js 也能完美地驅動複雜的單頁應用。 在配置環境之前呢,有些基礎的東西還是要和大家普及一
HCE基礎知識普及
NFC技術發展 NFC(Near Field Communication)是“近場通訊”的簡稱,採用短距離RF(射頻)通訊技術。NFC 工作頻率為13.56Hz,有效範圍為500px 以內,其傳輸速度有106 Kbit/秒、212 Kbit/秒或者424 Kbit/秒三
Linux作業系統的基礎知識
一、虛擬機器管理 虛擬機器管理常規操作如下: [[email protected] Desktop]$ rht-vmctl start desktop ##開啟虛擬機器 [[email protected] Deskt