我正在使用Java Sequencer播放MIDI歌曲。这首歌的设计是连续循环的,我可以轻松地做到
sequencer.setLoopCount(Sequencer.LOOP_CONTINUOUSLY)
当通过内部(声卡)合成器播放时,这可以正常工作(如果需要,可以添加dummy event)循环定时点。
然而,当通过外部(USB或串行)合成器播放时,输出处的环路周围存在明显的间隙。这可以解释为.mid文件开头有很多设置事件需要一些时间通过串行线发送。
我想尝试的是将一次性设置事件隔离到他们自己的Sequence
中,当歌曲加载但被保留在主要(循环){{1}之外时,该事件被发送到设备。 }。
是否有可以区分这两种事件的简单算法(或库函数)?
需要提供:
答案 0 :(得分:3)
看看javax.sound.midi。序列由曲目组成。曲目包含MidiEvents。 MidiEvents是时间戳和MidiMessage的组合。
MidiMessage有子类ShortMessage,MetaMessage和SysexMessage。
很可能在tick 0(MidiEvent.getTick()== 0)过滤出SysexMessages就可以了。如果没有,那么尝试在刻度0处过滤MetaMessages。注意信息,程序更改等通过ShortMessages完成,不要过滤那些。
for each track in sequence {
for all midievents in track at tick 0 {
remove from track if instanceof SysexMessage or MetaMessage
}
}
另一部分是创建初始化序列。只需创建具有相同divisionType和分辨率的Sequence。一个轨道就足够了,您可以将从循环序列中删除的所有事件添加到初始化序列中的单个轨道。