2012年04月03日

「カーネーション」は最終回も素晴らしかった。

糸子が夏木マリになってから、昔の朝ドラの映像がネタ振りにしか思えないくらい何度も流されていたし、演出チーフのインタビュー記事に2011年まで描くと書いてあったので、最終回でドラマが始まる様子が描かれるのは、決まりだと思っていた。きっと、大半の人もそう思っていただろう。それが、こんな見事な使い方になるとは。これには本当にやられた。

半年間の物語を見てきた後に、初回でのあの「ふたりの糸子の歌」!これは実にうれしい。そして椎名林檎のオープニングテーマまで流れ出す。まさに初回の繰り返し。これが最終回のエンディングとなって、いつものお人形たちの映像の上に、印象深いシーンをちりばめた走馬燈が重ねられている。そして出演者やスタッフの名前の最後に「小原糸子 尾野真千子」の文字。さらに番組最後に、クランクアップのときの三人の糸子の笑顔の写真。ああ、終わってしまったんだ。

それにしても久々に、「ふたりの糸子の歌」で初々しい十代の糸子を演じている尾野真千子の姿を見ると、この人が見せる表情が素晴らしかったから、このドラマを好きになったんだと改めて実感できた。

最終回の話で、だんじりの日、末期がんの加奈子さんがまだ生きていたことは、予想が外れても、これはこれでうれしい。現実はそう都合良くはいかないのは知っているけれど、それでもキセキが起きることは願い続けたい。

病院で小走りの看護師が通り過ぎると、入り口の自動ドアが開き、優しい風が吹き込んでくる場面は、糸子が病院に入ってきたのを表しているのだろう。朝ドラお約束の幽霊表現になるのだろうが、ここでは糸子の姿をわざわざ映さない。それが、くどくなくていい。

看護師がロビーのテレビの前に連れてくるおばあちゃんは、すんなり奈津だと思った。解説音声で確認してもちゃんと、そう言っている。台詞ではっきり言っていないのは、解釈にわざと幅を持たせたのだと思う。奈津でもいいし、奈津や糸子と同じ時代を生きた女性でもいい。奈津の人生は極端すぎるけれど、それぞれのかけがえのない人生を歩んできたあなたたちに、同じ時代を駆け抜けた女性たちの物語を届けますという描写になるだろう。

きっと糸子は奈津と一緒にこのドラマを見たくて、この病院に来たのだろう。だんじりの日の洋装店二階のサロンでは三姉妹の誰もドラマ化の話に興奮する糸子の存在に気付かなかったけれど、奈津にはしっかりこの場に訪ねてきてくれた糸子の姿が見えているだろう。尾野真千子の最終回のとき、お母ちゃんにお父ちゃんの姿が見えていたように。そういうことを想像してしまう。

最後のおばあちゃんの世界で流れている「カーネーション」は、最終回になったとき、きっと今回のそれではなくて、尾野真千子の最終回で終わるのだろう。そう考えないと、このおばあちゃんは最終回の放送ではドラマの中に組み込まれた自分自身を見ないといけなくなるから。そして、夏木マリの演じた物語は、晩年の糸子を姿を描くと共に、尾野真千子が演じた朝ドラが生まれるまでを描いた違う階層の物語で、それを共通する出演者で引き続き放送していたと考えることにしよう。

もうこれでこのお話ともお別れかと思うと、喪失感も相当なものだけど、最終回の「ふたりの糸子の歌」の歌声をきいたせいか、不思議なくらい充足感を持っている。



posted by takayan at 07:29 | Comment(0) | TrackBack(0) | 映画・ドラマ | このブログの読者になる | 更新情報をチェックする

「梅ちゃん先生」のparamファイル

さて、「梅ちゃん先生」が始まりました。

音声メーラー「Voice Popper」用のparamファイルを書いてみました。Voice Popperは桂木範さんが作られた有料の視覚障害者および肢体不自由者向けの音声メーラーです。なお、音読させるためにはPC-TalkerなどのスクリーンリーダーやSAPI音声がパソコンに入っている必要があります。

これにparamという設定ファイルを用意するとホームページの中から特定の部分を抽出して読み上げることができるようになります。

