OSS--跨平臺的音頻接口簡介

 OSS--跨平臺的音頻接口簡介
  作者:網絡收集   來源:linux.chinaunix.net   更新時間:2007-5-23 20:16:00   【大 中 小】  評論:0 條

    OSS(Open Sound System)是 unix 平臺上一個統一的音頻接口, 即只要音頻處理應用程序按照OSS的API來編寫,那麼在移植到另外一個平臺時,只需要重新編譯即可。

OSS (Open Sound System)是unix平臺上一個統一的音頻接口。以前,每個Unix廠商都會提供一個自己專有的API,用來處理音頻。這就意味着爲一種Unix平臺 編寫的音頻處理應用程序,在移植到另外一種Unix平臺上時,必須要重寫。不僅如此,在一種平臺上具備的功能,可能在另外一個平臺上無法實現。但是, OSS出現以後情況就大不一樣了,只要音頻處理應用程序按照OSS的API來編寫,那麼在移植到另外一個平臺時,只需要重新編譯即可。因此,OSS提供了 源代碼級的可移植性。

同時,很多的Unix工作站中,只能提供錄音與放音的功能。有了OSS後,給這些工作站帶來了 MIDI功能,加上音頻流、語音識別/生成、計算機電話(CT)、JAVA以及其它的多媒體技術,在Unix工作站中,同樣可以享受到同Windows、 Macintosh環境一樣的音頻世界。另外,OSS還提供了與視頻和動畫播放同步的音頻能力,這對在Unix中實現動畫、遊戲提供了幫助。

本文首先解釋在音頻編程時經常遇到的名詞、設備文件的含義,然後分別在錄音、播放、Mixer方面對OSS接口的使用方法進行介紹。由於OSS API十分豐富,因此在本文中只介紹那些最爲常用的接口。對於OSS API的一個完整描述,可以參考[1]。

一、基礎知識

數字音頻設備(有時也稱codec,PCM,DSP,ADC/DAC設備):播放或錄製數字化的聲音。它的指標主要有:採樣速率(電話爲8K,DVD爲96K)、channel數目(單聲道,立體聲)、採樣分辨率(8-bit,16-bit)。

mixer(混頻器):用來控制多個輸入、輸出的音量,也控制輸入(microphone,line-in,CD)之間的切換。

synthesizer(合成器):通過一些預先定義好的波形來合成聲音,有時用在遊戲中聲音效果的產生。

MIDI 接口:MIDI接口是爲了連接舞臺上的synthesizer、鍵盤、道具、燈光控制器的一種串行接口。

在Unix系統中,所有的設備都被統一成文件,通過對文件的訪問方式(首先open,然後read/write,同時可以使用ioctl讀取/設置參數,最後close)來訪問設備。在OSS中,主要有以下的幾種設備文件:

    * /dev/mixer:訪問聲卡中內置的mixer,調整音量大小,選擇音源。
    * /dev/sndstat:測試聲卡,執行cat /dev/sndstat會顯示聲卡驅動的信息。
    * /dev/dsp 、/dev/dspW、/dev/audio:讀這個設備就相當於錄音,寫這個設備就相當於放音。/dev/dsp與/dev/audio之間的區別在於 採樣的編碼不同,/dev/audio使用μ律編碼,/dev/dsp使用8-bit(無符號)線性編碼,/dev/dspW使用16-bit(有符號) 線形編碼。/dev/audio主要是爲了與SunOS兼容,所以儘量不要使用。
    * l /dev/sequencer:訪問聲卡內置的,或者連接在MIDI接口的synthesizer。

這些設備文件的設備編號見[1]。

二、音頻編程

OSS爲音頻編程提供三種設備,分別是/dev/dsp,/dev/dspW和/dev/audio,前面已經提到了它們之間的區別。

用戶可以直接使用Unix的命令來放音和錄音,命令cat /dev/dsp >xyz可用來錄音,錄音的結果放在xyz文件中;命令cat xyz >/dev/dsp播放聲音文件xyz。

如果通過編程的方式來使用這些設備,那麼Unix平臺通過文件系統提供了統一的訪問接口。程序員可以通過文件的操作函數直接控制這些設備,這些操作函數包 括:open、close、read、write、ioctl等。下面我們就分別討論打開音頻設備、放音、錄音和參數調整。

1. 打開音頻設備


1) 頭文件定義

/** Standard includes*/#include <ioctl.h>#include <unistd.h>#include <fcntl.h>#include <sys/soundcard.h>/** Mandatory variables.*/#define BUF_SIZE 4096int audio_fd;unsigned char audio_buffer[BUF_SIZE];



2) 打開設備

if ((audio_fd = open(DEVICE_NAME, open_mode, 0)) == -1) {/* Open of device failed */perror(DEVICE_NAME);exit(1);}


open_mode有三種選擇:O_RDONLY,O_WRONLY和O_RDWR,分別表示只讀、只寫和讀寫。OSS建議儘量使用只讀或只寫,只有在全雙工的情況下(即錄音和放音同時)才使用讀寫模式。

2. 錄音

int len;if ((len = read(audio_fd, audio_buffer, count)) == -1) {perror("audio read");exit(1);}


