1d5ac70f0Sopenharmony_ci/* 2d5ac70f0Sopenharmony_ci * This library is free software; you can redistribute it and/or 3d5ac70f0Sopenharmony_ci * modify it under the terms of the GNU Lesser General Public 4d5ac70f0Sopenharmony_ci * License as published by the Free Software Foundation; either 5d5ac70f0Sopenharmony_ci * version 2 of the License, or (at your option) any later version. 6d5ac70f0Sopenharmony_ci * 7d5ac70f0Sopenharmony_ci * This library is distributed in the hope that it will be useful, 8d5ac70f0Sopenharmony_ci * but WITHOUT ANY WARRANTY; without even the implied warranty of 9d5ac70f0Sopenharmony_ci * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 10d5ac70f0Sopenharmony_ci * Lesser General Public License for more details. 11d5ac70f0Sopenharmony_ci * 12d5ac70f0Sopenharmony_ci * You should have received a copy of the GNU Lesser General Public 13d5ac70f0Sopenharmony_ci * License along with this library; if not, write to the Free Software 14d5ac70f0Sopenharmony_ci * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 15d5ac70f0Sopenharmony_ci * 16d5ac70f0Sopenharmony_ci * Support for the verb/device/modifier core logic and API, 17d5ac70f0Sopenharmony_ci * command line tool and file parser was kindly sponsored by 18d5ac70f0Sopenharmony_ci * Texas Instruments Inc. 19d5ac70f0Sopenharmony_ci * Support for multiple active modifiers and devices, 20d5ac70f0Sopenharmony_ci * transition sequences, multiple client access and user defined use 21d5ac70f0Sopenharmony_ci * cases was kindly sponsored by Wolfson Microelectronics PLC. 22d5ac70f0Sopenharmony_ci * 23d5ac70f0Sopenharmony_ci * Copyright (C) 2021 Red Hat Inc. 24d5ac70f0Sopenharmony_ci * Authors: Jaroslav Kysela <perex@perex.cz> 25d5ac70f0Sopenharmony_ci */ 26d5ac70f0Sopenharmony_ci 27d5ac70f0Sopenharmony_ci/** 28d5ac70f0Sopenharmony_ci * \defgroup ucm_conf Use Case Configuration 29d5ac70f0Sopenharmony_ci * The ALSA Use Case Configuration. 30d5ac70f0Sopenharmony_ci * See \ref Usecase_conf page for more details. 31d5ac70f0Sopenharmony_ci * \{ 32d5ac70f0Sopenharmony_ci */ 33d5ac70f0Sopenharmony_ci 34d5ac70f0Sopenharmony_ci/*! \page Usecase_conf ALSA Use Case Configuration 35d5ac70f0Sopenharmony_ci 36d5ac70f0Sopenharmony_ciThe use case configuration files use \ref conf syntax to define the 37d5ac70f0Sopenharmony_cistatic configuration tree. This tree is evaluated (modified) at runtime 38d5ac70f0Sopenharmony_ciaccording the conditions and dynamic variables in the configuration tree. 39d5ac70f0Sopenharmony_ciThe result is parsed and exported to the applications using \ref ucm API. 40d5ac70f0Sopenharmony_ci 41d5ac70f0Sopenharmony_ci### Configuration directory and main filename lookup 42d5ac70f0Sopenharmony_ci 43d5ac70f0Sopenharmony_ciThe lookup paths are describen in *ucm.conf* file. The configuration 44d5ac70f0Sopenharmony_cistructure looks like: 45d5ac70f0Sopenharmony_ci 46d5ac70f0Sopenharmony_ci~~~{.html} 47d5ac70f0Sopenharmony_ciUseCasePath.path1 { 48d5ac70f0Sopenharmony_ci Directory "conf.virt.d" 49d5ac70f0Sopenharmony_ci File "${OpenName}.conf" 50d5ac70f0Sopenharmony_ci} 51d5ac70f0Sopenharmony_ciUseCasePath.path2 { 52d5ac70f0Sopenharmony_ci Directory "external" 53d5ac70f0Sopenharmony_ci File "${OpenName}.conf" 54d5ac70f0Sopenharmony_ci} 55d5ac70f0Sopenharmony_ci~~~ 56d5ac70f0Sopenharmony_ci 57d5ac70f0Sopenharmony_ci### UCM main configuration file 58d5ac70f0Sopenharmony_ci 59d5ac70f0Sopenharmony_ciEach sound card has a master sound card file that lists all the supported 60d5ac70f0Sopenharmony_ciuse case verbs for that sound card. i.e.: 61d5ac70f0Sopenharmony_ci 62d5ac70f0Sopenharmony_ci~~~{.html} 63d5ac70f0Sopenharmony_ci# Example master file for blah sound card 64d5ac70f0Sopenharmony_ci# By Joe Blogs <joe@bloggs.org> 65d5ac70f0Sopenharmony_ci 66d5ac70f0Sopenharmony_ciSyntax 6 67d5ac70f0Sopenharmony_ci 68d5ac70f0Sopenharmony_ci# Use Case name for user interface 69d5ac70f0Sopenharmony_ciComment "Nice Abstracted Soundcard" 70d5ac70f0Sopenharmony_ci 71d5ac70f0Sopenharmony_ci# The file is divided into Use case sections. One section per use case verb. 72d5ac70f0Sopenharmony_ci 73d5ac70f0Sopenharmony_ciSectionUseCase."Voice Call" { 74d5ac70f0Sopenharmony_ci File "voice_call_blah" 75d5ac70f0Sopenharmony_ci Comment "Make a voice phone call." 76d5ac70f0Sopenharmony_ci} 77d5ac70f0Sopenharmony_ci 78d5ac70f0Sopenharmony_ciSectionUseCase."HiFi" { 79d5ac70f0Sopenharmony_ci File "hifi_blah" 80d5ac70f0Sopenharmony_ci Comment "Play and record HiFi quality Music." 81d5ac70f0Sopenharmony_ci} 82d5ac70f0Sopenharmony_ci 83d5ac70f0Sopenharmony_ci# Define Value defaults 84d5ac70f0Sopenharmony_ci 85d5ac70f0Sopenharmony_ciValueDefaults { 86d5ac70f0Sopenharmony_ci PlaybackChannels 4 87d5ac70f0Sopenharmony_ci CaptureChannels 4 88d5ac70f0Sopenharmony_ci} 89d5ac70f0Sopenharmony_ci 90d5ac70f0Sopenharmony_ci# Define boot / initialization sequence 91d5ac70f0Sopenharmony_ci# This sequence is skipped, when the soundcard was already configured by system 92d5ac70f0Sopenharmony_ci# (alsactl configuration was already created). The purpose is to not alter 93d5ac70f0Sopenharmony_ci# ALSA card controls which may be modified by user after initial settings. 94d5ac70f0Sopenharmony_ci 95d5ac70f0Sopenharmony_ciBootSequence [ 96d5ac70f0Sopenharmony_ci cset "name='Master Playback Switch',index=2 0,0" 97d5ac70f0Sopenharmony_ci cset "name='Master Playback Volume',index=2 25,25" 98d5ac70f0Sopenharmony_ci msleep 50 99d5ac70f0Sopenharmony_ci cset "name='Master Playback Switch',index=2 1,1" 100d5ac70f0Sopenharmony_ci cset "name='Master Playback Volume',index=2 50,50" 101d5ac70f0Sopenharmony_ci] 102d5ac70f0Sopenharmony_ci 103d5ac70f0Sopenharmony_ci# Define fixed boot sequence 104d5ac70f0Sopenharmony_ci# This sequence is always executed on boot (hotplug). 105d5ac70f0Sopenharmony_ci 106d5ac70f0Sopenharmony_ciFixedBootSequence [ 107d5ac70f0Sopenharmony_ci cset "name='Something to toggle' toggle" 108d5ac70f0Sopenharmony_ci] 109d5ac70f0Sopenharmony_ci~~~ 110d5ac70f0Sopenharmony_ci 111d5ac70f0Sopenharmony_ci### UCM verb configuration file 112d5ac70f0Sopenharmony_ci 113d5ac70f0Sopenharmony_ciThe verb configuration file defines devices, modifier and initialization sequences. 114d5ac70f0Sopenharmony_ciIt is something like a sound profile. 115d5ac70f0Sopenharmony_ci 116d5ac70f0Sopenharmony_ci~~~{.html} 117d5ac70f0Sopenharmony_ci# Example Use case verb section for Voice call blah 118d5ac70f0Sopenharmony_ci# By Joe Blogs <joe@blogs.com> 119d5ac70f0Sopenharmony_ci 120d5ac70f0Sopenharmony_ci# verb global section 121d5ac70f0Sopenharmony_ci 122d5ac70f0Sopenharmony_ciSectionVerb { 123d5ac70f0Sopenharmony_ci 124d5ac70f0Sopenharmony_ci # enable and disable sequences are compulsory 125d5ac70f0Sopenharmony_ci EnableSequence [ 126d5ac70f0Sopenharmony_ci disdevall "" # run DisableSequence for all devices 127d5ac70f0Sopenharmony_ci ] 128d5ac70f0Sopenharmony_ci 129d5ac70f0Sopenharmony_ci DisableSequence [ 130d5ac70f0Sopenharmony_ci cset "name='Power Save' on" 131d5ac70f0Sopenharmony_ci ] 132d5ac70f0Sopenharmony_ci 133d5ac70f0Sopenharmony_ci # Optional transition verb 134d5ac70f0Sopenharmony_ci TransitionSequence."ToCaseName" [ 135d5ac70f0Sopenharmony_ci disdevall "" # run DisableSequence for all devices 136d5ac70f0Sopenharmony_ci msleep 1 137d5ac70f0Sopenharmony_ci ] 138d5ac70f0Sopenharmony_ci 139d5ac70f0Sopenharmony_ci # Optional TQ and device values 140d5ac70f0Sopenharmony_ci Value { 141d5ac70f0Sopenharmony_ci TQ HiFi 142d5ac70f0Sopenharmony_ci PlaybackChannels 6 143d5ac70f0Sopenharmony_ci } 144d5ac70f0Sopenharmony_ci} 145d5ac70f0Sopenharmony_ci 146d5ac70f0Sopenharmony_ci# Each device is described in new section. N devices are allowed 147d5ac70f0Sopenharmony_ci 148d5ac70f0Sopenharmony_ciSectionDevice."Headphones" { 149d5ac70f0Sopenharmony_ci 150d5ac70f0Sopenharmony_ci SupportedDevice [ 151d5ac70f0Sopenharmony_ci "x" 152d5ac70f0Sopenharmony_ci "y" 153d5ac70f0Sopenharmony_ci ] 154d5ac70f0Sopenharmony_ci 155d5ac70f0Sopenharmony_ci # or (not both) 156d5ac70f0Sopenharmony_ci 157d5ac70f0Sopenharmony_ci ConflictingDevice [ 158d5ac70f0Sopenharmony_ci "x" 159d5ac70f0Sopenharmony_ci "y" 160d5ac70f0Sopenharmony_ci ] 161d5ac70f0Sopenharmony_ci 162d5ac70f0Sopenharmony_ci EnableSequence [ 163d5ac70f0Sopenharmony_ci ... 164d5ac70f0Sopenharmony_ci ] 165d5ac70f0Sopenharmony_ci 166d5ac70f0Sopenharmony_ci DisableSequence [ 167d5ac70f0Sopenharmony_ci ... 168d5ac70f0Sopenharmony_ci ] 169d5ac70f0Sopenharmony_ci 170d5ac70f0Sopenharmony_ci TransitionSequence."ToDevice" [ 171d5ac70f0Sopenharmony_ci ... 172d5ac70f0Sopenharmony_ci ] 173d5ac70f0Sopenharmony_ci 174d5ac70f0Sopenharmony_ci Value { 175d5ac70f0Sopenharmony_ci PlaybackVolume "name='Master Playback Volume',index=2" 176d5ac70f0Sopenharmony_ci PlaybackSwitch "name='Master Playback Switch',index=2" 177d5ac70f0Sopenharmony_ci PlaybackPCM "hw:${CardId},4" 178d5ac70f0Sopenharmony_ci } 179d5ac70f0Sopenharmony_ci} 180d5ac70f0Sopenharmony_ci 181d5ac70f0Sopenharmony_ci# Each modifier is described in new section. N modifiers are allowed 182d5ac70f0Sopenharmony_ci 183d5ac70f0Sopenharmony_ciSectionModifier."Capture Voice" { 184d5ac70f0Sopenharmony_ci Comment "Record voice call" 185d5ac70f0Sopenharmony_ci 186d5ac70f0Sopenharmony_ci SupportedDevice [ 187d5ac70f0Sopenharmony_ci "x" 188d5ac70f0Sopenharmony_ci "y" 189d5ac70f0Sopenharmony_ci ] 190d5ac70f0Sopenharmony_ci 191d5ac70f0Sopenharmony_ci # or (not both) 192d5ac70f0Sopenharmony_ci 193d5ac70f0Sopenharmony_ci ConflictingDevice [ 194d5ac70f0Sopenharmony_ci "x" 195d5ac70f0Sopenharmony_ci "y" 196d5ac70f0Sopenharmony_ci ] 197d5ac70f0Sopenharmony_ci 198d5ac70f0Sopenharmony_ci EnableSequence [ 199d5ac70f0Sopenharmony_ci ... 200d5ac70f0Sopenharmony_ci ] 201d5ac70f0Sopenharmony_ci 202d5ac70f0Sopenharmony_ci DisableSequence [ 203d5ac70f0Sopenharmony_ci ... 204d5ac70f0Sopenharmony_ci ] 205d5ac70f0Sopenharmony_ci 206d5ac70f0Sopenharmony_ci TransitionSequence."ToModifierName" [ 207d5ac70f0Sopenharmony_ci ... 208d5ac70f0Sopenharmony_ci ] 209d5ac70f0Sopenharmony_ci 210d5ac70f0Sopenharmony_ci # Optional TQ and ALSA PCMs 211d5ac70f0Sopenharmony_ci Value { 212d5ac70f0Sopenharmony_ci TQ Voice 213d5ac70f0Sopenharmony_ci CapturePCM "hw:${CardId},11" 214d5ac70f0Sopenharmony_ci PlaybackMixerElem "Master" 215d5ac70f0Sopenharmony_ci PlaybackVolume "name='Master Playback Volume',index=2" 216d5ac70f0Sopenharmony_ci PlaybackSwitch "name='Master Playback Switch',index=2" 217d5ac70f0Sopenharmony_ci } 218d5ac70f0Sopenharmony_ci} 219d5ac70f0Sopenharmony_ci~~~ 220d5ac70f0Sopenharmony_ci 221d5ac70f0Sopenharmony_ci### Sequence graphs 222d5ac70f0Sopenharmony_ci 223d5ac70f0Sopenharmony_ci\image html ucm-seq-verb.svg 224d5ac70f0Sopenharmony_ci\image html ucm-seq-device.svg 225d5ac70f0Sopenharmony_ci 226d5ac70f0Sopenharmony_ci### Sequence commands 227d5ac70f0Sopenharmony_ci 228d5ac70f0Sopenharmony_ciCommand name | Description 229d5ac70f0Sopenharmony_ci---------------|---------------------------------------------- 230d5ac70f0Sopenharmony_cienadev2 ARG | execute device enable sequence 231d5ac70f0Sopenharmony_cidisdev2 ARG | execute device disable sequence 232d5ac70f0Sopenharmony_cidisdevall "" | execute device disable sequence for all devices in verb 233d5ac70f0Sopenharmony_cicdev ARG | ALSA control device name for snd_ctl_open() 234d5ac70f0Sopenharmony_cicset ARG | ALSA control set - snd_ctl_ascii_elem_id_parse() + snd_ctl_ascii_value_parse() 235d5ac70f0Sopenharmony_cicset-new ARG | Create new ALSA user control element - snd_ctl_ascii_elem_id_parse() + description 236d5ac70f0Sopenharmony_cictl-remove ARG | Remove ALSA user control element - snd_ctl_ascii_elem_id_parse() 237d5ac70f0Sopenharmony_cisysw ARG | write to sysfs tree 238d5ac70f0Sopenharmony_ciusleep ARG | sleep for specified amount of microseconds 239d5ac70f0Sopenharmony_cimsleep ARG | sleep for specified amount of milliseconds 240d5ac70f0Sopenharmony_ciexec ARG | execute a specific command (without shell - *man execv*) 241d5ac70f0Sopenharmony_cishell ARG | execute a specific command (using shell - *man system*) 242d5ac70f0Sopenharmony_cicfg-save ARG | save LibraryConfig to a file 243d5ac70f0Sopenharmony_ci 244d5ac70f0Sopenharmony_ci~~~{.html} 245d5ac70f0Sopenharmony_ci# Examples 246d5ac70f0Sopenharmony_cicset "name='PCM Playback Volue',index=2 99" 247d5ac70f0Sopenharmony_cicset-new "name='Bool2' type=bool,count=2 1,0" 248d5ac70f0Sopenharmony_cicset-new "name='Enum' type=enum,labels='L1;L2;L3' 'L2'" 249d5ac70f0Sopenharmony_cictl-remove "name='Bool2'" 250d5ac70f0Sopenharmony_cisysw "-/class/sound/ctl-led/speaker/card${CardNumber}/attach:Speaker Channel Switch" 251d5ac70f0Sopenharmony_ciusleep 10 252d5ac70f0Sopenharmony_ciexec "/bin/echo hello" 253d5ac70f0Sopenharmony_cishell "set" 254d5ac70f0Sopenharmony_cicfg-save "/tmp/test.conf:+pcm" 255d5ac70f0Sopenharmony_ci~~~ 256d5ac70f0Sopenharmony_ci 257d5ac70f0Sopenharmony_ci### Naming (devices, verbs) 258d5ac70f0Sopenharmony_ci 259d5ac70f0Sopenharmony_ciSee the SND_USE_CASE_VERB constains like #SND_USE_CASE_VERB_HIFI for the full list of known verbs. 260d5ac70f0Sopenharmony_ci 261d5ac70f0Sopenharmony_ciSee the SND_USE_CASE_DEV constants like #SND_USE_CASE_DEV_SPEAKER for the full list of known devices. 262d5ac70f0Sopenharmony_ciIf multiple devices with the same name exists, the number suffixes should 263d5ac70f0Sopenharmony_cibe added to these names like HDMI1,HDMI2,HDMI3 etc. No number gaps are 264d5ac70f0Sopenharmony_ciallowed. The names with numbers must be continuous. It is allowed to put 265d5ac70f0Sopenharmony_cia whitespace between name and index (like 'Line 1') for the better 266d5ac70f0Sopenharmony_cireadability. The device names 'Line 1' and 'Line1' are equal for 267d5ac70f0Sopenharmony_cithis purpose. 268d5ac70f0Sopenharmony_ci 269d5ac70f0Sopenharmony_ciIf EnableSequence/DisableSequence controls independent paths in the hardware 270d5ac70f0Sopenharmony_ciit is also recommended to split playback and capture UCM devices and use 271d5ac70f0Sopenharmony_cithe number suffixes. Example use case: Use the integrated microphone 272d5ac70f0Sopenharmony_ciin the laptop instead the microphone in headphones. 273d5ac70f0Sopenharmony_ci 274d5ac70f0Sopenharmony_ciThe preference of the devices is determined by the priority value (higher value = higher priority). 275d5ac70f0Sopenharmony_ci 276d5ac70f0Sopenharmony_ciSee the SND_USE_CASE_MOD constants like #SND_USE_CASE_MOD_ECHO_REF for the full list of known modifiers. 277d5ac70f0Sopenharmony_ci 278d5ac70f0Sopenharmony_ci### Boot (alsactl) 279d5ac70f0Sopenharmony_ci 280d5ac70f0Sopenharmony_ciThe *FixedBootSequence* is executed at each boot. The *BootSequence* is executed only 281d5ac70f0Sopenharmony_ciif the card's configuration is missing. The purpose is to let the users modify the 282d5ac70f0Sopenharmony_ciconfiguration like volumes or switches. The alsactl ensures the persistency (store 283d5ac70f0Sopenharmony_cithe state of the controls to the /var tree and loads the previous state in the next 284d5ac70f0Sopenharmony_ciboot). 285d5ac70f0Sopenharmony_ci 286d5ac70f0Sopenharmony_ci\image html ucm-seq-boot.svg 287d5ac70f0Sopenharmony_ci 288d5ac70f0Sopenharmony_ci### Device volume 289d5ac70f0Sopenharmony_ci 290d5ac70f0Sopenharmony_ciIt is expected that the applications handle the volume settings. It is not recommended 291d5ac70f0Sopenharmony_cito set the fixed values for the volume settings in the Enable / Disable sequences for 292d5ac70f0Sopenharmony_civerbs or devices, if the device exports the hardware volume (MixerElem or Volume/Switch 293d5ac70f0Sopenharmony_civalues). The default volume settings should be set in the *BootSequence*. The purpose 294d5ac70f0Sopenharmony_cifor this scheme is to allow users to override defaults using the alsactl sound card 295d5ac70f0Sopenharmony_cistate management. 296d5ac70f0Sopenharmony_ci 297d5ac70f0Sopenharmony_ciChecklist: 298d5ac70f0Sopenharmony_ci 299d5ac70f0Sopenharmony_ci1. Set default volume in BootSequence 300d5ac70f0Sopenharmony_ci2. Verb's EnableSequence should ensure that all devices are turned off (mixer paths) 301d5ac70f0Sopenharmony_ci to avoid simultaneous device use - the previous state is unknown (see *disdevall* 302d5ac70f0Sopenharmony_ci and *disdev2* commands or create a new custom command sequence) 303d5ac70f0Sopenharmony_ci 304d5ac70f0Sopenharmony_ci\image html ucm-volume.svg 305d5ac70f0Sopenharmony_ci 306d5ac70f0Sopenharmony_ci### Dynamic configuration tree 307d5ac70f0Sopenharmony_ci 308d5ac70f0Sopenharmony_ciThe evaluation order may look a bit different from the user perspective. 309d5ac70f0Sopenharmony_ciAt first, the standard alsa-lib configuration tree is parsed. All other 310d5ac70f0Sopenharmony_cilayers on top are working with this tree. It may shift / move the configuration 311d5ac70f0Sopenharmony_ciblocks from the configuration files as they are placed to the tree internally. 312d5ac70f0Sopenharmony_ci 313d5ac70f0Sopenharmony_ci~~~{.html} 314d5ac70f0Sopenharmony_ciExample configuration | Parsed static tree | Identical static tree 315d5ac70f0Sopenharmony_ci----------------------------+-------------------------+------------------------------- 316d5ac70f0Sopenharmony_ciIf.1 { | If { | If.1.True.Define.VAR "A" 317d5ac70f0Sopenharmony_ci True.Define.VAR "A" | 1.True.Define.VAR "A" | If.2.True.Define.VAR "C" 318d5ac70f0Sopenharmony_ci} | 2.True.Define.VAR "C" | Define.VAR "B" 319d5ac70f0Sopenharmony_ciDefine.VAR "B" | } | 320d5ac70f0Sopenharmony_ciIf.2 { | Define.VAR "B" | 321d5ac70f0Sopenharmony_ci True.Define.VAR "C" | | 322d5ac70f0Sopenharmony_ci} | | 323d5ac70f0Sopenharmony_ci~~~ 324d5ac70f0Sopenharmony_ci 325d5ac70f0Sopenharmony_ciEven if one or both conditions are evaluated as true, the variable _VAR_ will 326d5ac70f0Sopenharmony_cibe evaluated always as **B** because the first _If_ block was before the non-nested 327d5ac70f0Sopenharmony_ci_Define_ . The second _If_ block was appended to the first _If_ block (before 328d5ac70f0Sopenharmony_ci_Define_ in the configuration tree) in the text configuration parser. 329d5ac70f0Sopenharmony_ci 330d5ac70f0Sopenharmony_ci 331d5ac70f0Sopenharmony_ci### Syntax 332d5ac70f0Sopenharmony_ci 333d5ac70f0Sopenharmony_ciUnless described, the syntax version 4 is used. 334d5ac70f0Sopenharmony_ci 335d5ac70f0Sopenharmony_ci~~~ 336d5ac70f0Sopenharmony_ciSyntax 4 337d5ac70f0Sopenharmony_ci~~~ 338d5ac70f0Sopenharmony_ci 339d5ac70f0Sopenharmony_ci 340d5ac70f0Sopenharmony_ci### Include 341d5ac70f0Sopenharmony_ci 342d5ac70f0Sopenharmony_ciThere are two ways to include other configuration files. 343d5ac70f0Sopenharmony_ci 344d5ac70f0Sopenharmony_ci#### Static include 345d5ac70f0Sopenharmony_ci 346d5ac70f0Sopenharmony_ciThe static include is inherited from the standard alsa-lib configuration 347d5ac70f0Sopenharmony_cisyntax. It can be placed anywhere in the configuration files. The search 348d5ac70f0Sopenharmony_cipath is composed from the root alsa configuration path (usually 349d5ac70f0Sopenharmony_ci_/usr/share/alsa_) and _ucm2_ directory. 350d5ac70f0Sopenharmony_ci 351d5ac70f0Sopenharmony_ci~~~{.html} 352d5ac70f0Sopenharmony_ci<some/path/file.conf> # include file using the search path 353d5ac70f0Sopenharmony_ci</absolute/path/file.conf> # include file using the absolute path 354d5ac70f0Sopenharmony_ci~~~ 355d5ac70f0Sopenharmony_ci 356d5ac70f0Sopenharmony_ci#### Lazy include 357d5ac70f0Sopenharmony_ci 358d5ac70f0Sopenharmony_ciThe lazy include is evaluated at runtime. The root path is the ucm2 359d5ac70f0Sopenharmony_citree. The absolute include appends the ucm2 absolute path to the 360d5ac70f0Sopenharmony_cispecified path. The relative include is relative to the file which 361d5ac70f0Sopenharmony_cicontains the _Include_ configuration block. 362d5ac70f0Sopenharmony_ci 363d5ac70f0Sopenharmony_ci~~~{.html} 364d5ac70f0Sopenharmony_ciInclude.id1.File "/some/path/file.conf" # absolute include (in the ucm2 tree) 365d5ac70f0Sopenharmony_ciInclude.id2.File "subdir/file.conf" # relative include to the current configuration directory (UseCasePath) 366d5ac70f0Sopenharmony_ci~~~ 367d5ac70f0Sopenharmony_ci 368d5ac70f0Sopenharmony_ci### Configuration tree evaluation 369d5ac70f0Sopenharmony_ci 370d5ac70f0Sopenharmony_ciThe evaluation of the static configuration tree is proceed in 371d5ac70f0Sopenharmony_cithe specific order (see table bellow). When the dynamic configuration 372d5ac70f0Sopenharmony_citree changes, the evaluation sequence is restarted to evaluate 373d5ac70f0Sopenharmony_ciall possible changes (new *Define* or *Include* or *If* blocks). 374d5ac70f0Sopenharmony_ci 375d5ac70f0Sopenharmony_ciEvaluation order | Configuration block | Evaluation restart 376d5ac70f0Sopenharmony_ci------------------:|---------------------|-------------------- 377d5ac70f0Sopenharmony_ci1 | Define | No 378d5ac70f0Sopenharmony_ci2 | Include | Yes 379d5ac70f0Sopenharmony_ci3 | If | Yes 380d5ac70f0Sopenharmony_ci 381d5ac70f0Sopenharmony_ci 382d5ac70f0Sopenharmony_ci### Substitutions 383d5ac70f0Sopenharmony_ci 384d5ac70f0Sopenharmony_ciThe dynamic tree identifiers and assigned values in the configuration tree are 385d5ac70f0Sopenharmony_cisubstituted. The substitutes strings are in the table bellow. 386d5ac70f0Sopenharmony_ci 387d5ac70f0Sopenharmony_ciSubstituted string | Value 388d5ac70f0Sopenharmony_ci---------------------|--------------------- 389d5ac70f0Sopenharmony_ci${OpenName} | Original UCM card name (passed to snd_use_case_mgr_open()) 390d5ac70f0Sopenharmony_ci${ConfLibDir} | Library top-level configuration directory (e.g. /usr/share/alsa) 391d5ac70f0Sopenharmony_ci${ConfTopDir} | Top-level UCM configuration directory (e.g. /usr/share/alsa/ucm2) 392d5ac70f0Sopenharmony_ci${ConfDir} | Card's UCM configuration directory (e.g. /usr/share/alsa/ucm2/conf.d/USB-Audio) 393d5ac70f0Sopenharmony_ci${ConfName} | Configuration name (e.g. USB-Audio.conf) 394d5ac70f0Sopenharmony_ci${CardNumber} | Real ALSA card number (or empty string for the virtual UCM card) 395d5ac70f0Sopenharmony_ci${CardId} | ALSA card identifier (see snd_ctl_card_info_get_id()) 396d5ac70f0Sopenharmony_ci${CardDriver} | ALSA card driver (see snd_ctl_card_info_get_driver()) 397d5ac70f0Sopenharmony_ci${CardName} | ALSA card name (see snd_ctl_card_info_get_name()) 398d5ac70f0Sopenharmony_ci${CardLongName} | ALSA card long name (see snd_ctl_card_info_get_longname()) 399d5ac70f0Sopenharmony_ci${CardComponents} | ALSA card components (see snd_ctl_card_info_get_components()) 400d5ac70f0Sopenharmony_ci${env:\<str\>} | Environment variable \<str\> 401d5ac70f0Sopenharmony_ci${sys:\<str\>} | Contents of sysfs file \<str\> 402d5ac70f0Sopenharmony_ci${var:\<str\>} | UCM parser variable (set using a _Define_ block) 403d5ac70f0Sopenharmony_ci${eval:\<str\>} | Evaluate expression like *($var+2)/3* [**Syntax 5**] 404d5ac70f0Sopenharmony_ci${find-card:\<str\>} | Find a card - see _Find card substitution_ section 405d5ac70f0Sopenharmony_ci${find-device:\<str\>} | Find a device - see _Find device substitution_ section 406d5ac70f0Sopenharmony_ci 407d5ac70f0Sopenharmony_ci#### Special whole string substitution 408d5ac70f0Sopenharmony_ci 409d5ac70f0Sopenharmony_ciSubstituted string | Value 410d5ac70f0Sopenharmony_ci---------------------|--------------------- 411d5ac70f0Sopenharmony_ci${evali:\<str\>} | Evaluate expression like *($var+2)/3* [**Syntax 6**]; target node will be integer; substituted only in the LibraryConfig subtree 412d5ac70f0Sopenharmony_ci 413d5ac70f0Sopenharmony_ci#### Find card substitution 414d5ac70f0Sopenharmony_ci 415d5ac70f0Sopenharmony_ciThis substitutions finds the ALSA card and returns the appropriate identifier or 416d5ac70f0Sopenharmony_cithe card number (see return argument). 417d5ac70f0Sopenharmony_ci 418d5ac70f0Sopenharmony_ciUsage example: 419d5ac70f0Sopenharmony_ci 420d5ac70f0Sopenharmony_ci~~~{.html} 421d5ac70f0Sopenharmony_ci${find-card:field=name,regex='^acp$',return=number} 422d5ac70f0Sopenharmony_ci~~~ 423d5ac70f0Sopenharmony_ci 424d5ac70f0Sopenharmony_ciArguments: 425d5ac70f0Sopenharmony_ci 426d5ac70f0Sopenharmony_ciArgument | Description 427d5ac70f0Sopenharmony_ci---------------------|----------------------- 428d5ac70f0Sopenharmony_cireturn | return value type (id, number), id is the default 429d5ac70f0Sopenharmony_cifield | field for the lookup (id, driver, name, longname, mixername, components) 430d5ac70f0Sopenharmony_ciregex | regex string for the field match 431d5ac70f0Sopenharmony_ci 432d5ac70f0Sopenharmony_ci#### Find device substitution 433d5ac70f0Sopenharmony_ci 434d5ac70f0Sopenharmony_ciUsage example: 435d5ac70f0Sopenharmony_ci 436d5ac70f0Sopenharmony_ci~~~{.html} 437d5ac70f0Sopenharmony_ci${find-device:type=pcm,field=name,regex='DMIC'} 438d5ac70f0Sopenharmony_ci~~~ 439d5ac70f0Sopenharmony_ci 440d5ac70f0Sopenharmony_ciArguments: 441d5ac70f0Sopenharmony_ci 442d5ac70f0Sopenharmony_ciArgument | Description 443d5ac70f0Sopenharmony_ci---------------------|----------------------- 444d5ac70f0Sopenharmony_citype | device type (pcm) 445d5ac70f0Sopenharmony_cistream | stream type (playback, capture), playback is default 446d5ac70f0Sopenharmony_cifield | field for the lookup (id, name, subname) 447d5ac70f0Sopenharmony_ciregex | regex string for the field match 448d5ac70f0Sopenharmony_ci 449d5ac70f0Sopenharmony_ci 450d5ac70f0Sopenharmony_ci### Variable defines 451d5ac70f0Sopenharmony_ci 452d5ac70f0Sopenharmony_ciThe variables can be defined and altered with the *Define* or *DefineRegex* blocks. 453d5ac70f0Sopenharmony_ciThe *Define* block looks like: 454d5ac70f0Sopenharmony_ci 455d5ac70f0Sopenharmony_ci~~~{.html} 456d5ac70f0Sopenharmony_ciDefine { 457d5ac70f0Sopenharmony_ci variable1 "a" 458d5ac70f0Sopenharmony_ci variable2 "b" 459d5ac70f0Sopenharmony_ci} 460d5ac70f0Sopenharmony_ci~~~ 461d5ac70f0Sopenharmony_ci 462d5ac70f0Sopenharmony_ciThe *DefineRegex* allows substring extraction like: 463d5ac70f0Sopenharmony_ci 464d5ac70f0Sopenharmony_ci~~~{.html} 465d5ac70f0Sopenharmony_ciDefineRegex.rval { 466d5ac70f0Sopenharmony_ci Regex "(hello)|(regex)" 467d5ac70f0Sopenharmony_ci String "hello, it's my regex" 468d5ac70f0Sopenharmony_ci} 469d5ac70f0Sopenharmony_ci~~~ 470d5ac70f0Sopenharmony_ci 471d5ac70f0Sopenharmony_ciThe result will be stored to variables *rval1* as *hello* and *rval2* as *regex* (every matched 472d5ac70f0Sopenharmony_cisubstrings are stored to a separate variable with the sequence number postfix. 473d5ac70f0Sopenharmony_ci 474d5ac70f0Sopenharmony_ciVariables can be substituted using the `${var:rval1}` reference for example. 475d5ac70f0Sopenharmony_ci 476d5ac70f0Sopenharmony_ci### Macros 477d5ac70f0Sopenharmony_ci 478d5ac70f0Sopenharmony_ciMacros were added for *Syntax* version *6*. The *DefineMacro* defines new 479d5ac70f0Sopenharmony_cimacro like: 480d5ac70f0Sopenharmony_ci 481d5ac70f0Sopenharmony_ci~~~{.html} 482d5ac70f0Sopenharmony_ciDefineMacro.macro1 { 483d5ac70f0Sopenharmony_ci Define.a "${var:__arg1}" 484d5ac70f0Sopenharmony_ci Define.b "${var:__other}" 485d5ac70f0Sopenharmony_ci # Device or any other block may be defined here... 486d5ac70f0Sopenharmony_ci} 487d5ac70f0Sopenharmony_ci~~~ 488d5ac70f0Sopenharmony_ci 489d5ac70f0Sopenharmony_ciThe arguments in the macro are refered as the variables with the double 490d5ac70f0Sopenharmony_ciunderscore name prefix (like *__variable*). The configuration block in 491d5ac70f0Sopenharmony_cithe DefineMacro subtree is always evaluated (including arguments and variables) 492d5ac70f0Sopenharmony_ciat the time of the instantiation. 493d5ac70f0Sopenharmony_ci 494d5ac70f0Sopenharmony_ciThe macros can be instantiated (expanded) using: 495d5ac70f0Sopenharmony_ci 496d5ac70f0Sopenharmony_ci~~~{.html} 497d5ac70f0Sopenharmony_ci# short version 498d5ac70f0Sopenharmony_ciMacro.id1.macro1 "arg1='something 1',other='other x'" 499d5ac70f0Sopenharmony_ci 500d5ac70f0Sopenharmony_ci# long version 501d5ac70f0Sopenharmony_ciMacro.id1.macro1 { 502d5ac70f0Sopenharmony_ci arg1 'something 1' 503d5ac70f0Sopenharmony_ci other 'other x' 504d5ac70f0Sopenharmony_ci} 505d5ac70f0Sopenharmony_ci~~~ 506d5ac70f0Sopenharmony_ci 507d5ac70f0Sopenharmony_ciThe second identifier (in example as *id1*) must be unique, but the contents 508d5ac70f0Sopenharmony_ciis ignored. It just differentiate the items in the subtree (allowing multiple 509d5ac70f0Sopenharmony_ciinstances for one macro). 510d5ac70f0Sopenharmony_ci 511d5ac70f0Sopenharmony_ci### Conditions 512d5ac70f0Sopenharmony_ci 513d5ac70f0Sopenharmony_ciThe configuration tree evaluation supports the conditions - *If* blocks. Each *If* blocks 514d5ac70f0Sopenharmony_cimust define a *Condition* block and *True* or *False* blocks or both. The *True* or *False* 515d5ac70f0Sopenharmony_ciblocks will be merged to the parent tree (where the *If* block is defined) when 516d5ac70f0Sopenharmony_cithe *Condition* is evaluated. 517d5ac70f0Sopenharmony_ci 518d5ac70f0Sopenharmony_ciExample: 519d5ac70f0Sopenharmony_ci 520d5ac70f0Sopenharmony_ci~~~{.html} 521d5ac70f0Sopenharmony_ciIf.uniqueid { 522d5ac70f0Sopenharmony_ci Condition { 523d5ac70f0Sopenharmony_ci Type String 524d5ac70f0Sopenharmony_ci Haystack "abcd" 525d5ac70f0Sopenharmony_ci Needle "a" 526d5ac70f0Sopenharmony_ci } 527d5ac70f0Sopenharmony_ci True { 528d5ac70f0Sopenharmony_ci Define.a a 529d5ac70f0Sopenharmony_ci define.b b 530d5ac70f0Sopenharmony_ci } 531d5ac70f0Sopenharmony_ci} 532d5ac70f0Sopenharmony_ci~~~ 533d5ac70f0Sopenharmony_ci 534d5ac70f0Sopenharmony_ci#### True (Type AlwaysTrue) 535d5ac70f0Sopenharmony_ci 536d5ac70f0Sopenharmony_ciExecute only *True* block. It may be used to change the evaluation order as 537d5ac70f0Sopenharmony_ciexplained in the *Configuration Tree* paragraph. 538d5ac70f0Sopenharmony_ci 539d5ac70f0Sopenharmony_ci#### String is empty (Type String) 540d5ac70f0Sopenharmony_ci 541d5ac70f0Sopenharmony_ciField | Description 542d5ac70f0Sopenharmony_ci---------------------|----------------------- 543d5ac70f0Sopenharmony_ciEmpty | string 544d5ac70f0Sopenharmony_ci 545d5ac70f0Sopenharmony_ci#### Strings are equal (Type String) 546d5ac70f0Sopenharmony_ci 547d5ac70f0Sopenharmony_ciField | Description 548d5ac70f0Sopenharmony_ci---------------------|----------------------- 549d5ac70f0Sopenharmony_ciString1 | string 550d5ac70f0Sopenharmony_ciString2 | substring in string 551d5ac70f0Sopenharmony_ci 552d5ac70f0Sopenharmony_ci#### Substring is present (Type String) 553d5ac70f0Sopenharmony_ci 554d5ac70f0Sopenharmony_ciField | Description 555d5ac70f0Sopenharmony_ci---------------------|----------------------- 556d5ac70f0Sopenharmony_ciHaystack | string 557d5ac70f0Sopenharmony_ciNeedle | substring in string 558d5ac70f0Sopenharmony_ci 559d5ac70f0Sopenharmony_ci#### Regex match (Type RegexMatch) 560d5ac70f0Sopenharmony_ci 561d5ac70f0Sopenharmony_ciField | Description 562d5ac70f0Sopenharmony_ci---------------------|----------------------- 563d5ac70f0Sopenharmony_ciString | string 564d5ac70f0Sopenharmony_ciRegex | regex expression (extended posix, ignore case) 565d5ac70f0Sopenharmony_ci 566d5ac70f0Sopenharmony_ci#### ALSA control element exists (Type ControlExists) 567d5ac70f0Sopenharmony_ci 568d5ac70f0Sopenharmony_ciField | Description 569d5ac70f0Sopenharmony_ci---------------------|----------------------- 570d5ac70f0Sopenharmony_ciDevice | ALSA control device (see snd_ctl_open()) 571d5ac70f0Sopenharmony_ciControl | control in ASCII (parsed using snd_ctl_ascii_elem_id_parse()) 572d5ac70f0Sopenharmony_ciControlEnum | value for the enum control (optional) 573d5ac70f0Sopenharmony_ci 574d5ac70f0Sopenharmony_ciExample: 575d5ac70f0Sopenharmony_ci 576d5ac70f0Sopenharmony_ci~~~{.html} 577d5ac70f0Sopenharmony_ciIf.fmic { 578d5ac70f0Sopenharmony_ci Condition { 579d5ac70f0Sopenharmony_ci Type ControlExists 580d5ac70f0Sopenharmony_ci Control "name='Front Mic Playback Switch'" 581d5ac70f0Sopenharmony_ci } 582d5ac70f0Sopenharmony_ci True { 583d5ac70f0Sopenharmony_ci ... 584d5ac70f0Sopenharmony_ci } 585d5ac70f0Sopenharmony_ci} 586d5ac70f0Sopenharmony_ci~~~ 587d5ac70f0Sopenharmony_ci 588d5ac70f0Sopenharmony_ci### Variants 589d5ac70f0Sopenharmony_ci 590d5ac70f0Sopenharmony_ciTo avoid duplication of the many configuration files for the cases with 591d5ac70f0Sopenharmony_ciminimal configuration changes, there is the variant extension. Variants were 592d5ac70f0Sopenharmony_ciadded for *Syntax* version *6*. 593d5ac70f0Sopenharmony_ci 594d5ac70f0Sopenharmony_ciThe bellow example will create two verbs - "HiFi" and "HiFi 7.1" with 595d5ac70f0Sopenharmony_cithe different playback channels (2 and 8) for the "Speaker" device. 596d5ac70f0Sopenharmony_ci 597d5ac70f0Sopenharmony_ciExample (main configuration file): 598d5ac70f0Sopenharmony_ci 599d5ac70f0Sopenharmony_ci~~~{.html} 600d5ac70f0Sopenharmony_ciSectionUseCase."HiFi" { 601d5ac70f0Sopenharmony_ci File "HiFi.conf" 602d5ac70f0Sopenharmony_ci Variant."HiFi" { 603d5ac70f0Sopenharmony_ci Comment "HiFi" 604d5ac70f0Sopenharmony_ci } 605d5ac70f0Sopenharmony_ci Variant."HiFi 7+1" { 606d5ac70f0Sopenharmony_ci Comment "HiFi 7.1" 607d5ac70f0Sopenharmony_ci } 608d5ac70f0Sopenharmony_ci} 609d5ac70f0Sopenharmony_ci~~~ 610d5ac70f0Sopenharmony_ci 611d5ac70f0Sopenharmony_ciExample (verb configuration file - HiFi.conf): 612d5ac70f0Sopenharmony_ci 613d5ac70f0Sopenharmony_ci~~~{.html} 614d5ac70f0Sopenharmony_ciSectionDevice."Speaker" { 615d5ac70f0Sopenharmony_ci Value { 616d5ac70f0Sopenharmony_ci PlaybackChannels 2 617d5ac70f0Sopenharmony_ci } 618d5ac70f0Sopenharmony_ci Variant."HiFi 7+1".Value { 619d5ac70f0Sopenharmony_ci PlaybackChannels 8 620d5ac70f0Sopenharmony_ci } 621d5ac70f0Sopenharmony_ci} 622d5ac70f0Sopenharmony_ci~~~ 623d5ac70f0Sopenharmony_ci 624d5ac70f0Sopenharmony_ci*/ 625d5ac70f0Sopenharmony_ci 626d5ac70f0Sopenharmony_ci/** 627d5ac70f0Sopenharmony_ci \} 628d5ac70f0Sopenharmony_ci */ 629