转自 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下的音频问题(转)的更多相关文章

  1. Linux下常见音频格式之间的转换方法

    Linux下常见音频格式之间的转换方法[转] 下面简单介绍下Linux环境常见音频格式之间的转换方法: MP3 相关工具: lameOGG 相关工具: vorbis-toolsAPE 相关工具: ma ...

  2. 嵌入式Linux下ALSA音频架构ALSA-lib移植与编译心得

    **************************************************************************************************** ...

  3. Linux下压缩音频文件

    安装工具 sudo apt-get install lame 具体用法可以查看帮助  lame --help 通过更改音频文件的帧数 可以让文件变小  但是音质也会随之下降 现在比较多的mp3文件是1 ...

  4. linux下mono播放PCM音频

         测试环境: Ubuntu 14 MonoDevelop CodeBlocks 1.建立一个共享库(shared library) 这里用到了linux下的音频播放库,alsa-lib. al ...

  5. linux下调整音量大小

    不得不说,在linux下整音频和视频真是不容易.在windows中自带了关于音频和视频的工具,在linux下要两眼一抹黑地使用命令进行操作. 主要还是在linux下没找到合适的gui的调整工具. 几番 ...

  6. 说下 winOS / IOS / android /Linux 视频、音频 编码解码问题

    最近有朋友遇到一个问题, ios 上传视频文件,想在本地压缩下,然后再上传到服务器. 问有没有什么 视频处理的库, 最近Khronos的webgl 支持HTML5 ,(原理 WebGL 是openGL ...

  7. Linux下从视频提取音频的方法

    Linux下可以利用mencoder将视频里的音频提取出来.方法如下: 1.首先安装mencoder.对于Ubuntu来说,软件仓库里就有mencoder,可直接输入如下命令安装 sudo apt-g ...

  8. Linux下音频编程-输出音频文件

    程序实现了在Linux下播放Ok.wav的功能.程序首先调用fstat函数获得文件相关信息(主要是文件大小信息).通过malloc函数分配指定的内存空间,并将online.wav读入内存:然后,打开声 ...

  9. 信步漫谈之Redis—Linux下环境搭建

    一.环境 Linux 系统:Suse11(SLES-11-SP3-DVD-x86_64-GM-DVD1)Redis 安装包:redis-4.0.11.tar.gz      下载地址:http://d ...

随机推荐

  1. Python学习 —— 阶段综合练习一

    Python 阶段综合练习一 综合之前的函数.数据结构.流程控制等,做以下实例练习:(建议先不要看代码,自己先试着写:代码仅供参考,有多种实现方法) 1. 定义 is_Even 函数,传一 int 参 ...

  2. C++ 函数参数中“ *&代表什么? ”

    typedef struct BitNode  {      char value;      BitNode *lchild,*rchild;    }BitNode,*BiTree; void C ...

  3. Linux 查看当前时间和修改系统时间

    一.查看和修改Linux的时区 1. 查看当前时区 命令: date -R 2. 修改设置Linux服务器时区 方法 A 命令 : tzselect 方法 B 仅限于RedHat Linux 和 Ce ...

  4. 数字证书相关技术 : Versign信任签章

    资料网址: 淘宝网站可信服务 http://www.ert7.com/case/eb/1391.html Versign信任签章 http://www.ert7.com/verisign/ssl/29 ...

  5. sh: 1: node: Permission denied

    ionic app 开发的时候,https://dashboard.ionicframework.com/welcome ionic start myApp tabs 报错了https://www.j ...

  6. [AngularJS] ng-change vs $scope.$watch

    <div class="form-group"> <label for="pwd">Password</label> < ...

  7. shareSDK(分享第三方库)的 使用

    首先,下载第三方库,可以去官网下载,官网的地址我忘记了,但下面有一个我之前下的和我写的例子,其实官方的例子也写我们只是告诉大家用时需要把哪些代码复制出来就可以用了. 1.导入如下框架和第三方库 新浪微 ...

  8. JAVA学习目录

    开发环境以及IDE准备相关: 1.JAVA环境搭建 2.初次使用IntelliJ IDEA 3.IntelliJ IDEA界面设置 4.IntelliJ IDEA快捷键介绍 SprintBoot系列: ...

  9. Android画布更新过程OnDraw调用过程

    onDraw是触发的外置接口,用户能够复写这种方法,这样当回调onDraw时,就能够绘制出用户须要的画面 这个接口方法相似onLayout的回调,利用layout(l,t,r,b)就能够触发. 而这里 ...

  10. eclipse debug 错误 之 processWorkerExit

    eclipe 在debug模式下,有时候老是跳转到 ThreadPoolExecutor 之 processWorkerExit方法,很是让人恼火,是 因为在 java.util.concurrent ...