0

I am using billthefarmer/mididriver on android to play midi notes. I used this question here as the starting point. Now I can send a message to the internal android synthesizer to play a specific note on some channel with a given velocity and also to stop playing that note.

private void playNote(int noteNumber) {

        // Construct a note ON message for the specified at maximum velocity on channel 1:
        event = new byte[3];
        event[0] = (byte) (0x90 | 0x00);  // This is the channel I guess but why two hex?
        event[1] = (byte) noteNumber;  // specified note
        event[2] = (byte) 127;  // 0x7F = the maximum velocity (127)

        // Internally this just calls write() and can be considered obsoleted:
        //midiDriver.queueEvent(event);

        // Send the MIDI event to the synthesizer.
        midiDriver.write(event);

    }

    private void stopNote(int noteNumber) {

        // Construct a note OFF message for the specified note at minimum velocity on channel 1:
        event = new byte[3];
        event[0] = (byte) (0x80 | 0x00);  // again why two hex?
        event[1] = (byte) noteNumber;  // specified note
        event[2] = (byte) 0x00;  // 0x00 = the minimum velocity (0)

        // Send the MIDI event to the synthesizer.
        midiDriver.write(event);

    }

From what I can infer, these messages are sent as bytes because the midi files and signals are also binary (perhaps?). Anyway, there are some questions I couldn't sort out.

  1. How do I construct a message to change the instrument on the channel?

I found this on the web. Is this the right way to implement?

private void selectInstrument(int instrument) {

        // message to select the instrument on channel 1:
        event = new byte[2];
        event[0] = (byte)(0xC0 | 0x00); // Can't I use int 0 for channel 1?
        event[1] = (byte)instrument;

        // Send the MIDI event to the synthesizer.
        midiDriver.write(event);

    }

int instrument is General MIDI Level 1 Instrument Number.

  1. How is the synthesizer deciding which message tells it to play/stop note and which one tells it to change instrument on a channel? Is it the length of byte array?

  2. So far my app only plays a specific note based on the button pressed. If I wish to play a sequence of notes at a specific bpm. Say 180 bpm and one note per beat. I have to do all that with code? Or is there a way to feed some binary message to the synthesizer where it could play an array or sequence of specified notes at a specific rate (bpm). If so, how?

GunJack
  • 1,928
  • 2
  • 22
  • 35

1 Answers1

1

The upper four bits of the status byte specify the message type. Read the MIDI specification.

The android.media.midi package does not include a MIDI sequencer. If your MIDI messages are not generated in real time, it might be a better idea to write them to a .mid file and to tell the system to play it.

CL.
  • 173,858
  • 17
  • 217
  • 259
  • Midi Messages are not being generated in real time. Suppose I did write it into a midi file. How am I to tell the midiDriver to play this midi file? Do I pass the file as an argument to write function. – GunJack May 03 '20 at 15:29
  • That driver is a copy of Android's internal MIDI synthesizer. You should be able to use `MediaPlayer`. – CL. May 04 '20 at 08:52