本文主要内容来自 Running PulseAudio on top of JACK

Linux 下的音频框架实在让人吐槽无力,OSS、eSound、aRts、ALSA、PulseAudio……这回又冒出来一个 JACK,实在是把人折磨死了。

不过,Linux 发展到今天,PulseAudio 已经足够好用了,作为普通用户,只要把 PulseAudio 安装上之后,使用默认配置就好,基本不会再遇到过去常见的各种软件不出声的问题了。JACK 是为专业音频处理设计的,对于普通日常使用而言,它并不好用。如果你不打算在 Linux 下做音频相关处理的话,坚持用 PulseAudio 就好。

1 将 PulseAudio 的输出转到 JACK

当 JACK 启动之后,它会占用声卡,导致 PulseAudio 无法发声。而系统里大部分程序都需要通过 PulseAudio 来发声,因此,运行 JACK 之后,绝大部分程序就无法出声了。为了解决这个问题,很多土豪会买两块声卡,让 PulseAudio 使用普通廉价的“日常声卡”,而把高质量的“专业声卡”留给 JACK。

对于像我这样的预算有限的普通用户,专门为 JACK 买一块声卡未免过于浪费。幸运的是,PulseAudio 提供了很多插件可以用其它音频框架作为它的输出,因此,我们通过插件让 JACK 作为 PulseAudio 的后端就好了。创建 ~/.pulse/default.pa,写入以下内容:

load-module module-native-protocol-unix
load-module module-jack-sink channels=2
load-module module-jack-source channels=2
load-module module-null-sink
load-module module-stream-restore
load-module module-rescue-streams
load-module module-always-sink
load-module module-suspend-on-idle
set-default-sink jack_out
set-default-source jack_in

另外,据说把以下内容写到 ~/.pulse/daemon.conf 可以获得更好的录音效果:

default-sample-format = float32le
default-sample-rate = 48000
realtime-scheduling = yes
exit-idle-time = -1

2 将 ALSA 的输出转到 PulseAudio

虽然今天的大部分程序都可以通过 PulseAudio 来发声了,但仍然有不少程序是依赖 ALSA 的。JACK 占用声卡之后,ALSA 也会无法工作,因此我们需要把 ALSA 的输出也导入到 JACK 中去。遗憾的是,ALSA 并没有能够直接访问 JACK 的插件,因此我们只能先将 ALSA 的输出送到 PulseAudio 中去,再让 PulseAudio 输出到 JACK。要实现这点,我们在 ~/.asoundrc 里写入以下内容:

pcm.pulse {
    type pulse
}
ctl.pulse {
    type pulse
}
pcm.!default {
    type pulse
}
ctl.!default {
    type pulse
}

3 系统登录时加载 JACK 插件

我们以上的配置仅仅是告诉 PulseAudio 把输出从到 JACK 插件去,但如果 JACK 插件没有加载的话,我们仍然听不到声音。为了让系统登录的时候自动加载 JACK 插件,我们需要在 ~/.kde/Autostart/ 文件夹下创建一个脚本,写入以下内容:

pactl load-module module-jack-sink channels=2
pactl load-module module-jack-source channels=2
pacmd set-default-sink jack_out

这样每次我们登入 KDE 的时候,JACK 插件就会自动加载好了。

4 让 KDE 使用 JACK 作为音频设备

做完以上设置后,我们把系统重启一下,登录完成后,我们有很大可能会发现整个系统仍然没有声音,那是因为 KDE 默认把“空输出”作为首选音频设备了。打开系统设置,找到“硬件”、“多媒体”、“音频和视频设置”,把“Jack sink (PulseAudio JACK Sink)”的优先级调到最高,就有声音了。如图:

kde_settings_jack

5 存在问题

需要再次重申的一点是,JACK 是专业音频框架,因此对于普通用户而言,它的确不好用。按照以上设置配置之后,系统音量控制无法正常工作,调整音量只能通过命令行下的 alsamixer -c0 进行。

