mirror of
https://github.com/alsa-project/alsa-lib.git
synced 2025-10-29 05:40:25 -04:00
ucm: add initial doxygen documenation
This is an attempt to explain the UCM in a more verbose way. BugLink: https://github.com/alsa-project/alsa-ucm-conf/issues/103 Signed-off-by: Jaroslav Kysela <perex@perex.cz>
This commit is contained in:
parent
ebb8a6c7a1
commit
2623e4bb76
3 changed files with 572 additions and 38 deletions
|
|
@ -1,57 +1,60 @@
|
||||||
/*! \mainpage Index Preamble and License
|
/*! \mainpage Index, Preamble and License
|
||||||
|
|
||||||
\author Jaroslav Kysela <perex@perex.cz>
|
\author Jaroslav Kysela <perex@perex.cz>
|
||||||
\author Abramo Bagnara <abramo@alsa-project.org>
|
\author Abramo Bagnara <abramo@alsa-project.org>
|
||||||
\author Takashi Iwai <tiwai@suse.de>
|
\author Takashi Iwai <tiwai@suse.de>
|
||||||
\author Frank van de Pol <fvdpol@coil.demon.nl>
|
\author Frank van de Pol <fvdpol@coil.demon.nl>
|
||||||
|
|
||||||
<H2>Preface</H2>
|
Preface
|
||||||
<P>The Advanced Linux Sound Architecture (\e ALSA) comes with a kernel
|
-------
|
||||||
|
|
||||||
|
The Advanced Linux Sound Architecture (\e ALSA) comes with a kernel
|
||||||
API and a library API. This document describes the library API and how
|
API and a library API. This document describes the library API and how
|
||||||
it interfaces with the kernel API.</P>
|
it interfaces with the kernel API.
|
||||||
|
|
||||||
<H2>Documentation License</H2>
|
### Documentation License
|
||||||
|
|
||||||
<P>This documentation is free; you can redistribute it without
|
This documentation is free; you can redistribute it without
|
||||||
any restrictions. Modifications or derived work must retain
|
any restrictions. Modifications or derived work must retain
|
||||||
the copyright and list all authors.</P>
|
the copyright and list all authors.
|
||||||
|
|
||||||
<P>This documentation is distributed in the hope that it will be
|
This documentation is distributed in the hope that it will be
|
||||||
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.</P>
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
|
||||||
<H2>API usage</H2>
|
API usage
|
||||||
<P>Application programmers should use the library API rather than the
|
---------
|
||||||
|
|
||||||
|
Application programmers should use the library API rather than the
|
||||||
kernel API. The library offers 100% of the functionality of the kernel API,
|
kernel API. The library offers 100% of the functionality of the kernel API,
|
||||||
but adds major improvements in usability, making the application code simpler
|
but adds major improvements in usability, making the application code simpler
|
||||||
and better looking. In addition, future fixes or compatibility code
|
and better looking. In addition, future fixes or compatibility code
|
||||||
may be placed in the library code instead of the kernel driver.</P>
|
may be placed in the library code instead of the kernel driver.
|
||||||
|
|
||||||
<H2>API links</H2>
|
API links
|
||||||
|
---------
|
||||||
|
|
||||||
<UL>
|
- Page \subpage control explains the primitive controls API.
|
||||||
<LI>Page \ref control explains the primitive controls API.
|
- Page \subpage control_plugins explains the design of primitive control plugins.
|
||||||
<LI>Page \ref control_plugins explains the design of primitive control plugins.
|
- Page \subpage hcontrol explains the high-level primitive controls API.
|
||||||
<LI>Page \ref hcontrol explains the high-level primitive controls API.
|
- Page \subpage mixer explains the mixer controls API.
|
||||||
<LI>Page \ref mixer explains the mixer controls API.
|
- Page \subpage pcm explains the design of the PCM (digital audio) API.
|
||||||
<LI>Page \ref pcm explains the design of the PCM (digital audio) API.
|
- Page \subpage pcm_plugins explains the design of PCM (digital audio) plugins.
|
||||||
<LI>Page \ref pcm_plugins explains the design of PCM (digital audio) plugins.
|
- Page \subpage pcm_external_plugins explains the external PCM plugin SDK.
|
||||||
<LI>Page \ref pcm_external_plugins explains the external PCM plugin SDK.
|
- Page \subpage ctl_external_plugins explains the external control plugin SDK.
|
||||||
<LI>Page \ref ctl_external_plugins explains the external control plugin SDK.
|
- Page \subpage rawmidi explains the design of the RawMidi API.
|
||||||
<LI>Page \ref rawmidi explains the design of the RawMidi API.
|
- Page \subpage timer explains the design of the Timer API.
|
||||||
<LI>Page \ref timer explains the design of the Timer API.
|
- Page \subpage seq explains the design of the Sequencer API.
|
||||||
<LI>Page \ref seq explains the design of the Sequencer API.
|
- Page \subpage ucm explains the use case API.
|
||||||
<LI>Page \ref ucm explains the use case API.
|
- Page \subpage topology explains the DSP topology API.
|
||||||
<LI>Page \ref topology explains the DSP topology API.
|
|
||||||
</UL>
|
|
||||||
|
|
||||||
<H2>Configuration</H2>
|
Configuration
|
||||||
|
-------------
|
||||||
|
|
||||||
<UL>
|
- Page \subpage conf explains the syntax of library configuration.
|
||||||
<LI>Page \ref conf explains the syntax of library configuration files.
|
- Page \subpage confarg explains the run-time argument syntax.
|
||||||
<LI>Page \ref confarg explains the run-time argument syntax.
|
- Page \subpage conffunc explains run-time function definitions and their usage.
|
||||||
<LI>Page \ref conffunc explains run-time function definitions and their usage.
|
- Page \subpage confhooks explains run-time hook definitions and their usage.
|
||||||
<LI>Page \ref confhooks explains run-time hook definitions and their usage.
|
- Page \subpage ucm_conf explains the UCM configuration and their usage.
|
||||||
</UL>
|
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ EXTRA_LTLIBRARIES = libucm.la
|
||||||
libucm_la_SOURCES = utils.c parser.c ucm_cond.c ucm_subs.c ucm_include.c \
|
libucm_la_SOURCES = utils.c parser.c ucm_cond.c ucm_subs.c ucm_include.c \
|
||||||
ucm_regex.c ucm_exec.c main.c
|
ucm_regex.c ucm_exec.c main.c
|
||||||
|
|
||||||
noinst_HEADERS = ucm_local.h
|
noinst_HEADERS = ucm_local.h ucm_confdoc.h
|
||||||
|
|
||||||
all: libucm.la
|
all: libucm.la
|
||||||
|
|
||||||
|
|
|
||||||
531
src/ucm/ucm_confdoc.h
Normal file
531
src/ucm/ucm_confdoc.h
Normal file
|
|
@ -0,0 +1,531 @@
|
||||||
|
/*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
*
|
||||||
|
* Support for the verb/device/modifier core logic and API,
|
||||||
|
* command line tool and file parser was kindly sponsored by
|
||||||
|
* Texas Instruments Inc.
|
||||||
|
* Support for multiple active modifiers and devices,
|
||||||
|
* transition sequences, multiple client access and user defined use
|
||||||
|
* cases was kindly sponsored by Wolfson Microelectronics PLC.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2021 Red Hat Inc.
|
||||||
|
* Authors: Jaroslav Kysela <perex@perex.cz>
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \defgroup ucm_conf Use Case Configuration
|
||||||
|
* The ALSA Use Case Configuration.
|
||||||
|
* See \ref Usecase_conf page for more details.
|
||||||
|
* \{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*! \page Usecase_conf ALSA Use Case Configuration
|
||||||
|
|
||||||
|
The use case configuration files use \ref conf syntax to define the
|
||||||
|
static configuration tree. This tree is evaluated (modified) at runtime
|
||||||
|
according the conditions and dynamic variables in the configuration tree.
|
||||||
|
The result is parsed and exported to the applications using \ref ucm API.
|
||||||
|
|
||||||
|
### Configuration directory and main filename lookup
|
||||||
|
|
||||||
|
The lookup paths are describen in *ucm.conf* file. The configuration
|
||||||
|
structure looks like:
|
||||||
|
|
||||||
|
~~~{.html}
|
||||||
|
UseCasePath.path1 {
|
||||||
|
Directory "conf.virt.d"
|
||||||
|
File "${OpenName}.conf"
|
||||||
|
}
|
||||||
|
UseCasePath.path2 {
|
||||||
|
Directory "external"
|
||||||
|
File "${OpenName}.conf"
|
||||||
|
}
|
||||||
|
~~~
|
||||||
|
|
||||||
|
### UCM main configuration file
|
||||||
|
|
||||||
|
Each sound card has a master sound card file that lists all the supported
|
||||||
|
use case verbs for that sound card. i.e.:
|
||||||
|
|
||||||
|
~~~{.html}
|
||||||
|
# Example master file for blah sound card
|
||||||
|
# By Joe Blogs <joe@bloggs.org>
|
||||||
|
|
||||||
|
# Use Case name for user interface
|
||||||
|
Comment "Nice Abstracted Soundcard"
|
||||||
|
|
||||||
|
# The file is divided into Use case sections. One section per use case verb.
|
||||||
|
|
||||||
|
SectionUseCase."Voice Call" {
|
||||||
|
File "voice_call_blah"
|
||||||
|
Comment "Make a voice phone call."
|
||||||
|
}
|
||||||
|
|
||||||
|
SectionUseCase."HiFi" {
|
||||||
|
File "hifi_blah"
|
||||||
|
Comment "Play and record HiFi quality Music."
|
||||||
|
}
|
||||||
|
|
||||||
|
# Define Value defaults
|
||||||
|
|
||||||
|
ValueDefaults {
|
||||||
|
PlaybackChannels 4
|
||||||
|
CaptureChannels 4
|
||||||
|
}
|
||||||
|
|
||||||
|
# Define boot / initialization sequence
|
||||||
|
# This sequence is skipped, when the soundcard was already configured by system
|
||||||
|
# (alsactl configuration was already created). The purpose is to not alter
|
||||||
|
# ALSA card controls which may be modified by user after initial settings.
|
||||||
|
|
||||||
|
BootSequence [
|
||||||
|
cset "name='My control' on"
|
||||||
|
]
|
||||||
|
|
||||||
|
# Define fixed boot sequence
|
||||||
|
# This sequence is always executed on boot (hotplug).
|
||||||
|
|
||||||
|
FixedBootSequence [
|
||||||
|
cset "name='Something to toggle' toggle"
|
||||||
|
]
|
||||||
|
~~~
|
||||||
|
|
||||||
|
### UCM verb configuration file
|
||||||
|
|
||||||
|
The verb configuration file defines devices, modifier and initialization sequences.
|
||||||
|
It is something like a sound profile.
|
||||||
|
|
||||||
|
~~~{.html}
|
||||||
|
# Example Use case verb section for Voice call blah
|
||||||
|
# By Joe Blogs <joe@blogs.com>
|
||||||
|
|
||||||
|
# verb global section
|
||||||
|
|
||||||
|
SectionVerb {
|
||||||
|
|
||||||
|
# enable and disable sequences are compulsory
|
||||||
|
EnableSequence [
|
||||||
|
cset "name='Master Playback Switch',index=2 0,0"
|
||||||
|
cset "name='Master Playback Volume',index=2 25,25"
|
||||||
|
msleep 50
|
||||||
|
cset "name='Master Playback Switch',index=2 1,1"
|
||||||
|
cset "name='Master Playback Volume',index=2 50,50"
|
||||||
|
]
|
||||||
|
|
||||||
|
DisableSequence [
|
||||||
|
cset "name='Master Playback Switch',index=2 0,0"
|
||||||
|
cset "name='Master Playback Volume',index=2 25,25"
|
||||||
|
msleep 50
|
||||||
|
cset "name='Master Playback Switch',index=2 1,1"
|
||||||
|
cset "name='Master Playback Volume',index=2 50,50"
|
||||||
|
]
|
||||||
|
|
||||||
|
# Optional transition verb
|
||||||
|
TransitionSequence."ToCaseName" [
|
||||||
|
msleep 1
|
||||||
|
]
|
||||||
|
|
||||||
|
# Optional TQ and device values
|
||||||
|
Value {
|
||||||
|
TQ HiFi
|
||||||
|
PlaybackChannels 6
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Each device is described in new section. N devices are allowed
|
||||||
|
|
||||||
|
SectionDevice."Headphones" {
|
||||||
|
|
||||||
|
SupportedDevice [
|
||||||
|
"x"
|
||||||
|
"y"
|
||||||
|
]
|
||||||
|
|
||||||
|
# or (not both)
|
||||||
|
|
||||||
|
ConflictingDevice [
|
||||||
|
"x"
|
||||||
|
"y"
|
||||||
|
]
|
||||||
|
|
||||||
|
EnableSequence [
|
||||||
|
...
|
||||||
|
]
|
||||||
|
|
||||||
|
DisableSequence [
|
||||||
|
...
|
||||||
|
]
|
||||||
|
|
||||||
|
TransitionSequence."ToDevice" [
|
||||||
|
...
|
||||||
|
]
|
||||||
|
|
||||||
|
Value {
|
||||||
|
PlaybackVolume "name='Master Playback Volume',index=2"
|
||||||
|
PlaybackSwitch "name='Master Playback Switch',index=2"
|
||||||
|
PlaybackPCM "hw:${CardId},4"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Each modifier is described in new section. N modifiers are allowed
|
||||||
|
|
||||||
|
SectionModifier."Capture Voice" {
|
||||||
|
Comment "Record voice call"
|
||||||
|
|
||||||
|
SupportedDevice [
|
||||||
|
"x"
|
||||||
|
"y"
|
||||||
|
]
|
||||||
|
|
||||||
|
# or (not both)
|
||||||
|
|
||||||
|
ConflictingDevice [
|
||||||
|
"x"
|
||||||
|
"y"
|
||||||
|
]
|
||||||
|
|
||||||
|
EnableSequence [
|
||||||
|
...
|
||||||
|
]
|
||||||
|
|
||||||
|
DisableSequence [
|
||||||
|
...
|
||||||
|
]
|
||||||
|
|
||||||
|
TransitionSequence."ToModifierName" [
|
||||||
|
...
|
||||||
|
]
|
||||||
|
|
||||||
|
# Optional TQ and ALSA PCMs
|
||||||
|
Value {
|
||||||
|
TQ Voice
|
||||||
|
CapturePCM "hw:${CardId},11"
|
||||||
|
PlaybackVolume "name='Master Playback Volume',index=2"
|
||||||
|
PlaybackSwitch "name='Master Playback Switch',index=2"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
~~~
|
||||||
|
|
||||||
|
### Sequence commands
|
||||||
|
|
||||||
|
Command name | Description
|
||||||
|
---------------|----------------------------------------------
|
||||||
|
cdev ARG | ALSA control device name for snd_ctl_open()
|
||||||
|
cset ARG | ALSA control set - snd_ctl_ascii_elem_id_parse() + snd_ctl_ascii_value_parse()
|
||||||
|
cset-new ARG | Create new ALSA user control element - snd_ctl_ascii_elem_id_parse() + description
|
||||||
|
ctl-remove ARG | Remove ALSA user control element - snd_ctl_ascii_elem_id_parse()
|
||||||
|
sysw ARG | write to sysfs tree
|
||||||
|
usleep ARG | sleep for specified amount of microseconds
|
||||||
|
msleep ARG | sleep for specified amount of milliseconds
|
||||||
|
exec ARG | execute a specific command (without shell - *man execv*)
|
||||||
|
shell ARG | execute a specific command (using shell - *man system*)
|
||||||
|
cfg-save ARG | save LibraryConfig to a file
|
||||||
|
|
||||||
|
~~~{.html}
|
||||||
|
# Examples
|
||||||
|
cset "name='PCM Playback Volue',index=2 99"
|
||||||
|
cset-new "name='Bool2' type=bool,count=2 1,0"
|
||||||
|
cset-new "name='Enum' type=enum,labels='L1;L2;L3' 'L2'"
|
||||||
|
ctl-remove "name='Bool2'"
|
||||||
|
sysw "-/class/sound/ctl-led/speaker/card${CardNumber}/attach:Speaker Channel Switch"
|
||||||
|
usleep 10
|
||||||
|
exec "/bin/echo hello"
|
||||||
|
shell "set"
|
||||||
|
cfg-save "/tmp/test.conf:+pcm"
|
||||||
|
~~~
|
||||||
|
|
||||||
|
### Naming (devices, verbs)
|
||||||
|
|
||||||
|
See the SND_USE_CASE_VERB constains like #SND_USE_CASE_VERB_HIFI for the full list of known verbs.
|
||||||
|
|
||||||
|
See the SND_USE_CASE_DEV constants like #SND_USE_CASE_DEV_SPEAKER for the full list of known devices.
|
||||||
|
If multiple devices with the same name exists, the number suffixes should
|
||||||
|
be added to these names like HDMI1,HDMI2,HDMI3 etc. No number gaps are
|
||||||
|
allowed. The names with numbers must be continuous. It is allowed to put
|
||||||
|
a whitespace between name and index (like 'Line 1') for the better
|
||||||
|
readability. The device names 'Line 1' and 'Line1' are equal for
|
||||||
|
this purpose.
|
||||||
|
|
||||||
|
If EnableSequence/DisableSequence controls independent paths in the hardware
|
||||||
|
it is also recommended to split playback and capture UCM devices and use
|
||||||
|
the number suffixes. Example use case: Use the integrated microphone
|
||||||
|
in the laptop instead the microphone in headphones.
|
||||||
|
|
||||||
|
The preference of the devices is determined by the priority value (higher value = higher priority).
|
||||||
|
|
||||||
|
See the SND_USE_CASE_MOD constants like #SND_USE_CASE_MOD_ECHO_REF for the full list of known modifiers.
|
||||||
|
|
||||||
|
### Boot (alsactl)
|
||||||
|
|
||||||
|
The *FixedBootSequence* is executed at each boot. The *BootSequence* is executed only
|
||||||
|
if the card's configuration is missing. The purpose is to let the users modify the
|
||||||
|
configuration like volumes or switches. The alsactl ensures the persistency (store
|
||||||
|
the state of the controls to the /var tree and loads the previous state in the next
|
||||||
|
boot).
|
||||||
|
|
||||||
|
### Device volume
|
||||||
|
|
||||||
|
It is expected that the applications handle the volume settings. It is not recommended
|
||||||
|
to set the fixed values for the volume settings to the Enable / Disable sequences for
|
||||||
|
verbs or devices, if the device exports the hardware volume (MixerElem or Volume/Switch
|
||||||
|
values). The default volume settings should be set in the *BootSequence*.
|
||||||
|
|
||||||
|
### Dynamic configuration tree
|
||||||
|
|
||||||
|
The evaluation order may look a bit different from the user perspective.
|
||||||
|
At first, the standard alsa-lib configuration tree is parsed. All other
|
||||||
|
layers on top are working with this tree. It may shift / move the configuration
|
||||||
|
blocks from the configuration files as they are placed to the tree internally.
|
||||||
|
|
||||||
|
~~~{.html}
|
||||||
|
Example configuration | Parsed static tree | Identical static tree
|
||||||
|
----------------------------+-------------------------+-------------------------------
|
||||||
|
If.1 { | If { | If.1.True.Define.VAR "A"
|
||||||
|
True.Define.VAR "A" | 1.True.Define.VAR "A" | If.2.True.Define.VAR "C"
|
||||||
|
} | 2.True.Define.VAR "C" | Define.VAR "B"
|
||||||
|
Define.VAR "B" | } |
|
||||||
|
If.2 { | Define.VAR "B" |
|
||||||
|
True.Define.VAR "C" | |
|
||||||
|
} | |
|
||||||
|
~~~
|
||||||
|
|
||||||
|
Even if one or both conditions are evaluated as true, the variable _VAR_ will
|
||||||
|
be evaluated always as **B** because the first _If_ block was before the non-nested
|
||||||
|
_Define_ . The second _If_ block was appended to the first _If_ block (before
|
||||||
|
_Define_ in the configuration tree) in the text configuration parser.
|
||||||
|
|
||||||
|
|
||||||
|
### Syntax
|
||||||
|
|
||||||
|
Unless described, the syntax version 4 is used.
|
||||||
|
|
||||||
|
~~~
|
||||||
|
Syntax 4
|
||||||
|
~~~
|
||||||
|
|
||||||
|
|
||||||
|
### Include
|
||||||
|
|
||||||
|
There are two ways to include other configuration files.
|
||||||
|
|
||||||
|
#### Static include
|
||||||
|
|
||||||
|
The static include is inherited from the standard alsa-lib configuration
|
||||||
|
syntax. It can be placed anywhere in the configuration files. The search
|
||||||
|
path is composed from the root alsa configuration path (usually
|
||||||
|
_/usr/share/alsa_) and _ucm2_ directory.
|
||||||
|
|
||||||
|
~~~{.html}
|
||||||
|
<some/path/file.conf> # include file using the search path
|
||||||
|
</absolute/path/file.conf> # include file using the absolute path
|
||||||
|
~~~
|
||||||
|
|
||||||
|
#### Lazy include
|
||||||
|
|
||||||
|
The lazy include is evaluated at runtime. The root path is the ucm2
|
||||||
|
tree. The absolute include appends the ucm2 absolute path to the
|
||||||
|
specified path. The relative include is relative to the file which
|
||||||
|
contains the _Include_ configuration block.
|
||||||
|
|
||||||
|
~~~{.html}
|
||||||
|
Include.id1.File "/some/path/file.conf" # absolute include (in the ucm2 tree)
|
||||||
|
Include.id2.File "subdir/file.conf" # relative include to the current configuration directory (UseCasePath)
|
||||||
|
~~~
|
||||||
|
|
||||||
|
### Configuration tree evaluation
|
||||||
|
|
||||||
|
The evaluation of the static configuration tree is proceed in
|
||||||
|
the specific order (see table bellow). When the dynamic configuration
|
||||||
|
tree changes, the evaluation sequence is restarted to evaluate
|
||||||
|
all possible changes (new *Define* or *Include* or *If* blocks).
|
||||||
|
|
||||||
|
Evaluation order | Configuration block | Evaluation restart
|
||||||
|
------------------:|---------------------|--------------------
|
||||||
|
1 | Define | No
|
||||||
|
2 | Include | Yes
|
||||||
|
3 | If | Yes
|
||||||
|
|
||||||
|
|
||||||
|
### Substitutions
|
||||||
|
|
||||||
|
The dynamic tree identifiers and assigned values in the configuration tree are
|
||||||
|
substituted. The substitutes strings are in the table bellow.
|
||||||
|
|
||||||
|
Substituted string | Value
|
||||||
|
---------------------|---------------------
|
||||||
|
${OpenName} | Original UCM card name (passed to snd_use_case_mgr_open())
|
||||||
|
${ConfLibDir} | Library top-level configuration directory (e.g. /usr/share/alsa)
|
||||||
|
${ConfTopDir} | Top-level UCM configuration directory (e.g. /usr/share/alsa/ucm2)
|
||||||
|
${ConfDir} | Card's UCM configuration directory (e.g. /usr/share/alsa/ucm2/conf.d/USB-Audio)
|
||||||
|
${ConfName} | Configuration name (e.g. USB-Audio.conf)
|
||||||
|
${CardNumber} | Real ALSA card number (or empty string for the virtual UCM card)
|
||||||
|
${CardId} | ALSA card identifier (see snd_ctl_card_info_get_id())
|
||||||
|
${CardDriver} | ALSA card driver (see snd_ctl_card_info_get_driver())
|
||||||
|
${CardName} | ALSA card name (see snd_ctl_card_info_get_name())
|
||||||
|
${CardLongName} | ALSA card long name (see snd_ctl_card_info_get_longname())
|
||||||
|
${CardComponents} | ALSA card components (see snd_ctl_card_info_get_components())
|
||||||
|
${env:<str>} | Environment variable <str>
|
||||||
|
${sys:<str>} | Contents of sysfs file <str>
|
||||||
|
${var:<str>} | UCM parser variable (set using a _Define_ block)
|
||||||
|
${eval:<str>} | Evaluate expression like *($var+2)/3* [**Syntax 5**]
|
||||||
|
${find-card:<str>} | Find a card - see _Find card substitution_ section
|
||||||
|
${find-device:<str>} | Find a device - see _Find device substitution_ section
|
||||||
|
|
||||||
|
#### Find card substitution
|
||||||
|
|
||||||
|
This substitutions finds the ALSA card and returns the appropriate identifier or
|
||||||
|
the card number (see return argument).
|
||||||
|
|
||||||
|
Usage example:
|
||||||
|
|
||||||
|
~~~{.html}
|
||||||
|
${find-card:field=name,regex='^acp$',return=number}
|
||||||
|
~~~
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
Argument | Description
|
||||||
|
---------------------|-----------------------
|
||||||
|
return | return value type (id, number), id is the default
|
||||||
|
field | field for the lookup (id, driver, name, longname, mixername, components)
|
||||||
|
regex | regex string for the field match
|
||||||
|
|
||||||
|
#### Find device substitution
|
||||||
|
|
||||||
|
Usage example:
|
||||||
|
|
||||||
|
~~~{.html}
|
||||||
|
${find-device:type=pcm,field=name,regex='DMIC'}
|
||||||
|
~~~
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
Argument | Description
|
||||||
|
---------------------|-----------------------
|
||||||
|
type | device type (pcm)
|
||||||
|
stream | stream type (playback, capture), playback is default
|
||||||
|
field | field for the lookup (id, name, subname)
|
||||||
|
regex | regex string for the field match
|
||||||
|
|
||||||
|
|
||||||
|
### Variable defines
|
||||||
|
|
||||||
|
The variables can be defined and altered with the *Define* or *DefineRegex* blocks.
|
||||||
|
The *Define* block looks like:
|
||||||
|
|
||||||
|
~~~{.html}
|
||||||
|
Define {
|
||||||
|
variable1 "a"
|
||||||
|
variable2 "b"
|
||||||
|
}
|
||||||
|
~~~
|
||||||
|
|
||||||
|
The *DefineRegex* allows substring extraction like:
|
||||||
|
|
||||||
|
~~~{.html}
|
||||||
|
DefineRegex.rval {
|
||||||
|
Regex "(hello)|(regex)"
|
||||||
|
String "hello, it's my regex"
|
||||||
|
}
|
||||||
|
~~~
|
||||||
|
|
||||||
|
The result will be stored to variables *rval1* as *hello* and *rval2* as *regex* (every matched
|
||||||
|
substrings are stored to a separate variable with the sequence number postfix.
|
||||||
|
|
||||||
|
Variables can be substituted using the `${var:rval1}` reference for example.
|
||||||
|
|
||||||
|
### Conditions
|
||||||
|
|
||||||
|
The configuration tree evaluation supports the conditions - *If* blocks. Each *If* blocks
|
||||||
|
must define a *Condition* block and *True* or *False* blocks or both. The *True* or *False*
|
||||||
|
blocks will be merged to the parent tree (where the *If* block is defined) when
|
||||||
|
the *Condition* is evaluated.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
~~~{.html}
|
||||||
|
If.uniqueid {
|
||||||
|
Condition {
|
||||||
|
Type String
|
||||||
|
Haystack "abcd"
|
||||||
|
Needle "a"
|
||||||
|
}
|
||||||
|
True {
|
||||||
|
Define.a a
|
||||||
|
define.b b
|
||||||
|
}
|
||||||
|
}
|
||||||
|
~~~
|
||||||
|
|
||||||
|
#### True (Type AlwaysTrue)
|
||||||
|
|
||||||
|
Execute only *True* block. It may be used to change the evaluation order as
|
||||||
|
explained in the *Configuration Tree* paragraph.
|
||||||
|
|
||||||
|
#### String is empty (Type String)
|
||||||
|
|
||||||
|
Field | Description
|
||||||
|
---------------------|-----------------------
|
||||||
|
Empty | string
|
||||||
|
|
||||||
|
#### Strings are equal (Type String)
|
||||||
|
|
||||||
|
Field | Description
|
||||||
|
---------------------|-----------------------
|
||||||
|
String1 | string
|
||||||
|
String2 | substring in string
|
||||||
|
|
||||||
|
#### Substring is present (Type String)
|
||||||
|
|
||||||
|
Field | Description
|
||||||
|
---------------------|-----------------------
|
||||||
|
Haystack | string
|
||||||
|
Needle | substring in string
|
||||||
|
|
||||||
|
#### Regex match (Type RegexMatch)
|
||||||
|
|
||||||
|
Field | Description
|
||||||
|
---------------------|-----------------------
|
||||||
|
String | string
|
||||||
|
Regex | regex expression (extended posix, ignore case)
|
||||||
|
|
||||||
|
#### ALSA control element exists (Type ControlExists)
|
||||||
|
|
||||||
|
Field | Description
|
||||||
|
---------------------|-----------------------
|
||||||
|
Device | ALSA control device (see snd_ctl_open())
|
||||||
|
Control | control in ASCII (parsed using snd_ctl_ascii_elem_id_parse())
|
||||||
|
ControlEnum | value for the enum control (optional)
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
~~~{.html}
|
||||||
|
If.fmic {
|
||||||
|
Condition {
|
||||||
|
Type ControlExists
|
||||||
|
Control "name='Front Mic Playback Switch'"
|
||||||
|
}
|
||||||
|
True {
|
||||||
|
...
|
||||||
|
}
|
||||||
|
}
|
||||||
|
~~~
|
||||||
|
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
\}
|
||||||
|
*/
|
||||||
Loading…
Add table
Add a link
Reference in a new issue