xt-sdk 文档 v1.0.3
xt-sdk 嵌入式 SDK API 参考
载入中...
搜索中...
未找到
xt_audio_dev - 音频设备层

版本:0.1 | 日期:2026-07-03 | 路径: platforms/components/xtiny/xt_audio/


一、概述

xt_audio_dev 是音频设备抽象层,提供统一的播放、录音、全双工接口。用户通过一致的 API 操作不同硬件(DAC、I2S Codec 等),无需关心底层驱动差异。驱动通过 xt_audio_dev_register_drv() 预注册后,setup 时按 drv_name 匹配。

1.1 设计原则

  • 驱动解耦 :设备层通过统一的 ops 接口调用底层驱动,驱动需在 setup 前注册
  • 双模式录音 :支持持续模式( read_start_ext )和单次模式( read ),适应不同场景
  • 回调驱动 :事件(写入完成、读取就绪、错误等)通过回调通知上层
  • v% 参数 :每次 write/read 调用可指定音量 0-100,无需额外 API

1.2 依赖

依赖 用途
xt_audio_types.h 音频句柄、模式、回调、格式类型
xt_audio_dev_drv.h 驱动描述符和 ops 类型

二、核心概念

2.1 设备配置

struct xt_audio_dev_config 关键字段:

字段 类型 说明
drv_name const char * 匹配已注册驱动, NULL 或空串时取第一个注册的驱动
mode xt_audio_mode_t 模式: XT_AUDIO_MODE_IN / XT_AUDIO_MODE_OUT / 两者按位或
sample_freq uint16_t 采样率(Hz),如 8000、16000
sample_bits uint8_t 采样位深,如 16
channel_num uint8_t 通道数,如 1
frame_size uint16_t 帧大小(字节),公式见 xt_audio_types(音频类型定义)
write_wq_num uint8_t 写队列个数,决定可缓冲的未消费帧数
read_wq_num uint8_t 读队列个数,决定可缓冲的未读取帧数
evt_cb xt_audio_dev_evt_cb_t 事件回调
evt_cb_user_data void * 回调用户数据

2.2 设备事件

事件 说明
XT_AUDIO_DEV_EVT_NO_ERR 无错误
XT_AUDIO_DEV_EVT_WRITE_BATCH 写入单次完成(单次模式 write 后触发)
XT_AUDIO_DEV_EVT_WRITE_ERROR 写入出错
XT_AUDIO_DEV_EVT_WRITE_UNDERRUN 写入下溢(数据供给不足)
XT_AUDIO_DEV_EVT_READ_BATCH 读取单次完成(单次模式 read 后触发)
XT_AUDIO_DEV_EVT_READ_READY 读取就绪(持续模式 read_start_ext 后每帧回调)
XT_AUDIO_DEV_EVT_READ_ERROR 读取出错

2.3 播放流程

典型播放流程:

  1. 调用 xt_audio_dev_setup() 初始化设备
  2. 循环调用 xt_audio_dev_write() 写入 PCM 数据
  3. 若返回 XT_EFULL , osDelay 等待后重试
  4. 数据写完后 osDelay 等待缓冲区排空
  5. 调用 xt_audio_dev_stop() 停止, xt_audio_dev_close() 关闭

2.4 录音双模式

模式 启动函数 回调事件 行为
持续模式 xt_audio_dev_read_start_ext() READ_READY 每收到一帧回调一次,需在回调中读走数据
单次模式 xt_audio_dev_read() READ_BATCH 每次调用阻塞等待一帧数据返回

三、API 参考

以下为函数签名大纲,完整的参数说明、返回值、注意事项请查看 xt_audio_dev(音频设备) 。

3.1 生命周期

函数签名 说明
xt_err_t xt_audio_dev_setup(struct xt_audio_dev_config *cfg, xt_audio_t *hdl) 初始化音频设备
xt_err_t xt_audio_dev_close(xt_audio_t hdl) 关闭设备,释放资源
xt_err_t xt_audio_dev_stop_ext(xt_audio_t hdl, xt_audio_mode_t mode) 停止指定方向的传输, (xt_audio_mode_t)-1 停止全部
#define xt_audio_dev_stop(_hdl) 停止全部方向(宏包装)
#define xt_audio_dev_read_stop(_hdl) 停止读方向(宏包装)

3.2 数据收发

函数签名 说明
int xt_audio_dev_write_ext(xt_audio_t hdl, uint8_t *data, uint32_t size, struct xt_audio_dev_info *info) 写入数据(扩展版,info 可设回调/音量)
#define xt_audio_dev_write(_hdl, _data, _size, _level) 写入数据(简化版,只设音量)
int xt_audio_dev_read_ext(xt_audio_t hdl, uint8_t *data, uint32_t size, struct xt_audio_dev_info *info) 单次读取(扩展版)
#define xt_audio_dev_read(_hdl, _data, _size, _level) 单次读取(简化版,只设音量)
int xt_audio_dev_read_start_ext(xt_audio_t hdl, struct xt_audio_dev_info *info) 启动持续读取,通过回调返回数据

3.3 查询

函数签名 说明
xt_err_t xt_audio_dev_get_format(xt_audio_t hdl, struct xt_audio_format *fmt) 获取当前音频格式
uint16_t xt_audio_dev_get_frame_interval(xt_audio_t hdl) 获取帧间隔(ms)