Voice Popperをお持ちの方は、このparamファイルをparamフォルダに入れておくと、あらすじや特集記事などを音読してくれるようになります。

梅ちゃん先生param

なお、WindowsXPをお使いの方は作者のメンテナンスは終わっていますが、無料の「ニュースtoスピーチ」でも利用できるはずです。

それと、まだしばらく「カーネーション」のサイトも残っているので、「カーネーション」用のparamも公開します。あらすじやインタビューなどが読めます。

カーネーションparam



posted by takayan at 08:30 | Comment(0) | TrackBack(0) | 各種ブラウザの設定・操作 | このブログの読者になる | 更新情報をチェックする

2012年04月04日

そろそろ GNOME Orca を本格的に日本語対応させないと

Ubuntu 12.04のベータ2 をいろいろいじっていますが、Open JTalk が公式リポジトリに入っていて、簡単にインストールできるようになってますね。

参考
日本語の文字列をオーディオデータに変換するOpen JTalkの概要とインストール(2012年1月上旬時点) - 試験運用中なLinux備忘録
Open JTalk    [ja.nishimotz.com]

Orca への日本語対応をやり始めて二年も経つのに全然進展できてません。パッチをあてる余り美しくない解決策のままです。Open JTalk が利用しやすくなったからには、この機会に本格的に対応させることにしましょう。

とりあえず、音読対応のメッセージカタログ(ベータ) ja.po を Orca3.4.0 向けに更新しました。これ単体ではまだ何もできませんが、とりあえず。



posted by takayan at 19:40 | Comment(0) | TrackBack(0) | GNOME Orca | このブログの読者になる | 更新情報をチェックする

2012年04月10日

Open JTalk 1.05 を Windows でビルドするバッチファイル

以前作ったものがOpen JTalkのバージョンアップで使えなくなっていたので、また作ってみました。

Visual C++20087-zip がパソコンにインストールされていればビルドできるバッチファイルです。

ダウンロード→ openjtalk_buildbatch-002.zip
(MD5:661e1d709444198d99105baec627cc91)
(2012/04/11 更新)

興味がある人は使ってみてください。自己責任でお願いします。

通常の読み上げテキストはシフトJISの文字コードを使っていますが、Python2.7がインストールされていて、ちゃんと環境変数Pathに追加してあれば、文字コードがutf_8やeuc_jpの辞書用のopen_jtalk.exe もビルドできます。

■ 使い方

上記のファイルを展開して、展開したフォルダ内に次の3つのファイルを置いてください。

・open_jtalk-1.05.tar.gz
・hts_engine_API-1.05.tar.gz
・hts_voice_nitech_jp_atr503_m001-1.04.tar.gz

環境さえ整っていれば、build.bat を実行すると、自動的にビルドしてくれます。無事終わったら、確認を兼ねたOpen JTalkの音声が完了したと報告してくれます。

たぶん、Open JTalk などが細かなバージョンアップをしても、バッチファイル内のそれぞれのバージョン番号を書き換えれば対応できるでしょう。

ビルドが終われば、2つのファイルopen_jtalk.exe、ojtalk.bat と2つのフォルダーhts_voice_nitech_jp_atr503_m001-1.04フォルダ、dic フォルダを残して全部削除してしまってもかまいません。

■ ojtalk.bat

展開したファイル群の中に、ojtalk.bat というのがあります。これをダブルクリックしたり、コマンドプロンプトから実行すると、Open JTalk を使って text.txt の内容を簡単な読み上げのテストができます。

このフォルダを C:\openktalk などに配置して、そこにパスを通すと、簡易読み上げコマンドとして利用できるようにも作ってあります。

シフトを押しながら右クリックなどで、コマンドプロンプトを開き、そこに次のような文字列を入力しエンターを押すと、しゃべります。もしくはこの行をメモ帳などに書いて、hoge.batという「.bat」で終わる名前にして保存して、それをダブルクリックするとしゃべってくれます。

ojtalk こんにちは

いろいろなオプションスイッチの指定ができるようにしてあります。基本的に open_jtalk.exe と同じままですが、コマンドラインの文字列を読ませることをメインにしたかったので、読み上げファイルは -f で指定します。他に、-vdir で音声モデルファイルのディレクトリを指定できます。なおスイッチの引数は空白を空けて書きます。

