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