Advanced Linux Sound Architecture (简体中文)/Troubleshooting (简体中文)

From ArchWiki
翻译状态:本文是 Advanced_Linux_Sound_Architecture/Troubleshooting翻译。上次翻译日期:2021-09-18。如果英文版本有所更改,则您可以帮助同步翻译。

音量

没有输出

如果speaker-test能发出声音而一些其他程序却不能,确认是否使用了PulseAudio

# fuser -v /dev/snd/*

若是,试试apulseAUR,见Advanced Linux Sound Architecture (简体中文)#PulseAudio 兼容性。或者,终止PulseAudio进程可能会让声音在所需的进程中开始工作。

重启后输出被静音

运行以下命令:

# alsactl restore

如果问题持续,请确认alsamixer中的 Auto-Mute 选项已被设为 Disabled(禁用)。

音量过低

运行alsamixer,尝试提高滑块的值,必要时解除声道的静音。注意如果滑块很多,可能需要滚动到右侧查看是否有被遗漏的滑块。

如果所有滑块都已被推到最大,但音量仍然过低,可以尝试运行以下脚本复位编解码器设置:

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

该脚本假定/usr/bin/python指向Python 2,但这不符合Arch的默认设置。为避免此问题,运行以下命令:

$ sed -i 's/python %s/python2 %s/' hda-analyzer.py

关闭analyzer,当提示是否要复位编解码器时回答“yes”。

如果音量仍然过低,请再次运行alsamixer:复位编解码器可能会使新的滑块可用,其中一些可能被设定得较低。

声音音量低

如果发现把音箱/耳机开到最大之后音量仍然低,可以试试softvol插件。将以下内容加入/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分析器中更改设置(见#音量过低)才能达到正确的音量而不失真。Checking the HP option under widget control in the Playback Switch (Node[0x14] PIN in the ALC892 codec, for instance) can sometimes improve audio quality and volume significantly.

启动后随机出现无声

运行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,而上面的配置提示不起作用,再试试这个方法

麦克风

没有麦克风输入

请在alsamixer中确保recording下的所有音量等级都调了上去,并且已对麦克风(如Mic、Internal Mic)和/或Capture激活CAPTURE(在alsamixer中,选定这些项并按空格)。试试把Mic Boost设为正,并调高Capture和Digital音量等级;这样可能会造成静电噪声或失真,但一旦你在录音时听到有动静,就可以把它们调低回去了。

由于pulseaudio wrapper在alsamixer中显示为“default”,可能需要先按F6选择你的实际声卡。可能也需要在Playback部分中启用并调高Line-in的音量。

使用以下命令来测试麦克风(参考arecord的手册页获取更多信息):

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

或者也可用以下命令:

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

同时使用alsamixer就可以轻松分辨应当选择哪个声道并解除其静音。

要测试特定设备,使用--device后接hw:C,D形式的PCM硬件名称,声卡编号为 C 而设备编号为 D,如果是plug类硬件的话则使用plughw:C,D。例如:

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

如果都不管用,可能需要通过另一设备测试麦克风,以排除硬件故障。

至少对于某些电脑来说,静音麦克风(MM)仅仅意味着其输入并不直接送往音箱。它仍然会接收输入。

很多戴尔笔记本需要在/etc/modprobe.d/modprobe.conf中的model名字后面添加“-dmic”:

options snd-hda-intel model=dell-m6-dmic

一些程序尝试将OSS作为主输入软件。如果之前启用了snd_pcm_osssnd_mixer_osssnd_seq_oss 内核模块(默认不会加载它们),尝试卸载(unloading)它们。

另见:

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

一些应用(Pidgin、Adobe Flash)并不提供更改捕获设备的选项。如果你的麦克风是在内置声卡之外的单独设备上的话(如USB网络摄像头或麦克风)这就会成为问题。要想只更改默认捕获设备,而让默认回放设备保持原样,可以更改 ~/.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视图下的音量已经启用。有时“Internal Microphone”不会显示在按F4显示出的捕获列表当中。如果是这样,启动alsamixer时指定 aplay -l 给出的声卡编号(如 alsamixer -c 0 )就有可能让它出现。

之后将以下内容加入 /etc/modprobe.d/snd-hda-intel.conf

options snd-hda-intel enable_msi=1

然后重新加载模块:

# rmmod snd-hda-intel && modprobe snd-hda-intel

现在在前述的Capture视图当中就应该会多出来一路输入了。

麦克风有爆裂声

如果你的麦克风有爆裂或噗噗声,且无法通过ALSA设置或清洁麦克风插头解决,试试在 /etc/modprobe.d/modprobe.conf 中添加以下行:

options snd-hda-intel model=MODEL position_fix=3

该选项可以解决纯ALSA的爆裂声,但会对pulseaudio造成问题。要让pulseaudio等同使用这些设置,编辑/etc/pulse/default.pa,找到这一行:

load-module module-udev-detect

并将其更改为:

load-module module-udev-detect tsched=0

DMA-Position Problem in the kernel docs

音频质量

通过耳机插孔有爆裂声

无论是遵循了同时输出操作提示或是尝试自己完成,都有可能在耳机或外接音箱中听到爆裂声。通过将Mic项静音或音量设为0%可以解决。使用 alsamixeramixer

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

从挂起状态恢复后听到噗声

在从挂起状态恢复电脑后可能会听到一声噗声。编辑/etc/pm/sleep.d/90alsa,删除aplay -d 1 /dev/zero行即可解决。

回放时声音跳跃

运行alsamixer,如果其中有与不存在的输出设备相对应的声道则禁用它们(例如alsamixer显示了一个实际上并没有的中置音箱)。

音质差或卡顿

如果发现音质特别差,试试在 alsamixer 中调节 PCM 音量到增益(gain)为0的水平。

若使用 snd-usb-audio 驱动,可以试试在 /etc/asound.conf 中启用 softvol。下面是针对第一个声音设备的配置范例:

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_ac97_codecsnd_hda_intel)会在声卡闲置时关闭它以节约用电。声卡启动或关闭时,就会发出刺耳的噪音。甚至在调节音量或开关窗口(KDE4)时也可能发生这种情况。如果你觉得烦的话,试试用 modinfo your_module 寻找调整或禁用此功能的模块选项。

例如,要禁用 snd_hda_intel 模块的节电模式,向 /etc/modprobe.d/modprobe.conf添加:

options snd_hda_intel power_save=0

也可能需要对于声卡控制器禁用节电:

options snd_hda_intel power_save=0 power_save_controller=N

也可以使用 modprobe snd_hda_intel power_save=0 等为内核模块设置参数。

也可能需要解除ALSA“Line”通道的静音才能奏效。任何值都可以(只要不是0或者过高的话)。例如对于板载VIA VT1708S(使用snd_hda_intel模块),即使将 power_save 设为0也会发出爆裂声。解除“Line”通道的静音并设置音量值为1即可解决问题。

来源: https://www.kernel.org/doc/html/latest/sound/designs/powersave.html

使用CPU频率动态调整时声音发生跳跃

使用 ondemandconservative 频率策略、启用CPU频率动态调整时,某些声卡和 ALSA 驱动的组合会导致来自所有来源的声音出现跳跃。目前的解决方案是用回 performance 策略。

更多信息见 CPU frequency scaling (简体中文)

硬件与声卡

验证输出参数

检查 /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 kHz的音频:

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文档

内核升级后出现“Unknown hardware”错误

在初始化ALSA的过程中有可能会输出下面的错误信息:

Unknown hardware "foo" "bar" ...
Hardware is initialized using a guess method
/usr/bin/alsactl: set_control:nnnn:failed to obtain info for control #mm (No such file or directory)

或者:

Found hardware: "HDA-Intel" "VIA VT1705" "HDA:11064397,18490397,00100000" "0x1849" "0x0397"
Hardware is initialized using a generic method
/usr/bin/alsactl: set_control:1328: failed to obtain info for control #1 (No such file or directory)
/usr/bin/alsactl: set_control:1328: failed to obtain info for control #2 (No such file or directory)
/usr/bin/alsactl: set_control:1328: failed to obtain info for control #25 (No such file or directory)
/usr/bin/alsactl: set_control:1328: failed to obtain info for control #26 (No such file or directory)

只需重新保存ALSA混音器设定:

# alsactl -f /var/lib/alsa/asound.state store

可能需要用alsamixer重新配置ALSA。

修复错误的音频插孔映射

如果你的音频插孔(插头)映射不正确,但ALSA工作正常,可以试试HDA Analyzer,一个用于HD-audio控制的pyGTK2 GUI,见ALSA wiki。 尝试调整 PIN 节点的 Widget Control 部分,让麦克风为 IN 而耳机插孔为 OUT。 Referring to the Config Defaults heading is a good idea.

注意: 此脚本不兼容Python 3(Arch Linux的默认Python实现)。要使用该脚本,将run.py中出现的python全部替换为python2,从而将脚本指向Python 2版本。之后把脚本设为可执行并运行。

S/PDIF输出不工作

若主板/声卡的同轴/光纤数字输出不工作或停止工作,且已经在alsamixer启用之并解除静音,尝试运行:

$ iecset audio on

由于这样有时在重启后可能又会停止工作,也可以将其写成systemd服务并启用。

与PC喇叭冲突

如果你确认所有声道都已解除静音,声卡驱动配置正确,且音量大小也合适,但还是听不到声音,那么请试试将下面的内容添加到/etc/modprobe.d/modprobe.conf

options snd-NAME-OF-MODULE ac97_quirk=0

以上修补据观察可用于 via82xx

options snd-NAME-OF-MODULE ac97_quirk=1

以上修补据报告可用于 snd-intel8x0

HP TX2500

添加以下2 行到 /etc/modprobe.d/modprobe.conf

options snd-cmipci mpu_port=0x330 fm_port=0x388
options snd-hda-intel index=0 model=toshiba position_fix=1
options snd-hda-intel model=hp (works for tx2000cto)

当 S/PDIF 显卡安装上时无声

查询可用的模块及其次序:

$ cat /proc/asound/modules
 0 snd_hda_intel
 1 snd_ca0106

/etc/modprobe.d/modprobe.conf中禁用不想要的显卡音频编解码器:

/etc/modprobe.d/modprobe.conf
install snd_hda_intel /bin/false

如果两个设备使用同一模块,可使用snd_hda_intel模块的enable参数;它是一个布尔数组,可以启用/禁用所希望的显卡。

options snd_hda_intel enable=1,0

错误的声卡model类型

尽管ALSA通过BIOS检测声卡,有时候ALSA可能无法识别你的model类型。声卡芯片可以在alsamixer中找到(如ALC662),model可以在 /etc/modprobe.d/modprobe.conf/etc/modprobe.d/sound.conf中设置。例如:

options snd-hda-intel model=MODEL

也有其他的model设置。大部分情况下ALSA默认的就可以了。如果想要查询更加针对于你声卡的设置,访问ALSA声卡列表,查找你的型号,点击Details,然后阅读“Setting up modprobe...”部分。将这些值输入/etc/modprobe.d/modprobe.conf。例如对于英特尔AC97声卡:

# ALSA portion
alias char-major-116 snd
alias snd-card-0 snd-intel8x0
# module options should go here

# OSS/Free portion
alias char-major-14 soundcore
alias sound-slot-0 snd-card-0

# card #1
alias sound-service-0-0 snd-mixer-oss
alias sound-service-0-1 snd-seq-oss
alias sound-service-0-3 snd-pcm-oss
alias sound-service-0-8 snd-seq-oss
alias sound-service-0-12 snd-pcm-oss

英特尔板载声卡

英特尔板载声卡无声

问题可能是由加载了两个相冲突的模块导致的,具体是 snd-intel8x0snd-intel8x0m。这种情况下屏蔽掉 snd-intel8x0m

/etc/modprobe.d/modprobe.conf
blacklist snd-intel8x0m

alsamixeramixer静音 “External Amplifier” 也可能有效。见 ALSA wiki

在mixer中解除“Mix”设置的静音也有可能有帮助。

英特尔板载声卡耳机无声

如果是使用 Intel Corporation 82801 I (ICH9 Family) HD Audio Controller 的笔记本,可能需要将该行加入 modprobe 或 sound.conf:

options snd-hda-intel model=model

其中 model 为下列之中的一个:

  • dell-m6
  • dell-vostro
  • generic
  • laptop
  • laptop-hpsense
  • olpc-xo-1_5
注意: 可能需要将此“options”行置于对应于您的声卡的“alias”行之后。

可以在内核文档中看到所有可用的 model,如 https://www.kernel.org/doc/html/latest/sound/hd-audio/models.html ,但请确认它是对应于您的内核版本的正确文档版本。

可用 model 列表也见于 这里。使用以下命令即可获知声卡芯片名称(其中的*应当改为符合您的相应文件的值)。注意有些芯片可能已经更名,不能直接对应于该文件中的条目。

$ grep Codec /proc/asound/card*/codec*

注意如果进行此操作,则有很大可能所有输入设备(内置及外置麦克风)都不能工作,所以要么就用耳机,要么用麦克风。如果受到此bug影响,请将其报告给ALSA。

另外,如果蜂鸣器(pcspkr)出现问题:

options snd-hda-intel model=$model enable=1 index=0

HDMI

HDMI 输出不工作

以下流程可以用来测试 HDMI 音频。继续之前请确认已经通过 alsamixer 启用输出并解除其静音。

注意: 如果是使用 AMD 显卡,则有一个必要的内核模块默认被禁用了。详见 ATI (简体中文)#HDMI 音频输出

使用 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 上测试成功,可以使用以下配置(在联想 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_AUDIODRIVERalsa

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

Openal 默认使用 pulseaudio,要更改次序,将以下配置加入 /etc/openal/alsoft.conf

drivers=alsa,pulse

VirtualBox:虚拟机没有声音

如果你在使用VirtualBox的时候出现问题,尝试以下命令:

$ alsactl init
Found hardware: "ICH" "SigmaTel STAC9700,83,84" "AC97a:83847600" "0x8086" "0x0000"
Hardware is initialized using a generic method

同时你需要在你的音频软件中激活ALSA输出。也可以尝试在虚拟机设置中选择不同的声音设备,从而找到能够工作的。

其他:一般性应用问题

对于其它坚持采用其自身音频设置的应用,如 XMMS 或 MPlayer,需要设置其特定选项。

对于 MPlayermpv,将以下行加入相应的配置文件:

ao=alsa

如对于 XMMS2,进入其选项并确保声音驱动设为 ALSA 而非 oss。

要在 XMMS 中进行此操作:

  • 打开 XMMS
    • Options > Preferences.
    • 选择 ALSA 输出插件。

对于不提供 ALSA 输出的应用,可以使用来自 alsa-oss 软件包的 aoss。要使用 aoss,请在运行程序时加上 aoss 前缀,例如:

aoss realplay

pcm.!default{ ... } 对于我(原作者)来说不管用了。下面这些还可以用:

pcm.default pcm.dmixer

其他问题

同时播放时出现问题

如果您在同时播放时遇到问题,且安装了 PulseAudio ,则其默认配置是“独占”声卡。一些 ALSA 用户可能对自己的配置已经很满意,不希望使用 PulseAudio。 解决方案是编辑 /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 全局配置使用的,在该情况下工作正常。见 #同一时间只有一个用户可以使用
注意: 或者,如果没有安装 PulseAudio,只是想在原版 ALSA 下使用 dmix 的话,见 上游文档。特别地,可能需要将上述配置中的 dsp 换成 !default。另外,如果察觉到该操作导致某些应用在播放时出现跳跃(声音听起来不流畅), and complain about underrun occurring, 可能需要在 pcm.dmixer 中调整 slave.buffer_size

删除旧的 ALSA 状态文件

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

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

# 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 {
 ...

戴尔笔记本上出现爆裂或噗噗声

检查是否安装了 i8kutilsAUR ,是否有程序(如 i8kmon.service)在读写该模块提供的接口,因为 i8kutils BIOS 系统调用在一些系统上会短时阻塞内核运行。详见 Fan speed control#Dell laptops 中的警告。