カテゴリー: general

  • 自動作曲オルフェウス

    昨日のお昼のテレビ番組で紹介された直後からアクセスが殺到し、数時間後にサーバがダウンしました。3月の公開以来そんなことになるとは思わなかったので驚きました。サーバのチューニングを施して今日のお昼頃に再稼働しました。これまでの200倍くらいのアクセス頻度でしょうか。。

    • 深山 覚, 中妻 啓, 米林 裕一郎, 酒向 慎司, 西本 卓也, 小野 順貴, 嵯峨山 茂樹, “Orpheus 歌詞の韻律に基づく自動作曲システム,” 情報処理学会研究報告, 2008-MUS-76-30, pp.179-184, Aug., 2008. (PDF)
  • 音声対話と「もう一つの未来」

    8月下旬に京都で行われる音声対話技術の講習会で、音声対話技術コンソーシアム(ISTC)が製作する Galatea Toolkit DVD-ROM が配付される予定です。私は主にLinux版に関する Toolkit の更新作業を担当しています。

    SourceForge.JPのgalateaプロジェクトでは通称「IPAライセンス」で開発されたオープンソース成果物とその後継版を配付しています。私が開発している音声対話エンジンGalatea Dialog Studio (GDS) 2.2.2も300件以上ダウンロードしていただいているようです。

    全てのモジュールを統合したISTCの成果物は講習会参加者およびISTC会員に配付される予定です。コンソーシアムの活動は本年度で終了するので、その後の開発を継続するためには、これらのツールに関するオープンソースコミュニティをもっと盛り上げていく必要があるだろうと思います。

    以前この日記で考察した「Ruby on Rails による VoiceXML 開発」はまだ「今後の課題」のままなのですが、Ruby on Rails の「フルスタック」という特長はGDSにとっても重要ではないかと思います。GDS は Java で実装されているのですが、いずれ JRuby によって、アプリケーションとインタプリタのフルスタック処理系に手が届くだろうと展望しています。これは、そもそも HTTP と VoiceXML という技術によって音声対話システムをサーバ・クライアント型モデルに分離したという経緯を考えると、不合理に思えるかも知れません。しかし、その理由はそのまま「フルスタック環境である Ruby on Rails の利便性」と同じなのではないかと思います。

    フルスタックという言葉からもう一つ思うのは、音声対話システムがうまく動かないときに、システムが依存している全てのモジュールの設定ファイルやログの確認を行うのは非常に複雑な作業である、ということです。将来的には、全てのモジュールが統一的なリモートロギングのインタフェースを備える必要があるだろうと思います。暫定的には、全てのモジュール(音声認識、音声合成、顔画像合成)の設定ファイルを対話マネージャが動的に生成し、GDS が各モジュールのログファイルを一元的に監視する、という方向を目指しており、今日もそのための作業をすこし進めました。

    音声対話あるいは音声認識について、ヒューマンインタフェースの開発者・研究者の方々は「実用にならないまま過去のものになってしまった技術」という見方をお持ちかも知れません。その一方で音声認識の研究者の方々には「もう完成されており、後は使ってもらうだけの技術」という見方もあるのではないかと思います。

    西本が今年1月に研究会で発表した

    • 西本 卓也,岩田 英三郎, 櫻井 実, 廣瀬 治人: “探索的検索のための音声入力インタフェースの検討,” 情報処理学会研究報告 2008-HCI-127(2), pp.9-14, Jan 2008. (PDF)

    は、そうした現状における問題提起のひとつなのですが、この予稿の中で私が提案した「インタフェースシステムの導入原則」(下記、一部加筆)があります。

    (ここから)

    インタフェースシステムの基本原則および構成原則(西本 1996)を踏まえて,近年のインタラクション技術の動向を反映させ,また著者の経験を反映させるための再検討を行っている.

    「基本原則」および「構成原則」の視点は引き続き有効である.そのうえで,インタフェースシステムを成功させるためには,アプリケーションそのものの選択や設計により深く関与し,システムをどのような状況に適合させ,どのように評価や改良を行っていくか,というプロセスが重要になっている.インタフェース原則を補完するものとしてこれらを暫定的にまとめたものが,以下の「インタフェースの導入原則」である.

    「インタフェースの導入原則」

    • a.有用性の原則: システムが使用される現場における必然性を考慮して設計と導入を行う.ユーザに動機付けを与える心地よさ・美しさ・楽しさを盛り込む(エモーショナルデザイン(Norman 2004)).
    • b.適合性の原則: あらゆる年齢や能力の人々に対して可能な限り使いやすさを提供する(ユニバーサルデザイン).システムが使われる状況・環境を考慮する.ユーザ以外の人に悪影響を与えない.ユーザが行っている他のタスクに悪影響を与えない.
    • c.妥当性の原則: 妥当な時期に妥当な尺度で評価を行う.評価の結果を生かして反復的な開発・改良を行う.

    (ここまで)

    インターネットにまつわる日々の雑用(その多くは、メールを読んで、メールを検索して、カット&ペーストしてメールを送ったり、ウェブのフォームを埋めることだったりしますよね)が不毛に感じられることがあります。

    GUIが普及してインターネットが普及したからこそ、いまのPC利用の状況は「当たり前」にしか感じられないのですが、たまたま「音声対話システム」がなかったにも関わらず「インターネットというインフラ」は実現してしまい、「人間がやっていた仕事をコンピュータに代行させたい」というニーズが爆発的に増加してしまった。結果的に、テキスト情報と視覚的インタフェースだけで「人間の代わりをしてくれる自動応答サービス」を実現せざるを得なくなった、とは言えないでしょうか?

    音声対話システムは「起きるはずだった未来」あるいは「失われた未来」ではなかったでしょうか。。

    もしも、音声対話システムが「もっと上手に」実現され普及していたら、我々は今日のようなメールとウェブのフォームから解放され、もっとスマートにインターネットを使いこなせていたのではないか、と思えてきました。

    いや、「失われた未来」を取り戻すのは、まだ遅くないと思うのです。いかがでしょうか。。。

  • 1998年とニコニコ動画

    「あの仕事はむかし誰々がやった仕事の真似だ」みたいな話はよく出てきます。あまり好きではないのですが、あえて私もそういうスタンスであの「ニコニコ動画」について考察してみることにしました。

    1998年のはじめごろ、電話の自動応答サービスで音声を録音して、ウェブサーバからそれを聴取できる、というサービスを知り、そのころ私が主宰していたメーリングリストのメンバーたちと「どんな遊びに使えるのか」と試していました。その途中でこんなことに気づきました。

    ある人によって録音された音声を別の人が再生しながら、それに「うん」「そうだね」などとコメントをする。そのやりとりを録音して、さらに別の人に聞いてもらう。そうすると、なんとなく「時間と空間を超えて会話が成り立った」ような感じがしたのです。

    その「感じ」を追い求めて、私は「非同期音声会議」の研究・開発を始めました。

    この仕事については続きがあり、特許(特願2000-37349 特開2001-230773 会議システム)も出願したのですが、審査請求に至りませんでした。システムも継続運用するには至りませんでした。

    その後、やっぱり「ウェブのフォームを埋めたりメールで連絡するよりも音声の方が手っ取り早いなあ」と思うことはますます多くなる今日この頃。

    そして、私が1998年に発表した「時間と空間を超える疑似リアルタイム性」は「ニコニコ動画」の字幕機能として世に受けいられていることを思い、今こそ「非同期通信+音声入力」で面白いことができる&便利なものが作れるのではないかなあ、と思っています。

  • 国際会議への参加

    1日から12日まで出張し、フランスのパリとオーストリアのリンツで行われた国際会議に参加してきました。メール対応が滞ってしまったことなど、皆様にご迷惑をかけたことをお詫びします。発表内容はここ何年か東京女子大学と共同で行ってきた視覚障害者支援技術に関する研究でした(西本の発表リスト)

    Acoustics ’08 Paris では私はポスター発表で早口音声の知覚に関する報告をしたところ、du Poux 先生のグループの研究(文献など)を教えていただいたり、Univ. Washington の Richard Wright 先生に興味を持って聞いていただくなど、貴重な情報を得ました。

    ICCHP 2008 Linz は障害者支援技術に関する隔年の国際会議で、私が幹事をやっている福祉情報工学研究会に近い雰囲気でした。私は視覚障害者と対面朗読者の対話についての発表をして、座長を含む何人かの視覚障害者にも聞いていただきました(論文へのリンク)。発表者はヘッドセットをつけて音声をストリーミング配信。他には国際手話言語の通訳つきセッションもありました(ストリーミングのページへのリンク)

    予稿集は約1300ページで、支援技術の実践的な事例、プロジェクト紹介、各国の行政の取り組みなど幅広い内容です。擬人化エージェントによる高齢者や知的障害者の支援、視覚障害者のための音楽教育、といった発表もありました。

    様々な場面でフランス語やドイツ語がわからなくて不便な思いをしました。一方で、観光地や料理店などでは日本語の看板をちらほら見かけました。書店では日本のコミックがたくさん売られていました。もっと世界中のことを考えて仕事をしなくてはいけないなあと改めて感じました。

    以上、今後の活動や研究に行かしていきたいと思います。

    • [追記 2008-07-15] ICCHPの論文へのリンク(Springer)を追加しました。
  • C++Builder 2007 でのウィンドウメッセージ処理

    エンバカデロによる買収が決まったCodeGearですが、個人的には応援しています。

    Delphi は使いやすく、情報も豊富なのですが、私はとっくに Pascal よりも C++ に慣れてしまったので、できれば C++ Builder をメインに使いたいところです。

    Delphi の参考書や資料の多くは VCL について説明しているので、そのノウハウのかなりの部分は使えます。

    しかし C++ Builder に固有の話題についての情報はとても少ないのが現状です。

    Windowsプログラミング逆引きクロス大辞典

    Windowsプログラミング逆引きクロス大辞典

    「Windowsプログラミング逆引きクロス大辞典」にはTurbo DelphiとTurbo C++というかたちで、VB6 や .Net との比較がなされています。

    Turbo C++はC++Builderだと思って読むことができるので、CodeGear RAD Studio 2007を使う上で重宝しそうです。

    Delphi で「メッセージメソッド」と呼ばれている機能の実現方法が今日やっとわかりました。忘れないように書いておきます。

    mciSendString を使って mp3 ファイルを再生して、再生終了のメッセージを MCI から受け取る例です。

    VCLフォームアプリケーションにボタンをひとつ貼り付けて、以下のように記述。

    mmsystem.h をインクルードしないと MM_MCINOTIFY が未定義になります。

    C:\tone_a.mp3 を用意してボタンを押すと、音声再生が終了したらメッセージボックスが表示されます。

    //---------------------------------------------------------------------------
    // Unit1.h
    #ifndef Unit1H
    #define Unit1H
    //---------------------------------------------------------------------------
    #include <Classes.hpp>
    #include <Controls.hpp>
    #include <StdCtrls.hpp>
    #include <Forms.hpp>
    //---------------------------------------------------------------------------
    // by nishimotz
    #include <mmsystem.h>
    //---------------------------------------------------------------------------
    class TForm1 : public TForm
    {
    __published:	// IDE 管理のコンポーネント
    TButton *Button1;
    void __fastcall Button1Click(TObject *Sender);
    private:	// ユーザー宣言
    void __fastcall MMMCINotify(TMessage &Msg);
    BEGIN_MESSAGE_MAP
    VCL_MESSAGE_HANDLER(MM_MCINOTIFY, TMessage, MMMCINotify)
    END_MESSAGE_MAP(TForm);
    public:		// ユーザー宣言
    __fastcall TForm1(TComponent* Owner);
    };
    //---------------------------------------------------------------------------
    extern PACKAGE TForm1 *Form1;
    //---------------------------------------------------------------------------
    #endif
    
    //---------------------------------------------------------------------------
    // Unit1.cpp
    #include <vcl.h>
    #pragma hdrstop
    #include "Unit1.h"
    //---------------------------------------------------------------------------
    #pragma package(smart_init)
    #pragma resource "*.dfm"
    TForm1 *Form1;
    //---------------------------------------------------------------------------
    __fastcall TForm1::TForm1(TComponent* Owner)
    : TForm(Owner)
    {
    }
    //---------------------------------------------------------------------------
    void __fastcall TForm1::Button1Click(TObject *Sender)
    {
    mciSendString("open \"c:\\tone_a.mp3\" type Mpegvideo alias mp3", NULL, 0, 0);
    mciSendString("play mp3 notify", NULL, 0, Form1->Handle);
    }
    //---------------------------------------------------------------------------
    void __fastcall TForm1::MMMCINotify(TMessage &Msg)
    {
    ShowMessage("done.");
    mciSendString("close mp3", NULL, 0, 0);
    }
    

    END_MESSAGE_MAP(TForm) の後ろのセミコロンを忘れて、しばらくはまりました。

    VCL_MESSAGE_HANDLER に関する情報は RAD Studio のヘルプでも CodeGear のサイトでも見つけることができず、個人の方のウェブサイトを参考にさせていただきました。

  • 日記の表示モード

    先日、はてな日記の設定に「表示モード」という項目があることに気づきました。

    「日記モード」から「日記モード・見出し別ページ」「ブログモード」に変更することがいつでもできます、と書かれていたので、変更してみたのですが、そうすると他の方からブックマークしていただいたり「はてなスター」をいただいたものが無効になってしまうことに気づき、約1日で「日記モード」に戻しました。

    私がモードを変えている間に「はてなスター」をつけてくださった方がおられるのですが、そんな事情でご迷惑をおかけしてしまったようです。ごめんなさい。

    たまたま査読の仕事を抱えているときに「査読マニュアル」の存在を思い出すことができ、感謝しています。。。

  • 分散バージョン管理の意義

    いくつかのシステムに Mercurial をインストールして使い方を勉強しつつ、なぜ「バージョン管理システムを使うのか」について改めて考えました。

    まず「バージョン管理システムはバックアップツールだ」という主張は一見わかりやすいのですが、どうも違和感があるので、さらに考えた末、以前から考えてきたこと(数年前にソフトバンクのCVS本に書いたこと)と重複するのですが

    • バージョン管理システムは「無駄なバックアップを安全に消去するツール」である
    • バージョン管理システムは「リファクタリングを安全に行うツール」である

    と思えてきました。

    まず「バックアップの消去」について説明したいと思います。

    Windows のユーティリティに undup という重複ファイル削除ソフトがあるらしいのですが、バージョン管理システムは「賢いundup」ではないかと思うのです。

    以前と比べてバックアップを取ることは簡単になりました。モバイルPCも安価になり手軽になり、複数のマシンにコピーして作業することも日常的になりました。USBメモリも外付けドライブもネットワークストレージも手軽に使えるようになり、ついあちこちに気軽にバックアップコピーを取ってしまいがちです。

    しかし、本当に難しいのは「バックアップを取ること」ではなく「バックアップを捨てること」ではないでしょうか? あちこちにばらまかれてしまった重複ファイルを安全に削除するためにはどうしたらいいでしょうか? 完全に同じファイルなら安全に消すことができますが、もし改変があるなら、それを保存するべきかどうかを簡単に判断できるでしょうか?

    消去すべきファイルは、重複ファイルだけではありません。

    不要なファイルを簡単に見分けるための工夫として、ここ数年、私はファイル名の付け方の規則として

    • 一時ファイルには、先頭文字がアンダースコア(_)で始まるファイル名をつける

    ということを教わって実践しています。しかし、いろいろなソフトウェアの事情があり、この規則を徹底できない場合があったとすると、「保存するべきファイルか、一時的なファイルであるか」という区別は、ファイルそのものに記憶させるのではなく、メタ情報として外部に保存する必要が出てきます。

    バージョン管理システムのリポジトリとはまず「バックアップをすべきファイルかどうかを表す属性情報である」と捉えてはどうでしょうか。重複ファイルも一時ファイルも簡単に判断できる手段を提供するのがバージョン管理システムだと思うのです。

    もう一つの「リファクタリングの道具としてのバージョン管理」については、すでに多くが語られていると思うのですが、「プログラムを、機能を変えずに、構造を改良する」という作業のためには、「確実かつ効率的に過去の状態を参照できる(元の状態に戻せる)」という作業環境が求められます。ファイル群を丸ごとコピーしてしまうと、効率的に差分を表示することが難しくなります。

    バックアップとリファクタリングは目的が違います。バックアップは物理的に別のデバイスに保存する必要があるため、ネットワークを介した通信機能は必要です。しかし、リファクタリングはネットワークから切断された状態でも行われるべき作業なので、リポジトリがローカルに存在しないのはとても不便です。

    このように考えてみると Mercurial の分散バージョン管理という仕組みは、昨今のコンピュータ利用の現状にふさわしい枠組みではないか、と思います。

    ロック・アンロックをベースにしたRCSが大人数での分散作業に向いていない、ということで、コピー・マージ方式を導入したCVSが数年前に広く普及しました。それと同時に「伽藍とバザール」のモデル比較が話題になり、CVSはバザール型のオープンソース開発にふさわしいツールである、と考えられた時代がありました。しかしいま振り返ると、CVSは「バザール開発のツール」というよりも「みんなで分担してひとつの大きなものを作る」ための共同作業ツールであったように思えます。

    しかし現実に求められている問題の多くは「みんながそれぞれ自分のための派生物を作る」ことであり、さらに「派生物の差分を取捨選択して共有する」ことだったりします。そのためには、みんなが別々にリポジトリを持つ必要があり、しかもリポジトリ同士でマージを行うメカニズムがやはり必要なのだろう、と思います。

  • Mercurial によるバージョン管理

    巷で話題の「分散」バージョン管理システム Mercurial を使ってみました。

    遠い昔にCVSの本を書いたときには「オープンソース」という言葉が世の中に広まりはじめたばかりでした。

    でも私の興味はオープンソースそのものではなくて「個人が安全にソフトウェアを開発する」あるいは「グループが効率的に共同作業をする」ということでした。CVSよりもSubversion(svn)の方が優れているらしい、とは聞き及びつつも、道具にこだわるよりも、何かを作ることのほうが大事だと思ってきました。

    最近やっと Eclipse 経由で(というよりも3rdRail経由で)Subversion を使うようになりましたが、Eclipse からいじっている限り大きな違いはなく、大きな感動もありませんでした。むしろ、日々のコミット作業のインタフェースよりもリポジトリのビューワーの方がよっぽど大事だと思うのに、cvsweb はどうなっちゃったんだろう、などと思いました。

    そんなことを思いながら、Mercurial を触りはじめて、逆に cvs/svn が「グループが効率的に共同作業をする」というところに重きを置きすぎて「めんどくさい」ツールになってしまったことに気づきました。ある状況で「CVS よりも RCS の方が適しているのでは?」と思ったこともあるのですが、かつて RCS が適していた場面をカバーしてくれる(そしてそれ以上のことを実現してくれる)のが Mercurial だと思います。

    バージョン管理システムを「これはバックアップツールの一種です」と説明している本やサイトも多いのですが、そもそも「バックアップ」と「バージョン管理」は分けて考えた方がいいのではないか、という気もしてきました。(例えば pdumpfs はよいバックアップツールだと思いますが、バージョン管理ツールだと言い張るのは無理ではないかと。。。)

    「個人が安全に開発する」というところを重視するなら「作業中のファイルをいったん import して checkout しなおす」という「謎の御点前」が不要なだけでも Mercurial はずいぶん手軽だなあ、と感じました。

    とはいえ、Mercurial においても”hg init” して “hg add” して “hg ci” しなくてはいけないので、手間の問題というよりも「安全な場所を決めてリポジトリを作る」という作業そのものの精神的な抵抗がないことのメリットなのかも知れませんが。

    もう一つ評価に値するのは、リポジトリのビューワーが内蔵されていることです。”hg serve” を実行して、ウェブブラウザで localhost:8080 を開けば、cvsweb ライクなインタフェースがすでに備わっている、ということがわかりました(ポート番号はオプションで変えられるとのこと)。

    そんなわけで、私がいま試している Mercurial 1.0 の Windows 版バイナリはこちらからどうぞ:

    Mercurial なのにコマンドが hg なのは「水銀」の元素記号だからだそうです。

    そして hg は Python で実装されているとのこと。Python は個人的にコーディングスタイルが好きではない(制御構造を可視化すること=プログラムを読みやすくすること、とは限らないですよね?)のですが、Google に限らずいたるところで重要な言語になってきたなあ、と思います。

  • CodeGear C++Builder の property

    気になったので CodeGear C++Builder 2007 で試してみました。

    // THoge.hpp
    #ifndef THogeHPP
    #define THogeHPP
    class THoge
    {
    private:
    int f_count;
    void set_count(int n);
    int get_count();
    public:
    THoge();
    ~THoge();
    void doSomething();
    // __property int count = {read = f_count, write = f_count};
    __property int count = {read = get_count, write = set_count};
    };
    #endif
    
    // THoge.cpp
    #include "THoge.hpp"
    THoge::THoge()
    {
    f_count = 0;
    }
    THoge::~THoge()
    {
    //
    }
    void THoge::doSomething()
    {
    f_count ++;
    }
    void THoge::set_count(int n)
    {
    f_count = n;
    }
    int THoge::get_count()
    {
    return f_count;
    }
    
    // Unit1.h
    // (omitted)
    private:	// ユーザー宣言
    THoge *hoge;
    // (omitted)
    
    // Unit1.cpp
    //---------------------------------------------------------------------------
    __fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner)
    {
    hoge = new THoge();
    hoge->count = 100;
    }
    //---------------------------------------------------------------------------
    void __fastcall TForm1::Button1Click(TObject *Sender)
    {
    hoge->doSomething();
    int c = hoge->count;
    AnsiString s;
    s.sprintf("hoge %d", c);
    Edit1->Text = s;
    }
    

    というようなものがちゃんと動きました。

    __property という予約語は自分で勝手に作ったクラスで使える、ということのようです。Visual C++ の CLI でも property が使えるそうですが、CodeGear だと .NET じゃない Win32 でこれが使えるわけですね。

    THoge クラスで予約語 __published: を使おうとしたらコンパイルエラーになったので、こちらは VCL 関連のクラスを継承していないとダメみたいです。

    CodeGear RAD Studio の Help にはほとんど書かれていない C++ の property 拡張ですが、ここに説明がありました:

  • 明日への遺言

    映画「明日への遺言」が封切られてヒット中だそうです。私は昨年秋に、東京国際映画祭の特別招待作品として渋谷オーチャードホールで観てきました。映画祭に行くのも初めて、舞台挨拶も初めてで、あいにくの天気でしたが、貴重な「お祭り気分」を楽しむことができました。知人がエンドロールに名前を連ねていたのも嬉しかったのですが。

    上映後、主演の藤田まことさんが挨拶の最後に「15秒や20秒でオチをつけなくてはいけない昨今、もっとゆっくりした時代に戻っていってほしい」といったことを言われました。監督の小泉堯史氏が、「来年3月の公開のときの観客動員が一番心配だ」と言っておられました。そのくらい「頑張らないと観てもらいにくい」映画であり、「頑張って多くの人に観てもらうべき」映画だと、制作者たちが自覚しているのだろう、と思って話を聞きました。

    ひたすら「語ること」で物語が進み、「語ること」だけが観客の心を動かしていく、そんな映画です。戦争に関する映画なのですが、派手なシーンはなく、特殊な状況が言葉によって淡々と描写されていきます。

    そして紡がれる言葉によって明らかになっていくのは、「法」や「組織」といったシステムの不透明で不気味な力です。「責任を取ること」を放棄した経営者や官僚たちが起こした昨今の数々の不祥事を思うと、複雑な気持ちになる。そんなことを考えながら映画館を後にしました。

    あれから数ヶ月、相変わらず「責任の取り方」については不愉快なニュースが続いています。