ESP-BT-AUDIO 组件

[English]

组件概述

esp_bt_audio 是乐鑫提供的蓝牙音频高级组件,用于统一管理 Classic Bluetooth 与 LE Audio 的音频能力。组件向下对接 BT host、controller 与各类音频 profile,向上提供统一的初始化接口、角色配置、事件回调、stream 抽象与 packet I/O,降低蓝牙音频应用的开发复杂度。

组件根据应用配置的 Classic 和 LE role 自动完成对应协议的初始化和管理,并通过 esp_bt_audio_event_cb_t 统一上报连接状态、设备发现、stream 生命周期、播放控制、音量变化、通话状态、电话状态、通讯录和通话记录等信息。

Classic Bluetooth 音频使用 Bluedroid host;LE Audio 可根据芯片和工程配置使用 NimBLE 或 Bluedroid host,并要求开启 ESP-IDF Bluetooth Audio 与 ISO 支持。

该组件适用于以下典型场景:

  • 蓝牙音箱与蓝牙耳机

  • A2DP 音源设备

  • 车载、耳机或语音终端中的通话设备

  • TMAP 单播与广播音频设备

  • Auracast 或其他 BIS 广播发送/接收设备

  • 需要接入 ESP-GMF pipeline 的蓝牙音频应用

主要特性

  • 统一的蓝牙音频接口 对应用提供统一 API、role 配置和事件回调,应用无需分别处理各 profile 与 host 的底层差异。

  • Classic Bluetooth 音频 支持 A2DP Source/Sink、HFP Hands-Free(HF)、HFP Audio Gateway(AG)、AVRCP Controller/Target 和 PBAP Client Equipment。A2DP 支持外部 codec 路径,当前实现包含 SBC 与 AAC。

  • LE Audio 单播能力 支持 BAP Unicast Server,可暴露 sink/source ASE,用于 LE 单播媒体或通话音频。

  • LE Audio 广播能力 支持 BAP Broadcast Source、BAP Broadcast Sink 和 Scan Delegator,可发送或接收 LC3 广播音频流。

  • LE Audio 控制与协同能力 支持 TMAP 角色、VCP Renderer、MCP、MICP、CCP Client 和 CSIP Set Member 等音量、媒体、麦克风、通话控制与协同组能力。

  • 统一事件回调模型 通过 esp_bt_audio_event_cb_t 上报连接、发现、stream 生命周期、播放控制、元数据、音量、通话与电话状态、通讯录、通话记录以及 BIG/PA 同步丢失等事件。

  • Stream 抽象与 Packet I/O 使用 esp_bt_audio_stream_handle_t 表示蓝牙音频流,可查询 codec 信息、方向、上下文和 LE ISO 间隔,并通过 acquire/release API 读取或写入编码帧。

  • 可选 GMF I/O 提供 esp_gmf_io_bt,将蓝牙音频 stream 适配为 ESP-GMF pipeline 的 reader 或 writer。

功能特性

ESP_BT_AUDIO 支持如下功能:

功能

说明

典型应用

A2DP Sink

从手机、PC 等远端音源接收 SBC/AAC 等编码音频并在本地播放

蓝牙音箱、耳机

A2DP Source

将本地音频发送到远端蓝牙音箱或耳机

播放器、语音设备

HFP HF/AG

支持 Hands-Free 与 Audio Gateway 通话语音场景

车载、耳机、语音终端

AVRCP Controller/Target

支持播放控制、播放状态、元数据和通知

播控面板、音频播放器

PBAP Client Equipment

拉取手机通讯录与通话记录

带电话簿能力的终端设备

BAP Unicast Server

暴露 LE Audio sink/source ASE,用于媒体或通话音频

LE 音箱、LE 耳机

BAP Broadcast Source/Sink

发送或接收 LC3 广播音频流

Auracast 发送端与接收端

Scan Delegator

接收 Broadcast Assistant 的广播发现与同步请求

远程广播控制设备

TMAP

配置 CT、UMR、BMR、BMS 等电话与媒体角色组合

TMAP 音频设备

VCP/MCP/MICP/CCP/CSIP

支持音量、媒体控制、麦克风控制、通话控制与协同组能力

LE 音频控制与协同设备

GMF I/O

将蓝牙音频 stream 接入 ESP-GMF pipeline

复杂音频处理链路

架构概览