例えば、

ojtalk みなさん –p 60 –jm 1.2 こんにちは

このように指定すると、早口で、少し大きな声でしゃべります。Open_JTalk にはまだたくさんオプションがありますが、詳しい一覧は、まほろばさんのオープンソース音声合成エンジン「Open JTalk 1.05」などに分かりやすい表があります。

今回は、Open JTalk が直接しゃべるように設定していますが、しゃべらせずに、音声ファイルだけを作ってほしいというときは、オーディオバッファのサイズを指定する -z スイッチを使って、 -z 0 とします。 てくてくラボさんの Open JTalk    [ja.nishimotz.com] の「オーディオデバイスを無効化する」という記事を参考にしてソースを修正すればできるでしょう。 (打ち消し線で消した内容は-zスイッチがなかった頃の解決法でした。)

■ 他の音響モデル

ojtalk.bat の設定を少し書き換えると、標準の hts_voice_nitech_jp_atr503_m001 以外の音響モデルも利用できます。いろいろなMMDAgent 用の音声データも転用できます。open_jtalk.exe を作ったフォルダに音声データをフォルダをごとコピーして、ojtalk.bat の最初の方にある次の行

set VDIR=%CURDIR%hts_voice_nitech_jp_atr503_m001-1.04

この hts_voice_nitech_jp_atr503_m001-1.04 の部分を、そのフォルダの名前に変えると使えるようになります。

MMDAgent の Mei の音声は、mmdagent にある MMDAgent_Example の中にあります。Voiceフォルダをまるごと、今回作った open_jtalk.bat のあるフォルダにコピーしてきて、例の箇所を例えば次のように書き換えます。もしくは、新しく追加した -vdir スイッチでこのフォルダの絶対パスを指定します。

set VDIR=%CURDIR%Voice\mei_normal

 

標準音声のパラメータの数値のままでは、いい声ではありませんので、数値を多少変える必要があります。先ほどのまほろばさんのページに設定値が何通りか書いてあります。

なお、Open JTalk は長文を読ませると、発音がおかしくなる現象が起きます。これを解決するには、てくてくラボさんの Open JTalk    [ja.nishimotz.com]  に書かれている音素継続長の処理を参考にして、ソースを修正するとうまくいくかもしれません。

(2012/04/11最終更新)



posted by takayan at 02:35 | Comment(2) | TrackBack(0) | 音声合成 | このブログの読者になる | 更新情報をチェックする

2012年04月13日

Oxford Latin Dictionary 到着

十数時間前、 amazon.co.uk から到着。でかい、でも今は、とにかくうれしい。

以前からほしかったOxford Latin Dictionary。でも、とにかく高かった。三万円以上もするものだから、ずっと二の足を踏んでいた。

それが、今年の3月に増補改訂新版が出るというので、正月くらいから、この機会に買うぞと決めていた。けれど、4月になってもなかなか日本のアマゾンで取り扱いを開始しない。海外のアマゾンは中のクッションがおおざっぱすぎるので、日本で済ませられるのならば、その方が良いと思っていたが、もうこれ以上待っていられない。結局、イギリスのAmazonから買うことにした。

4月2日に注文。高価なものだから空港の通過が追跡ができて3〜4日で届くやつでも良かったのだけど、それだと日本での価格を超えてしまうので、10日ぐらいかかる通常便で注文した。待ち遠しくて、何度、通常便にしてしまったことを後悔したことか。でも、昨日、発送日に提示された予定よりも一日早く到着した。

ラテン語辞書は、Pocket Oxford Latin Dictionary などは持っていたけれど、例文も無しで対応する単語の羅列ばかりなので、言葉の意味がいまいち把握できなかった。

最初に調べてみた mundus の意味を例に挙げると、ポケット版だと、以下の2行が意味の全てになる。

・m. toilet,ornaments;world;universe
・adj. clean,elegant;delicate,refined

一方OLDだと、この綴りの言葉について、広いページの三分の一を使っている。もちろんだが、言葉の意味の説明がちゃんとある。一部を抜き出すと、次のような文がある。

・elegant or refined in appearance, manners, or taste
・the articles a woman uses to beautify herself, toilet, or sim
・the world, the earth

