Linux 音频系统简析

前言:

我之所以钻研linux内核,只想是知道为什么我的系统还是没有声音……
linux音频系统架构问题由来已久……远远比你想像的复杂。如果你想理 清从读取音频文件到最终从你的扬声器中播放出来这一过程中所用到的技术之间 的关系的话,纸上的结构图足以像炸酱面一样混乱,而你根本找不到任何头绪。



  • Linux 音频系统简析

这是因为,音频系统本身就比其他架构更加复杂。OSI模型每一层都有自己的作用域和功能,每一层几乎不会有任何交集,所以你绝对不会碰到任何混乱情 况。但是,在linux音频系统上,却上演着这样的事情:没有明确的底层,各种音频技术各自为政。linux的音频系统架构有点像地壳构造,偶尔就地震一 下,要不就火山爆发一下,上层结构则要使劲遮掩发生的一切。

Open Sound Protocol(开放声音协议?),原本用来内核和声卡通信的(驱动),但是现在却成了alsa的一个胶合层(也不错,驱动声卡)。alsa兼顾底层和 硬件通信,为应用程序提供api,即负责混音,又负责硬件资源调用,多声道支持,环绕立体声输出等,甚至还要负责mp3解码(什么时候alsa负责mp3 解码了?我out了)。所以当众多发行版使用PulseAudio或者Gstreamer时候,错误就不断的发生了…


  • ALSA

输入:  PulseAudio, Jack, GStreamer, Xine, SDL, ESD

输出:  Hardware, OSS

首先,让我们从了解alsa(Advanced Linux Sound Architecture, 高级linux音频架构)开始。alsa直接和内核通信,并提供音频接口功能以供调用。但是,似乎alsa做了“比当好一个驱动程序”更多的事情:为系统 混音,为其他程序提供音频输出输出接口,为程序员提供api。他的目标好像要同Windows的ASIO或者OS X的CoreAudio一样,作为一个底层而稳定的后台程序运行。

本来alsa是设计成为oss的继任者的,值得庆幸的是,oss并没有真的死亡,凭借着alsa的兼容层重生了。所以可以简单的把alsa理解为声 卡的驱动层。实际驱动声卡的还是oss。声卡需要加载前缀为snd_的内核驱动模块,以在发声事件时驱动声卡发声。这也就是你需要linux声卡驱动的原 因,这也可能是你笔记本不出声音的原因…

幸运的是,大部分的发行版都已经自动配置好相关设备以及驱动模块,alsa负责提供api给应用程序,应用程序可以调用api发声。最初这个设计是 给oss用的~(当时大部分驱动都是如此),但是会引发声卡独占问题(即只有一个程序可以发声,其他程序只能进入队列等待)。

alsa需要一个软件部件监测声卡并管理声卡。当有两个或多个程序需要同时发声,alsa则进行软混音——如果你的声卡支持,则使用声卡硬混音。 alsa最多可以同时管理8路的声频硬件,还可以同时支持mid特性。当然这个特性要取决于你的计算机硬件,所以随着硬件的发展,这个特性不是显得那么重 要了。

alsa和其他驱动不同之处是它的可制定性。也正是因为高度的可制定性,导致linux音频系统架构越来越复杂。通过配置文件(/usr /share/alsa/alsa.conf)你可以管理一切——不论是混音方式,输出设备选 择,采样率,比特深度,还是实时音效。

alsa因其透明性、高效性和灵活性使之成为 了Linux音频系统的标准,也成为了几乎其他所有的音频架构和硬件通信的桥梁。



  • PulseAudio

输入:  GStreamer, Xine, ALSA

输出:  ALSA, Jack, ESD, OSS

如果你认为让alsa当后台就万无一失,那可就大错特错了。alsa虽然可以管理硬件,但是软件层却是其力所不及的地方。

这就是pulse,连接软件和硬件,远程计算机和本地计算机。它可以像alsa那样处理本地音频流,可以更灵活的处理远程计算机的音频流并在本地发 声。因为其灵活性,可用性,已经被众多linux发行版所采用(为什么arch还是alsa而不是pulse,囧)。

附加效果和alsa一样,高度的灵活性带来了高度的复杂性。但是似乎pulse的问题更为复杂,因为pulse是面向用户设计的,所以用户的错误配 置可能轻易的引起故障。所以就算是ubuntu,系统也尽量不会让用户更改其配置文件。

当你使用面板上的音量调节工具调节音量时,实际上你调节的是个虚拟设备——你调节pulse的虚拟设备,pulse调节alsa,alsa反馈给 pulse,pulse再反馈给虚拟设备……(多纠结啊)

