0

在 jFugue 4.0 中有一个很好的功能:Transforming Patterns with PatternTransformer

但在 jFugue 5.0 中删除了所有模式转换器。我知道它必须用很酷的东西代替。但是请在 jFugue 5.0 中做什么?我不知道。我用谷歌搜索,但到目前为止还没有结果。

4

1 回答 1

1

“PatternTransformer”类已经消失,但转换模式从未如此简单!

在旧版本的 JFugue 中,PatternTransformer 和 ParserListener 之间实际上几乎没有区别。旧版本的 JFugue 也提到了 PatternTool,它就像一个 Transformer,但不是转换一个模式,它只是测量它;例如,您可以编写一个工具来告诉您乐曲中使用了哪些乐器。

要在 JFugue 中转换模式,只需创建一个实现 ParserListener(或扩展 ParserListenerAdapter)的类,并将其作为侦听器添加到解析器 - 例如 StaccatoParser:

例如,这是一个查找乐曲中使用的乐器的工具:

public class InstrumentTool extends ParserListenerAdapter 
{
    private List<String> instrumentNames;

    public InstrumentTool() {
        super();
        instrumentNames = new ArrayList<String>();
    }

    @Override
    public void onInstrumentParsed(byte instrument) {
        String instrumentName = MidiDictionary.INSTRUMENT_BYTE_TO_STRING.get(instrument);
        if (!instrumentNames.contains(instrumentName)) {
            instrumentNames.add(instrumentName);
        }

    }

    public List<String> getInstrumentNames() {
        return this.instrumentNames;
    }
}

以下是如何使用它:

MidiParser midiParser = new MidiParser();
InstrumentTool instrumentTool = new InstrumentTool();
midiParser.addParserListener(instrumentTool);
midiParser.parse(MidiSystem.getSequence(new File("filename")));
List<String> instrumentNames = instrumentTool.getInstrumentNames();
for (String name : instrumentNames) {
    System.out.println(name);
}

JFugue 5 中有一个新类可以让您将 ParserListener 链接在一起。这将允许您创建一个侦听器链,每个侦听器在将事件发送到链中的下一个侦听器之前修改一个模式。例如,假设您有一个模式,并且您想要转换所有乐器(例如,将 GUITAR 更改为 PIANO);然后你想记下任何用 PIANO 弹奏的音符并将其持续时间延长 2 倍;那么你想记下任何一个新的持续时间大于 2.0(两个全音符)的音符,并且你想改变它的八度。有点疯狂的例子,但它表明需要“链接”系列的解析器侦听器。

这是一个使用链接的演示示例。这个类读取一个 MIDI 模式;然后它会更改所有乐器,然后从原始 MIDI 创建一个断奏模式。

public class ChainingParserListenerDemo {
    public static void main(String[] args) throws InvalidMidiDataException, IOException {
        MidiParser parser = new MidiParser();
        InstrumentChangingParserListener instrumentChanger = new InstrumentChangingParserListener();
        StaccatoParserListener staccatoListener = new StaccatoParserListener();
        instrumentChanger.addParserListener(staccatoListener);
        parser.addParserListener(instrumentChanger);
        parser.parse(MidiSystem.getSequence(new File("filename")));
        System.out.println("Changed "+instrumentChanger.counter+" Piano's to Guitar! "+ staccatoListener.getPattern().toString());
    }
}

class InstrumentChangingParserListener extends ChainingParserListenerAdapter {
    int counter = 0;

    @Override 
    public void onInstrumentParsed(byte instrument) {
        if (instrument == MidiDictionary.INSTRUMENT_STRING_TO_BYTE.get("PIANO")) {
            instrument = MidiDictionary.INSTRUMENT_STRING_TO_BYTE.get("GUITAR");
            counter++;
        }
        super.onInstrumentParsed(instrument);
    }
}
于 2017-06-30T04:57:44.310 回答