ESP_BT_AUDIO 位于应用层与蓝牙协议栈之间,作为适配层向上提供统一接口,向下对接 BT host、controller、Classic profile 和 LE Audio profile。底层 profile 与 host 回调被组件转换为统一事件;Classic 与 LE stream 使用相同的生命周期和 packet I/O 模型。

应用
 |-- 初始化 / role 配置 / 控制命令
 |-- 统一事件回调
 v
esp_bt_audio
 |-- Classic profiles:A2DP / HFP / AVRCP / PBAP
 |-- LE Audio profiles:BAP / TMAP / VCP / MCP / MICP / CCP / CSIP
 |-- stream 抽象与 packet 队列
 v
BT host(Bluedroid / NimBLE)--> BT controller
                      |
                      +--> 可选 GMF I/O --> ESP-GMF pipeline

典型处理流程如下:

  1. 应用初始化 NVS 与 BT controller。

  2. 应用准备 Bluedroid 或 NimBLE host 配置,并设置 Classic 和/或 LE role、事件回调。

  3. 调用 esp_bt_audio_init() 初始化组件。

  4. 组件根据 role 初始化对应协议。

  5. 连接、发现、stream 状态和控制事件通过统一回调上报。

  6. 应用根据 stream 方向选择读取、写入或绑定 GMF pipeline。

API 概览

ESP_BT_AUDIO 主要头文件如下:

头文件

说明

esp_bt_audio.h

模块初始化、反初始化和整体配置

esp_bt_audio_event.h

事件 ID 与事件数据结构定义

esp_bt_audio_defs.h

Classic/LE role、codec 与基础定义

esp_bt_audio_host.h

Bluedroid / NimBLE host 配置结构

esp_bt_audio_classic.h

Classic 设备发现、连接、断开与扫描模式接口

esp_bt_audio_le.h

LE 扫描、广播开关、ACL 连接与广播同步接口

esp_bt_audio_stream.h

stream 抽象、属性查询和 packet acquire/release API

esp_bt_audio_media.h

本地媒体发送传输控制

esp_bt_audio_playback.h

播放控制、元数据和通知相关接口

esp_bt_audio_vol.h

绝对音量、相对音量控制和通知

esp_bt_audio_tel.h

通话状态、电话状态和通话控制

esp_bt_audio_pb.h

通讯录和通话记录

esp_bt_audio_le_playback_sync.h

可选 LE 播放启动与时钟同步辅助接口,依赖 CONFIG_SOC_MODEM_SUPPORT_ETM

io/esp_gmf_io_bt.h

可选 GMF I/O 适配接口

Stream 模型

stream 方向

  • ESP_BT_AUDIO_STREAM_DIR_SINK:下行接收方向。stream 向应用输出编码帧,应用使用 esp_bt_audio_stream_acquire_read() 与 esp_bt_audio_stream_release_read()。

  • ESP_BT_AUDIO_STREAM_DIR_SOURCE:上行发送方向。应用向 stream 写入编码帧,使用 esp_bt_audio_stream_acquire_write() 与 esp_bt_audio_stream_release_write()。

应用可通过以下接口查询 stream 属性:

  • esp_bt_audio_stream_get_codec_info():codec 类型、采样率、声道、位宽、帧大小等。

  • esp_bt_audio_stream_get_dir():数据方向。

  • esp_bt_audio_stream_get_profile():A2DP、HFP、LE unicast 或 LE broadcast 等 profile。

  • esp_bt_audio_stream_get_context():媒体、通话等业务上下文。

  • esp_bt_audio_stream_get_local_data():组件内部附加数据。

  • esp_bt_audio_stream_get_iso_interval():LE ISO 间隔,单位为微秒。

stream 生命周期

stream 生命周期由组件内部维护,并通过 ESP_BT_AUDIO_EVENT_STREAM_STATE_CHG 事件上报。常见状态如下:

  • ALLOCATED:stream 已创建,应用可查询 codec、方向、上下文并分配资源。

  • STARTED:音频流已启动,应用开始读取或写入编码帧。

  • STOPPED:音频流已停止,应用停止数据处理流程。

  • RELEASED:stream 已释放,应用清理相关资源。

典型数据流

Classic sink 场景中,手机或 PC 作为音源发送 SBC、AAC 等编码帧,ESP 设备通过 ESP_BT_AUDIO 获取编码数据,再经过解码、采样率转换、声道转换等处理后输出到 I2S、DAC 或 codec device。

