SMF スタンダードMIDIファイルをJavaで演奏します。およそ以下のような処理をします。
- 音源を出力先として取得
- SMFをシーケンスとして取得
- シーケンサーを取得
- シーケンサーにシーケンスを設定
- シーケンサーに音源の出力先を設定
- シーケンサーを開始する
今回作るもの
音源は色々なものを使うことがありますし、シーケンスもファイルから取得するとは限りません。このため上記の3以降の処理を最初に作ります。
実装
メソッドは以下のように宣言します。シーケンスと出力先を引数で指定するようにします。
public static void playMidi(Sequence sequence, Receiver receiver) {
シーケンサーを取得します。MidiSystemに問いあわせをします。このとき引数にfalseを設定するのはデフォルトの音源を設定させないためです。MidiUnavailableExceptionという例外が投げられますが実行時例外にして投げるようにします。このようにすればメソッドにthrowsの指定をせずに処理を中断することができます。
Sequencer sequencer;
try {
sequencer = MidiSystem.getSequencer(false);
} catch (MidiUnavailableException e) {
throw new IllegalStateException(e);
}
あまり起こり得ないとは思いますがシーケンサーが取得できない場合も処理を中断します。
if (sequencer == null) {
throw new IllegalStateException("can't get a Sequencer");
}
シーケンサーはopenすることによって使えるようになります。
try {
sequencer.open();
} catch (MidiUnavailableException e) {
throw new IllegalStateException(e);
}
シーケンスをシーケンサーに設定します。
try {
sequencer.setSequence(sequence);
} catch (InvalidMidiDataException e) {
throw new IllegalStateException(e);
}
シーケンサーのトランスミッターを取得します。シーケンサーの出力になります。
Transmitter seqTransmitter;
try {
seqTransmitter = sequencer.getTransmitter();
} catch (MidiUnavailableException e) {
throw new IllegalStateException(e);
}
トランスミッターに出力先を設定します。
seqTransmitter.setReceiver(receiver);
シーケンサーをスタートさせます。これで演奏が開始されます。
sequencer.start();
次回処理の1と2を実装して完成させたいと思います。
ソース
public static void playMidi(Sequence sequence, Receiver receiver) {
Sequencer sequencer;
try {
sequencer = MidiSystem.getSequencer(false);
} catch (MidiUnavailableException e) {
throw new IllegalStateException(e);
}
if (sequencer == null) {
throw new IllegalStateException("can't get a Sequencer");
}
try {
sequencer.open();
} catch (MidiUnavailableException e) {
throw new IllegalStateException(e);
}
try {
sequencer.setSequence(sequence);
} catch (InvalidMidiDataException e) {
throw new IllegalStateException(e);
}
Transmitter seqTransmitter;
try {
seqTransmitter = sequencer.getTransmitter();
} catch (MidiUnavailableException e) {
throw new IllegalStateException(e);
}
seqTransmitter.setReceiver(receiver);
System.out.println("start");
sequencer.start();
}