杰理可视化SDK开发-耳机端本地按键上报ANC模式状态给APP端同步显示

前言

现在为止也开发了许多杰理TWS蓝牙耳机、音响项目SDK的案子,在调试案子时不断的向前辈们学习到了很多关于蓝牙音响、蓝牙TWS耳机专业的知识。想在做一个学习汇总,方便各位同行和对杰理芯片SDK感兴趣的小伙伴们学习;

本章详细讲解杰理SDK中耳机端本地按键触发时上报切换ANC模式状态给APP端同步显示

调试一个AC7006F6芯片的TWS蓝牙耳机项目,目前项目的功能是有ANC主动降噪和APP功能;在耳机端连接手机端APP后,APP的界面有三种ANC模式。奇怪是的耳机端进行切换ANC模式操作,可是APP端的界面并没同步显示一只处于在ANC模式关界面;可当我在APP上进行按键设置操作之后,耳机端再次切换ANC模式;这个时候APP界面就会同步显示;遇到这个问题就非常奇怪;就需要抓取打印日志log分析了;


第一段日志log分析:默认流程(未经过APP设置)—— 本地直通,无状态上报

在第一段日志中,长按触发后的关键路径如下:

1、按键事件直接通过app_key_msg_handlerAPP_MSG_POWER_KEY_LONG消息处理。
2、耳机立刻执行本地ANC模式切换 (new_mode:ANC_ON) 并播放提示音。
3、全程没有任何rcsp相关日志,也没有发出任何数据给手机APP(无send记录)。
结论: 此时按键功能是纯本地行为,切换ANC后并不会通过蓝牙向APP上报状态。


在第二段日志log分析:APP设置按键后的流程 —— RCSP接管,主动同步状态

在第二段日志中,长按触发后路径变为:

1、按键消息首先被 RCSP(Remote Control Service Protocol)模块 拦截,日志中明确出现rcsp key msg receive
2、RCSP内部对按键进行了重新映射 (key_remap: 0x10001, 0x0, 0x1),然后触发两条并行操作:
(1)、调用anc_tone_sync_play执行本地ANC切换及提示音播放;
(2)、立即构造并发送MSG_JL_UPDATE_ANC_VOICE指令给手机APP(send 2161ac-81-1),通知ANC状态更新。
3、因此APP能收到通知,界面得以同步。
结论:此时按键被RCSP接管,在完成本地切换的同时,会主动通过BLE/SPP协议将新的ANC状态上报给APP,从而实现UI同步。

总结:

耳机固件默认将“长按2秒”映射为本地功能(APP_MSG_POWER_KEY_LONG),该功能仅切换ANC并播放音效,未设计成自动上报状态给APP。
当你在APP端将按键重新设置为“ANC模式切换”后,APP会下发配置,使该按键事件被RCSP服务接管(相当于启用了一个远程控制通道)。RCSP的处理函数中,除了执行本地ANC切换外,还强制调用了状态同步接口,向APP推送最新ANC模式。
因此,只要APP未下发配置修改,就始终走“本地无上报”流程;一旦通过APP配置按键,则转为“RCSP上报”流程,APP界面自然就能同步显示了。


解决方案

要在本地按键处理(未通过APP设置)时也能向APP发送状态包,需要在 ANC 模式切换成功之后,主动调用 RCSP 的状态上报接口。以下是具体分析和修改方法。
1、可以直接使用现有函数rcsp_adv_voice_mode_update(),因为它内部已经包含了:更新全局 ANC 信息、同步TWS、判断TWS角色,仅在主机或单耳时触发JL_rcsp_event_to_user(MSG_JL_UPDATE_ANC_VOICE)、

代码讲解:

void rcsp_adv_voice_mode_update(u8 mode) { u8 anc_info[25] = {0}; get_anc_voice_info(anc_info); // 获取全局 ANC 信息 anc_info[0] = mode; // 更新模式 if (mode) { memcpy(anc_info + 1, anc_info + 1 + mode * 8, 8); // 将对应模式的数据移到开头 } deal_anc_voice(anc_info, 1, 0); // 应用 ANC 设置、写入VM、同步TWS // TWS 从机不直接上报,由主机统一上报 if (TWS连接 && 本机为从机) { tws_api_send_data_to_sibling(...); // 通知主机 return; } // 主机或单耳模式直接触发状态上报 JL_rcsp_event_to_user(DEVICE_EVENT_FROM_RCSP, MSG_JL_UPDATE_ANC_VOICE, NULL, 0); }


2、需要在APP_MSG_POWER_KEY_LONG消息的处理函数中,在new_mode:ANC_ON执行完毕后加入上报逻辑。

代码讲解:

#if (RCSP_MODE && RCSP_ADV_ANC_VOICE) // 只有连接到 APP 且有 RCSP 功能时才上报 if (get_rcsp_connect_status()) { u8 current_mode = anc_mode_get(); // 获取切换后的模式(0/1/2) rcsp_adv_voice_mode_update(current_mode); } #endif

修改完成;


为什么这样就能同步?

因为:rcsp_adv_voice_mode_update最终会调用:
JL_rcsp_event_to_user(DEVICE_EVENT_FROM_RCSP, MSG_JL_UPDATE_ANC_VOICE, NULL, 0);
改事件被JL_rcsp_event_handler捕获,然后调用:
rcsp_device_status_update(COMMON_FUNCTION,BIT(RCSP_DEVICE_STATUS_ATTR_TYPE_ANC_VOICE));
该函数会将当前的ANC模式、各档位增益等数据打包成RCSP协议包,通过BLE/SPP发送给APP。APP收到后解析并更新UI,从而完成界面同步。


制作不易!喜欢的小伙伴给个小赞赞!喜欢我的小伙伴点个关注!有不懂的地方和需要的资源随时问我哟!