awk で喋らせてみる
404 Blog Not Found:perl - SayKanji + Yahoo API = itte.pl や saykanjiコマンドを定義して漢字仮名混じり文を読み上げる - ザリガニが見ていた...。を見て、awk をラッパーとして喋らせてみようという試みです。 このマシンが Linux (Fedora) ということもあり、手元にインストールしてある mecab で解析を行い、espeak で喋らせてみます。
#! /usr/bin/gawk -f
# say_japanese.awk
BEGIN {
echo_cmd = "/bin/echo";
mecab_cmd = "/usr/bin/mecab";
mecab_opt = "";
espeak_cmd = "/usr/bin/espeak";
espeak_opt = "";
str = ARGV[1];
mecab_exec = echo_cmd " " str "|" mecab_cmd " " mecab_opt;
while (mecab_exec | getline > 0) {
split($2, arr_mecab, ",");
num++;
if ($1 ~ /[:alnum:]+/ && $2 != "") {
arr_alpha[num] = $1;
} else {
arr_alpha[num] = yomi2alpha(arr_mecab[9]);
}
}
close(mecab_exec);
espeak_exec = espeak_cmd " " espeak_opt "'";
for (i = 1; i <= num; i++) {
espeak_exec = espeak_exec " " arr_alpha[i];
}
espeak_exec = espeak_exec "'";
system(espeak_exec);
}
function yomi2alpha(str) {
gsub("ッチャ", "tcha", str);
gsub("ッチュ", "tchu", str);
gsub("ッチョ", "tcho", str);
gsub("ッチ", "tchi", str);
gsub("キャ", "kya", str);
gsub("キュ", "kyu", str);
gsub("キョ", "kyo", str);
gsub("シャ", "sha", str);
gsub("シュ", "syu", str);
gsub("ショ", "sho", str);
gsub("チャ", "cha", str);
gsub("チュ", "chu", str);
gsub("チョ", "cho", str);
gsub("ニャ", "nya", str);
gsub("ニュ", "nyu", str);
gsub("ニョ", "nyo", str);
gsub("ヒャ", "hya", str);
gsub("ヒュ", "hyu", str);
gsub("ヒョ", "hyo", str);
gsub("ミャ", "mya", str);
gsub("ミュ", "myu", str);
gsub("ミョ", "myo", str);
gsub("リャ", "rya", str);
gsub("リュ", "ryu", str);
gsub("リョ", "ryo", str);
gsub("ギャ", "gya", str);
gsub("ギュ", "gyu", str);
gsub("ギョ", "gyo", str);
gsub("ジャ", "ja", str);
gsub("ジュ", "ju", str);
gsub("ジョ", "jo", str);
gsub("ビャ", "bya", str);
gsub("ビュ", "byu", str);
gsub("ビョ", "byo", str);
gsub("ピャ", "pya", str);
gsub("ピュ", "pyu", str);
gsub("ピョ", "pyo", str);
gsub("ア", "a", str);
gsub("イ", "i", str);
gsub("ウ", "u", str);
gsub("エ", "e", str);
gsub("オ", "o", str);
gsub("カ", "ka", str);
gsub("キ", "ki", str);
gsub("ク", "ku", str);
gsub("ケ", "ke", str);
gsub("コ", "ko", str);
gsub("サ", "sa", str);
gsub("シ", "shi", str);
gsub("ス", "su", str);
gsub("セ", "se", str);
gsub("ソ", "so", str);
gsub("タ", "ta", str);
gsub("チ", "chi", str);
gsub("ツ", "tsu", str);
gsub("テ", "te", str);
gsub("ト", "to", str);
gsub("ナ", "na", str);
gsub("ニ", "ni", str);
gsub("ヌ", "nu", str);
gsub("ネ", "ne", str);
gsub("ノ", "no", str);
gsub("ハ", "ha", str);
gsub("ヒ", "hi", str);
gsub("フ", "fu", str);
gsub("ヘ", "he", str);
gsub("ホ", "ho", str);
gsub("マ", "ma", str);
gsub("ミ", "mi", str);
gsub("ム", "mu", str);
gsub("メ", "me", str);
gsub("モ", "mo", str);
gsub("ヤ", "ya", str);
gsub("ユ", "yu", str);
gsub("ヨ", "yo", str);
gsub("ラ", "ra", str);
gsub("リ", "ri", str);
gsub("ル", "ru", str);
gsub("レ", "re", str);
gsub("ロ", "ro", str);
gsub("ワ", "wa", str);
gsub("ヲ", "wo", str);
gsub("ン", "n", str);
gsub("ガ", "ga", str);
gsub("ギ", "gi", str);
gsub("グ", "gu", str);
gsub("ゲ", "ge", str);
gsub("ゴ", "go", str);
gsub("ザ", "za", str);
gsub("ジ", "ji", str);
gsub("ズ", "zu", str);
gsub("ゼ", "ze", str);
gsub("ゾ", "zo", str);
gsub("ダ", "da", str);
gsub("ヂ", "ji", str);
gsub("ヅ", "zu", str);
gsub("デ", "de", str);
gsub("ド", "do", str);
gsub("バ", "ba", str);
gsub("ビ", "bi", str);
gsub("ブ", "bu", str);
gsub("ベ", "be", str);
gsub("ボ", "bo", str);
gsub("パ", "pa", str);
gsub("ピ", "pi", str);
gsub("プ", "pu", str);
gsub("ペ", "pe", str);
gsub("ポ", "po", str);
gsub("nb", "mb", str);
gsub("nm", "mm", str);
gsub("np", "mp", str);
while (match(str, "ー")) {
str = substr(str, 1, RSTART - 1) \
substr(str, RSTART - 1, 1) substr(str, RSTART + 1);
}
while (match(str, "ッ")) {
str = substr(str, 1, RSTART - 1) \
substr(str, RSTART + 1, 1) substr(str, RSTART + 1);
}
gsub("oo", "o", str);
gsub("ou", "o", str);
return str;
}
カタカナをアルファベットに変更する yomi2alpha() 関数のダラダラさは仕方がないとしても、あまり awk らしさの感じられないものになってしまいました。
$ gawk -f say_japanese.awk 'あなたは English しゃべれますか?'
音声はespeak で wav に落として ffmpeg で MP3 に変換したものを置いておきますが、某ゆっくりよりも酷いです。 ネタは巡音ルカ と 英語でおしゃべり!‐ニコニコ動画(ββ)ですが、思ったように喋ってくれませんね。


