智能音响蓝牙调试经验

蓝牙适配器

0人已加入

描述

智能蓝牙音箱是音箱升级的产物,是家庭消费者用语音控制的一个智能化设备。譬如:人们可以通过智能音箱点歌曲、上网购物或是了解天气预报等。同时,它也可以对智能家居设备进行控制,比如打开窗帘、设置冰箱温度、提前让热水器升温等。而关于这一智能设备要如何开发,则可以从以下4大方面了解:

一、智能音箱的控制方式

据了解,传统的非智能音箱一般通过遥控器或机身按钮进行控制。而当下智能音箱使用的遥控器越来越被看作是备用功能。而常用的控制功能,是通过APP/微信/支付宝小程序进行控制。并且,智能音箱同时还兼容手势识别、语音控制、挥手感应等控制方式。

这就意味着,企业在对智能蓝牙音箱解决方案进行开发时,除了要注意微信、支付宝、APP等进行开发外,还应设置手势识别、语音控制能开发功能。

二、智能音箱的通信手段

智能音箱是通过蓝牙、WIFI、NFC等信息传输方式来传递信息。NFC通常在手机和音箱连接的瞬间连接,简单直接,不会有复杂的使用过程。与此类似,有的智能音箱还采用了声波连接的方式,在一定范围内进行传输,质量和蓝牙、WIFI平分秋色,只是WIFI的成本略高,但对于智能开发端的企业,可以抹平这个差价。

三、智能音箱的功能开发

从上可知,智能音箱的功能包含了集成机音机、播报天气、闹钟等常见功能,除此以外,还具有朗读、智能座机、甚至智能电视机以及智能语音机器人助手等功能。这些功能可以指引智能音箱进行语音购物、语音信息查询、语音视频聊天等。

而这意味着,智能音箱解决方案的投资人,在对其进行开发时,在功能设置上也不应马虎。

四、智能音箱关键性技术

了解项目开发的人都知道,音箱本来就是强调品牌且技术门槛较高的领域。而智能音箱是传统音箱的升级,它不仅有基础的技术开发,还将声学设计、无线技术、语音识别、远场拾音、语义分析等众多技术互融在一起。

不仅技术复杂,而且更加依赖音乐内容平台支持。而这一切,都离不开小型便捷与低音增强技术、无线技术及声音对码技术以及远场语音唤醒识别技术等。

智能音响蓝牙调试经验

介绍:

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 的支持还不到位?

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分