智能音响蓝牙调试经验
介绍:
BT ,bluetooth ,硬件的厂家有 realtek , Broadcom, csr ,rad 等,我了解到的,前两者在 arm android 上集成的比较多,如 rockchip 平台上rtl8723bs ,ap6212,ap6210, ap6335.等。后者 csr rda 没怎么接触过,听说终端设备上用的比较多。
硬件:
Arm adroid 机子上的蓝牙的硬件几乎都是以模块的形式出现,一般同时封装了 WiFi 和 蓝牙,有的甚至还封装了FM. 管脚为 44pin
蓝牙和主控的连接是串口,需要用到串口的流控:cts rts ,(有的例外,如 realtek rtl8723 可把 芯片cts 接地)。
并且上电,复位和 wake 的几个 gpio 要配置正确,同时,32k 的慢时钟是需要的,不然有可能造成蓝牙打不开的情况,32k 的时钟,一般在 rtc (8563),或者pmu ,或者其他地方取。
在蓝牙用到实时通话(hfp , hfp client)的过程中,还需要pcm/i2s 的连接,注意 in 和 out 多分析一下,容易反,其标识容易混淆。
软件:
蓝牙软件实现比较复杂,对比了一下 android5.1 和 android6.0 发现很大的区别,由于项目需要,把 android5.1 的蓝牙部分移植到了 6.0上,花了相当大的经历。
Android6.0 上蓝牙相关代码位置介绍一下:
1 package/app/blutooth
这里不仅仅是蓝牙的app 层的东西,还有和蓝牙协议栈通信的 Jni , 和 api 通信的service
2 frame/base/core/java/android/bluetooth/
这里是 api 的一些东西,实现和 蓝牙 service 通信的 aidl 接口也是在这实现的。
3 system/bt
蓝牙协议栈,android5.1 放在 externel/bluedroid 里面的
4 device/common/bluetooth/libbt
libbt-vendor 不同厂家私有的一些蓝牙定义。
5 ./hardware/libhardware/include/hardware/bluetooth.h
蓝牙的一些头文件。
6 内核的 dts 以及蓝牙rfkill 的电源的支持。
移植过程:
蓝牙在android 上连耳机,连手机电脑的功能,实现比较简单,差不多底层移植好后就能实现了,由android 本身移植好了。
主要是移植音响的功能,也就是做为设备端,让手机连。使设备播放音乐。
到这里的时候就会去查看蓝牙的一些场景:专业术语叫 profile
如手机,平板功能,都是用的 a2dp, hfp, avrcp 等 profile ,而做为音响,耳机的时候是 a2dp sink , avrcp , hfp client 的profile .,另外还一些我没用过的 profile 如: SPP ,HID
这里需要说明的一点,目前蓝牙对一些 profile 的硬件通路,很多没做过蓝牙的人几乎会犯错:
A2dp / A2dp sink :虽然是播放音乐用的,但是他并没有走 pcm 接口,而是走的串口。这时很多人会计算串口波特率,觉得播放音乐完全不够用,以为串口是 115200 为最高波特率,但是实际在蓝牙串口上,波特率设置在3m左右,一般在蓝牙芯片公司给出的 config 文件里可以看到。
Hfp / Hfp client : 实时语音通话,这个时候是走的pcm (软件中有 SCO 的字样)
A2dp sink 的移植看起来比较简单,不需要考虑硬件通路,反正走串口,只需要讲蓝牙过来的音频数据播放到喇叭就可以。
- 在哪取蓝牙过来的音频数据,怎么能让蓝牙进入音频数据过来的模式?
答案是这部分android 已经做好了。我们只需要配置一下 packages/apps/Bluetooth/res/values/config.xml 里的profile_supported_a2dp_sink 为 true 就可以了
他会模拟出一个 app 可以用声音源: AudioSource.BLUETOOTH_A2DP ,我们只需要用new AudioRecord(AudioSource.BLUETOOTH_A2DP,xxxx), 我这边没有用 AudioSource.BLUETOOTH_A2DP 这个名字,直接用的数字11代替,因为要用到这个 AudioSource.BLUETOOTH_A2DP ,其他地方要改很多东西。
2 蓝牙音频数据的播放如何实现?
这个得自己写,我这边主控公司给出的技术支持,写了2个线程的方法,一个线程负责录音,一个线程负责播放。
这个时候,很多人很问一个问题,蓝牙是串口过来的东西,怎么可以直接用AudioRecord 来读数据呢?对这个问题,如果不深入理解,都是迷茫的。后查资料并读 system/bt 协议栈会发现,协议栈通过 audio_a2dp_hw.c btif_media_task.c等实现声卡的模拟,对上层来说就是多了一个蓝牙声卡,可以对它读写控制。蓝牙声卡的模拟实现的数据传输方式是:socket 。Socket 文件地址 /data/misc/bluedroid/.a2dp_ctrl 和 /data/misc/bluedroid/.a2dp_data
实现录音播放后,a2dp sink 是可以听到手机传过来的声音了。
HFP client 移植主要考虑入口 和线程实现,还有 pcm 接口的配置
1 如何进入 hfp client 的profile ,进入后怎么把数据丢到硬件pcm 上去?
同样是配置
packages/apps/Bluetooth/res/values/config.xml 的 profile_supported_hfpclient 为true ,android 已经实现了它的功能。
我们在 java 的找到接口(hfp_enable)后
./packages/apps/Bluetooth/src/com/android/bluetooth/hfpclient/HeadsetClientStateMachine.java:2145: mAudioManager.setParameters("hfp_enable=true");
在hardware 层来实现其功能,我这里还是主控厂家给的补丁。写了4个线程,2个收2个发:流程如下:
downlink 表示 , 远端电话语音信号-> 手机蓝牙-> AP6212 -> 3368 I2S1 PCM_IN 8K- > 3368 I2S0 I2S_SDO 48K-> ES8316 DAC
uplink表示 , CX20921 ADC->3368 I2S0 I2S_SDI 48K -> 3368 I2S1 PCM_OUT 8K -> AP6212 -> 手机蓝牙->远端电话语音信号
2 硬件上怎么设计能出声音?
硬件设计有几种方式
1,拿主控的一路 i2s/pcm 出来,直接接到蓝牙 pcm 。这个直接读写这一路 i2s
2,蓝牙pcm 接到 主控的codec 上。这个切换 codec 的通路。
我们用的第一种方式
3 pcm 参数的配置:可能是个人以前很少用到 pcm 格式,只知道 i2s 的几种格式,如 标准 i2s ,左右对其什么的。
Pcm 也有几种格式,1time delay ,2 time delay 等等。得注意主控 i2s 和 pcm 的配置。当然这个时候示波器是相当重要的,可以查一下配置是否正确,
Pcm 的格式4线的定义是 clk ,sync ,in ,out . clk 一般在256K ,sync 8k ,sync 的波形是差不多一个 slot 的高电平,其余是低电平。
I2s 的格式4线的定义是 ,bclk .lrclk ,in ,out . clk 一般在2.82m ,lrclk 为采样率,44.1k ,8k 都有
4 蓝牙pcm 采样率和播放到喇叭 codec 采样率不一致,怎么调?
采用重采样,直接采用 externel/speex 的 speex 做重采样。
5 通道数不一致,有的通道有杂音,声音不能调大小?
还是在 hardware 层做算法处理,如丢弃声道,mix 声道,大小按规律去更修改 pcm 数据的大小。
AVRCP 的控制
这个简单,直接调用 api ,发送一个play pause 等命令
另外再说一下,花时间最多的问题: android 6.0 上。A2dp sink 老是出 system crash. 查了很久。因为它是偶现的,比如两个小时才出一次,不管是用 addr2line 定位文件位置,还是看 /data/tombstone 文件查看都没有进展,有兴趣的话可以帮查一下问题:
05-07 17:15:46.901 2474 2501 F libc : Fatal signal 11 (SIGSEGV), code 1, fault addr 0xfb0b1ff8 in tid 2501 (bluedroid wake/)
05-07 17:15:47.006 229 229 F DEBUG : *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
05-07 17:15:47.006 229 229 F DEBUG : Build fingerprint: 'Android/rk3368_64/rk3368:6.0.1/MOB30J/user.wade.20180507.150808:userdebug/test-keys'
05-07 17:15:47.007 229 229 F DEBUG : Revision: '0'
05-07 17:15:47.007 229 229 F DEBUG : ABI: 'arm'
05-07 17:15:47.008 229 229 F DEBUG : pid: 2474, tid: 2501, name: bluedroid wake/ >>> com.android.bluetooth <<<
05-07 17:15:47.008 229 229 F DEBUG : signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0xfb0b1ff8
05-07 17:15:47.046 229 229 F DEBUG : r0 aaeb0ed8 r1 00000000 r2 00000108 r3 aaeb1258
05-07 17:15:47.046 229 229 F DEBUG : r4 aaeb1ba0 r5 00000380 r6 fffffc80 r7 00ef0004
05-07 17:15:47.046 229 229 F DEBUG : r8 f74f1eb8 r9 aaeb0ee8 sl f74f1eb8 fp f4249aac
05-07 17:15:47.046 229 229 F DEBUG : ip 00000000 sp e2892288 lr 00ef0050 pc f74bc394 cpsr a00e0030
05-07 17:15:47.055 229 229 F DEBUG :
05-07 17:15:47.055 229 229 F DEBUG : backtrace:
05-07 17:15:47.055 229 229 F DEBUG : #00 pc 0002f394 /system/lib/libc.so (dlmalloc_real+1303)
05-07 17:15:47.055 229 229 F DEBUG : #01 pc 000fc241 /system/lib/hw/bluetooth.default.so (osi_malloc+8)
05-07 17:15:47.055 229 229 F DEBUG : #02 pc 0009c469 /system/lib/hw/bluetooth.default.so (GKI_getbuf+6)
05-07 17:15:47.056 229 229 F DEBUG : #03 pc 0005bc91 /system/lib/hw/bluetooth.default.so (btif_media_sink_enque_buf+72)
05-07 17:15:47.056 229 229 F DEBUG : #04 pc 0003cf17 /system/lib/hw/bluetooth.default.so
05-07 17:15:47.056 229 229 F DEBUG : #05 pc 0008d8f7 /system/lib/hw/bluetooth.default.so (bta_av_stream_data_cback+162)
05-07 17:15:47.056 229 229 F DEBUG : #06 pc 000da5df /system/lib/hw/bluetooth.default.so (avdt_scb_event+70)
05-07 17:15:47.056 229 229 F DEBUG : #07 pc 000dac75 /system/lib/hw/bluetooth.default.so (avdt_ad_tc_data_ind+64)
05-07 17:15:47.057 229 229 F DEBUG : #08 pc 000eb5c7 /system/lib/hw/bluetooth.default.so (l2c_csm_execute+3486)
05-07 17:15:47.057 229 229 F DEBUG : #09 pc 000e600f /system/lib/hw/bluetooth.default.so (l2c_rcv_acl_data+4018)
05-07 17:15:47.057 229 229 F DEBUG : #10 pc 000fe96b /system/lib/hw/bluetooth.default.so
05-07 17:15:47.057 229 229 F DEBUG : #11 pc 000ff93f /system/lib/hw/bluetooth.default.so
05-07 17:15:47.057 229 229 F DEBUG : #12 pc 000415af /system/lib/libc.so (_ZL15__pthread_startPv+30)
05-07 17:15:47.058 229 229 F DEBUG : #13 pc 0001918b /system/lib/libc.so (__start_thread+6)
05-07 17:15:47.532 229 229 F DEBUG :
05-07 17:15:47.532 229 229 F DEBUG : Tombstone written to: /data/tombstones/tombstone_05
05-07 17:15:47.532 229 229 E DEBUG : AM write failed: Broken pipe
05-07 17:15:47.539 564 595 I BootReceiver: Copying /data/tombstones/tombstone_05 to Dr
最后解决这个问题的办法,我采取了把 5.1 的蓝牙部分全部移植到 6.0上。测试没有问题。难道是 android 6.0 对a2dp sink 的支持还不到位?
智能音响蓝牙调试经验相关推荐
- 单片机设计:基于stm32智能语音识别蓝牙音响(ld3320语音识别模块+mp3模块+喇叭+点阵屏+OLED+蓝牙+手机app)
单片机设计:基于stm32智能语音识别蓝牙音响(ld3320语音识别模块+mp3模块+喇叭+点阵屏+OLED+蓝牙+手机app) 一.主要功能: 1.手机app播放内存卡的音乐.同时点阵屏随音乐进行跳 ...
- 蓝牙智能音响测试软件,蓝牙功能测试:蓝牙版本和芯片方案_麦博 MD312_音频评测-中关村在线...
● 易用性测试--蓝牙功能:蓝牙版本和芯片方案 蓝牙的功能是易用性中非常重要的因素,这也是蓝牙音响最为重要的素质之一.在易用性的客观测试方面,我们主要对蓝牙的功能以及相关方面进行测试.我们从这些音响的 ...
- python控制蓝牙音响_[ESP32+MicroPython]智能音响控制
blinker支持多种智能音响控制,如天猫精灵.百度小度.小米小爱.京东叮咚等. 这里以天猫精灵控制为例,blinker DIY支持将设备模拟成三种类型的智能家居:插座.灯.传感器. Blinker支 ...
- Arduino智能小车——蓝牙小车
Arduino智能小车--蓝牙小车 Arduino智能小车系列教程时空门: Arduino智能小车--拼装篇 点击跳转 Arduino智能小车--测试篇 点击跳转 Arduino智能小车--调速篇 点 ...
- 求解:如果通过蓝牙调试小米手环2?
20200228 现状: 一只2016的小米手环2,JD入手,开始时一直带着,后来一年后屏幕越来越暗,放着吃灰. 疑问: 1.是什么原因导致小米手环2屏幕变暗,是老化还是程序设置(例如检测充电周期或电 ...
- 小度智能音响拆解 芯片_不拆不快:小度音箱拆解测评
不拆不快:小度音箱拆解测评 2018-11-15 11:38:37 16点赞 4收藏 2评论 其实刚收到测评申请通过信息的时候,内心是拒绝的,百度财大气粗的提供了100个小度音箱,也就意味着未来一段时 ...
- 软件测试AI语音智能音响,什么是智能音箱_ai音箱都有什么功能 - 全文
智能音箱是什么?智能音箱究竟都有些什么功能呢?今天我们就来聊聊这个话题. 一.什么是智能音箱? 智能音箱是什么?简单的说,这类产品拥有更加人性化的操控和功能,而且也不仅仅是一个扬声器那么简单,例如近期 ...
- 分享在实际项目中积累的硬件调试经验 - 调试方法,以及常见调试案例
文章目录 一.硬件调试的四个目标 二.硬件调试心得 三.一块新的板子的调试思路 四.硬件调试,一些网络资料 五.单片机硬件调试中常见的案例(杂记) 往期系列文章: 1.裸机项目开发经验分享 - 完整开 ...
- sja1000调试经验
sja1000调试经验 去年年底的时候,一个公司给我打电话,问我最近有没有空,说要请我帮忙做一个基于CAN总 这里写代码片线通讯的东西,我去看了看,是一个数据采集系统,下面是一系列数据采集的智能板卡, ...
最新文章
- BZOJ 2004 [Hnoi2010]Bus 公交线路
- vue如何使用原生js写动画效果_手摸手,带你用 vue 动画实现原生 app 切换效果,丝滑般的体验...
- C#选择目录对话框FolderBrowserDialog
- 利用windbg探索进程和进程上下文
- 11.3finally块控制的读取文件释放
- 3.2 使用pytorch搭建AlexNet并训练花分类数据集
- “象征界”的奇观:刘天怜花鸟工笔作品印象
- 小猪佩奇python_python画个小猪佩奇
- python封装api给vue_Vue axios api统一管理的封装
- java反射方法调用_Java反射(3)调用方法
- 【学习OpenCV】—— 深入了解 cv::Mat
- 《计算机系统:系统架构与操作系统的高度集成》——1.5 计算机硬件的演化...
- MATLAB线性方程组的两种求解,matlab求解线性方程组
- 如何修改apk服务器,如何修改apk服务器地址
- Dummy variable (变量dummy化)
- matlab 混沌工具箱,matlab混沌工具箱
- 云服务器/树莓派搭建我的世界Minecraft多人游戏服务器
- Word2016加载MathType打开时显示“安全警告 宏已被禁用”解决办法
- HYSBZ 2565 最长双回文串 (回文树)
- 20145212罗天晨 逆向及Bof基础实践