7.2. 设置声卡

在开始配置之前,请确定声卡的型号以及使用的芯片。FreeBSD 支持各种各样的声卡。检查硬件说明中支持的音频设备列表,看是否支持该卡以及它所使用的 FreeBSD 驱动。

为了使用声音设备,必须加载其设备驱动程序。最简单的方法是用 kldload(8) 加载声卡的内核模块。这个例子加载的是基于 Intel 规范的内置音频芯片组的驱动:

  1. # kldload snd_hda

要在启动时自动加载这个驱动程序,请将该驱动程序添加到 /boot/loader.conf 中。这个驱动程序的行是:

  1. snd_hda_load="YES"

其他可用的声音模块在 /boot/defaults/loader.conf 中列出。当不确定要使用哪个驱动时,请加载 snd_driver 模块。

  1. # kldload snd_driver

这是一个元驱动,可以加载所有最常见的声音驱动,可以用来加速搜索正确的驱动。也可以通过在 /boot/loader.conf 中加入 metadriver 来加载所有的声卡驱动。

要确定加载 snd_driver metadriver 后声卡选择了哪个驱动程序,请输入 cat /dev/sndstat

7.2.1. 配置一个支持声音的自定义内核

这一节是为那些喜欢在自定义内核中静态编译支持声卡的用户准备的。关于重新编译内核的更多信息,请参考[配置FreeBSD内核]。

当使用自定义内核来提供声音支持时,要确保音频框架驱动存在于自定义内核的配置文件中:

  1. device sound

接下来,添加对声卡的支持。继续上一节中基于Intel规范的内置音频芯片组的例子,在自定义内核配置文件中使用以下一行:

  1. device snd_hda

请务必阅读驱动程式的手册页,了解驱动程式要使用的设备名称。

非 PnP ISA 声卡可能需要把声卡的 IRQ 和 I/O ports 设置加入到 /boot/device.hints 。在启动过程中,loader(8) 会读取这个文件,并把设定传给核心。例如,一个老的 Creative SoundBlaster® 16 ISA 非 PnP 卡将使用 snd_sbc(4) 驱动程序和 snd_sb16 一起使用。对于这种卡,必须在内核配置文件中加入以下几行:

  1. device snd_sbc
  2. device snd_sb16

如果卡使用 0x220 I/O ports 和 IRQ 5 ,以下这些行也必须被添加到 /boot/device.hints

  1. hint.sbc.0.at="isa"
  2. hint.sbc.0.port="0x220"
  3. hint.sbc.0.irq="5"
  4. hint.sbc.0.drq="1"
  5. hint.sbc.0.flags="0x15"

/boot/device.hints 中使用的语法在 sound(4) 和声卡驱动程式的手册页中有描述。

上面显示的设定是默认值。在某些情况下,IRQ 或其他的设定可能需要改变,以符合卡的要求。请参考 snd_sbc(4) 了解更多关于此卡的信息。

7.2.2. 测试声音

加载所需的模块或重启到自定义内核后,应该可以侦测到声卡。要确认,请运行 dmesg | grep pcm 。这个例子是来自一个内置 Conexant CX20590 芯片组的系统:

  1. pcm0: <NVIDIA (0x001c) (HDMI/DP 8ch)> at nid 5 on hdaa0
  2. pcm1: <NVIDIA (0x001c) (HDMI/DP 8ch)> at nid 6 on hdaa0
  3. pcm2: <Conexant CX20590 (Analog 2.0+HP/2.0)> at nid 31,25 and 35,27 on hdaa1

也可以用这个命令检查声卡的状态:

  1. # cat /dev/sndstat
  2. FreeBSD Audio Driver (newpcm: 64bit 2009061500/amd64)
  3. Installed devices:
  4. pcm0: <NVIDIA (0x001c) (HDMI/DP 8ch)> (play)
  5. pcm1: <NVIDIA (0x001c) (HDMI/DP 8ch)> (play)
  6. pcm2: <Conexant CX20590 (Analog 2.0+HP/2.0)> (play/rec) default

输出会因声卡的不同而不同。如果没有列出 pcm 设备,请仔细检查是否有正确的设备驱动程式被载入或编译到核心里。下一节列出一些常见的问题及其解决方法。

如果一切顺利,声卡现在应该可以在 FreeBSD 中工作。如果 CD 或 DVD 驱动器正确地连接到声卡上,可以在驱动器中插入一张音频 CD ,用 cdcontrol(1) 播放:

  1. % cdcontrol -f /dev/acd0 play 1

提示: 音频光盘有专门的编码,这意味着它们不应该用 mount(8) 来挂载。

各种应用程序,如 audio/workman ,提供一个更友好的界面。可以安装 audio/mpg123 ports 来收听 MP3 音频文件。

另一个快速测试卡的方法是向 /dev/dsp 送数据。

  1. % cat filename > /dev/dsp

其中文件名可以是任何类型的文件。这个命令应该产生一些噪音,确认声卡在工作。

注意: /dev/dsp 设备节点将根据需要自动创建。未使用时,它们不存在,也不会出现在 ls(1) 的输出中。

7.2.3. 设置蓝牙声音设备

连接到蓝牙设备不属于本章的范围。更多信息请参考“[蓝牙]”。

为了让蓝牙声汇与 FreeBSD 的声音系统一起工作,用户必须先安装 audio/virtual_oss

  1. # pkg install virtual_oss

audio/virtual_oss 需要将 cuse 加载到内核中:

  1. # kldload cuse

要在系统启动时加载 cuse ,运行这个命令:

  1. # echo 'cuse_load=yes' >> /boot/loader.conf