好像pulse没有给linux音频系统带来什么增益?所以反对的声音不绝于耳(他们觉得和alsa相比就是重复造轮子?)。他没有使已有的操作起 来更简单(指alsa),也没有带来更好地音效(本子想要hifi效果?),但是它带来了几个非常重要的特性。首当其冲就是混音特性。

如果所有的程序都使用pulse,一切都将变得美好起来。开发者们不用再考虑系统复杂性,因为pulse是跨平台的。但正是因为如此,所以有这么多 其他的音频解决方案的主要原因之一。

不像alsa那样,pulse可以跨平台,运行在不同的操作系统上,包括POSIX标准的unix-like系统和微软的Windows。也就是说 呢,如果你写的程序使用pulse而不是alsa,那么移植起来会非常轻松。

事情其实并不简单,因为在linux上,pulse依赖于alsa,pulse把自身模拟成输出设备,供alsa调用。这点有点和Jack相似,处 在alsa和桌面之间,使用管道来传输数据。

不同于jack,它不主动添加或删除音频源,所以你可以对所有输出的音频程序音量等进行分控,哈哈,至少用这个特性你可以让那些吵人的网站全部静音 (firefox静音吗?flashblock就好了嘛~)


  • GStreamer

输入:  Phonon

输出:  ALSA, PulseAudio, Jack, ESD

算上gstreamer,linux的音频系统更加复杂了……因为gstreamer有点像pulse,没有什么新的特性。他是诞生在pulse之 前,而且拥有更多的开发者。看起来更象是gnome专属的一个多媒体框架。它是为数不多的可以安装并使用解码器的架构之一。他也是GTK开发者的首选,使 用gstreamer你甚至可以为Palm Pre进行程序开发。

gstreamer介于软件层和音频输入层之间,优先于pulseaudio。gstreamer与众不同之处在于他不只是个音频处理框架,通过安 装解码器,你还可以通过他来播放音频视频文件。

例如播放mp3,通常是下载相应的gstreamer解码器并安装。linux下唯一一个官方授权的商业版的Fluendo MP3解码器,是一个gstreamer插件,其实mpeg,h264等也都是如此。



  • Jack

输入:  PulseAudio, GStreamer, ALSA,

输出:  OSS, FFADO, ALSA

拥有pulse开放性等特点,通过管道传输音频流,最终使用输出设备输出音频。jack是个中间层,音频和程序的远程进程信号等同,这使得应用程序 可以通过组件建立。

最好的例子就是虚拟录音,应用程序在录音的同时可以对音频进行处理,并把处理好的数据通过一个虚拟设备“输出”到应用程序。实际录音情况中有可能使 通过网络或者电缆等,jack同样对输入的音频流进行处理。

jack是jack音频连接工具包的简称,由于其低延时,面向底层设计,所以不会发生因为需要处理过多数据而缓慢的情况。但是如 果需要使用jack,音频程序需要进行相应的编码,专为jack而设计。jack不像alsa,pulse那样简单,他需要运行在系统的最高优先级,而且 需要专门的设备输入。

在jack兼容的程序中,你自由的选择音频输入方式,例如你可以直接使用audacity录制当前vlc输出的音频。或者你可以通过 JackRack,建立包括ping延迟、多道混响和语言编码等多种实时效果的应用程序来发送它。

jack对于多媒体工作站是不二之选。Ardour就是使用jack作为输入输出组件。jack是如此之出色,甚至你在mac上也能看到他的身影。


  • FFADO

输入:  Jack

输出:  Audio hardware

许多专业设备都是通过“火线”连接到pc的。这样做有很多优点,火线传输速率快,而且可以为外设供电。很多台式机和笔记本都有火线插口,它是如此稳 定而成熟。在外面,你可以通过笔记本的火线插口录制音频,回到工作室再导入工作站中。

与usb不同,它是专用于音频输入输出的插口,拥有自己的通信协议,无须安装驱动程序。如此的复杂性,导致alsa不能胜任。所以它使用专属于自己 的胶合层。

起初,这是个叫FreeBOB的项目,这得益于许多火线音频设备都是基于相同的硬件协议。FFADO是FreeBOB的继任者,提供更多特性,并为 其他类型的火线插口设备提供支持。

