2009年6月10日 星期三

藍芽Speaker,請不要斷續

前一陣子,因為demo需要,和 Jserv去光華商場買了一件藍芽Speaker回來,也開始玩了Bluetooth的a2dp。但運氣不好的是,沒有把bluetooth device 整合好,bluetooth init和開啟時沒有把baud rate設對,以致於經由bluetooth輸出到Speaker時,聲音是斷斷續續,固定間隔的出來。這的確是讓我卡了一陣,雖然解法似乎很簡單。時間差了一點,就可demo出經由a2dp輸出到藍芽Speaker。這讓我感受到資訊整理的重要。

android1.5,已支援a2dp, 經由android的mediaserver 使用 libaudioflinger,再呼叫 liba2dp的function,把解好的聲音檔 (pcm格式) 丟給bluez,做sbc encode,丟到socket,而後送到bluetooth device上。 liba2dp.so為android在bluez裡建立的plugin,這條路是android所提供的。

另一條路,則是build 出bluez 原本給 alsa-lib使用的alsa plugins, libasound_module_ctl_bluetooth.so and libasound_module_pcm_bluetooth.so,
並將其放至/system/usr/lib/alsa-lib/ , here is a quick patch for this.

Some test steps and notes are as below (on Android 1.5, 00:17:53:09:2E:E0 is the device address):
vi /system/etc/asound.conf ,
pcm.bluetooth {
type bluetooth
device 00:17:53:09:2E:E0
profile "auto"
}

test steps:
1. hcitool scan
2. passkey-agent --default --path /org/bluez/hci0 0000 00:17:53:09:2E:E0 &
3. dbus-send --system --dest=org.bluez --type=method_call --print-reply /org/bluez/hci0 org.bluez.Adapter.
CreateBonding string:00:17:53:09:2E:E0
4. dbus-send --system --dest=org.bluez --type=method_call --print-reply /org/bluez/audio org.bluez.audio.Manager.CreateDevice string:00:17:53:09:2E:E0
5. alsa_aplay -Dplug:bluetooth /horse.wav

除了a2dp, 與Android UI的整合也花了一些功夫,overview的整理一下,SystemSever起來時,會啟動BluetoothDeviceService, BluetoothA2dpService這兩個service。bluetooth 的上層java部份(framework.jar),會透過一層JNI 呼叫 (libandroid_runtime.so),使用dbus與hcid溝通(之後bluez 4.x版為bluetoothd), 以及呼叫libbluedroid來控制硬體。