音頻編程基礎

http://wenku.baidu.com/view/3897d27c1eb91a37f1115ce3.html?re=view
wenku.baidu.com/view/6a979c5f804d2b160b4ec0ba.html?re=view
採樣 ->量化->編碼
採樣就是每隔一定時間就讀一次聲音信號的幅度,而量化則是將採樣得到的聲音信號幅度轉換爲數字值,從本質上講,採樣是時間上的數字化,而量化則是幅度上的數字化。

基礎:

音頻採樣:自然界中音頻信號是一種連續變化的模擬信號,但計算機只能處理和記錄二進制的數字信號,由自然音源得到的音頻信號必須經過模數轉化器(A/D),轉換成數字音頻信號之後,才能送到計算機中作進一步的處理。

音頻播放:計算機中存儲的音頻信息實爲二進制數字信號,因此必須經過數模轉換器(D/A),轉換成模擬信號後才正常播放。

採樣頻率:

採樣頻率是指將模擬聲音波形進行數字化時,每秒鐘抽取聲波幅度樣本的次數。常用的音頻採樣頻率有8kHz、11.025kHz、22.05kHz、16kHz、37.8kHz、44.1kHz、48kHz等,如果採用更高的採樣頻率,還可以達到DVD的音質。

量化位數:

量化位數是指對模擬音頻信號的幅度進行數字化,它決定了模擬信號數字化以後的動態範圍,常用的有8位、12位和16位。量化位越高,信號的動態範圍越大,數字化後的音頻信號就越可能接近原始信號,但所需要的存儲空間也越大。

聲道數:

有單聲道和雙聲道之分。雙聲道又稱爲立體聲,在硬件中有兩條線路,音質和音色都要優於單聲道,但數字化後佔據的存儲空間的大小要比單聲道多一倍。

錄音和放音:

錄音:A/D模擬信號轉換成數字信號(讀數據)
放音:D/A數字信號轉換成模擬信號(寫數據)

聲卡驅動

出於對安全性方面的考慮,Linux下的應用程序無法直接對聲卡這類硬件設備進行操作,而是必須通過內核提供的驅動程序才能完成。在Linux上進行音頻編程的本質就是要藉助於驅動程序,來完成對聲卡的各種操作。
對硬件的控制涉及到寄存器中各個比特位的操作,通常這是與設備直接相關並且對時序的要求非常嚴格,如果這些工作都交由應用程序員來負責,那麼對聲卡的編程將變得異常複雜而困難起來,驅動程序的作用正是要屏蔽硬件的這些底層細節,從而簡化應用程序的編寫。目前Linux下常用的聲卡驅動程序主要有兩種:OSS和ALSA。

編程接口

如何對各種音頻設備進行操作是在Linux上進行音頻編程的關鍵,通過內核提供的一組系統調用,應用程序能夠訪問聲卡驅動程序提供的各種音頻設備接口,這是在Linux下進行音頻編程最簡單也是最直接的方法。

訪問音頻設備:

無論是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內核就會阻塞當前應用程序,直到數據成功地從聲卡讀出或者寫入爲止。

close系統調用

當應用程序使用完聲卡之後,需要用close系統調用將其關閉,以便及時釋放佔用的硬件資源,其函數原型如下所示:
int close(int fd);
參數fd是設備文件的標識符,它是在設備打開時獲得的。一旦應用程序調用了close系統調用,Linux內核就會釋放與之相關的各種資源,因此建議在不需要的時候儘量及時關閉已經打開的設備。

發佈了95 篇原創文章 · 獲贊 13 · 訪問量 5萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章