日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 >

OSS音频编程概述(DSP部分)

發布時間:2023/12/20 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 OSS音频编程概述(DSP部分) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一、 音頻概念

音頻信號是一種連續變化的模擬信號,但計算機只能處理和記錄二進制的數字信號,由自然音源得到的音頻信號必須經過一定的變換,成為數字音頻信號之后,才能送到計算機中作進一步的處理。

對于OSS編程來說,需要掌握聲音數字化的兩個關鍵步驟:采樣和量化。采樣就是每隔一定時間就讀一次聲音信號的幅度,而量化則是將采樣得到的聲音信號幅度轉換為數字值,從本質上講,采樣是時間上的數字化,而量化則是幅度上的數字化。

下面是音頻編程時經常要使用到的技術指標:

1. 采樣頻率

采樣頻率是指將模擬聲音波形進行數字化時,每秒鐘抽取聲波幅度樣本的次數。正常人聽覺的頻率范圍大約在20Hz~20kHz之間,根據奈奎斯特采樣理論,為了保證聲音不失真,采樣頻率應該在40kHz左右。常用的音頻采樣頻率有8kHz、11.025kHz、22.05kHz、16kHz、37.8kHz、44.1kHz、48kHz等。

2. 量化位數

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

3. 聲道數

聲道數是反映音頻數字化質量的另一個重要因素,它有單聲道和雙聲道之分。雙聲道又稱為立體聲,在硬件中有兩條線路,音質和音色都要優于單聲道,但數字化后占據的存儲空間的大小要比單聲道多一倍。

二、 聲卡驅動(OSS)

目前Linux下常用的聲卡驅動程序主要有兩種:OSS和ALSA。

OSS(Open Sound System)部分代碼開源,其他部分由4Front Technologies公司以二進制的形式提供。

ALSA(Advanced Linux Sound Architecture)是完全開放源代碼的產品。因為OSS由商業公司提供,而ALSA由志愿者維護,所以OSS支持的聲卡類型更多。

1. OSS的安裝(Ubuntu環境)

當前OSS的版本是V4.2-build 2004

下載地址: http://www.4front-tech.com/download.cgi

根據Linux內核版本選擇安裝包。

P.S.:查看內核版本的命令為uname –r

ubuntu選擇DEB包。安裝命令dpkg -l oss-Linux_v4.2-2004_i686.deb。安裝完成后,會在/dev下找到/dev/dsp,/dev/mixer等設備文件。也可以用osstest命令來測試oss是否正常工作。

2. 設備文件說明
l /dev/sndstat

設備文件/dev/sndstat的作用是用于匯報聲卡當前的狀態。Linux下的cat命令可以方便的獲取聲卡的當前狀態。

l /dev/dsp

聲卡驅動程序提供的/dev/dsp是用于數字采樣(sampling)和數字錄音(recording)的設備文件,它對于Linux下的音頻編程來講非常重要:向該設備寫數據即意味著激活聲卡上的D/A轉換器進行放音,而向該設備讀數據則意味著激活聲卡上的A/D轉換器進行錄音。目前許多聲卡都提供有多個數字采樣設備,它們在Linux下可以通過/dev/dsp1等設備文件進行訪問。

無論是從聲卡讀取數據,或是向聲卡寫入數據,事實上都具有特定的格式(format),默認為8位無符號數據、單聲道、8KHz采樣率,如果默認值無法達到要求,可以通過ioctl系統調用來改變它們。通常說來,在應用程序中打開設備文件/dev/dsp之后,接下去就應該為其設置恰當的格式,然后才能從聲卡讀取或者寫入數據。

l /dev/mixer

在聲卡的硬件電路中,混音器(mixer)是一個很重要的組成部分,它的作用是將多個信號組合或者疊加在一起,對于不同的聲卡來說,其混音器的作用可能各不相同。運行在Linux內核中的聲卡驅動程序一般都會提供/dev/mixer這一設備文件,它是應用程序對混音器進行操作的軟件接口。

由于混音器的操作不符合典型的讀/寫操作模式,因此除了open和close兩個系統調用之外,大部分的操作都是通過ioctl系統調用來完成的。與/dev/dsp不同,/dev/mixer允許多個應用程序同時訪問,并且混音器的設置值會一直保持到對應的設備文件被關閉為止。

為了簡化應用程序的設計,Linux上的聲卡驅動程序大多都支持將混音器的ioctl操作直接應用到聲音設備上,也就是說如果已經打開了/dev/dsp,那么就不用再打開/dev/mixer來對混音器進行操作,而是可以直接用打開/dev/dsp時得到的文件標識符來設置混音器。

