Java Midi - Как получать заметки из миди во время воспроизведения

Я искал некоторое время и не могу найти ответ на то, что я хочу сделать.

Я хочу воспроизвести миди-файл и отображать ноты на экране во время воспроизведения. Когда нота перестает воспроизводиться, она должна исчезнуть с экрана.

Я могу играть миди с секвенсором, но понятия не имею, как получить ноты, которые он играет, или когда он перестает воспроизводить ноты.

Я изучил ControllerEventListeners и MetaEventListeners, но до сих пор не знаю, как это сделать.

Любая помощь будет оценена по достоинству.


person pandagoespoop    schedule 08.10.2014    source источник
comment
Будет ли одно из решений читать миди-файл, получать все заметки и их продолжительность, а затем запускать другой поток для отображения заметок? Не будет ли это рассинхронизировано, если есть некоторая задержка?   -  person pandagoespoop    schedule 09.10.2014


Ответы (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;
    }
}
person JFValdes    schedule 20.03.2017

Это часто задаваемые вопросы.
Подключите свой приемник к передатчику секвенсора.

В качестве примера см. DumpReceiver в MidiPlayer.

person CL.    schedule 09.10.2014
comment
Это оказалось очень полезным, но знаете ли вы, как получить продолжительность ноты? Я хочу сделать базовый миди-визуализатор, который будет исчезать квадратом по мере исчезновения ноты. - person pandagoespoop; 30.10.2014
comment
Заметка останавливается, когда вы получаете событие выключения заметки. - person CL.; 30.10.2014
comment
Я не уверен, что ясно изложил свою точку зрения. На данный момент я показываю цветной квадрат, когда играет нота. Я сделал, чтобы он исчезал, когда я получаю заметку о событии. Я хотел бы, чтобы цветной квадрат медленно исчезал по мере исчезновения ноты. Буду ли я прав, если предположу, что Получатель не знает, как долго будет играть нота? Если это так, я думаю, что мне придется как-то прочитать миди-файл перед воспроизведением и использовать его для расчета времени. Спасибо за вашу помощь, вы действительно помогли. - person pandagoespoop; 30.10.2014
comment
Есть инструменты, которые исчезают, и те, которые не исчезают. На это затухание не влияет время события note-off (за исключением гораздо более быстрого затухания из-за отключения ноты). - person CL.; 30.10.2014
comment
Теперь я понимаю, поскольку MIDI нуждается в звуковом банке, невозможно узнать, затухает ли нота. Думаю, я все еще мог бы смягчить цвет, если бы нашел инструмент с хорошим временем затухания. Спасибо за твою помощь. Теперь у меня есть забавная часть возиться с моей программой и, возможно, добавлять что-то еще, чтобы я мог больше узнать о java. - person pandagoespoop; 30.10.2014