Classic source 场景中,ESP 设备从文件、麦克风或 pipeline 获取本地音频数据,经过必要的转换和编码后,通过 ESP_BT_AUDIO 发送给远端蓝牙音箱或耳机。

LE Audio sink 场景中,远端单播或广播音源发送 LC3 帧,ESP 设备在 stream 启动后读取编码帧并送入本地解码播放链路。LE Audio source 场景则可由本地音频输入生成 LC3 帧,并通过已协商的 LE Audio stream 发送。

LE 播放同步辅助能力

在支持 CONFIG_SOC_MODEM_SUPPORT_ETM 的芯片上,esp_bt_audio_le_playback_sync.h 提供 LE 播放启动同步与 I2S FIFO 时钟同步辅助接口。应用可将 BLE 时序事件与 I2S 输出对齐,用于降低 LE Audio 播放启动和时钟偏差。

GMF I/O 集成

当使能 CONFIG_ESP_BT_AUDIO_GMF_IO_SUPPORT 后,组件提供 esp_gmf_io_bt,将蓝牙音频 stream 适配为 ESP-GMF 的 I/O 节点。

使用逻辑如下:

  1. 在 GMF Pool 中按方向注册 io_bt reader 和/或 writer,初始化时可将 stream 置空。

  2. 在 ALLOCATED 状态收到 stream 后,根据方向调用 esp_gmf_io_bt_set_stream() 绑定。

  3. Bluetooth sink stream 作为 pipeline 输入,使用 io_bt reader;Bluetooth source stream 作为 pipeline 输出,使用 io_bt writer。

  4. 在 STARTED / STOPPED 状态变化时运行或停止对应 pipeline。

典型 pipeline 组合如下:

  • Classic / LE sink:io_bt reader → aud_dec → aud_rate_cvt / aud_ch_cvt → io_codec_dev writer

  • Classic / LE source:io_file 或 io_codec_dev reader → aud_dec → aud_enc → io_bt writer

  • LE broadcast source:本地音频输入 → 解码/转换/编码 → io_bt writer → BIS

使用方法

集成组件

当前组件版本为 1.1.x,要求 ESP-IDF 5.5 或更高版本。使用 ESP-IDF Component Manager 时,可在工程中添加如下依赖:

dependencies:
  espressif/esp_bt_audio:
    version: "~1.1"

组件依赖 ESP-IDF 的 bt 组件与 esp_audio_codec。当 CONFIG_ESP_BT_AUDIO_GMF_IO_SUPPORT=y 时,还会引入 gmf_core 与 gmf_io。

也可以通过命令添加依赖:

idf.py add-dependency "espressif/esp_bt_audio~1.1"

配置 Classic Bluetooth

Classic profile 相关源码只有在对应 ESP-IDF 配置打开时才会参与编译:

  • CONFIG_BT_CLASSIC_ENABLED

  • CONFIG_BT_BLUEDROID_ENABLED

  • CONFIG_BT_A2DP_ENABLE

  • CONFIG_BT_A2DP_USE_EXTERNAL_CODEC

  • CONFIG_BT_HFP_ENABLE

  • CONFIG_BT_HFP_CLIENT_ENABLE 或 CONFIG_BT_HFP_AG_ENABLE

  • CONFIG_BT_HFP_AUDIO_DATA_PATH_HCI

  • CONFIG_BT_HFP_USE_EXTERNAL_CODEC

  • CONFIG_BT_AVRCP_ENABLED

  • CONFIG_BT_PBAC_ENABLED

配置 LE Audio

LE Audio 需要开启 Bluetooth Audio 与 ISO 支持,并根据目标芯片和工程选择 NimBLE 或 Bluedroid host:

  • CONFIG_BT_AUDIO

  • CONFIG_BT_ISO

  • CONFIG_BT_NIMBLE_ENABLED 或 CONFIG_BT_BLUEDROID_ENABLED

可选 LE profile 开关来自 ESP-IDF Bluetooth Audio 配置,例如:

  • CONFIG_BT_BAP_UNICAST_SERVER

  • CONFIG_BT_BAP_BROADCAST_SOURCE

  • CONFIG_BT_BAP_BROADCAST_SINK

  • CONFIG_BT_BAP_SCAN_DELEGATOR

  • CONFIG_BT_VCP_VOL_REND

  • CONFIG_BT_MCC

  • CONFIG_BT_MICP_MIC_DEV

  • CONFIG_BT_TBS_CLIENT

  • CONFIG_BT_CSIP_SET_MEMBER

  • CONFIG_BT_TMAP

