首页 > 代码库 > 漫谈Linux下的音频问题(转)
漫谈Linux下的音频问题(转)
转自 http://www.kunli.info/2009/03/24/linux-sound-issue/
现今的互联网,比较Linux和Windows的战争贴基本都成月经贴了。一群群激进的用户不断轰轰烈烈攻击对方,但是很少有能拿出新鲜干货的,基本上双方理由我现在都能背得了。在攻击Linux的阵营中,一条很重要的理由就是:硬件驱动不完善。
今天要谈的声卡问题,就是属于“驱动”这类问题。我在我工作用笔记本,家用笔记本,工作用服务器两台,上面都装过Ubuntu,无一例外遇到声音的 问题。去ubuntu.org看看,抱怨声卡问题的呐喊不绝于耳,无论是菜鸟,中鸟还是老鸟。当然不光是ubuntu,debian系的,Redhat系 的(包括Fedora),据我所知都能找到类似的问题。我的博客之前也有关于声音问题的文章。到底是什么原因导致Linux这么难发声呢?
Ubuntu官方Forum上有一篇非常好的帖子谈了这一点。本文其实是该帖原意的中文表达。但这只是从理论的高度上来分析的,如果你是遇到问题了,通过搜索引擎来到了这里,请直接看本文“总结部分”,这部分的reference post基本上就就是Ubuntu 音频问题大全了。
现在让我们从下到上对这个问题来一次bottom-up的分析吧。
首先,Linux社区面对的最大也是最现实的现状,就是得到的支持太少了。从芯片的层次讲,每一个OEM商都有能力去配置线路的连接,以适应自己生产机器的需求,比如一个厂商可以在机器上搞两个麦克风接口,一个在前面板,一个在后面板;而另一个厂商则可能会反过来配置,诸如此类。商家们搞完个性化,弄好Windows驱动,就万事大吉开庆功会了,可怜我们的Linux社区不得不针对不同机器的不同配置进行处理,然后还要保证用户们能搞清楚自己的机器是什么样的配置情况。
从声卡本身的层次讲。目前,台式机最流行的也就是创新的声卡了。最让人沮丧的就是,创新的Linux驱动从来就没有做好过。创新自己也没有办法,干脆自己就放弃了这块的开发,于去年11月宣布公开发布Sound Blaster X-Fi和X-Fi Titanium系列的Linux 32/64-bit驱动源代码,说好听点,叫做众人拾材火焰高,说不好听点,就是爷不玩了,谁爱用谁开发去。当然也有一些支持比较好的,比如C-Media的一些板载,或者就是那种高端和专业的声卡了。
是不是觉得很沮丧?Linux的问题就在这里,如果你哪天发现x厂商发布一款超级无敌牛逼限量发行1000套的硬件,然后你想入手给周边众多狐朋狗友炫耀,然后很不幸你用的是Linux…….好吧,你必须祈祷在另外购买的999个人里面有至少2-3个Linux开发者,注意,不是所谓的高手。然后再把硬件晾在家里几个月,等待驱动的推出…….
为什么Linux的驱动就这么难开发呢?有人会说,驱动不就是一个翻译转换部件么,你声卡芯片不就是通过操作系统提供的底层服务和其他软件打交道的么,Linux源码都在那里了,这么多底层硬件驱动示例都在那里了,你怎么就开发不出来呢?
对,驱动的作用就是讲操作系统传递过来的命令和请求翻译并递交给声卡芯片,并将结果反馈。正因为这样,驱动就必须对硬件的细节非常了解。它必须知道,并能检测,那些厂商对芯片的固件或者配置电路做了什么手脚,因为OEM们从来就懒得去发布这种信息。否则,就算是同样的芯片,也无法保证能适应不同的cable搭配。这个难度有多大呢?举个例子,就算是在同样的电脑的同样的芯片组上,新的7.1环绕声卡芯片的麦克风输入的线路,也可能是和以前老的5.1的配置过的声卡芯片的speaker输出用的是相同的线路。
现在,你知道问题所在了吧?作为驱动编写者,他们可以让驱动去适应所能发现的所有的变化,但是,这就像一场猜谜游戏一样,没有尽头。所以,如果你拥有一款比较特殊的声卡芯片并受困于其Linux驱动,请不要责备编写驱动的人,他们已经春蚕到死丝方尽了。如今,最有名且活跃的Ubuntu/linux驱动编写团队要数ALSA和OSS了,对于他们所接受的这种极度困难的任务,我们所能作的,应该是对他们的感谢。
讲完驱动,来讲讲音频服务器吧。音频服务器就是位于驱动上面一层的东西,它负责给那些需要音频支持的应用提供内核服务,同时还调度这些服务,以及作为其他硬件和软件交互的接口抽象。总的来说,音频服务器就是用来连接应用程序到你的声卡,或者到网络,或者哪都不到,如果你配置错误的话。
刚才提到的ALSA和OSS团队,不仅仅提供驱动,同时还提供音频服务器的服务。对于ALSA来说,大多数提供的服务是单独运行的程序,比如ESD,Enlightened Sound Demon,这玩意允许多个应用程序共享音频服务。这些程序已经开发了好几年了,但是都是以一种比较混乱的方式去解决已经观察到的缺陷。而OSS呢,则是一个更老的项目,它是内核版本2.4.x时期的唯一认定音频系统,但之后一度被ALSA所替代,最后还是存活了下来。关于两者的比较,请参考这里,我就不赘言了。后来OSS整个被重写,被命名为OSS4,现在还在活跃中。
接下来要介绍的Pulseaudio则是一个比较新的,完全独立的音频服务器,只不过它利用的是ALSA的驱动,所以其目标就是替代ALSA的音频服务器,包括所有的辅助部分,比如ESD。Pulseaudio同时还致力于提供ALSA当初很难提供的功能,比如网络广播,同步刷新多个声卡,分别控制不同应用程序的音量,以及很多别的好玩的功能。也有小道消息指出,Pulseaudio正在试验看能否工作在OSS4.1基础上。
然后我们看看Jackd。很多人都把Jackd看作是音频服务器,这其实是不准确的,它不是音频服务器,它的本质是音频连接套件。它的设计目标就是围绕着提供某些应用所需要的服务来制定的。什么样的应用呢?是那些为音乐界专业大佬们服务的,这些应用的特殊之处在于,他们需要“实时”。比如说,它们可能是位于支持实时内核/CPU优先访问和底层驱动访问的操作系统,用于减少在一些对时间狠敏感的活动中可能会出现的延迟或者中断,比如现场录制啊,表演啊之类的。Jackd支持所有以JACK API套件编写的应用程序连接在一起,并同时被键盘或者midi设备本地或远程操作。所以说,Jackd非常适用于音乐家。但正是由于Jackd提供了如此底层的控制,所以需要很仔细地去支配资源,并可能和同样希望支配这些资源的音频服务器相冲突。考虑到这点,无论是ALSA OSS还是Pulseaudio音频服务器,都提供了专门的模块负责和Jackd交互。
还有一个值得一提的玩意就是Phonon,这是一个新的音频服务器和应用API,专门用于KDE的,它可以兼容Pulseaudio以及ALSA驱动。具体的介绍请参加这篇文章。
讲完了音频服务器,接下来讲讲接口。和驱动不一样的是,音频服务器需要一个公用接口,用户才能和它们交互,并告知自己的需求。这个接口在哪里呢?就在菜单里面的System/Preferences/Sound里面,打开看看。在这里,你可以指定将系统的声音送往音频服务器,或者直接送往驱动。前者将导致音频服务器掌控一切,后者则会以驱动为主,服务器为辅。如果你选择autodetect,那第一个应用程序如何决定声音传输路径,之后的应用程序就会遵循这个路径。如果你选择音频服务器,那么服务器会帮你管理,你可以在其之上做出一些调整。像ALSA就可以调用ESD来做声音共享,Pulseaudio则会自己搞定这个。你还可以让一个音频服务器来调用另一个,比如让Pulseaudio作为ALSA的默认声卡,这样所有的ALSA相关程序都会被重定向到Pulseaudio,这个过程,应用程序都是不知道的。
对于ALSA来讲,它的接口包括了很多调音工具,最基本的就是在终端中调用的alsamixer,当然,你也可以用GUI版本的alsamixer。在调音工具中,你可以通过各种各样的滑块和开关来控制声卡,当然有什么样的滑块和开关取决于你声卡的类型了。当然还有我们更熟悉的音量控制器,在这里也可以调节很多的选项。ALSA另一个经常使用的接口就是asoundrc文件,你可以通过手工编辑它,也可以用asoundconf-gtk来调整选项。
对于Pulseaudio来说,它本身对于驱动并没有很深入的控制,所以Pulseaudio也是调用的ALSA的调音工具。然后,Pulseaudio可以控制主音量,声道的音量,应用程序的音量,等等。Pulseaudio的接口给用户提供了很详细的控制选项,在Pulseaudio音量控制,也就是pavucontrol中,你可以看到你所有的输入输出设备,并可以将其中任何一个设置成默认设备。你还可以在不影响应用程序操作的前提下控制任何程序的音量,以及它所使用的设备。在Pulse Audio Preferences (paprefs)中,你可以控制对你音频设备的网络访问,建立RTP服务器,甚至建立实际上几乎等同于实际硬件设备的虚拟设备。
正是由于这么多不同的音频格式,不同的音频服务器,为了保证音频仍然能正常工作,我们最后不得不被带进一个充斥着音频滤波器,插件,包装器(wrapper)等等部件的时代。为了能让大家理解这些东西是怎么工作的,举大名鼎鼎的Amarok作为例子吧。
当你准备使用Amarok播放mp3的时候,Amarok会先看看你指定的文件,然后对自己说,好,现在我需要一些帮助,让我来看看谁能帮助我……好,xine引擎,你小子有mp3插件,来把mp3文件转换成我能使用的东西,就是你了。Xine一看,哟,Amarok需要帮忙了,哪能见死不救呢,立马将mp3插件双手奉上。Amarok会再对xine说,来,能帮我把数据送到Pulseaudio音频服务器那里去么?Xine自然不敢怠慢,立马找到Pulseaudio,说,哥们,我这里有Amarok送过来的流数据,你能帮忙播放一下么?Pulseaudio说,没问题,拿过来吧。于是Amarok得到消息,开始处理文件,送到xine,xine将其转换为pcm,并将pcm流送到Pulseaudio,Pulseaudio将流数据送到alsa负责驱动的输出音频设备。如果这个设备是音箱或者耳机,pcm就会在alsa音量控制中被调整以让你能听到。所以最后整个流程是这样的
Amarok-xine-pulseaudio-alsa driver-sound card-speakers
只有xine能做这种后端处理的服务么?不是,另一个大名远扬的服务就叫Gstreamer,喜欢用Rhythmbox的朋友估计不会对其陌生。事实上Gstreamer和xine还能提供视频处理服务,只要有相应插件和滤波器支持就行了。这种方式对于程序开发者来说更加具有吸引力,原因就是他们只需要编写和Gstreamer或者xine交互的接口,其他细节一律不关心。Gstreamer和xine同时也提供可以更改的配置文件。
对于插件来说,程序开发者可以创建自己的插件,实际上,无论是gstreamer还是xine,还是alsa或者 oss 或者pulseaudio或者jack,都是很常见的程序插件。音频服务器也是包含了各种各样插件的,比如Pulseaudio就有很多被称为模块的插件。ALSA也有很多包装到libasound2和libasound2-plugins的插件。插件是一个很好的东西,用户应该去尽可能多地拥有他们,这样才会有更好的灵活性,以及更宽的选择。
总结:
基本上,这就是音频系统在系统中工作的基础知识。希望看到这里的朋友没有被搞昏头了。这篇文章只是给大家一个基础概念,并没有牵涉到很多的细节。关于具体很多问题是怎么产生的,怎么解决,可以参考一下一些资料
漫谈Linux下的音频问题(转)