raspberry piの音周り
ラズベリーパイにしゃべらせたりairplayサーバーにしたりして遊んでいたメモを放出。
モデルはRaspberrry pi type B 512MB。
イヤホンジャック/HDMIから出力
参考: http://elinux.org/R-Pi_Troubleshooting#Sound
$ amixer cset numid=3
n はヘッドフォン端子が1、HDMIでは2、0で自動判別
テスト
$ aplay /usr/share/sounds/alsa/Noise.wav
ボリューム調節
$ amixer set PCM 20%
USBスピーカー
USB経由での方が音がよいという噂なので
サンワサプライ USBスピーカー ブラック MM-SPU6BK
- 出版社/メーカー: サンワサプライ
- 発売日: 2012/05/01
- メディア: Personal Computers
- この商品を含むブログを見る
電力を食うのか、繋いだ瞬間にraspberry piが落ちる。電源付きのUSBハブ越しでも落ちる。wifiのドングルはハブ越しなら平気だったのに…。
ハブにつないだまま起動すれば問題はない。それだけで認識はする(alsamixerコマンドで選択出来るようになっていた気がする)が、
$ sudo vi /etc/modprobe.d/alsa-base.conf
で
options snd-usb-audio index=-2
の行をコメントアウトして再起動するとデフォルトのサウンドデバイスになる。
音質はヘッドフォン端子から出すよりはよい、がまあそれなり、という感じ。ゲインを0にするとよくなるという噂を見てやってみたら(要は上でvolumeを100% にする。本体にも物理的なボリュームがあるのでそっちで調節)少しよくなった気がする?
あと1ヶ月くらい使ってるうちに音質悪くなくなってきた気がする(耳が慣れただけだ)。さすがにiphoneよりは良い音がする。
ゆっくり
ゆっくりの名で有名な AquasTalk のラズベリーパイ版。商用だが、個人・非営利利用ならライセンス料はかからない。http://www.a-quest.com/products/aquestalkpi.html からいただいたパッケージをどこかに解凍するだけ。解凍したディレクトリに行って
$ ./AquesTalkPi ゆっくりしていってね | aplay
とするとしゃべる。英単語もある程度読める。
オープンソースの OpenJTalk というのも試したのだが、商用だけあってこっちの方が読み上げが自然だし動作も軽快。
このままだとなんかエラーが発生したとき aplay に変なデータが流れ込んでザーッと言う音になって耳障りなので、シェルスクリプトを作った。
atalk:
#!/bin/bash aquestalkpi=/home/pi/build/aquestalkpi/AquesTalkPi var=`$aquestalkpi "$@" | base64; echo ":${PIPESTATUS[0]}"` ret=(${var##*:}) data=${var%:*} if [ $ret -eq 0 ]; then echo $data | base64 --decode --ignore-garbage | aplay -q else echo $data | base64 --decode --ignore-garbage exit $ret fi
というのを作って実行権限を付けてパスの通ったところに置いて、
$ atalk -g 15 ほげ
とする。オプションはもともとのAquesTalkと同じで、例えば上の -g は音量(100が最大)。なんも指定しないで走らせるともとの AquesTalkPi のヘルプを表示するのでそれを参照。
$ atalk NAME AquesTalkPi - Raspberry Pi用テキスト音声合成コマンド Ver.1.00 SYNOPSIS AquesTalkPi [-h] [-s speed] [-g volume] [-b] [-v f1|f2] [-k] [-t] [-o out.wav] [-f file | string] DESCRIPTION 日本語のテキスト音声合成を行います。 標準出力にWAV形式の音声データを出力します。 OPTIONS string 発声する文字列を指定します(UTF-8)。漢字も読めます。 音声記号列での指定も可能です(-k オプション) 音声記号列の詳細は、AquesTalk音声記号列仕様を参照。 スペース等を含む場合は ""で囲んで指定してください。 -f file 発声する文字列をファイルで指定するときに指定します。 先頭行だけしか処理しません。 stringを指定せず、且つ fileに - を指定したときは、 標準入力からの入力になります(pipe使用可能)。 -o file WAVファイルとして出力するときにファイル名を指定します。 指定しないときは標準出力に出力されます。 -t WAV形式音声データの代わりに音声記号列を出力します。 言語処理の結果を返します。 -k 発声する文字列が音声記号列の場合に指定します。 -v f1 | f2 声種を指定します。 f1:女声1(default) f2:女声2 -b 棒読み(アクセントが平板)になります。 -g volume 音量を指定します。 (0-100) default:100 -s speed 発話速度を指定します。 (50-300) default:100 -h このメッセージを表示します。 EXAMPLE $ ./AquesTalkPi 漢字も読めます。 | aplay $ echo ゆっくりしていってね? | ./AquesTalkPi -b -f - | aplay $ ./AquesTalkPi -s 150 -v f2 -k -o out.wav "ファイルニ、シュツ'リョクシマ_ス。" *実行時にはAquesTalkPiと同じディレクトリに付属の/aq_dic以下が必要です。 LICENCE, etc. 商用利用、再配布には別途ライセンス契約(有償)が必要です。 ライセンス、その他につきましては、下記サイトを参照ください。 http://www.a-quest.com/products/aquestalkpi.html ---- COPYRIGHT 2013 AQUEST Corp. ----
AirPlay
参考: http://www.lifehacker.jp/2013/03/130306raspberry_piairplay.html
sudo apt-get install git libao-dev libssl-dev libcrypt-openssl-rsa-perl libio-socket-inet6-perl libwww-perl avahi-utils libmodule-build-perl git clone https://github.com/njh/perl-net-sdp.git cd perl-net-sdp perl Build.PL sudo ./Build sudo ./Build test sudo ./Build install cd .. git clone https://github.com/hendrikw82/shairport.git cd shairport make # ./shairport.pl -a AirPi sudo make install sudo cp shairport.init.sample /etc/init.d/shairport sudo chmod 755 /etc/init.d/shairport sudo update-rc.d shairport defaults sudo vi /etc/init.d/shairport #DAEMON_ARGS="-w $PIDFILE" #DAEMON_ARGS="-w $PIDFILE -a AirPi" sudo service start shairport
で、同じネットワークのiphoneとかから AirPi という名前で見えるようになるはず。
youtube
$ sudo apt-get install mplayer youtube-dl $ sudo apt-get install rtmpdump swftools libxml2-utils $ mplayer $(youtube-dl -g www.youtube.com/watch?v=Y6ljFaKRTrI)
NHKラジオ
第1
$ mplayer -playlist http://mfile.akamai.com/129931/live/reflector:46032.asx
時報・天気予報をしゃべらせる
応用としてcrontabに入れて定時でしゃべるようにしてみる。
時報
上で作った atalk が ~/bin 以下に置いてあれば
0 */1 * * * /home/pi/bin/atalk -g 15 `date +\%-H`'時だよ'
としておくと毎時時報をしゃべる。crontabだと % をバックスラッシュでエスケープしなければいけないらしいのでそこは注意。
天気予報
コード参考(というかほぼそのまま):
- http://nwpct1.hatenablog.com/entry/2013/10/18/175913
- http://www.programming-magic.com/20080820002254/
pythonでtenki.jpから天気予報の情報を読んで、atalkでしゃべらせられるようなテキストにする。
tenki:
#!/usr/bin/env python #coding: utf-8 import urllib2 import re import socket import htmlentitydefs def unescape_html_entity(text): reference_regex = re.compile(u'&(#x?[0-9a-f]+|[a-z]+);', re.IGNORECASE) num16_regex = re.compile(u'#x\d+', re.IGNORECASE) num10_regex = re.compile(u'#\d+', re.IGNORECASE) result = '' i = 0 while True: match = reference_regex.search(text, i) if match is None: result += text[i:] break result += text[i:match.start()] i = match.end() name = match.group(1) if name in htmlentitydefs.name2codepoint.keys(): result += unichr(htmlentitydefs.name2codepoint[name]) elif num16_regex.match(name): result += unichr(int(u'0'+name[1:], 16)) elif num10_regex.match(name): result += unichr(int(name[1:])) return result def tenki(url): socket.setdefaulttimeout(10.0) # 正規表現のパターンを定義 - タグ消し remove_tag = re.compile(r'<.*?>') try: htmldata = urllib2.urlopen(url) except urllib2.HTTPError as err: print('HTTPError') print(err) except urllib2.URLError as err: print('URLError') print(err) if isinstance(err.reason, socket.timeout): print('timeout') else: # print('Get HTML') pass content = htmldata.read() htmldata.close() content_list = content.split('\n') flag = False result = '' for line in content_list: if flag==True and not "</div>" in line: #正規表現でタグ消しした後にstripメソッドでスペースを除去。後ろに,をつけると改行しない result += remove_tag.sub("", line).strip() #print line #filewrite(line) if flag==True and "</div>" in line: result += remove_tag.sub("", line).strip() #print line #filewrite(line) flag = False elif "weatherCountryDescriptionBody" in line: result += remove_tag.sub("", line).strip() #print line #filewrite(line) flag = True print unescape_html_entity(result.decode('utf-8')).encode('utf-8') # print result if __name__ == "__main__": url = "http://tenki.jp/forecast/pref-14.html" tenki(url)
上は埼玉県の天気を出力するが、一番下のurlを変えたら他の県もいけるはず。
実行権限をつけて ~/bin において、
$ tenki
で埼玉県の天気がテキストで出力されるのを確認する。
そしたらcrontabに
30 8 * * * /home/pi/bin/atalk -g 15 '天気予報です、'`/home/pi/bin/tenki`
と書いておくと毎朝8時半に天気予報をしゃべってくれる。