前言
现在为止也开发了许多杰理TWS蓝牙耳机、音响项目SDK的案子,在调试案子时不断的向前辈们学习到了很多关于蓝牙音响、蓝牙TWS耳机专业的知识。想在这里做一个学习汇总,方便各位同行和对杰理芯片SDK感兴趣的小伙伴们学习;
本章详细讲解杰理SDK开发中实现首次连接固定媒体音量
在我们进行杰理蓝牙耳机、蓝牙音响等蓝牙产品软件开发时,音量控制是我们避免不了的开发功能,杰理SDK呢底层都是写死了芯片首次连接时媒体音量功能为40%。有时候根据项目,客户会要求要是改变这个首次连接时通话音量为其它数值,在这里本博主出两个稳定实现首次连接固定媒体音量的教程。方便大家学习参考!
方法一:杰理官方实现首次连接固定媒体音量方法
修改方法:
cpp
#if LYF_NEDD_DEFAULT_VOLUME
//配合外面重新定义
u8 need_default_volume = 127*8/10; //为初始化80%。
//外面程序定义
u8 sync_default_volume_every_time = 0 ;//0是首次连接时使用默认音(need_default_volume), 1是每次都使用默认音量。
#endif
如下图所示:

使用这个方法目前有一个小小的缺陷:就是连接苹果手机时,不会再连接上立马更改媒体音量,而是需要播歌/刷视频等音频流的建立之后才会更改媒体音量。针对这个问题各位工程师们欢迎在下方指导解决办法。
方法二:自定义方法实现首次连接固定媒体音量方法
目前这个方法是针对上一个方法不足点:" 连接苹果手机时,不会再连接上立马更改媒体音量,而是需要播歌/刷视频等音频流的建立之后才会更改媒体音量 "。这个问题点针对修复的。
步骤1:新增全局变量和设置首次连接手机修改音量辅助函数(earphone.c 顶部)如图所示:

代码讲解:
cpp
#if LYF_NEDD_DEFAULT_VOLUME
u8 user_set_music_vol_first_conn = 0; // 首次配对标志
u8 default_volume = 127*7/10; // 默认音量值 88(对应 70%)
u8 vol_protect = 0; // 音量保护标志
// 超时回调:清除保护标志
static void clear_vol_protect_timeout(void *priv)
{
if (vol_protect) {
vol_protect = 0;
printf("[LYF] protect timeout, protect OFF\n");
}
}
// 延时发送默认音量(AVRCP 通道就绪后执行)
static void send_vol_sync_delayed(void *priv)
{
vol_protect = 1; // 开启保护,防止手机反推旧音量
// 设置 AVRCP 绝对音量,并通过 phone_get_device_vol() 返回给手机
app_var.opid_play_vol_sync = default_volume;
// 计算本地 DAC 音量等级(0~16)
u8 dac_vol = ((default_volume + 1) * 16) / 127;
app_var.music_volume = dac_vol;
app_audio_set_volume(APP_AUDIO_STATE_MUSIC, dac_vol, 1);
// 发送 AVRCP 同步命令给手机
user_send_cmd_prepare(USER_CTRL_AVCTP_OPID_SEND_VOL, 0, NULL);
printf("[LYF] send_vol_sync_delayed: vol=%d, dac_vol=%d, protect ON\n", default_volume, dac_vol);
#if TCFG_USER_TWS_ENABLE
if (get_bt_tws_connect_status()) {
bt_tws_sync_volume(); // TWS 主耳同步音量给副耳
printf("[LYF] send_vol_sync_delayed: TWS synced\n");
}
#endif
}
#endif
步骤二:在 bt_hci_event_handler() 中修改配对确认事件 设置首次配对标志HCI_EVENT_USER_CONFIRMATION_REQUEST,如图所示

代码讲解:只有当手机与耳机之间没有存储的 Link Key 时(即首次配对),才会产生该事件。回连时不会触发,完美区分首次与回连。
步骤三:在 A2DP/HFP 通道建立时发送默认音量和清除保护标志,修改 bt_connction_status_event_handler() 中的 BT_STATUS_CONN_A2DP_CH / BT_STATUS_CONN_HFP_CH 分支。如图所示

代码讲解:A2DP 控制通道建立后,AVRCP 通道通常也很快建立。延时 100ms 发送命令,确保 USER_CTRL_AVCTP_OPID_SEND_VOL 能被正确处理。同时判断角色,避免 TWS 副耳误触发。并且启动1秒清除超时保护定时器。保护定时器确保即使媒体不播放,保护也能在 1 秒后解除。不清楚的话后果就是手机端调节音量是调节不了的。
步骤四:在媒体开始或超时时解除保护,媒体开始事件 (BT_STATUS_A2DP_MEDIA_START)如图所示:

代码讲解:在这里小伙伴们就可以发现,这个保护标志本博主做了两个清除方法;
方法1:在媒体事件触发如播歌/刷视频等事件触发在软件上BT_STATUS_A2DP_MEDIA_START同步触发,在这里做清除保护标志位的方法
方法2:在步骤三中本博主也做了一个定时1秒清除保护标志位的方法。
步骤五:保护标志位防止手机推送旧音量值,造成修改默认音量功能失效;如图所示

代码讲解:首先判断保护标志位是否开启并且当前手机设置音量是否不等于需要设置的首次连接默认音量。满足这两个条件直接在这里强制更改为默认音量。因为本博主抓取log发现苹果手机不老实总是想发送旧的音量值给耳机端。
制作不易!喜欢的小伙伴给个小赞赞!喜欢我的小伙伴点个关注!有不懂的地方和需要的资源随时问我哟!