Java | MIDI Introduction
The Musical Instrument Digital Interface (MIDI) standard defines a communication protocol for electronic music devices, such as electronic keyboard instruments and personal computers. MIDI data can be transmitted over special cables during a live performance, and can also be stored in a standard type of file for later playback or editing.
A midi file contains data that represents music in terms of events. Each event gives a description of the musical note to be played – duration, pitch, velocity, channel etc. The Package javax.sound.midi provides interfaces and classes for I/O, sequencing, and synthesis of MIDI data.
MIDI is both a hardware specification and a software specification.
The javax.sound.midi package is used to create and use midi events to produce a simple soundtrack in Java.
Java Sound API’s Representation of MIDI Device
- MidiDevice Interface : The MidiDevice interface includes an API for opening and closing a device. It also includes an inner class called MidiDevice.Info that provides textual descriptions of the device, including its name, vendor, and version.
- Transmitters and Receivers : The way a device sends data is via one or more transmitter objects that it “owns.” Similarly, the way a device receives data is via one or more of its receiver objects. The transmitter objects implement the Transmitter interface, and the receivers implement the Receiver interface.
Each transmitter can be connected to only one receiver at a time, and vice versa
Essential components of a Midi system
- Synthesizer: This is the device that plays the midi soundtrack. It can either be a software synthesizer or a real midi compatible instrument.
- Sequencer: A sequencer takes in Midi data(via a sequence) and commands different instruments to play the notes. It arranges events according to start time, duration and channel to be played on.
- Channel: Midi supports upto 16 different channels. We can send off a midi event to any of those channels which are later synchronized by the sequencer.
- Track: It is a sequence of Midi events.
- Sequence: It is a data structure containing multiple tracks and timing information.The sequencer takes in a sequence and plays it.
Important classes and methods
- MidiSystem: This class provides access to installed MIDI resources like sequencers, synthesizers, I/O ports. All methods are static and this class can’t be instantiated.
- MidiSystem.getSequencer() – returns an instance of the sequencer interface which is connected to a synthesizer/receiver.
- sequencer.open() – opens the sequencer so it can acquire system resources.
- sequencer.setSequence(Sequence sequence) – Sets the current sequence on which the sequencer operates.
- sequencer.setTempoInBPM(float bpm) – Sets the playback tempo in beats per minute.
- sequencer.start() – Starts playback of the MIDI data in the currently loaded sequence.
- sequencer.isRunning() – Indicates whether the Sequencer is currently running.
- Sequence – The Sequence class instance holds a data structure representing one or more tracks and timing information.
- Sequence.PPQ – Tempo based timing type, for which the resolution is expressed in pulses (ticks) per quarter note.
- Sequence.createTrack() – Creates an empty track
- Track – Class containing midi events arranged chronologically.
- Track.add(MidiEvent event) – Adds a new event to the track.
- MidiEvent(MidiMessage message, long tick) – A midi event object that contains a time stamped midi message.
- ShortMessage() – A ShortMessage object with at most two data bytes (Extended from MidiMessage).
- ShortMessage.setMessage(int command, int channel, int data1, int data2) – sets a ShortMessage object that has at most two data bytes (data1 and data2).
|144||Note On Event|
|128||Note Off Event|
|192||Program Change for changing default instrument etc|
|176||Control change for sending events|
Below programs illustrate the usage of MIDI in Java:
Program 1: Illustrating the implementation of a simple record.
Input: Enter the number of notes to be played: 15 Output: 15 sound notes with increasing pitch are played Input: Enter the number of notes to be played: 25 Output: 25 sound notes with increasing pitch are played (Note: Number of notes should not exceed 31 for reasons cited later)
Why is the number of notes limited to 31?
Since data1 and data2 fields of ShortMessage are of byte type, while using setMessage(int command, int channel, int note, int velocity), note and velocity must not exceed 127.
Program 2: Using command code 192 to change the instrument type
Input : Enter the instrument to be played 102 Enter the note to be played 110 Output : Sound note is played Input : Enter the instrument to be played 40 Enter the note to be played 100 Output : Sound note is played
NOTE: The code won’t run on online IDE since the code requires a few seconds of runtime for playback which IDE won’t permit.