色々調べていくと、Windows で音楽を正しいタイミングで再生するのは難しいという事が分かった。MIDI Player によっては、演奏エンジンを 32bit で動かすか 16bit で動かすかを選択できるものも有るくらいだ。Windows でのリアルタイム制御も興味はあるのだが、モノにするまで時間がかかりそうなので断念。別の手を考える事にした。
DECO氏が作成した DECOPLAY97 という Windows 用 MIDI Player がプラグインを開発できる事が分かった。MIDI ファイルの演奏に応じたイベントをプラグインが受け取る事が出来るので、これを解釈して IR Tower を通じて RCX にコマンドを送信すれば、MIDI ファイルを再生しながら音に応じて RCX を制御出来ることになる。早速この DECOPLAY97 を使ってみる事にしよう。
しかしプラグインは DLL で実装することになっている。テンプレートソースが付属しているが、お気楽に Spirit.ocx を使用する方法が良く分からない。OCX と格闘してみたが断念。ここは一つ気合いを入れて、Win32API を用いてシリアルで直接 RCX を制御してみよう。両方ともいしかわにとっては初めてだが、1つ1つモノにしていこう!
まずは RCX のシリアル制御だ。日本語ページを探してみたが、見つけられなかった。RCX 解析では有名な Kekoa さんの Web ページを参考にする。どうやら以下のようにすれば RCX に接続されたモータを回せる事が分かった。
コマンドは1バイト。コマンドの種類に応じて 0〜数バイトのパラメータが続く。 コマンドのヘッダとして 0x55 0xFF 0x00 を最初に送信する。 同じコマンドを示すバイトコードが2つ有る。bit3 が 0 と 1 の違いだ。 コマンドが1つ送られるたびに bit3 を反転させる。 ヘッダを除く送信データの合計の下位1バイトを チェックサムとして全てのデータの最後に送信する。 コマンド/パラメータ/チェックサムは本来のデータを送信した後 ビット反転したデータを続けて送信する。 コマンドは bit3 操作後のデータをビット反転して送信する。 送信データはコマンド[C1]パラメータ{P1]..[Pn]チェックサム[S1]とすると 以下のようになる。 0x55 0xFF 0x00 [C1] ~[C1] [P1] ~[P1] .. [Pn] ~[Pn] [S1] ~[S1] (S1 = C1 + P1 + .. + Pn) 例えばモータを全て ON する時には以下のようなデータを送信すればよい。 0x21 がコマンド、0x87 はモータ選択とON/OFF指示のパラメータ。 0x55 0xFF 0x00 0x21 0xDE 0x87 0x78 0xA8 0x57 その次にモータを全て OFF する時には以下のようなデータを送信する。 Set motor on/off コマンド(0x21/0x29)の bit3 が今度は 1 になる。 0x55 0xFF 0x00 0x29 0xD6 0x47 0xB8 0x70 0x8F シリアルのプロトコルは 2400bps / 8bit / 奇数パリティ / ストップビット1 だ。 |
コマンドのリファレンスは Kekoa さんの Opcode Reference を参照すればバッチリだ。ヘッダも変わる時もあるようなので、上の記述はあくまでモータ ON/OFF のテスト用だと思って頂きたい。これを VisualBasic を使って実装しテストした所、RCX に接続したモータを制御出来るようになった。
次は Win32API だ。まずは練習を兼ねて RCX を音源にしてみよう。送られた MIDI データを元に RCX でその音を鳴らすのだ。もちろん MIDI データでは複数のチャネルを同時に鳴らしているので、そのうちの1つだけを鳴らす事になるのだが。
ということで早速プラグインを作ってみた。IR Tower を接続した COM ポートと MIDI チャネルを指定して DECOPLAY97 で MIDI ファイルを演奏すると、RCX から指定したチャネルの音が鳴るようにした。MIDI に関する理解はさっぱりなので、あまりまともな演奏にはならない。しかし MIDI ファイルを選べば、結構けなげに RCX が音を奏でてくれる。自分で MIDI ファイルを作成してみるのも面白いかもしれない。PlayTone コマンドでは音の長さの指定を行うが、これを途中でキャンセルできなかったので、音は短い長さでポ、ポ、と鳴る。ちょっと情けない。
Note ON のみで音を出しているので、鳴らない音もある。IR は受信しているのに音が鳴らない時もあるので、プログラムを改良すればもっと良い演奏が出来るようになるだろう。どこがボトルネックになっているかを調べる必要がありそうだ。とりあえずは MIDI データと連動して RCX の制御をする道筋は出来たので、後は MIDI データをどう料理するかと、RCX へどんなコマンドを送るかが問題だ。IR の指向性をどうするかもあるな。
Win32API は初めて触ったが、なかなか面白い。VB 等に比べれば確かに面倒だが、メニューシステムなどを自分で作成する事を考えれば非常に楽だ。また一つ世界が開けたような気がする。