高级Linux音频架构/故障排除

出自ArchWiki

软件包alsa-utils包含 alsa-info.sh 脚本,可用于收集关于ALSA状态的详细数据。

提示: 使用root用户权限运行 alsa-info.sh 并分享其输出,以便寻求帮助。

另请参阅 SoundcardTesting

音量

重启后输出被静音

运行以下命令

# alsactl restore

如果问题仍然存在,请验证alsamixer中的“自动静音”选项是否设置为“已禁用”。

音量太小

运行alsamixer并尝试增加滑块的值,必要时取消静音通道。请注意,如果您有很多滑块,您可能需要向右滚动才能看到任何遗漏的滑块。

如果所有滑块都已调到最大,并且音量仍然太小,您可以尝试运行以下脚本来重置您的编解码器设置

$ wget -O hda-analyzer.py https://git.alsa-project.org/?p=alsa.git;a=blob_plain;f=hda-analyzer/run.py

关闭分析器,当提示是否要重置编解码器时,请回答“是”。

如果音量仍然太小,请再次运行alsamixer:重置编解码器可能会导致新的滑块被启用,并且其中一些滑块可能被设置为较低的值。

音量仍然太小

如果您在将扬声器/耳机音量调到最大后仍然面临音量过低的问题,您可以尝试使用softvol插件。将以下内容添加到/etc/asound.conf

/etc/asound.conf
pcm.!default {
    type plug
    slave.pcm "softvol"
}

pcm.softvol {
    type softvol
    slave {
        pcm "dmix"
    }
    control {
        name "Pre-Amp"
        card 0
    }
    min_dB -5.0
    max_dB 20.0
    resolution 6
}
注意: 您可能需要重启计算机,因为重启alsa守护进程没有加载新的配置。此外,如果即使重启后配置仍然不起作用,请尝试将上述配置中的plug更改为hw

更改成功加载后,您将在alsamixer中看到一个“Pre-Amp”部分。您可以在那里调整音量级别。

