星期日, 4月 09, 2006

在 Mandriva 2006 上,讓 skype 使用 Bluetooth 耳機

先說一點廢話。以前一直是使用 Red Hat 的,連我的 desktop 上,到最後都只剩下 Red Hat Linux 9.0+,也就是 9.0 加上一堆我自己的修改。不過因為 Red Hat 在 9.0 之後停止發展 RHL,而我自己對於 Fedora 的 FC1/2 感覺不是很好,因此一直有想要轉到 Mandriva 上的想法。雖然之前已經裝過 Mandrake 10.0,不過因為一些原因,裝好之後都一直沒有使用。最近重新裝了 Mandriva 2006.0,大致上感覺還不錯,但是一些小地方讓人覺得Mandriva 公司的軟體包裝策略實在有點讓人摸不著頭緒。

廢話說完,回歸到主題。Mandriva 2006 上,預設使用 bluez 套件來提供 bluetooth 支援。不過目前來說,bluez 仍然不直接支援使用 SCO (Sychronous Connection-Oriented) 和 A2DP (Advanced Audio Distribution Profile) 的藍芽裝置,例如藍芽無線耳機麥克風或藍芽立體聲無線耳機等等。因此即使安裝了相關的藍芽支援套件,例如 bluez-utils 和 gnome-bluetooth 以後,仍然無法使用藍芽耳機麥克風。

不過事情總是會有轉機,Free Software/Open Source Software 的美妙之處,就是總是可以發現一些高手看到某些不方便,然後就發展一些解決方案。在 Linux 上無法使用藍芽耳機麥克風,感覺實在是有點糟,因此就有了一個叫作 Bluetooth-ALSA 的計劃,這個計劃的目的就是讓 Linux 也能使用藍芽無線耳機和無線耳機麥克風。引用一段計劃網頁上的說明:

This project provides a way to use a bluetooth headset with Linux. We do this currently by making an alsa kernel driver which uses bluez to reach the headset. It works well enough now to get voice-quality audio to and from most headsets.


不過這個計劃還是在發展初期,最 新的 release 是 btsco 0.41。雖然 btsco v0.41 中已經包含了使用 skype 所需要的基本功能,不過由於是發展中的軟體,我是比較偏向使用 CVS 中的 source code。

