智能音響藍(lán)牙調(diào)試經(jīng)驗(yàn)
智能藍(lán)牙音箱是音箱升級(jí)的產(chǎn)物,是家庭消費(fèi)者用語音控制的一個(gè)智能化設(shè)備。譬如:人們可以通過智能音箱點(diǎn)歌曲、上網(wǎng)購(gòu)物或是了解天氣預(yù)報(bào)等。同時(shí),它也可以對(duì)智能家居設(shè)備進(jìn)行控制,比如打開窗簾、設(shè)置冰箱溫度、提前讓熱水器升溫等。而關(guān)于這一智能設(shè)備要如何開發(fā),則可以從以下4大方面了解:
一、智能音箱的控制方式
據(jù)了解,傳統(tǒng)的非智能音箱一般通過遙控器或機(jī)身按鈕進(jìn)行控制。而當(dāng)下智能音箱使用的遙控器越來越被看作是備用功能。而常用的控制功能,是通過APP/微信/支付寶小程序進(jìn)行控制。并且,智能音箱同時(shí)還兼容手勢(shì)識(shí)別、語音控制、揮手感應(yīng)等控制方式。
這就意味著,企業(yè)在對(duì)智能藍(lán)牙音箱解決方案進(jìn)行開發(fā)時(shí),除了要注意微信、支付寶、APP等進(jìn)行開發(fā)外,還應(yīng)設(shè)置手勢(shì)識(shí)別、語音控制能開發(fā)功能。
二、智能音箱的通信手段
智能音箱是通過藍(lán)牙、WIFI、NFC等信息傳輸方式來傳遞信息。NFC通常在手機(jī)和音箱連接的瞬間連接,簡(jiǎn)單直接,不會(huì)有復(fù)雜的使用過程。與此類似,有的智能音箱還采用了聲波連接的方式,在一定范圍內(nèi)進(jìn)行傳輸,質(zhì)量和藍(lán)牙、WIFI平分秋色,只是WIFI的成本略高,但對(duì)于智能開發(fā)端的企業(yè),可以抹平這個(gè)差價(jià)。
三、智能音箱的功能開發(fā)
從上可知,智能音箱的功能包含了集成機(jī)音機(jī)、播報(bào)天氣、鬧鐘等常見功能,除此以外,還具有朗讀、智能座機(jī)、甚至智能電視機(jī)以及智能語音機(jī)器人助手等功能。這些功能可以指引智能音箱進(jìn)行語音購(gòu)物、語音信息查詢、語音視頻聊天等。
而這意味著,智能音箱解決方案的投資人,在對(duì)其進(jìn)行開發(fā)時(shí),在功能設(shè)置上也不應(yīng)馬虎。
四、智能音箱關(guān)鍵性技術(shù)
了解項(xiàng)目開發(fā)的人都知道,音箱本來就是強(qiáng)調(diào)品牌且技術(shù)門檻較高的領(lǐng)域。而智能音箱是傳統(tǒng)音箱的升級(jí),它不僅有基礎(chǔ)的技術(shù)開發(fā),還將聲學(xué)設(shè)計(jì)、無線技術(shù)、語音識(shí)別、遠(yuǎn)場(chǎng)拾音、語義分析等眾多技術(shù)互融在一起。
不僅技術(shù)復(fù)雜,而且更加依賴音樂內(nèi)容平臺(tái)支持。而這一切,都離不開小型便捷與低音增強(qiáng)技術(shù)、無線技術(shù)及聲音對(duì)碼技術(shù)以及遠(yuǎn)場(chǎng)語音喚醒識(shí)別技術(shù)等。
智能音響藍(lán)牙調(diào)試經(jīng)驗(yàn)
介紹:
BT ,bluetooth ,硬件的廠家有 realtek , Broadcom, csr ,rad 等,我了解到的,前兩者在 arm android 上集成的比較多,如 rockchip 平臺(tái)上rtl8723bs ,ap6212,ap6210, ap6335.等。后者 csr rda 沒怎么接觸過,聽說終端設(shè)備上用的比較多。
硬件:
Arm adroid 機(jī)子上的藍(lán)牙的硬件幾乎都是以模塊的形式出現(xiàn),一般同時(shí)封裝了 WiFi 和 藍(lán)牙,有的甚至還封裝了FM. 管腳為 44pin
藍(lán)牙和主控的連接是串口,需要用到串口的流控:cts rts ,(有的例外,如 realtek rtl8723 可把 芯片cts 接地)。
并且上電,復(fù)位和 wake 的幾個(gè) gpio 要配置正確,同時(shí),32k 的慢時(shí)鐘是需要的,不然有可能造成藍(lán)牙打不開的情況,32k 的時(shí)鐘,一般在 rtc (8563),或者pmu ,或者其他地方取。
在藍(lán)牙用到實(shí)時(shí)通話(hfp , hfp client)的過程中,還需要pcm/i2s 的連接,注意 in 和 out 多分析一下,容易反,其標(biāo)識(shí)容易混淆。
軟件:
藍(lán)牙軟件實(shí)現(xiàn)比較復(fù)雜,對(duì)比了一下 android5.1 和 android6.0 發(fā)現(xiàn)很大的區(qū)別,由于項(xiàng)目需要,把 android5.1 的藍(lán)牙部分移植到了 6.0上,花了相當(dāng)大的經(jīng)歷。
Android6.0 上藍(lán)牙相關(guān)代碼位置介紹一下:
1 package/app/blutooth
這里不僅僅是藍(lán)牙的app 層的東西,還有和藍(lán)牙協(xié)議棧通信的 Jni , 和 api 通信的service.
2 frame/base/core/java/android/bluetooth/
這里是 api 的一些東西,實(shí)現(xiàn)和 藍(lán)牙 service 通信的 aidl 接口也是在這實(shí)現(xiàn)的。
3 system/bt
藍(lán)牙協(xié)議棧,android5.1 放在 externel/bluedroid 里面的
4 device/common/bluetooth/libbt
libbt-vendor 不同廠家私有的一些藍(lán)牙定義。
5 。/hardware/libhardware/include/hardware/bluetooth.h
藍(lán)牙的一些頭文件。
6 內(nèi)核的 dts 以及藍(lán)牙rfkill 的電源的支持。
移植過程:
藍(lán)牙在android 上連耳機(jī),連手機(jī)電腦的功能,實(shí)現(xiàn)比較簡(jiǎn)單,差不多底層移植好后就能實(shí)現(xiàn)了,由android 本身移植好了。
主要是移植音響的功能,也就是做為設(shè)備端,讓手機(jī)連。使設(shè)備播放音樂。
到這里的時(shí)候就會(huì)去查看藍(lán)牙的一些場(chǎng)景:專業(yè)術(shù)語叫 profile
如手機(jī),平板功能,都是用的 a2dp, hfp, avrcp 等 profile ,而做為音響,耳機(jī)的時(shí)候是 a2dp sink , avrcp , hfp client 的profile 。,另外還一些我沒用過的 profile 如: SPP ,HID
這里需要說明的一點(diǎn),目前藍(lán)牙對(duì)一些 profile 的硬件通路,很多沒做過藍(lán)牙的人幾乎會(huì)犯錯(cuò):
A2dp / A2dp sink :雖然是播放音樂用的,但是他并沒有走 pcm 接口,而是走的串口。這時(shí)很多人會(huì)計(jì)算串口波特率,覺得播放音樂完全不夠用,以為串口是 115200 為最高波特率,但是實(shí)際在藍(lán)牙串口上,波特率設(shè)置在3m左右,一般在藍(lán)牙芯片公司給出的 config 文件里可以看到。
Hfp / Hfp client : 實(shí)時(shí)語音通話,這個(gè)時(shí)候是走的pcm (軟件中有 SCO 的字樣)
A2dp sink 的移植看起來比較簡(jiǎn)單,不需要考慮硬件通路,反正走串口,只需要講藍(lán)牙過來的音頻數(shù)據(jù)播放到喇叭就可以。
在哪取藍(lán)牙過來的音頻數(shù)據(jù),怎么能讓藍(lán)牙進(jìn)入音頻數(shù)據(jù)過來的模式?
答案是這部分android 已經(jīng)做好了。我們只需要配置一下 packages/apps/Bluetooth/res/values/config.xml 里的profile_supported_a2dp_sink 為 true 就可以了
他會(huì)模擬出一個(gè) app 可以用聲音源: AudioSource.BLUETOOTH_A2DP ,我們只需要用new AudioRecord(AudioSource.BLUETOOTH_A2DP,xxxx), 我這邊沒有用 AudioSource.BLUETOOTH_A2DP 這個(gè)名字,直接用的數(shù)字11代替,因?yàn)橐玫竭@個(gè) AudioSource.BLUETOOTH_A2DP ,其他地方要改很多東西。
2 藍(lán)牙音頻數(shù)據(jù)的播放如何實(shí)現(xiàn)?
這個(gè)得自己寫,我這邊主控公司給出的技術(shù)支持,寫了2個(gè)線程的方法,一個(gè)線程負(fù)責(zé)錄音,一個(gè)線程負(fù)責(zé)播放。
這個(gè)時(shí)候,很多人很問一個(gè)問題,藍(lán)牙是串口過來的東西,怎么可以直接用AudioRecord 來讀數(shù)據(jù)呢?對(duì)這個(gè)問題,如果不深入理解,都是迷茫的。后查資料并讀 system/bt 協(xié)議棧會(huì)發(fā)現(xiàn),協(xié)議棧通過 audio_a2dp_hw.c btif_media_task.c等實(shí)現(xiàn)聲卡的模擬,對(duì)上層來說就是多了一個(gè)藍(lán)牙聲卡,可以對(duì)它讀寫控制。藍(lán)牙聲卡的模擬實(shí)現(xiàn)的數(shù)據(jù)傳輸方式是:socket 。Socket 文件地址 /data/misc/bluedroid/.a2dp_ctrl 和 /data/misc/bluedroid/.a2dp_data
實(shí)現(xiàn)錄音播放后,a2dp sink 是可以聽到手機(jī)傳過來的聲音了。
HFP client 移植主要考慮入口 和線程實(shí)現(xiàn),還有 pcm 接口的配置
1 如何進(jìn)入 hfp client 的profile ,進(jìn)入后怎么把數(shù)據(jù)丟到硬件pcm 上去?
同樣是配置
packages/apps/Bluetooth/res/values/config.xml 的 profile_supported_hfpclient 為true ,android 已經(jīng)實(shí)現(xiàn)了它的功能。
我們?cè)?java 的找到接口(hfp_enable)后
。/packages/apps/Bluetooth/src/com/android/bluetooth/hfpclient/HeadsetClientStateMachine.java:2145: mAudioManager.setParameters(“hfp_enable=true”);
在hardware 層來實(shí)現(xiàn)其功能,我這里還是主控廠家給的補(bǔ)丁。寫了4個(gè)線程,2個(gè)收2個(gè)發(fā):流程如下:
downlink 表示 , 遠(yuǎn)端電話語音信號(hào)-》 手機(jī)藍(lán)牙-》 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 -》 手機(jī)藍(lán)牙-》遠(yuǎn)端電話語音信號(hào)
2 硬件上怎么設(shè)計(jì)能出聲音?
硬件設(shè)計(jì)有幾種方式
1,拿主控的一路 i2s/pcm 出來,直接接到藍(lán)牙 pcm 。這個(gè)直接讀寫這一路 i2s
2,藍(lán)牙pcm 接到 主控的codec 上。這個(gè)切換 codec 的通路。
我們用的第一種方式
3 pcm 參數(shù)的配置:可能是個(gè)人以前很少用到 pcm 格式,只知道 i2s 的幾種格式,如 標(biāo)準(zhǔn) i2s ,左右對(duì)其什么的。
Pcm 也有幾種格式,1time delay ,2 time delay 等等。得注意主控 i2s 和 pcm 的配置。當(dāng)然這個(gè)時(shí)候示波器是相當(dāng)重要的,可以查一下配置是否正確,
Pcm 的格式4線的定義是 clk ,sync ,in ,out 。 clk 一般在256K ,sync 8k ,sync 的波形是差不多一個(gè) slot 的高電平,其余是低電平。
I2s 的格式4線的定義是 ,bclk .lrclk ,in ,out 。 clk 一般在2.82m ,lrclk 為采樣率,44.1k ,8k 都有
4 藍(lán)牙pcm 采樣率和播放到喇叭 codec 采樣率不一致,怎么調(diào)?
采用重采樣,直接采用 externel/speex 的 speex 做重采樣。
5 通道數(shù)不一致,有的通道有雜音,聲音不能調(diào)大小?
還是在 hardware 層做算法處理,如丟棄聲道,mix 聲道,大小按規(guī)律去更修改 pcm 數(shù)據(jù)的大小。
AVRCP 的控制
這個(gè)簡(jiǎn)單,直接調(diào)用 api ,發(fā)送一個(gè)play pause 等命令
另外再說一下,花時(shí)間最多的問題: android 6.0 上。A2dp sink 老是出 system crash. 查了很久。因?yàn)樗桥棘F(xiàn)的,比如兩個(gè)小時(shí)才出一次,不管是用 addr2line 定位文件位置,還是看 /data/tombstone 文件查看都沒有進(jìn)展,有興趣的話可以幫查一下問題:
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: ‘a(chǎn)rm’
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
最后解決這個(gè)問題的辦法,我采取了把 5.1 的藍(lán)牙部分全部移植到 6.0上。測(cè)試沒有問題。難道是 android 6.0 對(duì)a2dp sink 的支持還不到位?
非常好我支持^.^
(0) 0%
不好我反對(duì)
(0) 0%
相關(guān)閱讀:
- [電子說] STM32速成筆記(15)—串口IAP 2023-10-24
- [電子說] HAL庫(kù)中對(duì)串口中斷執(zhí)行流程的分解 2023-10-24
- [電子說] nrf_serial庫(kù)的使用技巧 2023-10-24
- [電子說] 國(guó)產(chǎn)藍(lán)牙芯片的發(fā)展趨勢(shì)值藍(lán)牙數(shù)傳ble芯片 2023-10-24
- [電子說] 藍(lán)牙芯片PHY6222應(yīng)用電動(dòng)牙刷徠芬的細(xì)節(jié)以及為什么選他和替代 2023-10-24
- [電子說] 致遠(yuǎn)電子新一代8路串口服務(wù)器 2023-10-24
- [電子說] 拔掉你的硬盤,吵到我的藍(lán)牙了! 2023-10-24
- [電子說] STM32速成筆記(5)—串口通信 2023-10-24
( 發(fā)表人:李倩 )