Java Midi-如何在Midi';在玩什么

Java Midi-如何在Midi';在玩什么,java,midi,javax.sound.midi,Java,Midi,Javax.sound.midi,我已经找了一段时间了,但找不到我想做什么的答案 我想播放一个midi文件,并在播放时在屏幕上显示音符。当一个音符停止播放时,它应该从屏幕上消失 我可以用音序器播放midi,但不知道如何在播放时获得音符,或者何时停止播放音符 我已经研究过ControllerEventListeners和MetaEventListeners,但仍然不知道如何做到这一点 任何帮助都将不胜感激。这是一个很好的解决方案。 将您自己的接收器连接到音序器的发射器 有关示例,请参阅中的DumpReceiver。这是您应该做的:

我已经找了一段时间了,但找不到我想做什么的答案

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

我可以用音序器播放midi,但不知道如何在播放时获得音符,或者何时停止播放音符

我已经研究过ControllerEventListeners和MetaEventListeners,但仍然不知道如何做到这一点

任何帮助都将不胜感激。

这是一个很好的解决方案。
将您自己的接收器连接到音序器的发射器


有关示例,请参阅中的DumpReceiver。

这是您应该做的:

您必须实现
接收器
,然后

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;
    }
}

一种解决方案是读取midi文件,获取所有音符及其持续时间,然后运行另一个线程来显示音符吗?如果有一些延迟,这不会变得不同步吗?这已经证明是非常有用的,但是你知道如何获得一张便条的持续时间吗?我想做一个基本的midi可视化工具,当音符消失时,它会变成一个正方形。当你收到一个音符消失事件时,一个音符就会停止。我不确定我的观点是否清楚。此时,当一个音符播放时,我正在显示一个彩色方块。我已经让它消失,当我得到一个笔记的事件。我想让彩色方块随着音符的淡出慢慢淡出。我假设接收者不知道一个音符会演奏多长时间,对吗?如果是这样的话,我想我必须在播放之前读取midi文件,然后用它来计算时间。谢谢你的帮助,你真的帮了大忙。有些乐器会褪色,有些则不会。这种衰减不受音符消失时间的影响(除了由于音符消失而更快的衰减)。我现在明白了,因为MIDI需要一个音库,所以不可能知道音符是否消失。我想我仍然可以淡出颜色,如果我找到一个很好的淡出时间仪器。谢谢你的帮助。现在我有了修补程序的乐趣,也许还可以添加更多的东西,这样我就可以了解更多关于java的知识。