You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何避免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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.07 12:43:06