歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux基礎 >> 關於Linux >> Linux的聲音系統

Linux的聲音系統

日期:2017/3/3 16:44:03   编辑:關於Linux

從Linux控制台喚起你注意的簡單的“丁”聲,到DVD的環繞聲,今天音頻已成為桌面計算的重要部分。確實有許多計算機用戶不需要聲音,但是聲音能夠為許多計算機任務增色。正是如此,音頻硬件已經成為一個幾乎所有主板和操作系統,也包括大多數Linux發行版,的通用部件。

不幸的是,配置Linux的聲音是一項讓人頭疼的事。在Linux中,有3套音頻驅動,使用著兩種不同的API。在這些驅動之上,還有幾種支持庫,目的是讓程序員的日子好過一點,但對最終用戶增加了配置的復雜性。實際上,對於一個普通用戶,讓系統發聲會成為一項令人沮喪的經驗。假如某個發行版沒有正確地配置好聲音,最終用戶面對的將是尋找、安裝和調試各種模稜兩可、沒有完善文檔的設置選項。

作為對Linux聲音系統的調查,讓我們從對聲音架構的總體認識開始。了解多種音頻流如何混在一起同步發聲也正日益重要。在這些話題的基礎上,對於特定驅動的認識就顯得很必要。聲音設備文件以及它們的權限經常是發生問題的根源,所以我們也會談到這個話題。此外,支持聲音的庫文件既可以是祝福也可以是詛咒,所以了解它們也很有幫助。在文章的結尾,當掌握了前面的基礎知識,你可以測試和使用聲音工具,並且設置常見發聲程序的選項。

理想化地說,音頻應用程序應該是直接了當的:發出一個命令或點擊一個按鈕,就可以聽見預期中的聲音。在這個情形的背後,Linux采用了幾種層次的工具來發聲,如圖1所示。

聲音數據在某個應用程序和聲卡之間准確的傳輸路徑,取決於該程序以及系統的整體配置,會有極大的差異。由於這個原因,追蹤聲音的問題也就非常困難。到底問題是出在硬件損壞、驅動程序的編程錯誤、庫文件的錯誤配置、應用程序出錯還是這些問題之間的相互作用呢?

如圖1所示,聲音庫和應用程序都可以直接和聲音驅動程序打交道或者依賴於其他的庫。有些應用程序和庫提供了多種選擇:它們既可以直接使用驅動程序也可以通過其他的庫來做。雖然圖1還不很完備(還有數十個小的聲音支持庫),但已經涉及了許多最常用的工具和庫,包括:

聲音硬件 - 盡管在圖1中只顯示成一項,實際上有許多不同種類的聲音硬件。如果沒有支持你的硬件的Linux驅動程序,你可能該買個新的硬件。

