linda-temperature-alertで温度をlinda-mac-sayに読み上げさせると数字21が“にい・いち”のようにひとつずつ読み上げられてしまい,“にじゅういちど”とかにならないのが悲しかった.
数字を漢数字にしてsaykanji記事(saykanjiコマンドを定義して漢字仮名混じり文を読み上げる - ザリガニが見ていた...。)のように'mecab -O yomi'すればいけるんじゃない?とか考えていろいろやりはじめた.その成果がこれ. 参考:漢数字に変換
n2k.rbでこれを
#! /usr/bin/env ruby -Ku # coding: utf-8 def num2kanji(val) kanji_str= ':一二三四五六七八九'.split('') keta_str = ':十百千'.split('') keta_str2= ':万億兆京垓'.split('') return '零' if (val==0) val= val.to_s.reverse.gsub(/(\d{4})/, "\\1,").sub(/,$/, "").split(/,/) i= 0; for val_item in val str= '' chars= val_item.split('') j= chars.length-1 for char_item in chars.reverse str+= kanji_str[char_item.to_i] + keta_str[j] j= j-1 end str = str.gsub(/:./,'') + keta_str2[i] str= '' if (str.split(//u).length==1) val[i] = str.gsub(/:/,''); val[i] = val[i].gsub(/一(百)|一(十)/, "\\1\\2"); i= i+1 end return val.reverse.join(''); end puts ARGV[0].gsub(/\d+/){ num2kanji($&.to_i) } if (ARGV[0] != nil)
ruby n2k.rb 現在の気温は23度です|mecab -O yomi|sayと読み出せばいいんじゃないか?と思った. ただこれだと「気温は」の「は」が「ha」と発音されてしまう.
調べてみるとこれを解決されている方がいた. MeCab と KanateaTalk で漢字かな交じり文の読み上げ - 電脳スピーチ blog mecabをportsで入れたのでdicrcは/opt/local/lib/mecab/dic/ipadic-utf8/dicrcにあった. これに以下の三行を追加した.ruby n2k.rb 現在の気温は23度です|mecab -O yomi ゲンザイノキオンハニジュウサンドデス
(ちなみにmecabで入れるとeucjpの辞書が入るので+utf8とかしていれないと色々困る) これで「は」は「wa」と発音されることになるnode-format-talk = %pS%f[8]\s unk-format-talk = %M eos-format-talk = \n
ruby n2k.rb 現在の気温は23度です|mecab -O talk ゲンザイ ノ キオン ワ ニ ジュー サン ド デス
で,ここまでやってフト,sayコマンドにKyokoさんがいたじゃないかと気がついた.
すっかり忘れてました.
(いまでもデフォルトでは使えなかったと思う.Kyokoさんのインストールについてはこちらの記事が参考になるかと思う. 「Kyoko」さんに優しく警告してもらう方法 - Macの手書き説明書)
ということで,以下のようにlinda-mac-say.rbを改造してみた.
(英語を読ませようとした時にKyokoさんだと冠詞「a」が「エイ」となったりするので全角があるときだけKyokoさんに登場いただくことにした.)
#!/usr/bin/env ruby
require 'rubygems'
require 'sinatra/rocketio/linda/client'
$stdout.sync = true
class String
def sanitize
self.gsub(/[`"'\r\n;\|><]/, '').strip
end
end
url = ENV["LINDA_BASE"] || ARGV.shift || "http://localhost:5000"
space = ENV["LINDA_SPACE"] || "test"
puts "connecting.. #{url}"
linda = Sinatra::RocketIO::Linda::Client.new url
ts = linda.tuplespace[space]
linda.io.on :connect do ## RocketIO's "connect" event
puts "connect!! <#{linda.io.session}> (#{linda.io.type})"
ts.watch ["say"] do |tuple|
p tuple
if tuple.size == 2 or (tuple.size == 3 and tuple[2].kind_of? Hash)
str = tuple[1].sanitize
opts = tuple[2] ? tuple[2].map{|k,v| "#{k} #{v}"}.join(' ').sanitize : ""
vopt = (/[^ -~。-゚]/=~str)?"-v Kyoko -r 300":"-v Victoria -r 500"
if system "say #{vopt} #{opts} \"#{str}\""
ts.write ["say", str, "success"] # write response
else
ts.write ["say", str, "fail"] # write response
end
end
end
end
linda.io.on :disconnect do
puts "RocketIO disconnected.."
end
linda.wait
0 件のコメント:
コメントを投稿