拥有这个有效的简单代码(但在我用 ^-c 终止它之前永远不会结束):
import javax.sound.midi.*;
public class Foo {
public void play(int instrument, int note) {
try {
Sequencer player = MidiSystem.getSequencer();
player.open();
Sequence seq = new Sequence(Sequence.PPQ, 4);
Track track = seq.createTrack();
ShortMessage first = new ShortMessage();
first.setMessage(192, 1, instrument, 0);
MidiEvent changeInstrument = new MidiEvent(first, 1);
track.add(changeInstrument);
ShortMessage a = new ShortMessage();
a.setMessage(144, 1, note, 100);
MidiEvent noteOn = new MidiEvent(a, 1); //fired on "tick 1"
track.add(noteOn);
ShortMessage b = new ShortMessage();
b.setMessage(128, 1, note, 100);
MidiEvent noteOff = new MidiEvent(b, 8); //fired on "tick 8"
track.add(noteOff);
player.setSequence(seq);
player.start();
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
Foo foo = new Foo();
foo.play(0, 42);
}
}
noteOn
MidiEvent
被触发(构造函数的1 tick
第二个参数MidiEvent
)。被noteOff
MidiEvent
触发8 tick
,这意味着。应该有 7 个刻度跨度。但我永远看不到结束(程序结束)。从 cmd 触发时,提示永远不会返回,除非我强制终止进程(使用<ctrl-c>
)。这是为什么?Sequencer 何时结束,程序何时结束?
编辑:可能是因为打开了 Sequencer,但没有关闭它。所以我想在最后关闭它,但它不能立即跟随player.start()
语句,否则它会立即结束。所以肯定有一些延迟。虽然这是笨重的解决方案
...
player.setSequence(seq);
player.start();
TimeUnit.SECONDS.sleep(3);
player.close();
之后,提示返回。但是有更好的解决方案吗?