LE Broadcast Source 通过 esp_bt_audio_le_bsrc_cfg_t 配置广播码、广播名称与 stream_num。

组件自身配置

在 menuconfig 的 ESP Bluetooth Audio 菜单中可配置:

  • CONFIG_ESP_BT_AUDIO_GMF_IO_SUPPORT:编译 esp_gmf_io_bt。

  • CONFIG_ESP_BT_AUDIO_MONITOR 及其子选项:播放同步、时钟同步或 stream 监控 GPIO。

初始化示例

Classic A2DP Sink 示例:

#include "esp_bt_audio.h"
#include "esp_bt_audio_host.h"

static void bt_audio_event_cb(esp_bt_audio_event_t event,
                               void *event_data, void *user_data);

void init_classic_bt_audio(void)
{
    esp_bt_audio_host_bluedroid_cfg_t host_cfg =
        ESP_BT_AUDIO_HOST_BLUEDROID_CFG_DEFAULT();

    esp_bt_audio_config_t cfg = {
        .host_config = &host_cfg,
        .event_cb = bt_audio_event_cb,
        .event_user_ctx = NULL,
        .classic.roles = ESP_BT_AUDIO_CLASSIC_ROLE_A2DP_SNK |
                         ESP_BT_AUDIO_CLASSIC_ROLE_AVRC_TG,
    };

    ESP_ERROR_CHECK(esp_bt_audio_init(&cfg));
}

LE Audio Unicast Server 与 Broadcast Sink 示例:

#include "esp_bt_audio.h"
#include "esp_bt_audio_host.h"

static void bt_audio_event_cb(esp_bt_audio_event_t event,
                               void *event_data, void *user_data);

void init_le_audio(void)
{
    esp_bt_audio_host_nimble_cfg_t host_cfg =
        ESP_BT_AUDIO_HOST_NIMBLE_CFG_DEFAULT();

    esp_bt_audio_config_t cfg = {
        .host_config = &host_cfg,
        .event_cb = bt_audio_event_cb,
        .event_user_ctx = NULL,
        .le.user_case = ESP_BT_AUDIO_LE_USER_CASE_TMAP,
        .le.roles = ESP_BT_AUDIO_LE_ROLE_UNICAST_SERVER |
                    ESP_BT_AUDIO_LE_ROLE_BROADCAST_SINK,
        .le.snk_cnt = 1,
        .le.src_cnt = 0,
    };

    ESP_ERROR_CHECK(esp_bt_audio_init(&cfg));
}

实际工程需要按目标芯片和所用 host 完整配置 NVS、BT controller、PACS、CSIP、VCP 或 broadcast source 等参数。

辅助接口

Classic 辅助接口

启用 Classic 与 Bluedroid 后,esp_bt_audio_classic.h 提供设备发现启停、按 role 与地址连接/断开、设置 connectable/discoverable 扫描模式等接口。

LE Audio 辅助接口

启用 LE Audio 后,esp_bt_audio_le.h 提供以下常用操作:

  • LE 扫描启停与按目标地址扫描:esp_bt_audio_le_scan_start()、esp_bt_audio_le_scan_start_ext()、esp_bt_audio_le_scan_stop()。

  • 广播开关:esp_bt_audio_le_set_advertising()。

  • LE ACL 连接与断开:esp_bt_audio_le_connect()、esp_bt_audio_le_disconnect()、esp_bt_audio_le_disconnect_peer()。

  • 广播 source 启停:esp_bt_audio_le_broadcast_source_start() / stop()。

  • 广播同步与取消同步:esp_bt_audio_le_broadcast_sync()、esp_bt_audio_le_pa_sync_terminate()。

示例工程

可通过以下命令创建 bt_audio 示例工程:

idf.py create-project-from-example "espressif/esp_bt_audio~1.1:bt_audio"

示例覆盖 Classic 音频播放/发送、通话与电话簿、LE Audio 单播与广播以及 GMF pipeline。详细编译和板级配置请参考组件中的 examples/bt_audio 目录。

组件链接