带有外部声音适配器的 Pulseaudio:解决声音损坏的问题

带有外部声音适配器的 Pulseaudio:解决声音损坏的问题

我在带有内置声卡的笔记本电脑上使用外部 USB 声音适配器。有一些问题:

  • 默认情况下,应用程序继续使用内部声卡。我可以通过以下方式手动解决此问题:打开pavucontrol:转到“输出设备”,找到适配器输出并单击“设置为后备”,有时在“播放”选项卡中找到已经播放的应用程序并更改其接收器。

  • 键盘音量按钮仍然在内部声卡上运行,而不是在外部适配器上运行。

  • 该适配器具有物理音量增大、减小和切换静音按钮。按下时,系统会执行预期的操作,但在内部声卡上执行,而不是在外部适配器上执行。还有一个麦克风静音按钮,未经测试。
  • 使用外部适配器设置音量pavucontrol可以工作,但如果设置低于 35%,则根本没有声音。由于音量很大,35%对于安静的声源来说还可以,对于大声的声源来说是不可接受的。我可以通过设置每个应用程序的音量限制(在pavucontrol窗口中单击)来手动解决此问题,但它很乏味,并且每当应用程序启动新流时都必须重做。

如何拥有:

  • (1) 应用程序默认播放该适配器
  • (2) 键盘音量按钮适用于所选声卡(此处为适配器)
  • (3) 物理适配器按钮适用于所选声卡(此处为适配器)
  • (4) 适配器的音量设置可以低于 35% 而不会直接进入静音状态

系统是运行 XFCE 4.10 的 Ubuntu 14.10。适配器为“ID 0d8c:000c C-Media Electronics, Inc. 音频适配器”

答案1

我有一个实验性的解决方法。

首先获取适配器接收器名称

第一个必须找出适配器的接收器名称。打开一个外壳。我们将bash通过切换到默认区域设置来假设并防止任何本地化问题:

export LC_ALL=C 

要获取接收器列表:

pacmd list-sinks | grep name:

您可以读取输出并将名称手动复制粘贴到命令行中:ADAPTER_SINK_NAME=name_in_your_setup

更自动的是,下面的行找到第一个非 pci 适配器的名称,这对我有用,并且在许多情况下都应该有效。

ADAPTER_SINK_NAME=$( pacmd list-sinks | sed -n 's/^.*name: <\([^>]*\.usb[^>]*\)>$/\1/p' | head -n 1 )
echo $ADAPTER_SINK_NAME

替代使用pactl(但一定要运行export上面的行,否则它不会在非默认区域设置中找到任何内容):

ADAPTER_SINK_NAME=$( pactl list sinks | sed -n 's/^.*Name: \(.*\.usb.*\)$/\1/p' | head -n 1 ) 
echo $ADAPTER_SINK_NAME

进行部分修复 (1) (2) (3)

现在这将提供问题的第 (1) (2) (3) 点:

pactl set-default-sink $ADAPTER_SINK_NAME

有趣的是,我首先使用pacmd set-default-sink ...(pacmd而不是pactl),它提供了 (2) 和 (3),但并不总是 (1)。

获得完整修复 (1) 至 (4)

它基于我可以使用 PulseAudio 同时在两个声卡上播放音乐吗?尽管原则是“同时在一张声卡上播放”。 ;-)

pacmd load-module module-combine sink_name=adapter-soft-volume slaves=$ADAPTER_SINK_NAME
pactl set-default-sink adapter-soft-volume

现在一切都按照问题中的要求进行。

清理。

如果多次运行上述命令,将会有多个组合接收器,并且将使用第一个,而不是最后一个。如果出于任何原因您想重新开始,请首先运行此命令来清理组合接收器:

pacmd unload-module module-combine

如果您想继续,请不要立即使用清理功能

奖励:将当前播放的流移动到适配器

上面的命令适用于新的流,而不是已经播放的流。这将调整所需的内容:

for SINK_ID in $(pactl list sink-inputs | sed -n 's/^Sink Input #\([0-9]*\)$/\1/p')
do
    echo Sink $SINK_ID
    pactl move-sink-input $SINK_ID $ADAPTER_SINK_NAME
    pactl move-sink-input $SINK_ID adapter-soft-volume
done

它将尝试移动所有接收器输入,包括会导致圆形路径的组合输入。幸运的是,pulseaudio 会做正确的事情并打印Failure: Invalid argument一次来表明这一点。

自动化事情

下面的脚本提供了 (1) 到 (4) 的好处。您可能想添加move-sink-input上面的内容。每当插入适配器时让它运行可能会很有趣。

#!/bin/bash

export LC_ALL=C

ADAPTER_SINK_NAME=$( pacmd list-sinks | sed -n 's/^.*name: <\([^>]*\.usb[^>]*\)>$/\1/p' | head -n 1 )

if [[ -z "${ADAPTER_SINK_NAME:-}" ]]
then
    ADAPTER_SINK_NAME=$( pactl list sinks | sed -n 's/^.*Name: \(.*\.usb.*\)$/\1/p' | head -n 1 ) 
fi

echo will plug on $ADAPTER_SINK_NAME

# partial fix, can be run anyway to provide partial benefit if later steps fail
pactl set-default-sink $ADAPTER_SINK_NAME

pacmd unload-module module-combine # not useful first, used to clean things up if run several times

pacmd load-module module-combine sink_name=adapter-soft-volume slaves=$ADAPTER_SINK_NAME
pactl set-default-sink adapter-soft-volume

答案2

针对第 4 点,音量低于 35% 时没有声音。

同样的问题,不同的发行版(Fedora,不是 Ubuntu)。不幸的是,现有答案中解释的命令(set-default-sink...)在这种情况下没有帮助。

在 Fedora 22 上,修改配置文件即可完成此任务:

配置文件:/usr/share/pulseaudio/alsa-mixer/paths/analog-output.conf.common

查找 [Element PCM] 部分:

[Element PCM]
switch = mute
volume = merge
override-map.1 = all 
override-map.2 = all-left,all-right

将“volume = merge”行替换为以下两行:

volume = ignore
volume-limit = 0.01

重新加载脉冲音频:

$ pulseaudio -k

重新启动音频播放器并重试。

从: https://chrisjean.com/fix-for-usb-audio-is-too-loud-and-mutes-at-low-volume-in-ubuntu/

(看错误 1248649.)

然而,这个解决方法似乎对 Fedora 23 (pulseaudio 7.1) 不再有帮助 - 或者可能必须使用不同的值。

希望这对某人有帮助。

相关内容