歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux綜合 >> Linux資訊 >> 更多Linux >> OSS--跨平台的音頻接口簡介

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

日期:2017/2/27 9:24:00   编辑:更多Linux
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 4096 int audio_fd; unsigned char audio_buffer[BUF_SIZE];

QQread.com 推出各大專業服務器評測 Linux服務器的安全性能 SUN服務器 HP服務器 DELL服務器 IBM服務器 聯想服務器 浪潮服務器 曙光服務器 同方服務器 華碩服務器 寶德服務器

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 ( /* 返回的速率(即硬件支持的速率)與需要的速率差別很大... */ ) { /* 本設備不支持需要的速率... */ }

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

QQread.com 推出各大專業服務器評測 Linux服務器的安全性能 SUN服務器 HP服務器 DELL服務器 IBM服務器 聯想服務器 浪潮服務器 曙光服務器 同方服務器 華碩服務器 寶德服務器

三、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接口的樣例程序。




Copyright © Linux教程網 All Rights Reserved