# Enable TinyALSA-based applications

TinyALSA is a library that wraps the ALSA kernel interface into APIs that
clients can invoke. It also gives a plug-in interface to emulate ALSA
APIs.

Find TinyALSA source code at:

`build-qcom-wayland/workspace/sources/tinyalsa` and

`build-qcom-wayland/workspace/sources/tinycompress`.

The following figure shows the TinyALSA plug-in architecture.

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<!-- Generated by Microsoft Visio, SVG Export tinyalsa_plugin_architecture.svg Page-1 -->
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ev="http://www.w3.org/2001/xml-events" xmlns:v="http://schemas.microsoft.com/visio/2003/SVGExtensions/" width="12.4375in" height="6.84028in" viewbox="0 0 895.5 492.5" xml:space="preserve" color-interpolation-filters="sRGB" class="st13" aria-label="../../_images/tinyalsa_plugin_architecture.svg"><v:documentproperties v:langid="1033" v:viewmarkup="false">	<v:userdefs>		<v:ud v:nameu="msvNoAutoConnect" v:val="VT0(1):26"></v:ud>	</v:userdefs></v:documentproperties>
<style>.svg-1 .st1 { fill: #ffffff; stroke: none; stroke-linecap: round; stroke-linejoin: round; stroke-width: 1 }
.svg-1 .st2 { fill: #fafafa; stroke: #d2d7e1; stroke-linecap: round; stroke-linejoin: round; stroke-width: 1.5 }
.svg-1 .st3 { fill: #ffffff; stroke: #d2d7e1; stroke-linecap: round; stroke-linejoin: round; stroke-width: 2 }
.svg-1 .st4 { fill: #000000; font-family: Roboto; font-size: 1.00001em; letter-spacing: 0.0833327em }
.svg-1 .st5 { fill: #007884; stroke: #007884; stroke-linecap: round; stroke-linejoin: round; stroke-width: 2 }
.svg-1 .st6 { fill: #ffffff; font-family: Roboto; font-size: 1.00001em; letter-spacing: 0.0833327em }
.svg-1 .st7 { fill: #007884; stroke: #fafafa; stroke-linecap: round; stroke-linejoin: round; stroke-width: 2 }
.svg-1 .st8 { marker-end: url("#1-mrkr4-53"); marker-start: url("#1-mrkr4-51"); stroke: #000000; stroke-linecap: round; stroke-linejoin: round; stroke-width: 2 }
.svg-1 .st9 { fill: #000000; fill-opacity: 1; stroke: #000000; stroke-opacity: 1; stroke-width: 0.44247787610619 }
.svg-1 .st10 { fill: #007884; stroke: none; stroke-linecap: round; stroke-linejoin: round; stroke-width: 1 }
.svg-1 .st11 { fill: none; stroke: none; stroke-linecap: round; stroke-linejoin: round; stroke-width: 1 }
.svg-1 .st12 { fill: #000000; font-family: Roboto Mono; font-size: 1.00001em; font-weight: bold; letter-spacing: 0.0833327em }
.svg-1 .st13 { fill: none; fill-rule: evenodd; font-size: 12px; overflow: visible; stroke-linecap: square; stroke-miterlimit: 3 }</style>
<defs id="Markers">	<g id="lend4">		<path d="M 2 1 L 0 0 L 2 -1 L 2 1 " style="stroke:none"></path>	</g>	<marker id="1-mrkr4-51" class="st9" v:arrowtype="4" v:arrowsize="2" v:setback="4.34" refx="4.34" orient="auto" markerunits="strokeWidth" overflow="visible">		<use xlink:href="#lend4" transform="scale(2.26) "></use>	</marker>	<marker id="1-mrkr4-53" class="st9" v:arrowtype="4" v:arrowsize="2" v:setback="4.52" refx="-4.52" orient="auto" markerunits="strokeWidth" overflow="visible">		<use xlink:href="#lend4" transform="scale(-2.26,-2.26) "></use>	</marker></defs><g v:mid="4" v:index="1" v:groupcontext="backgroundPage">	<v:userdefs>		<v:ud v:nameu="msvVisioCreated" v:prompt="" v:val="VT0(0):26"></v:ud>	</v:userdefs>	<title>VBackground-1</title>	<v:pageproperties width="12.4375" height="6.84028" v:drawingscale="0.0138889" v:pagescale="0.0138889" v:drawingunits="29" v:shadowoffsetx="9" v:shadowoffsety="-9"></v:pageproperties>	<g id="shape1-1" v:mid="1" v:groupcontext="shape">		<title>Solid</title>		<v:userdefs>			<v:ud v:nameu="Background" v:val="VT0(0):26"></v:ud>			<v:ud v:nameu="visVersion" v:val="VT0(15):26"></v:ud>			<v:ud v:nameu="msvShapeCategories" v:prompt="" v:val="VT4(DoNotContain)"></v:ud>			<v:ud v:nameu="msvVisioCreated" v:prompt="" v:val="VT0(0):26"></v:ud>		</v:userdefs>		<rect x="0" y="0" width="895.5" height="492.5" rx="4.5" ry="4.5" class="st1"></rect>	</g></g><g v:mid="0" v:index="2" v:groupcontext="foregroundPage">	<title>Page-1</title>	<v:pageproperties v:drawingscale="0.0138889" v:pagescale="0.0138889" v:drawingunits="29" v:shadowoffsetx="9" v:shadowoffsety="-9"></v:pageproperties>	<v:layer v:name="Connector" v:index="0"></v:layer>	<g id="shape42-3" v:mid="42" v:groupcontext="shape" transform="translate(18.75,-18.75)">		<title>Sheet.42</title>		<rect x="0" y="37.5" width="858" height="455" rx="4.5" ry="4.5" class="st2"></rect>	</g>	<g id="shape13-5" v:mid="13" v:groupcontext="shape" transform="translate(37.75,-245.75)">		<title>Sheet.13</title>		<desc>TinyALSA</desc>		<v:textblock v:margins="rect(4,4,4,4)" v:verticalalign="0"></v:textblock>		<v:textrect cx="183" cy="452.5" width="366" height="80"></v:textrect>		<rect x="0" y="412.5" width="366" height="80" rx="4.5" ry="4.5" class="st3"></rect>		<text x="4" y="430" class="st4" v:langid="1033"><v:paragraph v:spline="-1.5"></v:paragraph><v:tablist></v:tablist>TinyALSA</text>		</g>	<g id="shape14-8" v:mid="14" v:groupcontext="shape" transform="translate(419.75,-245.75)">		<title>Sheet.14</title>		<desc>Tiny compress</desc>		<v:textblock v:margins="rect(4,4,4,4)" v:verticalalign="0"></v:textblock>		<v:textrect cx="97" cy="452.5" width="194.01" height="80"></v:textrect>		<rect x="0" y="412.5" width="194" height="80" rx="4.5" ry="4.5" class="st3"></rect>		<text x="4" y="430" class="st4" v:langid="1033"><v:paragraph v:spline="-1.5"></v:paragraph><v:tablist></v:tablist>Tiny compress</text>		</g>	<g id="shape1-11" v:mid="1" v:groupcontext="shape" transform="translate(37.75,-421.75)">		<title>Sheet.1</title>		<desc>Client</desc>		<v:textblock v:margins="rect(4,4,4,4)"></v:textblock>		<v:textrect cx="288" cy="476.5" width="576" height="32"></v:textrect>		<rect x="0" y="460.5" width="576" height="32" rx="4.5" ry="4.5" class="st3"></rect>		<text x="269.73" y="481" class="st4" v:langid="1033"><v:paragraph v:spline="-1.5" v:horizalign="1"></v:paragraph><v:tablist></v:tablist>Client</text>		</g>	<g id="shape2-14" v:mid="2" v:groupcontext="shape" transform="translate(37.75,-117.75)">		<title>Sheet.2</title>		<desc>ALSA/ASoC kernel framework</desc>		<v:textblock v:margins="rect(4,4,4,4)"></v:textblock>		<v:textrect cx="288" cy="476.5" width="576" height="32"></v:textrect>		<rect x="0" y="460.5" width="576" height="32" rx="4.5" ry="4.5" class="st5"></rect>		<text x="195.13" y="481" class="st6" v:langid="1033"><v:paragraph v:spline="-1.5" v:horizalign="1"></v:paragraph><v:tablist></v:tablist>ALSA/ASoC kernel framework</text>		</g>	<g id="shape3-17" v:mid="3" v:groupcontext="shape" transform="translate(421.75,-181.75)">		<title>Sheet.3</title>		<desc>Compress plugin</desc>		<v:textblock v:margins="rect(4,4,4,4)"></v:textblock>		<v:textrect cx="64.1364" cy="476.5" width="128.28" height="32"></v:textrect>		<rect x="0" y="460.5" width="128.273" height="32" rx="4.5" ry="4.5" class="st5"></rect>		<text x="11.54" y="481" class="st6" v:langid="1033"><v:paragraph v:spline="-1.5" v:horizalign="1"></v:paragraph><v:tablist></v:tablist>Compress plugin</text>		</g>	<g id="shape4-20" v:mid="4" v:groupcontext="shape" transform="translate(37.75,-181.75)">		<title>Sheet.4</title>		<desc>PCM plugin</desc>		<v:textblock v:margins="rect(4,4,4,4)"></v:textblock>		<v:textrect cx="64.1364" cy="476.5" width="128.28" height="32"></v:textrect>		<rect x="0" y="460.5" width="128.273" height="32" rx="4.5" ry="4.5" class="st5"></rect>		<text x="28.46" y="481" class="st6" v:langid="1033"><v:paragraph v:spline="-1.5" v:horizalign="1"></v:paragraph><v:tablist></v:tablist>PCM plugin</text>		</g>	<g id="shape5-23" v:mid="5" v:groupcontext="shape" transform="translate(230.614,-181.75)">		<title>Sheet.5</title>		<desc>Mixer plugin</desc>		<v:textblock v:margins="rect(4,4,4,4)"></v:textblock>		<v:textrect cx="64.1364" cy="476.5" width="128.28" height="32"></v:textrect>		<rect x="0" y="460.5" width="128.273" height="32" rx="4.5" ry="4.5" class="st5"></rect>		<text x="25.51" y="481" class="st6" v:langid="1033"><v:paragraph v:spline="-1.5" v:horizalign="1"></v:paragraph><v:tablist></v:tablist>Mixer plugin</text>		</g>	<g id="shape6-26" v:mid="6" v:groupcontext="shape" transform="translate(67.4773,-261.75)">		<title>Sheet.6</title>		<desc>PCM</desc>		<v:textblock v:margins="rect(4,4,4,4)"></v:textblock>		<v:textrect cx="64.1364" cy="476.5" width="128.28" height="32"></v:textrect>		<rect x="0" y="460.5" width="128.273" height="32" rx="4.5" ry="4.5" class="st5"></rect>		<text x="49.71" y="481" class="st6" v:langid="1033"><v:paragraph v:spline="-1.5" v:horizalign="1"></v:paragraph><v:tablist></v:tablist>PCM</text>		</g>	<g id="shape7-29" v:mid="7" v:groupcontext="shape" transform="translate(257.614,-357.75)">		<title>Sheet.7</title>		<desc>Libaudioroute</desc>		<v:textblock v:margins="rect(4,4,4,4)"></v:textblock>		<v:textrect cx="64.1364" cy="476.5" width="128.28" height="32"></v:textrect>		<rect x="0" y="460.5" width="128.273" height="32" rx="4.5" ry="4.5" class="st5"></rect>		<text x="20.85" y="481" class="st6" v:langid="1033"><v:paragraph v:spline="-1.5" v:horizalign="1"></v:paragraph><v:tablist></v:tablist>Libaudioroute</text>		</g>	<g id="shape8-32" v:mid="8" v:groupcontext="shape" transform="translate(257.614,-261.75)">		<title>Sheet.8</title>		<desc>Mixer</desc>		<v:textblock v:margins="rect(4,4,4,4)"></v:textblock>		<v:textrect cx="64.1364" cy="476.5" width="128.28" height="32"></v:textrect>		<rect x="0" y="460.5" width="128.273" height="32" rx="4.5" ry="4.5" class="st5"></rect>		<text x="46.76" y="481" class="st6" v:langid="1033"><v:paragraph v:spline="-1.5" v:horizalign="1"></v:paragraph><v:tablist></v:tablist>Mixer</text>		</g>	<g id="shape9-35" v:mid="9" v:groupcontext="shape" transform="translate(451.477,-261.75)">		<title>Sheet.9</title>		<desc>Compress</desc>		<v:textblock v:margins="rect(4,4,4,4)"></v:textblock>		<v:textrect cx="64.1364" cy="476.5" width="128.28" height="32"></v:textrect>		<rect x="0" y="460.5" width="128.273" height="32" rx="4.5" ry="4.5" class="st5"></rect>		<text x="32.79" y="481" class="st6" v:langid="1033"><v:paragraph v:spline="-1.5" v:horizalign="1"></v:paragraph><v:tablist></v:tablist>Compress</text>		</g>	<g id="shape10-38" v:mid="10" v:groupcontext="shape" transform="translate(267.477,-53.75)">		<title>Sheet.10</title>		<rect x="0" y="460.5" width="120.273" height="32" rx="4.5" ry="4.5" class="st5"></rect>	</g>	<g id="shape11-40" v:mid="11" v:groupcontext="shape" transform="translate(259.75,-45.75)">		<title>Sheet.11</title>		<rect x="0" y="460.5" width="120.273" height="32" rx="4.5" ry="4.5" class="st7"></rect>	</g>	<g id="shape12-42" v:mid="12" v:groupcontext="shape" transform="translate(251.75,-37.75)">		<title>Sheet.12</title>		<desc>ASoC drivers</desc>		<v:textblock v:margins="rect(4,4,4,4)"></v:textblock>		<v:textrect cx="60.1364" cy="476.5" width="120.28" height="32"></v:textrect>		<rect x="0" y="460.5" width="120.273" height="32" rx="4.5" ry="4.5" class="st7"></rect>		<text x="19.77" y="481" class="st6" v:langid="1033"><v:paragraph v:spline="-1.5" v:horizalign="1"></v:paragraph><v:tablist></v:tablist>ASoC drivers</text>		</g>	<g id="shape15-45" v:mid="15" v:groupcontext="shape" v:layermember="0" transform="translate(311.25,-421.75)">		<title>Dynamic connector</title>		<path d="M12.5 501.18 L12.5 501.54 L12.5 515.46" class="st8"></path>	</g>	<g id="shape16-54" v:mid="16" v:groupcontext="shape" v:layermember="0" transform="translate(311.25,-357.75)">		<title>Dynamic connector.16</title>		<path d="M12.5 501.18 L12.5 501.54 L12.5 547.46" class="st8"></path>	</g>	<g id="shape19-61" v:mid="19" v:groupcontext="shape" v:layermember="0" transform="translate(511.25,-421.75)">		<title>Dynamic connector.19</title>		<path d="M12.5 501.18 L12.5 501.54 L12.5 611.46" class="st8"></path>	</g>	<g id="shape20-68" v:mid="20" v:groupcontext="shape" v:layermember="0" transform="translate(119.25,-421.75)">		<title>Dynamic connector.20</title>		<path d="M12.5 501.18 L12.5 501.54 L12.5 611.46" class="st8"></path>	</g>	<g id="shape21-75" v:mid="21" v:groupcontext="shape" v:layermember="0" transform="translate(103.08,-261.75)">		<title>Dynamic connector.21</title>		<path d="M12.5 501.18 L12.5 501.54 L12.5 531.46" class="st8"></path>	</g>	<g id="shape22-82" v:mid="22" v:groupcontext="shape" v:layermember="0" transform="translate(167.25,-261.75)">		<title>Dynamic connector.22</title>		<path d="M12.5 501.18 L12.5 501.54 L12.5 595.46" class="st8"></path>	</g>	<g id="shape24-89" v:mid="24" v:groupcontext="shape" v:layermember="0" transform="translate(359.25,-261.75)">		<title>Dynamic connector.24</title>		<path d="M12.5 501.18 L12.5 501.54 L12.5 595.46" class="st8"></path>	</g>	<g id="shape27-96" v:mid="27" v:groupcontext="shape" v:layermember="0" transform="translate(293.233,-261.75)">		<title>Dynamic connector.27</title>		<path d="M12.48 501.18 L12.48 501.54 L12.48 508.75 a0.0170428 0.0170428 -180 0 0 0.0170428 0.0170428 L12.5 508.77 a0.0170428					 0.0170428 0 0 1 0.0170428 0.0170428 L12.52 531.46" class="st8"></path>	</g>	<g id="shape28-103" v:mid="28" v:groupcontext="shape" v:layermember="0" transform="translate(551.25,-261.75)">		<title>Dynamic connector.28</title>		<path d="M12.5 501.18 L12.5 501.54 L12.5 595.46" class="st8"></path>	</g>	<g id="shape30-110" v:mid="30" v:groupcontext="shape" v:layermember="0" transform="translate(487.25,-261.75)">		<title>Dynamic connector.30</title>		<path d="M12.5 501.18 L12.5 501.54 L12.5 531.46" class="st8"></path>	</g>	<g id="shape31-117" v:mid="31" v:groupcontext="shape" v:layermember="0" transform="translate(219.75,-420.75)">		<title>Dynamic connector.31</title>		<path d="M0 501.18 L0 501.54 L0 635.5 L28.82 635.5" class="st8"></path>	</g>	<g id="shape32-124" v:mid="32" v:groupcontext="shape" v:layermember="0" transform="translate(311.25,-117.75)">		<title>Dynamic connector.32</title>		<path d="M12.5 501.18 L12.5 501.54 L12.5 523.46" class="st8"></path>	</g>	<g id="shape34-131" v:mid="34" v:groupcontext="shape" transform="translate(642.75,-40.75)">		<title>Sheet.34</title>		<rect x="0" y="476.5" width="40" height="16" rx="4.5" ry="4.5" class="st10"></rect>	</g>	<g id="shape40-133" v:mid="40" v:groupcontext="shape" transform="translate(692.45,-38.75)">		<title>Sheet.40</title>		<desc>Open source/Framework</desc>		<v:textblock v:margins="rect(4,4,4,4)"></v:textblock>		<v:textrect cx="83.15" cy="482.5" width="166.3" height="20"></v:textrect>		<rect x="0" y="472.5" width="166.3" height="20" rx="4.5" ry="4.5" class="st11"></rect>		<text x="6.49" y="487" class="st4" v:langid="1033"><v:paragraph v:spline="-1.5" v:horizalign="1"></v:paragraph><v:tablist></v:tablist>Open source/Framework</text>		</g>	<g id="shape41-136" v:mid="41" v:groupcontext="shape" transform="translate(628.35,-60.25)">		<title>Sheet.41</title>		<desc>Legend</desc>		<v:textblock v:margins="rect(4,4,4,4)"></v:textblock>		<v:textrect cx="39.2" cy="481.25" width="78.4" height="22.5"></v:textrect>		<rect x="0" y="470" width="78.4" height="22.5" rx="4.5" ry="4.5" class="st11"></rect>		<text x="14.6" y="485.75" class="st12" v:langid="1033"><v:paragraph v:spline="-1.5" v:horizalign="1"></v:paragraph><v:tablist></v:tablist>Legend</text>		</g></g>
</svg>

TinyALSA plug-in architecture

The ALSA framework in the kernel exposes card and device nodes for PCM,
compress, and mixer.

PCM, mixer, and compress plug-ins are TinyALSA plug-ins. They route all
PCM, mixer, and compress calls from the application to plug-in specific
implementation.

The plug-ins create a virtual sound card with PCM, compress, and mixer
nodes. Virtual nodes map to on-device `.so` files (dynamically
loadable shared objects).

The virtual sound card configuration is in
the `card-defs.xml` file. This file is in the `/etc/` folder
on the device.

## TinyALSA APIs

The following are common TinyALSA APIs. See the
[open source TinyALSA
documentation](https://github.com/tinyalsa/tinyalsa/blob/master/include/tinyalsa/pcm.h)
for a complete description of all APIs.

### pcm\_open

Opens a PCM audio device for input and output operations.
Initializes a PCM device for communication, allowing
read/write operations in audio data.

struct pcm *pcm_open(
         unsigned int card,
         unsigned int device,
         unsigned int flags,
         struct pcm_config *config)
    Copy to clipboard

**Parameters**

| card | Card number. |
| --- | --- |
| device | Device number in the chosen card. |
| flags | Flags to configure the PCM device. |
| config | Structure variable that specifies audio stream parameters. |

**Return value**

`pcm* handle`

### pcm\_is\_ready

Checks if the PCM device is ready for input and output operations.

int pcm_is_ready(struct pcm *pcm)
    Copy to clipboard

**Parameters**

| pcm | Pointer to the open PCM device. |
| --- | --- |

**Return value**

- Non-zero if the PCM device is ready
- 0 if the PCM device is not ready

### pcm\_prepare

Prepares audio device input and output operations.

int pcm_prepare(
         struct pcm *pcm)
    Copy to clipboard

**Parameters**

| pcm | Pointer to the open PCM device. |
| --- | --- |

**Return value**

- 0 on success
- Error code on failure

### pcm\_start

Starts the PCM audio device for input and output operations.

int pcm_start(
         struct pcm *pcm)
    Copy to clipboard

**Parameters**

| pcm | Pointer to the open PCM device. |
| --- | --- |

**Return value**

- 0 on success
- Error code on failure

### pcm\_write

Writes audio data to the audio PCM device. Takes audio data as
input and sends it to the PCM device for playback or processing.

int pcm_write(
         struct pcm *pcm,
         const void *data,
         unsigned int count)
    Copy to clipboard

**Parameters**

| pcm | Pointer to the open PCM device. |
| --- | --- |
| data | Audio data to write. |
| count | Number of audio frames to write. |

**Return value**

- 0 on success
- Error code on failure

### pcm\_read

Gets audio data from the PCM device, which allows the application
to capture audio data from a microphone.

int pcm_read(
         struct pcm *pcm,
         void *data,
         unsigned int count)
    Copy to clipboard

**Parameters**

| pcm | Pointer to the open PCM device. |
| --- | --- |
| data | Audio data to read. |
| count | Number of audio frames to read. |

**Return value**

- 0 on success
- Error code on failure

### pcm\_stop

Stops the PCM audio device from further input and output
operations.

int pcm_stop(
         struct pcm *pcm)
    Copy to clipboard

**Parameters**

| pcm | Pointer to the open PCM device. |
| --- | --- |

**Return value**

- 0 on success
- Error code on failure

### pcm\_close

Closes the PCM audio device. This releases the resources
associated with the PCM device and releases the memory.

int pcm_close(
         struct pcm *pcm)
    Copy to clipboard

**Parameters**

| pcm | Pointer to the open PCM device. |
| --- | --- |

**Return value**

- 0 on success
- Error code on failure

## Configure TinyALSA

For audio use cases from TinyALSA, configure the virtual mixer
controls.

These controls, created by the mixer plug-in, set up audio use case
graphs and modules. Most are byte array-based and are configured using the
`mixer_ctl_set_array` API. Metadata (referred to as ‘PCM100 metadata’)
is set using key-value (KV) pairs. For implementation details, see the
`set_agm_audio_intf_metadata` API in `build-qcom-wayland/workspace/sources/qcom-agm/opensource/agm/plugins/tinyalsa/test/agmmixer.c`.

/**
                * Key Vector pair
                */
                struct agm_key_value {
                uint32_t key; /**< key */
                uint32_t value; /**< value */
                };
                /*Sample allocation for the key value pair*/
                gkv = calloc(num_gkv, sizeof(struct agm_key_value));
                ckv = calloc(num_ckv, sizeof(struct agm_key_value));
    Copy to clipboard

Sample code for the TinyALSA-based agmplay and agmcap utilities can be
found at:

`build-qcom-wayland/workspace/sources/qcom-agm/opensource/agm/plugins/tinyalsa/test`.

To enable and execute audio use cases from TinyALSA:

1. Set the audio interface (backend) device configuration, including
sample rate, channels, format, and data format.

'CODEC_DMA-LPAIF_WSA-RX-0 rate ch fmt' 48000 2 2(PCM_16)
        Copy to clipboard
2. Set the metadata, including graph keys, cal keys for the device, and
DevicePP.

'CODEC_DMA-LPAIF_WSA-RX-0 metadata' bytes
        Copy to clipboard
3. Set the control to indicate that follow-on mixer configurations will
set the metadata for the stream and StreamPP subgraphs. Zero
indicates that subsequent commands are for the stream.

'PCM100 control' Zero
                            'PCM100 metadata' bytes
        Copy to clipboard
4. Set the control to indicate that follow on mixer configurations will
set the metadata for the DevicePP and stream-device subgraphs.
`CODEC_DMA-LPAIF_WSA-RX-0` indicates that the subsequent commands
are for stream-device. `CODEC_DMA-LPAIF_WSA-RX-0` is one of the
audio interfaces registered with the ALSA ASOC framework. A list of
all audio interfaces can be found at `/proc/asound/pcm`.

'PCM100 control' CODEC_DMA-LPAIF_WSA-RX-0
                            'PCM100 metadata' bytes
        Copy to clipboard
5. Retrieve all tags, module ID, and instance IDs associated with a
given session between the stream and audio interface.

'PCM100 getTaggedInfo' bytes
        Copy to clipboard
6. Set the control to indicate that follow on mixer configurations will
set the parameters for modules on the stream subgraph.

'PCM100 control' Zero
                            'PCM100 setParam' bytes
        Copy to clipboard
7. Set the control to indicate that follow on mixer configurations will
set the parameters for modules on the StreamDevice and DevicePP
subgraphs.

'PCM100 control' CODEC_DMA-LPAIF_WSA-RX-0
                            'PCM100 setParam' bytes
        Copy to clipboard
8. Connect the frontend (stream) with the backend (codec/audio
interface).

'PCM100 connect' CODEC_DMA-LPAIF_WSA-RX-0
        Copy to clipboard
9. Open the PCM device.

pcm_open
        Copy to clipboard
10. Prepare the audio device for input and output operations.

pcm_prepare
        Copy to clipboard
11. Start the PCM audio device for input and output operations.

pcm_start
        Copy to clipboard
12. Write and read audio data from the audio PCM device.

pcm_write/pcm_read
        Copy to clipboard
13. Stop the PCM device.

pcm_stop
        Copy to clipboard
14. Close the PCM audio device.

pcm_close
        Copy to clipboard

All mixer controls for a virtual device can be fetched using:

ssh root@ip-addr
    Copy to clipboard

systemctl stop pipewire
    Copy to clipboard

tinymix set -D 100
    Copy to clipboard

Last Published: May 14, 2026

[Previous Topic
Customize at PAL level](https://docs.qualcomm.com/bundle/publicresource/80-80022-16/topics/pal.md) [Next Topic
Customize audio graph](https://docs.qualcomm.com/bundle/publicresource/80-80022-16/topics/agm.md)