经典蓝牙音量同步机制

经典蓝牙的媒体音量与通话音量是两套独立机制:

A2DP 和 SCO/eSCO 负责承载音频;

音量控制分别由 AVRCP Absolute Volume 与 HFP Remote Audio Volume Control 完成。

  

1.1 机制对比

项目 媒体音量(A2DP 播放) 通话音量(SCO/eSCO)
控制协议 AVRCP Absolute Volume HFP Remote Audio Volume Control / Volume Level Synchronization
典型角色 手机/音源:CT Controller;音箱、耳机:TG Target 手机:AG Audio Gateway;音箱、耳机:HF Hands-Free
协议值 0x00~0x7F 对应最大音量的 0%~100%,bit7 保留;TG 可按自身档位量化 0~15 的绝对增益等级;每一级对应的实际声压由 HF 实现决定
手机到设备 SetAbsoluteVolume +VGS:<gain>
设备到手机 EVENT_VOLUME_CHANGED 通知 AT+VGS=<gain>
建立条件 双方支持 AVRCP Absolute Volume;A2DP 本身不提供音量同步 已建立 HFP Service Level Connection;不要求 SCO 音频链路已经建立

1.2 媒体音量:AVRCP Absolute Volume

场景 规范机制 结论
手机设置音量 CT 发送 SetAbsoluteVolume; TG 调整渲染端音量,并在响应中返回"实际设置值"。 由该命令造成的变化不得再完成 EVENT_VOLUME_CHANGED,避免回环。 手机 UI 与设备使用同一绝对音量状态;返回值必须反映设备实际可实现的档位。
设备本地按键/MCU 设置 CT 先用 RegisterNotification(EVENT_VOLUME_CHANGED) 注册。 TG 先回 INTERIM 当前值; 本地音量真正变化后回一次 CHANGED,CT 收到后应重新注册。 通知是一次性的;在最大/最小档继续按键而音量未变化时,不应发送 CHANGED
连接初始化 规范未规定"手机缓存优先"或"设备缓存优先"。 能力查询、事件注册和初始 SetAbsoluteVolume 的具体时序由 CT 平台实现。 安卓按设备保存音量属于操作系统策略,不是 AVRCP 的强制行为;不能把手机始终作为固定初始化主方。
不支持 Absolute Volume 没有跨设备的绝对音量状态。 手机和设备只能各自调节自身增益,或使用相对音量命令。 两端 UI/档位不保证一致;手机是否修改音频流增益属于平台实现,不是 AVRCP 规范结论。

1.3 通话音量:HFP Remote Volume

场景 规范机制 结论
SLC 建立 HF 应使用 AT+VGS 上报当前扬声器增益(同时可用 AT+VGM 上报麦克风增益)。 HFP 1.8 明确由 HF 在 SLC 建立时报告当前值,并非要求手机先下发初始通话音量。
手机设置音量 AG 发送非请求结果码 +VGS:<gain>,要求 HF 设置扬声器增益。 值域为 0~15;HF 负责把协议档位映射为本机实际增益。
设备本地按键/MCU 设置 HF 发送 AT+VGS=<gain> 并等待 OK,持续把当前扬声器增益报告给 AG。 AT+VGS 只报告 HF 当前值,不直接改变 AG 自身的扬声器增益。
保存范围 双方至少在当前 SLC 生命周期内保存增益设置;跨连接持久化由产品和操作系统决定。 不能把"手机按设备缓存"写成 HFP 强制要求。

当 SCO 已连接时,应使用 HFP 机制同步通话扬声器音量,避免同时完成 AVRCP 音量变化通知而产生双通道回报。Windows 经典蓝牙附件指南对此有明确互操作要求。

1.4 当前 SDK 的落地方式

当前选中板级配置同时使能 BT_SUPPORT_MUSIC_VOL_SYNC=1USER_BT_VOLUME_RELAY_ENABLE=1