另外,alsamixer 经常会出现插拔耳机之后记不住之前的音量设置的情况,经常需要手工重新调整音量设置。为了减少不必要的麻烦,可以将常用的音量设置写到脚本里。具体做法是,先在 alsamixer 里把每个频道的音量调到适合的程度,然后运行 amixer -c0 显示目前的音量设置,记住关心的每一个频道的名称,以及 Playback 之后的数值,在脚本里调用 amixer -c0 set 频道 数值 unmute 就可以了。

举个例子,在我现在的机器上,我运行 amixer -c0 得到的结果如下:

Simple mixer control 'Master',0
  Capabilities: pvolume pvolume-joined pswitch pswitch-joined
  Playback channels: Mono
  Limits: Playback 0 - 74
  Mono: Playback 74 [100%] [0.00dB] [on]
Simple mixer control 'Headphone',0
  Capabilities: pvolume pswitch
  Playback channels: Front Left - Front Right
  Limits: Playback 0 - 74
  Mono:
  Front Left: Playback 38 [51%] [-36.00dB] [on]
  Front Right: Playback 38 [51%] [-36.00dB] [on]
Simple mixer control 'Speaker',0
  Capabilities: pvolume pswitch
  Playback channels: Front Left - Front Right
  Limits: Playback 0 - 74
  Mono:
  Front Left: Playback 48 [65%] [-26.00dB] [on]
  Front Right: Playback 48 [65%] [-26.00dB] [on]
Simple mixer control 'PCM',0
  Capabilities: pvolume
  Playback channels: Front Left - Front Right
  Limits: Playback 0 - 255
  Mono:
  Front Left: Playback 255 [100%] [0.00dB]
  Front Right: Playback 255 [100%] [0.00dB]
Simple mixer control 'Mic Boost',0
  Capabilities: volume
  Playback channels: Front Left - Front Right
  Capture channels: Front Left - Front Right
  Limits: 0 - 3
  Front Left: 0 [0%] [0.00dB]
  Front Right: 0 [0%] [0.00dB]
Simple mixer control 'IEC958',0
  Capabilities: pswitch pswitch-joined
  Playback channels: Mono
  Mono: Playback [off]
Simple mixer control 'IEC958',1
  Capabilities: pswitch pswitch-joined
  Playback channels: Mono
  Mono: Playback [on]
Simple mixer control 'IEC958',2
  Capabilities: pswitch pswitch-joined
  Playback channels: Mono
  Mono: Playback [on]
Simple mixer control 'Beep',0
  Capabilities: pvolume pvolume-joined pswitch pswitch-joined
  Playback channels: Mono
  Limits: Playback 0 - 7
  Mono: Playback 3 [43%] [-16.00dB] [on]
Simple mixer control 'Capture',0
  Capabilities: cvolume cswitch
  Capture channels: Front Left - Front Right
  Limits: Capture 0 - 80
  Front Left: Capture 80 [100%] [6.00dB] [on]
  Front Right: Capture 80 [100%] [6.00dB] [on]
Simple mixer control 'Auto-Mute Mode',0
  Capabilities: enum
  Items: 'Disabled' 'Enabled'
  Item0: 'Disabled'
Simple mixer control 'Internal Mic Boost',0
  Capabilities: volume
  Playback channels: Front Left - Front Right
  Capture channels: Front Left - Front Right
  Limits: 0 - 3
  Front Left: 0 [0%] [0.00dB]
  Front Right: 0 [0%] [0.00dB]

我关心的频道有 Master、Headphone、Speaker 和 PCM,因此我根据上面查到的数值写出的脚本如下:

amixer -c 0 set 'Master' 74 unmute
amixer -c 0 set 'Headphone' 38 unmute
amixer -c 0 set 'Speaker' 48 unmute
amixer -c 0 set 'PCM' 255 unmute