l /dev/sequencer

目前大多數聲卡驅動程序還會提供/dev/sequencer這一設備文件,用來對聲卡內建的波表合成器進行操作,或者對MIDI總線上的樂器進行控制,一般只用于計算機音樂軟件中。

三、 編程接口與框架(DSP)

無論是OSS還是ALSA,都是以內核驅動程序的形式運行在Linux內核空間中的,應用程序要想訪問聲卡這一硬件設備,必須借助于Linux內核所提供的系統調用(system call)。從程序員的角度來說,對聲卡的操作在很大程度上等同于對磁盤文件的操作:首先使用open系統調用建立起與硬件間的聯系,此時返回的文件描述符將作為隨后操作的標識;接著使用read系統調用從設備接收數據,或者使用write系統調用向設備寫入數據,而其它所有不符合讀/寫這一基本模式的操作都可以由ioctl系統調用來完成;最后,使用close系統調用告訴Linux內核不會再對該設備做進一步的處理。

1. 編程接口
l open系統調用

系統調用open可以獲得對聲卡的訪問權,同時還能為隨后的系統調用做好準備。

函數原型:

1: #include <fcntl.h> 2: #include <sys/types.h> 3: #include <sys/stat.h> 4: //嚴格說一般使用open系統調用不需要包含sys/types.h,sys/stat.h。 5: int open(const char *path, int oflags); 6: int open(const char *path, int oflags, mode_t mode);

參數path是將要被打開的設備文件的名稱,對于聲卡來講一般是/dev/dsp。參數oflags用來指明應該以什么方式打開設備文件,格式是

(O_RDONLY | O_WRONLY | ORDWR)[ | O_APPEND | O_TRUNC | O_CREAT| O_EXCL]

分別表示以只讀、只寫或者讀寫的方式打開設備文件,后面參數可選;使用O_CREAT標志時,需要用3個參數的open調用,這時用mode設置文件的權限。

如果open系統調用能夠成功完成,它將返回一個正整數作為文件標識符,在隨后的系統調用中需要用到該標識符。如果open系統調用失敗,它將返回-1,同時還會設置全局變量errno,指明是什么原因導致了錯誤的發生。

l read系統調用

系統調用read用來從聲卡讀取數據

函數原型:

1: #include <unistd.h> 2: size_t read(int fildes, void *buf, size_t nbytes);

參數fildes是設備文件的標識符,它是通過之前的open系統調用獲得的;參數buf是指向緩沖區的字符指針,它用來保存從聲卡獲得的數據;參數nbytes則用來限定從聲卡獲得的最大字節數。如果read系統調用成功完成,它將返回從聲卡實際讀取的字節數,通常情況會比nbytes的值要小一些;如果read系統調用失敗,它將返回-1,同時還會設置全局變量errno,來指明是什么原因導致了錯誤的發生。

l write系統調用

系統調用write用來向聲卡寫入數據

函數原型:

1: #include <unistd.h> 2: size_t write(int fildes, const void *buf, size_t nbytes);

系統調用write和系統調用read在很大程度是類似的,差別只在于write是向聲卡寫入數據,而read則是從聲卡讀入數據。參數fildes同樣是設備文件的標識符,它也是通過之前的open系統調用獲得的;參數buf是指向緩沖區的字符指針,它保存著即將向聲卡寫入的數據;參數nbytes則用來限定向聲卡寫入的最大字節數。

如果write系統調用成功完成,它將返回向聲卡實際寫入的字節數;如果read系統調用失敗,它將返回-1,同時還會設置全局變量errno,來指明是什么原因導致了錯誤的發生。無論是read還是write,一旦調用之后Linux內核就會阻塞當前應用程序,直到數據成功地從聲卡讀出或者寫入為止。

l ioctl系統調用

系統調用ioctl可以對聲卡進行控制,凡是對設備文件的操作不符合讀/寫基本模式的,都是通過ioctl來完成的,它可以影響設備的行為,或者返回設備的狀態。

函數原型:

1: #include <sys/ioctl.h> 2: int ioctl(int fildes, int request, ...);

參數fildes是設備文件的標識符,它是在設備打開時獲得的;如果設備比較復雜,那么對它的控制請求相應地也會有很多種,參數request的目的就是用來區分不同的控制請求;通常說來,在對設備進行控制時還需要有其它參數,這要根據不同的控制請求才能確定,并且可能是與硬件設備直接相關的。

l close系統調用

當應用程序使用完聲卡之后,需要用close系統調用將其關閉,以便及時釋放占用的硬件資源。

