Alsa UCM

Alsa Use Case Manager describes how to set up the mixer for certain usecases (like "playing audio", "calling"). It also describes how to modify the mixer state to route audio to certain outputs and inputs and how to control those devices.

This basically covers the same things profiles do in Pulseaudio except that UCM files are easier to write and also work without Pulseaudio running. If an UCM configuration is present for a card then pulseaudio will ignore the built-in profiles and generate a profile based on the UCM files.

Official documentation: https://www.alsa-project.org/alsa-doc/alsa-lib/group__ucm__conf.html

Card name
The first thing you need is the card name, this is used as the directory and filename for the UCM main file. You can find it using the aplay command from the alsa-utils package

In this case the name you need is the first name in square brackets:

The first usecase
The next step is creating a file that contains the list of available usecases for the mixer. This file will be named after the mixer name from the section above:

For every usecase there will be a  block. The name in quotes directly after that is the "verb", which is the internal name of the profile. This has to be one of the predefined usecases from alsa. The ones that are currently defined are:


 * "Inactive"
 * "HiFi"
 * "HiFi Low Power"
 * "Voice"
 * "Voice Low Power"
 * "Voice Call"
 * "Voice Call IP"
 * "FM Analog Radio"
 * "FM Digital Radio"

The most important profile to create is the HiFi one, that's the main audio playback profile for the card. For the other profiles the actual use of them isn't very well defined by Alsa.

The first setting for the profile is the  line. This defines the filename for the file that contains the exact mixer configuration for that usecase.

The second setting in this example is the. This is used as the display name in the alsaucm tool and in Pulseaudio. This can be freely defined.

The Use case definition
The most complicated part is the actual contents of the  file that needs to be created. This file is basically a collection of scripts to enable/disable the mixer and commands to move from one input/output to another.

This is a minimal example of a usecase file.

The  block defines what commands need to be run to enable or disable this usecase. This is mostly used to bring the whole mixer in a known state on start so it's probably a good idea to set a value for all controls in the mixer here.

The commands in the sections in this section are all   commands. These commands correspond to commands you'd normally use with the  tool from the alsa-utils package. The first command does this when run with amixer:

To get a list of all the controls you can set you can also use the amixer command:

These should be fairly easy to correlate with the controls you see in alsamixer. The controls follow a standard naming scheme. The volume sliders for devices on the Playback page of alsamixer are called, the same control on the Capture page is called. The mute button underneath the playback volume sliders are called  and the enable switches on the Capture page are called. Controls that don't have a volume slider in it but a text selection the name is



Reload UCM configs
reload the configuration, but if you're using PulseAudio you also need to restart PulseAudio somehow. To both reload alsaucm and PulseAudio conveniently, you can run.

Monitor ALSA events
allows you to monitor the ALSA events, especially for jack detection. The event name in the log must match the UCM config if you want to change ALSA settings when a jack is plugged in or removed.

Using plain ALSA for finding controls
Finding the right controls with ALSA UCM is a pain, to make your life easier:


 * 1) Disable PulseAudio or PipeWire so ALSA UCM is not active at all.
 * 2) Write a simple script with
 * 3) Execute the script to set your mixers
 * 4) Test your sound with

Repeat this until you figured out a working list of mixers to play audio to the output device you want. Also make sure that the list of mixers is sufficient to work directly after a reboot. Once you have them figured out, you can transfer to ALSA UCM configs, this way you're sure that the mixers are at least correct without influence from ALSA UCM or PulseAudio/PipeWire.

List of controls
can provide you a lot of information about the available controls with:



TinyALSA can provide you a more readable version of them. TinyALSA is not in the repos but can be compiled as followed:



After compiling TinyALSA, the tools are in, you probably might need

Checking if a control is actually called
Sometimes you may be wondering if your controls are called you defined in your ALSA UCM sections. ALSA UCM allows executing of arbitrary commands with  and   commands. You can add

shell "/bin/echo 'My Control was called in X' >> /tmp/alsa-ucm.txt"

to debug your sequences. The output will appear in

Keywords

 * : indicates conflicts with other devices. For example: earpiece and headphones may be incompatible with each other when they are driven by the same codec.
 * : specifies the amixer commands to enable the device or verb.
 * : specifies the amixer commands to disable the device or verb.
 * : commands to execute to go from a device to an other device.
 * : commands to execute only once when the card configuration is not available yet, useful to set the initial volume.
 * : commands to execute at each boot, useful to unmute certain things.

Most keywords are documented in the official docs: https://www.alsa-project.org/alsa-doc/alsa-lib/group__ucm__conf.html

Configuration of a card:

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 ] }

Configuration of a device:

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 ] }