そして、セネカや、ルクレティウス、オウィディウスなど有名どころからの例文がたくさん添えられている。まだちょっとだけしか見てないが、これが確認できただけでも十分幸せだ。

今までこれを使って研究をしてこなかったのが、恥ずかしいくらいだ。これで、今まで分からなかったいろんなことが調べられる。

オックスフォード大学出版局のこの辞書の解説のページ
http://www.oupjapan.co.jp/products/detail.php?product_id=993



posted by takayan at 03:23 | Comment(0) | TrackBack(0) | 言葉・言語 | このブログの読者になる | 更新情報をチェックする

2012年04月21日

C++/CLIでフィルタを作ってみる

先日バッチファイルを作ったとき、文字セット変換の部分をpythonのワンライナーで書いてみました。

python -c"import codecs,sys;sys.stdout=codecs.lookup('%CHARSET%')[-1](sys.stdout);f=codecs.open('text.tmp','r','sjis');print f.read();f.close()">text.txt

これで、SJISの文書をUTF-8にしたり、EUC-JPにしたりするわけです。でも、こんなことするのに、わざわざpythonインストールするのも大変なんで、どうしようかと考えてました。

まず考えたのは、perlで書くこと。patchコマンドを使うものを次に書こうと思っていて、Windows に patchコマンドを入れるんだったらMinGW/MSYSのものが入れやすいので( MinGW Developer Toolkitにチェックを入れる)、MinGW/MSYSを入れるとき、perlも入るので、perlでもいいと思ったわけです。

perlだと、かなりすっきりして、こんな感じになりました。(結局公開しなかったけど。)

perl -MEncode -pe "$_=encode('%CHARSET%',decode('SHIFT_JIS',$_));" text.tmp>text.txt

でも、patchコマンドの作業は、無ければ無いで手作業でできることなので、わざわざMinGW/MSYSを入れるのも大変だなと思って、他の手は無いかと考えてみました。

灯台もと暗し。C++でビルドする作業を自動化しようとしているわけですから、それもC++で書けばいいのです。C++/CLIで作る標準入力のデータを加工して、標準出力に出すだけのサンプルのような簡単なフィルタプログラムです。

以前、UTF-8に変換するプログラムをMultiByteToWideCharを使って書いたことありますが、面倒だった記憶しか残ってません。それは嫌なので、C++/CLIで作ってみました。.NET FrameworkのEncodingクラスが使えるなら、利用しない手はないわけです。結局こうなりました。

#using <System.dll>
using namespace System;
using namespace System::Text;
using namespace System::IO;

int main(array<System::String ^> ^args)
{
    TextReader^ input = Console::In;
    String^ charset;

    if (args->Length != 1)
    {
        return -1;
    }

    String^ sw = args[0]->ToLower();

    if (String::Compare(sw, "-utf-8") == 0) {
        charset = "UTF-8";
    }else if (String::Compare(sw, "-utf_8") == 0) {
        charset = "UTF-8";
    }else if (String::Compare(sw, "-utf8") == 0) {
        charset = "UTF-8";
    }else if (String::Compare(sw, "-euc-jp") == 0) {
        charset = "EUC-JP";
    }else if (String::Compare(sw, "-euc_jp") == 0) {
        charset = "EUC-JP";
    }else if (String::Compare(sw, "-eucjp") == 0) {
        charset = "EUC-JP";
    }else if (String::Compare(sw, "-euc") == 0) {
        charset = "EUC-JP";
    } else {
        Console::Error->Write(" 引数は-UTF_8と -EUC_JP のどちらか一方です。");
        return -1;
    }

    Encoding^ src = Encoding::Unicode;
    Encoding^ dst = Encoding::GetEncoding( charset );
    Stream^ output = Console::OpenStandardOutput();
    String^ line;

    while ((line = input->ReadLine()) != nullptr)
    {
        array<Byte>^temp = Encoding::Convert(src, dst, src->GetBytes(line + Environment::NewLine));
        output->Write(temp, 0, temp->Length);
    }
    return 0;
}

これを、cscnv.cpp なんて名前で保存して、こんなバッチファイルを作ってコンパイルします。VSVER=10.0 はVisual Studio 2010のことです。9.0 だと Visual Studio 2008 です。現在、既に評価版公開中の次期バージョンだと 11.0 です。