函數原型:

1: #include <unistd.h> 2: int close(int fildes);

參數fildes是設備文件的標識符,它是在設備打開時獲得的。一旦應用程序調用了close系統調用,Linux內核就會釋放與之相關的各種資源,因此建議在不需要的時候盡量及時關閉已經打開的設備。

2. DSP編程框架
l 打開設備

對聲卡進行編程時首先要做的是打開與之對應的硬件設備,這是借助于open系統調用來完成的,并且一般情況下使用的是/dev/dsp文件。采用何種模式對聲卡進行操作也必須在打開設備時指定,對于不支持全雙工的聲卡來說,應該使用只讀或者只寫的方式打開,只有那些支持全雙工的聲卡,才能以讀寫的方式打開,并且還要依賴于驅動程序的具體實現。Linux允許應用程序多次打開或者關閉與聲卡對應的設備文件,從而能夠很方便地在放音狀態和錄音狀態之間進行切換,建議在進行音頻編程時只要有可能就盡量使用只讀或者只寫的方式打開設備文件,因為這樣不僅能夠充分利用聲卡的硬件資源,而且還有利于驅動程序的優化。

范例:只寫方式(放音palyback)打開設備

1: int handle = open("/dev/dsp", O_WRONLY); 2: ? 3: if (handle == -1) { 4: ? 5: perror("open /dev/dsp"); 6: ? 7: return -1; 8: ? 9: }
l 設置聲道(channel)

根據硬件設備和驅動程序的具體情況,可以將其設置為1(單聲道,mono)或者2(立體聲,stereo)。

范例:設置聲道

1: ioctl_val = chn; 2: if ((ioctl(fd, SNDCTL_DSP_CHANNELS, &ioctl_val)) == -1) 3: { 4: fprintf(stderr, "Set Audio Channels %d failed:%s\n", chn, 5: strerror(errno)); 6: return (-1); 7: } 8: if (ioctl_val != chn) 9: { 10: fprintf(stderr, "do not support channel %d,supported %d\n", chn,ioctl_val); 11: return (-1); 12: }
l 設置采樣格式

范例:

1: ioctl_val = bits; 2: if (ioctl(fd, SNDCTL_DSP_SETFMT, &ioctl_val) == -1) 3: { 4: fprintf(stderr, "Set fmt to bit %d failed:%s\n", bits, 5: strerror(errno)); 6: return (-1); 7: } 8: if (ioctl_val != bits) 9: { 10: fprintf(stderr, "do not support bit %d, supported %d\n", bits, 11: ioctl_val); 12: return (-1); 13: } 14: ? l 設置采樣頻率

調用ioctl時將第二個參數的值設置為SNDCTL_DSP_SPEED,同時在第三個參數中指定采樣頻率的數值。對于大多數聲卡來說,其支持的采樣頻率范圍一般為5kHz到44.1kHz或者48kHz,但并不意味著該范圍內的所有頻率都會被硬件支持,在Linux下進行音頻編程時最常用到的幾種采樣頻率是11025Hz、16000Hz、22050Hz、32000Hz和44100Hz。

范例:

1: ioctl_val = hz; 2: if (ioctl(fd, SNDCTL_DSP_SPEED, &ioctl_val) == -1) 3: { 4: fprintf(stderr, "Set speed to %d failed:%s\n", hz, 5: strerror(errno)); 6: return (-1); 7: } 8: if (ioctl_val != hz) 9: { 10: fprintf(stderr, "do not support speed %d,supported is %d\n", hz,ioctl_val); 11: return (-1); 12: } 13: ? l 錄音、放音

對設備讀操作即為錄音,寫操作即為放音。

范例:

1: nRD = read(s_fd, buff, BUFF_SIZE);
l 關閉設備

范例:

1: close(dev_fd);

四、 參考資料

1. Linux音頻編程指南, http://www.ibm.com/developerworks/cn/linux/l-audio/, 肖文鵬 (xiaowp@263.net);

2. OSS--跨平臺的音頻接口簡介, http://www.ibm.com/developerworks/cn/linux/l-ossapi/index.html, 湯凱 (tangk73@hotmail.com);

3. OSS安裝幫助, http://www.opensound.com/release/oss-install.pdf, 4Front Technologies;

4. Linux下的OSS音頻接口編程一例, http://blog.chinaunix.net/space.php?uid=7897183&do=blog&cuid=189502, rockins。

轉載于:https://www.cnblogs.com/jasonwang/archive/2011/03/30/oss_program.html

總結

以上是生活随笔為你收集整理的OSS音频编程概述(DSP部分)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。