前言
到现在为止也开发了许多杰理TWS蓝牙耳机项目SDK的案子,在调试案子时不断的向前辈们学习到了很多关于蓝牙TWS耳机专业的知识。想在这里做一个学习汇总,方便各位同行和对杰理芯片SDK感兴趣的小伙伴们学习;
本章详细讲解中科蓝讯SDK开发-BT897X、BT891X、AB573X、AB572X 系列 触摸按键提示音功能实现
在调试一个TWS蓝牙耳机案子时,按键通常是我们必须要添加的功能,通过按键我们可以实现音量的增大/减少,歌曲的播放/暂停,曲目的切换 ,开机/关机等特定功能;所有我们必须在按键按下是添加提示音,有提示音的存在方便我们更好的感知按键的状态;在中科蓝讯SDK中有非常多可以实现按键提示音的方法。这里出一个常用稳定实现按键提示音的方法;
本章实现步骤为:
1、按键触摸音功能开关(config.h)
2、按键触摸音消息定义(key_scan.h)
3、按键触摸音触发(key_scan.c)--- 核心触发点
4、消息分发处理(func.c)
5、音频资源映射资源索引(res_tbl.h)
6、 资源地址表(multi_lang.c)
7、编译时资源拷贝(copy_tone.xm)
8、SDK 还提供了另一种纯 Tone 方式
步骤1:按键触摸音功能开关(config.h)
本人实现某个功能时一般都喜欢使用宏去控制这个功能,方便我排查问题和控制功能的实现
实现触摸按键音功能开关

设置为 1 开启按键音功能,设置为 0 则关闭。整个实现链路上的所有代码都用 #if LYF_USER_KEY_TONE_EN 包裹,编译时条件决定是否参与编译,零开销。
步骤2:按键触摸音消息定义(key_scan.h)

在消息枚举中定义了一个专属消息 MSG_LYF_USER_KEY_TONE,这是按键音在整个系统中的消息标识符 。
设计思路 :SDK 采用消息驱动架构------所有事件(按键、蓝牙状态变化等)都以消息的方式入队,然后在主循环中统一分发处理。按键音作为一个独立的消息类型,遵循了相同的架构模式。
步骤3:按键触摸音触发(key_scan.c)--- 核心触发点
在按键扫描函数中获取按键刚按下时就发送按键触摸音消息

触发时机:
| 按键事件类型 | 含义 | 是否触发按键音 |
|---|---|---|
KEY_SHORT |
按键刚按下(下降沿检测) | ✅ 是 |
KEY_SHORT_UP |
按键抬起(短按) | ❌ 否 |
KEY_LONG |
长按到达阈值 | ❌ 否 |
KEY_LONG_UP |
长按后抬起 | ❌ 否 |
KEY_HOLD |
连按(按住不放) | ❌ 否 |
KEY_DOUBLE / KEY_THREE 等 |
双击/三击等 | ❌ 否 |
关键设计精髓 :按键音只在按键按下瞬间触发 (KEY_SHORT),而不是在按键抬起或长按触发时。这意味着:
-
✅ 按下就响,给用户即时反馈
-
✅ 无论后续是短按/长按/双击,按下就有声音
步骤4:消息分发出处理(func.c)
所有的msg消息都是通过一个先进先出的队列进行存储的,用msg_enqueue()接口添加消息,然后在主程序的消息处理函数中调用msg_dequeue()取出消息处理,不同模式下都会有自己的一个消息处理函数。该消息处理函数只是一个简单的switch判断,根据取出的不同消息值,去执行case对应的代码。需要注意的是,SDK中有一个公共的消息处理函数,都在default中执行。
使用msg_enqueue()接口添加按键消息;

在蓝牙模式下按键的单击、双击事件会在这个函数中处理按键事件,但是我不在这里进行触摸音播放处理。我在SDK公共的消息处理函数中处理

步骤5:音频资源映射资源索引(res_tbl.h)
在提示音资源索引枚举中添加 RES_IDX_KEY_TONE,作为按键音资源的唯一 ID。

步骤6:资源地址表(multi_lang.c)

将 RES_IDX_KEY_TONE 映射到一个 WAV 格式的音频资源 KEY。宏展开后大致相当于:
RES_BUF_WAV(KEY)→ 编译时生成的 WAV 数据首地址(例如RES_BUF_KEY_WAV)RES_LEN_WAV(KEY)→ 编译时生成的 WAV 数据长度(例如RES_LEN_KEY_WAV)
这里的底层宏定义(在 res_tbl.h 末尾):

所以 RES_BUF_WAV(KEY) 最终拼接为 &(RES_BUF_KEY_WAV),指向 flash 中存储的 WAV 二进制数据。
步骤7:编译时资源拷贝(copy_tone.xm)
在编译流程的预处理阶段,GCC 用 -E -P 预处理此 .xm 文件生成 .bat 批处理脚本,将 key.wav 从 res_tone 目录拷贝到 res 目录,然后编译链接器将 WAV 文件嵌入 firmware 镜像。

在res_tone提示音资源仓库中放入key.wac提示音音源文件,编译流程的预处理阶段会自动把key.wav 从 res_tone 目录拷贝到 res 目录

这样我们按键触摸音功能就顺利实现了
SDK 还提供了另一种纯 Tone 方式
从 api_music.h 可以看到,SDK 还提供了一个不依赖 WAV 资源文件的纯 tone 生成接口:

这是用 DSP 直接生成正弦波/方波的方式播放按键音,不需要预先准备 WAV 文件。当前项目选择的是 WAV 资源方式,是因为可以播放更丰富的音效(如自定义的音乐按键音),而不是单调的单频 "嘀" 声。
制作不易!喜欢的小伙伴给个小赞赞!喜欢我的小伙伴点个关注!有不懂的地方和需要的资源随时问我哟!