> ## Documentation Index
> Fetch the complete documentation index at: https://dragonwingdocs.qualcomm.com/llms.txt
> Use this file to discover all available pages before exploring further.

# 启用基于 TinyALSA 的应用程序

> 在 Qualcomm Linux 上使用 PCM API 和虚拟混音器控制启用基于 TinyALSA 的音频应用程序。

TinyALSA 是一个将 ALSA 内核接口封装为客户端可调用 API 的库。它还提供插件接口来模拟 ALSA API。

TinyALSA 源代码位于:

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

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

下图展示了 TinyALSA 插件架构。

<div className="flex flex-col items-center gap-2">
  <img src="https://mintcdn.com/qualcomm-prod/PyJ823JBh-_RDtS4/Technologies/Audio/media/qualcomm-linux-iot-audio-voice/tinyalsa_plugin_architecture.svg?fit=max&auto=format&n=PyJ823JBh-_RDtS4&q=85&s=d2737ec486529cb89240b34944cfe1ab" alt="TinyALSA 插件架构" width="1194" height="657" data-path="Technologies/Audio/media/qualcomm-linux-iot-audio-voice/tinyalsa_plugin_architecture.svg" />

  <p className="text-sm text-gray-700">
    TinyALSA 插件架构
  </p>
</div>

TinyALSATiny compressClientALSA/ASoC kernel frameworkCompress pluginPCM pluginMixer pluginPCMLibaudiorouteMixerCompressASoC driversOpen source/FrameworkLegend

TinyALSA 插件架构

内核中的 ALSA 框架为 PCM、compress 和混音器公开声卡和设备节点。

PCM、混音器和 compress 插件均为 TinyALSA 插件。它们将应用程序的所有 PCM、混音器和 compress 调用路由到插件特定的实现。

这些插件会创建一个带有 PCM、compress 和混音器节点的虚拟声卡。虚拟节点映射到设备上的 `.so` 文件(可动态加载的共享对象)。

虚拟声卡配置位于 `card-defs.xml` 文件中。该文件位于设备的 `/etc/` 文件夹中。

## **TinyALSA API**

