Linux 上實際做法可以參考這篇 : https://blog.gtwang.org/iot/raspberry-pi-dvb-usb-tv-stick/
但2017的現在, 我發現 scan 只能掃到 5690000 那個頻道 (公視3, 客家, 原民), 看了一下 tw-all 那個檔案, 裏面只有 569000 用 QAM_64, 其它用 QAM_16, 鑑於公視HD是最早的HD台, 我猜, 這 tw-all 太舊了, 把所有的頻率都改成 QAM_64 就都抓到了
....連帶, 我正在寫的 EPG 程式也自動 OK 了, 原來都是這個 QAM 惹的視
channels.conf : (有+號的是雙語, 好像有些軟體不接受+號 )
中視:533000000:INVERSION_AUTO:BANDWIDTH_6_MHZ:FEC_2_3:FEC_AUTO:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:1001:1002+1003:100
中視新聞台:533000000:INVERSION_AUTO:BANDWIDTH_6_MHZ:FEC_2_3:FEC_AUTO:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:1011:1012:101
中視經典台:533000000:INVERSION_AUTO:BANDWIDTH_6_MHZ:FEC_2_3:FEC_AUTO:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:1021:1022:102
BRAVO經典台:533000000:INVERSION_AUTO:BANDWIDTH_6_MHZ:FEC_2_3:FEC_AUTO:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:1031:1032:103
公視:545000000:INVERSION_AUTO:BANDWIDTH_6_MHZ:FEC_2_3:FEC_2_3:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:2011:2012+2013:201
公視2台:545000000:INVERSION_AUTO:BANDWIDTH_6_MHZ:FEC_2_3:FEC_2_3:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:2021:2022+2023:202
民視:557000000:INVERSION_AUTO:BANDWIDTH_6_MHZ:FEC_2_3:FEC_AUTO:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:3001:3002+3003:300
交通電視台:557000000:INVERSION_AUTO:BANDWIDTH_6_MHZ:FEC_2_3:FEC_AUTO:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:3011:3012:301
民視新聞台:557000000:INVERSION_AUTO:BANDWIDTH_6_MHZ:FEC_2_3:FEC_AUTO:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:3021:3022:302
民視台灣台:557000000:INVERSION_AUTO:BANDWIDTH_6_MHZ:FEC_2_3:FEC_AUTO:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:3041:3042:304
台視:581000000:INVERSION_AUTO:BANDWIDTH_6_MHZ:FEC_2_3:FEC_AUTO:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:4001:4002+4003:400
台視新聞台:581000000:INVERSION_AUTO:BANDWIDTH_6_MHZ:FEC_2_3:FEC_AUTO:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:4011:4012:401
台視財經台:581000000:INVERSION_AUTO:BANDWIDTH_6_MHZ:FEC_2_3:FEC_AUTO:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:4021:4022:402
台視綜合台:581000000:INVERSION_AUTO:BANDWIDTH_6_MHZ:FEC_2_3:FEC_AUTO:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:4031:4032:403
華視:593000000:INVERSION_AUTO:BANDWIDTH_6_MHZ:FEC_2_3:FEC_2_3:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:5011:5012+5013:501
教育文化台:593000000:INVERSION_AUTO:BANDWIDTH_6_MHZ:FEC_2_3:FEC_2_3:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:5021:5022:502
華視新聞台:593000000:INVERSION_AUTO:BANDWIDTH_6_MHZ:FEC_2_3:FEC_2_3:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:5031:5032:503
國會頻道:593000000:INVERSION_AUTO:BANDWIDTH_6_MHZ:FEC_2_3:FEC_2_3:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:5041:5042:504
2017年7月3日 星期一
2017年6月24日 星期六
Ubuntu 16.04 64bit install
已經安裝過 32bit 的, 本來以為很快才對, 不過還是有些問題
1. Static IP
社區網路的天兵工程師當初因為不會設定 Ubuntu, 乾脆直接鎖 Mac address, 好在當時我立刻抗議, 他給了我另一個 IP -> 其實我只付一個 IP 的錢, 結果我有了兩個 IP 可用
但現在換主機板, 也就是換了網卡, 所以其中那個鎖 Mac address 不能用了, 得用目前 RPI3 佔用的那個 IP
But, 平平是 Ubuntu Mate, 怎麼 IP 設定的方法和 RPI3 不同呢? 頭痛~~
最後居然是最簡單的 UI 版 Networkmanager 就可以了
2017/07/04 補記 : 發現原來 Mac address 可以改的 !
/etc/network/interfaces:
auto enp0xxx
iface enp0xxx inet dhcp
hwaddress ether xx:xx:xx:xx
2. HiChannel -> 想了好一會想才起來 : 要裝 flash-plugin
3. gcin 因為光碟安裝時沒有網路, 所以語言包沒裝好, 裝了 gcin 之後一直無法中文輸入, 後來是去地區/語言選項時, 才發現裝了語言包之後, 一切就好了
4. dconf-editor
不喜歡的行為要改掉 : 1. automount-open 2. side-by-side tiling(?)
5. chrome (for Line app)要求的keyring 要設空白, 不然每次都要輸入 (夠白痴的)
6. 啟動應用程式移除 blueman-serive, 不然明明沒有藍芽, 還要show個 icon
7. 用 QT5 寫的 vbook 不能用了, 得重 compile
-> 安裝 QT5.5, qmake, make
8. pcmanx 要裝 ttf-mscorefonts 才有慣用字型
9. 電視遙控器不能用! python decode 的程式改了半天才能用, 但接收力比舊機器弱很多 -> 為什麼呢 ?
10. 新發現一個 command : acpi_listen 可以監測耳麥插拔, 因為本來懷疑原價屋小哥接錯了~~
11. crontab 裏 mplayer 需要 > /dev/null 2>&1
12. virtualbox 裏裝 additional 才有 sharefolder 可用
apt install virtualbox-guest-utils
加 user 進 vboxfs group (/etc/group)
1. Static IP
社區網路的天兵工程師當初因為不會設定 Ubuntu, 乾脆直接鎖 Mac address, 好在當時我立刻抗議, 他給了我另一個 IP -> 其實我只付一個 IP 的錢, 結果我有了兩個 IP 可用
但現在換主機板, 也就是換了網卡, 所以其中那個鎖 Mac address 不能用了, 得用目前 RPI3 佔用的那個 IP
But, 平平是 Ubuntu Mate, 怎麼 IP 設定的方法和 RPI3 不同呢? 頭痛~~
最後居然是最簡單的 UI 版 Networkmanager 就可以了
2017/07/04 補記 : 發現原來 Mac address 可以改的 !
/etc/network/interfaces:
auto enp0xxx
iface enp0xxx inet dhcp
hwaddress ether xx:xx:xx:xx
2. HiChannel -> 想了好一會想才起來 : 要裝 flash-plugin
3. gcin 因為光碟安裝時沒有網路, 所以語言包沒裝好, 裝了 gcin 之後一直無法中文輸入, 後來是去地區/語言選項時, 才發現裝了語言包之後, 一切就好了
4. dconf-editor
不喜歡的行為要改掉 : 1. automount-open 2. side-by-side tiling(?)
5. chrome (for Line app)要求的keyring 要設空白, 不然每次都要輸入 (夠白痴的)
6. 啟動應用程式移除 blueman-serive, 不然明明沒有藍芽, 還要show個 icon
7. 用 QT5 寫的 vbook 不能用了, 得重 compile
-> 安裝 QT5.5, qmake, make
8. pcmanx 要裝 ttf-mscorefonts 才有慣用字型
9. 電視遙控器不能用! python decode 的程式改了半天才能用, 但接收力比舊機器弱很多 -> 為什麼呢 ?
10. 新發現一個 command : acpi_listen 可以監測耳麥插拔, 因為本來懷疑原價屋小哥接錯了~~
11. crontab 裏 mplayer 需要 > /dev/null 2>&1
12. virtualbox 裏裝 additional 才有 sharefolder 可用
apt install virtualbox-guest-utils
加 user 進 vboxfs group (/etc/group)
買新電腦啦
全都是為了 Android Studio! 2.3.3 在 32bit 上可以 install, 可以執行, 但有一堆奇怪的 error message
而那台老舊的 CP5141, 雖然號稱可以裝 64bit, 但 Ubuntu 16.04 64bit 光碟總是跑到一半就 Hang, 本想加個RAM 就好, 但, 一時腦熱....
花了近七千在原價屋裝了台不含硬碟的新電腦, G4600 + H110M ECO, 第一次用微星的主機板呢, 沒辦法, 有 D-SUB + HDMI 的主機板, 最便宜就它了
在 pc_shopping 上 G4600 評價很好, H110M ECO 也有人稱讚, 雖然 pc_shopping 讀起來老覺得有人在帶風向, 不過找了外國的文章, 也還都不錯
尤其在 Amazon 上有一則說 H110M ECO is great for Linux !
和 CP5141 相比, 這台機殼還是太高, 要躺下來放, 然後和 CPU 風扇看起來很兩光, 是 G4600 附的? CP5141 的 ASUS 風扇看起來強壯些
拿回來裝硬碟時, 怎麼看都會被 RAM 擋住, 心裏詛咒了原價屋 N 次後, 才發現, 原來機殼有個和光碟機一樣的擋板可拆, 要從外面插進來才對...., 原來是我太蠢, 原價屋的小哥好冤
稍微看了一下影片, 感覺有點改善, 不過, 舊機器其實也夠用了, 就是愛亂花錢啊, 寫什麼 Android app 呢
而那台老舊的 CP5141, 雖然號稱可以裝 64bit, 但 Ubuntu 16.04 64bit 光碟總是跑到一半就 Hang, 本想加個RAM 就好, 但, 一時腦熱....
花了近七千在原價屋裝了台不含硬碟的新電腦, G4600 + H110M ECO, 第一次用微星的主機板呢, 沒辦法, 有 D-SUB + HDMI 的主機板, 最便宜就它了
在 pc_shopping 上 G4600 評價很好, H110M ECO 也有人稱讚, 雖然 pc_shopping 讀起來老覺得有人在帶風向, 不過找了外國的文章, 也還都不錯
尤其在 Amazon 上有一則說 H110M ECO is great for Linux !
和 CP5141 相比, 這台機殼還是太高, 要躺下來放, 然後和 CPU 風扇看起來很兩光, 是 G4600 附的? CP5141 的 ASUS 風扇看起來強壯些
拿回來裝硬碟時, 怎麼看都會被 RAM 擋住, 心裏詛咒了原價屋 N 次後, 才發現, 原來機殼有個和光碟機一樣的擋板可拆, 要從外面插進來才對...., 原來是我太蠢, 原價屋的小哥好冤
稍微看了一下影片, 感覺有點改善, 不過, 舊機器其實也夠用了, 就是愛亂花錢啊, 寫什麼 Android app 呢
2016年11月15日 星期二
RPI3's lirc
refer to : http://ozzmaker.com/how-to-control-the-gpio-on-a-raspberry-pi-with-an-ir-remote/
hardward : 1838B 接 GPIO, 3.3V, GND, PIN18
Software :
1. sudo apt-get install lirc liblircclient-dev
2. 在 /etc/modules 裏加兩行
lirc_dev
lirc_rpi gpio_in_pin=18
hardward : 1838B 接 GPIO, 3.3V, GND, PIN18
Software :
1. sudo apt-get install lirc liblircclient-dev
2. 在 /etc/modules 裏加兩行
lirc_dev
lirc_rpi gpio_in_pin=18
3. 改 /etc/lirc/hardware.conf
DEVICE="/dev/lirc0"
MODULES="lirc_rpi"
4. reboot, 理論上應該 lircd 會自動起來, 但並沒有
5. 用mode2 測試硬體
sudo /etc/init.d/lirc stop ( 沒有這個也無妨, 因為 service 沒設好? )
mode2 -d /dev/lirc0
6. irrecord --disable-namespace -d /dev/lirc0 lircd.conf
錄試遙控器的 key, 要加 --disable-namespace 才能隨便給名字
錄好後 copy 到 /etc/lirc/lircd.conf
7. 手動起 lircd -d /dev/lirc0
這是試出來的, 沒有手動起這個 irw 會說 connect fail,
而沒有用 -d 指定 /dev/lirc0 的話, irw 沒反應
8. 用 irw 試, 它會印 lircd.conf 出按鍵的名字
9. 原文的程式會去讀 /root/lircrc 或 /etc/lirc/lirc/lircrc
可以在 readconfig 那裏改 path, 但之後的 irexe 不知怎麼指定 path,
所以還是建了 /etc/lirc/lirc/lircrc
那程式只是做了和 irw 類似的事
10. 設定 lircrc
begin
button = power
prog = irexec
repeat = 1
config = /home/pi/autoplay/starttv1.sh
end
起 irexe, 它就會依遙控器的 button, 去執行 config 那行
2016年7月8日 星期五
簡單自製雲端家電
家附近的全國電子一直在播那個什麼"涼de等"的廣告, 每次去買菜都要被轟一次, 煩得很, 不過因為最近閒閒在家玩 DIY, 所以忍不住會想: 這自己做應該不難吧?
一個很簡單的設想: 1. 在外面寄e-mail回家 2.家裏的PC收到e-mail後照著信件標題的指示送個遙控訊號給冷氣機.
好像很簡單.
所以, 首先要在電腦裏存著各個家電的遙控訊號, 然後能發送它!
還是依照 mobile01 這篇文 http://www.mobile01.com/topicdetail.php?f=383&t=2845603
做出來的, 但是, 我的方法簡單多了
所需硬體 :
0. 電腦一台 (有耳機孔和麥克風孔即可, 老舊電腦應該都夠用)
1. 沒在用的音源線一條
2. 小吃店帶回來的塑膠繩一條 ( 不然縫衣線應該也可以)
3. 紅外線接收器1838B 38Khz 一顆 ( 10~30 元)
4. 5mm紅外線發射管 940nm LED 兩顆 (不到 10 元, 聽說 5mm 比 3mm 夠力, 只是聽說 )