目前來說,Mandriva 2006 中,還沒有出現已經包裝好的 btsco RPM 可以用,因此安裝上比較麻煩些。現階段來說,btsco 的使用還不是非常適合一般使用者使用,因此我暫時也沒有打包成 RPM 的計劃。大致上的安裝步驟如下:


  1. 由 CVS 取得最新的 source code:


    $ cd /tmp
    $ cvs -d:pserver:anonymous@cvs.sf.net:/cvsroot/bluetooth-alsa co btsco
    $ cd btsco


  2. 在開始進行 building 程序之前,需先確認以下 RPM 已經安裝:

    automake1.7
    libbluez1-devel
    libalsa2-devel
    libao2-devel


  3. 修改 bootstrap 這個 shell script 的內容。由於 Mandriva 2006 預設使用 automake 1.8,因此這個修改是必要的,否則接下來的 building 程序一定會失敗。修改 bootstrap 的內容,將 aclocal 和 automake 改成 aclocal-1.7 和 automake-1.7:

    #! /bin/sh

    aclocal-1.7 -I /usr/share/aclocal && autoheader && automake-1.7 --add-missing --copy && autoconf


  4. 開 始 building 程序。依序使用以下 building 程序,compile btsco 的 utility (a2play, a2recv, avrecv, avsnd, btsco, btsco2) 和 kernel 模組 (snd-bt-sco.ko.gz)。由於 Mandriva 2006 的 bluez-utils RPM 中已經包含了 btsco 裡面的 ALSA plugin,因此不需要自己 compile ALSA plugin。

    $ ./bootstrap
    $ ./configure --enable-all
    $ make
    $ cd kernel
    $ make
    $ gzip *.ko


  5. 把 snd-bt-sco.ko.gz 以 root 權限安裝到系統中。雖然直接放到 /lib/modules 裡面就可以了,但是我不是很建議這麼做,因為可能會造成一些後續管理上的麻煩。我的作法是把 snd-bt-sco.ko.gz 和其他的 utility 都先放在 $HOME/btsco 裡面,然後用 root 權限在 /lib/modules 下某個適當的位置建立 symbolic link:

    $ mkdir ~/btsco
    $ mv a2play a2recv avrecv avsnd btsco btsco2 snd-bt-sco.ko.gz ~/btsco/
    $ pushd /lib/modules/`uname -r`/kernel/3rdparty
    $ sudo ln -s $HOME/btsco/snd-bt-sco.ko.gz .
    $ sudo depmod
    $ sudo modprobe snd_bt_sco
    $ popd


  6. 在 ~/bin 中建立適當的 symbolic link。基本上只要有 btsco 這個 SCO daemon 即可,但是其他的 utility 在其他場合可能會用到,所以一併建立 link:

    $ cd ~/bin
    $ ln -s ../btsco/{a2play,a2recv,avrecv,avsnd,btsco,btsco2} .


  7. 使用 root 權限設定 hci0 這個 hci device 的 voice 參數:

    $ sudo hciconfig hci0 voice 0x0060


  8. 確 定藍芽無線耳機麥克風可以跟電腦建立連線。需要注意的是,大部分的藍芽無線耳機麥克風在非 pairing 模式時,使用 hcitool 進行 scan 是找不到的,因此這邊可能必須要重新對耳機麥克風做一次 pairing。方法是先把藍芽無線耳機麥克風切換至 pairing 模式,然後執行以下指令建立連線完成 pairing:

    $ hcitool scan
    00:0A:94:93:74:B7 Jabra Blah 1234
    $ hcitool cc 00:0A:94:93:74:B7


  9. 如果上面有成功建立連線的話,那就可以啟動 btsco 進行測試。啟動 btsco 的方法很簡單,不過需要上面得到的那個 BD Addr:

    $ btsco 00:0A:94:93:74:B7


  10. 如果上面 btsco daemon 能成功執行的話,那就可以用下面的指令使用 mplayer 播放 mp3,如果能夠在耳機中聽到正確的音樂,那麼基本的設定就已經完成:

    $ mplayer -ao alsa:device=plughw=Headset FOO_BAR.mp3




