Alsa Use Case Manager(用例管理器)描述如何为某些用例(如 “播放音频”、“通话”)设置 mixer 混频器。它还描述如何修改 mixer 混频器状态以将音频路由到某些输出和输入,以及如何控制这些设备。
这基本上涵盖了 Pulseaudio 中配置 (profile) 所做的相同的事情,除了 UCM 文件更容易编写,并且在不运行 Pulseaudio 的情况下也可以工作。如果声卡的 UCM 配置存在,则 pulseaudio 将忽略内置的配置 (profile),并基于 UCM 文件生成一个配置 (profile)。
官方文档:https://www.alsa-project.org/alsa-doc/alsa-lib/group__ucm__conf.html。
声卡名称
你需要做的第一件事是确定声卡名称,它被用作 UCM 主文件的目录和文件名。你可以使用 alsa-utils 包中的 aplay 命令来确定它:
$ apk add alsa-utils
$ aplay -l
card 0: sun50ia64audio [sun50i-a64-audio], device 0: 1c22c00.dai-sun8i-codec-aif1 sun8i-codec-aif1-0 [1c22c00.dai-sun8i-codec-aif1 sun8i-codec-aif1-0]
Subdevices: 1/1
Subdevice #0: subdevice #0
在这个例子中你需要的名称是方括号中的第一个名称:sun50i-a64-audio
。
第一个用例
下一步是创建一个包含 mixer 混合器可用用例列表的文件。该文件将以上面小节中所述的规则命名:
/usr/share/alsa/ucm2/sun50i-a64-audio/sun50i-a64-audio.conf
Syntax 2
SectionUseCase."HiFi" {
File "HiFi"
Comment "Play high quality music"
}
对于每个用例,都将有一个 SectionUseCase
块。后面直接用引号括起来的名称是 “verb”,它是配置 (profile) 的内部名称。它必须是来自 alsa 的预定义用例之一。目前定义的有如下这些:
- “Inactive”
- “HiFi”
- “HiFi Low Power”
- “Voice”
- “Voice Low Power”
- “Voice Call”
- “Voice Call IP”
- “FM Analog Radio”
- “FM Digital Radio”
要创建的最重要的配置 (profile) 是 HiFi,它是声卡的主音频播放配置 (profile)。对于其它一些配置 (profile),Alsa 并没有明确定义它们的实际用途。
配置 (profile) 的第一个设置是 File
行。这定义了包含该用例的确切 mixer 混合器配置的文件的文件名。
这个例子中的第二个设置是 Comment
。它用作 alsaucm 工具和 Pulseaudio 中的显示名称。它可以自由定义。
用例定义
最复杂的部分是需要创建的 HiFi
文件的实际内容。该文件基本上是启用/禁用 mixer 混频器的脚本和从一个输入/输出移动到另一个输入/输出的命令的集合。
这是一个用例文件的最小示例。
/usr/share/alsa/ucm2/sun50i-a64-audio/HiFi
SectionVerb {
EnableSequence [
cset "name='Headphone Playback Switch' off"
cset "name='Headphone Source Playback Route' DAC"
cset "name='Headphone Playback Volume' 50%"
]
DisableSequence [
]
Value {
PlaybackPCM "hw:${CardId},0"
CapturePCM "hw:${CardId},0"
}
}
SectionVerb
块定义了启用/禁用这个用例需要运行的命令。这主要是用来使整个 mixer 混频器在启动时处于已知状态,所以在这里为 mixer 混频器中的所有 controls 控件设置一个值可能是个好主意。
本节中的命令均为 cset
命令。这些命令对应于你常常通过 alsa-utils 包中的 amixer
工具使用的命令。第一个命令当直接通过 amixer 运行时做这些事情:
$ amixer cset name='Headphone Playback Switch' off
numid=36,iface=MIXER,name='Headphone Playback Switch'
; type=BOOLEAN,access=rw------,values=2
; values=on,on
要获得你可以设置的所有 controls 控件的列表,你也可以使用如下的 amixer 命令:
$ amixer controls
numid=35,iface=MIXER,name='Headphone Source Playback Route'
numid=36,iface=MIXER,name='Headphone Playback Switch'
numid=17,iface=MIXER,name='Headphone Playback Volume'
... a lot more lines here ...
这些应该很容易就可以与你在 alsamixer 中看到的 controls 控件关联起来。Controls 控件遵循标准的命名方案。alsamixer 的播放页上设备的音量滑块称为 $name Playback Volume
,采集页上相同的 control 控件称为 $name Capture Volume
。播放音量滑块下面的静音按钮称为 $name Playback Switch
,采集页上的启用开关称为 $name Capture Switch
。Controls 控件中没有音量滑块但有文本选择的控件名称为 $name Playback Route
。
调试 UCM 配置
重新加载 UCM 配置
alsaucm reload
重新加载配置,但如果你正在使用 PulseAudio,你还需要以某种方式重启 PulseAudio。要方便地重新加载 alsaucm 和 PulseAudio,你可以运行alsaucm reload && killall -9 pulseaudio
。
监视 ALSA 事件
alsactl monitor
允许你监视 ALSA 事件,特别是插孔检测。如果你想要在插孔插入或移除时修改 ALSA 设置,则日志中的事件名称必须与 UCM 配置 JackControl
匹配。
使用 plain ALSA 来查找控件
使用 ALSA UCM 寻找正确的控件是一件很痛苦的事情,但为了让你的生活更轻松:
- 禁用 PulseAudio 或 PipeWire,以便 ALSA UCM 根本不活动。
- 使用
amixer -c $CARD cset iface=MIXER,name='$CONTROL' '$VALUE'
编写一个简单的脚本。 - 执行脚本来设置混音器。
- 通过
aplay -D plughw:$CARD,$DEVICE /usr/share/sounds/alsa/Front_*.wav
测试你的声音。
重复此操作,直到找到混音器的工作列表,以将音频播放到所需的输出设备。还要确保混音器列表足以在重新启动后直接工作。一旦你弄清楚了它们,你就可以转换到 ALSA UCM 配置,这样你就可以确保混音器至少是正确的,而不受 ALSA UCM 或 PulseAudio/PipeWire 的影响。
控件列表
amixer
可以为你提供有关可用控件的大量信息:
amixer -c $CARD scontrols
amixer -c $CARD scontents
TinyALSA 可以为你提供更具可读性的版本。TinyALSA 不在 repos 存储库中,但可以按如下方式编译:
git clone https://github.com/tinyalsa/tinyalsa
apk add alpine-sdk linux-headers
make
编译 TinyALSA 之后,该工具在 utils
中,你可能需要 tinymixer
。
检查控件是否被实际调用
有时你可能想知道你在 ALSA UCM 部分中定义的控件是否被调用。ALSA UCM 允许使用 shell
和 exec
命令执行任意命令。你可以添加
shell "/bin/echo 'My Control was called in X' >> /tmp/alsa-ucm.txt"
来调试你的序列。输出将出现在 /tmp/alsa-ucm.txt
文件中。
关键字
ConflictingDevice
:表示与其它设备冲突。例如:听筒和耳机在由相同编解码器驱动时可能彼此不兼容。EnableSequence
:指定 amixer 命令以启用设备或 verb。DisableSequence
:指定 amixer 命令以禁用设备或 verb。TransitionSection."$SECTIONDEVICE"
:执行从一个设备到另一个设备的命令。BootSequence
:当声卡配置尚不可用时仅执行一次的命令,对于设置初始音量很有用。FixedBootSequence
:每次启动时执行的命令,对于取消某些事情的静音很有用。
大多数关键字都记录在官方文档中:https://www.alsa-project.org/alsa-doc/alsa-lib/group__ucm__conf.html。
声卡的配置:
SectionVerb {
Value {
// Values to config this card, example for HiFi profile:
TQ "HiFi"
}
EnableSequence [
// mixer control to be set when the card is initialized
]
DisableSequence [
// mixer control to be set when the card is destroyed
]
}
设备的配置:
SectionDevice."Speaker" { // The node name.
Value {
// Values to config this node
}
EnableSequence [
// mixer control to be set when this node is selected
]
DisableSequence [
// mixer control to be set when this node is unselected
]
}
原文。
Done.