Audio 驱动
基于 lisa_device 框架的 Audio 设备驱动,为 ARCS 平台提供统一的音频录音(Record)和播放(Play)接口。
功能特性
设备支持: Audio0 音频设备
录音功能: 支持多通道录音、增益控制、高通滤波、差分输入
播放功能: 支持多通道播放、增益控制、缓冲区管理
音频格式: 灵活配置采样率(8kHz-96kHz)、通道数(单声道/立体声)、采样位深(16/24/32位)
统一回调: 提供统一的音频事件回调,同时接收录音数据和播放回声数据
相位补偿: 支持录音和播放之间的相位调整
控制功能: 支持启动、停止、暂停、恢复等控制操作
配置选项
在 prj.conf 中启用驱动:
CONFIG_LISA_AUDIO_DEVICE=y
CONFIG_LISA_AUDIO0=y # 启用 Audio0 设备
API 接口
回调管理接口
int lisa_audio_register_callback(lisa_device_t *dev, lisa_audio_callback_t callback, void *user_data);
int lisa_audio_unregister_callback(lisa_device_t *dev, lisa_audio_callback_t callback);
录音接口
// 配置
int lisa_audio_record_config(lisa_device_t *dev, const lisa_audio_record_config_t *config);
// 控制
int lisa_audio_record_start(lisa_device_t *dev);
int lisa_audio_record_stop(lisa_device_t *dev);
int lisa_audio_record_pause(lisa_device_t *dev);
int lisa_audio_record_resume(lisa_device_t *dev);
int lisa_audio_record_set_gain(lisa_device_t *dev, const lisa_audio_gain_t *gain);
播放接口
// 配置
int lisa_audio_play_config(lisa_device_t *dev, const lisa_audio_play_config_t *config);
// 数据传输
int lisa_audio_play_write(lisa_device_t *dev, const void *buffer, uint32_t samples);
int lisa_audio_play_get_buffer(lisa_device_t *dev, void **buffer, uint32_t timeout_ms);
// 控制
int lisa_audio_play_start(lisa_device_t *dev);
int lisa_audio_play_stop(lisa_device_t *dev);
int lisa_audio_play_flush(lisa_device_t *dev);
int lisa_audio_play_set_gain(lisa_device_t *dev, const lisa_audio_gain_t *gain);
通用接口
int lisa_audio_set_phase_compensation(lisa_device_t *dev, const lisa_audio_phase_compensation_t *compensation);
int lisa_audio_get_phase_compensation(lisa_device_t *dev, lisa_audio_phase_compensation_t *compensation);
int lisa_audio_ioctl(lisa_device_t *dev, uint8_t cmd, void *arg);
使用示例
基本录音配置与启动
#include "lisa_audio.h"
// 获取 Audio0 设备
lisa_device_t *audio0 = lisa_device_get("audio0");
if (!audio0) {
return -1;
}
// 配置录音参数
lisa_audio_record_config_t record_config = {
.format = {
.sample_rate = LISA_AUDIO_RATE_16K, // 16kHz 采样率
.channels = LISA_AUDIO_CH_LEFT, // 左声道
.sample_bits = LISA_AUDIO_BIT_16, // 16位采样
},
.gain = {
.analog_gain = 0, // 模拟增益 0dB
.digital_gain = 0, // 数字增益 0dB
},
.enable_hpf = true, // 启用高通滤波器
.differential_input = false, // 单端输入
.buffer_count = 2, // 2个缓冲区
.buffer_samples = 256, // 每个缓冲区256采样点
};
lisa_audio_record_config(audio0, &record_config);
// 启动录音
lisa_audio_record_start(audio0);
基本播放配置与数据写入
// 配置播放参数
lisa_audio_play_config_t play_config = {
.format = {
.sample_rate = LISA_AUDIO_RATE_16K, // 16kHz 采样率
.channels = LISA_AUDIO_CH_STEREO, // 立体声
.sample_bits = LISA_AUDIO_BIT_16, // 16位采样
},
.gain = {
.analog_gain = 0, // 模拟增益 0dB
.digital_gain = 0, // 数字增益 0dB
},
.buffer_count = 4, // 4个缓冲区
.buffer_samples = 512, // 每个缓冲区512采样点
};
lisa_audio_play_config(audio0, &play_config);
// 启动播放
lisa_audio_play_start(audio0);
// 写入音频数据
int16_t audio_data[1024]; // 准备音频数据
// ... 填充 audio_data ...
int ret = lisa_audio_play_write(audio0, audio_data, 1024);
if (ret > 0) {
// 成功写入 ret 个采样点
}
// 等待播放完成
lisa_audio_play_flush(audio0);
// 停止播放
lisa_audio_play_stop(audio0);
使用统一回调接收音频数据
// 音频数据回调函数
void audio_event_callback(const lisa_audio_event_t *event, void *user_data)
{
// 处理录音数据
if (event->record_buffer && event->record_samples > 0) {
const int16_t *record_data = (const int16_t *)event->record_buffer;
// 处理录音数据...
// 注意:回调在中断上下文中执行,应尽量简短快速
}
// 处理播放回声数据
if (event->echo_buffer && event->echo_samples > 0) {
const int16_t *echo_data = (const int16_t *)event->echo_buffer;
// 处理回声数据...
}
}
// 注册回调
lisa_audio_register_callback(audio0, audio_event_callback, NULL);
// 配置并启动录音和播放
lisa_audio_record_config(audio0, &record_config);
lisa_audio_play_config(audio0, &play_config);
lisa_audio_record_start(audio0);
lisa_audio_play_start(audio0);
// ... 运行一段时间 ...
// 停止并注销回调
lisa_audio_record_stop(audio0);
lisa_audio_play_stop(audio0);
lisa_audio_unregister_callback(audio0, audio_event_callback);
动态调整增益
// 设置录音增益
lisa_audio_gain_t record_gain = {
.analog_gain = 6, // 模拟增益 +6dB
.digital_gain = 3, // 数字增益 +3dB
};
lisa_audio_record_set_gain(audio0, &record_gain);
// 设置播放增益
lisa_audio_gain_t play_gain = {
.analog_gain = -3, // 模拟增益 -3dB
.digital_gain = 0, // 数字增益 0dB
};
lisa_audio_play_set_gain(audio0, &play_gain);
相位补偿配置
// 设置相位补偿(用于调整录音和播放之间的相位差)
lisa_audio_phase_compensation_t phase_comp = {
.record_skip_samples = 0, // 录音数据不丢弃
.echo_skip_samples = 32, // ECHO数据丢弃32个采样点
};
lisa_audio_set_phase_compensation(audio0, &phase_comp);
// 读取当前相位补偿配置
lisa_audio_phase_compensation_t current_comp;
lisa_audio_get_phase_compensation(audio0, ¤t_comp);
使用播放缓冲区零拷贝方式
// 获取空闲播放缓冲区
void *buffer;
int buffer_size = lisa_audio_play_get_buffer(audio0, &buffer, 1000); // 超时1秒
if (buffer_size > 0) {
// 直接向缓冲区写入数据(零拷贝)
int16_t *audio_buf = (int16_t *)buffer;
for (int i = 0; i < buffer_size; i++) {
audio_buf[i] = /* 生成音频数据 */;
}
// 提交数据
lisa_audio_play_write(audio0, buffer, buffer_size);
}
暂停和恢复录音
// 启动录音
lisa_audio_record_start(audio0);
// ... 录音一段时间 ...
// 暂停录音
lisa_audio_record_pause(audio0);
// ... 暂停期间不会产生录音数据 ...
// 恢复录音
lisa_audio_record_resume(audio0);
// 停止录音
lisa_audio_record_stop(audio0);
音频格式配置
采样率
支持的采样率:
LISA_AUDIO_RATE_8K- 8kHzLISA_AUDIO_RATE_16K- 16kHzLISA_AUDIO_RATE_24K- 24kHzLISA_AUDIO_RATE_32K- 32kHzLISA_AUDIO_RATE_48K- 48kHzLISA_AUDIO_RATE_96K- 96kHz
通道配置
LISA_AUDIO_CH_LEFT- 左声道LISA_AUDIO_CH_RIGHT- 右声道LISA_AUDIO_CH_STEREO- 立体声(左+右)
采样位深
LISA_AUDIO_BIT_16- 16位采样 (2字节)LISA_AUDIO_BIT_24- 24位采样 (3字节)LISA_AUDIO_BIT_32- 32位采样 (4字节)
采样点计算
对于立体声音频,采样点数是所有通道的总和。例如:
单声道 256 个采样点 = 256 个样本
立体声 256 个采样点 = 每个声道 128 个样本
对于 16 位立体声:
缓冲区大小(字节) = 采样点数 × 2(字节/采样) × 2(声道) = 采样点数 × 4
状态定义
LISA_AUDIO_STATUS_IDLE- 空闲状态LISA_AUDIO_STATUS_RUNNING- 运行中LISA_AUDIO_STATUS_PAUSED- 已暂停LISA_AUDIO_STATUS_ERROR- 错误状态
注意事项
设备初始化: 使用前需确保设备已正确初始化
配置顺序: 需先调用配置函数,再调用启动函数
回调上下文: 音频数据回调在中断上下文中执行,应尽量简短快速,不要执行耗时操作
缓冲区管理:
录音缓冲区由驱动内部管理
播放缓冲区数量影响延迟和缓冲深度
采样点数: 对于多通道音频,采样点数是所有通道的总和
增益范围: 增益单位为 dB,具体范围取决于硬件支持
相位补偿: 用于调整录音和播放之间的时间对齐,具体值需根据实际测试确定
线程安全: 驱动内部使用互斥锁保护关键操作
文件说明
lisa_audio.h- 驱动头文件,包含所有 API 和类型定义lisa_audio_arcs.c- ARCS 平台适配实现lisa_audio_internal.h- 内部实现头文件CMakeLists.txt- 构建配置Kconfig- 配置选项