Advanced Linux Sound Architecture (简体中文)

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

高级 Linux 声音体系(Advanced Linux Sound Architecture,ALSA)提供声卡的内核驱动,代替了原来的开放声音系统(Open Sound System,OSS)。

除了声音设备驱动,ALSA还捆绑了一个用户空间驱动的库用于应用开发。开发者可以使用这些 ALSA 驱动进行高级 API 开发,可以通过 ALSA 库达成与声音设备的内核(直接)交互。

安装

ALSA是一组内置的Linux内核模块,故无需手动安装。

udev会在系统启动时自动检测硬件并选择所需的驱动,并加载相应的声音设备驱动模块。所以你的声卡应当已经可以工作了,然而在一开始声音可能被静音了。这种情况下见#解除各声道的静音

用户权限

一般情况下,本地用户有权播放音频和改变混音器音量。

要让远程用户拥有这些权限,需要把这些用户加入 audio 用户组,但默认情况下不推荐这样做(见下方注意)。

注意: 添加用户到 audio 组允许其直接访问设备。记住,这样会允许应用独占输出设备。在多用户系统中,这会破坏软件混音或快速用户切换。因此,默认情况下不建议把用户加入 audio 用户组,除非有特别需要[1]

ALSA 实用程序

安装 软件包 alsa-utils。其包含 alsamixeramixer 等实用程序。amixer是一个用于更改音频设置的shell命令,而alsamixer则提供了一个较为直观的,基于ncurses的界面,用于配置声音设备。

如果需要高质量重采样,请安装 alsa-plugins 软件包,即可启用#上混和缩混和其他高级特性。

OSS 兼容性

注意: 如果你的应用报告缺少/dev/dsp或者/dev/snd/seq,这一部分很重要

OSS 是一个可选的声音架构。

ALSA有能力截获Open Sound System (简体中文)调用,并转而将之发往ALSA。例如,对于试图打开/dev/dsp并向里面直接写入声音数据的传统应用,这个模拟层很有用。没有OSS或者该模拟库,就会缺少/dev/dsp,应用就不会产生任何声音。

如果希望Open Sound System (简体中文)应用和dmix共同工作,请一并安装alsa-oss。然后加载snd-seq-osssnd-pcm-osssnd-mixer-oss 内核模块 来激活OSS模拟。

PulseAudio 兼容性

apulseAUR 可以为只提供PulseAudio声音支持的应用使用 ALSA。用法为 $ apulse 你的应用

ALSA 和 Systemd

alsa-utils 软件包默认包含了 systemd 单元配置文件 alsa-restore.servicealsa-state.service

在安装时它们会自动安装并激活(通过软件包提供的指向sound.target的符号链接)。二者都不会默认运行,因为要确定该使用哪种方法需要由用户专门决定。两个选项如下所述:

  • alsa-restore.service 在引导时读取 /var/lib/alsa/asound.state ,并在关机时写入更新后的值,前提是已经运行 alsactl store 生成了配置文件;
  • alsa-state.service 以守护进程方式(重新)启动alsactl,以持续跟踪并保持音量变化。同样,前提是用户已经专门启动过了 alsactl daemon

两种方法是互斥的,根据需要可以选择其中一种。更多信息请查看 alsactl(1)

可以通过 systemctl 检查其状态。

ALSA 固件

alsa-firmware 软件包包含了某些声卡(如创新SB0400 Audigy2)可能需要的固件。

一些较新型号的笔记本电脑(2019年底/2020)需要sof-firmwarealsa-ucm-conf,它们使用 Sound Open Firmware 提供的固件实现驱动程序。

解除各声道的静音

ALSA 默认静音所有声道,必须手动解除。

使用amixer解除静音

可以使用 amixer 解除声卡的主音量静音:

$ amixer sset Master unmute
$ amixer sset Speaker unmute
$ amixer sset Headphone unmute

使用alsamixer解除静音

使用 alsamixer 可以解除声卡的静音:

$ alsamixer

声道下方标有 MM 表示其已经静音,而标有 00 表示已经启用。

使用 键滚动到 MasterPCM 声道,按下 m 键解除静音。

使用 键增加音量,获得0dB的增益。增益值可在左上方 Item: 字段旁边看到。

注意: 若增益高于0 dB,可能会听到失真。

解除5.1/7.1声音的静音

要想得到完整的 5.1 或 7.1 环绕声,可能需要解除 FrontSurroundCenterLFE (低音炮)以及 Side 等其他声道的静音(这些声道名称是 Intel HD Audio 声卡使用的,可能因设备不同而有所差异)。

