SewiGの日記
2005-12-20 [火] [長年日記]
■ [Java][Programming] JavaでSMF (3)
MIDIイベントの作成は前回登場したMidiEventを自分でいくらでも作ればいいだけです。
で、再生ですがこれがけっこう面倒です。方法はいくつかあります。
1. 独自に実装する
動的なデータ変更に対応できて便利なのですが、Win32 + JavaVM環境ではSystem#currentTimeMillisの性能が恐ろしく悪いのであまりオススメできません。とはいえ、J2SE 5.0になってからSystem#nanoTimeが使えるようになってかなり精度が良くなりました。もし独自実装にするにしても、以下のようにループさせるのではなくタイマを使用したほうが、楽で見やすくて良いと思われます。音色ですが、デフォルトではJava Sound Synthesizerで演奏されます。これはSoundbankを変更することでより豪華な音色に変更できますし、指定したMIDIデバイスにも送信できます。
→ソースコード (MIDIPlayer.java, Note.java)
以下にソースコードの要所を示しておきます。
int TPQN = 480;
int BPM = 120;
int TPS = TPQN * (BPM / 60);
long interval = 1000000000L / TPS;
long offset = System.nanoTime();
long startTime = offset;
long d;
for (;;) {
while ((d = System.nanoTime()) - offset < interval) {
try {
NANOSECONDS.sleep(1L);
} catch (InterruptedException e) {
}
}
offset = d;
// ここに割り込みが入ったときの処理を書く。
// ちなみに、Tickとナノ秒の変換は以下のようにする。誤差は無視しています。
// long t = (long)((double)TPS / 1000000000L * (d - startTime));
}
さらに1の方法でシーケンスをQuickTimeで鳴らしたソースコードです。それにしても、JavaでQuickTimeを扱った日本語の資料が少なすぎです。Windowsなら「C:\Program Files\QuickTime\QTSystem\QTJava.zip」をCLASSPATHに追加してください。
→ソースコード (QTMIDIPlayer.java, Note.java)
2. javax.sound.midi.Sequencerを使用する
これはすごく楽ですし、パフォーマンスも悪くないです。再生させると制御が戻ってこなくなるので再生用にThreadを作るといいでしょう。よほど細かい制御を行わないかぎりjavax.sound.midi.Sequencerで事足りると思います。
→ソースコード (SequencePlayer.java)
3. JMFを使用する
ほとんど2の方法と同様に使用できます。JMFは様々なメディアに対応していてとても汎用的です。ダウンロードはhttp://java.sun.com/products/java-media/jmf/
→ソースコード (JMFPlayer.java)
aaa hotel discounts missouri
aaa hotel discounts missouri