智能音響藍牙調試經驗
智能藍牙音箱是音箱升級的產物,是家庭消費者用語音控制的一個智能化設備。譬如:人們可以通過智能音箱點歌曲、上網購物或是了解天氣預報等。同時,它也可以對智能家居設備進行控制,比如打開窗簾、設置冰箱溫度、提前讓熱水器升溫等。而關于這一智能設備要如何開發,則可以從以下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
藍牙的一些頭文件。
移植過程:
藍牙在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 的支持還不到位?
非常好我支持^.^
(0) 0%
不好我反對
(0) 0%
相關閱讀:
- [電子說] STM32速成筆記(15)—串口IAP 2023-10-24
- [電子說] HAL庫中對串口中斷執行流程的分解 2023-10-24
- [電子說] nrf_serial庫的使用技巧 2023-10-24
- [電子說] 國產藍牙芯片的發展趨勢值藍牙數傳ble芯片 2023-10-24
- [電子說] 藍牙芯片PHY6222應用電動牙刷徠芬的細節以及為什么選他和替代 2023-10-24
- [電子說] 致遠電子新一代8路串口服務器 2023-10-24
- [電子說] 拔掉你的硬盤,吵到我的藍牙了! 2023-10-24
- [電子說] STM32速成筆記(5)—串口通信 2023-10-24
( 發表人:李倩 )