如何避免JFugue的MidiParser生成多余字符?
如何避免JFugue的MidiParser生成多余字符?
兄弟,我之前也踩过这个坑!那些跟着音符后面的a76、a102其实是MIDI里的**复音触后(Polyphonic Aftertouch)**事件对应的Staccato指令——a就是触后的标识,后面的数字是触后力度值。默认的StaccatoParserListener会把MIDI里所有的事件都转换成Staccato字符串,所以这些触后事件就被带进来了。
给你两个实用的解决办法:
方案一:自定义Listener过滤触后事件
最稳妥的方式是自己写一个Listener,继承默认的StaccatoParserListener,然后忽略触后相关的回调方法,这样这些事件根本不会被添加到Pattern里:public class CleanStaccatoListener extends StaccatoParserListener { @Override public void onPolyphonicAftertouch(PolyphonicAftertouch event) { // 什么都不做,直接忽略复音触后事件 } @Override public void onChannelAftertouch(ChannelAftertouch event) { // 如果你的MIDI里有通道触后事件,也一起忽略掉 } }之后修改你的解析代码,用这个自定义Listener替换默认的即可:
public String getMusicStringFromSequence(Sequence sequence) { MidiParser parser = new MidiParser(); CleanStaccatoListener listener = new CleanStaccatoListener(); parser.addParserListener(listener); parser.parse(sequence); return listener.getPattern().toString(); }方案二:正则表达式直接清理生成的字符串
要是觉得写自定义Listener有点麻烦,也可以在生成Staccato字符串后,用正则把多余的a\d+部分替换掉,这种方式更快捷:public String getMusicStringFromSequence(Sequence sequence) { MidiParser parser = new MidiParser(); StaccatoParserListener listener = new StaccatoParserListener(); parser.addParserListener(listener); parser.parse(sequence); String rawPattern = listener.getPattern().toString(); // 精准替换掉所有"a+数字"的组合 return rawPattern.replaceAll("a\\d+", ""); }放心,JFugue的Staccato语法里
a就是专门用来标识触后事件的,这个正则替换不会误删其他有效内容。
如果你的MIDI序列里本来就没有必要的触后事件,这两种方法都能完美解决问题。要是之后还需要保留其他MIDI事件,方案一的可控性会更强,因为你可以精准过滤掉不需要的事件类型。
内容来源于stack exchange
相关产品推荐
相关产品推荐

