跳转至

音频输出示例*

提示

1. 概述*

音频输出(DAC/SDM)示例 App,演示如何通过 DMA + 双缓冲机制播放本地 PCM 音频数据。音频数据来自 test_wav.h 中硬编码的 PCM 数组(16kHz、16bit、单声道),播放完毕后自动循环。

2. 功能特性*

  • DMA 双缓冲音频播放,实现无间断连续输出
  • 演示缓存一致性处理(gx_dcache_clean_range
  • 音量控制(0-100 映射到 -16dB ~ 0dB)
  • 自动循环播放

3. 目录结构*

app/audio_out_sample_app/
├── audio_out_sample_app.c  # 主程序
├── app.mk                   # 编译配置
├── app.name                 # Kconfig 选项
└── test_wav.h               # 测试 PCM 数据(16kHz、16bit、单声道)
文件 作用
audio_out_sample_app.c 音频播放初始化、DMA 配置、双缓冲回调
app.mk 编译 audio_out_sample_app.c
app.name 定义 CONFIG_APP_AUDIO_OUT 选项
test_wav.h PCM 音频原始数据(174080 字节)

4. 配置说明*

4.1 宏定义*

#define AUDIO_OUT_BUFFER_LEN  8192   // DMA 缓冲区大小,必须 64 字节对齐

PCM 数据长度在代码中硬编码:

uint32_t g_all_len = 174080;   // test_wav.h 中 PCM 数据的总字节数

4.2 引脚配置*

引脚 功能 说明
PAD 0 DAC_P DAC 正输出
PAD 1 DAC_N DAC 负输出

5. 工作原理*

5.1 初始化流程*

  1. 配置 PAD 0/1 为 DAC 模式
  2. 使能 AUDPCLKAOUT 时钟
  3. 初始化 SDM,配置 16kHz 单声道 PCM 参数
  4. 分配 8KB DMA 缓冲区
  5. 注册帧回调 _aout_new_frame_callback
  6. 将首帧 PCM 数据入队,使能音频路由

5.2 双缓冲机制*

8KB 缓冲池分为两个 4KB 半区:

中断回调填充半区 A  →  DMA 播放半区 A
                     ↓
中断回调填充半区 B  ←  DMA 播放半区 B

每次 _aout_new_frame_callback 被调用时,填充另一个半区并重新入队,实现无间断播放。

5.3 事件处理*

该 App 不使用事件驱动,所有播放逻辑在 DMA 中断回调中完成。app_event_response() 为空实现。

5.4 主循环*

app_task_loop() 为空实现。

6. 使用方法*

6.1 编译*

cp configs/example/app/8006_audio_out_sample_app.config .config
make defconfig
make clean; make

或通过 menuconfig 选择:

make menuconfig
# OVP Application Settings → Applications Selection → Audio Out Sample

6.2 烧录运行*

cd tools/bootx/
./flash_nor.sh 0 -r 1000000

7. 预期输出*

扬声器循环播放 test_wav.h 中的音频。

8. 注意事项*

  1. 缓存一致性:音频播放走 DMA 直接访问内存,不会经过 Cache,每帧数据入队前必须调用 gx_dcache_clean_range() 刷新 Cache
  2. 缓冲区对齐AUDIO_OUT_BUFFER_LEN 必须 64 字节对齐
  3. 中断上下文_aout_new_frame_callback 在中断上下文中执行,不应包含耗时操作
  4. PCM 参数test_wav.h 中的 PCM 数据固定为 16kHz、16bit、单声道格式,替换音频数据需保持相同参数
  5. 休眠/唤醒未实现:当前 SDK 不支持休眠功能,app_suspend()app_resume() 保持空实现即可