注意
  • 为“Pre-Amp”设置过高的值可能会导致声音失真,因此请根据适合您的级别进行调整。
  • 某些音频编解码器可能需要在HDA Analyzer(参见 #音量太小)中调整设置,以便在不失真的情况下获得适当的音量。检查播放开关中的小部件控件下的HP选项(例如ALC892编解码器中的Node[0x14] PIN)有时可以显著提高音频质量和音量。

启动时随机无声音

您可以通过运行speaker-test快速测试声音。如果没有声音,您可能会看到类似于

ALSA lib pcm_dmix.c:1022:(snd_pcm_dmix_open) unable to open slave
Playback open error: -16
Device or resource busy

如果您在启动时没有声音,这可能是因为您的系统有多个声卡,并且它们的顺序有时会在启动时更改。如果是这种情况,请尝试设置默认声卡

如果您使用MPD并且上述配置技巧不起作用,请尝试按照 https://mpd.wikia.com/wiki/Configuration#ALSA_MPD_software_volume_control 进行操作。

麦克风

无麦克风输入

在alsamixer中,确保录音下的所有音量级别都已调高,并且麦克风(例如Mic、Internal Mic)和/或Capture上的CAPTURE已切换为活动状态(在alsamixer中,选择这些项目并按空格键)。尝试启用正向麦克风增强并提高Capture和Digital级别;这可能会产生静电或失真,但是一旦您在录音时听到某些声音,就可以将它们调回较低的水平。

由于pulseaudio包装器在alsamixer中显示为“default”,您可能需要先按F6选择您的实际声卡。您可能还需要在“播放”部分中启用并增加“线路输入”的音量。

要测试麦克风,请运行以下命令(有关更多信息,请参阅 arecord(1)

$ arecord --duration=5 --format=dat test-mic.wav
$ aplay test-mic.wav

或者,您可以运行此命令

$ arecord -vv --format=dat /dev/null

与alsamixer一起运行,以轻松识别您应该选择和取消静音的通道。

要测试特定设备,请使用 --device 参数,后跟硬件PCM名称,格式为 hw:C,D,表示声卡C设备D;或 plughw:C,D,表示插入式硬件。例如

$ arecord -vvv --format=dat --device=plughw:0,0 /dev/null

如果一切都失败了,您可能需要通过使用不同的设备测试麦克风来排除硬件故障。

对于至少某些计算机,静音麦克风 (MM) 仅表示其输入不会立即传送到扬声器。它仍然接收输入。

某些程序尝试使用OSS作为主要输入软件。如果您之前启用了 snd_pcm_osssnd_mixer_osssnd_seq_oss 内核模块(默认情况下未加载),请尝试卸载它们。

另请参阅

设置默认麦克风/捕获设备

某些应用程序(Pidgin、Adobe Flash)不提供更改捕获设备的选项。如果您的麦克风位于与内置声卡不同的设备上(例如USB网络摄像头或麦克风),则会成为问题。要仅更改默认捕获设备,而保持默认播放设备不变,您可以修改您的 ~/.asoundrc 文件以包含以下内容

~/.asoundrc
pcm.usb
{
    type hw
    card U0x46d0x81d
}

pcm.!default
{
    type asym
    playback.pcm
    {
        type plug
        slave.pcm "dmix"
    }
    capture.pcm
    {
        type plug
        slave.pcm "usb"
    }
}

U0x46d0x81d 替换为您的捕获设备在ALSA中的声卡名称。您可以使用 arecord -L 列出ALSA检测到的所有捕获设备。

内置麦克风不工作

首先确保在alsamixer的“Capture”视图下启用了音量。在某些情况下,按下F4时,“内置麦克风”不会显示在可用的捕获列表中。如果是这样,指定 aplay -l 给出的声卡编号来启动alsamixer(例如 alsamixer -c 0)可以使其出现。

音频质量

通过迷你插孔(耳机接口)发出噼啪声

遵循 高级Linux音频架构#同步输出 可能会导致耳机或外接扬声器发出噼啪声。这可以通过静音或将麦克风音量设置为0%来解决。使用 alsamixeramixer

$ amixer sset "Mic" 0%
$ amixer sset "Mic" mute

从睡眠恢复后发出爆破声

您可能会在计算机从睡眠状态恢复后听到爆破声。这可以通过编辑 /etc/pm/sleep.d/90alsa 并删除包含 aplay -d 1 /dev/zero 的行来解决

播放期间声音跳跃

运行alsamixer,如果存在不存在的输出设备的通道,则禁用它们(例如alsamixer显示一个中置扬声器,但您没有)。

音频质量差或削波

如果您遇到音频质量差的问题,请尝试将PCM音量(在alsamixer中)设置为增益为0的水平。

如果已加载 snd_usb_audio 驱动程序,您可以尝试启用 softvol

/etc/asound.conf
pcm.!default {
    type plug
    slave.pcm "softvol"
}
pcm.dmixer {
    type dmix
    ipc_key 1024
    slave {
        pcm "hw:0"
        period_size 4096
        buffer_size 131072
        rate 50000
    }
    bindings {
        0 0
        1 1
    }
}
pcm.dsnooper {
    type dsnoop
    ipc_key 1024
    slave {
        pcm "hw:0"
        channels 2
        period_size 4096
        buffer_size 131072
        rate 50000
    }
    bindings {
        0 0
        1 1
        }
}
pcm.softvol {
  type softvol
  slave { pcm "dmixer" }
  control {
    name "Master"
    card 0
  }
}
ctl.!default {
  type hw
  card 0
}
ctl.softvol {
  type hw
  card 0
}
ctl.dmixer {
  type hw
  card 0
}

开始和停止播放时发出爆破声

某些模块(例如 snd_hda_intel)可以在声卡未使用时关闭其电源。这可能会在每次断电/上电时引起可听见的咔哒声—例如噼啪声/爆破声/刮擦声—具体取决于设备(有时甚至在移动音量滑块或在某些桌面环境中打开和关闭窗口时)。

有关更多信息,请参阅 电源管理#音频#节能

硬件和声卡

HD音频

有关更多信息,请参阅 Module snd-hda-intel 以及 modinfo --field=parm snd_hda_intel | column --separator=':' --table 的输出。

另请参阅 高级Linux音频架构#驱动程序配置

节能

节能 默认情况下启用节能模式,并且可能会导致以下问题

要完全禁用 snd_hda_intel 模块的节能模式,请使用以下内核模块参数

/etc/modprobe.d/alsa-base.conf
options snd_hda_intel power_save=0 power_save_controller=N

编解码器探测

编解码器是HD音频声卡的硬件组件。一张声卡可能包含多个编解码器,一个编解码器可能对应多个ALSA设备。

编解码器插槽是一个数字(从零开始),用于标识给定声卡上的编解码器。您可以从 /proc/asound/cardi/codec#s 文件和 /sys/class/sound/hwCiDs/ 目录名称中获取编解码器插槽号—其中 i 是声卡索引,s 是编解码器插槽。

注意: 不要将 HD 声卡编解码器插槽OSS 插槽号混淆,后者对应于 ALSA 声卡索引

要禁用编解码器——以及随后所有相关的 ALSA 设备——使用 snd_hda_intel 模块的 probe_mask 选项。

错误的型号自动检测

错误的型号自动检测可能会导致以下问题

提示: 如果您的芯片是 ALC22x/23x/25x/269/27x/28x/29xALC66x/67x/892,则尝试 dell-headset-multi,即使硬件不是来自 Dell。
  • 没有耳机输出

有关给定声卡芯片可能的 model 字符串,请参阅 HD-Audio Codec-Specific Models

声卡芯片可以在以下位置找到

  • alsamixer — 在左上角查看 Chip:
  • grep 'Codec:' /proc/asound/card*/codec#* 的输出,
  • grep . /sys/class/sound/hwC?D?/chip_name 的输出,
  • /proc/asound/pcm 文件。

要强制指定型号,请使用 snd_hda_intel 模块的 model 选项。

消息信号中断

是否应启用 消息信号中断 (MSI) 很大程度上取决于硬件。在错误自动检测的情况下,可能会发生各种糟糕的事情

  • 错误的禁用可能导致声卡未被检测到;
  • 错误的启用可能导致音频质量差(断断续续),甚至内核锁死。

要检查 MSI 功能状态,请使用 root 用户 权限运行 lspci -vv -nn -d ::0403

提示: 此处的 ::0403 指的是 多媒体控制器 PCI 设备类的 音频设备 子类。

HD 声卡上的 MSI 由 snd_hda_intel 模块的 enable_msi 选项控制。

DMA 指针

HD 声卡的输入和/或输出上的咔哒声(噼啪声、爆裂声)可能是由 DMA 位置问题 引起的。尝试更改 snd_hda_intel 模块的 position_fix 选项。

修复错误的音频引脚映射

如果您的音频引脚(插头)的映射不对应,但 ALSA 工作正常,您可以尝试 HDA Analyzer —— 一个用于 HD 音频控制的 pyGTK2 GUI,可以在 ALSA wiki 上找到。尝试调整 PIN 节点的 Widget Control 部分,以使麦克风为输入,耳机插孔为输出。参考 Config Defaults 标题是一个好主意。

注意: 该脚本与 Python 3 不兼容,Python 3 是 Arch Linux 上的默认 Python 实现。为了使用该脚本,请将 run.py 文件中所有出现的 python 替换为 python2,以将脚本指向 Python 2 版本。然后使脚本可执行 并运行它。

验证输出参数

检查 /proc/asound/cardX/pcmYp/subZ/hw_params 的内容,其中 XYZ 是系统相关的。为了找到此文件,请在通过 ALSA 输出任何内容时执行以下命令

$ find /proc/asound/ -name hw_params | xargs -I FILE grep -v -l "closed" FILE | grep '/proc/asound/card./pcm.p/sub./hw_params'

如果没有播放任何内容,则应该没有结果。

这是一个位深度为 24 位和采样频率为 44.1 千赫兹的音频的示例输出

$ cat /proc/asound/card1/pcm0p/sub0/hw_params
access: RW_INTERLEAVED
format: S24_3LE
subformat: STD
channels: 2
rate: 44100 (44100/1)
period_size: 5513
buffer_size: 22050

更多信息请参见 ALSA 文档

S/PDIF 输出不工作

S/PDIF (IEC958) 使用两种模式

  • 音频模式是数字 PCM 信号,因此接收器只需使用 数模转换器 (DAC) 转换数据。
  • 非音频模式是编码的比特流,因此接收器必须先解码数据,然后将其发送到 DAC。杜比数字DTS 数字环绕 是编码比特流格式的示例。

ALSA 应该自动检测到合适的模式,但如果失败,您可以使用 iecset(1) 强制指定模式(on音频off非音频

# iecset audio on
# iecset audio off

有关更多信息,请参阅 DigitalOut

HDMI

本文或本节是与 ALSA 合并的候选对象。

注意: 本节几乎与 HDMI 本身无关:它有点像是主文章的 TL;DR(列出设备、测试声音、设置默认设备;重新映射)。(在 Talk:Advanced Linux Sound Architecture/Troubleshooting 中讨论)

HDMI 输出不工作

下面描述的过程可用于测试 HDMI 音频。在继续之前,请确保已使用 alsamixer 启用并取消静音输出。

通过 HDMI 电缆将您的 PC 连接到显示器,并使用 xrandr 启用显示器。

使用 aplay -l 发现声卡和设备编号。例如

$ aplay -l
**** List of PLAYBACK Hardware Devices ****
card 0: SB [HDA ATI SB], device 0: ALC892 Analog [ALC892 Analog]
  Subdevices: 1/1
  Subdevice #0: subdevice #0
card 0: SB [HDA ATI SB], device 1: ALC892 Digital [ALC892 Digital]
  Subdevices: 1/1
  Subdevice #0: subdevice #0
card 1: Generic [HD-Audio Generic], device 3: HDMI 0 [HDMI 0]
  Subdevices: 1/1
  Subdevice #0: subdevice #0

将声音发送到设备。按照上一步中的示例,您将声音发送到 card 1device 3

$ aplay -D plughw:1,3 /usr/share/sounds/alsa/Front_Center.wav

如果 aplay 没有输出任何错误,但仍然没有声音,请“重启”接收器、显示器或电视机。由于 HDMI 接口在连接时执行握手,它可能之前注意到没有嵌入音频流,并禁用了音频解码。如果您使用的是独立的窗口管理器,则可能需要在插入 HDMI 电缆时播放声音。

mplay 和其他应用程序可以配置为使用特殊的 HDMI 设备作为音频输出。但是 flashplugin 只能使用默认设备。以下方法用于覆盖默认设备。但是,当您的电视机从 HDMI 端口断开连接时,您需要将其改回。

如果测试成功,请创建或编辑您的 ~/.asoundrc 文件以将 HDMI 设置为默认音频设备。

~/.asoundrc
pcm.!default {
    type hw
    card 1
    device 3
}

或者如果上述配置不起作用,请尝试

~/.asoundrc
defaults.pcm.card 1
defaults.pcm.device 3
defaults.ctl.card 1

或者如果您以以下方式成功

$ speaker-test -Dplug:hdmi

对于您的 HDMI 或 DisplayPort 端口,以下配置将起作用(已在 Lenovo ThinkPad T430s 上成功测试)

~/.asoundrc
pcm.!default {
    type plug
    slave.pcm "hdmi"
}

HDMI 5.1 声道声音输出到错误的扬声器

可以使用 ALSA 的 remap 功能将声音重定向到预期的扬声器。

/etc/asound.conf
pcm.!hdmi-remap {
    type asym
    playback.pcm {
        type plug
        slave.pcm "remap-surround51"
    }
}

pcm.!remap-surround51 {
    type route
    slave.pcm "hw:0,3"
    ttable {
        0.0= 1
        1.1= 1
        2.4= 1
        3.5= 1
        4.2= 1
        5.3= 1
    }
}

应用程序

SDL:SDL 应用程序没有声音

如果您在使用基于 SDL 的应用程序时没有声音,请尝试将 环境变量 SDL_AUDIODRIVER 设置为 alsa

OpenAL:使用 OpenAL 的应用程序没有声音

OpenAL 默认为 PulseAudio。要指示它首先尝试 ALSA

/etc/openal/alsoft.conf
drivers=alsa,pulse

其他:通用应用程序问题

对于其他坚持使用自己的音频设置的应用程序,例如 XMMS 或 MPlayer,您需要设置其特定选项。

对于 MPlayermpv,将以下行添加到相应的配置文件中

ao=alsa

例如,对于 XMMS2,进入其选项并确保声音驱动程序设置为 ALSA,而不是 oss。

要在 XMMS 中执行此操作

  • 打开 XMMS
    • 选项 > 首选项。
    • 选择 ALSA 输出插件。

对于不提供 ALSA 输出的应用程序,您可以使用 alsa-oss 包中的 aoss。要使用 aoss,当您运行程序时,请在其前面加上 aoss,例如

aoss realplay

pcm.!default{ ... } 对我不再有效。但这有效

pcm.default pcm.dmixer

其他问题

同步播放问题

如果您在同步播放时遇到问题,并且安装了 PulseAudio,则其默认配置设置为“劫持”声卡。一些 ALSA 用户可能不想使用 PulseAudio,并且对他们当前的 ALSA 设置非常满意。一种解决方法是编辑 /etc/asound.conf 并注释掉以下行

# Use PulseAudio by default
pcm.!default {
    type pulse
    fallback "sysdefault"
    hint {
        show on
        description "Default ALSA Output (currently PulseAudio Sound Server)"
    }
}

注释掉以下内容也可能有所帮助

ctl.!default {
    type pulse
    fallback "sysdefault"
}

这可能比完全卸载 PulseAudio 更简单的解决方案。

实际上,这是一个可用的 /etc/asound.conf 文件的示例

pcm.dmixer {
    type dmix
    ipc_key 1024
    ipc_key_add_uid 0
    ipc_perm 0660
}
pcm.dsp {
    type plug
    slave.pcm "dmix"
}
注意:/etc/asound.conf 文件旨在用于全局 MPD 配置并已成功使用。请参阅 #Problems with availability to only one user at a time
注意: 或者,如果您没有安装 PulseAudio,并且只想让 dmix 与原始 ALSA 一起工作,请参阅 上游文档。特别是,您可能需要将上述配置中的 dsp 替换为 !default。此外,如果您注意到这会导致某些应用程序在播放时跳过(即声音“卡顿”),并抱怨发生欠载,您可能需要调整 pcm.dmixer 中的 slave.buffer_size

删除旧的 ALSA 状态文件 (asound.state)

alsa-utils 软件包提供了 alsa-store.service,它会在系统关机时自动将当前的 ALSA 状态存储到 /var/lib/alsa/asound.state。对于尝试重置其当前 ALSA 状态的用户来说,这可能会有问题,因为 asound.state 文件将在每次关机时使用当前状态重新创建(例如,尝试从混音器中删除用户定义的通道)。可以通过创建以下空文件来临时禁用 alsa-store.service 服务

# mkdir -p /etc/alsa
# touch /etc/alsa/state-daemon.conf

state-daemon.conf 的存在阻止 alsa-store.service 在关机期间保存 asound.state。禁用此服务后,可以按如下方式删除 asound.state 文件

# rm /var/lib/alsa/asound.state

重新启动后,之前的 ALSA 状态应该丢失,当前状态应该重置为默认值。通过删除我们创建的条件文件来重新启用 alsa-store.service

# rm /etc/alsa/state-daemon.conf

在下次关机时,asound.state 文件应该使用 ALSA 默认值重新创建。也可以使用以下命令立即生成该文件

# alsactl store

如果您想在不重新启动的情况下清除 ALSA 状态,可以使用 rmmod 删除声音驱动程序模块,然后手动删除 asound.state 中不需要的条目,然后使用 modprobe 重新安装声音驱动程序模块。

每次只有一个用户可用时出现的问题

您可能会发现一次只有一个用户可以使用 dmixer。对于大多数人来说这可能还可以,但对于那些以单独用户身份运行 mpd 的人来说,这是一个问题。当 mpd 正在播放时,普通用户无法通过 dmixer 播放声音。虽然完全可以在用户的登录帐户下运行 mpd,但已经找到了另一种解决方案。将 ipc_key_add_uid 0 行添加到 pcm.dmixer 块会禁用此锁定。以下是 asound.conf 中的代码片段,其余部分与上面相同。

...
pcm.dmixer {
    type dmix
    ipc_key 1024
    ipc_key_add_uid 0
    ipc_perm 0660
slave {
 ...

Dell 笔记本电脑上的噼啪声/爆裂声

检查您是否安装了 i8kutilsAUR 以及是否有任何东西(例如 i8kmon.service)正在读取或写入模块公开的接口,因为 i8kutils BIOS 系统调用会在某些系统上暂时阻止内核。有关更多详细信息,请参阅 风扇速度控制#Dell 笔记本电脑 中的警告。