シーケンサとシンセサイザー
Java Sound APIを用いてMIDIデータ(MIDIシーケンスと呼びます)を鳴らす手法です。シーケンサとシンセサイザを用います。曲はTAM MUSIC FACTORYさんから。
シーケンサとシンセサイザの関係図
シーケンサは指揮者、シンセサイザは演奏者と考えるとわかりやすいかも。シーケンサは楽譜(MIDIファイル)を見ながらデータの流れの指揮を取り、シンセサイザは実際に音を鳴らして演奏します。MIDIデータはSequenceと呼ばれます。
シーケンサの初期化
// シーケンサー private Sequencer sequencer; // シンセサイザー private Synthesizer synthesizer; private void initSequencer() { try { // シーケンサを開く sequencer = MidiSystem.getSequencer(); sequencer.open(); // メタイベントリスナーを登録 sequencer.addMetaEventListener(this); // シーケンサとシンセサイザーの接続 if (!(sequencer instanceof Synthesizer)) { // J2SE 5.0用 // シンセサイザーを開く synthesizer = MidiSystem.getSynthesizer(); synthesizer.open(); Receiver synthReceiver = synthesizer.getReceiver(); Transmitter seqTransmitter = sequencer.getTransmitter(); seqTransmitter.setReceiver(synthReceiver); } else { // J2SE 1.4.2以前 // シーケンサとシンセサイザーは同じ synthesizer = (Synthesizer) sequencer; } } catch (MidiUnavailableException e) { e.printStackTrace(); } }
MIDIシーケンスのロード
// MIDIファイルデータ(名前->Sequence) private HashMap<String, Sequence> midiMap; public void load(String name, String filename) { ・・・ try { // MIDIファイルをロード Sequence seq = MidiSystem.getSequence( getClass().getResource(filename)); // 登録 midiMap.put(name, seq); } catch (InvalidMidiDataException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } }
MIDIシーケンスの再生
public void play(String name) { ・・・ // 現在再生中のシーケンスを停止する stop(); // 名前に対応するMIDIを取得 Sequence seq = midiMap.get(name); // MIDIシーケンス if (sequencer != null && seq != null) { try { sequencer.setSequence(seq); // シーケンサにセット sequencer.start(); // 再生開始! currentSequenceName = name; } catch (InvalidMidiDataException e) { e.printStackTrace(); } } }
ループ処理
// 再生終了メタイベント private static final int END_OF_TRACK = 47; public void meta(MetaMessage meta) { // 再生が終了した場合 if (meta.getType() == END_OF_TRACK) { if (sequencer != null && sequencer.isOpen()) { // MIDIシーケンス再生位置に戻す sequencer.setMicrosecondPosition(0); // 最初から再生 sequencer.start(); } } }