基 本上到這邊,系統已經可以透過 btsco 使用藍芽無線耳機麥克風了。但是如果要讓 skype 可以透過 btsco 使用藍芽無線耳機麥克風的話,還需要一些手續。skype 目前的 Linux 版本除了是 1.2 以外,最大的問題在於目前 skype 只支援 OSS,並不直接支援 ALSA。雖然這在一般使用上並沒有太大的問題,而在 GNOME/KDE 上,可以透過 EsounD/aRTs 的 wrapper,或者是 Mandriva 自己的 soundwrapper 來和 GNOME/KDE 和平相處,但是也因此要讓 skype 能使用 btsco 變得有一點麻煩。好在已經有人提出暫時的變通辦法,Andreas Beck 在 Bluetooth-ALSA 計劃的 mailing list 上,提到他對 btsco 做了些 patch,也寫了些 script 和 wrapper,讓 skype 可以使用 btsco 來聯接無線耳機麥克風。他的 patch 後來沒多久就被收錄進 btsco 的 CVS 中,因此最新的 0.41 tarball 以及 CVS source 中,都已經包含了所需要的 patch,而他寫的 script 和 wrapper 則可以直 接在他的網站下載, 或者也可以在最新的 tarball 和 CVS source 的 btsco/contrib 目錄裡面找到。假設使用 CVS 中的 souce,那麼 compile 和設定他的 script/wrapper 的程序如下,相關細節請參考原作者寫的 README 檔案內容:


  1. 先 compile 他的 libskype_bt_hijacker.so wrapper:

    $ cd /tmp/btsco/contrib
    $ make


  2. 修改 btscorunner script 的 HEADSETADDR 變數值,改成上面 scan 時得到的 BD Addr 值。

  3. 修 改 skype_bt_hijacker script 的 HIJACKDSP 和 SECONDARYDEV 的值,改成系統中的 primary 和 secondary dsp device 的值。在我的機器上,Mandriva 2006 的系統使用原本的設定值 (/dev/dsp 和 /dev/dsp1) 即可。這個主要是要告訴 wrapper 該攔截 skype 對哪個裝置的 I/O 動作。此外還要修改 BINPATH 的值,假設接下來要把這些 script 和 wrapper 都放在 ~/btsco 裡面的話,就把 BINPATH 改成 ~/btsco 即可。

  4. 修 改 skype_bt_hijacker_onopen。這個 script 是當 libskype_bt_hijacker.so 攔截到 skype 開啟 dsp 裝置時,用來通知藍芽無線耳機麥克風用的。原作者是播放一段鈴聲提醒他,不過也可以改成 "killall -USR1 btsco" 送 SIGUSR1 給 btsco,則 btsco 會送預設的鈴聲指令給藍芽無線耳機麥克風。但是需要注意的是,實際測試結果,送 SIGUSR1 的方法在單獨測試時都正常運作,但是搭配 skype_bt_hijacker_onopen 時,很容易失敗。原因代查。如果想像原作者一樣播放一段鈴聲,則把原 script 中 aplay 播放的檔案位置改為你要的位置即可。

  5. 修改 skype_bt_hijacker_on* script 的權限:

    $ chmod 700 skype_bt_hijacker_on*


  6. 把這些 script 和 wrapper,以及一個 btsco 設定檔放到適當的位置。我的作法是把這些都一起放在 $HOME/btsco,然後在適當的位置建立 symbolic link。
    $ mv btscorunner libskype_bt_hijacker.so skype_bt_hijacker skype_bt_hijacker_on* skype_pickup.py btscorc ~/btsco/
    $ cd ~/bin
    $ ln -s ../btsco/{btscorunner,skype_bt_hijacker,skype_pickup.py} .
    $ ln -s ../btsco/skype_bt_hijacker_on* .
    $ cd ..
    $ ln -s btsco/btscorc .btscorc




安 裝到此為止。不過在使用之前,要先確定 dbus-python RPM 有裝起來,因為 skypc_pickup.py 使用 dbus 的功能來呼叫 skype API,控制 skype 的接聽與掛斷動作。而第一次使用時,skype 會警告有程式使用 API 控制 skype,問使用者是否允許該操作,必須要回答允許才行。

使用的方法很簡單,先執行 btscorunner 啟動 btsco,如果沒有錯誤的話,使用 skype_bt_hijacker 程式啟動 skype。理論上如果都正確的話,可以使用 headset 的 handfree profile 功能來控制接通和切斷,這就是透過 ~/.btscorc 裡面的設定達成的,當 btsco 偵測到 ~/.btscorc 內設定的 pattern 時,會執行 pattern 下一列指定的 action,而 skype-bt-hijacker 提供的 btscorc 就是設定當使用者按下 headset 上的按鈕時,執行 skype_pickup.py 來控制 skype。這代表 skype_pickup.py 和其他相關 script 都必須放在 $PATH 所及的地方,skype 的啟動指令也是,這也是為何我會在 ~/bin 裡面建立相關的 symbolic link 的緣故。

實測結果,在我的感覺是堪用,但是音質不是很好。音質不好的原因目前 還不確定。此外,這種啟動程序其實還不是很方便,現階段來說,可能還需要寫一些 helper script 來讓整個啟動過程更順暢才行。而且由於目前 btsco 是直接透過 ALSA 的 plugin 和 ALSA 溝通,因此如果在有使用 GNOME/KDE 等桌面整合環境下使用 btsco 時,如果 esd 等 audio server 正在使用 /dev/dsp 等 PCM 裝置的話,可能會發生錯誤。
繼續閱讀全文