7. 蓝牙音频框架示例 - SBC 回环测试

本示例演示如何使用 lisa_bt_audio_framework 进行 SBC 编解码回环,实现麦克风到扬声器的音频路径。

7.1. 功能说明

  1. SBC 编码:从麦克风录制音频,使用 SBC 编码器进行编码

  2. SBC 解码:将编码后的 SBC 数据解码并播放到扬声器

  3. 实时回环:编码和解码在同一设备上进行,形成音频回环

7.2. 硬件连接

  • 板卡需要有 audio0 设备,包括麦克风和扬声器

7.3. 架构说明

[麦克风] -> [录音会话/SBC编码] -> [回环任务] -> [播放会话/SBC解码] -> [扬声器]
              (SBC Encoder)                        (SBC Decoder)

7.3.1. 数据流程

  1. 回环任务(Loopback Task)

    • 从录音会话获取 SBC 编码数据

    • 直接将 SBC 数据喂给播放会话进行解码

    • 实现编码->解码的实时回环

7.4. SBC 编解码器参数

  • 采样率:16 kHz

  • 声道:单声道(Mono)

  • 位深:16 位

  • 比特率:自适应

  • 子带数:8

  • 块长度:16

  • 分配方法:Loudness

7.5. 配置说明

7.5.1. prj.conf 配置

# 蓝牙音频框架
CONFIG_LISA_BT_AUDIO_FRAMEWORK=y
CONFIG_LISA_BT_AUDIO_INTERFACE=y
CONFIG_LISA_BT_AUDIO_MAX_SESSIONS=4

# SBC 编解码器
CONFIG_AUDIO_CODEC_SBC=y

# 编码数据缓冲区配置
CONFIG_LISA_BT_AUDIO_ENCODED_RINGBUF_SIZE=8
CONFIG_LISA_BT_AUDIO_ENCODED_PREFILL_SIZE=4

# PCM 环形缓冲区时间配置
CONFIG_LISA_BT_AUDIO_PCM_RINGBUF_TIME_MS_DOWNLINK=200
CONFIG_LISA_BT_AUDIO_PCM_RINGBUF_TIME_MS_UPLINK=200
CONFIG_LISA_BT_AUDIO_PCM_PREFILL_TIME_MS=60

# 工作缓冲区配置
CONFIG_LISA_BT_AUDIO_WORK_BUFFER_TIME_MS=64
CONFIG_LISA_BT_AUDIO_HW_BUFFER_COUNT=3

# 音频驱动
CONFIG_LISA_AUDIO_DEVICE=y
CONFIG_LISA_AUDIO_PLAY_ECHO_ENABLE=y

7.5.2. 线程配置

  • 回环任务:优先级 10,栈大小 2048 字节

  • 编码任务:由框架自动创建和管理

  • 解码任务:由框架自动创建和管理

8. 音频驱动

CONFIG_LISA_AUDIO_DEVICE=y CONFIG_LISA_AUDIO_PLAY_ECHO_ENABLE=y


### 线程优先级

- **透传任务**:优先级 10,栈大小 2048 字节

## 示例内容

1. 初始化蓝牙音频框架
2. 创建录音会话(SBC 编码模式)
3. 创建播放会话(SBC 解码模式)
4. 启动回环任务,实时转发 SBC 编码数据
5. 运行 10 秒后自动停止并清理资源

## 编译