JL 作为蓝牙协议与主控 MCU 之间的音量中转,媒体/通话 DAC 使用固定增益;最终可听音量由主控 MCU 应用。

链路 手机到主控 MCU 主控 MCU 到手机 协议值
媒体 AVRCP 回调 set_music_device_volume() 更新镜像,换算为百分比后通过 PL_BT_VOL_SET 上报 PL_EVT_BT_VOL_SETbt_sync_remote_media_volume()USER_CTRL_AVCTP_OPID_SEND_VOL AVRCP 0~127 ↔ MCU 0~100
通话 BT_STATUS_CALL_VOL_CHANGE 更新镜像,换算为百分比后通过 PL_BT_VOL_SET 上报 PL_EVT_BT_VOL_SETbt_sync_remote_call_volume()USER_CTRL_HFP_CALL_SET_VOLUME HFP 0~15 ↔ MCU 0~100
音量加减 PL_BT_VOLUP/PL_BT_VOLDOWN 根据通话状态选择 HFP 音量命令,否则选择 AVRCP 音量同步命令 按当前协议档位步进
初始化 蓝牙栈初始化后依次用 PL_BT_VOL_GET 获取媒体、通话音量;重试失败使用 50%。对应 AVCTP/HFP 通道建立后,如 MCU 值有效,则同步给远端。 后续任一端产生新的有效值时,以最新事件更新镜像并转发

**一致性约束:**对手机返回或通知的值必须是产品最终实际应用的音量。当前中转模式下,只有主控 MCU 成功应用对应增益,才满足 AVRCP "返回实际设置值"的语义;同时应保留现有回声抑制,避免手机→JL→MCU→JL→手机形成循环。

1.5 小结

结合1.2 和1.3可知,

对于媒体音量:当手机没有开启音量同步时,各自调节自身增益;当手机开启音量同步时,最终音量由被控终端设备调节增益;音量在手机和被控终端均有存储备份;

对于通话音量:始终开启音量同步,由终端设备先上报自身音量,同步后,声音始终由终端设备调节;音量在手机和被控终端均有存储备份;

2 参考规范

相关推荐
你怎么知道我是队长6 天前
经典蓝牙(Classic Bluetooth / BR/EDR)--- 核心协议层5 --- 经典蓝牙(BR/EDR)服务发现层核心机制详解
bluetooth
你怎么知道我是队长8 天前
经典蓝牙(Classic Bluetooth / BR/EDR)--- 核心协议层5 --- 经典蓝牙(BR/EDR)电缆替代协议层核心机制详解
bluetooth
你怎么知道我是队长13 天前
经典蓝牙(Classic Bluetooth / BR/EDR)--- 核心协议层1 --- 经典蓝牙(BR/EDR)物理层核心机制详解
bluetooth
奔跑吧 android1 个月前
【Bluetooth-SIG】【CoreV6.2】【Vol3 Part G】【GATT】【零】【GATT 逐句逐段学习计划 2】
ble·bluetooth·att·gatt·core_v6.2·sig
奔跑吧 android1 个月前
【Bluetooth-SIG】【CoreV6.2】【Vol3 Part F】【十三】【Error Handling——ATT_ERROR_RSP】
ble·bluetooth·att·gatt·蓝牙协议·bt·core_v6.2
一渊之隔3 个月前
uniapp蓝牙搜索连接展示蓝牙设备包含信号显示
前端·网络·uni-app·bluetooth
yanlaifan4 个月前
BLE中PHY 1M和 2M
bluetooth
奔跑吧 android4 个月前
【BT-SIG】【Core_v6.2】【Vol 3 Host】【Part G: GATT】【3.1 Service definition】
ble·bluetooth·gatt·蓝牙协议·bt·core_v6.2·bt-sig
奔跑吧 android4 个月前
【BT-SIG】【Core_v6.2】【Vol 3 Host】【Part G: GATT】【2.Profile overview】
ble·bluetooth·协议解析·gatt·bt-sig解析·core_v6.2