2009年末,他发布了第二版,包含了对许多类似Alesis、Apogee、 ART、CME、Echo、Edirol、Focusrite、M-Audio、Mackie、Phonic和Terratec的单元的支持。因为不能确 保所有的硬件都能在这个平台上工作,所以购买前你需要进行测试(livecd测试ati显卡?lol),很多厂商也提供FFADO开发者设备以支持其改进 和驱动完善。

FFADO另一个特性是整合了dsp芯片的混音驱动,你可以通过图形界面设置输入输出,以及音效等。不同于alsa的软混音,你可以真正的对硬件进 行控制,做到真正的0延时,这对现场录音等需求大大有助。

和alsa等其他架构不同,jack仅仅对其支持的硬件进行处理,没有对alsa或者pulse提供接口,除非你用alsa替代jack,否则你无 法使用jack正常的进行音频播放。但是很多专业设备对jack支持良好,所以jack是你的最优选择。


  • Xine

输入:  Phonon

输出:  PulseAudio, ALSA, ESD

如果说linux音频发展像地球史,那xine就处在白垩纪。它就像个遗老,你仍能从很多播放器中发现它的身影,所以很多linux发行版仍然捆绑 着xine。

xine创立之初,设计分为前端和后端,前端用于和用户交互,后端处理多媒体。得益于封装的解码库,它可以播放包括AVI、Matroska和 Ogg以及它们 包含的数十种格式,例如AAC、Flack、MP3、Vorbis和WMA。

因为它依赖于库实现,所以xine被开发成一个多媒体框架,库的开发,使得xine在法律允许范围内对多媒体文件提供最好的支持。xine可以和 alsa,pulse通信,很多程序也可以调用xine,例如totme-xine。同时xine也是kde的Phonon默认后端,所以不论是 Amarok 还是 Kaffeine,都能看到他的踪迹。


  • Phonon

输入:  Qt 和 KDE 程序

输出:  GStreamer, Xine

PortAudio
跨平台是他最大的优势。开发者可以用Qt在Linux上编写一个音乐播放器,然后可以重编译给OS X和Windows使用,而无需要考虑音乐是如何播放的、使用的音频硬件的兼容性如何,或者最终操作系统会如何处理音频这些问题。Qt的Phonon自动 完成音频传送,例如自动传送到OS X的CoreAudio的API中,或者Windows的DirectSound中。
 
在Linux平台上(不同于早先的KDE版本),得益于其透明的编解码器的支持,Phonon传递音频给GStreamer。phonon正在 慢慢从Qt的框架中剥离。
 
这个架构受到最大的批评就是它过于简单,没有任何新的特性,不过看样子KDE 4中,还是会将它保留在架构中的。
 
  • 其他分支

当然还有其他很多小众的音频技术,例如ESD、SDL和 PortAudio。

ESD 是声音启发守护进程(Enlightenment Sound Daemon),它在曾经很长的一段时间里曾是Gnome桌面的默认声音服务。后来,Gnome开始使用libcanberra(它本身可以和ALSA、 GStreamer、OSS和PulseAudio通信),ESD在2009年4月被彻底放弃支持。在kde上esd也是杯具。因为大部分人都是使用 kde4,所以phonon替代了esd。慢慢的esd坠入历史长河…

SDL 依然欣欣向荣的发展着。因为已经是用他开发了上百款跨平台游戏, 所以SDL库的音频输出组件依然支持良好,具有大量新的特性,并且成熟而稳定。

PortAudio 也是一个跨平台音频库,它把 SGI、Unix和Beos加入到可能的终端混音器中。使用PortAudio的最知名的应用程序就是Audacity音频编辑器了,因为使用了 portaudio,使得它音频输出遇到了问题,jack支持也遇到了bug(audacity得不偿失啊)

OSS ,开放声音系统(Open Sound System)。它已经被从linux 2.4之后的版本中剥离,但是他仍然存在……主要原因是有太多的程序仍然在使用它。不像 alsa,它可以在除Linux的平台上运行。它甚至还有个FreeBSD版本……(老当益壮~)在1992年,它可以说是一个很好的系统,但是现在它几 乎被alsa替换。OSS定义了Linux下音频的工作方式,特别是音频设备要通过ioctl分支访问,例如通过/dev/dsp。ALSA提供了一个 OSS兼容层来让那些使用OSS的程序仍旧可以使用alsa标准。OSS项目曾经作过开源和专利开发的尝试,现在仍作在为4项前端技术(4 Front Technologies)的商业开发而努力,并在2009年11月发布了OSS 4.2的2002版。

released in November 2009.

你可能感兴趣的:(linux,音频架构,alsa,oss)