以下是常用的 TinyALSA API。有关所有 API 的完整说明,请参阅[开源 TinyALSA 文档](https://github.com/tinyalsa/tinyalsa/blob/master/include/tinyalsa/pcm.h)。

### **pcm\_open**

打开 PCM 音频设备,用于输入和输出操作。初始化 PCM 设备以进行通信,允许对音频数据进行读/写操作。

```text theme={null}
struct pcm *pcm_open(
     unsigned int card,
     unsigned int device,
     unsigned int flags,
     struct pcm_config *config)
```

**参数**

| card   | 声卡编号。           |
| :----- | :-------------- |
| device | 所选声卡中的设备编号。     |
| flags  | 用于配置 PCM 设备的标志。 |
| config | 指定音频流参数的结构变量。   |

**返回值**

`pcm* handle`

### **pcm\_is\_ready**

检查 PCM 设备是否已准备好进行输入和输出操作。

```text theme={null}
int pcm_is_ready(struct pcm *pcm)
```

**参数**

| pcm | 指向已打开 PCM 设备的指针。 |
| :-- | :--------------- |

**返回值**

* PCM 设备就绪时返回非零值
* PCM 设备未就绪时返回 0

### **pcm\_prepare**

准备音频设备的输入和输出操作。

```text theme={null}
int pcm_prepare(
     struct pcm *pcm)
```

**参数**

| pcm | 指向已打开 PCM 设备的指针。 |
| :-- | :--------------- |

**返回值**

* 成功时返回 0
* 失败时返回错误代码

### **pcm\_start**

启动 PCM 音频设备,以进行输入和输出操作。

```text theme={null}
int pcm_start(
     struct pcm *pcm)
```

**参数**

| pcm | 指向已打开 PCM 设备的指针。 |
| :-- | :--------------- |

**返回值**

* 成功时返回 0
* 失败时返回错误代码

### **pcm\_write**

将音频数据写入 PCM 音频设备。以音频数据作为输入,并将其发送到 PCM 设备进行播放或处理。

```text theme={null}
int pcm_write(
     struct pcm *pcm,
     const void *data,
     unsigned int count)
```

**参数**

| pcm   | 指向已打开 PCM 设备的指针。 |
| :---- | :--------------- |
| data  | 要写入的音频数据。        |
| count | 要写入的音频帧数。        |

**返回值**

* 成功时返回 0
* 失败时返回错误代码

### **pcm\_read**

从 PCM 设备获取音频数据,允许应用程序从麦克风捕获音频数据。

```text theme={null}
int pcm_read(
     struct pcm *pcm,
     void *data,
     unsigned int count)
```

**参数**

| pcm   | 指向已打开 PCM 设备的指针。 |
| :---- | :--------------- |
| data  | 要读取的音频数据。        |
| count | 要读取的音频帧数。        |

**返回值**

* 成功时返回 0
* 失败时返回错误代码

### **pcm\_stop**

停止 PCM 音频设备的进一步输入和输出操作。

```text theme={null}
int pcm_stop(
     struct pcm *pcm)
```

**参数**

| pcm | 指向已打开 PCM 设备的指针。 |
| :-- | :--------------- |

**返回值**

* 成功时返回 0
* 失败时返回错误代码

### **pcm\_close**

关闭 PCM 音频设备。这会释放与 PCM 设备关联的资源并释放内存。

```text theme={null}
int pcm_close(
     struct pcm *pcm)
```

**参数**

| pcm | 指向已打开 PCM 设备的指针。 |
| :-- | :--------------- |

**返回值**

* 成功时返回 0
* 失败时返回错误代码

## **配置 TinyALSA**

对于来自 TinyALSA 的音频用例,请配置虚拟混音器控制。

这些由混音器插件创建的控制用于设置音频用例图和模块。大多数控制基于字节数组,并使用 `mixer_ctl_set_array` API 进行配置。元数据(称为 'PCM100 metadata')通过键值(KV)对设置。有关实现详情,请参阅 `build-qcom-wayland/workspace/sources/qcom-agm/opensource/agm/plugins/tinyalsa/test/agmmixer.c` 中的 `set_agm_audio_intf_metadata` API。

```text theme={null}
/**
            * 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));
```

基于 TinyALSA 的 agmplay 和 agmcap 实用工具的示例代码位于:

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

要启用并执行来自 TinyALSA 的音频用例:

1. 设置音频接口(后端)设备配置,包括采样率、声道、格式和数据格式。
   ```text theme={null}
   'CODEC_DMA-LPAIF_WSA-RX-0 rate ch fmt' 48000 2 2(PCM_16)
   ```
2. 设置元数据,包括图键、设备的校准键和 DevicePP。
   ```text theme={null}
   'CODEC_DMA-LPAIF_WSA-RX-0 metadata' bytes
   ```
3. 设置控制,以指示后续的混音器配置将为 stream 和 StreamPP 子图设置元数据。零表示后续命令针对 stream。
   ```text theme={null}
   'PCM100 control' Zero
                       'PCM100 metadata' bytes
   ```
4. 设置控制,以指示后续的混音器配置将为 DevicePP 和 stream-device 子图设置元数据。`CODEC_DMA-LPAIF_WSA-RX-0` 表示后续命令针对 stream-device。`CODEC_DMA-LPAIF_WSA-RX-0` 是在 ALSA ASOC 框架中注册的音频接口之一。所有音频接口的列表可在 `/proc/asound/pcm` 中找到。
   ```text theme={null}
   'PCM100 control' CODEC_DMA-LPAIF_WSA-RX-0
                       'PCM100 metadata' bytes
   ```
5. 检索与 stream 和音频接口之间给定会话关联的所有标签、模块 ID 和实例 ID。
   ```text theme={null}
   'PCM100 getTaggedInfo' bytes
   ```
6. 设置控制,以指示后续的混音器配置将为 stream 子图上的模块设置参数。
   ```text theme={null}
   'PCM100 control' Zero
                       'PCM100 setParam' bytes
   ```
7. 设置控制,以指示后续的混音器配置将为 StreamDevice 和 DevicePP 子图上的模块设置参数。
   ```text theme={null}
   'PCM100 control' CODEC_DMA-LPAIF_WSA-RX-0
                       'PCM100 setParam' bytes
   ```
8. 将前端(stream)与后端(编解码器/音频接口)连接。
   ```text theme={null}
   'PCM100 connect' CODEC_DMA-LPAIF_WSA-RX-0
   ```
9. 打开 PCM 设备。
   ```text theme={null}
   pcm_open
   ```
10. 准备音频设备的输入和输出操作。
    ```text theme={null}
    pcm_prepare
    ```
11. 启动 PCM 音频设备,以进行输入和输出操作。
    ```text theme={null}
    pcm_start
    ```
12. 向 PCM 音频设备写入和读取音频数据。
    ```text theme={null}
    pcm_write/pcm_read
    ```
13. 停止 PCM 设备。
    ```text theme={null}
    pcm_stop
    ```
14. 关闭 PCM 音频设备。
    ```text theme={null}
    pcm_close
    ```

可使用以下命令获取虚拟设备的所有混音器控制:

```text theme={null}
ssh root@ip-addr
```

```text theme={null}
systemctl stop pipewire
```

```text theme={null}
tinymix set -D 100
```

## **后续步骤**

* [自定义音频图](customize-audio-graph) — 在 PAL 层自定义音频用例
* [排查音频问题](troubleshoot-audio) — 捕获并分析音频日志以解决问题
* [音频补充文档](../audio-addendum-overview) — 使用 QACT 和 QXDM 进行校准和诊断
