怒濤の新製品ラッシュ、皆さんもさぞかし興奮したことだろうと思います。ええ、買いますとも、新iPad。職業柄、先代・先々代とどう書き分けるかの表記ルールが気になりますが、まずは製品を入手しなければ。もちろん購入次第ご報告させていただきます!
さて、今回は「say」コマンドについて。OS Xのスピーチシンセサイザーを利用し、テキストを人間の話し言葉に変換するというこのコマンド、活用の場面は限られるにせよ、Terminalにおいて屈指の"遊べる"存在であることは確か。ついにリリースされたiOSの「日本語版Siri」を横目で睨みつつ、sayコマンドならではの活用方法を紹介しよう。
Siri日本語版の声は彼女……なのか?
sayコマンドは、OS XのスピーチAPI(CocoaフレームワークのNSSpeechSynthesizeクラス)のCUIフロントエンドとでも表現すべき存在。引数に文字列またはテキストファイルを与えて実行すると、その内容を解釈し、設定された言語に応じた言葉を出力する。いわゆる「Text To Speech」の機能を提供するコマンドなのだ。
出力される音声には、システム環境設定「スピーチ」ペインの「テキスト読み上げ」タブで設定したものが使用される。その情報はプロパティリスト(~/Library/Preferences/com.apple.speech.voice.prefs.plist)に記録され、sayコマンドもこれを参照する。日本語音声は「Kyoko」一種類なので、いちど設定してしまえば変更することは少ないだろう。
実はこの声(以下「Kyokoさん」)、Siri日本語版が発する声によく似ている。というより、同じ言葉をsayコマンドでKyokoさんに発音させてみると、イントネーションといい声質といい、Siri日本語版にそっくりだ。今後OS XにもSiriが搭載されるとは考えにくいが、技術やリソースがiOSと共有可能だとすると、sayコマンドも将来的にはより自然な読み上げができるよう進化していくのかもしれない。
Rubyのコードを対話形式で実行できる「irb」を使い、直接NSSpeechSynthesizeクラスにアクセスしたところ。日本語音声(Kyoko)を選択していれば、女性の声で「こんにちは」と発音される |
意外なところでKyokoさん大活躍
せっかくのsayコマンド、ただ文章を読み上げさせるだけでは惜しい。クラウドの力を借りたSiriには及ばないとしても、もっと実用的であるべきなのだ。この主張には、Kyokoさんも同調してくれることだろう、たぶん。
そこで注目したのが、sayコマンドは「標準入力経由でデータを受け取れる」ということ。つまり、他のコマンドが出力した文字列をsayコマンドに引き渡し、読み上げさせるのだ。なんだそんなことかと言うなかれ、これがなかなか便利に使える。なかでも気に入っている使用例を、2つほど紹介してみよう。
いま何時?
Lionに収録のdateコマンドは国際化(i18n)されているため、LANG環境変数に日本語環境用の適切な値(ja_JP.UTF-8)が設定されていれば、日本の流儀に沿った日付や時刻情報を返してくれる。たとえば、Terminalで「date +%X」と実行すると、「16時33分01秒」などと表示されるはずだ。
Kyokoさんに現在時刻を話してもらうには、このdateコマンドとsayコマンドを組み合わせればいい。実行例は以下のとおり。これをエイリアスにでも登録しておけば、いつでもKyokoさんが現在時刻を教えてくれるというわけだ。
$ date +%X | say
しかし、これでは秒単位まで読み上げられるので具合が悪い。Kyokoさんは女性なのだから、語尾に「です」くらいあってもいい。その意を反映させたものが以下のコマンド実行例で、「17時53分です」などと答えてくれるはずだ。
$ date +%H"時"%M"分です" | say
SiriにはできないがKyokoさんならバッチリ
感心するほど賢いSiri日本語版だが、こんなこともできないの? ということがある。ひょっとすると、筆者の話し方に問題があるのかもしれないが、かんたんな四則演算ができないのだ。「四足す四は?」と聞いてもダメ、もちろん九九も全問不正解、というよりこちらの問いの趣旨をまったく理解してくれない。
我らがKyokoさんは、そんなことどうということもない。こなれない書き方で恐縮だが、処理の流れがひと目でわかるよう1行に書くと以下のとおり。最初に「何を計算する?」とKyokoさんにたずねられるので、「9*9」などと数式を入力すると、bcコマンドで計算した結果をKyokoさんが読み上げてくれる、という寸法だ。とても単純だが、Kyokoさんに秘められた無限(?)の可能性を感じていただければ、と思う。
$ say "何を計算する?" ; read STR ; NUM="`echo $STR | bc`です" ; say $NUM