Search code examples
javamidijavasound

Output midi file to console while being played in Java


I am trying to read a midi file and output when the note is played, the note, and velocity. This would work great but it doesn't output the data live when the note is played. The code that plays the midi:

package midistep;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;

import javax.sound.midi.MidiSystem;
import javax.sound.midi.Sequencer;

public class MidiReadAndPlay {

    public static void main(String[] args) throws Exception {
        Sequencer sequencer;
        sequencer = MidiSystem.getSequencer();
        sequencer.open();

        InputStream is = new BufferedInputStream(new FileInputStream(new File("midifile.mid")));
        sequencer.setSequence(is);
        sequencer.start();
    }
}

The code from the question I mention earlier doesn't output the data live. It just outputs it all at once. I would like it to output the sequencer data when the note is played so then it could be used later.


Solution

  • The solution to outputting the note note data in time was to add a receiver with custom code:

    public class MidiReadAndPlay {
    
        public static Receiver synthRcvr = new CustomReceiver();
        public static Transmitter seqTrans;
        public static Synthesizer synth;
        public static Sequencer sequencer;
        public static Sequence sequence;
    
        public static void main(String[] args) throws Exception {      
            sequencer = MidiSystem.getSequencer();
            sequence = MidiSystem.getSequence(new File("midi.mid"));
    
            Sequencer sequencer = MidiSystem.getSequencer();
            seqTrans = sequencer.getTransmitter();
            seqTrans.setReceiver(synthRcvr);
    
            sequencer.open(); 
            sequencer.setSequence(sequence);
    
            sequencer.start();
        }
    
    }
    

    Receiver:

    public class CustomReceiver implements Receiver {
    
        public CustomReceiver() {
    
        }
        public static final int NOTE_ON = 0x90;
        public static final int NOTE_OFF = 0x80;
        public static final String[] NOTE_NAMES = {"C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"};
    
        @Override
        public void send(MidiMessage message, long timeStamp) {
            if (message instanceof ShortMessage) {
                ShortMessage sm = (ShortMessage) message;
                System.out.print("Channel: " + sm.getChannel() + " ");
                if (sm.getCommand() == NOTE_ON) {
                    int key = sm.getData1();
                    int octave = (key / 12)-1;
                    int note = key % 12;
                    String noteName = NOTE_NAMES[note];
                    int velocity = sm.getData2();
                    System.out.println("Note on, " + noteName + octave + " key=" + key + " velocity: " + velocity);
                } else if (sm.getCommand() == NOTE_OFF) {
                    int key = sm.getData1();
                    int octave = (key / 12)-1;
                    int note = key % 12;
                    String noteName = NOTE_NAMES[note];
                    int velocity = sm.getData2();
                    System.out.println("Note off, " + noteName + octave + " key=" + key + " velocity: " + velocity);
                } else {
                    System.out.println("Command:" + sm.getCommand());
                }
            } else {
                System.out.println("Other message: " + message.getClass());
            }
        }
    
        @Override
        public void close() {
    
        }
    }