BCCのお勉強したら、Windowsも喋ったよ。(2)
8年間、連続出場してた、「笑っていいとも」のタモリさんが、今週から計画停止で休みを 取っている。鉄人かと思っていたら、普通の人だった訳で、お疲れ様。ゆっくり休んで、悪い 所を十分に修理してくださいと応援したくなる。
タモリさんも凄いと思うけど、普通の人だって十分すぎる程凄いぞ。人によっては、100年も ずっと、無故障、無停止で動いているポンプを持っているんだもの。しかも、そのポンプ、 一回のどきっで、40ccだかの血液を送り出す。脈拍が60/分 だとすると、2.4リットル/分 の送出能力だ。一日にどのくらいになるか、計算してみるといい。
しかも、自動制御されてて、外界の状況(びっくりしたとか)とか、自分の状況(運動してる、寝てるなど) に合わせて、緩急自在に能力が変わる。緩急はともかく、100年間、無停止のポンプなんて 今の工学で可能なんだろうか?
迷惑な飛行物体である「蚊」。あの小さな体のくせに、りっぱなセンサー(二酸化炭素)を 持っていて、的確に食物を探知する。素早い手の動きに対して、さっと、身をかわす。 こういうのって、今の工学で作れるか? 私の知る限りでは、nil だな。
タモリさんのお休みに合わせて、ふと、こんな事を思った次第。合わせて読みたい「象の時間、 ねずみの時間」という本は、もう、処分してしまった。また、蚊ってくるかな。
新鮮な体験
昨日は気分を変えて、隣町にあるショッピングモールまで遠征。丁度、昼だったので、何か 食べよう。そうだ、寿司にしようとなりました。回転寿司です。注文は、写真をタッチでOK。 ベルトコンベアーから、支線へちゃんと、お皿が運ばれてきて、びっくりしたよ。
タッチパネルと指令塔とはどう結ばれているか、思わず裏側を覗いてしまったぞ。LANケーブル でしたね。今度、あの寿司屋へは、wiresheak持参で行きたいぞ。
も一つ、新鮮体験で、併設されてたスーパーでの出来事。セルフ精算機でレジ打ちを 体験しました。
バーコードが付いてない商品は、写真を出してから、それをタッチ。続いて個数をタッチ。 これで、「アスパラ___きゅーじゅーはち_えん___です」なんて具合に声で応答が返ったきた。 これには、AquesTalk - テキスト音声合成ミドルウェア が、組み込まれているのだろうか?
ちょうど今、hatuneなんていう喋るソフト(Windows native版)を作っているので、興味深かったよ。 さて、もうちょっと、hatuneを教育して、利口にしてあげよう。なにせ、生まれたばかり の女の子ですから。
hatuneの構成
hatune を、分解してみます。 まずは、hatune.bat
@echo off ruby control.rb %1
前回書いた、hatune.rb は、ちょいと改名しました。無理してMVCを考えたら、controllerに なりますから。(って、matzさんの背広本の影響だったり、するのかな?)
control.rb とか、そこから呼ばれる、jsay.exe 等は、一式をPATHの通った所に入れて おきます。(たとえば、kakasi/bin の中とか -- 要control.rbのフルパス指定 -- 今は、hatuneの教育中なので、 保育園に入れてますが)その保育園の具合は
c:\sakae\test-kakasi>ls -l -rw- 110592 2006-10-12 12:05 AquesTalkDa.dll -rwx 1943 2009-07-15 10:58 control.rb* -rwx 33 2009-07-14 16:19 hatune.bat* -rwx 52224 2009-07-13 15:03 jsay.exe* -rw- 85 2009-07-15 11:47 test.txt
test.txt は、hatuneのテスト問題です。
hatune の脳
hatuneの心臓は、jsayになるのかな? MVC で言ったら、V か。Vって、本来は、Viewの意味 だけど、Voice で、この場合はうまく語呂が合う。こちらは、前回のままです。
hatuneは、あれから、少し教育をして、(和製の)アルファベットと数字と、少々の記号を 喋れるようになりました。
親の影響を受けて、'(' を、かっこ、')' を、こっか と喋るようになったのは、ご愛嬌と 言う事で許してください。そんじゃ、脳みそ公開。
# Speak out text-file, text-file must be sjis # Usage: ruby control.rb text-file (called by hatune.bat) infile = ARGV.shift KAKASI = 'kakasi -JH -kH -s -u -osjis' AH = { 'A' => 'えー', 'B' => 'びー', 'C' => 'しー', 'D' => 'でぃー', 'E' => 'いー', 'F' => 'えふ', 'G' => 'じー', 'H' => 'えっち', 'I' => 'あい', 'J' => 'じぇい', 'K' => 'けー', 'L' => 'える', 'M' => 'えむ', 'N' => 'えぬ', 'O' => 'おー', 'P' => 'ぴー', 'Q' => 'きゅー', 'R' => 'あーる', 'S' => 'えす', 'T' => 'てぃー', 'U' => 'ゆー', 'V' => 'ぶい', 'W' => 'だぶりゅー', 'X' => 'えっくす', 'Y' => 'わい', 'Z' => 'ぜっと', '0' => 'ぜろ', '1' => 'いち', '2' => 'にー', '3' => 'さん', '4' => 'よん', '5' => 'ご', '6' => 'ろく', '7' => 'なな', '8' => 'はち', '9' => 'きゅう', } KH = { '(' => 'かっこ', ')' => 'こっか', '-' => 'はいふん', '.' => 'どっと', '/' => 'すらしゅ', ':' => 'ころん', '@' => 'あっと', '+' => 'ぷらす', } def adj(co) co = co.gsub(/\t/s, '') # Delete No allow char co = co.gsub(/[\(\)\-\.\/\:¥@\+]/s){|k| KH[k] + ',' } # Kigo co = co.gsub(/[a-z]/s){|s| s.upcase} # lower to upcase co = co.gsub(/[0-9A-Z]/s){|s| AH[s] + ',' } # Num or Alpha to hatuon co.gsub(/ /, ',') # make short priod end def say(s) fp = IO.popen( KAKASI, 'a+' ) fp.print s co = fp.readline hi = adj(co) # Adj for AquerTalk printf(">>%s==%s~~%s\n", s, co, hi) # Debug print system("jsay #{hi}") fp.close end def main(infile) puts 'このプログラムは、AquesTalk - テキスト音声合成を利用しています。' File.foreach(infile) do |al| al += "\r\n" unless al =~ /\n/ # adj line end (at last line of file) next if al =~ /^[ \t ]*$/s # skip (hankaku|zenkaku) Space or TAB only line say(al) end end main(infile)
見ての通り、記号類は充実してません。知らない記号に出会うと、貝になってしまいます。 また、周りの空気を読んで、'-' を、マイナス なんて読む芸当も出来ません。後、ここには 現れていませんが、原稿に 'ぇ' なんて不純物が含まれていると、即、心臓停止か、悪く すると、マイクロソフトに密告しちゃう と言う、暴挙に出てしまいます。
使う場合は、全て自己責任でお願いします。私は、hatuneの生みの親ですが、子供が暴れて 損害が発生しても、その責任を取る事を放棄します。(大事な事ですから、もう一度言いますよ。 子供の責任は取りませんからね!)
なお、まだまだ、頭の悪い子ですから、いくら調教、もとえ、教育して頂いてもかまいません。 良い教育を施して自慢の子に育ったら、里帰りさせてください。親として、待ち望んでおります。
おっと、この地方の方言を教えるの忘れていました。'?' の発音は、"はてな", '!' は、"びっくり"って 言うんですからね。これを覚えておかないとダメよ、hatuneちゃん。
これだけ覚えさせれば、取り合えず、習わぬScheme教を読めるな。しめしめ。(これって、親のエゴ ですか。)
成果発表
それじゃ、型苦しい事は、置いておいて、ちょっと披露しますね。
c:\sakae\test-kakasi>hatune test.txt このプログラムは、AquesTalk - テキスト音声合成を利用しています。 >>今、午前11時46分28秒です。 ==いま 、 ごぜん 11 とき 46 ふん 28 びょう です 。 ~~いま,、,ごぜん,いち,いち,,とき,よん,ろく,,ふん,にー,はち,,びょう,です,。 >>2009年7月15日、水曜日です。 ==2009 ねん 7 がつ 15 にち 、 すいようび です 。 ~~にー,ぜろ,ぜろ,きゅう,,ねん,なな,,がつ,いち,ご,,にち,、,すいようび,です,。 >>もうすぐ、お昼になりますよ。 ==もうすぐ 、 お ひる になりますよ 。 ~~もうすぐ,、,お,ひる,になりますよ,。
脳にセンサーを埋め込んで、何を思っているかモニターしてます。(って、ブレインのあの人 みたい)
>>の行は、入力された原稿 ==の行は、kakasiをつかって、ひらがなに変換した結果 ~~の行は、jsayに与える、発音データ
となっています。変なひらがなになってしまうのは、取り合えず、kakasiの辞書充実をすれば 良いと思います。(kakasiから、データを取り出しているから、MVC になぞらえるとMになるか。 そう考えると、control.rb内にある AH,KHのテーブルもMですな。-- Mって言うと、あれ みたいで、想像しちゃうでしょうから、言葉使いは難しいなー。)
喋らなくなったりする場合は、AquesTalkの資料を見て、control.rb に、手 を入れてください。
TODO
control.rb では、数字の棒読みしか出来ません。充実した数字の発声をサポートして 下さった(更には、そのDLLを公開くださった) AquesTalk開発者の皆様に感謝すると共に、申し訳ない気持ちで一杯です。
ちゃんと数字を読み上げるには、control.rb 内で、数字の列を取り出し、それをTAGでくくって、 jsayに渡してあげる必要があります。それには、例えば
co.sub( /(-?d+)(.?d+)?/s, '<NUM VAL=\1\2>' )
等として、数字をTAG内に埋め込みます。 (この正規表現は、即興ですから、信用しないように!)
問題は、<NUM VAL=123> のような(<> と半角スペースを含む)ものが、今のjsayでは、 受理できないのです。(コマンド引数渡しのため)
こういうデータをjsayにきちんと届けるには、PIPEを使うか、ファイル 渡ししか、解決方法がありません。(おっと、姑息に、環境変数って、手もあるか) いずれにしろ、jsayのソースを変更するはめになります。
LLで育った私は、カジュアルな事が好きですので、仕事でも無い限り、そこまで踏み込んで 改造に走る事は無いでしょう。
腕に自信のある、心臓外科医な方がおられましたら是非。。
夏の祭典
さあ、そろそろ夏の祭典 RubyKaigi2009の準備をして おかねば。頑張って "LET OVER LAMBDA" をGetするぞ。あれ? 何か違うよ。 Rubyはmatzさんの信念で未来永劫マクロが無い、matzLisp。
本物のLisperは、CLなり Schemeを使えと。(Schemeも一部のLisperからは、、以下自粛) LoLは、その為の指南書と言う訳か。会場で買ったら、あの方のサインを頂けるのだろうか? このことが、petite気になっております。