写真 青い空と雲と建物と木々の緑

nishimotzの日記

  • 未踏オフ会

    古川亨さんの講演を聴きたかったので、天才プログラマーではない私も未踏オフ会に行ってきました。

    「自分が作ったものを使ってくれる人の喜んでいる顔が見たい」

    その思いが、いまの自分にとって、やっぱり大切である、ということを再認識しました。

    プログラマー定年説の35歳のときに未踏ソフトに応募して、運良く採択され、運悪くいろいろな障害に遭遇しましたが、自分の弱点や限界を認識できたし、自分の情熱も確認できました。

    あれから2年、やっぱりプログラミングが楽しくて、だからこの分野で仕事を続けているのだと思います。そのわりには微妙に職種を選び間違えた気もしますが。。

    人と出会うことの大切さや可能性も再認識しました。

    そろそろ私は自分がスーパークリエーターになるのではなく、若くて能力がある人をサポートをするための能力を身につけたい、と思います。かつてのアスキーでの古川氏のように。

    でも並行して、自分が楽しむためのプログラミング技術を持ち続けたい、そして最後まで「自分が作ったものを・・・」という夢を持ち続けたい、とも思っています。

  • NVDA + GalateaTalk

    昨日の日記の続きです。gtalk.pyは今日はこんな感じになってます。

    class SynthDriver(silence.SynthDriver):
    name = "gtalk"
    description = "galatea talk (experimental)"
    def initialize(self):
    os.chdir("c:\\work\\istc\\SSM\\gtalk")
    cmd = "gtalk -C ssm-win.conf"
    (self.cout, self.cin) = popen2.popen4( cmd )
    self.cin = codecs.getwriter('shift_jis')(self.cin)
    self.cin.write("prop Speak.text = NoAutoOutput\n")
    self.cin.write("prop Speak.pho = NoAutoOutput\n")
    self.cin.write("prop Speak.dur = NoAutoOutput\n")
    self.cin.write("prop Speak.stat = NoAutoOutput\n")
    self.cin.write("prop Speak.len = NoAutoOutput\n")
    self.cin.write("prop Speak.utt = NoAutoOutput\n")
    self.cin.write("set AutoPlay = YES\n")
    self.cin.flush()
    self.frame = SynthFrame()
    return True
    def speakText(self,text,wait=False,index=None):
    self.cin.write("set Text = " + text + "\n")
    self.cin.flush()
    if wait:
    s = "[speak wait]"
    else:
    s = "[speak]"
    self.frame.textCtrl.AppendText(s + text + "\n")
    def cancel(self):
    self.cin.write("set Speak = STOP\n")
    self.cin.flush()
    self.frame.textCtrl.AppendText("[cancel]\n")
    def terminate(self):
    self.cin.write("set Run = EXIT\n")
    self.cin.flush()
    if not self.frame:
    return
    self.frame.Close()
    self.frame.Destroy()
    self.frame = None
    def getVoiceName(self,num):
    return "gtalk voice"
    

    で、今度は5~6行くらいは読み上げるようになりました。カーソルで行を移動すると「音切れ」もちゃんと実現されています。ちょっと反応が遅く感じるのは GalateaTalk の処理時間の問題でしょう。

    数行読み上げるとやがて止まってしまうのは GalateaTalk のコンソール出力をちゃんと読み出ししていないから不安定なのかも知れません。

    そもそも cout の読み出しをどうやればいいのでしょう。別スレッドを回して non-blocking I/O でcoutを読み出して捨てる必要があるのですが、まだ Python に慣れていない私はそこでつまづいています。

    ところで GalateaTalk の README には

    各スロットは、プロパティとして AutoOutput か NoAutoOutput のどちらかの
    値をとり、それぞれ自動出力する、自動出力しないを表す。
    プロパティの値を変更するには、
    prop Text.text = NoAutoOutput
    prop Text.text = AutoOutput
    のように prop コマンドによって行なう。
    初期値としては、全て AutoOutput が設定されている。
    

    と書かれているのですが、サンプルのPerlスクリプト(RUN)は

    print OUT "prop Text.text = NoAutoOutput\n";
    print OUT "prop Text.pho = NoAutoOutput\n";
    print OUT "prop Text.dur = NoAutoOutput\n";
    

    になっています。これ Text.text ではなくて Speak.text じゃないでしょうか?

    今日はここまで。

  • Python + GalateaTalk

    NVDA というオープンソースのWindows用スクリーンリーダーで GalateaTalk が使えないか、という話があったので、調べてみました。

    最新の NVDA snapshots には NVDAJp の活動の成果が取り込まれています。

    まず、python で gtalk を実行してみます。下記を UTF-8 で保存して実行。

    # -*- coding: utf-8 -*-
    import popen2
    import os
    import codecs
    os.chdir("c:\\work\\istc\\SSM\\gtalk\\")
    cmd = "gtalk -C ssm-win.conf"
    (cout, cin) = popen2.popen4( cmd )
    cin = codecs.getwriter('shift_jis')(cin)
    text = u'こんにちは'
    cin.write("set Text = " + text + "\n")
    cin.write("set Speak = NOW\n")
    for line in cout.readlines():
    print line
    

    あちこちからパクったソースです。「こんにちは」と喋ってくれました。

    次は NVDA のドライバー実装です。

    NVDA/synthDrivers/display.py をコピーして gtalk.py を作り、

    class SynthDriver(silence.SynthDriver):
    name = "gtalk"
    description = "galatea talk (experimental)"
    

    にしてみたら、とりあえず NVDA 起動→ Ctrl-Shift-S で gtalk が選択可能に。

    def initialize(self):
    os.chdir("c:\\work\\istc\\SSM\\gtalk")
    cmd = "gtalk -C ssm-win.conf"
    (self.cout, self.cin) = popen2.popen4( cmd )
    self.cin = codecs.getwriter('shift_jis')(self.cin)
    text = u'子猫が隠れんぼをしています'
    self.cin.write("set Text = " + text + "\n")
    self.cin.write("set Speak = NOW\n")
    self.frame = SynthFrame()
    

    gtalk ドライバー選択時に「子猫が・・」と喋ってくれました。

    def speakText(self,text,wait=False,index=None):
    self.cin.write("set Text = " + text + "\n")
    self.cin.write("set Speak = NOW\n")
    self.frame.textCtrl.AppendText(text + "\n")
    

    お、最初の2行くらい喋った!!

    でも、すぐに音声合成がハングアップ。やっぱり「音切れ」の処理を実装しないとダメですね。

    続きは明日!!