MIDIを演奏する MCI/midiStream

MIDIを再生する場合、通常はMCI命令を使用します。 MCIとはMultimedia Control Interfaceの略で、音楽や動画を手軽に扱えるようにした命令です。

MCI命令には文字列で命令を与えるmciSendStringと、 構造体で命令を与えるmciSendCommandがあります。 ここではmciSendStringの方を書いてみます。
mciSendString

ここで使っている変数です。

mciError: LongInt; //MCIの返り値
MusicName: String; //演奏ファイル名 openの前に名前を入れておきます。

演奏方法
open命令でファイルを開いて、play命令で演奏を開始します。
mciError = mciSendString(PChar('open ' + MusicName + ' type sequencer alias midifile'), nil, 0, 0);
mciError = mciSendString(PChar('play midifile'), nil, 0, 0);
命令に成功するとmciErrorに0が入ります。失敗するとエラーコードを返します。

演奏を止める
stop命令で演奏を止めて、close命令でファイルを閉じます。
mciSendString(PChar('stop midifile'), nil, 0, 0);
mciSendString(PChar('close midifile'), nil, 0, 0);

NTとmciSendString

以上mciSendStringを駆け足で説明してみました。
この命令簡単で良いのですけど、 NT系のOSではopen命令等に時間がかかるようです。 open命令を処理している間、待ち時間が発生する事があります。
という訳で、これを何とかしてみる事にしました。
DirectX

ぱっと思いついたのがDirectX。何となく速そうでしょ?
DirectXでMIDIを演奏するのはDirectSound。これはDirectX6.1以降で対応しているようです。 (と言う事はNT4.0では動かないですね・・)

とりあえず、これで女神戦の音楽がどういう風に演奏されるのか試してみました。 ・・あれ?音色がおかしい。どうやらDirectSoundのエミュレータ上で再生されているらしい。
何かDirectXのバージョンアップで音色や仕様が変わりそうな気がする。 NT4.0では動かないし、やめておこう。
MIDI用WindowsAPI

やっぱり標準のAPIで何とかしてみよう。 で、ちょっと調べてみました。
MIDIを演奏するAPIには3種類あります。

1、MCI命令
mciSendStringやmciSendCommandの事です。 DelphiのTMediaPlayerコンポーネントもこれを使っています。

2、midiStream系API
midiStreamOpenやmidiStreamOutといったStream系APIです。

3、一つ一つのMIDIコマンドを送出して演奏する
midiOutShortMsg等使用。

1が高レベルオーディオ、2、3が低レベルオーディオとも言うようです。 高レベルオーディオを使えば割と楽に演奏できる。 低レベルオーディオは細かい演奏が可能。
低レベルオーディオの方を使えばNTでも待ち時間無しで演奏出来るようです。こちらを使ってみます。
サンプル探索

低レベルオーディオをサポートしたサンプルやコンポーネントを探してみました。
それで演奏を試してみたのですが、演奏出来ない事がありました。 調べてみた所、これはSMFのフォーマットが異なるからでした。

SMFとはStandard MIDI Fileの略で、MIDIファイルの仕様です。 SMFにはFormat 0/1/2の3種類があって、それぞれに対応していないと音が出ません。 通常Format 0/1が良く使われています。Format 3はほとんど使われないようです。

音色が違う事もありました。 これはMIDI出力を標準マッパーにすれば良い様ですね・・。

Delphi3では動かないものもありました。 Delphi5も持ってますので、こう言う時は便利です。 とりあえずのチェックは出来ますし、Delphi3で使えるように直す事も可能でしょう。

midiStreamサンプル発見

Delphiマガジン Vol.6に該当記事発見。 midiStreamの解説からサンプルまであるので、これを読めば何とかなるでしょう。

女神戦へのmidiStream組込み

サンプルはDelphi4用みたいだったからDelphi3でも動くようにする。 Format 0用だったからMIDIファイル側をFormat 0に揃える・・。 MIDI出力を標準マッパー。その他ループ処理等プログラムしてみる。

95系OSはMCIのままでも良いかな。こちらで問題なかった訳だし。
NT系をmidiStream。 これでNT系でもスムーズに演奏出来るようになりました。