1

我已经搜索了一段时间,但找不到我想做的事情的答案。

我想播放一个 MIDI 文件,并在播放时在屏幕上显示音符。当一个音符停止播放时,它应该会从屏幕上消失。

我可以用音序器演奏 MIDI,但不知道如何让音符播放,或者何时停止播放音符。

我已经研究了 ControllerEventListeners 和 MetaEventListeners,但仍然不知道该怎么做。

任何帮助,将不胜感激。

4

2 回答 2

2

这就是你应该做的:

你必须实施Receiver然后

sequencer = MidiSystem.getSequencer();
sequencer.open();
transmitter = sequencer.getTransmitter();
transmitter.setReceiver(this);

之后,每次发生事件时都会触发下一个方法:

@Override
public void send(MidiMessage message, long timeStamp) {
    if(message instanceof ShortMessage) {
        ShortMessage sm = (ShortMessage) message;
        int channel = sm.getChannel();

        if (sm.getCommand() == NOTE_ON) {

            int key = sm.getData1();
            int velocity = sm.getData2();
            Note note = new Note(key);
            System.out.println(note);

        } else if (sm.getCommand() == NOTE_OFF) {

            int key = sm.getData1();
            int velocity = sm.getData2();
            Note note = new Note(key);
            System.out.println(note);
        } else {
            System.out.println("Command:" + sm.getCommand());
        }
    }
}

如果你愿意,你也可以使用这个类:

public class Note {

    private static final String[] NOTE_NAMES = {"C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"};

    private String name;
    private int key;
    private int octave;

    public Note(int key) {
        this.key = key;
        this.octave = (key / 12)-1;
        int note = key % 12;
        this.name = NOTE_NAMES[note];
    }

    @Override
    public boolean equals(Object obj) {
        return obj instanceof Note && this.key == ((Note) obj).key;
    }

    @Override
    public String toString() {
        return "Note -> " + this.name + this.octave + " key=" + this.key;
    }
}
于 2017-03-20T21:41:18.617 回答
1

这是一个常见问题解答
将您自己的 Receiver 连接到音序器的 Transmitter。

有关示例,请参见 MidiPlayer 中的DumpReceiver

于 2014-10-09T07:34:49.533 回答