Current File : //proc/self/root/kunden/usr/share/doc/alsa-lib-devel/doxygen/html/group__ucm__conf.html |
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=9"/>
<meta name="generator" content="Doxygen 1.9.1"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<title>ALSA project - the C library reference: Use Case Configuration</title>
<link href="tabs.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="dynsections.js"></script>
<link href="search/search.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="search/searchdata.js"></script>
<script type="text/javascript" src="search/search.js"></script>
<link href="doxygen.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
<div id="titlearea">
<table cellspacing="0" cellpadding="0">
<tbody>
<tr style="height: 56px;">
<td id="projectalign" style="padding-left: 0.5em;">
<div id="projectname">ALSA project - the C library reference
</div>
</td>
</tr>
</tbody>
</table>
</div>
<!-- end header part -->
<!-- Generated by Doxygen 1.9.1 -->
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */
var searchBox = new SearchBox("searchBox", "search",false,'Search','.html');
/* @license-end */
</script>
<script type="text/javascript" src="menudata.js"></script>
<script type="text/javascript" src="menu.js"></script>
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */
$(function() {
initMenu('',true,false,'search.php','Search');
$(document).ready(function() { init_search(); });
});
/* @license-end */</script>
<div id="main-nav"></div>
</div><!-- top -->
<!-- window showing the filter options -->
<div id="MSearchSelectWindow"
onmouseover="return searchBox.OnSearchSelectShow()"
onmouseout="return searchBox.OnSearchSelectHide()"
onkeydown="return searchBox.OnSearchSelectKey(event)">
</div>
<!-- iframe showing the search results (closed by default) -->
<div id="MSearchResultsWindow">
<iframe src="javascript:void(0)" frameborder="0"
name="MSearchResults" id="MSearchResults">
</iframe>
</div>
<div class="header">
<div class="headertitle">
<div class="title">Use Case Configuration</div> </div>
</div><!--header-->
<div class="contents">
<p>The ALSA Use Case Configuration. See <a class="el" href="group__ucm__conf.html">ALSA Use Case Configuration</a> page for more details. </p>
<h3><a id="Usecase_conf"></a>ALSA Use Case Configuration</h3><div class="textblock">The use case configuration files use <a class="el" href="conf.html">Configuration files</a> 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 <a class="el" href="group__ucm.html">Use Case Interface</a> API.<h3><a class="anchor" id="autotoc_md5"></a>
Configuration directory and main filename lookup</h3>
<p>The lookup paths are describen in <em>ucm.conf</em> file. The configuration structure looks like:</p>
<div class="fragment"><div class="line">UseCasePath.path1 {</div>
<div class="line"> Directory "conf.virt.d"</div>
<div class="line"> File "${OpenName}.conf"</div>
<div class="line">}</div>
<div class="line">UseCasePath.path2 {</div>
<div class="line"> Directory "external"</div>
<div class="line"> File "${OpenName}.conf"</div>
<div class="line">}</div>
</div><!-- fragment --><h3><a class="anchor" id="autotoc_md6"></a>
UCM main configuration file</h3>
<p>Each sound card has a master sound card file that lists all the supported use case verbs for that sound card. i.e.:</p>
<div class="fragment"><div class="line"># Example master file for blah sound card</div>
<div class="line"># By Joe Blogs <joe@bloggs.org></div>
<div class="line"> </div>
<div class="line">Syntax 7</div>
<div class="line"> </div>
<div class="line"># Use Case name for user interface</div>
<div class="line">Comment "Nice Abstracted Soundcard"</div>
<div class="line"> </div>
<div class="line"># The file is divided into Use case sections. One section per use case verb.</div>
<div class="line"> </div>
<div class="line">SectionUseCase."Voice Call" {</div>
<div class="line"> File "voice_call_blah"</div>
<div class="line"> Comment "Make a voice phone call."</div>
<div class="line">}</div>
<div class="line"> </div>
<div class="line">SectionUseCase."HiFi" {</div>
<div class="line"> File "hifi_blah"</div>
<div class="line"> Comment "Play and record HiFi quality Music."</div>
<div class="line">}</div>
<div class="line"> </div>
<div class="line"># Define Value defaults</div>
<div class="line"> </div>
<div class="line">ValueDefaults {</div>
<div class="line"> PlaybackChannels 4</div>
<div class="line"> CaptureChannels 4</div>
<div class="line">}</div>
<div class="line"> </div>
<div class="line"># Define boot / initialization sequence</div>
<div class="line"># This sequence is skipped, when the soundcard was already configured by system</div>
<div class="line"># (alsactl configuration was already created). The purpose is to not alter</div>
<div class="line"># ALSA card controls which may be modified by user after initial settings.</div>
<div class="line"> </div>
<div class="line">BootSequence [</div>
<div class="line"> cset "name='Master Playback Switch',index=2 0,0"</div>
<div class="line"> cset "name='Master Playback Volume',index=2 25,25"</div>
<div class="line"> msleep 50</div>
<div class="line"> cset "name='Master Playback Switch',index=2 1,1"</div>
<div class="line"> cset "name='Master Playback Volume',index=2 50,50"</div>
<div class="line">]</div>
<div class="line"> </div>
<div class="line"># Define fixed boot sequence</div>
<div class="line"># This sequence is always executed on boot (hotplug).</div>
<div class="line"> </div>
<div class="line">FixedBootSequence [</div>
<div class="line"> cset "name='Something to toggle' toggle"</div>
<div class="line">]</div>
</div><!-- fragment --><h3><a class="anchor" id="autotoc_md7"></a>
UCM verb configuration file</h3>
<p>The verb configuration file defines devices, modifier and initialization sequences. It is something like a sound profile.</p>
<div class="fragment"><div class="line"># Example Use case verb section for Voice call blah</div>
<div class="line"># By Joe Blogs <joe@blogs.com></div>
<div class="line"> </div>
<div class="line"># verb global section</div>
<div class="line"> </div>
<div class="line">SectionVerb {</div>
<div class="line"> </div>
<div class="line"> # enable and disable sequences are compulsory</div>
<div class="line"> EnableSequence [</div>
<div class="line"> disdevall "" # run DisableSequence for all devices</div>
<div class="line"> ]</div>
<div class="line"> </div>
<div class="line"> DisableSequence [</div>
<div class="line"> cset "name='Power Save' on"</div>
<div class="line"> ]</div>
<div class="line"> </div>
<div class="line"> # Optional transition verb</div>
<div class="line"> TransitionSequence."ToCaseName" [</div>
<div class="line"> disdevall "" # run DisableSequence for all devices</div>
<div class="line"> msleep 1</div>
<div class="line"> ]</div>
<div class="line"> </div>
<div class="line"> # Optional TQ and device values</div>
<div class="line"> Value {</div>
<div class="line"> TQ HiFi</div>
<div class="line"> PlaybackChannels 6</div>
<div class="line"> }</div>
<div class="line">}</div>
<div class="line"> </div>
<div class="line"># Each device is described in new section. N devices are allowed</div>
<div class="line"> </div>
<div class="line">SectionDevice."Headphones" {</div>
<div class="line"> </div>
<div class="line"> SupportedDevice [</div>
<div class="line"> "x"</div>
<div class="line"> "y"</div>
<div class="line"> ]</div>
<div class="line"> </div>
<div class="line"> # or (not both)</div>
<div class="line"> </div>
<div class="line"> ConflictingDevice [</div>
<div class="line"> "x"</div>
<div class="line"> "y"</div>
<div class="line"> ]</div>
<div class="line"> </div>
<div class="line"> EnableSequence [</div>
<div class="line"> ...</div>
<div class="line"> ]</div>
<div class="line"> </div>
<div class="line"> DisableSequence [</div>
<div class="line"> ...</div>
<div class="line"> ]</div>
<div class="line"> </div>
<div class="line"> TransitionSequence."ToDevice" [</div>
<div class="line"> ...</div>
<div class="line"> ]</div>
<div class="line"> </div>
<div class="line"> Value {</div>
<div class="line"> PlaybackVolume "name='Master Playback Volume',index=2"</div>
<div class="line"> PlaybackSwitch "name='Master Playback Switch',index=2"</div>
<div class="line"> PlaybackPCM "hw:${CardId},4"</div>
<div class="line"> }</div>
<div class="line">}</div>
<div class="line"> </div>
<div class="line"># Each modifier is described in new section. N modifiers are allowed</div>
<div class="line"> </div>
<div class="line">SectionModifier."Capture Voice" {</div>
<div class="line"> Comment "Record voice call"</div>
<div class="line"> </div>
<div class="line"> SupportedDevice [</div>
<div class="line"> "x"</div>
<div class="line"> "y"</div>
<div class="line"> ]</div>
<div class="line"> </div>
<div class="line"> # or (not both)</div>
<div class="line"> </div>
<div class="line"> ConflictingDevice [</div>
<div class="line"> "x"</div>
<div class="line"> "y"</div>
<div class="line"> ]</div>
<div class="line"> </div>
<div class="line"> EnableSequence [</div>
<div class="line"> ...</div>
<div class="line"> ]</div>
<div class="line"> </div>
<div class="line"> DisableSequence [</div>
<div class="line"> ...</div>
<div class="line"> ]</div>
<div class="line"> </div>
<div class="line"> TransitionSequence."ToModifierName" [</div>
<div class="line"> ...</div>
<div class="line"> ]</div>
<div class="line"> </div>
<div class="line"> # Optional TQ and ALSA PCMs</div>
<div class="line"> Value {</div>
<div class="line"> TQ Voice</div>
<div class="line"> CapturePCM "hw:${CardId},11"</div>
<div class="line"> PlaybackMixerElem "Master"</div>
<div class="line"> PlaybackVolume "name='Master Playback Volume',index=2"</div>
<div class="line"> PlaybackSwitch "name='Master Playback Switch',index=2"</div>
<div class="line"> }</div>
<div class="line">}</div>
</div><!-- fragment --><h3><a class="anchor" id="autotoc_md8"></a>
Sequence graphs</h3>
<div class="image">
<object type="image/svg+xml" data="ucm-seq-verb.svg" style="pointer-events: none;"></object>
</div>
<div class="image">
<object type="image/svg+xml" data="ucm-seq-device.svg" style="pointer-events: none;"></object>
</div>
<h3><a class="anchor" id="autotoc_md9"></a>
Sequence commands</h3>
<table class="markdownTable">
<tr class="markdownTableHead">
<th class="markdownTableHeadNone">Command name </th><th class="markdownTableHeadNone">Description </th></tr>
<tr class="markdownTableRowOdd">
<td class="markdownTableBodyNone">enadev2 ARG </td><td class="markdownTableBodyNone">execute device enable sequence </td></tr>
<tr class="markdownTableRowEven">
<td class="markdownTableBodyNone">disdev2 ARG </td><td class="markdownTableBodyNone">execute device disable sequence </td></tr>
<tr class="markdownTableRowOdd">
<td class="markdownTableBodyNone">disdevall "" </td><td class="markdownTableBodyNone">execute device disable sequence for all devices in verb </td></tr>
<tr class="markdownTableRowEven">
<td class="markdownTableBodyNone">cdev ARG </td><td class="markdownTableBodyNone">ALSA control device name for <a class="el" href="group___control.html#ga58537f5b74c9c1f51699f9908a0d7f56" title="Opens a sound card.">snd_ctl_open()</a> </td></tr>
<tr class="markdownTableRowOdd">
<td class="markdownTableBodyNone">cset ARG </td><td class="markdownTableBodyNone">ALSA control set - <a class="el" href="group___control.html#ga2f530217bd896e3c0498b3e46624977a" title="parse ASCII string as CTL element identifier">snd_ctl_ascii_elem_id_parse()</a> + <a class="el" href="group___control.html#ga05d994f242e8a524a94ea482689fa2c0" title="parse ASCII string as CTL element value">snd_ctl_ascii_value_parse()</a> </td></tr>
<tr class="markdownTableRowEven">
<td class="markdownTableBodyNone">cset-new ARG </td><td class="markdownTableBodyNone">Create new ALSA user control element - <a class="el" href="group___control.html#ga2f530217bd896e3c0498b3e46624977a" title="parse ASCII string as CTL element identifier">snd_ctl_ascii_elem_id_parse()</a> + description </td></tr>
<tr class="markdownTableRowOdd">
<td class="markdownTableBodyNone">ctl-remove ARG </td><td class="markdownTableBodyNone">Remove ALSA user control element - <a class="el" href="group___control.html#ga2f530217bd896e3c0498b3e46624977a" title="parse ASCII string as CTL element identifier">snd_ctl_ascii_elem_id_parse()</a> </td></tr>
<tr class="markdownTableRowEven">
<td class="markdownTableBodyNone">sysw ARG </td><td class="markdownTableBodyNone">write to sysfs tree </td></tr>
<tr class="markdownTableRowOdd">
<td class="markdownTableBodyNone">usleep ARG </td><td class="markdownTableBodyNone">sleep for specified amount of microseconds </td></tr>
<tr class="markdownTableRowEven">
<td class="markdownTableBodyNone">msleep ARG </td><td class="markdownTableBodyNone">sleep for specified amount of milliseconds </td></tr>
<tr class="markdownTableRowOdd">
<td class="markdownTableBodyNone">exec ARG </td><td class="markdownTableBodyNone">execute a specific command (without shell - <em>man execv</em>) </td></tr>
<tr class="markdownTableRowEven">
<td class="markdownTableBodyNone">shell ARG </td><td class="markdownTableBodyNone">execute a specific command (using shell - <em>man system</em>) </td></tr>
<tr class="markdownTableRowOdd">
<td class="markdownTableBodyNone">cfg-save ARG </td><td class="markdownTableBodyNone">save LibraryConfig to a file </td></tr>
</table>
<div class="fragment"><div class="line"># Examples</div>
<div class="line">cset "name='PCM Playback Volue',index=2 99"</div>
<div class="line">cset-new "name='Bool2' type=bool,count=2 1,0"</div>
<div class="line">cset-new "name='Enum' type=enum,labels='L1;L2;L3' 'L2'"</div>
<div class="line">ctl-remove "name='Bool2'"</div>
<div class="line">sysw "-/class/sound/ctl-led/speaker/card${CardNumber}/attach:Speaker Channel Switch"</div>
<div class="line">usleep 10</div>
<div class="line">exec "/bin/echo hello"</div>
<div class="line">shell "set"</div>
<div class="line">cfg-save "/tmp/test.conf:+pcm"</div>
</div><!-- fragment --><h3><a class="anchor" id="autotoc_md10"></a>
Naming (devices, verbs)</h3>
<p>See the SND_USE_CASE_VERB constains like <a class="el" href="group__ucm.html#ga71b24a1fcc4ce2cee555520ca546b348">SND_USE_CASE_VERB_HIFI</a> for the full list of known verbs.</p>
<p>See the SND_USE_CASE_DEV constants like <a class="el" href="group__ucm.html#ga515b2956d58485b27fb982965d067c55">SND_USE_CASE_DEV_SPEAKER</a> 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.</p>
<p>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.</p>
<p>The preference of the devices is determined by the priority value (higher value = higher priority).</p>
<p>See the SND_USE_CASE_MOD constants like <a class="el" href="group__ucm.html#gae2a230a913142c17f30d7dc2ae416866">SND_USE_CASE_MOD_ECHO_REF</a> for the full list of known modifiers.</p>
<h3><a class="anchor" id="autotoc_md11"></a>
Boot (alsactl)</h3>
<p>The <em>FixedBootSequence</em> is executed at each boot. The <em>BootSequence</em> 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).</p>
<div class="image">
<object type="image/svg+xml" data="ucm-seq-boot.svg" style="pointer-events: none;"></object>
</div>
<h3><a class="anchor" id="autotoc_md12"></a>
Device volume</h3>
<p>It is expected that the applications handle the volume settings. It is not recommended to set the fixed values for the volume settings in 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 <em>BootSequence</em>. The purpose for this scheme is to allow users to override defaults using the alsactl sound card state management.</p>
<p>Checklist:</p>
<ol type="1">
<li>Set default volume in BootSequence</li>
<li>Verb's EnableSequence should ensure that all devices are turned off (mixer paths) to avoid simultaneous device use - the previous state is unknown (see <em>disdevall</em> and <em>disdev2</em> commands or create a new custom command sequence)</li>
</ol>
<div class="image">
<object type="image/svg+xml" data="ucm-volume.svg" style="pointer-events: none;"></object>
</div>
<h3><a class="anchor" id="autotoc_md13"></a>
Dynamic configuration tree</h3>
<p>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.</p>
<div class="fragment"><div class="line">Example configuration | Parsed static tree | Identical static tree</div>
<div class="line">----------------------------+-------------------------+-------------------------------</div>
<div class="line">If.1 { | If { | If.1.True.Define.VAR "A"</div>
<div class="line"> True.Define.VAR "A" | 1.True.Define.VAR "A" | If.2.True.Define.VAR "C"</div>
<div class="line">} | 2.True.Define.VAR "C" | Define.VAR "B"</div>
<div class="line">Define.VAR "B" | } |</div>
<div class="line">If.2 { | Define.VAR "B" |</div>
<div class="line"> True.Define.VAR "C" | |</div>
<div class="line">} | |</div>
</div><!-- fragment --><p>Even if one or both conditions are evaluated as true, the variable <em>VAR</em> will be evaluated always as <b>B</b> because the first <em>If</em> block was before the non-nested <em>Define</em> . The second <em>If</em> block was appended to the first <em>If</em> block (before <em>Define</em> in the configuration tree) in the text configuration parser.</p>
<h3><a class="anchor" id="autotoc_md14"></a>
Syntax</h3>
<p>Unless described, the syntax version 4 is used.</p>
<div class="fragment"><div class="line">Syntax 4</div>
</div><!-- fragment --><h3><a class="anchor" id="autotoc_md15"></a>
Include</h3>
<p>There are two ways to include other configuration files.</p>
<h4><a class="anchor" id="autotoc_md16"></a>
Static include</h4>
<p>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 <em>ucm2</em> directory.</p>
<div class="fragment"><div class="line"><some/path/file.conf> # include file using the search path</div>
<div class="line"></absolute/path/file.conf> # include file using the absolute path</div>
</div><!-- fragment --><h4><a class="anchor" id="autotoc_md17"></a>
Lazy include</h4>
<p>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 <em>Include</em> configuration block.</p>
<div class="fragment"><div class="line">Include.id1.File "/some/path/file.conf" # absolute include (in the ucm2 tree)</div>
<div class="line">Include.id2.File "subdir/file.conf" # relative include to the current configuration directory (UseCasePath)</div>
</div><!-- fragment --><h3><a class="anchor" id="autotoc_md18"></a>
Configuration tree evaluation</h3>
<p>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 <em>Define</em> or <em>Include</em> or <em>If</em> blocks).</p>
<table class="markdownTable">
<tr class="markdownTableHead">
<th class="markdownTableHeadRight">Evaluation order </th><th class="markdownTableHeadNone">Configuration block </th><th class="markdownTableHeadNone">Evaluation restart </th></tr>
<tr class="markdownTableRowOdd">
<td class="markdownTableBodyRight">1 </td><td class="markdownTableBodyNone">Define </td><td class="markdownTableBodyNone">No </td></tr>
<tr class="markdownTableRowEven">
<td class="markdownTableBodyRight">2 </td><td class="markdownTableBodyNone">Include </td><td class="markdownTableBodyNone">Yes </td></tr>
<tr class="markdownTableRowOdd">
<td class="markdownTableBodyRight">3 </td><td class="markdownTableBodyNone">Variant </td><td class="markdownTableBodyNone">Yes </td></tr>
<tr class="markdownTableRowEven">
<td class="markdownTableBodyRight">4 </td><td class="markdownTableBodyNone">Macro </td><td class="markdownTableBodyNone">Yes </td></tr>
<tr class="markdownTableRowOdd">
<td class="markdownTableBodyRight">5 </td><td class="markdownTableBodyNone">If </td><td class="markdownTableBodyNone">Yes </td></tr>
</table>
<h3><a class="anchor" id="autotoc_md19"></a>
Substitutions</h3>
<p>The dynamic tree identifiers and assigned values in the configuration tree are substituted. The substitutes strings are in the table bellow.</p>
<table class="markdownTable">
<tr class="markdownTableHead">
<th class="markdownTableHeadNone">Substituted string </th><th class="markdownTableHeadNone">Value </th></tr>
<tr class="markdownTableRowOdd">
<td class="markdownTableBodyNone">${OpenName} </td><td class="markdownTableBodyNone">Original UCM card name (passed to <a class="el" href="group__ucm.html#ga74f0ef0116590fe8eec1edeaf1d88847" title="Open and initialise use case core for sound card.">snd_use_case_mgr_open()</a>) </td></tr>
<tr class="markdownTableRowEven">
<td class="markdownTableBodyNone">${ConfLibDir} </td><td class="markdownTableBodyNone">Library top-level configuration directory (e.g. /usr/share/alsa) </td></tr>
<tr class="markdownTableRowOdd">
<td class="markdownTableBodyNone">${ConfTopDir} </td><td class="markdownTableBodyNone">Top-level UCM configuration directory (e.g. /usr/share/alsa/ucm2) </td></tr>
<tr class="markdownTableRowEven">
<td class="markdownTableBodyNone">${ConfDir} </td><td class="markdownTableBodyNone">Card's UCM configuration directory (e.g. /usr/share/alsa/ucm2/conf.d/USB-Audio) </td></tr>
<tr class="markdownTableRowOdd">
<td class="markdownTableBodyNone">${ConfName} </td><td class="markdownTableBodyNone">Configuration name (e.g. USB-Audio.conf) </td></tr>
<tr class="markdownTableRowEven">
<td class="markdownTableBodyNone">${CardNumber} </td><td class="markdownTableBodyNone">Real ALSA card number (or empty string for the virtual UCM card) </td></tr>
<tr class="markdownTableRowOdd">
<td class="markdownTableBodyNone">${CardId} </td><td class="markdownTableBodyNone">ALSA card identifier (see <a class="el" href="group___control.html#gaadadbd2d4aef000a30ec4c1c949326cc" title="Get the sound card ID from the given info object.">snd_ctl_card_info_get_id()</a>) </td></tr>
<tr class="markdownTableRowEven">
<td class="markdownTableBodyNone">${CardDriver} </td><td class="markdownTableBodyNone">ALSA card driver (see <a class="el" href="group___control.html#ga4abf685f77a8fa8dd14232397cab6f71" title="Get the sound card driver from the given info object.">snd_ctl_card_info_get_driver()</a>) </td></tr>
<tr class="markdownTableRowOdd">
<td class="markdownTableBodyNone">${CardName} </td><td class="markdownTableBodyNone">ALSA card name (see <a class="el" href="group___control.html#gae71617c9deadee635b0ad38ca9aaf746" title="Get the sound card name from the given info object.">snd_ctl_card_info_get_name()</a>) </td></tr>
<tr class="markdownTableRowEven">
<td class="markdownTableBodyNone">${CardLongName} </td><td class="markdownTableBodyNone">ALSA card long name (see <a class="el" href="group___control.html#ga54a54f4b1cc3740eafba54b1cc1b8111" title="Get the sound cards long name from the given info object.">snd_ctl_card_info_get_longname()</a>) </td></tr>
<tr class="markdownTableRowOdd">
<td class="markdownTableBodyNone">${CardComponents} </td><td class="markdownTableBodyNone">ALSA card components (see <a class="el" href="group___control.html#ga2181aa6bf919fd1342b259d2f3af755b" title="Get the sound cards "components" property from the given info object.">snd_ctl_card_info_get_components()</a>) </td></tr>
<tr class="markdownTableRowEven">
<td class="markdownTableBodyNone">${env:<str>} </td><td class="markdownTableBodyNone">Environment variable <str> </td></tr>
<tr class="markdownTableRowOdd">
<td class="markdownTableBodyNone">${sys:<str>} </td><td class="markdownTableBodyNone">Contents of sysfs file <str> </td></tr>
<tr class="markdownTableRowEven">
<td class="markdownTableBodyNone">${var:<str>} </td><td class="markdownTableBodyNone">UCM parser variable (set using a <em>Define</em> block) </td></tr>
<tr class="markdownTableRowOdd">
<td class="markdownTableBodyNone">${eval:<str>} </td><td class="markdownTableBodyNone">Evaluate expression like *($var+2)/3* [<b>Syntax 5</b>] </td></tr>
<tr class="markdownTableRowEven">
<td class="markdownTableBodyNone">${find-card:<str>} </td><td class="markdownTableBodyNone">Find a card - see <em>Find card substitution</em> section </td></tr>
<tr class="markdownTableRowOdd">
<td class="markdownTableBodyNone">${find-device:<str>} </td><td class="markdownTableBodyNone">Find a device - see <em>Find device substitution</em> section </td></tr>
</table>
<h4><a class="anchor" id="autotoc_md20"></a>
Special whole string substitution</h4>
<table class="markdownTable">
<tr class="markdownTableHead">
<th class="markdownTableHeadNone">Substituted string </th><th class="markdownTableHeadNone">Value </th></tr>
<tr class="markdownTableRowOdd">
<td class="markdownTableBodyNone">${evali:<str>} </td><td class="markdownTableBodyNone">Evaluate expression like *($var+2)/3* [<b>Syntax 6</b>]; target node will be integer; substituted only in the LibraryConfig subtree </td></tr>
</table>
<h4><a class="anchor" id="autotoc_md21"></a>
Find card substitution</h4>
<p>This substitutions finds the ALSA card and returns the appropriate identifier or the card number (see return argument).</p>
<p>Usage example:</p>
<div class="fragment"><div class="line">${find-card:field=name,regex='^acp$',return=number}</div>
</div><!-- fragment --><p>Arguments:</p>
<table class="markdownTable">
<tr class="markdownTableHead">
<th class="markdownTableHeadNone">Argument </th><th class="markdownTableHeadNone">Description </th></tr>
<tr class="markdownTableRowOdd">
<td class="markdownTableBodyNone">return </td><td class="markdownTableBodyNone">return value type (id, number), id is the default </td></tr>
<tr class="markdownTableRowEven">
<td class="markdownTableBodyNone">field </td><td class="markdownTableBodyNone">field for the lookup (id, driver, name, longname, mixername, components) </td></tr>
<tr class="markdownTableRowOdd">
<td class="markdownTableBodyNone">regex </td><td class="markdownTableBodyNone">regex string for the field match </td></tr>
</table>
<h4><a class="anchor" id="autotoc_md22"></a>
Find device substitution</h4>
<p>Usage example:</p>
<div class="fragment"><div class="line">${find-device:type=pcm,field=name,regex='DMIC'}</div>
</div><!-- fragment --><p>Arguments:</p>
<table class="markdownTable">
<tr class="markdownTableHead">
<th class="markdownTableHeadNone">Argument </th><th class="markdownTableHeadNone">Description </th></tr>
<tr class="markdownTableRowOdd">
<td class="markdownTableBodyNone">type </td><td class="markdownTableBodyNone">device type (pcm) </td></tr>
<tr class="markdownTableRowEven">
<td class="markdownTableBodyNone">stream </td><td class="markdownTableBodyNone">stream type (playback, capture), playback is default </td></tr>
<tr class="markdownTableRowOdd">
<td class="markdownTableBodyNone">field </td><td class="markdownTableBodyNone">field for the lookup (id, name, subname) </td></tr>
<tr class="markdownTableRowEven">
<td class="markdownTableBodyNone">regex </td><td class="markdownTableBodyNone">regex string for the field match </td></tr>
</table>
<h3><a class="anchor" id="autotoc_md23"></a>
Variable defines</h3>
<p>The variables can be defined and altered with the <em>Define</em> or <em>DefineRegex</em> blocks. The <em>Define</em> block looks like:</p>
<div class="fragment"><div class="line">Define {</div>
<div class="line"> variable1 "a"</div>
<div class="line"> variable2 "b"</div>
<div class="line">}</div>
</div><!-- fragment --><p>The <em>DefineRegex</em> allows substring extraction like:</p>
<div class="fragment"><div class="line">DefineRegex.rval {</div>
<div class="line"> Regex "(hello)|(regex)"</div>
<div class="line"> String "hello, it's my regex"</div>
<div class="line">}</div>
</div><!-- fragment --><p>The result will be stored to variables <em>rval1</em> as <em>hello</em> and <em>rval2</em> as <em>regex</em> (every matched substrings are stored to a separate variable with the sequence number postfix.</p>
<p>Variables can be substituted using the <code>${var:rval1}</code> reference for example.</p>
<h3><a class="anchor" id="autotoc_md24"></a>
Macros</h3>
<p>Macros were added for <em>Syntax</em> version <em>6</em>. The <em>DefineMacro</em> defines new macro like:</p>
<div class="fragment"><div class="line">DefineMacro.macro1 {</div>
<div class="line"> Define.a "${var:__arg1}"</div>
<div class="line"> Define.b "${var:__other}"</div>
<div class="line"> # Device or any other block may be defined here...</div>
<div class="line">}</div>
</div><!-- fragment --><p>The arguments in the macro are refered as the variables with the double underscore name prefix (like *__variable*). The configuration block in the DefineMacro subtree is always evaluated (including arguments and variables) at the time of the instantiation. Argument string substitutions (for multiple macro call levels) were added in <em>Syntax</em> version <em>7</em>.</p>
<p>The macros can be instantiated (expanded) using:</p>
<div class="fragment"><div class="line"># short version</div>
<div class="line">Macro.id1.macro1 "arg1='something 1',other='other x'"</div>
<div class="line"> </div>
<div class="line"># long version</div>
<div class="line">Macro.id1.macro1 {</div>
<div class="line"> arg1 'something 1'</div>
<div class="line"> other 'other x'</div>
<div class="line">}</div>
</div><!-- fragment --><p>The second identifier (in example as <em>id1</em>) must be unique, but the contents is ignored. It just differentiate the items in the subtree (allowing multiple instances for one macro).</p>
<h3><a class="anchor" id="autotoc_md25"></a>
Conditions</h3>
<p>The configuration tree evaluation supports the conditions - <em>If</em> blocks. Each <em>If</em> blocks must define a <em>Condition</em> block and <em>True</em> or <em>False</em> blocks or both. The <em>True</em> or <em>False</em> blocks will be merged to the parent tree (where the <em>If</em> block is defined) when the <em>Condition</em> is evaluated.</p>
<p>Example:</p>
<div class="fragment"><div class="line">If.uniqueid {</div>
<div class="line"> Condition {</div>
<div class="line"> Type String</div>
<div class="line"> Haystack "abcd"</div>
<div class="line"> Needle "a"</div>
<div class="line"> }</div>
<div class="line"> True {</div>
<div class="line"> Define.a a</div>
<div class="line"> define.b b</div>
<div class="line"> }</div>
<div class="line">}</div>
</div><!-- fragment --><h4><a class="anchor" id="autotoc_md26"></a>
True (Type AlwaysTrue)</h4>
<p>Execute only <em>True</em> block. It may be used to change the evaluation order as explained in the <em>Configuration Tree</em> paragraph.</p>
<h4><a class="anchor" id="autotoc_md27"></a>
String is empty (Type String)</h4>
<table class="markdownTable">
<tr class="markdownTableHead">
<th class="markdownTableHeadNone">Field </th><th class="markdownTableHeadNone">Description </th></tr>
<tr class="markdownTableRowOdd">
<td class="markdownTableBodyNone">Empty </td><td class="markdownTableBodyNone">string </td></tr>
</table>
<h4><a class="anchor" id="autotoc_md28"></a>
Strings are equal (Type String)</h4>
<table class="markdownTable">
<tr class="markdownTableHead">
<th class="markdownTableHeadNone">Field </th><th class="markdownTableHeadNone">Description </th></tr>
<tr class="markdownTableRowOdd">
<td class="markdownTableBodyNone">String1 </td><td class="markdownTableBodyNone">string </td></tr>
<tr class="markdownTableRowEven">
<td class="markdownTableBodyNone">String2 </td><td class="markdownTableBodyNone">substring in string </td></tr>
</table>
<h4><a class="anchor" id="autotoc_md29"></a>
Substring is present (Type String)</h4>
<table class="markdownTable">
<tr class="markdownTableHead">
<th class="markdownTableHeadNone">Field </th><th class="markdownTableHeadNone">Description </th></tr>
<tr class="markdownTableRowOdd">
<td class="markdownTableBodyNone">Haystack </td><td class="markdownTableBodyNone">string </td></tr>
<tr class="markdownTableRowEven">
<td class="markdownTableBodyNone">Needle </td><td class="markdownTableBodyNone">substring in string </td></tr>
</table>
<h4><a class="anchor" id="autotoc_md30"></a>
Regex match (Type RegexMatch)</h4>
<table class="markdownTable">
<tr class="markdownTableHead">
<th class="markdownTableHeadNone">Field </th><th class="markdownTableHeadNone">Description </th></tr>
<tr class="markdownTableRowOdd">
<td class="markdownTableBodyNone">String </td><td class="markdownTableBodyNone">string </td></tr>
<tr class="markdownTableRowEven">
<td class="markdownTableBodyNone">Regex </td><td class="markdownTableBodyNone">regex expression (extended posix, ignore case) </td></tr>
</table>
<h4><a class="anchor" id="autotoc_md31"></a>
Path is present (Type Path)</h4>
<table class="markdownTable">
<tr class="markdownTableHead">
<th class="markdownTableHeadNone">Field </th><th class="markdownTableHeadNone">Description </th></tr>
<tr class="markdownTableRowOdd">
<td class="markdownTableBodyNone">Path </td><td class="markdownTableBodyNone">path (filename) </td></tr>
<tr class="markdownTableRowEven">
<td class="markdownTableBodyNone">Mode </td><td class="markdownTableBodyNone">exist,read,write,exec </td></tr>
</table>
<p>Note: Substitution for Path and Mode fields were added in <em>Syntax</em> version <em>7</em>.</p>
<h4><a class="anchor" id="autotoc_md32"></a>
ALSA control element exists (Type ControlExists)</h4>
<table class="markdownTable">
<tr class="markdownTableHead">
<th class="markdownTableHeadNone">Field </th><th class="markdownTableHeadNone">Description </th></tr>
<tr class="markdownTableRowOdd">
<td class="markdownTableBodyNone">Device </td><td class="markdownTableBodyNone">ALSA control device (see <a class="el" href="group___control.html#ga58537f5b74c9c1f51699f9908a0d7f56" title="Opens a sound card.">snd_ctl_open()</a>) </td></tr>
<tr class="markdownTableRowEven">
<td class="markdownTableBodyNone">Control </td><td class="markdownTableBodyNone">control in ASCII (parsed using <a class="el" href="group___control.html#ga2f530217bd896e3c0498b3e46624977a" title="parse ASCII string as CTL element identifier">snd_ctl_ascii_elem_id_parse()</a>) </td></tr>
<tr class="markdownTableRowOdd">
<td class="markdownTableBodyNone">ControlEnum </td><td class="markdownTableBodyNone">value for the enum control (optional) </td></tr>
</table>
<p>Example:</p>
<div class="fragment"><div class="line">If.fmic {</div>
<div class="line"> Condition {</div>
<div class="line"> Type ControlExists</div>
<div class="line"> Control "name='Front Mic Playback Switch'"</div>
<div class="line"> }</div>
<div class="line"> True {</div>
<div class="line"> ...</div>
<div class="line"> }</div>
<div class="line">}</div>
</div><!-- fragment --><h3><a class="anchor" id="autotoc_md33"></a>
Variants</h3>
<p>To avoid duplication of the many configuration files for the cases with minimal configuration changes, there is the variant extension. Variants were added for <em>Syntax</em> version <em>6</em>.</p>
<p>The bellow example will create two verbs - "HiFi" and "HiFi 7.1" with the different playback channels (2 and 8) for the "Speaker" device.</p>
<p>Example (main configuration file):</p>
<div class="fragment"><div class="line">SectionUseCase."HiFi" {</div>
<div class="line"> File "HiFi.conf"</div>
<div class="line"> Variant."HiFi" {</div>
<div class="line"> Comment "HiFi"</div>
<div class="line"> }</div>
<div class="line"> Variant."HiFi 7+1" {</div>
<div class="line"> Comment "HiFi 7.1"</div>
<div class="line"> }</div>
<div class="line">}</div>
</div><!-- fragment --><p>Example (verb configuration file - HiFi.conf):</p>
<div class="fragment"><div class="line">SectionDevice."Speaker" {</div>
<div class="line"> Value {</div>
<div class="line"> PlaybackChannels 2</div>
<div class="line"> }</div>
<div class="line"> Variant."HiFi 7+1".Value {</div>
<div class="line"> PlaybackChannels 8</div>
<div class="line"> }</div>
<div class="line">}</div>
</div><!-- fragment --> </div></div><!-- contents -->
<!-- start footer part -->
<hr class="footer"/><address class="footer"><small>
Generated by <a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.1
</small></address>
</body>
</html>