做法 :
1. 把 音源線剪半, 剝成這樣 (紅白皮要剝掉一些, 冒出芯, 才能和 LED 連接)

2. 接收器 : 接收器外側兩支腳分別連上上圖的紅白線, 中間那支腳連上那條裸線
發射器 : 取發射器的一支長腳和另一個的短腳連上紅線, 白線就連另外的長短腳. (注意:兩顆LED 要盡量肩并肩平行)
從塑膠繩上撕下幾條細絲綁好, 成品長這樣 :

3. 接收器插上電腦的麥克風接頭, 發射器插進耳機孔, 硬體部份就完成了
軟體部份我寫了一支小程式 , 可以把收錄音訊直接轉為發射器可用的 wav 檔, 所以不需要像 mobile01 上那篇動用到 Audacity, 程式在此, 是個文字檔
https://gist.github.com/xvwang/5b441d1f9360b8ec067a24a04bbc904c
但要執行這個小程式需要安裝 python2.7, pyaudio 和 numpy
python2.7 下載頁 : https://www.python.org/downloads/release/python-2712/
後兩個最簡單的安裝方法是先裝 python package installer, 方法可以參考這篇 :
http://coopermaa2nd.blogspot.tw/2012/12/easyinstall-pip.html
有了pip 之後, 用 pip install pyaudio numpy 就 OK 了
軟體都裝好後, 執行
python recordSendIRWav.py
它會要你輸入按鍵名稱, 輸入一個名字按一個搖控器的鍵, (主要應該是開關鍵吧), 最好用英文, 因為我的程式沒用中文測過. 最後按 q 離開
注意, 我這程式會一直等到有錄到訊號為止, 如果按了搖控器, 它一直不出現再次要你輸入按鍵名稱的提示行, 那, 可能你的接收器失敗了....
之後會得到一堆 wav 檔, 用任一個播放器音量開到最大由耳機放播出來, 看看看被遙控的電器有沒有反應.
這裏有幾點要注意.
1. 音量先調到最大試試, 我在這點上被打敗了近一個月
2. 耳機孔的功率不大, 所以這個發射器的有效距離很有限, 我是接上音源延長線到處試, 最後決定我這個發射器的有效距離是 50~70cm (各電器不同)
3. 我在 Linux 用 mpv 可以指定由耳機孔播放, 但在 Window 上我就不知道該怎麼辦, 只好把外接喇叭 disable 掉, 才試成功的
4. 可能可以用手機播來試試, 因為手機上也有耳機孔, 但我的 Xperia J 行不通, 我看到有網友說他家三支手機只有一支可以用, 而且有效距離還只有 20 cm
5. 所以, 如果你要遙控的電器比較遠, 要嘛像我用音源延長線, 要嘛試著製作使用電池的發射器 : http://swf.com.tw/?p=359 (有空我也會試, 成功的話再來 update)
最後就簡單了, 我寫了個小程式, 每十分鐘去檢查一下e-mail, 只要標題合規格的, 就播放一下相對的 wav.
例如 :
1. 執行 python sendIRThroughEmail.py keyword_of_today
2. 送 email 到信箱裏, 標題為 "keyword_of_today cooler_power" 開/關冷氣
注意 :
1. 這支程式裏要改成你自己的 mail-server, mail-id 和 password
2. 我用 mpv 指定由耳機播放, 在 window 上可以用 wmplayer (PATH 要設好), 但不知怎麼從耳機播...
mpv --audio-device=help 可以列出所以可用的播放硬體
3. wav 檔記得要放在執行目錄之下
sendIRThroughEmail.py 在這裏 :
https://gist.github.com/xvwang/f9e57b324085d7a3293a193e67b11643
一個很簡單的設想: 1. 在外面寄e-mail回家 2.家裏的PC收到e-mail後照著信件標題的指示送個遙控訊號給冷氣機.
好像很簡單.
所以, 首先要在電腦裏存著各個家電的遙控訊號, 然後能發送它!
還是依照 mobile01 這篇文 http://www.mobile01.com/topicdetail.php?f=383&t=2845603
做出來的, 但是, 我的方法簡單多了
所需硬體 :
0. 電腦一台 (有耳機孔和麥克風孔即可, 老舊電腦應該都夠用)
1. 沒在用的音源線一條
2. 小吃店帶回來的塑膠繩一條 ( 不然縫衣線應該也可以)
3. 紅外線接收器1838B 38Khz 一顆 ( 10~30 元)
4. 5mm紅外線發射管 940nm LED 兩顆 (不到 10 元, 聽說 5mm 比 3mm 夠力, 只是聽說 )

