發表文章

關於藍牙裝置找尋(inquiry, scan)兩三事

圖片
當我們拿到手機或平板要和藍牙耳機配對時, 配對程式做的第一件事其實是找尋(scan, inquiry)的動作, 列出周遭附近的藍牙設備名稱或MAC位址, 以供使用者選擇要和那一台配對。在Linux平台上,我們可以透過bluez來做這件事,以C語言來寫,Albert Huang的書 [1] 給了我們一個簡單的範例程式 simplescan.c : #include .... int main(int argc, char **argv) { inquiry_info *ii = NULL; int max_rsp, num_rsp; int dev_id, sock, len, flags; int i; char addr[19] = { 0 }; char name[248] = { 0 }; dev_id = hci_get_route(NULL); sock = hci_open_dev( dev_id ); if (dev_id < 0 || sock < 0) { perror("opening socket"); exit(1); } len = 8; max_rsp = 255; flags = IREQ_CACHE_FLUSH; ii = (inquiry_info*)malloc(max_rsp * sizeof(inquiry_info)); num_rsp = hci_inquiry (dev_id, len, max_rsp, NULL, &ii, flags); if( num_rsp < 0 ) perror("hci_inquiry"); for (i = 0; i < num_rsp; i++) { ba2str(&(ii+i)->bdaddr, addr); memset(name, 0, sizeof(name)); if ( hci_read_remote_name (sock, &(ii+i)->...

python gtk+ glade and dbus work together

圖片
這篇的篇名下得有點奇怪,我也不知如何命名之,主要是想要表達整合這幾個技術: 用python語言 使用gtk+來做出圖形界面 利用glade工具來編排圖形界面的佈局,而不是用程式來寫 結合dbus來控制圖形界面 之前有看到python dbus的範例程式:參見 Python DBus教學精要 [1] 的 example-service.py 其程式主要架構為: class CLASSNAME(dbus.service.Object) @dbus.service.method("INTERFACE NAME") def METHOD_NAME(self): # do something here if __name__ == '__main__': # request dbus public name, instantiate object for dbus # gobject mainloop run 注意到我們必須建立GObject的事件處理迴圈,因為這是在寫DBus服務,而服務是不會跑完馬上停止的,而是必須一直在等待是否有客戶端的要求進來。 另外也看到可以用python配合glade來寫gtk+的圖形界面: 參見 Python Gtk glade開發GUI程式 [2] 。其中python的程式為: from gi.repository import Gtk class Handler : def onDeleteWindow ( self , * args ): Gtk . main_quit ( * args ) def onButtonPressed ( self , button ): print "Hello World!" builder = Gtk . Builder () builder . add_from_file ( "builder_example.glade" ) builder . connect_signals ( Handler ()) window = builder . get_object ( ...

A2DP學習筆記

圖片
其實在PC桌面Linux已經支援藍牙的A2DP協定,包括將音樂由電腦播至藍牙耳機,也包括反方向由手機或平板將音樂傳送至電腦。 在Ubuntu 12.10的桌面環境裡,操作很容易,只要先和耳機或手機(平板)配對後,一連線成功,在電腦的設定-音效畫面就會出現設備。藍牙耳機會出現在輸出的頁籤,而手機或平板會出現在輸入頁籤。如Fig.1及Fig.2。 如果配對連線後,音效設定畫面看不到藍牙設備,請檢查/etc/bluetooth/audio.conf檔[General]區段下是否有Disable=Headset,若有請移除。 Fig.1 Fig.2 這時,打開電腦的軟體播放器,開始播放音樂,我們可以在音效設定裡(如Fig.1)選擇要將音樂由那個輸出設備播出;選到内建音效,就會由電腦的喇叭發出韾音,選到藍牙耳機,就會在藍牙耳機聽到音樂了。 而要由電腦喇叭播放手機或平板的音樂,也只要直接在手機或平板播放,在iOS裝置中會看到可以選擇那一個AirPlay裝置的小圖示。確定是放送到電腦,則在音效設定(如Fig.2)的輸入頁籤,可以看到這個手機的圖示,只要選到這個圖示,可以看到輸入等級的指示圖在左右動作。這表示手機的音樂已經傳到電腦的錄音源了,此時可以打開錄音軟體,開始錄音,然後播放錄音的結果就可以聽到由手機傳來的音樂。這好像還是有點不方便,我們要的應該是直接由電腦的喇叭發出韾音。 Ivan_wl [1] 的文章下半部份就是在討讑這個問題的解法。摘要其解決方式有二個重點: 在/etc/bluetooth/audio.conf中[General]區段要加入Enable=Source 使用Blueman套件或pulseaudio將錄音源轉至電腦喇叭  Ivan_wl比較推薦使用Blueman,因為什縻設定都不用做,但是這様一來,你原來的藍牙管理工具要留著或移除,這有時是很討厭的決定。所以來看一下怎縻用pulseaudio: 簡單版: $ pactl load-module module-loopback 20 用以上指令的意思就是載入loopback模組,它會將錄音源轉送至輸出。所以你就可以聽到由手機透過藍牙走A2DP協定過來的音樂了。你會注意到這個指令有返回一個數字,在這裡的例子是20。當你想要關掉loopback模組的時候,你會用...