为了使用耳机作为 audio/virtual_oss 的声汇,用户需要在连接到蓝牙音频设备后创建一个虚拟设备:

  1. # virtual_oss -C 2 -c 2 -r 48000 -b 16 -s 768 -R /dev/null -P /dev/bluetooth/headphones -d dsp

注意: 本例中的 headphones 是来自 /etc/bluetooth/hosts 的一个主机名。可以用 BT_ADDR 来代替。

更多信息请参考 virtual_oss(8)

7.2.4. 声音的故障排除

常见错误信息中列出了一些常见的错误信息和它们的解决方案。

表1. 常见错误信息

错误 解决方案
sb_dspwr(XX) timed out I/O ports 的设置不正确。
bad irq XX IRQ 的设置不正确。确保设置的 IRQ 和声音的 IRQ 是一样的。
xxx: gus pcm not attached, out of memory 没有足够的可用内存来使用设备。
xxx: can’t open /dev/dsp! 输入 `fstat \ grep dsp` 来检查是否有其他的应用程序在打开设备。值得注意的麻烦制造者是 esound 和 KDE 的声音支持。

现代显卡通常都有自己的声音驱动,以便与 HDMI 一起使用。这个声音设备有时被列在声卡之前,意味着声卡不会被用作默认的播放设备。要检查是否是这种情况,可以运行 dmesg 并查找 pcm 。输出结果看起来像这样:

  1. ...
  2. hdac0: HDA Driver Revision: 20100226_0142
  3. hdac1: HDA Driver Revision: 20100226_0142
  4. hdac0: HDA Codec #0: NVidia (Unknown)
  5. hdac0: HDA Codec #1: NVidia (Unknown)
  6. hdac0: HDA Codec #2: NVidia (Unknown)
  7. hdac0: HDA Codec #3: NVidia (Unknown)
  8. pcm0: <HDA NVidia (Unknown) PCM #0 DisplayPort> at cad 0 nid 1 on hdac0
  9. pcm1: <HDA NVidia (Unknown) PCM #0 DisplayPort> at cad 1 nid 1 on hdac0
  10. pcm2: <HDA NVidia (Unknown) PCM #0 DisplayPort> at cad 2 nid 1 on hdac0
  11. pcm3: <HDA NVidia (Unknown) PCM #0 DisplayPort> at cad 3 nid 1 on hdac0
  12. hdac1: HDA Codec #2: Realtek ALC889
  13. pcm4: <HDA Realtek ALC889 PCM #0 Analog> at cad 2 nid 1 on hdac1
  14. pcm5: <HDA Realtek ALC889 PCM #1 Analog> at cad 2 nid 1 on hdac1
  15. pcm6: <HDA Realtek ALC889 PCM #2 Digital> at cad 2 nid 1 on hdac1
  16. pcm7: <HDA Realtek ALC889 PCM #3 Digital> at cad 2 nid 1 on hdac1
  17. ...

在这个例子中,显卡(NVidia)被列举在声卡(Realtek ALC889)之前。要使用声卡作为默认的播放设备,将 hw.snd.default_unit 改为应该用于播放的单元。

  1. # sysctl hw.snd.default_unit=n

其中 n 是要使用的声音设备的编号。在这个例子中,它应该是 4 。在 /etc/sysctl.conf 中加入以下一行,使这个改变永久化:

  1. hw.snd.default_unit=4

使用 audio/pulseaudio 的程序可能需要重新启动 audio/pulseaudio 守护进程,以使 hw.snd.default_unit 的变化生效。pacmd(1) 打开一个与 audio/pulseaudio 守护进程的命令行连接,另外,audio/pulseaudio 的设置也可以在运行中改变:

  1. # pacmd
  2. Welcome to PulseAudio 14.2! Use "help" for usage information.
  3. >>>

下面的命令将默认的 sink 改为前面例子中的卡号 4 :

  1. set-default-sink 4

提示: 不要使用 exit 命令来退出命令行界面。那会杀死 audio/Pulseaudio 守护进程。用 Ctrl+D 代替。

7.2.5. 利用多个声源

通常希望有多个声源能够同时播放。FreeBSD 使用“虚拟声道”,通过在内核中混合声音来复用声卡的播放。

三个 sysctl(8) 旋钮可以用来配置虚拟通道:

  1. # sysctl dev.pcm.0.play.vchans=4
  2. # sysctl dev.pcm.0.rec.vchans=4
  3. # sysctl hw.snd.maxautovchans=4

这个例子分配了 4 个虚拟通道,这是一个日常使用的实用数字。dev.pcm.0.play.vchans=4dev.pcm.0.rec.vchans=4 都是在设备连接后可配置的,代表 pcm0 用于播放和录制的虚拟通道的数量。由于 pcm 模块可以独立于硬件驱动加载,hw.snd.maxautovchans 表示当一个音频设备被连接时,将有多少个虚拟通道被赋予。更多信息请参考 pcm(4)

注意: 当设备在使用时,不能改变它的虚拟通道的数量。首先,关闭任何使用该设备的程序,如音乐播放器或声音守护程序。

正确的 pcm 设备将被自动分配给请求 /dev/dsp0 的程序,是透明的。

7.2.6. 设置混音器通道的默认值

不同混音器通道的默认值是在 pcm(4) 驱动程序的源代码中硬编码的。虽然声卡的混音器等级可以用 mixer(8) 或第三方应用程序和守护程序来改变,但这并不是一个永久的解决方案。要在驱动程式层面设定默认的混音器值,请在 /boot/device.hints 中定义适当的值,如本例所示:

  1. hint.pcm.0.vol="50"

这将在加载 pcm(4) 模块时将音量通道设置为 50 的默认值。