@echo off
set VSVER=10.0
set ARCH=x86
if %PROCESSOR_ARCHITECTURE% == x86 (
    set VCVARSALL_PATH="C:\Program Files\Microsoft Visual Studio %VSVER%\VC\vcvarsall.bat"
) else (
    set VCVARSALL_PATH="C:\Program Files (x86)\Microsoft Visual Studio %VSVER%\VC\vcvarsall.bat"
)
call %VCVARSALL_PATH% %ARCH%
cl /clr:safe cscnv.cpp

VC++ のツールメニューにあるVisual Studio のコマンドプロンプトを呼び出してから、ファイルのある場所に移動して、cl /clr:safe cscnv.cpp と入力してエンターでもいいです。

コンパイルが終わったら、コマンドプロンプトから、次のように打ち込んで、

echo こんにちは | cscnv –UTF8>test.txt

そのあと test.txt ファイルを開いて確かめます。うまくいっていれば、文字コードがUTF-8(BOM無し)のファイルができているはずです。

これで、python や perl などのコマンドを使わずに、shift-jis から、urf-8 や euc-jp への文字セットの変換ができるようになりました。

perl で一行で済ませられることを書くにしては、実質的な部分を比べても長いのは長いのですが、この基本形さえ押さえておけば、いろいろ応用できそうです。



posted by takayan at 12:46 | Comment(0) | TrackBack(0) | プログラミング | このブログの読者になる | 更新情報をチェックする

2012年04月22日

16進エスケープシーケンスにするフィルタ

今度は、SJIS以外の文書を読み込むとVC++が警告を出してしまう問題の対策をしてみます。

やろうとしていることは単純です。怒られそうな文字コードを16進数表記の文字リテラルに置き換えるだけです。シフトJISならば、2バイト文字の2バイト目に隠れている「 \ 」が表に出てきて、この記号にはいろいろな役割があるせいで、処理が大変ですが、EUC-JP の2バイト文字は 0x80よりも大きいものばかりで、UTF-8 の方も、1バイト文字以外は0x80以上の列になるので、どちらの文字セットでも0x80以上のものだけを16進数表記の文字リテラル(例えば\x80)にすることで、うまく解決できるはずです。

この問題に対しては、以前から escapize.py なんて名前の python スクリプトを対処していました。これもワンライナーで簡潔に表記できるなら、こんな別ファイルのスクリプトを書くより扱いやすいでしょう。

そういうわけで perl で書くと、バッチコマンド for の再帰探索を利用してこうなります。

for /R %%i in (*_%CHARSET%.h) do (
perl -i.backup -pe "s/(.)/(ord($1)>=128)?sprintf('\\x%%x',ord($1)):$1/eg" "%%i"
)

ビルド処理が終わったら .backup を元に戻します。perl が使える環境ならば、これで解決です。

 

今度は、perl は入っていないけれどVC++ は入れてある環境で考えてみます。 これも前回のように C++/CLI で作るならば、簡単に正規表現が使えるので、上と同じものを書けるだろう、と作る前は思ってました。でもそう簡単にはいきません。正規表現は Stringクラス、つまり Unicode が対象です。UTF-8 や EUC-JP の生の文字コードが扱えません。

そもそも正規表現を使うまでもない内容なので、それはすんなり諦めて、他にC++/CLI でやる方法を考えてみました。C++/CLI では指定すれば UTF-8 や EUC-JP で文書を読み込むことができると分かりましたが、それは String クラス(Unicode)に変換するためのものでした。今回のような場合はバイナリー配列として読み込む必要があるようです。実際いろいろ作ってみたら、キーボードからの入力だと思い通りにならなかったり、難しいので、結局、純粋な C++ のプログラムとして書くことにしました。

ということで、

#include <string>
#include <iostream>
int main()
{
while ( !std::cin.eof() )
{
std::string line;
std::getline(std::cin, line);
for ( int i = 0; i < line.length(); i++ )
{
unsigned char c = line[i];
printf( (c >= 128)?"\\x%02X":"%c", c );
}
std::cout << std::endl;
}
return 0;
}