OSS - 2.4.x版內核系列中,OSS的開源版本是標准的Linux音頻驅動。4Front Technologies (http://www.opensound.com)公司還提供商業版。對於軟件來說,標准的內核OSS驅動和商業版OSS驅動沒什麼不同。多數Linux庫和發聲工具都支持OSS。盡管2.6.x版本的內核中還包含OSS,但是它們已經正式被ALSA所取代。

ALSA - 高級Linux聲音架構(ALSA,http://www.alsa-project.org)是OSS的替代方案。ALSA既兼容OSS,又提供了新的音頻界面方法。ALSA作為2.6.x內核的標准配備,也能在編譯成用在以往的內核上的模塊。

ESOUND - EsounD是一個庫以及後台服務,目的是無論使用OSS還是ALSA,它都為Linux音頻系統提供一個統一的界面。EsounD還提供了一些底層驅動程序所沒有提供的額外特性,例如支持多音頻流同時發聲(這個庫有時也叫做esd)。

POLYPAUDIO - 這個庫是意圖取代EsounD的不速之客。

ARTS - aRts(http://www.arts-project.org)與KDE相聯系的聲音庫。它能用EsounD、ALSA或OSS作為輸出。你通過與之關聯的後台服務使用aRts來產生對網絡傳輸透明的聲音,對於使用網絡瘦終端來說會很方便。

SDL - SDL(http://www.libsdl.org)是一個游戲開發者常用的跨平台的多媒體庫,它經常用名為libsdl的包安裝在Linux系統中,它可以依賴於多種其它的庫或者直接和聲音驅動打交道。

聲音應用程序 - 最終你的興趣在於使用聲音應用程序,例如XMMS(http://www.xmms.org)。這些程序可能直接用到一種或多種的音頻驅動,可能依賴於某個庫,或者給你提供幾種選擇。

處理多音頻流

Linux聲音系統的一個煩人的方面在於處理多音頻流。傳統上,Linux聲音系統是單線程的:如果某個程序在發聲,別的程序就不能發聲了。在某些情況下,這樣會產生問題。

例如,假設你設置了讓email軟件在有新郵件到達時發聲。如果你正在聽一個OGG文件而有郵件來了,郵件程序將不能發出新郵件到達的提示聲。隨著越來越多的簡單程序具備了發聲功能,這種限制成為一個越來越嚴重的問題。

解決這個問題有兩個辦法:為音頻驅動添加多線程支持和為音頻庫添加多音頻支持。可以認為,為音頻驅動添加多線程支持是最好的辦法,因為直接使用音頻驅動的程序無須修改。如果你的所有程序都使用同樣的庫,用庫文件來處理這個問題則更快速,但是只要有一個程序是直接使用音頻驅動的,這個好處就非常受限制了。

今天,許多ALSA驅動支持多音頻流。然而,這種支持在一定程度上取決於音頻硬件。同時,ALSA的OSS模擬對多音頻流沒有支持──使用OSS的程序享受不到這種好處,除非它想和使用了ALSA的其它程序競爭。OSS也采用了一些多線程的支持(常被稱為多線程OSS)。EsounD、aRts和一些其它庫也支持多線程發聲。

從實用上說,你應該盡可能多地采用多線程的選擇。假如一個程序能讓你選擇使用多線程的庫還是直接使用不支持多線程的驅動,那麼在所有可能情況下應選擇用庫。假如你可以在ALSA和OSS之間選擇,而你的ALSA驅動支持多線程,則使用ALSA驅動。你可能無法設置每個程序都使用多線程的方案,但是你很可能能把大多數頻繁使用聲音的程序設置成多線程的。

啟動驅動程序

驅動程序代表著Linux聲音系統的核心。因此,編譯和安裝驅動是至關重要的。不幸的是,這個任務有時候看起來像是巫術。Linux的音頻驅動是出了名的難伺候。在驅動程序層面的出問題的原因包括選錯了驅動、不同種類驅動(ALSA和OSS)之間的相互干擾以及用了錯誤的驅動程序(通過錯誤的聲音設備文件,很快會談這個話題)。

首先你必須決定是采用ALSA驅動、內核OSS驅動還是商業版OSS驅動。為此,你應該在有關網站或使用內核配置工具查看你的硬件兼容性。假如你的硬件有多種驅動的支持,你得逐一測試以找出最好的那個。但是要小心 -- 如果你試圖同時直接把兩種驅動加載到內核,最多只能是其中之一能夠工作。要想逐個嘗試,你需要編譯兩個內核或者把驅動編譯成模塊,這樣就可以隨你的意願加載或卸載了。

假如你的系統已經有了基本的聲音,最好不要改變配置,除非真有這個必要(例如,你因為別的原因需要重新編譯內核)。

當挑選需編譯的驅動時,選擇“Device Drivers, Sound, Sound Card Support”這一選項。然後,在ALSA或OSS之間作出抉擇並設定選項。

通常情況下,把聲音驅動直接編譯進內核比把它們編譯成模塊要容易得多,但是編譯成模塊會更有靈活性,因為你可以隨意加載或卸載。編譯ALSA模塊時,要選擇OSS兼容的選項(對於mixer功能和PCM功能都要選),因為許多程序編程時是直接使用OSS設備的,如果你不包含兼容層,它們將不能工作。假如你想使用商業的OSS驅動,你必須在內核設定基本的OSS支持,但是不要選擇把你的聲卡驅動編譯進內核(最多只是把它編譯成模塊)。

一旦你重新編譯了內核並用新內核重新啟動之後,聲音可能正常也可能不正常工作,這取決於你設的選項是否准確。如果你把關鍵功能編譯成了模塊,你需要加載它們。你可以用常用的命令,例如modprobe做到這一點。然而有些驅動需要在加載時設置特定的參數,ALSA就常有這種情況。請在ALSA網站查看詳情,每種聲卡都有所不同。典型情況是,你必須把幾行alias命令加入到 /etc/modules.conf 文件中去。

聲音設備文件

許多Linux驅動允許程序通過讀寫設備文件來使用硬件,這些文件存在 /dev 目錄和子目錄裡。對於音頻設備也是如此。不使用庫文件的程序會直接使用設備文件,而使用了庫文件的程序通過庫文件間接地使用設備文件。

表1概括了對應OSS和ALSA的最重要的音頻文件。這些設備文件依據它們的用途分屬於幾個范疇。(多數文件名以0或C0D0結尾。當你有多個聲卡時,這些數字會變化,有些情形下會完全省略掉。)

表1: 重要的音頻設備文件

設備類型 OSS ALSA 數字取樣 /dev/dsp0 /dev/snd/pcmC0D0 Sun音頻兼容性 /dev/audio0 N/A 混音器 /dev/mixer0 /dev/snd/mixerC0D0 高層音序器(high-level sequencer) /dev/music0 N/A 低層音序器(low-level sequencer) /dev/midi0 N/A 聲音狀態 /dev/sndstat N/A 控制文件 N/A /dev/snd/controlC0

對於大多數功能來說,最重要的文件是處理數字音頻的輸入和輸出的數字取樣文件,以及使調音程序能夠控制音量的混音器文件。Sun音頻兼容性提供了與Sun工作站兼容的界面,對應於一些非常老的程序。音序器(sequencer)文件使你能播放MIDI文件,但不是所有的驅動都支持這個特性。狀態和控制文件給聲卡提供了信息和控制的界面。

早期版本的ALSA要求你運行一個叫snddevices的腳本來產生聲音設備文件。這些文件在後期版本的ALSA應該是自動生成的,或者應該在多數現行的Linux發行版中默認建立。

盡管如此,假如你找不到適當的聲音設備文件,你應該找找snddevices腳本並運行一下。

有個重要的細節是,打算使用聲音應用程序的用戶必須對設備文件有讀和寫的權限,至少對OSS風格的訪問有這種權限。多數Linux發行版用兩種途徑之一來處理這個問題:或者提供一個具有寫權限的組(例如audio或sound組),你可以把用戶添加進去;或者把設備文件的所有權改成當前登錄用戶。前者會在用戶遠程登錄並使用聲音應用程序時產生沖突,而後者會在系統有多個用戶登錄時出問題(例如,你特地用多個用戶名登錄)。

安裝庫文件

許多程序依賴聲音庫,所以首先你必須安裝這些庫文件。幸運的是,如果你知道需要哪些庫文件,這項任務是相當簡單的,只要找到並安裝適合你的發行版的軟件包就行了。

庫文件的部分問題在於,你不一定知道使用一個特定程序時的具體要求。有些程序在找不到所需的庫文件時,會把一些選項隱藏起來。另一些不提供先決條件的說明,特別是當你從tar.gz格式(tarball)安裝,或者是用其它繞過你的包管理系統的方法安裝時。

然而,當通過RPM或用Debian的包來安裝程序時,如果你試圖安裝的軟件依賴於一個你還沒有安裝的庫文件時,包管理工具會發出提示。在此情況下,你需要循著線索找到那個庫。(有些包管理工具,例如APT,會自動幫你做這件事)

值得稍微詳細地介紹一下Gentoo。由於它采用的是“全部自己編譯”的方式,Gentoo讓你在程序中明確包含或排除對特定音頻庫文件的支持──至少對於在編譯時支持這些選項的程序如此。/etc/make.profile/make.defaults 文件包含了在可能情況下應該用到的所有庫文件的清單,每個占一行。

假如你知道你不想用到某個庫,比方說SDL,除非絕對必要,你應該在上述文件裡面注釋掉sdl這一行。你也可以在每次運行emerge時個別改動,通過加入庫的名稱以提供支持,或者在庫名稱前面加個“-”(比方像這樣 -sdl)來忽略對這些庫的支持。然而,這些選項只會在當這些庫被列為軟件包的“可選”(optional)庫文件時才有效。

例如,如果軟件包必需SDL才能正常工作時,在emerge命令中指定 -sdl選項將不起作用。你應該小心這些問題,因為可能造成程序的選項出現或消失。在某些情況下,它們還會影響到程序的音頻質量。如果一個庫比起另一個來,能更好地在你的硬件和程序上工作,你的選擇就會影響到聲音輸出的質量。

為了得到這種控制權,在傳統的二進制Linux發行版上,你必須用源碼重新編譯軟件包,這麼做要麼干脆繞過包管理系統,要麼用你喜歡的編譯選項產生定制的軟件包。

有些庫提供了設置各種選項的配置工具。例如,aRts讓你選擇用ALSA、OSS還是EsounD(很快會更詳細介紹)。你可能要看看庫文件的文檔來了解它提供了哪些選項。

測試和使用聲音工具

所有的庫文件和驅動程序安裝之後,就可以著手測試聲音了。做這件事,最好從最簡單的工具入手 ── 即那些不依賴於驅動程序的。然後,再逐步向“上”測試用到不同的庫文件的其它工具。

play

play命令直接通過OSS驅動(或者ALSA對OSS的兼容層)播放聲音文件。例如,輸入 play test.wav 來播放 test.wav。除了用 cat 直接發送一個聲音文件到聲音設備文件(這將極大地扭曲聲音)之外,這是測試你的聲音系統的功能和可操作性的最簡單辦法了。如果你使用了ALSA但是沒能成功編譯或加載OSS兼容支持,play命令將不起作用。

aplay

aplay在ALSA中的作用等同於play,用法也完全一樣。如果你用ALSA,兩個工具都應該試一下。如果aplay能用而play不行,通常表明你沒能成功編譯或加載OSS兼容支持。

esdplay

這個命令與play,aplay非常類似,只是它通過EsounD播放文件。

這些程序都只播放相對簡單的文件,例如.wav文件。它們不能正確處理MP3、Ogg Vorbis或其它復雜的文件類型。

理想情況下,你能以普通用戶的身份使用這些程序。然而,如果你在OSS設備文件上的權限不正確,你可能只能以root身份播放聲音。果真如此,檢查一下你的設備文件的權限然後再試試。

這些程序都有對應的錄音程序:rec,arecord和esdrec。你應該能夠用這些命令來錄制一個聲音文件。取決於你的混音器設置,生成的文件可能完全是空白的,即使你已經給了聲卡一個適當的輸入。

談到混音器(mixer),這裡需要注意一下,特別當你使用ALSA的時候。按照默認設置,ALSA啟動時所有的輸出頻道都是靜音的。因此,你可能能播放一個聲音文件,但是卻什麼都聽不到(播放程序可能暫時“凍住”了,但過了一會兒當文件靜悄悄地播放完,又“解凍”了)。有很多種混音器程序,包括mixer,amixer,alsamixer,kmix以及gnome-volume-control。前三個是文本界面的,其余是圖形界面的。amixer和alsamixer僅使用ALSA接口,其它的使用OSS接口或者兩者都支持。圖2顯示了gnome音量調節程序。

你應該確保你所需的頻道解除了靜音並且音量調節滑塊設置在恰當的水平(你需要通過試驗才知道何謂“恰當”)。“Mater”和“PCM”選項對於放音至關重要。如果想播放音樂CD,你可能還需要設置CD選項。(編程入門網)

為了錄音,通常你必須對“Mic”(麥克風)或者“Line”選項解除靜音。許多聲卡提供了額外的選項,可能很重要,也可能無關緊要。例如,假如你只有傳統的2個喇叭,環繞聲的音量選項就不重要,然而如果你用了全套的環繞聲系統則另當別論。

當重新啟動計算機時,混音器的設置將被重置。為解決這個問題,你可以用一個能從文本文件中讀入音量設置的文本界面的混音器。在本地的啟動腳本中,如/etc/rc.d/rc.local,加入對這個程序的調用,或者從一個SysV風格的啟動腳本中設置調用。

對於OSS來說,mixer程序是個好選擇,但是你要從試驗中找出最好的選項。詳情請查看manpage。對於ALSA,一個捷徑是用alsactl。這個程序能把當前的混音器設置存到一個文件中或者從文件中讀出來。當你用自己喜歡的混音程序調節滿意之後,用root身份輸入 alsactl store 。這個命令將把混音設置儲存到 /etc/asound.state 中。此後,你就能在一個啟動腳本中調用 alsactl restore 來恢復設置(有些發行版的ALSA啟動腳本已經包括了這個功能)。

除了簡單的放音、錄音和混音程序之外,還有許多更為復雜的音頻工具。例如,xmms是播放Ogg Vorbis和MP3文件的常用程序,xine是播放MPEG流媒體的工具,當然,還有許多游戲也播放聲音。事實上,聲音已經用在許多你通常意識不到會放音的程序中。例如,大多數桌面環境,像KDE和GNOME,都能把聲音和特定事件聯系起來,比如說啟動一個程序或控制台鈴聲。

設置 KDE/aRts 選項

許多應用程序和庫提供了與聲音有關的選項。這些選項你讓你選擇聲音如何輸出(直接通過驅動程序還是通過庫),或者提供更精細的選項(例如時序選項)。如果你安裝了多個聲卡,你也許能選擇想用哪一個。盡管將所有應用程序的所有選項羅列出來是不可能的,一些例子能讓你建立起有哪些是能做的的概念。

我們來看看設置 KDE/aRts 選項和 XMMS 的選項。

KDE讓你通過控制中心來調節輸出選項(輸入kcontrol命令或在菜單裡選擇)。這些控制實際上是設置aRts──KDE的聲音庫。這些選項位於控制中心的“聲音和多媒體,聲音系統”部分,見圖3(有些發行版在名稱上可能稍有不同)。

“General”標簽讓你設置有關網絡可達性、CPU使用率已經自動掛起(auto-suspend)之類特性(當驅動程序不支持多線程,而且你也無法告訴aRts使用一個低層的多線程庫時,最好是啟用最後那個特性)。你也可以點擊“Test Sound”和“Test MIDI”來測試aRts的設置(後者不是在每種聲卡上都起作用)。

“Hardware”標簽設置低層的選項。要特別注意的是“Select the Audio Device”按鈕。你可以告訴aRts在幾種低層的驅動和庫中選擇哪一個。典型的選項包括auto-detect,ALSA,OSS,Threaded OSS和EsounD。在不同的系統上,列出來的內容會有所不同,取決於安裝的驅動程序和KDE編譯時的選項。

默認設置通常是auto-detect,而通常也是可以接受的。然而,如果KDE應用程序(或其它使用aRts的程序)的聲音質量有問題,或者KDE的聲音特性與其它程序發生干擾,你可以試驗其它選項。你也可以設置額外選項,例如取樣率和質量。再一次,默認選項通常是可接受的,但是出問題的時候你也調整。

設置 XMMS 選項

作為一個專門的多媒體應用程序,與多數程序相比,XMMS提供了更多的音頻選項。然而,這些選項並非完全是顯而易見的,在 XMMS 菜單條上按鼠標右鍵並選擇“Option,Preferences”,結果就是圖4顯示的 XMMS “Preferences”對話框。

XMMS 最重要的選項是“Output Plug-in”按鈕,使你你選擇輸出驅動。通常你能在ALSA、OSS和EsounD之間作選擇,然而准確的選項依發行版和安裝的輸出插件的不同而不同。

一旦你選擇了要用的輸出方式,你還能點擊“Configure”機型微調。它會帶來一個插件特定的對話框讓你來設置其它特性。例如,用 ALSA 插件,你能選擇要用的音頻設備、啟動或停止Mmap模式等等。

有時候,這些選項會對你聽到的聲音質量造成很大的影響,所以出現問題時,你應該嘗試不同的選項。

Copyright © Linux教程網 All Rights Reserved