Mabinogi MML Emulatorについて

このプログラムは以下の4つのプログラムを使用して実装しています。 まず、LZMAで圧縮されたmusic.jsonに含まれる音楽データーをlzma.jsで解凍し、フォームにデーターを展開します。 次に、PSGConverter.jsでMIDIに変換し、それをsmfplayer.jsを用いて再生します。 smfplayer.jsは、あらかじめ読み込んでおいたsf2synth.jsをIFRAME越しに叩きここで音が鳴ります。

MML→MIDI変換プログラム(PSGConverter.js)について

これは2007年頃、私がネット上に存在したプログラムを参考に作ったプログラムで、MMLをMIDIデーターに変換します。 仕組みとして、MMLデーターを正規表現で命令単位に分解し、それをMIDIデーターに変換し出力します。

ここで生成されたMIDIデーターは、dataスキーマ(アドレスがdata:audio/midi;base64,AZ65...という感じになる。ファイルをURLに埋め込むものと考えてください。)で出力され、 これをQuickTimeプラグインなどで再生することが本来の使い方です。しかし、最近QuickTimeがMIDIを認識しなくなったため、今回のプログラムを作ることにしました。

lzma.jsについて

これは、nmrugg氏の作ったJavaScriptによるLZMA圧縮/解凍プログラムです。LZMAは7zで使われていることで有名なもので負荷はかかるものの最も圧縮率が高い圧縮アルゴリズムです。 今回は、フォームのデーターを保存するのに使用しました。ロスが多いですがフォーム内のデーターをサニタイズしたものをLZMAで圧縮し、MMLを読み込むときこのデーターを読み込むことで、データーサイズを節約しました。 ポイントとして、Web Workerという技術を使用しています。これは、バックグラウンドで処理を行うことによりブラウザをロックさせることなく実行されるため、複数に同時進行で処理を実行することができます。

もっとも、今回使用されてるプログラムでは、大した容量はないため体感上気になることはありません。

smfplayer.js、sf2synth.js

これらは、今年(2013年)の5月ごろGreeのImaya氏の作ったライブラリで、SMFをサウンドフォントを用いて再生するライブラリです。 大きく分けて、サウンドフォントを解析し鳴らすsf2synth.jsと、MIDIデーターを解析するsmfplayer.jsの2つからできており、Web MIDI Linkと呼ばれる技術を用いてこの2つをつないでいます。 Web MIDI Linkとは、去年の6月ごろにg200kg氏が提唱した規格で、JavaScriptのwindow.postMessage()命令を利用したWeb上でMIDIデーターをやり取りするためのものです。 今回、MIDIプレイヤー部分はほぼ、サンプルのソースをベタ移植して作りました。

いずれも、HTML5のHTML5 Audio APIをフルに生かして作っているため、Webkit系以外のブラウザでは動作しません。

苦労した点

MMLからMIDIに変換するプログラムはかけていたので、問題なのはどうやってsmfplayer.jsに読み込ませるかというところでした。 smfplayer.jsは、ajaxでMIDIファイルをarrayBuffer配列というデーター形式にして読み込む方式だったので、dataスキーマで生成されたMIDIファイルを直接読んでくれません。 このdataスキーマをarrayBufferに変換する処理でかなり躓きました。

結局、Googleで検索したところ、gistでconvertDataURIToBinaryという関数を作ってあるのを見かけ、これを用いてarrayBuffer配列に変換しました。これにより変換したMIDIが無事再生されるようになりました。

次に躓いたのは、曲の終了の検知です。 再生中の曲が終了したら、次の曲を再生するという実装が望ましい動きです。 しかし、smfplayer.jsは、現在再生している曲の位置を調べる関数はありますが、曲の終了時の位置を調べる関数がありません。 幸い、曲の位置を調べる関数は、曲の末尾に行き演奏が止まると、この値は変化しません。 この性質を利用して、別途2つのインターバル関数を用意し、この曲の位置を調べる関数の値が変化しなくなったかを調べます。 あとは、その時に次の曲がかかるようにするだけです。ここは、結構苦労しました。

制限事項

エミュレーターなので実機と異なる動作をすることがいくつかあります。

空白のトラックが含まれるMMLを正常に再生できない。
MML@aaaa,bb,,;のようなMMLは再生できません。休符でもいいので必ずなにかノートを入れるようにしてください。(例:MML@aaaa,bb,r,;
打楽器の2トラック目が再生されない
オリジナルのMMLはメロディトラックが再生された後、和音2のトラックの演奏時間の分だけ和音1のトラックが再生されますが、そのような処理は本プログラムに含まれておらず、単純にメロディトラックの後で和音1のトラックが再生されるようになっています。 このため、和音2の内容は無視されます。なお、シロフォンはオリジナルと同じように音階のある打楽器として処理されます。
ロンカドーラの音階がおかしい
本プログラムは、MSXSprit.dlsをSF2に変換したものを使用して再生しています。 ロンカドーラは、同じオクターブ領域に異なる音を同時に鳴らすことで独特の味を出していますが、SFでの変換がうまくいかなかったため、このようになっています。

今回使用したもの

なお、このプログラムに含まれるMMLはすべて、私の自作です。


[ 戻る ]