今日は七夕。なんで、きらきら星を演奏しますw
最近はMIDIもあまり見かけません。ちょっと寂しいですね。
とは言え、DTMではもちろん現役ですね。
Sequenceを使って、きらきら星を演奏するサンプル
MIDIできらきら星のメロディーを演奏します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 | import java.util.Arrays; import java.util.List; import javax.sound.midi.InvalidMidiDataException; import javax.sound.midi.MidiEvent; import javax.sound.midi.MidiSystem; import javax.sound.midi.Sequence; import javax.sound.midi.Sequencer; import javax.sound.midi.ShortMessage; import javax.sound.midi.Track; public class MidiPlayTest { //音符(60-69)、休符(0) private static final int C4 = 60; private static final int D4 = 62; private static final int E4 = 64; private static final int F4 = 65; private static final int G4 = 67; private static final int A4 = 69; private static final int RE = 0; public static void main(String[] args) { try (Sequencer sequencer = MidiSystem.getSequencer()) { //シーケンス・トラックを作成 Sequence sequence = new Sequence(Sequence.PPQ, 1); Track track = sequence.createTrack(); //音色を変える track.add(createMidiEvent(ShortMessage.PROGRAM_CHANGE, 0, 10, 0, 0)); //譜面 List<Integer> noteList = (List<Integer>)Arrays.asList( RE, RE, RE, RE, C4, C4, G4, G4, A4, A4, G4, RE, F4, F4, E4, E4, D4, D4, C4, RE, G4, G4, F4, F4, E4, E4, D4, RE, G4, G4, F4, F4, E4, E4, D4, RE, C4, C4, G4, G4, A4, A4, G4, RE, F4, F4, E4, E4, D4, D4, C4, RE ); // 音符イベントの作成 for(int i=0 ; i<noteList.size() ; i++) { int note = noteList.get(i); if (note != RE) { // 音符を追加 track.add(createMidiEvent(ShortMessage.NOTE_ON, 0, note, 100, i)); track.add(createMidiEvent(ShortMessage.NOTE_OFF, 0, note, 100, i + 1)); } } // シーケンサーにシーケンスをセット sequencer.open(); sequencer.setSequence(sequence); //シーケンサーで再生 sequencer.start(); while(sequencer.isRunning()) { Thread.sleep(1000); } } catch (Exception e) { e.printStackTrace(); } } //MIDIイベントの作成 private static MidiEvent createMidiEvent(int command, int channel, int data1, int data2, long tick) throws InvalidMidiDataException { ShortMessage message = new ShortMessage(); message.setMessage(command, 0, data1, data2); return new MidiEvent(message, tick); } } |
実行結果
きらきら星が演奏されます♪
せっかくなんで音色はMUSIC BOXにしてます。
なんとなく、電車が出発しそうな感じですねw
サンプルの解説
シーケンサーの取得は前回同様です。
次に出てくるのが、シーケンス。これはMIDIファイルの中身(データ構造)や楽譜だと考えるとわかりやすいですね。
Sequenceは、解像度を指定してオブジェクトを作成します。
第一引数PPQは、パルス・パー・クオーターノート。つまり、四分音符あたりでどれくらいの分解能にするかを決めたいですと言っています。
んで、その解像度が第二引数です。このサンプルでは1なので、次に進むと次の四分音符ですw
楽譜は、Sequence#createTrack()で作ったトラックに入れます。
トラックには、先ほどの次に進む(=tick)ごとに、楽器の操作に関する情報などが格納されます。
途中に出てくる、NOTE_ONが鍵盤を押す。NOTE_OFFが鍵盤から指を離す。って感じです。
また、音色の変更は、PROGRAM_CHANGEイベントでできます。この例では、10(MUSIC BOX)を指定しています。
例えば、0はピアノ。40はバイオリンです。ただしGM(General MIDI)規格の場合。このあたりはどの規格でも同じだとは思いますが、後ろの方は変わってきます。