Open In App

Java | MIDI Introduction

Introduction:

Java MIDI is a set of Java APIs for handling musical data and MIDI (Musical Instrument Digital Interface) devices. These APIs allow Java programs to access and manipulate MIDI data, and can be used to create applications such as music players, synthesizers, and more. The Java Sound API, which includes the MIDI package, provides a low-level, platform-independent interface to audio devices and MIDI devices.

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

 



 

Essential components of a Midi system

 

 

Important classes and methods

 

 

MIDI Commands

 

Code Command
144 Note On Event
128 Note Off Event
192 Program Change for changing default instrument etc
176 Control change for sending events
224 Pitch Bend

Below programs illustrate the usage of MIDI in Java: 
Program 1: Illustrating the implementation of a simple record.
 




// Java program showing the implementation of a simple record
import javax.sound.midi.*;
import java.util.*;
 
public class MyMidiPlayer {
 
    public static void main(String[] args)
    {
 
        System.out.println("Enter the number of notes to be played: ");
        Scanner in = new Scanner(System.in);
        int numOfNotes = in.nextInt();
 
        MyMidiPlayer player = new MyMidiPlayer();
        player.setUpPlayer(numOfNotes);
    }
 
    public void setUpPlayer(int numOfNotes)
    {
 
        try {
 
            // A static method of MidiSystem that returns
            // a sequencer instance.
            Sequencer sequencer = MidiSystem.getSequencer();
            sequencer.open();
 
            // Creating a sequence.
            Sequence sequence = new Sequence(Sequence.PPQ, 4);
 
            // PPQ(Pulse per ticks) is used to specify timing
            // type and 4 is the timing resolution.
 
            // Creating a track on our sequence upon which
            // MIDI events would be placed
            Track track = sequence.createTrack();
            .
 
                // Adding some events to the track
                for (int i = 5; i < (4 * numOfNotes) + 5; i += 4)
            {
 
                // Add Note On event
                track.add(makeEvent(144, 1, i, 100, i));
 
                // Add Note Off event
                track.add(makeEvent(128, 1, i, 100, i + 2));
            }
 
            // Setting our sequence so that the sequencer can
            // run it on synthesizer
            sequencer.setSequence(sequence);
 
            // Specifies the beat rate in beats per minute.
            sequencer.setTempoInBPM(220);
 
            // Sequencer starts to play notes
            sequencer.start();
 
            while (true) {
 
                // Exit the program when sequencer has stopped playing.
                if (!sequencer.isRunning()) {
                    sequencer.close();
                    System.exit(1);
                }
            }
        }
        catch (Exception ex) {
 
            ex.printStackTrace();
        }
    }
 
    public MidiEvent makeEvent(int command, int channel,
                               int note, int velocity, int tick)
    {
 
        MidiEvent event = null;
 
        try {
 
            // ShortMessage stores a note as command type, channel,
            // instrument it has to be played on and its speed.
            ShortMessage a = new ShortMessage();
            a.setMessage(command, channel, note, velocity);
 
            // A midi event is comprised of a short message(representing
            // a note) and the tick at which that note has to be played
            event = new MidiEvent(a, tick);
        }
        catch (Exception ex) {
 
            ex.printStackTrace();
        }
        return event;
    }
}

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 
 




// Java program showing how to change the instrument type
import javax.sound.midi.*;
import java.util.*;
 
public class MyMidiPlayer1 {
 
    public static void main(String[] args)
    {
 
        MyMidiPlayer1 player = new MyMidiPlayer1();
 
        Scanner in = new Scanner(System.in);
        System.out.println("Enter the instrument to be played");
        int instrument = in.nextInt();
        System.out.println("Enter the note to be played");
        int note = in.nextInt();
 
        player.setUpPlayer(instrument, note);
    }
 
    public void setUpPlayer(int instrument, int note)
    {
 
        try {
 
            Sequencer sequencer = MidiSystem.getSequencer();
            sequencer.open();
            Sequence sequence = new Sequence(Sequence.PPQ, 4);
            Track track = sequence.createTrack();
 
            // Set the instrument type
            track.add(makeEvent(192, 1, instrument, 0, 1));
 
            // Add a note on event with specified note
            track.add(makeEvent(144, 1, note, 100, 1));
 
            // Add a note off event with specified note
            track.add(makeEvent(128, 1, note, 100, 4));
 
            sequencer.setSequence(sequence);
            sequencer.start();
 
            while (true) {
 
                if (!sequencer.isRunning()) {
                    sequencer.close();
                    System.exit(1);
                }
            }
        }
        catch (Exception ex) {
 
            ex.printStackTrace();
        }
    }
 
    public MidiEvent makeEvent(int command, int channel,
                               int note, int velocity, int tick)
    {
 
        MidiEvent event = null;
 
        try {
 
            ShortMessage a = new ShortMessage();
            a.setMessage(command, channel, note, velocity);
 
            event = new MidiEvent(a, tick);
        }
        catch (Exception ex) {
 
            ex.printStackTrace();
        }
        return event;
    }
}

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.

Advantages Or Disadvantages:
 Advantages of Java MIDI:

  1. Cross-platform compatibility: Java MIDI works on any platform that has a Java Virtual Machine, making it a portable solution.
  2. High-level API: Java MIDI provides a high-level API, which makes it easier to work with MIDI data compared to the low-level MIDI API.
  3. Large developer community: Java has a large developer community, which makes it easier to find support and resources when working with Java MIDI.

Disadvantages of Java MIDI:

  1. Performance: Java MIDI may not perform as well as native MIDI implementations, particularly when it comes to real-time performance.
  2. Limited device support: Java MIDI may not support all the features of a particular MIDI device, as the API is designed to be platform-independent.
  3. Complexity: Java MIDI can be complex to work with, especially for developers who are not familiar with the Java Sound API.

Article Tags :