注意: 请注意这样并不会自动上混立体声源(如多数音乐)。要实现这一功能,见#上混和缩混

启用麦克风

要启用麦克风,按 F4 切换至 Capture (捕获)选项卡,然后按 空格 启用一个声道即可。如果麦克风不工作,参考Advanced Linux Sound Architecture (简体中文)/Troubleshooting (简体中文)#没有麦克风输入

按下 Esc 键退出 alsamixer。

测试你的更改

接下来,测试声卡是否工作:

$ speaker-test -c 2

根据扬声器的配置,调整 -c 。对于 7.1 声道,使用 -c 8

$ speaker-test -c 8

如果声音输出到了错误的设备,可以试试用 -D 参数手动指定。

$ speaker-test -D default:PCH -c 8

-D 的值是 PCM 通道的名字,运行以下命令即可获取:

$ aplay -L | grep :CARD
default:CARD=PCH  # 'default:PCH' is the PCM channel name for -D
sysdefault:CARD=PCH
front:CARD=PCH,DEV=0
surround21:CARD=PCH,DEV=0
surround40:CARD=PCH,DEV=0
surround41:CARD=PCH,DEV=0
surround50:CARD=PCH,DEV=0
surround51:CARD=PCH,DEV=0
surround71:CARD=PCH,DEV=0

若声音工作异常,而通过参数指定获得了正确的声音输出,尝试#设置默认声卡

如果没有正常工作,请继续阅读 #配置 部分和 Advanced Linux Sound Architecture/Troubleshooting 页面。

附加注释

  • 如果你的系统有多个声卡,则可以按F6切换声卡。
  • 有些声卡需要静音或禁用数字输出,才能听到模拟声音。Soundblaster Audigy LS应当静音标有 IEC958 的声道。
  • 有些机器(如Thinkpad T61)有Speaker声道,也需要解除静音并调整。
  • 有些机器(如Dell E6400)可能也需要解除FrontHeadphone 通道的静音并调整它们。
  • 如果重启以后,你的声音调整似乎丢失了,尝试以root运行alsamixer。

配置

系统配置文件是 /etc/asound.conf, 分用户配置文件是 ~/.asoundrc.

基本语法

Alsa 设置文件遵循一个简单语法,由分层次的参数(键值)赋值组成。语法在[2]中也有说明。

赋值与分隔符

赋值能够定义一个键值的具体值,可以使用不同的赋值类型和风格。

#  使用 # 符号来注释文字,该符号后所有到行尾的符号能够被注释掉。 
key = value  # 句中等号通常可以省略,因为空格也能够被用作分隔符。

key value  # 此句意义与上句 key = value 等同

分隔符被用作指示赋值的开始和结束,不过逗号或是空白字符也是可以使用的。

key value0; key valueN;
key value0, key valueN, # 所有赋值操作都是等同意义的
key value0 key valueN

key	
value0
	key		
valueN

复合赋值使用大括号作为分隔符。

key {	subkey0 value0;
	subkeyN valueN;	} 

key.subkey0 value0; # 与上述语句意义相同
key.subkeyN valueN;

出于可读性考虑,在定义三种以上的参数时,推荐使用第一种方式。

序列定义使用中括号当作分隔符。

key [	"value0";
	"valueN";	]

key.0 "value0"; # 与上述语句意义相同
key.N "valueN";

不同的配置风格都取决于使用者的偏好,但是需要避免混用不同风格。关于基础配置的更多信息见 [3]

数据类型

对于参数值 Alsa 使用不同的数据类型,必须在用户对应的配置文件中设置。一些键值接受多种数据类型,但大部分则并非如此。一个配置选项列表及其相应的PCM插件类型要求见[4]

操作模式

解析节点有不同的操作模式,默认模式为“合并/创建”(merge/create)。如果操作模式为“合并/创建”或“合并”(merge),会进行类型检查。只有同样类型的赋值能够被合并,因此字符串不能与整形数合并。在默认操作模式中尝试对复合键值定义一个简单赋值是没有作用的,反之亦然。

操作模式前缀符号:

  • "+" -- 合并/创建
  • "-" -- 合并
  • "?" -- 不覆盖(do not override)
  • "!" -- 覆盖(override)
# 合并/创建 - 如果不存在节点则创建之。
# 如果其存在且类型匹配,则合并subkeyN到键值中。
key.subkeyN valueN;

# 合并/创建 - 与上面等同
key.+subkeyN valueN;

# 合并 - 节点 key.subkeyN 必须已经存在且拥有相同类型
key.-subkeyN valueN;

# 不覆盖 - 如果 key.subkeyN 节点已经存在,则忽略新的赋值
key.?subkeyN valueN;

# 覆盖 - 移除 subkeyN 及其下所有键值, 然后创建节点 key.subkeyN
key.!subkeyN valueN;

在操作正确的情况下,使用覆盖操作模式通常来说是安全的。但是切记,在一个节点中可能会有其他对于正确动作来说必要的键值。

警告: 覆盖 pcm 节点大致必然会使 alsa 无法使用,因为所有插件定义都会被删除。 因此除非要从头开始创建配置,否则 不要使用 !pcm.key
使用“默认”节点的默认设备设定示例

假设“默认”(default)节点在 /usr/share/alsa/alsa.conf 设定,其中“defaults.pcm.card”及其对应的“ctl”(控制)项都赋值为整型数“0”, 而用户想要将默认PCM与控制设备设定为声卡“2”(第三个声卡),或对于Azalia声卡设定为“SB”。

defaults.ctl.card 2; # 将默认设备与控制设定为第三个声卡(计数从0开始)。
defaults.pcm.card 2; # 寻址类型不会更改。

defaults.ctl.+card 2; # 与上面相同。
defaults.pcm.+card 2;

defaults.ctl.-card 2; # 对于默认设置来说效果相同,但如果默认节点被去除
defaults.pcm.-card 2; # 或类型被更改,则合并操作不会带来更改。

defaults.pcm.?card 2; # 没有效果,因为该赋值已经存在。
defaults.ctl.?card 2;

defaults.pcm.!card "SB"; # 此处有必要使用覆盖操作模式,
defaults.ctl.!card "SB"; # 因为数值类型有所不同。

这里使用双引号会自动将值的数据类型设为字符串,因此在上例中设置 defaults.pcm.!card "2" 的结果就是保持之前的默认设备不变,此例中为声卡0。只要不使用特殊字符(理想状态下也不应该会使用),双引号就不是强制性的。This may be irrelevant in other assignments.

注意: From a configuration point of view those are not equivalent to setting a compound "default" pcm device, since most users specify addressing type in there also, which actually may be the same, but the assignment itself still differs. Also defaults.pcm.card is referred to multiple times in alsa configuration files, usually as a fallback assignment, where different environment variables take precedence.

嵌套

有时在配置中使用嵌套有用而且更易读。

pcm.azalia {	type hw; card 0	}
pcm.!default {	type plug; slave.pcm "azalia"	}

# 等同于

pcm.!default {	type plug; slave.pcm {	type hw; card 0;	}	}

# 也等同于

pcm.!default.type plug;
pcm.default.slave.pcm.type hw;            
pcm.default.slave.pcm.card 0;

包含配置文件

</path/to/configuration-file> # 包含一个配置文件
<confdir:/path/to/configuration-file> # 对全局配置目录的引用

设置默认声卡

提示: 对于ALSA相关术语“card”(声卡)、“device”(设备)(“card”并非等同于“device”)、“subdevice”(子设备)等的解释见Wikipedia:Advanced Linux Sound Architecture#Concepts。维基百科上也有关于很多相关术语的文章,如PCM以及S/PDIF

通过默认节点设置默认声卡

关于 defaults.pcm.carddefaults.pcm.device,要实际运用上面的例子,假定有2块声卡分别编号为0和1,想要默认使用编号1的声卡,在 /etc/asound.conf 或用户对应的 ~/.asoundrc 使用以下配置即可更改回放与混音控制声卡。

defaults.pcm.card 1
defaults.ctl.card 1

通过内核模块选项配置编号

如果发现开机时声卡次序会发生变化,可以在 /etc/modprobe.d 中的任何名字以 .conf 结尾的文件(以下假设为 /etc/modprobe.d/alsa-base.conf)中指定次序。

比如,要让 mia 声卡成为 #0:

/etc/modprobe.d/alsa-base.conf
options snd_mia index=0
options snd_hda_intel index=1

使用 $ cat /proc/asound/modules 来获得当前已经载入的声音模块及其次序。这个列表通常对于载入次序来说就是全部所需的了。使用 $ lsmod | grep snd来获得设备和模块的列表。这个配置假设你有一个使用 snd_mia 的mia声卡和一个使用 snd_hda_intel 的(板载)声卡。

也可以指定index为 -2,让ALSA不要将对应的设备作为主声卡。Linux Mint 和 Ubuntu 等发行版使用了以下配置,避免 USB 声卡和其他“非正常”设备获得序号 0

/etc/modprobe.d/alsa-base.conf
options bt87x index=-2
options cx88_alsa index=-2
options saa7134-alsa index=-2
options snd-atiixp-modem index=-2
options snd-intel8x0m index=-2
options snd-via82xx-modem index=-2
options snd-usb-audio index=-2
options snd-usb-caiaq index=-2
options snd-usb-ua101 index=-2
options snd-usb-us122l index=-2
options snd-usb-usx2y index=-2
options snd-pcsp index=-2
options snd-usb-audio index=-2

以上配置会在系统重启后生效。

参阅[5]

当载入被多个卡(比如,snd-hda-intel)使用的模块时,推荐您加入供应商和设备认证信息到选项中。为了获得 vidpid 信息,使用以下命令:

$ lspci -nn | grep -i audio
00:14.2 Audio device [0403]: Advanced Micro Devices, Inc. [AMD/ATI] SBx00 Azalia (Intel HDA) [1002:4383] (rev 40)
01:00.1 Audio device [0403]: Advanced Micro Devices, Inc. [AMD/ATI] RV770 HDMI Audio [Radeon HD 4850/4870] [1002:aa30]
07:05.0 Multimedia audio controller [0401]: VIA Technologies Inc. VT1720/24 [Envy24PT/HT] PCI Multi-Channel Audio Controller [1412:1724] (rev 01)

Last numbers in square brackets are [vid:pid], so for the above example, for setting Azalia as default card following is correct:

/etc/modprobe.d/alsa-base.conf
# SB [HDA ATI SB]
options snd-hda-intel index=0 model=auto vid=1002 pid=4383
# HDMI [HDA ATI HDMI]
options snd-hda-intel index=1 model=auto vid=1002 pid=aa30
# HiFi [Audiotrak Prodigy 7.1 HiFi]
options snd-ice1724 index=2 model=prodigy71hifi vid=1412 pid=1724

使用环境变量选择默认PCM设备

把ALSA_CARD设为设备的名字也许就可以了。首先用 aplay -l 获取名称,然后将ALSA_CARD设为冒号之后、方括号之前的名称:例如,如果有

card 1: HDMI [HDA ATI HDMI], device 3: HDMI 0 [HDMI 0]

那就设置ALSA_CARD=HDMI

其他变量见默认全局配置:

/usr/share/alsa/alsa.conf
Variable name # Definition
ALSA_CARD # pcm.default pcm.hw pcm.plughw ctl.sysdefault ctl.hw rawmidi.default rawmidi.hw hwdep.hw
ALSA_CTL_CARD # ctl.sysdefault ctl.hw
ALSA_HWDEP_CARD # hwdep.default hwdep.hw
ALSA_HWDEP_DEVICE # hwdep.default hwdep.hw
ALSA_PCM_CARD # pcm.default pcm.hw pcm.plughw
ALSA_PCM_DEVICE # pcm.hw pcm.plughw
ALSA_RAWMIDI_CARD # rawmidi.default rawmidi.hw
ALSA_RAWMIDI_DEVICE # rawmidi.default rawmidi.hw

或者也可以在你自己的配置文件(最好是全局的/etc/asound.conf)中对行为进行覆盖。添加:

pcm.!default {
  type plug
  slave.pcm {
    @func getenv
    vars [ ALSAPCM ]
    default "hw:Audigy2"
  }
}

同样把本例中的 Audigy2 替换成你的设备名字。你可以使用aplay -l获取名字,或者也可以使用surround51等PCM。不过,如果你需要使用麦克风的话,选择全双工PCM声卡为默认设备是个不错的选择。

现在只需改变环境变量 ALSAPCM,就可以在启动程序时选择声卡。对于所有不允许选择声卡的程序此法效果良好,而对于其他的程序请确保保持默认声卡选择。

举例来说,假设你写了一个缩混PCM命名为 mix51to20 ,用以下命令即可将之用于mplayer

ALSAPCM=mix51to20 mplayer example_6_channel.wav
注意: 请注意默认寻址类型。

替代方式

提示: 使用asoundconfAUR可部分地自动化该过程。

首先确认你想设为默认的声卡和设备ID:

$ aplay -l
**** List of PLAYBACK Hardware Devices ****
card 0: Intel [HDA Intel], device 0: CONEXANT Analog [CONEXANT Analog]
  Subdevices: 1/1
  Subdevice #0: subdevice #0
card 0: Intel [HDA Intel], device 1: Conexant Digital [Conexant Digital]
  Subdevices: 1/1
  Subdevice #0: subdevice #0
card 1: JamLab [JamLab], device 0: USB Audio [USB Audio]
  Subdevices: 1/1
  Subdevice #0: subdevice #0
card 2: Audio [Altec Lansing XT1 - USB Audio], device 0: USB Audio [USB Audio]
  Subdevices: 1/1
  Subdevice #0: subdevice #0
警告: 仅仅把type hw设为默认声卡等同于直接指定硬件,使得其他应用无法使用该设备。仅当作为更复杂设置的一部分(~/.asoundrc)或者用户有意地想要直接指定声卡(如通过eic958的数字输出或专门的音乐服务器)才推荐这种做法。

例如,该列表中的最后一项的声卡ID为2,设备ID为0。要把这块声卡设为默认,可以使用系统级的 /etc/asound.conf 或用户级的 ~/.asoundrc 文件。如果文件不存在,需要手动创建。然后针对相应的声卡加入以下内容:

pcm.!default {
    type hw
    card 2
}

ctl.!default {
    type hw
    card 2
}
注意: 对于华硕U32U系列,似乎应当将pcm与ctl的声卡都设为1。

多数情况下建议使用声卡名代替数字引用。声卡名称容易理解,同时克服了启动顺序问题。因此以下配置对于上面的示例应当是正确的。

pcm.!default {
	type hw
	card Audio
}

ctl.!default {
	type hw           
	card Audio
}

使用aplay获取有效的ALSA声卡名称:

$ aplay -l | awk -F \: '/,/{print $2}' | awk '{print $1}' | uniq
PCH

或者用cat,但可能会返回没用的设备:

$ cat /proc/asound/card*/id
PCH
ThinkPadEC
注意: 这种方法在有多个相同(ALSA)名字的声卡的时候可能会造成问题。

“pcm”选项影响哪个声卡和设备用于音频回放,“ctl”选项则影响alsamixer等控制工具使用哪个声卡。

一旦(重新)启动MPlayer等应用程序,更改应当就会生效。也可以用aplay等命令进行测试。

$ aplay -D default:PCH your_favourite_sound.wav

如果你收到关于asound配置的报错,阅读上游文档查看对于配置文件格式的可能更改。

确认已经加载正确的声音模块

可以假定 udev 会正确地自动探测出声卡。使用以下命令确认:

$ lsmod | grep '^snd' | column -t
snd_hda_codec_hdmi     22378   4
snd_hda_codec_realtek  294191  1
snd_hda_intel          21738   1
snd_hda_codec          73739   3  snd_hda_codec_hdmi,snd_hda_codec_realtek,snd_hda_intel
snd_hwdep              6134    1  snd_hda_codec
snd_pcm                71032   3  snd_hda_codec_hdmi,snd_hda_intel,snd_hda_codec
snd_timer              18992   1  snd_pcm
snd                    55132   9  snd_hda_codec_hdmi,snd_hda_codec_realtek,snd_hda_intel,snd_hda_codec,snd_hwdep,snd_pcm,snd_timer
snd_page_alloc         7017    2  snd_hda_intel,snd_pcm

如果你的输出和上面类似,那就说明声卡已经被正确识别。

注意:udev的171版本开始,默认情况下 OSS 仿真模块(snd_seq_osssnd_pcm_osssnd_mixer_oss)不再自动加载。如有需要,请手动加载

还可以检查一下 /dev/snd/ 目录,看看是否有正确的设备文件:

$ ls -l /dev/snd
total 0
crw-rw----  1 root audio 116,  0 Apr  8 14:17 controlC0
crw-rw----  1 root audio 116, 32 Apr  8 14:17 controlC1
crw-rw----  1 root audio 116, 24 Apr  8 14:17 pcmC0D0c
crw-rw----  1 root audio 116, 16 Apr  8 14:17 pcmC0D0p
crw-rw----  1 root audio 116, 25 Apr  8 14:17 pcmC0D1c
crw-rw----  1 root audio 116, 56 Apr  8 14:17 pcmC1D0c
crw-rw----  1 root audio 116, 48 Apr  8 14:17 pcmC1D0p
crw-rw----  1 root audio 116,  1 Apr  8 14:17 seq
crw-rw----  1 root audio 116, 33 Apr  8 14:17 timer
注意: 在 IRC 或论坛寻求这方面帮助时,如果有需要,请贴出上面几个命令的输出。

如果你的输出跟上面类似,或至少有 controlC0pcmC0D0p,那么声卡模块就已经正常检测并加载了。

如果不是,则声卡模块没有被正确检测。要解决问题,可以尝试手动加载模块:

  • 确定声卡对应的驱动模块:ALSA Soundcard Matrix。这些模块都会有一个“snd-”前缀(例如:snd-via82xx)。
  • 加载模块
  • 检查 /dev/snd 目录中的设备文件(参见上文);或者,检查 alsamixeramixer 的输出是否正确。
  • 修改配置,使 snd-<模块名>snd-pcm-oss 模块开机自动加载

启用 SPDIF 输出

S/PDIF 是一种数字音频介面,常用来连接电脑与数字功放(如有5.1/7.1环绕声的家庭影院)。

注意: 在某些声卡(如Audigy2)上这会禁用模拟声音输出。
  • ~/.xinitrc 或shell的配置文件中加入下面一行:
amixer -c 0 cset name='IEC958 Playback Switch' on

使用以下命令,获取你的声卡的数字输出的名称:

 $ amixer scontrols

系统级均衡器

使用 AlsaEqual(包含界面)

安装 alsaequalAUR。同时安装 lib32-alsaequalAUR[损坏的链接:package not found] 以支持32位应用。

安装后,把下列内容添加到 ALSA 配置文件(/etc/asound.conf):

ctl.equal {
 type equal;
}

pcm.plugequal {
  type equal;
  # Modify the line below if you do not
  #slave.pcm "plughw:0,0";
  #by default we want to play from more sources at time:
  slave.pcm "plug:dmix";
}
#pcm.equal {
  # If you do not want the equalizer to be your
  # default soundcard comment the following
  # line and uncomment the above line. (You can
  # choose it as the output device by addressing
  # it with specific apps,eg mpg123 -a equal 06.Back_In_Black.mp3)
pcm.!default {
  type plug;
  slave.pcm plugequal;
}

之后就可以用该命令调整均衡器了:

$ alsamixer -D equal

需要注意,每个用户的 alsaequal 配置文件都是不同的,位于 ~/.alsaequal.bin。因此,如果想在 mpd 之类的以独立用户身份运行的程序中使用 AlsaEqual,就得像下面这样:

# su mpd -c 'alsamixer -D equal'

或者,在那个用户的主目录下创建符号链接,指向你的 .alsaequal.bin

管理 AlsaEqual 配置

Xyne 的软件仓库alsaequal-mgrAUR 安装 alsaequal-mgr

同上,配置均衡器:

$alsamixer -D equal

如果对效果感到满意,将其命名(如“foo”)并保存该配置:

$alsaequal-mgr save foo

之后可以重新加载“foo”中的配置:

$alsaequal-mgr load foo

不过这样只会恢复~/.alsaequal.bin。之后还需要用alsamixer -D equal更新均衡器设置。

这样,就可以为游戏、电影、不同音乐流派、网络电话等等创建不同的均衡器配置,以便按需切换。

参见项目主页和程序的帮助信息,了解更多设置。

使用 mbeq

注意: 该方法用到了一个 LADSPA 插件,可能导致播放音频时 CPU 占用率偏高。另外该方法主要考虑的是双声道立体声(如耳机)的需要。

如果还没有的话,安装 alsa-pluginsladspaswh-plugins 软件包。

  • ~/.asoundrc/etc/asound.conf 中添加如下内容:
/etc/asound.conf
pcm.eq {
  type ladspa

  # The output from the EQ can either go direct to a hardware device
  # (if you have a hardware mixer, e.g. SBLive/Audigy) or it can go
  # to the software mixer shown here.
  #slave.pcm "plughw:0,0"
  slave.pcm "plug:dmix"

  # Sometimes you may need to specify the path to the plugins,
  # especially if you have just installed them.  Once you have logged
  # out/restarted this should not be necessary, but if you get errors
  # about being unable to find plugins, try uncommenting this.
  #path "/usr/lib/ladspa"

  plugins [
    {
      label mbeq
      id 1197
      input {
        #this setting is here by example, edit to your own taste
        #bands: 50hz, 100hz, 156hz, 220hz, 311hz, 440hz, 622hz, 880hz, 1250hz, 1750hz, 25000hz,
        #50000hz, 10000hz, 20000hz
        controls [ -5 -5 -5 -5 -5 -10 -20 -15 -10 -10 -10 -10 -10 -3 -2 ]
      }
    }
  ]
 }

 # Redirect the default device to go via the EQ - you may want to do
 # this last, once you are sure everything is working.  Otherwise all
 # your audio programs will break/crash if something has gone wrong.

 pcm.!default {
  type plug
  slave.pcm "eq"
 }

 # Redirect the OSS emulation through the EQ too (when programs are running through "aoss")

 pcm.dsp0 {
  type plug
  slave.pcm "eq"
 }

高质量重采样

启用软件混音时,ALSA 会强制把所有音频重采样到相同的频率(如果系统支持,默认是 48000)。默认会尝试使用speexrate转换器进行,如果它不可用的话就会回退到低质量的线性插值[6]

因此如果由于糟糕的重采样导致音质差,只需安装 alsa-plugins 就可能解决问题。

如果想要更高质量的重采样,可将默认采样率转换器改为 speexrate_mediumspeexrate_best。二者的效果都足够好,实际上选哪个并不重要,所以一般来说不值得花费更多CPU资源去使用“best”转换器。

要更改默认转换器,将以下内容加入你的~/.asoundrc/etc/asound.conf

/etc/asound.conf
defaults.pcm.rate_converter "speexrate_medium"
注意: 也可以使用libsamplerate转换器,其速度大约只有speexrate转换器的一半,而质量则并没有高到哪里去。见Talk:Advanced Linux Sound Architecture#On high quality resampling
注意: 也可以使用lavcrate重采样器,其使用ffmpeg,可选的filter sizes 有 lavcrate_faster:4 lavcrate_fast:8 lavcrate:16 lavcrate_high:32 lavcrate_higher:64 最后两个选项分别等同于 Kodi 低/中等质量重采样器
注意: 有些应用(如MPlayer及其分支)默认自己进行重采样,因为一些ALSA驱动在启用重采样时会报告不正确的延迟(这样会导致音画不同步)。所以除非设置它们使用ALSA重采样,否则改变此设置不会有任何效果。

上混和缩混

注意: 由于未找到 upmix 和 downmix 的常用翻译,译者暂时采用字面翻译(上混、缩混)。所谓“上混”,即将声道较少的立体声(如常见的双声道立体声)信号,通过软件或硬件处理,模拟为声道较多的立体声(如5.1环绕立体声)信号。反之即为“缩混”。

上混(upmixing)

播放双声道立体声音源(如音乐)时,需要利用上混才能充分利用 5.1 或 7.1 环绕立体声系统。以前,上混很麻烦,还经常出错;但如今有了插件可以轻松地打理好这一任务。我们使用由 alsa-plugins 软件包提供的 upmix 插件。

然后在ALSA配置文件(/etc/asound.conf~/.asoundrc)中添加如下内容:

pcm.upmix71 {
    type upmix
    slave.pcm "surround71"
    delay 15
    channels 8
}

该范例适用于7.1声道上混。类比该范例,同样能设置5.1或4.0声道上混。

该设置添加了一个新的用于上混的pcm通道。如果希望所有音频源都通过该 pcm 输出,在上述设置后添加如下配置即可:

pcm.!default "plug:upmix71"

插件自动允许多个音频源同时通过它输出,所以将其设为默认实际上是个安全的选择。如果不行,就得像下面这样为上混配置 dmixer:

pcm.dmix6 {
    type asym
    playback.pcm {
        type dmix
        ipc_key 567829
        slave {
            pcm "hw:0,0"
            channels 6
        }
    }
}

并使用 dmix6 而非 surround71。

如果遇到声音卡顿或混乱,考虑增加 buffer_size(比如增加到 32768),或使用高质量重采样

缩混(downmixing)

有时也会用到缩混,比如在只支持双声道立体声的电脑上观看5.1声道的电影时。这一功能由 ALSA 插件 vdownmix 实现(同样在 alsa-plugins 软件包里)。

在配置文件中添加如下内容:

pcm.!surround51 {
    type vdownmix
    slave.pcm "default"
}
pcm.!surround40 {
    type vdownmix
    slave.pcm "default"
}
注意: 这可能还不足以让缩混工作,见 [7] 。因此可能需要添加 pcm.!default "plug:surround51"pcm.!default "plug:surround40"。只能使用一个 vdownmix 插件;如果你有7.1声道音响,需要使用 surround71 来代替上面所述的配置文件。一个让 vdownmixdmix 同时工作的配置文件的示例见 [8]

Dmix

混音使得多个应用可以同时发出声音。多数独立声卡支持硬件混音,在允许的情况下会默认启用。板载集成声卡(如Intel HD Audio)通常不支持硬件混音。在这种声卡上,软件混音由一个称作dmix的ALSA插件完成。若硬件混音不可用,将自动启用该功能。

注意: 对于不支持硬件混音的声卡,会默认启用dmix。对于数字输出(S/PDIF),不会默认启用dmix,需要下面的配置。

要手动启用dmix,可以将以下内容加入你的ALSA配置文件:

pcm.dsp {
    type plug
    slave.pcm "dmix"
}

提示和技巧

禁止启动时自动静音

启动时自动静音模式可以通过amixer配置。例如,要禁用它:

# amixer -c 0 sset "Auto-Mute Mode" Disabled

或者可以通过alsamixer使用图形界面。要保存更改,请使用:

# alsactl store

# alsactl daemon

参考 #ALSA 和 Systemd

USB声卡热插拔

参见 Writing Udev rules for ALSA

同时输出

你可能会希望使用一个用小型插头连接的外置扬声器与内置扬声器同时播放音乐。使用alsamixeramixer解除静音Auto-Mute即可实现:

$ amixer sset "Auto-Mute" unmute

然后解除静音其他需要的项目, 比如 Headphones, Speaker, Bass Speaker...

注意: 如果之后你在耳机连接器(mini-jack)中听到劈啪声,参见 这里.

键盘控制音量

将下列命令映射到你的音量键: XF86AudioRaiseVolumeXF86AudioLowerVolumeXF86AudioMute

增加音量:

amixer set Master 5%+

减小音量:

amixer set Master 5%-

静音/解静音:

amixer set Master toggle

使用snd-aloop的虚拟声音设备

You might want a jack alternative to create a virtual recording or play device in order to mix different sources, using the snd-aloop module:

modprobe snd-aloop

List your new virtual devices using:

aplay -l

now you can for example using ffmpeg:

ffmpeg -f alsa -i hw:1,1,0 -f alsa -i hw:1,1,1 -filter_complex amerge output.mp3

In the hw:R,W,N format R is your virtual card device number, W 1 recording devices 0 for writing, R is your sub device you can use all the virtual devices available and play/stop using applications like mplayer:

mplayer -ao alsa:device=hw=1,0,0 fileA
mplayer -ao alsa:device=hw=1,0,1 fileB 

Another thing you could do with this approach, is using festival to generate a voice into a recording stream using an script like this:

#!/bin/sh
echo "$1"|iconv -f utf-8 -t iso-8859-1| text2wave  > "_tmp_.wav";   
mplayer -ao alsa:device=hw=2,0,0 "_tmp.wav";
rm "_tmp.wav";

排除ALSA故障

获取驱动程序状态

alsa-utils软件包也包含了alsa-info.sh命令,可用于收集关于ALSA驱动程序与用户空间状态的详细信息。

更多信息见ALSA bug tracking

重新配置输入输出端口

alsa-tools软件包包含有hdajackretask工具,(在英特尔HDA声卡上)可用于重新配置声卡输入输出端口;例如,将麦克风插孔转为耳机插孔。

复位编解码器

ALSA驱动程序能够完全重新配置所连接的编解码器(声音系统中实际处理音频流的组件),用法如下:

# echo 1 > /sys/class/sound/card/reconfig

在此之前,必须停止所有使用ALSA驱动程序的进程(如PulseaudioJACK)。

正确检测插入四极3.5毫米(TRRS)插孔的麦克风

在一些现代笔记本上,可能会有一个3.5毫米组合耳机插孔,而不是两个分开的插孔,在默认情况下可能不能被正确检测到。要想让ALSA正确检测到你的3.5毫米插孔的插入状态,可以在/etc/modprobe.d/alsa-base.conf中加入下面一行:

options snd_hda_intel index=0 model=your_model_setting

对于写在your_model_setting处的完整选项列表,见HD-Audio Codec-Specific Models或其位于/usr/lib/modules/$(uname -r)/build/Documentation/sound/hd-audio/models.rst(由linux-docs软件包提供)的源。

在搭载有ALC255的技嘉Aero15 2017 (P65 Model)上经过测试,model设为dell-headset-multi

相关阅读