count 爲錄音數據的字節個數(建議爲2的指數),但不能超過audio_buffer的大小。從讀字節的個數可以精確的測量時間,例如8kHZ 16-bit stereo的速率爲8000*2*2=32000bytes/second,這是知道何時停止錄音的唯一方法。

3. 放音

放音實際上和錄音很類似,只不過把read改成write即可,相應的audio_buffer中爲音頻數據,count爲數據的長度。

注意,用戶始終要讀/寫一個完整的採樣。例如一個16-bit的立體聲模式下,每個採樣有4個字節,所以應用程序每次必須讀/寫4的倍數個字節。

另外,由於OSS是一個跨平臺的音頻接口,所以用戶在編程的時候,要考慮到可移植性的問題,其中一個重要的方面是讀/寫時的字節順序。

4. 設置參數

    * 設置採樣格式

      int format;format = AFMT_S16_LE;if (ioctl(audio_fd, SNDCTL_DSP_SETFMT, &format) == -1) {/* fatal error */perror("SNDCTL_DSP_SETFMT");exit(1);}if (format != AFMT_S16_LE) {/* 本設備不支持選擇的採樣格式. */}在設置採樣格式之前,可以先測試設備能夠支持那些採樣格式,方法如下:int mask;if (ioctl(audio_fd, SNDCTL_DSP_GETFMTS, &mask) == -1) {/* Handle fatal error ... */}if (mask & AFMT_MPEG) {/* 本設備支持MPEG採樣格式 ... */}


    * 設置通道數目

      int channels = 2; /* 1=mono, 2=stereo */if (ioctl(audio_fd, SNDCTL_DSP_CHANNELS, &channels) == -1) {/* Fatal error */perror("SNDCTL_DSP_CHANNELS");exit(1);}if (channels != 2){/* 本設備不支持立體聲模式 ... */}


    * 設置採樣速率

      int speed = 11025;if (ioctl(audio_fd, SNDCTL_DSP_SPEED, &speed)==-1) {/* Fatal error */perror("SNDCTL_DSP_SPEED");exit(Error code);}if ( /* 返回的速率(即硬件支持的速率)與需要的速率差別很大... */ ) {/* 本設備不支持需要的速率... */}


音頻設備通過分頻的方法產生需要的採樣時鐘,因此不可能產生所有的頻率。驅動程序會計算出最接近要求的頻率來,用戶程序要檢查返回的速率值,如果誤差較小,可以忽略,但誤差不能太大。

三、Mixer編程

對Mixer 的控制,包括調節音量(volume)、選擇錄音音源(microphone,line-in)、查詢mixer的功能和狀態,主要是通過Mixer設備 /dev/mixer的ioctl接口。相應的,ioctl接口提供的功能也分爲三類:調節音量、查詢mixer的能力、選擇mixer的錄音通道。下面 就分別介紹使用的方法:

下面的mixer_fd是對mixer設備執行open操作返回的文件描述符。

    *

      調節音量

      應用程序通過ioctl的SOUND_MIXER_READ和SOUND_MIXER_WIRTE功能號來讀取/設置音量。在OSS中,音量的大小範圍在0-100之間。使用方法如下:

      int vol;if (ioctl(mixer_fd, SOUND_MIXER_READ(SOUND_MIXER_MIC), &vol) == -1) {/* 訪問了沒有定義的mixer通道... */


      SOUND_MIXER_MIC 是通道參數,表示讀microphone通道的音量,結果放置在vol中。如果通道是立體聲,那麼vol的最低有效字節爲左聲道的音量值,接着的字節爲右 聲道的音量值,另外的兩個字節不用。如果通道是單聲道,vol中左聲道與右聲道具有相同的值。
    *

      查詢mixer的能力

      int mask;if (ioctl(mixer_fd, SOUND_MIXER_READ_xxxx, &mask) == -1) {/* Mixer 的沒有此能力... */}


      SOUND_MIXER_READ_xxxx 中的xxxx代表具體要查詢的內容,比如檢查可用的mixer通道用SOUND_MIXER_READ_DEVMASK;檢查可用的錄音設備,用 SOUND_MIXER_READ_RECMASK;檢查單聲道/立體聲,用SOUND_MIXER_READ_STEREODEVS;檢查mixer的 一般能力,用SOUND_MIXER_READ_CAPS等等。所有通道的查詢的結果都放在mask中,所以要區分出特定通道的狀況,使用 mask& (1 << channel_no)。
    *

      選擇mixer的錄音通道

      首先可以通過SOUND_MIXER_READ_RECMASK檢查可用的錄音通道,然後通過SOUND_MIXER_WRITE_RECSRC選擇錄音通道。可以隨時通過SOUND_MIXER_READ_RECSRC查詢當前聲卡中已經被選擇的錄音通道。

      OSS建議把mixer的用戶控制功能單獨出來形成一個通用的程序。但前提是,在使用mixer之前,首先通過API的查詢功能檢查聲卡的能力。在linux中,就有一個專門的mixer程序--aumix。

四、結束語

前面討論的是OSS中一些最基本的內容,實際上OSS中還有很多高級的特性,比如在音頻編程時十分重要的實時性問題,畫面與聲音的同步問題,這裏都沒有介紹。如果讀者對這些特性感興趣的話,可以進一步參考[1]。另外,在[2]中,還可以下載使用OSS接口的樣例程序。

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