BCCのお勉強したら、Windowsも喋ったよ。うひょ。
昨日は、月に2回の、グルーミングデーだった。ここ数十年は床屋へ行っていない。女房が、バリカンで 高校球児宜しく、3分の丸坊主にしてくれる。
床屋へ行く面倒さも無いし、手入れが簡単なので至極気に入っている。最初は、丸坊主に女房が 難色を示し、グラディーションを付けたGI風カットと言うか、職人風だったんだけど、そのうちに、 女房が、折れて、数年前からは、丸坊主。
ピョンと数本特異的に延びた、眉毛を切って貰って、女房の担当分は終了。残りの、鼻毛、爪きり、 耳掃除は、セルフサービスだ。
鹿児島の女性を女房にすると、靴下を履かせてくれたと友人が言っていたけど、もしうちの 女房が鹿児島女子だったら、グルーミングをセットでやってくれるんだろうか?
猫でも分かるプログラミング
先日、Windows用のfree版喋るdll をちょっと試してみた。その時は、VC++でのサンプルが 付属してたので、諦めてたのだ。けれども、ちょっと出来心が出て。
うちのWindows機には、BCCが入っていたのだ。ひょっとして、これならdllだって使えちゃう んでないかいと、素人っぽく思った訳だ。確かそのBCCは、 猫でも分かるプログラミングの BCCでプログラムを作ろうを参考に 練習した覚えがある。
で、カミングアウトしちゃうと、途中で挫折してしまい、それっきりになっていたのだ。こういう おいらは、猫以下って事になる。さあ、リベンジ成るか? 見ておかなければならないのは、第11章 dllを作る かな。
dll と連携させる
AquesTalkのサンプルから、AquesTalkDa.h AquesTalkDa.lib を引っ張ってきた。プロジェクト dir(今回は、sndとした)へ入れてあげる。また、Debug-buildするので、Debug-dirの中には AquesTalkDa.dllを入れておく。
こんな環境の中で、簡単なcppファイルを作った。(例題をコピーして、ちと変更)
c:\borland\work\snd>cat HelloTalk.cpp #include <stdio.h> #include <stdlib.h> #include "AquesTalkDa.h" main(){ return AquesTalkDa_PlaySync("こんにちわ。"); }
こんにちわ。と喋って欲しいのだ。喋るんじゃなくて、ファイルに落とすには、サンプルの 例題そのままで、いいのかな。
猫でもに習って、プロジェクトメニューのプロジェクト設定から、リンクのタブを選び、 AquesTalkDa.lib を追加しておく。 これが、dllを使うための、おまじないらしい。
コンパイルしてみると
> C:\borland\bcc55\Bin\make.exe -fDebug\snd.mak -B TARGET MAKE Version 5.2 Copyright (c) 1987, 2000 Borland bcc32 -WC -5 -Od -w -AT -pc -H- -k -b -v -y -DDEBUG -nDebug -c C:\borland\work\snd\HelloTalk.cpp Borland C++ 5.5.1 for Win32 Copyright (c) 1993, 2000 Borland c:\borland\work\snd\hellotalk.cpp: bcc32 -WC -5 -Od -w -AT -pc -H- -k -b -v -y -DDEBUG -eDebug\snd.exe Debug\HelloTalk.obj C:\borland\work\snd\AquesTalkDa.lib Borland C++ 5.5.1 for Win32 Copyright (c) 1993, 2000 Borland Turbo Incremental Link 5.00 Copyright (c) 1997, 2000 Borland Error: 'C:\BORLAND\WORK\SND\AQUESTALKDA.LIB' contains invalid OMF record, type 0x21 (possibly COFF) ** error 1 ** deleting Debug\snd.exe Build End !! (Elapsed time 0:01.833)
見事に失敗してる。でも、良く見ると、サンプルから持ってきた、AQUESTALKDA.LIB が、BCCの リンカーのお気に召さなかったようだ。後ちょっとなので、先生に聞いてみた。
解決編
dllを元にして、BCCのリンカーに馴染むようにlibを作成するツールがあるそうな。
c:\borland\work\snd>ls -l *lib *dll -rw- 110592 2006-10-12 12:05 AquesTalkDa.dll -rw- 3230 2006-10-12 12:05 AquesTalkDa.lib c:\borland\work\snd>implib AquesTalkDa.lib AquesTalkDa.dll Borland Implib Version 3.0.22 Copyright (c) 1991, 2000 Inprise Corporation c:\borland\work\snd>ls -l *lib *dll -rw- 110592 2006-10-12 12:05 AquesTalkDa.dll -rw- 1536 2009-07-12 20:15 AquesTalkDa.lib
こうしておいてから、再コンパイルしてみると
> C:\borland\bcc55\Bin\make.exe -fDebug\snd.mak -B TARGET MAKE Version 5.2 Copyright (c) 1987, 2000 Borland bcc32 -WC -5 -Od -w -AT -pc -H- -k -b -v -y -DDEBUG -nDebug -c C:\borland\work\snd\HelloTalk.cpp Borland C++ 5.5.1 for Win32 Copyright (c) 1993, 2000 Borland c:\borland\work\snd\hellotalk.cpp: bcc32 -WC -5 -Od -w -AT -pc -H- -k -b -v -y -DDEBUG -eDebug\snd.exe Debug\HelloTalk.obj C:\borland\work\snd\AquesTalkDa.lib Borland C++ 5.5.1 for Win32 Copyright (c) 1993, 2000 Borland Turbo Incremental Link 5.00 Copyright (c) 1997, 2000 Borland Build End !! (Elapsed time 0:02.484)
コンパイルでけた。しゃべったよ。 参考までに、Makefileが、Debugの中にあったので、掲載
c:\borland\work\snd\Debug>cat snd.mak #------------------------------------------------------- # BCC Developer 1.2.21 # Copyright (C) 2003 jun_miura@.........jp #------------------------------------------------------- .autodepend CC=bcc32 RC=brc32 CFLAG=-WC -5 -Od -w -AT -pc -H- -k -b -v -y -DDEBUG OUTDIR=-nDebug CINCS= TARGET=Debug\snd.exe SRC1=C:\borland\work\snd\HelloTalk.cpp OBJ1=Debug\HelloTalk.obj LIB1=C:\borland\work\snd\AquesTalkDa.lib TARGET: $(TARGET) $(TARGET): $(OBJ1) $(CC) $(CFLAG) -e$(TARGET) $(OBJ1) $(LIB1) $(OBJ1): $(SRC1) $(CC) $(CFLAG) $(OUTDIR) $(CINCS) -c $(SRC1)
BCCなかなかやるじゃん。後は、このサンプルをいじっていけばいいんだな。 どういじる。その前に、も一つ難題が。そう、Windows用のkakasiがあるかだ。
探してみたよ。Windnows-kakasi この近辺をうろうろ してたら、kakasi を使ってるアプリケーションとして、 yomi が、しっかりリストアップ されてた。
Windows版喋るの設計
さあ、材料は揃った。全体をコントロールするのは、rubyにしておく。 rubyだとkakasiを便利に使うモジュールがあるようだ。喋るプログラムへの インターフェースはどうしよう?
パイプで渡しちゃうのが簡単そうだけど、Windowsの偽パイプは途中で 詰まったりしないかな。次の選択子は、引数渡しだけど、環境エリアの サイズと、0x5C問題は無いかが心配。ああ、ほとんどがひらがなだから 大丈夫?
一番無難なのは、ファイル渡しか。rubyだと temp-fileが使えるから 落ちても、ゴミファイルが残る事は少なそう。でも、1行毎にファイルを 作成して、使って(喋り終わったら)削除の繰り返しじゃ、HDDへの負担 大きそう。まてよ、Windowsは、遅延書き込みなんてサポートしてるかな?
これにて、検討終わり。後は、得意のカット&トライの出番です。
まてまて、喋るプログラムの制限で、発声通りに変換してあげないと てにをはを間違えた、外人みたいになっちゃうぞ。
「私は、小林です。」 --> "わたしわ、こばやしです。" に変換等。 先輩の yomi-lib.pl では、どうしてるのだろう。まてまて、そこまで思いを馳せる前に 幹の構築だな。
構築編
rubyから、kakasi を読んで、ひらがなを出すスクリプトを まず、unixで書いてみた。ちょっとWindowsでは動くかどうか分からない 危なっかしい事をやっちゃったけど、そのまま、Windowsへ持ってきたら 動いちゃったよ。
infile = ARGV.shift KAKASI = 'kakasi -JH -kH -KH -Ea -s -u -osjis' def say(s) fp = IO.popen(KAKASI, 'a+') fp.print s co = fp.readline puts co # debug print system("jsay #{co.gsub(/ /, '')}") # call speaker fp.close end def main(infile) puts 'このプログラムは、AquesTalk - テキスト音声合成を利用しています。' File.foreach(infile) do |al| say(al) end end main(infile)
上記で、ひらがなになったデータは、co に入っているから、そいつのスペースを削除した上で、 発声ソフトに渡してる。(単なる手抜きで、コマンドライン引数をパースするのが、面倒だった からと言う、脱力系です。)
そうそう、名前重要と言う事で、プログラムに名前を付けてあげないといけないな。 ひらがなを受け取って、発声するソフトは、taro でもいいんだけど、寿命が短そう なので、jsay としたよ。
読み上げ原稿を受け取って、全体をコントロールする(上記のラフスケッチ版)rubyスクリプト は、yomi に、インスパイアーされてるので、妹みたいなものだな。発音 と書いて、 hatune ちょっと長いかな?
この子、おっとりした子で、喋り出すまで、ちと間があるのが難点。後、数字とか アルファベットが途中にあると、貝になってしまいます。このあたりは、もう少し 教育が必要だな。でも、文の終わりを、尻上がりっぽく発音してくれるので、ちょっと かわゆい。
ああ、肝心の、jsayは、実装が変わって、下記のように(今の所)なっています。(世の中では、 これを称して、手抜き工事と言うらしい)
#include <stdio.h> #include <stdlib.h> #include "AquesTalkDa.h" main(int argc, char *argv[]){ if ( argc != 2){ printf("もう、hatune 何喋ったらいいか、わかんなーい。\n"); return 1; } return AquesTalkDa_PlaySync(argv[1]); }
使い方は、
c:\sakae\test-kakasi>ruby hatune.rb 原稿.txt このプログラムは、AquesTalk - テキスト音声合成を利用しています。 こんにちは , あつい よ . あめ が , ふら ないかなあ . きょう の ゆうしょく は なにか な .
今日を こんにち と言うのは、辞書を鍛えないとだめだな。それから、 ruby が、そのまま見えるのは、ちょっとカッコ悪いな。後で、batファイルに収納しちゃおう。
兄貴分の yomi について
前回、私のFreeBSD上で、うまく yomi が動かなかった件。作者様に連絡を取った所 至急に対応して頂きました。FreeBSD 7.X で動く版が公開されるはずですので そちらをお使い下さい。
至急の対応、ありがとうございました。