今 何時?
女房がアマゾンで時計を検索してた。実家の父の目が衰え、母に「今何時?」と、しょっちゅう 聞くものだから、時刻を声で教えてくれるのを探して、プレゼントしてあげようと思ったとの事。
で、見つけたのが、セイコーの電波時計 DA203S というやつ。別に電波時計でなくてもいいんだ けど、音声となると、これぐらいしか適当なものが無い。おいらが、アマゾンは嫌いじゃーと 言うと、だったら、東京へ行った時に買ってきてと下命されてしまった。
一応下調べしたら、アキバ価格で5140円だったよ。でも、ふらっと、昼の買出しに出た時に ホームセンターに立ち寄ったら、4980円で売ってた。アキバが安いとは限らないのね。
しゃべる時計
一応電波時計と言うので、nict.jpのお世話になります。毎00分に校正が行われ、ntpdで 同期を取っているパソコンと同じ時刻を表示しましたよ。
ボタンを押すと、「10時20分33秒です」なんて言う。ボタンを2回クリックすると「7月7日火曜日です」 なんて具合に教えてくれる。歳老いた父に、2回クリックが出来るかどうかは、ちょっと疑問 だけど、まあ、当初の目的は達成されました。
パソコンは喋るか?
5000円の時計が喋るなら、それよりも10倍は高価なパソコンがおしゃべりするのだろうか? と、ふと疑問が出てきた。
この時、頭をかすめたのは、ビューティフルコードに emacspeak というソフトを開発した方 が載っていたよなぁ。紐解いてみました。emacs自身が発声してくれると誤解してたけど、 そうじゃ無かった。Tcl で書かれた発声エンジンとemacsが通信して、目の不自由な方が emacsを操れるようにしたものなのね。
ネットで、このTclで書かれたと言うエンジンを探してみたけど探しきれなかった。残念! でも、面白いのを見つけたよ。
Windowsには、発声エンジンと音声認識機能が搭載されているんですって。 それをrubyからCOMに乗せてコントロールしている方がおられた。 またもや、灯台元暗し だったなあ。
Let speak english
日本語版のWindowsXPのくせして、日本語を喋る人は入っていなかった。せめて、言語明瞭、意味 不明瞭、難しい漢字はルビが振ってないと読めないぐらいの能力がある taroちゃんぐらいは 入れておいて欲しかったぞ。 >M$
入って無いものはしょうがないので、元サンプルを少々整理して、時計にしてみました。
require 'win32ole' ap = WIN32OLE.new('SAPI.SpVoice') se = ap.GetVoices # Get speak engine en = nil (0 .. se.Count-1).each do |i| id = se.Item(i).Id if (id.match(/MSSam/)) # find english speaker en = se.Item(i) end end ap.Voice = en # Select voice ap.Rate = 1 # Slow speed ap.Speak(Time.now.to_s ,2) # 2:sync mode
実行すると、ちゃんと喋ってくれたよ。数字は棒読みだけどね。
もう少し流暢にならないかな?
昔、某国へ出張した時の事。pinkのlampが灯るパブに入りましたよ。横に付いたおねーさんが 何か飲んでいい? なんて、おねだりされました。この場合の何かって言うと、それ用の シャンパンと相場が決まっています。
で、いいよ、でも、一応値段を確認。彼女の言う事にゃ、フィフティーン。 店を出る時、フィフティーを請求されましたよ。それ以来、値段は、Write it down pls. って 言って、騙されないようになりました。
無駄話になっちゃったけど、今回は、数字を与えると、話言葉に翻訳して喋って欲しい訳だ。 すぐに思いつくのは、rubyにテーブルを用意する事。でも、そんなのつまんないな。 Common Lispに、面白い機能があったな。
[1]> (format t "~R" 1234567890) one billion, two hundred and thirty-four million, five hundred and sixty-seven thousand, eight hundred and ninety NIL
後は、これを使って、時刻を英語に直せばいいわけだ。
;; what time is it ? (defun main () (multiple-value-bind (second minute hour date month year day-of-weak daylight-p time-zone) (get-decoded-time) (format t "It's ~R ~R" hour minute))) (main)
c:\sakae>time 現在の時刻: 14:01:08.38 新しい時刻を入力してください: c:\sakae>clisp time.lisp It's fourteen one
後は、上記rubyスクリプト中の Time.now.to_s を、 `clisp time.lisp` に変更 すればOK。それにしても、Windows上のrubyで、バッククォート構文が使えるなんて 開発の方、いい仕事してますねぇ。