高级Linux音频架构/故障排除
软件包alsa-utils包含 alsa-info.sh 脚本,可用于收集关于ALSA状态的详细数据。
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 }
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_oss
、snd_mixer_oss
或 snd_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%来解决。使用 alsamixer
或 amixer
$ 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
是编解码器插槽。
要禁用编解码器——以及随后所有相关的 ALSA 设备——使用 snd_hda_intel
模块的 probe_mask
选项。
错误的型号自动检测
错误的型号自动检测可能会导致以下问题
- 没有耳机输出
有关给定声卡芯片可能的 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 标题是一个好主意。
run.py
文件中所有出现的 python
替换为 python2
,以将脚本指向 Python 2 版本。然后使脚本可执行 并运行它。验证输出参数
检查 /proc/asound/cardX/pcmYp/subZ/hw_params
的内容,其中 X
、Y
和 Z
是系统相关的。为了找到此文件,请在通过 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) 转换数据。
ALSA 应该自动检测到合适的模式,但如果失败,您可以使用 iecset(1) 强制指定模式(on
— 音频,off
— 非音频)
# iecset audio on # iecset audio off
有关更多信息,请参阅 DigitalOut。
HDMI
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 1
,device 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,您需要设置其特定选项。
对于 MPlayer 或 mpv,将以下行添加到相应的配置文件中
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。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 笔记本电脑 中的警告。