做法 :
1. 把 音源線剪半, 剝成這樣 (紅白皮要剝掉一些, 冒出芯, 才能和 LED 連接)

2. 接收器 : 接收器外側兩支腳分別連上上圖的紅白線, 中間那支腳連上那條裸線
發射器 : 取發射器的一支長腳和另一個的短腳連上紅線, 白線就連另外的長短腳. (注意:兩顆LED 要盡量肩并肩平行)
從塑膠繩上撕下幾條細絲綁好, 成品長這樣 :

3. 接收器插上電腦的麥克風接頭, 發射器插進耳機孔, 硬體部份就完成了
軟體部份我寫了一支小程式 , 可以把收錄音訊直接轉為發射器可用的 wav 檔, 所以不需要像 mobile01 上那篇動用到 Audacity, 程式在此, 是個文字檔
https://gist.github.com/xvwang/5b441d1f9360b8ec067a24a04bbc904c
但要執行這個小程式需要安裝 python2.7, pyaudio 和 numpy
python2.7 下載頁 : https://www.python.org/downloads/release/python-2712/
後兩個最簡單的安裝方法是先裝 python package installer, 方法可以參考這篇 :
http://coopermaa2nd.blogspot.tw/2012/12/easyinstall-pip.html
有了pip 之後, 用 pip install pyaudio numpy 就 OK 了
軟體都裝好後, 執行
python recordSendIRWav.py
它會要你輸入按鍵名稱, 輸入一個名字按一個搖控器的鍵, (主要應該是開關鍵吧), 最好用英文, 因為我的程式沒用中文測過. 最後按 q 離開
注意, 我這程式會一直等到有錄到訊號為止, 如果按了搖控器, 它一直不出現再次要你輸入按鍵名稱的提示行, 那, 可能你的接收器失敗了....
之後會得到一堆 wav 檔, 用任一個播放器音量開到最大由耳機放播出來, 看看看被遙控的電器有沒有反應.
這裏有幾點要注意.
1. 音量先調到最大試試, 我在這點上被打敗了近一個月
2. 耳機孔的功率不大, 所以這個發射器的有效距離很有限, 我是接上音源延長線到處試, 最後決定我這個發射器的有效距離是 50~70cm (各電器不同)
3. 我在 Linux 用 mpv 可以指定由耳機孔播放, 但在 Window 上我就不知道該怎麼辦, 只好把外接喇叭 disable 掉, 才試成功的
4. 可能可以用手機播來試試, 因為手機上也有耳機孔, 但我的 Xperia J 行不通, 我看到有網友說他家三支手機只有一支可以用, 而且有效距離還只有 20 cm
5. 所以, 如果你要遙控的電器比較遠, 要嘛像我用音源延長線, 要嘛試著製作使用電池的發射器 : http://swf.com.tw/?p=359 (有空我也會試, 成功的話再來 update)
最後就簡單了, 我寫了個小程式, 每十分鐘去檢查一下e-mail, 只要標題合規格的, 就播放一下相對的 wav.
例如 :
1. 執行 python sendIRThroughEmail.py keyword_of_today
2. 送 email 到信箱裏, 標題為 "keyword_of_today cooler_power" 開/關冷氣
注意 :
1. 這支程式裏要改成你自己的 mail-server, mail-id 和 password
2. 我用 mpv 指定由耳機播放, 在 window 上可以用 wmplayer (PATH 要設好), 但不知怎麼從耳機播...
mpv --audio-device=help 可以列出所以可用的播放硬體
3. wav 檔記得要放在執行目錄之下
sendIRThroughEmail.py 在這裏 :
https://gist.github.com/xvwang/f9e57b324085d7a3293a193e67b11643
2016年6月28日 星期二
遙控電腦的 python code
========= homeirctl.py =============================
from ctypes import *
from array import array
from struct import pack
import pyaudio
import codeset
import subprocess
import signal, sys
THRESHOLD = 2000
CHUNK_SIZE = 1024
FORMAT = pyaudio.paInt16
RATE = 38000
ERROR_HANDLER_FUNC = CFUNCTYPE(None, c_char_p, c_int, c_char_p, c_int, c_char_p)
def py_error_handler(filename, line, function, err, fmt):
pass
def record():
"""
Record a word or words from the microphone and
return the data as an array of signed shorts.
"""
p = pyaudio.PyAudio()
stream = p.open(format=FORMAT, channels=2, rate=RATE,
input=True, output=True,
frames_per_buffer=CHUNK_SIZE)
num_silent = 0
rcv_started = False
r = array('h')
while 1:
rcv_data = array('h', stream.read(CHUNK_SIZE))
rcv_data = [ (x>THRESHOLD) for x in rcv_data ]
silent = (sum(rcv_data) < 10 )
if silent and rcv_started:
num_silent += 1
elif not silent and not rcv_started:
rcv_started = True
if rcv_started :
r.extend(rcv_data)
if rcv_started and num_silent > 2:
break
stream.stop_stream()
stream.close()
p.terminate()
return r
def to_bit(data) :
sumData = []
pN = 0
nN = 0
started = False
for j in data :
if j :
pN = pN + 1
if pN > 10 :
started = True
if nN < -10 :
sumData.append(nN)
nN = 0
elif started :
nN = nN - 1
if pN > 10 :
sumData.append(pN)
pN = 0
if pN > 10 :
sumData.append(pN)
if started and (nN < -10) :
sumData.append(nN)
result = ''
started = False
it = iter(sumData)
for x1 in it :
try:
x = x1 + next(it)
except:
break
if x1>120 :
result = ''
elif x < -300 or len(result)>50:
break
elif x < -90:
result = result + '1'
else:
result = result + '0'
return result
def sigterm_handler(_signo, _stack_frame):
sys.exit(0)
def main() :
while True:
data = record()
signal = to_bit(data)
try:
buttonName = codeset.TVCODE[signal]
print(buttonName)
except:
print(signal,'key not found')
else:
if buttonName is 'red' :
subprocess.call("/home/viola/autoplay/starttv.sh", shell=True)
elif buttonName is 'green' :
subprocess.call("/home/viola/autoplay/starttvnews2.sh", shell=True)
elif buttonName is 'yellow' :
subprocess.call("/home/viola/autoplay/starttvnews3.sh", shell=True)
elif buttonName is 'blue' :
subprocess.call("/home/viola/autoplay/starttvnews1.sh", shell=True)
elif buttonName is 'stop' :
subprocess.call("/home/viola/autoplay/stopall.sh", shell=True)
subprocess.call('xrandr --output VGA1 --mode 1440x900 --output HDMI1 --off', shell=True)
elif buttonName is 'option' :
subprocess.call("/home/viola/autoplay/startmusic.sh", shell=True)
elif buttonName is 'soundtrack' :
subprocess.call('xdotool search --name " - mpv" key s', shell=True)
elif buttonName is 'soundpattern' :
subprocess.call('xdotool search --name " - mpv" key A', shell=True)
elif buttonName is 'speedup' :
subprocess.call('xdotool search --name " - mpv" key Right', shell=True)
elif buttonName is 'speeddown' :
subprocess.call('xdotool search --name " - mpv" key Left', shell=True)
elif buttonName is 'pauseplay' :
subprocess.call('xdotool search --name " - mpv" key space', shell=True)
elif buttonName is 'stepf' :
subprocess.call('xdotool search --name " - mpv" key n', shell=True)
elif buttonName is 'stepb' :
subprocess.call('xdotool search --name " - mpv" key b', shell=True)
elif buttonName is 'vup' :
subprocess.call('xdotool search --name "playing music" key bracketright', shell=True)
elif buttonName is 'vdown' :
subprocess.call('xdotool search --name "playing music" key bracketleft', shell=True)
elif buttonName is 'cursorU' :
subprocess.call('xdotool search --name "playing music" key N', shell=True)
elif buttonName is 'cursorD' :
subprocess.call('xdotool search --name "playing music" key B', shell=True)
elif buttonName is 'cursorL' :
subprocess.call('xdotool key XF86AudioLowerVolume', shell=True)
elif buttonName is 'cursorR' :
subprocess.call('xdotool key XF86AudioRaiseVolume', shell=True)
elif buttonName is 'mute' :
subprocess.call('xdotool key XF86AudioMute', shell=True)
elif buttonName is 'epg' :
subprocess.call('chromium-browser --app="http://hichannel.hinet.net/radio/mobile/index.do?id=205#"', shell=True)
elif buttonName is '3D' :
subprocess.call("/home/viola/autoplay/startplaying.sh", shell=True)
elif buttonName is 'information' :
subprocess.call('xdotool search --name " - mpv" key t', shell=True)
elif len(buttonName)==1 :
subprocess.call('xdotool search --name " - mpv" key '+buttonName, shell=True)
if __name__ == '__main__':
signal.signal(signal.SIGTERM, sigterm_handler)
signal.signal(signal.SIGINT, sigterm_handler)
c_error_handler = ERROR_HANDLER_FUNC(py_error_handler)
asound = cdll.LoadLibrary('libasound.so')
asound.snd_lib_error_set_handler(c_error_handler)
main()
========== codeset.py ====================
TVCODE = {
'111111110001000000001110':'red',
'111111011101000000100010':'green',
'111111000111000000111000':'yellow',
'111111100111000000011000':'blue',
'111111111010000000000101':'pauseplay',
'111111101110000000010001':'speedup',
'111111010110000000101001':'speeddown',
'111111100011000000011100':'stop',
'101101110010010100001101':'stepf',
'101101010010010100101101':'stepb',
'111111010010000000101101':'option',
'111111011000000000100111':'vup',
'111111111000000000000111':'vdown',
'111111100000000000011111':'power',
'111111000110000000111001':'soundtrack',
'111111100110000000011001':'soundpattern',
'111111101000000000010111':'mute',
'111111110000000000001111':'information',
'111111010111000000101000':'epg',
'111111011001000000100110':'return',
'111111100101000000011010':'OK',
'101101101110010100010001':'3D',
'111111101101000000010010':'cursorR',
'111111001101000000110010':'cursorL',
'111111110101000000001010':'cursorU',
'111111010101000000101010':'cursorD',
'111111000100000000111011':'1',
'111111100100000000011011':'2',
'111111100100000000011011':'3',
'111111010100000000101011':'4',
'111111000100000000111011':'1',
'111111100100000000011011':'2',
'111111010100000000101011':'3',
'111111110100000000001011':'4',
'111111001100000000110011':'5',
'111111101100000000010011':'6',
'111111011100000000100011':'7',
'111111111100000000000011':'8',
'111111000010000000111101':'9',
'111111100010000000011101':'0' }
============= recordWavToFile.py =====================
import pyaudio
import wave
import numpy
from array import array
FORMAT = pyaudio.paInt16
CHANNELS = 2
RATE = 38000
CHUNK = 1024
RECORD_SECONDS = 2
WAVE_OUTPUT_FILENAME = "file.wav"
audio = pyaudio.PyAudio()
# start Recording
stream = audio.open(format=FORMAT, channels=CHANNELS,
rate=RATE, input=True,
frames_per_buffer=CHUNK)
print "recording..."
frames = []
for i in range(0, int(RATE / CHUNK * RECORD_SECONDS)):
data = stream.read(CHUNK)
frames.append(data)
print "finished recording"
# stop Recording
stream.stop_stream()
stream.close()
audio.terminate()
waveFile = wave.open(WAVE_OUTPUT_FILENAME, 'wb')
waveFile.setnchannels(CHANNELS)
waveFile.setsampwidth(audio.get_sample_size(FORMAT))
waveFile.setframerate(RATE)
waveFile.writeframes(b''.join(frames))
waveFile.close()
================ drawWavPlot.py ====================
from scipy.io import wavfile
from matplotlib import pyplot as plt
import numpy as np
# Load the data and calculate the time of each sample
samplerate, data = wavfile.read('file.wav')
print data
times = np.arange(len(data))/float(samplerate)
# Make the plot
# You can tweak the figsize (width, height) in inches
plt.figure(figsize=(20, 4))
plt.fill_between(times, data[:,0], data[:,1])
plt.xlim(times[0], times[-1])
plt.xlabel('time (s)')
plt.ylabel('amplitude')
#You can set the format by changing the extension
#like .pdf, .svg, .eps
plt.savefig('plot.png', dpi=100)
plt.show()
from ctypes import *
from array import array
from struct import pack
import pyaudio
import codeset
import subprocess
import signal, sys
THRESHOLD = 2000
CHUNK_SIZE = 1024
FORMAT = pyaudio.paInt16
RATE = 38000
ERROR_HANDLER_FUNC = CFUNCTYPE(None, c_char_p, c_int, c_char_p, c_int, c_char_p)
def py_error_handler(filename, line, function, err, fmt):
pass
def record():
"""
Record a word or words from the microphone and
return the data as an array of signed shorts.
"""
p = pyaudio.PyAudio()
stream = p.open(format=FORMAT, channels=2, rate=RATE,
input=True, output=True,
frames_per_buffer=CHUNK_SIZE)
num_silent = 0
rcv_started = False
r = array('h')
while 1:
rcv_data = array('h', stream.read(CHUNK_SIZE))
rcv_data = [ (x>THRESHOLD) for x in rcv_data ]
silent = (sum(rcv_data) < 10 )
if silent and rcv_started:
num_silent += 1
elif not silent and not rcv_started:
rcv_started = True
if rcv_started :
r.extend(rcv_data)
if rcv_started and num_silent > 2:
break
stream.stop_stream()
stream.close()
p.terminate()
return r
def to_bit(data) :
sumData = []
pN = 0
nN = 0
started = False
for j in data :
if j :
pN = pN + 1
if pN > 10 :
started = True
if nN < -10 :
sumData.append(nN)
nN = 0
elif started :
nN = nN - 1
if pN > 10 :
sumData.append(pN)
pN = 0
if pN > 10 :
sumData.append(pN)
if started and (nN < -10) :
sumData.append(nN)
result = ''
started = False
it = iter(sumData)
for x1 in it :
try:
x = x1 + next(it)
except:
break
if x1>120 :
result = ''
elif x < -300 or len(result)>50:
break
elif x < -90:
result = result + '1'
else:
result = result + '0'
return result
def sigterm_handler(_signo, _stack_frame):
sys.exit(0)
def main() :
while True:
data = record()
signal = to_bit(data)
try:
buttonName = codeset.TVCODE[signal]
print(buttonName)
except:
print(signal,'key not found')
else:
if buttonName is 'red' :
subprocess.call("/home/viola/autoplay/starttv.sh", shell=True)
elif buttonName is 'green' :
subprocess.call("/home/viola/autoplay/starttvnews2.sh", shell=True)
elif buttonName is 'yellow' :
subprocess.call("/home/viola/autoplay/starttvnews3.sh", shell=True)
elif buttonName is 'blue' :
subprocess.call("/home/viola/autoplay/starttvnews1.sh", shell=True)
elif buttonName is 'stop' :
subprocess.call("/home/viola/autoplay/stopall.sh", shell=True)
subprocess.call('xrandr --output VGA1 --mode 1440x900 --output HDMI1 --off', shell=True)
elif buttonName is 'option' :
subprocess.call("/home/viola/autoplay/startmusic.sh", shell=True)
elif buttonName is 'soundtrack' :
subprocess.call('xdotool search --name " - mpv" key s', shell=True)
elif buttonName is 'soundpattern' :
subprocess.call('xdotool search --name " - mpv" key A', shell=True)
elif buttonName is 'speedup' :
subprocess.call('xdotool search --name " - mpv" key Right', shell=True)
elif buttonName is 'speeddown' :
subprocess.call('xdotool search --name " - mpv" key Left', shell=True)
elif buttonName is 'pauseplay' :
subprocess.call('xdotool search --name " - mpv" key space', shell=True)
elif buttonName is 'stepf' :
subprocess.call('xdotool search --name " - mpv" key n', shell=True)
elif buttonName is 'stepb' :
subprocess.call('xdotool search --name " - mpv" key b', shell=True)
elif buttonName is 'vup' :
subprocess.call('xdotool search --name "playing music" key bracketright', shell=True)
elif buttonName is 'vdown' :
subprocess.call('xdotool search --name "playing music" key bracketleft', shell=True)
elif buttonName is 'cursorU' :
subprocess.call('xdotool search --name "playing music" key N', shell=True)
elif buttonName is 'cursorD' :
subprocess.call('xdotool search --name "playing music" key B', shell=True)
elif buttonName is 'cursorL' :
subprocess.call('xdotool key XF86AudioLowerVolume', shell=True)
elif buttonName is 'cursorR' :
subprocess.call('xdotool key XF86AudioRaiseVolume', shell=True)
elif buttonName is 'mute' :
subprocess.call('xdotool key XF86AudioMute', shell=True)
elif buttonName is 'epg' :
subprocess.call('chromium-browser --app="http://hichannel.hinet.net/radio/mobile/index.do?id=205#"', shell=True)
elif buttonName is '3D' :
subprocess.call("/home/viola/autoplay/startplaying.sh", shell=True)
elif buttonName is 'information' :
subprocess.call('xdotool search --name " - mpv" key t', shell=True)
elif len(buttonName)==1 :
subprocess.call('xdotool search --name " - mpv" key '+buttonName, shell=True)
if __name__ == '__main__':
signal.signal(signal.SIGTERM, sigterm_handler)
signal.signal(signal.SIGINT, sigterm_handler)
c_error_handler = ERROR_HANDLER_FUNC(py_error_handler)
asound = cdll.LoadLibrary('libasound.so')
asound.snd_lib_error_set_handler(c_error_handler)
main()
========== codeset.py ====================
TVCODE = {
'111111110001000000001110':'red',
'111111011101000000100010':'green',
'111111000111000000111000':'yellow',
'111111100111000000011000':'blue',
'111111111010000000000101':'pauseplay',
'111111101110000000010001':'speedup',
'111111010110000000101001':'speeddown',
'111111100011000000011100':'stop',
'101101110010010100001101':'stepf',
'101101010010010100101101':'stepb',
'111111010010000000101101':'option',
'111111011000000000100111':'vup',
'111111111000000000000111':'vdown',
'111111100000000000011111':'power',
'111111000110000000111001':'soundtrack',
'111111100110000000011001':'soundpattern',
'111111101000000000010111':'mute',
'111111110000000000001111':'information',
'111111010111000000101000':'epg',
'111111011001000000100110':'return',
'111111100101000000011010':'OK',
'101101101110010100010001':'3D',
'111111101101000000010010':'cursorR',
'111111001101000000110010':'cursorL',
'111111110101000000001010':'cursorU',
'111111010101000000101010':'cursorD',
'111111000100000000111011':'1',
'111111100100000000011011':'2',
'111111100100000000011011':'3',
'111111010100000000101011':'4',
'111111000100000000111011':'1',
'111111100100000000011011':'2',
'111111010100000000101011':'3',
'111111110100000000001011':'4',
'111111001100000000110011':'5',
'111111101100000000010011':'6',
'111111011100000000100011':'7',
'111111111100000000000011':'8',
'111111000010000000111101':'9',
'111111100010000000011101':'0' }
============= recordWavToFile.py =====================
import pyaudio
import wave
import numpy
from array import array
FORMAT = pyaudio.paInt16
CHANNELS = 2
RATE = 38000
CHUNK = 1024
RECORD_SECONDS = 2
WAVE_OUTPUT_FILENAME = "file.wav"
audio = pyaudio.PyAudio()
# start Recording
stream = audio.open(format=FORMAT, channels=CHANNELS,
rate=RATE, input=True,
frames_per_buffer=CHUNK)
print "recording..."
frames = []
for i in range(0, int(RATE / CHUNK * RECORD_SECONDS)):
data = stream.read(CHUNK)
frames.append(data)
print "finished recording"
# stop Recording
stream.stop_stream()
stream.close()
audio.terminate()
waveFile = wave.open(WAVE_OUTPUT_FILENAME, 'wb')
waveFile.setnchannels(CHANNELS)
waveFile.setsampwidth(audio.get_sample_size(FORMAT))
waveFile.setframerate(RATE)
waveFile.writeframes(b''.join(frames))
waveFile.close()
================ drawWavPlot.py ====================
from scipy.io import wavfile
from matplotlib import pyplot as plt
import numpy as np
# Load the data and calculate the time of each sample
samplerate, data = wavfile.read('file.wav')
print data
times = np.arange(len(data))/float(samplerate)
# Make the plot
# You can tweak the figsize (width, height) in inches
plt.figure(figsize=(20, 4))
plt.fill_between(times, data[:,0], data[:,1])
plt.xlim(times[0], times[-1])
plt.xlabel('time (s)')
plt.ylabel('amplitude')
#You can set the format by changing the extension
#like .pdf, .svg, .eps
plt.savefig('plot.png', dpi=100)
plt.show()
訂閱:
文章 (Atom)