介绍:

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 的移植看起来比较简单,不需要考虑硬件通路,反正走串口,只需要讲蓝牙过来的音频数据播放到喇叭就可以。

  1. 在哪取蓝牙过来的音频数据,怎么能让蓝牙进入音频数据过来的模式?

答案是这部分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 的支持还不到位?

智能音响蓝牙调试经验相关推荐

  1. 单片机设计:基于stm32智能语音识别蓝牙音响(ld3320语音识别模块+mp3模块+喇叭+点阵屏+OLED+蓝牙+手机app)

    单片机设计:基于stm32智能语音识别蓝牙音响(ld3320语音识别模块+mp3模块+喇叭+点阵屏+OLED+蓝牙+手机app) 一.主要功能: 1.手机app播放内存卡的音乐.同时点阵屏随音乐进行跳 ...

  2. 蓝牙智能音响测试软件,蓝牙功能测试:蓝牙版本和芯片方案_麦博 MD312_音频评测-中关村在线...

    ● 易用性测试--蓝牙功能:蓝牙版本和芯片方案 蓝牙的功能是易用性中非常重要的因素,这也是蓝牙音响最为重要的素质之一.在易用性的客观测试方面,我们主要对蓝牙的功能以及相关方面进行测试.我们从这些音响的 ...

  3. python控制蓝牙音响_[ESP32+MicroPython]智能音响控制

    blinker支持多种智能音响控制,如天猫精灵.百度小度.小米小爱.京东叮咚等. 这里以天猫精灵控制为例,blinker DIY支持将设备模拟成三种类型的智能家居:插座.灯.传感器. Blinker支 ...

  4. Arduino智能小车——蓝牙小车

    Arduino智能小车--蓝牙小车 Arduino智能小车系列教程时空门: Arduino智能小车--拼装篇 点击跳转 Arduino智能小车--测试篇 点击跳转 Arduino智能小车--调速篇 点 ...

  5. 求解:如果通过蓝牙调试小米手环2?

    20200228 现状: 一只2016的小米手环2,JD入手,开始时一直带着,后来一年后屏幕越来越暗,放着吃灰. 疑问: 1.是什么原因导致小米手环2屏幕变暗,是老化还是程序设置(例如检测充电周期或电 ...

  6. 小度智能音响拆解 芯片_不拆不快:小度音箱拆解测评

    不拆不快:小度音箱拆解测评 2018-11-15 11:38:37 16点赞 4收藏 2评论 其实刚收到测评申请通过信息的时候,内心是拒绝的,百度财大气粗的提供了100个小度音箱,也就意味着未来一段时 ...

  7. 软件测试AI语音智能音响,什么是智能音箱_ai音箱都有什么功能 - 全文

    智能音箱是什么?智能音箱究竟都有些什么功能呢?今天我们就来聊聊这个话题. 一.什么是智能音箱? 智能音箱是什么?简单的说,这类产品拥有更加人性化的操控和功能,而且也不仅仅是一个扬声器那么简单,例如近期 ...

  8. 分享在实际项目中积累的硬件调试经验 - 调试方法,以及常见调试案例

    文章目录 一.硬件调试的四个目标 二.硬件调试心得 三.一块新的板子的调试思路 四.硬件调试,一些网络资料 五.单片机硬件调试中常见的案例(杂记) 往期系列文章: 1.裸机项目开发经验分享 - 完整开 ...

  9. sja1000调试经验

    sja1000调试经验 去年年底的时候,一个公司给我打电话,问我最近有没有空,说要请我帮忙做一个基于CAN总 这里写代码片线通讯的东西,我去看了看,是一个数据采集系统,下面是一系列数据采集的智能板卡, ...

最新文章

  1. BZOJ 2004 [Hnoi2010]Bus 公交线路
  2. vue如何使用原生js写动画效果_手摸手,带你用 vue 动画实现原生 app 切换效果,丝滑般的体验...
  3. C#选择目录对话框FolderBrowserDialog
  4. 利用windbg探索进程和进程上下文
  5. 11.3finally块控制的读取文件释放
  6. 3.2 使用pytorch搭建AlexNet并训练花分类数据集
  7. “象征界”的奇观:刘天怜花鸟工笔作品印象
  8. 小猪佩奇python_python画个小猪佩奇
  9. python封装api给vue_Vue axios api统一管理的封装
  10. java反射方法调用_Java反射(3)调用方法
  11. 【学习OpenCV】—— 深入了解 cv::Mat
  12. 《计算机系统:系统架构与操作系统的高度集成》——1.5 计算机硬件的演化...
  13. MATLAB线性方程组的两种求解,matlab求解线性方程组
  14. 如何修改apk服务器,如何修改apk服务器地址
  15. Dummy variable (变量dummy化)
  16. matlab 混沌工具箱,matlab混沌工具箱
  17. 云服务器/树莓派搭建我的世界Minecraft多人游戏服务器
  18. Word2016加载MathType打开时显示“安全警告 宏已被禁用”解决办法
  19. HYSBZ 2565 最长双回文串 (回文树)
  20. 20145212罗天晨 逆向及Bof基础实践

热门文章

  1. 我国量子通信卫星将于7月份发射 产业链股受益
  2. 【Android休眠】之Android休眠机制
  3. 京东物流加入全球区块链货运联盟
  4. java a3 套打印_Java输出打印工具类封装的实例
  5. 饿了么UI的表单验证,有输入东西,但是一直无法通过验证。
  6. 重写VueRouter的push|replace
  7. 支持avi mkv的html视频插件,轻型智能云存储 N2家庭云盘探索区块链新路径
  8. 【WebApp】单页webapp应用开发总结【暂完】
  9. 儿童玩具相机亚马逊CPC认证检测标准
  10. 如何在火狐浏览器中安装vuejs devtools