```{eval-rst}
.. include:: /sample_build.rst

8.1. 烧录

编译完成后,使用 SDK tools 目录下的 cskburn 工具烧录固件:

./tools/burn/cskburn -s /dev/ttyUSB0 -b 3000000 0x0 build/arcs.bin -C arcs

Note

烧录参数说明

  • -s /dev/ttyUSB0:串口设备路径,需要根据实际情况修改 - Linux 系统:通常是 /dev/ttyUSB0/dev/ttyACM0 - 可通过 ls /dev/tty* 命令查看可用串口设备 - 不同开发板或 USB 转串口芯片可能使用不同的设备名

  • -b 3000000:烧录波特率(3Mbps)

  • 0x0:烧录起始地址

  • build/arcs.bin:编译生成的固件路径

  • -C arcs:芯片类型

注意事项

  • 确保开发板已正确连接到电脑

  • 如果无法识别串口设备,请检查 USB 连接线是否正常,或尝试其他 USB 端口

8.2. 预期输出

程序启动后会:

  1. 初始化蓝牙音频框架

  2. 创建录音会话(SBC 编码模式)

  3. 创建播放会话(SBC 解码模式)

  4. 启动回环任务,实时转发 SBC 编码数据

  5. 运行 10 秒后自动停止并清理资源

8.2.1. 日志输出示例

I/bt_audio_sample [0:00:00.100] BT Audio Framework Sample - SBC Loopback
I/bt_audio_sample [0:00:00.101] =========================================
I/bt_audio_sample [0:00:00.105] BT audio framework initialized, version: 1.0.0
I/bt_audio_sample [0:00:00.150] Capture session created and started (SBC encode mode)
I/bt_audio_sample [0:00:00.200] Playback session created and started (SBC decode mode)
I/bt_audio_sample [0:00:00.201] Sample running... Press Ctrl+C to stop
I/bt_audio_sample [0:00:00.201] Recording -> SBC Encode -> SBC Decode -> Playback
I/bt_audio_sample [0:00:00.210] SBC loopback task started
...
I/bt_audio_sample [0:00:10.000] Cleaning up...
I/bt_audio_sample [0:00:10.201] SBC loopback task stopped
I/bt_audio_sample [0:00:10.500] Sample finished

8.3. API 使用说明

8.3.1. 1. 初始化框架

bt_audio_error_t ret = bt_audio_framework_init();

8.3.2. 2. 创建编码会话(录音)

bt_audio_session_config_t capture_config = {
    .profile = BT_PROFILE_HFP,
    .codec_type = BT_CODEC_SBC,               // SBC 编解码器
    .direction = BT_AUDIO_DIR_CAPTURE,        // 录音方向
    .interface_name = "lisa_audio",
    .passthrough_mode = false,                // 编解码模式
    .event_callback = capture_event_callback,
    .user_data = NULL,
};

bt_audio_session_handle_t capture_session;
bt_audio_session_create(&capture_config, &capture_session);

8.3.3. 3. 启动编码会话

bt_audio_codec_config_t codec_config = {
    .codec_type = BT_CODEC_SBC,
    .format = {
        .sample_rate = 16000,     // 16kHz
        .channels = 1,            // 单声道
        .bits_per_sample = 16,
    },
    .bitrate = 0,                 // 自适应比特率
};

bt_audio_session_start(capture_session, &codec_config);

8.3.4. 4. 创建并启动解码会话(播放)

// 配置和启动类似编码会话,但 direction = BT_AUDIO_DIR_PLAYBACK

8.3.5. 5. SBC 数据传输

从录音会话获取 SBC 编码数据

uint8_t buffer[512];
size_t read_size;
bt_audio_session_get_encoded_data(capture_session, buffer, sizeof(buffer), &read_size);

向播放会话喂入 SBC 编码数据

bt_audio_session_feed_encoded_data(playback_session, buffer, read_size);

8.3.6. 6. 清理资源(正确顺序)

// 1. 先停止会话(停止硬件和线程)
bt_audio_session_stop(capture_session);
bt_audio_session_stop(playback_session);

// 2. 通知回环任务退出
g_running = false;

// 3. 等待任务完全退出
vTaskDelay(pdMS_TO_TICKS(200));

// 4. 销毁会话
bt_audio_session_destroy(capture_session);
bt_audio_session_destroy(playback_session);

// 5. 反初始化框架
bt_audio_framework_deinit();

8.4. 注意事项

  1. 音频设备:确保板卡有 audio0 设备,包括麦克风和扬声器

  2. 编解码模式passthrough_mode = false 表示启用 SBC 编解码

  3. 缓冲区配置:根据实际需求调整 ringbuf 大小

  4. 清理顺序:必须按照正确顺序清理资源,避免 ringbuf full 警告

  5. 延迟:SBC 编解码会引入一定延迟(约 100-200ms)

8.5. SBC vs mSBC

特性

SBC

mSBC

采样率

灵活(16/32/44.1/48 kHz)

固定 16 kHz

比特率

可变

固定(约 64 kbps)

用途

A2DP 音乐传输

HFP 语音通话

帧时长

可变

固定 7.5ms

子带数

4 或 8

固定 8

块长度

4/8/12/16

固定 15

8.6. 扩展建议

  1. 不同参数:尝试不同的采样率、比特率和声道配置

  2. 性能测试:测量编解码延迟和 CPU 占用

  3. 音质对比:对比 SBC、mSBC 和 PCM 透传的音质差异

  4. 多会话:同时运行多个编解码会话

  5. 文件录制:将编码后的 SBC 数据保存到文件

8.7. 参考文档

8.8. 故障排查

8.8.1. 问题:没有音频输出

可能原因

  • 音频设备未正确初始化

  • 麦克风或扬声器硬件问题

  • SBC 编解码器未正确配置

解决方法

  • 检查 CONFIG_AUDIO_CODEC_SBC=y 是否已设置

  • 查看日志中的错误信息

  • 测试硬件是否正常

8.8.2. 问题:音频断续或有噪音

可能原因

  • 缓冲区配置不足

  • 系统负载过高

  • 编解码错误

解决方法

  • 增加 PCM ringbuf 时间配置

  • 增加编码数据 ringbuf 大小

  • 提高任务优先级

  • 检查 SBC 编解码器返回值

8.8.3. 问题:程序退出时有 ringbuf full 警告

原因:清理顺序不正确,会话停止前任务就已退出

解决方法:按照正确的清理顺序操作(见上文第 6 节)

8.8.4. 问题:编译错误

解决方法

  • 确认 prj.conf 中已启用 SBC 相关配置

  • 检查 SDK 版本

  • 确认依赖组件已正确配置

8.9. 许可证

Copyright © 2025, LISTENAI

SPDX-License-Identifier: Apache-2.0