蓝牙电话之HFP协议中的电话音频
蓝牙技术通信的内容多种多样,其中音频部分包含媒体音频和电话音频。
媒体音频:播放蓝牙音乐的数据,这种音频对质量要求高,数据发送有重传机制,从而以l2cap的数据形式走ACL链路。编码方式有:SBC、AAC、APTX、APTX_HD、LDAC这五种编码方式,最基础的编码方式是SBC,支持蓝牙多媒体播放的设备必须支持该编码方式,编码质量最好的是LDAC。编码方式的选取需要蓝牙连接设备间的互相协商确定。
电话音频:蓝牙通话过程的语音数据,这种音频对时效性有高要求,一般通过特殊的SCO或eSCO链路传输数据。编码方式有:CVSD、mSBC。最基础的编码方式为CVSD,免提蓝牙设备都需支持该编码方式,支持宽带语音的设备可选mSBC编码数据。
- CVSD:该编码方式的数据传输使用 SCO 或 eSCO 链路。链路的选取是根据本端 Controller是否支持 Enhanced Setup Synchronous Connection指令来决定的,如果支持该命令则创建语音音频链路时使用 eSCO,否则创建 SCO 链路。
- mSBC:该编码方式的数据传输只能使用 eSCO 链路。
音频链路 SCO 或 eSCO 创建成功后,蓝牙系统会以 AUDIO_STATE_CHANGED 的广播通知注册过的应用,并且HF侧的蓝牙芯片会将接收到的语音数据通过PCM接口送入 audio 系统,那系统的 audio 模块是如何操作避免多音源输出呢 ?
这其实还是和蓝牙电话应用密切相关的,蓝牙电话收到音频链路创建成功的广播后通过AudioManager.requestAudioFocus() 申请到系统的音频焦点后,audio 模块会根据申请焦点的 stream type 判断其级别,高级别的音源可以打断低级别的音源(比如:听音乐时打电话,会先暂停掉音乐)。蓝牙电话还需要通过AudioManager.setMode() 接口通知 audio 底层打开通话通道,从而播放出通话语音。
蓝牙电话一般还会有个电话静音功能,开启静音功能后,本端可以听到对方的语音,但对方听不到本端的语音,这样一个功能其实只需要将本端的收音设备给静音掉就可实现。AudioManager.setMicrophoneMute() 设置 true,将 Mic 静音。
由于蓝牙电话语音的传输途径为:phone Audio -> PCM -> AG基带 -> HF基带 -> PCM -> Audio,以及反方向。那么语音数据都是在底层传输的,上层基本涉及不到,从而开发蓝牙电话时获取语音数据就显得尤为困难,但方法也是有的。
- 在音频数据传输的各个节点保存数据文件(如 PCM 输入输出),使用音频分析软件查看
- 蓝牙抓包工具抓取通话的空口数据(如 Ellisys 或 Frontline 工具)
电话音频的分析就先到这里,后续有新的想法我会再更新相关文章的,感兴趣的小伙伴欢迎私信留言一起讨论。
更多互联互通技术,欢迎关注微信公众号:Connectivity