3.4 休眠管理

函数签名 说明
xt_err_t xt_audio_dev_sleep(xt_audio_t hdl) 设备进入休眠(释放功耗)
xt_err_t xt_audio_dev_resume(xt_audio_t hdl) 设备从休眠恢复

3.5 驱动注册

函数签名 说明
xt_err_t xt_audio_dev_register_drv(struct xt_audio_dev_drv *drv) 注册驱动,必须在 setup 前调用
struct xt_audio_dev_drv *xt_audio_dev_get_drv(const char *name) 按名称查找已注册的驱动

四、常见模式

4.1 播放 PCM 数据

#include "xt_audio_dev.h"
/* setup */
xt_audio_t dev = NULL;
struct xt_audio_dev_config cfg = {
.drv_name = "codec",
.sample_freq = 8000,
.sample_bits = 16,
.channel_num = 1,
.frame_size = 640,
.write_wq_num = 8,
};
xt_audio_dev_setup(&cfg, &dev);
/* 循环写入 PCM */
int16_t frame[320];
for (int i = 0; i < 50; i++) {
/* 填充 frame */
int r;
do {
r = xt_audio_dev_write(dev, (uint8_t *)frame, sizeof(frame), 70);
if (r == XT_EFULL) {
osDelay(5);
}
} while (r == XT_EFULL);
}
/* 等待排空后停止 */
osDelay(1500);
#define xt_audio_dev_write(_hdl, _data, _size, _level)
xt_err_t xt_audio_dev_setup(struct xt_audio_dev_config *cfg, xt_audio_t *hdl)
初始化音频设备
#define xt_audio_dev_stop(_hdl)
xt_err_t xt_audio_dev_close(xt_audio_t hdl)
关闭音频设备
void * xt_audio_t
音频设备句柄类型
@ XT_AUDIO_MODE_OUT
#define XT_EFULL
音频设备配置结构体
音频设备抽象层(普通用户接口)

完整示例见: examples/platform_specific/lm620/audio_dev/src/test_codec_play.c

4.2 持续录音

#include "xt_audio_dev.h"
static uint8_t rec_buf[150][640];
static volatile uint32_t rec_cnt = 0;
static void rec_evt_cb(xt_audio_t hdl, enum xt_audio_dev_evt evt,
struct xt_audio_dev_cb_info *info)
{
if (evt == XT_AUDIO_DEV_EVT_READ_READY && rec_cnt < 150) {
memcpy(rec_buf[rec_cnt], info->data, info->size);
rec_cnt++;
}
}
void record_example(void)
{
xt_audio_t dev = NULL;
struct xt_audio_dev_config cfg = {
.drv_name = "codec",
.sample_freq = 16000,
.sample_bits = 16,
.channel_num = 1,
.frame_size = 640,
.read_wq_num = 2,
.evt_cb = rec_evt_cb,
};
xt_audio_dev_setup(&cfg, &dev);
struct xt_audio_dev_info info = { .level = 18 };
osDelay(3000);
/* 此时 rec_buf[0..rec_cnt-1] 存有录音数据 */
}
#define xt_audio_dev_read_stop(_hdl)
int xt_audio_dev_read_start_ext(xt_audio_t hdl, struct xt_audio_dev_info *info)
启动音频设备读取(扩展版本)
xt_audio_dev_evt
音频设备事件枚举
@ XT_AUDIO_DEV_EVT_READ_READY
@ XT_AUDIO_MODE_IN
音频设备回调信息结构体
音频设备操作信息结构体

完整示例见: examples/platform_specific/lm620/audio_dev/src/test_codec_record.c

4.3 全双工(录播回环)

struct xt_audio_dev_config cfg = {
.drv_name = "codec",
.sample_freq = 16000,
.sample_bits = 16,
.frame_size = 640,
.evt_cb = rec_evt_cb,
};
xt_audio_dev_setup(&cfg, &dev);
/* 启动持续录音 */
struct xt_audio_dev_info info = { .level = 18 };
osDelay(3000);
/* 回放录到的数据 */
for (uint32_t i = 0; i < rec_cnt; i++) {
int r;
do {
r = xt_audio_dev_write(dev, rec_buf[i], cfg.frame_size, 70);
if (r == XT_EFULL) osDelay(5);
} while (r == XT_EFULL);
}
osDelay(3500);
xt_audio_dev_evt_cb_t evt_cb

完整示例见: examples/platform_specific/lm620/audio_dev/src/test_codec_loopback.c


五、已知行为与限制

行为 说明
驱动必须预注册 xt_audio_dev_register_drv() 必须在 xt_audio_dev_setup() 前调用
write 返回 XT_EFULL 写缓冲区满,必须 osDelay 等待后重试,不可丢弃数据
write 数据大小建议等于 frame_size 每次写入量等于 frame_size 可获得最佳同步效果
stop 后必须 close stop 不释放资源,需调用 close 释放
fram_size 需精确计算 公式 sr * bits/8 * ch * ms / 1000 必须可整除
read/read_ext 为单次模式 每次调用阻塞等待一帧(触发 READ_BATCH 回调)
read_start_ext 为持续模式 启动后每帧通过回调推送数据(触发 READ_READY 回调)