このファイル名を csesc.cpp などとして、前回のようにビルド用の環境設定をやったあと、次のコマンドで実行ファイル csesc.exe ができあがります。

cl /EHsc csesc.cpp

前回のコマンドと組み合わせて、次のような感じで動作確認できます。

echo こんにちは|csesc
echo こんにちは|cscnv –utf8|csesc

結果:
\x82\xB1\x82\xF1\x82\xC9\x82\xBF\x82\xCD
\xE3\x81\x93\xE3\x82\x93\xE3\x81\xAB\xE3\x81\xA1\xE3\x81\xAF

こういう実験もできます。csesc.cpp に適当に日本語のコメントを入れて、UTF-8(BOM無し)かEUC-JPで保存してみます。ちなみに、BOM無しUTF-8やEUC-JPで保存できる無料のエディタは サクラエディタEmEditor Free などがあります。

これをコンパイルすると警告が出ます。そこで、このフィルタ・コマンドの登場です。

cl /EHsc csesc.cpp
csesc <csesc.cpp >csesc_new.cpp
cl /EHsc csesc_new.cpp

なお、今回はEUC-JPのファイルも対象だったので、この方法をとりましたが、これが UTF-8 のファイルだけだったら、ファイルの頭にUTF-8であることを示すBOM("\xEF\xBB\xBF")をくっつけても解決できます。

(修正 \xAA の形式で、 \の後ろの’x’は必ず小文字じゃないといけません。)



posted by takayan at 19:34 | Comment(0) | TrackBack(0) | プログラミング | このブログの読者になる | 更新情報をチェックする

2012年04月25日

Open JTalk を 64ビットWindows用にビルドする方法

Open JTalk を x64 Windows 向けにビルドする方法を調べてみました。

単純にターゲット環境を /MACHINE:x64 のスイッチで64ビットにしてビルドすると、Mecabのコード部分でコンパイルエラーが出ます。feature_index.cppとwrite.cpp です。原因は型の曖昧さエラーです。これを下記のページを参考にしてキャストで型を明示的に指定して解決します。

64ビットWindows用にMeCabをビルドする (Visual Studio 2010を利用)

open_jtalk_1.05 に使われている feature_index.cpp では310行目、write.cpp は235行目が問題の箇所となっています。

feature_index.cpp:310
-            case 't':  os_ << (size_t)path->rnode->char_type;     break;
+            case 't':  os_ << (unsigned int)path->rnode->char_type;     break;

writer.cpp:235
-          case 'L': *os << std::strlen(sentence); break;
+          case 'L': *os << (unsigned int)std::strlen(sentence); break;

とりあえず、これだけの修正でビルドが通ります。しかし、実際に動かすと、応答無しになってしまいます。

VC++でデバッグして調べてみると、hts_engine_API-1.06.tar.gz にある HTS_audio.c の167行目、関数 waveOutOpen 呼び出しでの引数の型が原因だと分かりました。4番目と5番目の引数のキャストを DWORD から DWORD_PTR に変えると、エラーが起きなくなります。DWORDとしてあるのはx64を考慮していない頃の古い定義によるものです。

HTS_audio.c:167
-   error = waveOutOpen(&audio->hwaveout, WAVE_MAPPER, &audio->waveformatex, (DWORD) HTS_Audio_callback_function, (DWORD) audio, CALLBACK_FUNCTION);
+   error = waveOutOpen(&audio->hwaveout, WAVE_MAPPER, &audio->waveformatex, (DWORD_PTR) HTS_Audio_callback_function, (DWORD_PTR) audio, CALLBACK_FUNCTION);

以上、3行修正して、x64向けのビルドをすると、open_jtalk.exe は 64ビットアプリケーションとして動くようになります。

このくらい手作業で十分ですが、折角なので、先日コメント欄で指摘してもらった長文で音声がおかしくなる問題を修正したものも含めて、パッチを三つ作ってみました。

open_jtalk-1.05_x64_patch.zip

patch コマンドがあれば、展開したフォルダに該当するパッチファイルを置いて、例えば、次のコマンドでパッチが当てられます。

patch -p1 < open_jtalk-1.05_x64.patch



posted by takayan at 23:53 | Comment(0) | TrackBack(0) | 音声合成 | このブログの読者になる | 更新情報をチェックする