搞不清楚之ubuntu pulseaudio

圖片
先說了,我搞不清楚ubuntu的pulseaudio。 備忘一:如何暫時關掉pulseaudio? A: 網上有人問了也有人答了,見 how-to-temporarily-disable-pulseaudio 個人偏好第二個答案,就是去/etc/pulse/client.conf設定檔,將autospawn=yes改成no,記得前面;是備註的意思,要把它去掉。這樣當我們下指令: $ pulseaudio --kill 把pulseaudio關掉後,pulseaudio就不會再自己自動重新開啟了。 那如果我們想要打開pulseaudio,就下指令: $ pulseaudio --start 狀況一: 使用MAC機器架VirtualBox,裝ubuntu 10.04,暫時關掉pulseaudio,發現aplay還可以正常運作: $ aplay ~/音樂/01\ 慢火車.wav 正在播放 WAVE '/home/ops/音樂/01 慢火車.wav' : Signed 16 bit Little Endian, 速率 44100 Hz, 立體聲 $ aplay -Dhw:0,0 ~/音樂/01\ 慢火車.wav 正在播放 WAVE '/home/ops/音樂/01 慢火車.wav' : Signed 16 bit Little Endian, 速率 44100 Hz, 立體聲 $ aplay -L null     Discard all samples (playback) or generate zero samples (capture) default:CARD=I82801AAICH     Intel 82801AA-ICH, Intel 82801AA-ICH     Default Audio Device front:CARD=I82801AAICH,DEV=0     Intel 82801AA-ICH, Intel 82801AA-ICH     Front speakers surround40:CARD=I82801AAICH,DEV=0  ...

D-BUS學習筆記

圖片
我第一個看到的文章是 ali's Blog [1] , 其中提到二支程式server.c client.c,我試著去compile這二支程式, 沒什麼太大的問題就可以成功。因為這是所謂的dbus c api, 也就是low lever api,在ubuntu下只要安裝套件libdbus-1-dev, 就會安裝這個api: $ sudo apt-get install libdbus-1-dev 然後就如該文所提到的,在compile時,必須指定library: $ gcc server.c -o server -l dbus-1 此時再去compile程式,可能會發現找不到dbus.h的問題。其實檔案是存在的,只是gcc不知道去那裡找而已。我們只要加入-I/usr/include/dbus-1.0 -I/usr/lib/dbus-1.0/include 告訴gcc就可以了。 $ gcc -I/usr/include/dbus-1.0 -I/usr/lib/dbus-1.0/include -o server server.c -l dbus-1 如此,可以compile成功。但每次要打這麼多字,實在記不得,也容易打錯,所以使用Makefile吧! 建一個檔案,其名為Makefile,內容如下: All: server client server: server.c   gcc -I/usr/include/dbus-1.0 -I/usr/lib/dbus-1.0/include -o server server.c -l dbus-1 client: client.c   gcc -I/usr/include/dbus-1.0 -I/usr/lib/dbus-1.0/include -o client client.c -l dbus-1 我們把server.c client.c Makefile三個檔案,都放在同一個目錄,叫做dbus-test好了。這樣以後只要: $ cd dbus-test $ make 就會正確的編出server client二支可執行的程式。我們也不用去記這些很長的路徑名稱了。用過Makefile的朋友應該看得出來,其實Makefile可以再簡短一些。改成如下: ...