简体   繁体   中英

How to look ahead to next event in Midi Sequence

We are trying to code a simple guitar hero clone for university using javax.sound.midi.

Currently we can play back a midi file with a sequencer and log the midi event that is currently played. However, we want to display the upcoming event (more specifically, the the data bytes in the MIDI message that indicate the note).

We are currently using a Sequencer to play the sounds and a Receiver and that logs the sound to the console. However, it logs it the exact moment the sound is played, not the upcoming sound.

In Sequencer class:

public void startSequencer() {
    try {
        sequencer.open();
        Thread.sleep(2000);
        sequencer.setTempoInBPM(BPM);
        InputStream is = new BufferedInputStream(new FileInputStream(song));
        sequencer.setSequence(is);
        sequencer.getTransmitter().setReceiver(receiver);

        sequencer.start();

        while (sequencer.isRunning()) {
            Thread.sleep(100);
        }
        sequencer.close();

        System.out.println(receiver.getNoteOnAmount());

    } catch (MidiUnavailableException | InterruptedException | IOException | InvalidMidiDataException e) {
        throw new RuntimeException(e);
    }
}

In Receiver class:

public void send(MidiMessage message, long timeStamp) {
    //If the Status is NOTE_ON (144), process the note
    if (message.getStatus() == 144) {
        System,out.println(message.getMessage()[1]);
    }

Retrieve the Sequence from the Sequencer using Sequencer.getSequence() .

All the MidiEvents from the Midi file are stored in one or more Track instances within the Sequence . A MidiEvent is a MidiMessage with a tick position. MidiEvents are ordered by tick position.

So in your Receiver.send(MidiMessage) method, search the tracks to find the MidiEvent which corresponds to the received MidiMessage .

If you have only one track and find the corresponding MidiEvent at index meIndex /tick meTick , then the next MidiEvents to be played are at meIndex+1 , meIndex+2 etc. If you have several tracks, you also need to search other tracks for MidiEvents whose tick position is right after meTick .

Of course there is plenty of room for optimization (eg preprocess Tracks in advance), so that you don't spend time reparsing all the Tracks each time you receive a note.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM