import javax.sound.midi.MetaEventListener; import javax.sound.midi.MetaMessage; import javax.sound.midi.MidiChannel; import javax.sound.midi.MidiEvent; import javax.sound.midi.MidiSystem; import javax.sound.midi.MidiUnavailableException; import javax.sound.midi.InvalidMidiDataException; import javax.sound.midi.Sequence; import javax.sound.midi.Sequencer; import javax.sound.midi.ShortMessage; import javax.sound.midi.Soundbank; import javax.sound.midi.Synthesizer; import javax.sound.midi.Track; import java.io.File; import java.io.IOException; /** * The {@code StdMidi} class provides easy-to-use static methods for playing * musical notes in real time using MIDI. It also supports reading and writing * audio files in the MIDI format. * The Musical Instrument Digital Interface (MIDI) standard * is a communication protocol that allows computers, musical instruments, and * other hardware to communicate. * {@code StdMidi} is built on top of * Java's Sound API, * a powerful framework for audio playback, recording, mixing, MIDI synthesis, and more. * The goal is to make real-time MIDI synthesis accessible to novice programmers. * Advanced features of MIDI (such as sequencing or multiple instruments at the same time) * are beyond the scope of this library. *
* Getting started. * To use this class, you must have {@code StdMidi} in your Java classpath. * Here are three possible ways to do this: *
* As a test, cut-and-paste the following short program into your editor: *
* public class AxelF {
StdMidi.setInstrument(StdMidi.SYNTH_BASS_1);
StdMidi.setTempo(220);
int[] pitches1 = { F4, REST, AF4, REST, F4, F4, BF4, F4, EF4 };
double[] beats1 = { QN, QN, QN, EN, QN, EN, QN, QN, QN };
int[] pitches2 = { F4, REST, C5, REST, F4, F4, DF5, C5, AF4 };
double[] beats2 = { QN, QN, QN, EN, QN, EN, QN, QN, QN };
int[] pitches3 = { F4, C5, F5, F4, EF4, EF4, C4, G4, F4, REST };
double[] beats3 = { QN, QN, QN, EN, QN, EN, QN, QN, DQN, WN };
for (int i = 0; i < pitches1.length; i++)
StdMidi.playNote(pitches1[i], beats1[i]);
for (int i = 0; i < pitches2.length; i++)
StdMidi.playNote(pitches2[i], beats2[i]);
for (int i = 0; i < pitches3.length; i++)
StdMidi.playNote(pitches3[i], beats3[i]);
* }
* }
*
* * If you compile and execute the program, you should hear the first few notes of * the electronic instrumental track Axel F by Harold Faltermeyer. * *
* Playing pitched instruments. * You can use the following method to play an individual MIDI note with a given pitch:: *
* The MIDI note number is an integer between 0 and 127 (60 = Middle C) * that specifies the pitch. * The method plays the specified note for the specified duration (measured in beats). * The special pitch {@code StdMidi.REST} corresponds to a rest. * A rest has a duration but produces no sound. * *
* Playing unpitched percussion instruments. * Unpitched instruments are not tuned to identifiable frequencies. * You can use the following method to play unpitched percussion instruments * (such as drums and cymbals): *
* The method plays the specified percussive instrument for the specified * duration (measured in beats). * The {@code percussionInstrument} is an integer between 35 (acoustic bass drum) * and 81 (open triangle). * *
* Durations. * The durations are measured in beats, with one beat corresponding to a quarter note. * The length of a beat is determined by the tempo, which is measured in * beats per minute. The default tempo is 120 beats per minute, * so each beat (or quarter note) lasts 0.5 seconds. *
* There are a number of predefined constants for common tempos, ranging from * {@code StdMidi.LARGHISSIMO} (20 beats per minute) to * {@code StdMidi.PRESTISSIMO} (200 beats per minute). * You can set the tempo using the method: *
* The {@code StdMidi} class provides predefined constants for * standard musical durations (measured in beats), including * {@code StdMidi.QUARTER_NOTE} (1 beat), * {@code StdMidi.HALF_NOTE} (2 beats), * {@code StdMidi.WHOLE_NOTE} (4 beats), * {@code StdMidi.EIGHTH_NOTE} (1/2 beat), and * {@code StdMidi.SIXTEENTH_NOTE} (1/4 beat). * For brevity, you can also use * {@code StdMidi.QN}, * {@code StdMidi.HN}, * {@code StdMidi.WN}, * {@code StdMidi.EN}, and * {@code StdMidi.SN}. * *
* Key velocities. * The key-down velocity indiciates the force with which a note is played. * It controls the note's volume and/or brightness. * Velocities range from 0 (silent) to 127 (loudest). * The default MIDI velocity is 96. * You can use change the key-down velocity using the method: *
* Instruments. * The default MIDI instrument is an Acousic Grand Piano. * You can use change the instrument using the method: *
* Subsequent notes will be synthesized using that instrument. * The {@code instrument} argument must be an integer between 1 and 128. * The instrument is identified using the * General MIDI standard, which * specifies 128 individual instruments and numbers them from 1 (Acoustic Grand Piano) * to 128 (Gunshot). * The {@code StdMidi} class provides pre-defined constants for these instruments, * such as {@code StdMidi.ACOUSTIC_GRAND_PIANO} and {@code StdMidi.GUNSHOT}. * Depending on the soundfont, each instrument may sound different. * *
* Playing multiple notes at the same time. * For added control, you can use the following methods to play * several notes (of different durations) at the same time. *
* If a note has a natural decay (such as a piano or bass drum), it is not strictly * necessary to call {@code noteOff()} or {@code percussionOff()}. * Nevertheless, it is good practice to do so in order to avoid allocating * unnecessary resources for a note that is no longer making sound. * Also, some instruments have limited polyphony (number of notes you can * play at the same time), so you may exceed this limit if you don't explicitly * turn off the notes. * *
* Playing MIDI files. * You can use the following method to play a MIDI file: *
* The {@code play()} method plays the MIDI file and waits until the * audio file finishes playing before continuing. * The {@code playInBackground()} method plays the MIDI file in a background thread * (e.g., as a background score in your program). * The {@code filename} must have the extension {@code .mid} or {@code .midi}. * *
* Saving MIDI files. * You can use the following method to save the sequence of notes to a MIDI file: *
* The {@code filename} must have the extension {@code .mid} or {@code .midi}. * * *
* Soundfonts.
* A soundfont stores samples of musical instruments for MIDI playback.
* This determines how each musical instruments sounds.
* We recommend FluidR3,
* pro-quality soundfont developed by Frank Wen and released under an
* open-source license.
* If you ran our autoinstaller, it should be installed and configured automatically.
* If not, Java will default to an internal soundfont, known as Gervill.
* (On OS X, it is located in ~/.gervill/soundbank-emg.sf2.)
* Alternatively, you can download
* {@code FluidR3_GM2-2.sf2} and install it at {@code /usr/local/lift/Soundfonts/FluidR3_GM2-2.sf2}.
*
* @author Kevin Wayne
*/
public class StdMidi {
/**
* The default MIDI tempo (120 beats per minute).
*/
public static final int DEFAULT_TEMPO = 120;
/**
* The default MIDI velocity (96).
*/
public static final int DEFAULT_VELOCITY = 96;
/**
* The default MIDI instrument (Acoustic Grand Piano).
*/
public static final int DEFAULT_INSTRUMENT = 1;
// private static final String SOUNDFONT_FILENAME = "/usr/local/lift/Soundfonts/MuseScore_General.sf2";
// private static final String SOUNDFONT_FILENAME = "/usr/local/lift/Soundfonts/MuseScore_General.sf3";
// private static final String SOUNDFONT_FILENAME = "/usr/local/lift/Soundfonts/MuseScore_General_HQ.sf3";
private static final String SOUNDFONT_FILENAME = "/usr/local/lift/Soundfonts/FluidR3_GM2-2.sf2";
private static MidiChannel channel; // for real-time pitched instruments
private static MidiChannel percussionChannel; // for real-time unpitched percussion instruments
private static int tempo; // current tempo
private static int velocity; // current velocity
// the synthesizer for playing MIDI files
private static Synthesizer synthesizer;
/* for playing MIDI files */
// for playing MIDI files and blocking
private static Object lock = new Object();
// play in background thread
private static final boolean BACKGROUND = true;
/* for saving to file */
private static final int MIDI_MESSAGE_IGNORE_BYTE = -1;
private static final int MIDI_TICKS_PER_QUARTER_NOTE = 48;
// MIDI channel number
private static int channelNumber = -1;
// MIDI file types
private static final int ONE_TRACK = 0;
private static final int SYNCHRONOUS = 1;
private static final int ASYNCHRONOUS = 2;
private static long tick;
private static Sequence sequence;
private static Track track;
// tempo in beats per minute (quarter note = 1 beat)
/**
* The tempo larghissimo (20 beats per minute).
*/
public static final int LARGHISSIMO = 20;
/**
* The tempo grave (40 beats per minute).
*/
public static final int GRAVE = 40;
/**
* The tempo largo (50 beats per minute).
*/
public static final int LARGO = 50;
/**
* The tempo larghetto (60 beats per minute).
*/
public static final int LARGHETTO = 60;
/**
* The tempo adagio (70 beats per minute).
*/
public static final int ADAGIO = 70;
/**
* The tempo adagietto (74 beats per minute).
*/
public static final int ADAGIETTO = 74;
/**
* The tempo andante (90 beats per minute).
*/
public static final int ANDANTE = 90;
/**
* The tempo andantino (96 beats per minute).
*/
public static final int ANDANTINO = 96;
/**
* The tempo moderato (110 beats per minute).
*/
public static final int MODERATO = 110;
/**
* The tempo allegro (140 beats per minute).
*/
public static final int ALLEGRO = 140;
/**
* The tempo vivace (166 beats per minute).
*/
public static final int VIVACE = 166;
/**
* The tempo vivacissimo (174 beats per minute).
*/
public static final int VIVACISSIMO = 174;
/**
* The tempo presto (180 beats per minute).
*/
public static final int PRESTO = 180;
/**
* The tempo prestissimo (200 beats per minute).
*/
public static final int PRESTISSIMO = 200;
// dynamic or volumes of notes (MIDI velocity)
// https://jythonmusic.me/api/midi-constants/dynamic/
/**
* The velocity 0. Playing a note with this velocity is equivalent to turning it off.
*/
public static final int SILENT = 0;
/**
* The velocity pianississimo (10).
*/
public static final int PIANISSISSIMO = 10;
/**
* The velocity pianissimo (25).
*/
public static final int PIANISSIMO = 25;
/**
* The velocity piano (50).
*/
public static final int PIANO = 50;
/**
* The velocity mezzo piano (60).
*/
public static final int MEZZO_PIANO = 60;
/**
* The velocity mezzo forte (70).
*/
public static final int MEZZO_FORTE = 70;
/**
* The velocity forte (85).
*/
public static final int FORTE = 85;
/**
* The velocity fortissimo (100).
*/
public static final int FORTISSIMO = 100;
/**
* The velocity fortississimo (120).
*/
public static final int FORTISSISSIMO = 120;
// MIDI note pitches (0 to 127)
// https://jythonmusic.me/api/midi-constants/pitch/
/**
* The note A in octave 4, also known as Concert A and A440.
*/
public static final int CONCERT_A = 69;
/**
* The note C in octave 4, also known as Middle C.
*/
public static final int MIDDLE_C = 60;
/**
* The note number corresponding to a rest.
*/
public static final int REST = -1;
/**
* The note C in octave -1.
*/
public static final int C_1 = 0;
/**
* The note C♯ in octave -1.
*/
public static final int CS_1 = 1;
/**
* The note D♭ in octave -1.
*/
public static final int DF_1 = 1;
/**
* The note D in octave -1.
*/
public static final int D_1 = 2;
/**
* The note D♯ in octave -1.
*/
public static final int DS_1 = 3;
/**
* The note E♭ in octave -1.
*/
public static final int EF_1 = 3;
/**
* The note E in octave -1.
*/
public static final int E_1 = 4;
/**
* The note F in octave -1.
*/
public static final int F_1 = 5;
/**
* The note F♯ in octave -1.
*/
public static final int FS_1 = 6;
/**
* The note G♭ in octave -1.
*/
public static final int GF_1 = 6;
/**
* The note G in octave -1.
*/
public static final int G_1 = 7;
/**
* The note G♯ in octave -1.
*/
public static final int GS_1 = 8;
/**
* The note A♭ in octave -1.
*/
public static final int AF_1 = 8;
/**
* The note A in octave -1.
*/
public static final int A_1 = 9;
/**
* The note A♯ in octave -1.
*/
public static final int AS_1 = 10;
/**
* The note B♭ in octave -1.
*/
public static final int BF_1 = 10;
/**
* The note B in octave -1.
*/
public static final int B_1 = 11;
/**
* The note C in octave 0.
*/
public static final int C0 = 12;
/**
* The note C♯ in octave 0.
*/
public static final int CS0 = 13;
/**
* The note D♭ in octave 0.
*/
public static final int DF0 = 13;
/**
* The note D in octave 0.
*/
public static final int D0 = 14;
/**
* The note D♯ in octave 0.
*/
public static final int DS0 = 15;
/**
* The note E♭ in octave 0.
*/
public static final int EF0 = 15;
/**
* The note E in octave 0.
*/
public static final int E0 = 16;
/**
* The note F in octave 0.
*/
public static final int F0 = 17;
/**
* The note F♯ in octave 0.
*/
public static final int FS0 = 18;
/**
* The note G♭ in octave 0.
*/
public static final int GF0 = 18;
/**
* The note G in octave 0.
*/
public static final int G0 = 19;
/**
* The note G♯ in octave 0.
*/
public static final int GS0 = 20;
/**
* The note A♭ in octave 0.
*/
public static final int AF0 = 20;
/**
* The note A in octave 0.
*/
public static final int A0 = 21;
/**
* The note A♯ in octave 0.
*/
public static final int AS0 = 22;
/**
* The note B♭ in octave 0.
*/
public static final int BF0 = 22;
/**
* The note B in octave 0.
*/
public static final int B0 = 23;
/**
* The note C in octave 1.
*/
public static final int C1 = 24;
/**
* The note C♯ in octave 1.
*/
public static final int CS1 = 25;
/**
* The note D♭ in octave 1.
*/
public static final int DF1 = 25;
/**
* The note D in octave 1.
*/
public static final int D1 = 26;
/**
* The note D♯ in octave 1.
*/
public static final int DS1 = 27;
/**
* The note E♭ in octave 1.
*/
public static final int EF1 = 27;
/**
* The note E in octave 1.
*/
public static final int E1 = 28;
/**
* The note F in octave 1.
*/
public static final int F1 = 29;
/**
* The note F♯ in octave 1.
*/
public static final int FS1 = 30;
/**
* The note G♭ in octave 1.
*/
public static final int GF1 = 30;
/**
* The note G in octave 1.
*/
public static final int G1 = 31;
/**
* The note G♯ in octave 1.
*/
public static final int GS1 = 32;
/**
* The note A♭ in octave 1.
*/
public static final int AF1 = 32;
/**
* The note A in octave 1.
*/
public static final int A1 = 33;
/**
* The note A♯ in octave 1.
*/
public static final int AS1 = 34;
/**
* The note B♭ in octave 1.
*/
public static final int BF1 = 34;
/**
* The note B in octave 1.
*/
public static final int B1 = 35;
/**
* The note C in octave 2.
*/
public static final int C2 = 36;
/**
* The note C♯ in octave 2.
*/
public static final int CS2 = 37;
/**
* The note D♭ in octave 2.
*/
public static final int DF2 = 37;
/**
* The note D in octave 2.
*/
public static final int D2 = 38;
/**
* The note D♯ in octave 2.
*/
public static final int DS2 = 39;
/**
* The note E♭ in octave 2.
*/
public static final int EF2 = 39;
/**
* The note E in octave 2.
*/
public static final int E2 = 40;
/**
* The note F in octave 2.
*/
public static final int F2 = 41;
/**
* The note F♯ in octave 2.
*/
public static final int FS2 = 42;
/**
* The note G♭ in octave 2.
*/
public static final int GF2 = 42;
/**
* The note G in octave 2.
*/
public static final int G2 = 43;
/**
* The note G♯ in octave 2.
*/
public static final int GS2 = 44;
/**
* The note A♭ in octave 2.
*/
public static final int AF2 = 44;
/**
* The note A in octave 2.
*/
public static final int A2 = 45;
/**
* The note A♯ in octave 2.
*/
public static final int AS2 = 46;
/**
* The note B♭ in octave 2.
*/
public static final int BF2 = 46;
/**
* The note B in octave 2.
*/
public static final int B2 = 47;
/**
* The note C in octave 3.
*/
public static final int C3 = 48;
/**
* The note C♯ in octave 3.
*/
public static final int CS3 = 49;
/**
* The note D♭ in octave 3.
*/
public static final int DF3 = 49;
/**
* The note D in octave 3.
*/
public static final int D3 = 50;
/**
* The note D♯ in octave 3.
*/
public static final int DS3 = 51;
/**
* The note E♭ in octave 3.
*/
public static final int EF3 = 51;
/**
* The note E in octave 3.
*/
public static final int E3 = 52;
/**
* The note F in octave 3.
*/
public static final int F3 = 53;
/**
* The note F♯ in octave 3.
*/
public static final int FS3 = 54;
/**
* The note G♭ in octave 3.
*/
public static final int GF3 = 54;
/**
* The note G in octave 3.
*/
public static final int G3 = 55;
/**
* The note G♯ in octave 3.
*/
public static final int GS3 = 56;
/**
* The note A♭ in octave 3.
*/
public static final int AF3 = 56;
/**
* The note A in octave 3.
*/
public static final int A3 = 57;
/**
* The note A♯ in octave 3.
*/
public static final int AS3 = 58;
/**
* The note B♭ in octave 3.
*/
public static final int BF3 = 58;
/**
* The note B in octave 3.
*/
public static final int B3 = 59;
/**
* The note C in octave 4.
*/
public static final int C4 = 60;
/**
* The note C♯ in octave 4.
*/
public static final int CS4 = 61;
/**
* The note D♭ in octave 4.
*/
public static final int DF4 = 61;
/**
* The note D in octave 4.
*/
public static final int D4 = 62;
/**
* The note D♯ in octave 4.
*/
public static final int DS4 = 63;
/**
* The note E♭ in octave 4.
*/
public static final int EF4 = 63;
/**
* The note E in octave 4.
*/
public static final int E4 = 64;
/**
* The note F in octave 4.
*/
public static final int F4 = 65;
/**
* The note F♯ in octave 4.
*/
public static final int FS4 = 66;
/**
* The note G♭ in octave 4.
*/
public static final int GF4 = 66;
/**
* The note G in octave 4.
*/
public static final int G4 = 67;
/**
* The note G♯ in octave 4.
*/
public static final int GS4 = 68;
/**
* The note A♭ in octave 4.
*/
public static final int AF4 = 68;
/**
* The note A in octave 4.
*/
public static final int A4 = 69;
/**
* The note A♯ in octave 4.
*/
public static final int AS4 = 70;
/**
* The note B♭ in octave 4.
*/
public static final int BF4 = 70;
/**
* The note B in octave 4.
*/
public static final int B4 = 71;
/**
* The note C in octave 5.
*/
public static final int C5 = 72;
/**
* The note C♯ in octave 5.
*/
public static final int CS5 = 73;
/**
* The note D♭ in octave 5.
*/
public static final int DF5 = 73;
/**
* The note D in octave 5.
*/
public static final int D5 = 74;
/**
* The note D♯ in octave 5.
*/
public static final int DS5 = 75;
/**
* The note E♭ in octave 5.
*/
public static final int EF5 = 75;
/**
* The note E in octave 5.
*/
public static final int E5 = 76;
/**
* The note F in octave 5.
*/
public static final int F5 = 77;
/**
* The note F♯ in octave 5.
*/
public static final int FS5 = 78;
/**
* The note G♭ in octave 5.
*/
public static final int GF5 = 78;
/**
* The note G in octave 5.
*/
public static final int G5 = 79;
/**
* The note G♯ in octave 5.
*/
public static final int GS5 = 80;
/**
* The note A♭ in octave 5.
*/
public static final int AF5 = 80;
/**
* The note A in octave 5.
*/
public static final int A5 = 81;
/**
* The note A♯ in octave 5.
*/
public static final int AS5 = 82;
/**
* The note B♭ in octave 5.
*/
public static final int BF5 = 82;
/**
* The note B in octave 5.
*/
public static final int B5 = 83;
/**
* The note C in octave 6.
*/
public static final int C6 = 84;
/**
* The note C♯ in octave 6.
*/
public static final int CS6 = 85;
/**
* The note D♭ in octave 6.
*/
public static final int DF6 = 85;
/**
* The note D in octave 6.
*/
public static final int D6 = 86;
/**
* The note D♯ in octave 6.
*/
public static final int DS6 = 87;
/**
* The note E♭ in octave 6.
*/
public static final int EF6 = 87;
/**
* The note E in octave 6.
*/
public static final int E6 = 88;
/**
* The note F in octave 6.
*/
public static final int F6 = 89;
/**
* The note F♯ in octave 6.
*/
public static final int FS6 = 90;
/**
* The note G♭ in octave 6.
*/
public static final int GF6 = 90;
/**
* The note G in octave 6.
*/
public static final int G6 = 91;
/**
* The note G♯ in octave 6.
*/
public static final int GS6 = 92;
/**
* The note A♭ in octave 6.
*/
public static final int AF6 = 92;
/**
* The note A in octave 6.
*/
public static final int A6 = 93;
/**
* The note A♯ in octave 6.
*/
public static final int AS6 = 94;
/**
* The note B♭ in octave 6.
*/
public static final int BF6 = 94;
/**
* The note B in octave 6.
*/
public static final int B6 = 95;
/**
* The note C in octave 7.
*/
public static final int C7 = 96;
/**
* The note C♯ in octave 7.
*/
public static final int CS7 = 97;
/**
* The note D♭ in octave 7.
*/
public static final int DF7 = 97;
/**
* The note D in octave 7.
*/
public static final int D7 = 98;
/**
* The note D♯ in octave 7.
*/
public static final int DS7 = 99;
/**
* The note E♭ in octave 7.
*/
public static final int EF7 = 99;
/**
* The note E in octave 7.
*/
public static final int E7 = 100;
/**
* The note F in octave 7.
*/
public static final int F7 = 101;
/**
* The note F♯ in octave 7.
*/
public static final int FS7 = 102;
/**
* The note G♭ in octave 7.
*/
public static final int GF7 = 102;
/**
* The note G in octave 7.
*/
public static final int G7 = 103;
/**
* The note G♯ in octave 7.
*/
public static final int GS7 = 104;
/**
* The note A♭ in octave 7.
*/
public static final int AF7 = 104;
/**
* The note A in octave 7.
*/
public static final int A7 = 105;
/**
* The note A♯ in octave 7.
*/
public static final int AS7 = 106;
/**
* The note B♭ in octave 7.
*/
public static final int BF7 = 106;
/**
* The note B in octave 7.
*/
public static final int B7 = 107;
/**
* The note C in octave 8.
*/
public static final int C8 = 108;
/**
* The note C♯ in octave 8.
*/
public static final int CS8 = 109;
/**
* The note D♭ in octave 8.
*/
public static final int DF8 = 109;
/**
* The note D in octave 8.
*/
public static final int D8 = 110;
/**
* The note D♯ in octave 8.
*/
public static final int DS8 = 111;
/**
* The note E♭ in octave 8.
*/
public static final int EF8 = 111;
/**
* The note E in octave 8.
*/
public static final int E8 = 112;
/**
* The note F in octave 8.
*/
public static final int F8 = 113;
/**
* The note F♯ in octave 8.
*/
public static final int FS8 = 114;
/**
* The note G♭ in octave 8.
*/
public static final int GF8 = 114;
/**
* The note G in octave 8.
*/
public static final int G8 = 115;
/**
* The note G♯ in octave 8.
*/
public static final int GS8 = 116;
/**
* The note A♭ in octave 8.
*/
public static final int AF8 = 116;
/**
* The note A in octave 8.
*/
public static final int A8 = 117;
/**
* The note A♯ in octave 8.
*/
public static final int AS8 = 118;
/**
* The note B♭ in octave 8.
*/
public static final int BF8 = 118;
/**
* The note B in octave 8.
*/
public static final int B8 = 119;
/**
* The note C in octave 9.
*/
public static final int C9 = 120;
/**
* The note C♯ in octave 9.
*/
public static final int CS9 = 121;
/**
* The note D♭ in octave 9.
*/
public static final int DF9 = 121;
/**
* The note D in octave 9.
*/
public static final int D9 = 122;
/**
* The note D♯ in octave 9.
*/
public static final int DS9 = 123;
/**
* The note E♭ in octave 9.
*/
public static final int EF9 = 123;
/**
* The note E in octave 9.
*/
public static final int E9 = 124;
/**
* The note F in octave 9.
*/
public static final int F9 = 125;
/**
* The note F♯ in octave 9.
*/
public static final int FS9 = 126;
/**
* The note G♭ in octave 9.
*/
public static final int GF9 = 126;
/**
* The note G in octave 9.
*/
public static final int G9 = 127;
// duration constants (quarter note = 1 beat)
// https://jythonmusic.me/api/midi-constants/duration/
/**
* The duration of a whole note (4 beats).
*/
public static final double WN = 4.0;
/**
* The duration of a double dotted half note (7/2 beats).
*/
public static final double DDHN = 3.5;
/**
* The duration of a dotted half note (3 beats).
*/
public static final double DHN = 3.0;
/**
* The duration of a half note (2 beats).
*/
public static final double HN = 2.0;
/**
* The duration of a double dotted quarter note (7/4 beats).
*/
public static final double DDQN = 1.75;
/**
* The duration of a dotted quarter note (3/2 beats).
*/
public static final double DQN = 1.5;
/**
* The duration of a half note triplet (4/3 beats).
*/
public static final double HNT = 4.0/3.0;
/**
* The duration of a quarter note (1 beat).
*/
public static final double QN = 1.0;
/**
* The duration of a double dotted eighth note (7/8 beat).
*/
public static final double DDEN = 0.875;
/**
* The duration of a quarter note triplet (2/3 beat).
*/
public static final double QNT = 2.0/3.0;
/**
* The duration of a double dotted eighth note (3/4 beats).
*/
public static final double DEN = 0.75;
/**
* The duration of an eighth note (1/2 beat).
*/
public static final double EN = 0.5;
/**
* The duration of a dotted sixteenth note (3/8 beat).
*/
public static final double DSN = 0.375;
/**
* The duration of an eighth note triplet (1/3 beat).
*/
public static final double ENT = 1.0/3.0;
/**
* The duration of a sixteenth note (1/4 beat).
*/
public static final double SN = 0.25;
/**
* The duration of a thirty-second note (1/8 beat).
*/
public static final double TN = 0.125;
/**
* The duration of a sixteenth note triplet (1/6 beat).
*/
public static final double SNT = 1.0/6.0;
/**
* The duration of a thirty-second note (1/8 beat).
*/
public static final double TNT = 1.0/12.0;
/**
* The duration of a whole note (4 beats).
*/
public static final double WHOLE_NOTE = 4.0;
/**
* The duration of a dotted half note (3 beats).
*/
public static final double DOTTED_HALF_NOTE = 3.0;
/**
* The duration of a double dotted half note (7/2 beats).
*/
public static final double DOUBLE_DOTTED_HALF_NOTE = 3.5;
/**
* The duration of a half note (2 beats).
*/
public static final double HALF_NOTE = 2.0;
/**
* The duration of a double dotted quarter note (7/4 beats).
*/
public static final double DOUBLE_DOTTED_QUARTER_NOTE = 1.75;
/**
* The duration of a dotted quarter note (3/2 beats).
*/
public static final double DOTTED_QUARTER_NOTE = 1.5;
/**
* The duration of a half note triplet (4/3 beats).
*/
public static final double HALF_NOTE_TRIPLET = 4.0 / 3.0;
/**
* The duration of a quarter note (1 beat).
*/
public static final double QUARTER_NOTE = 1.0;
/**
* The duration of a double dotted eighth note (7/8 beat).
*/
public static final double DOUBLE_DOTTED_EIGHTH_NOTE = 0.875;
/**
* The duration of a double dotted eighth note (3/4 beats).
*/
public static final double DOTTED_EIGHTH_NOTE = 0.75;
/**
* The duration of a quarter note triplet (2/3 beat).
*/
public static final double QUARTER_NOTE_TRIPLET = 2.0 / 3.0;
/**
* The duration of an eighth note (1/2 beat).
*/
public static final double EIGHTH_NOTE = 0.5;
/**
* The duration of a dotted sixteenth note (3/8 beat).
*/
public static final double DOTTED_SIXTEENTH_NOTE = 0.375;
/**
* The duration of an eighth note triplet (1/3 beat).
*/
public static final double EIGHTH_NOTE_TRIPLET = 1.0 / 3.0;
/**
* The duration of a sixteenth note (1/4 beat).
*/
public static final double SIXTEENTH_NOTE = 0.25;
/**
* The duration of a sixteenth note triplet (1/6 beat).
*/
public static final double SIXTEENTH_NOTE_TRIPLET = 1.0/6.0;
/**
* The duration of a thirty-second note (1/8 beat).
*/
public static final double THIRTYSECOND_NOTE = 0.125;
/**
* The duration of a thirty-second note triplet (1/12 beat).
*/
public static final double THIRTYSECOND_NOTE_TRIPLET = 1.0/12.0;
/***************************************************************************
* The instrument names, as reported by FluidR3 GM2-2.SF2.
***************************************************************************/
/**
* The instrument Acoustic Grand Piano.
*/
public static final int ACOUSTIC_GRAND_PIANO = 1;
/**
* The instrument Bright Acoustic Piano.
*/
public static final int BRIGHT_ACOUSTIC_PIANO = 2;
/**
* The instrument Electric Grand Piano.
*/
public static final int ELECTRIC_GRAND_PIANO = 3;
/**
* The instrument Honky Tonk Piano.
*/
public static final int HONKY_TONK_PIANO = 4;
/**
* The instrument Electric Piano 1.
*/
public static final int ELECTRIC_PIANO_1 = 5;
/**
* The instrument Electric Piano 2.
*/
public static final int ELECTRIC_PIANO_2 = 6;
/**
* The instrument Harpsichord.
*/
public static final int HARPSICHORD = 7;
/**
* The instrument Clavinet.
*/
public static final int CLAVINET = 8;
/**
* The instrument Celesta.
*/
public static final int CELESTA = 9;
/**
* The instrument Glockenspiel.
*/
public static final int GLOCKENSPIEL = 10;
/**
* The instrument Music Box.
*/
public static final int MUSIC_BOX = 11;
/**
* The instrument Vibraphone.
*/
public static final int VIBRAPHONE = 12;
/**
* The instrument Marimba.
*/
public static final int MARIMBA = 13;
/**
* The instrument Xylophone.
*/
public static final int XYLOPHONE = 14;
/**
* The instrument Tubular Bells.
*/
public static final int TUBULAR_BELLS = 15;
/**
* The instrument Dulcimer.
*/
public static final int DULCIMER = 16;
/**
* The instrument Drawbar Organ.
*/
public static final int DRAWBAR_ORGAN = 17;
/**
* The instrument Percussive Organ.
*/
public static final int PERCUSSIVE_ORGAN = 18;
/**
* The instrument Rock Organ.
*/
public static final int ROCK_ORGAN = 19;
/**
* The instrument Church Organ.
*/
public static final int CHURCH_ORGAN = 20;
/**
* The instrument Reed Organ.
*/
public static final int REED_ORGAN = 21;
/**
* The instrument Accordion.
*/
public static final int ACCORDION = 22;
/**
* The instrument Harmonica.
*/
public static final int HARMONICA = 23;
/**
* The instrument Bandoneon.
*/
public static final int BANDONEON = 24;
/**
* The instrument Nylon String Guitar.
*/
public static final int NYLON_STRING_GUITAR = 25;
/**
* The instrument Steel String Guitar.
*/
public static final int STEEL_STRING_GUITAR = 26;
/**
* The instrument Jazz Guitar.
*/
public static final int JAZZ_GUITAR = 27;
/**
* The instrument Clean Guitar.
*/
public static final int CLEAN_GUITAR = 28;
/**
* The instrument Palm Muted Guitar.
*/
public static final int PALM_MUTED_GUITAR = 29;
/**
* The instrument Overdrive Guitar.
*/
public static final int OVERDRIVE_GUITAR = 30;
/**
* The instrument Distortion Guitar.
*/
public static final int DISTORTION_GUITAR = 31;
/**
* The instrument Guitar Harmonics.
*/
public static final int GUITAR_HARMONICS = 32;
/**
* The instrument Acoustic Bass.
*/
public static final int ACOUSTIC_BASS = 33;
/**
* The instrument Fingered Bass.
*/
public static final int FINGERED_BASS = 34;
/**
* The instrument Picked Bass.
*/
public static final int PICKED_BASS = 35;
/**
* The instrument Fretless Bass.
*/
public static final int FRETLESS_BASS = 36;
/**
* The instrument Slap Bass.
*/
public static final int SLAP_BASS = 37;
/**
* The instrument Pop Bass.
*/
public static final int POP_BASS = 38;
/**
* The instrument Synth Bass 1.
*/
public static final int SYNTH_BASS_1 = 39;
/**
* The instrument Synth Bass 2.
*/
public static final int SYNTH_BASS_2 = 40;
/**
* The instrument Violin.
*/
public static final int VIOLIN = 41;
/**
* The instrument Viola.
*/
public static final int VIOLA = 42;
/**
* The instrument Cello.
*/
public static final int CELLO = 43;
/**
* The instrument Contrabass.
*/
public static final int CONTRABASS = 44;
/**
* The instrument Tremolo Strings.
*/
public static final int TREMOLO_STRINGS = 45;
/**
* The instrument Pizzicato Strings.
*/
public static final int PIZZICATO_STRINGS = 46;
/**
* The instrument Harp.
*/
public static final int HARP = 47;
/**
* The instrument Timpani.
*/
public static final int TIMPANI = 48;
/**
* The instrument Strings.
*/
public static final int STRINGS = 49;
/**
* The instrument Slow Strings.
*/
public static final int SLOW_STRINGS = 50;
/**
* The instrument Synth Strings 1.
*/
public static final int SYNTH_STRINGS_1 = 51;
/**
* The instrument Synth Strings 2.
*/
public static final int SYNTH_STRINGS_2 = 52;
/**
* The instrument Ahh Choir.
*/
public static final int AHH_CHOIR = 53;
/**
* The instrument Ohh Voices.
*/
public static final int OHH_VOICES = 54;
/**
* The instrument Synth Voice.
*/
public static final int SYNTH_VOICE = 55;
/**
* The instrument Orchestra Hit.
*/
public static final int ORCHESTRA_HIT = 56;
/**
* The instrument Trumpet.
*/
public static final int TRUMPET = 57;
/**
* The instrument Trombone.
*/
public static final int TROMBONE = 58;
/**
* The instrument Tuba.
*/
public static final int TUBA = 59;
/**
* The instrument Muted Trumpet.
*/
public static final int MUTED_TRUMPET = 60;
/**
* The instrument French Horn.
*/
public static final int FRENCH_HORN = 61;
/**
* The instrument Brass Section.
*/
public static final int BRASS_SECTION = 62;
/**
* The instrument Synth Brass 1.
*/
public static final int SYNTH_BRASS_1 = 63;
/**
* The instrument Synth Brass 2.
*/
public static final int SYNTH_BRASS_2 = 64;
/**
* The instrument Soprano Sax.
*/
public static final int SOPRANO_SAX = 65;
/**
* The instrument Alto Sax.
*/
public static final int ALTO_SAX = 66;
/**
* The instrument Tenor Sax.
*/
public static final int TENOR_SAX = 67;
/**
* The instrument Baritone Sax.
*/
public static final int BARITONE_SAX = 68;
/**
* The instrument Oboe.
*/
public static final int OBOE = 69;
/**
* The instrument English Horn.
*/
public static final int ENGLISH_HORN = 70;
/**
* The instrument Bassoon.
*/
public static final int BASSOON = 71;
/**
* The instrument Clarinet.
*/
public static final int CLARINET = 72;
/**
* The instrument Piccolo.
*/
public static final int PICCOLO = 73;
/**
* The instrument Flute.
*/
public static final int FLUTE = 74;
/**
* The instrument Recorder.
*/
public static final int RECORDER = 75;
/**
* The instrument Pan Flute.
*/
public static final int PAN_FLUTE = 76;
/**
* The instrument Bottle Chiff.
*/
public static final int BOTTLE_CHIFF = 77;
/**
* The instrument Shakuhachi.
*/
public static final int SHAKUHACHI = 78;
/**
* The instrument Whistle.
*/
public static final int WHISTLE = 79;
/**
* The instrument Ocarina.
*/
public static final int OCARINA = 80;
/**
* The instrument Square Lead.
*/
public static final int SQUARE_LEAD = 81;
/**
* The instrument Saw Wave.
*/
public static final int SAW_WAVE = 82;
/**
* The instrument Calliope Lead.
*/
public static final int CALLIOPE_LEAD = 83;
/**
* The instrument Chiffer Lead.
*/
public static final int CHIFFER_LEAD = 84;
/**
* The instrument Charang.
*/
public static final int CHARANG = 85;
/**
* The instrument Solo Vox.
*/
public static final int SOLO_VOX = 86;
/**
* The instrument Fifth Sawtooth Wave.
*/
public static final int FIFTH_SAWTOOTH_WAVE = 87;
/**
* The instrument Bass and Lead.
*/
public static final int BASS_AND_LEAD = 88;
/**
* The instrument Fantasia.
*/
public static final int FANTASIA = 89;
/**
* The instrument Warm Pad.
*/
public static final int WARM_PAD = 90;
/**
* The instrument Polysynth.
*/
public static final int POLYSYNTH = 91;
/**
* The instrument Space Voice.
*/
public static final int SPACE_VOICE = 92;
/**
* The instrument Bowed Glass.
*/
public static final int BOWED_GLASS = 93;
/**
* The instrument Metal Pad.
*/
public static final int METAL_PAD = 94;
/**
* The instrument Halo Pad.
*/
public static final int HALO_PAD = 95;
/**
* The instrument Sweep Pad.
*/
public static final int SWEEP_PAD = 96;
/**
* The instrument Ice Rain.
*/
public static final int ICE_RAIN = 97;
/**
* The instrument Soundtrack.
*/
public static final int SOUNDTRACK = 98;
/**
* The instrument Crystal.
*/
public static final int CRYSTAL = 99;
/**
* The instrument Atmosphere.
*/
public static final int ATMOSPHERE = 100;
/**
* The instrument Brightness.
*/
public static final int BRIGHTNESS = 101;
/**
* The instrument Goblin.
*/
public static final int GOBLIN = 102;
/**
* The instrument Echo Drops.
*/
public static final int ECHO_DROPS = 103;
/**
* The instrument Star Theme.
*/
public static final int STAR_THEME = 104;
/**
* The instrument Sitar.
*/
public static final int SITAR = 105;
/**
* The instrument Banjo.
*/
public static final int BANJO = 106;
/**
* The instrument Shamisen.
*/
public static final int SHAMISEN = 107;
/**
* The instrument Koto.
*/
public static final int KOTO = 108;
/**
* The instrument Kalimba.
*/
public static final int KALIMBA = 109;
/**
* The instrument Bagpipe.
*/
public static final int BAGPIPE = 110;
/**
* The instrument Fiddle.
*/
public static final int FIDDLE = 111;
/**
* The instrument Shehnai.
*/
public static final int SHEHNAI = 112;
/**
* The instrument Tinkle Bell.
*/
public static final int TINKLE_BELL = 113;
/**
* The instrument Agogô.
*/
public static final int AGOGÔ = 114;
/**
* The instrument Steel Drums.
*/
public static final int STEEL_DRUMS = 115;
/**
* The instrument Woodblock.
*/
public static final int WOODBLOCK = 116;
/**
* The instrument Taiko Drum.
*/
public static final int TAIKO_DRUM = 117;
/**
* The instrument Melodic Tom.
*/
public static final int MELODIC_TOM = 118;
/**
* The instrument Synth Drum.
*/
public static final int SYNTH_DRUM = 119;
/**
* The instrument Reverse Cymbal.
*/
public static final int REVERSE_CYMBAL = 120;
/**
* The instrument Fret Noise.
*/
public static final int FRET_NOISE = 121;
/**
* The instrument Breath Noise.
*/
public static final int BREATH_NOISE = 122;
/**
* The instrument Sea Shore.
*/
public static final int SEA_SHORE = 123;
/**
* The instrument Bird Tweet.
*/
public static final int BIRD_TWEET = 124;
/**
* The instrument Telephone.
*/
public static final int TELEPHONE = 125;
/**
* The instrument Helicopter.
*/
public static final int HELICOPTER = 126;
/**
* The instrument Applause.
*/
public static final int APPLAUSE = 127;
/**
* The instrument Gunshot.
*/
public static final int GUNSHOT = 128;
/***************************************************************************
* The percussion instruments.
* See https://en.wikipedia.org/wiki/General_MIDI
***************************************************************************/
/**
* The percussion instrument Acoustic Bass Drum.
*/
public static final int ACOUSTIC_BASS_DRUM = 35;
/**
* The percussion instrument Electric Bass Drum.
*/
public static final int ELECTRIC_BASS_DRUM = 36;
/**
* The percussion instrument Side Stick.
*/
public static final int SIDE_STICK = 37;
/**
* The percussion instrument Acoustic Snare.
*/
public static final int ACOUSTIC_SNARE = 38;
/**
* The percussion instrument Hand Clap.
*/
public static final int HAND_CLAP = 39;
/**
* The percussion instrument Electric Snare.
*/
public static final int ELECTRIC_SNARE = 40;
/**
* The percussion instrument Low Floor Tom.
*/
public static final int LOW_FLOOR_TOM = 41;
/**
* The percussion instrument Closed Hi Hat.
*/
public static final int CLOSED_HI_HAT = 42;
/**
* The percussion instrument High Floor Tom.
*/
public static final int HIGH_FLOOR_TOM = 43;
/**
* The percussion instrument Pedal Hi Hat.
*/
public static final int PEDAL_HI_HAT = 44;
/**
* The percussion instrument Low Tom.
*/
public static final int LOW_TOM = 45;
/**
* The percussion instrument Open Hi Hat.
*/
public static final int OPEN_HI_HAT = 46;
/**
* The percussion instrument Low Mid Tom.
*/
public static final int LOW_MID_TOM = 47;
/**
* The percussion instrument High Mid Tom.
*/
public static final int HIGH_MID_TOM = 48;
/**
* The percussion instrument Crash Cymbal 1.
*/
public static final int CRASH_CYMBAL_1 = 49;
/**
* The percussion instrument High Tom.
*/
public static final int HIGH_TOM = 50;
/**
* The percussion instrument Ride Cymbal 1.
*/
public static final int RIDE_CYMBAL_1 = 51;
/**
* The percussion instrument Chinese Cymbal.
*/
public static final int CHINESE_CYMBAL = 52;
/**
* The percussion instrument Ride Bell.
*/
public static final int RIDE_BELL = 53;
/**
* The percussion instrument Tambourine.
*/
public static final int TAMBOURINE = 54;
/**
* The percussion instrument Splash Cymbal.
*/
public static final int SPLASH_CYMBAL = 55;
/**
* The percussion instrument Cowbell.
*/
public static final int COWBELL = 56;
/**
* The percussion instrument Crash Cymbal 2.
*/
public static final int CRASH_CYMBAL_2 = 57;
/**
* The percussion instrument Vibraslap.
*/
public static final int VIBRASLAP = 58;
/**
* The percussion instrument Ride Cymbal 2.
*/
public static final int RIDE_CYMBAL_2 = 59;
/**
* The percussion instrument High Bongo.
*/
public static final int HIGH_BONGO = 60;
/**
* The percussion instrument Low Bongo.
*/
public static final int LOW_BONGO = 61;
/**
* The percussion instrument Mute Hi Conga.
*/
public static final int MUTE_HI_CONGA = 62;
/**
* The percussion instrument Open Hi Conga.
*/
public static final int OPEN_HI_CONGA = 63;
/**
* The percussion instrument Low Conga.
*/
public static final int LOW_CONGA = 64;
/**
* The percussion instrument High Timbale.
*/
public static final int HIGH_TIMBALE = 65;
/**
* The percussion instrument Low Timbale.
*/
public static final int LOW_TIMBALE = 66;
/**
* The percussion instrument High Agogô.
*/
public static final int HIGH_AGOGÔ = 67;
/**
* The percussion instrument Low Agogô.
*/
public static final int LOW_AGOGÔ = 68;
/**
* The percussion instrument Cabasa.
*/
public static final int CABASA = 69;
/**
* The percussion instrument Maracas.
*/
public static final int MARACAS = 70;
/**
* The percussion instrument Short Whistle.
*/
public static final int SHORT_WHISTLE = 71;
/**
* The percussion instrument Long Whistle.
*/
public static final int LONG_WHISTLE = 72;
/**
* The percussion instrument Short Guiro.
*/
public static final int SHORT_GUIRO = 73;
/**
* The percussion instrument Long Guiro.
*/
public static final int LONG_GUIRO = 74;
/**
* The percussion instrument Claves.
*/
public static final int CLAVES = 75;
/**
* The percussion instrument High Woodblock.
*/
public static final int HIGH_WOODBLOCK = 76;
/**
* The percussion instrument Low Woodblock.
*/
public static final int LOW_WOODBLOCK = 77;
/**
* The percussion instrument Mute Cuica.
*/
public static final int MUTE_CUICA = 78;
/**
* The percussion instrument Open Cuica.
*/
public static final int OPEN_CUICA = 79;
/**
* The percussion instrument Mute Triangle.
*/
public static final int MUTE_TRIANGLE = 80;
/**
* The percussion instrument Open Triangle.
*/
public static final int OPEN_TRIANGLE = 81;
// singleton pattern: client can't instantiate
private StdMidi() { }
static {
tempo = DEFAULT_TEMPO;
velocity = DEFAULT_VELOCITY;
try {
synthesizer = MidiSystem.getSynthesizer();
synthesizer.open();
MidiChannel[] channels = synthesizer.getChannels();
channel = channels[0];
percussionChannel = channels[9]; // MIDI channel 10 is for percussion
}
catch (MidiUnavailableException e) {
System.err.println("Couldn't open a MIDI device");
}
setSoundbank(synthesizer, SOUNDFONT_FILENAME);
startRecording();
}
private static void startRecording() {
try {
// use tempo-based timing: pulses per quarter note (Sequence.PPQ)
sequence = new Sequence(Sequence.PPQ, MIDI_TICKS_PER_QUARTER_NOTE);
// track = sequence.createTrack();
tick = 0;
setInstrument(DEFAULT_INSTRUMENT);
tick++;
}
catch(InvalidMidiDataException e) {
System.out.println(e);
}
catch(Exception e) {
System.out.println(e);
}
}
private static void setSoundbank(Synthesizer synthesizer, String filename) {
// use better soundbank, if available
try {
// look in specified location
File file = new File(filename);
if (file.exists()) {
Soundbank originalSoundbank = synthesizer.getDefaultSoundbank();
Soundbank updatedSoundbank = MidiSystem.getSoundbank(file);
synthesizer.unloadAllInstruments(originalSoundbank);
synthesizer.loadAllInstruments(updatedSoundbank);
}
}
catch (IOException e) {
System.err.println("Couldn't read soundfont from " + filename);
System.err.println("Reverting to default soundfont.");
System.err.println(e);
}
catch (InvalidMidiDataException e) {
System.err.println("Couldn't read MIDI data from " + filename);
}
}
private static void validateVelocity(int val) {
if (val < 0 || val > 127)
throw new IllegalArgumentException("MIDI velocity must be between 0 and 127: " + val);
}
private static void validateTempo(int val) {
if (val <= 0)
throw new IllegalArgumentException("the tempo (beats per minute) must be a positive integer: " + val);
}
private static void validateNote(int val) {
if (val < -1 || val > 127)
throw new IllegalArgumentException("the pitch must be between 0 and 127: " + val);
}
private static void validateDuration(double val) {
if (val < 0.0)
throw new IllegalArgumentException("the number of beats must be non-negative: " + val);
}
private static void validateInstrument(int val) {
if (val <= 0 || val > 128)
throw new IllegalArgumentException("the MIDI instrument number must be between 1 and 128: " + val);
}
private static void validatePercussionInstrument(int val) {
if (val != -1 && (val < 35 || val > 81))
throw new IllegalArgumentException("the percussion instrument number must be between 35 and 81: " + val);
}
/**
* Sets the MIDI instrument to the specified value.
* For example 1 corresponds to an acoustic grand piano and 39 corresponds to a synthetic bass.
* You can specify the instrument numbers using predefined constants, such as
* {@code StdMidi.ACOUSTIC_GRAND_PIANO} and {@code StdMidi.SYNTH_BASS_1}.
*
* @param instrument the integer corresponding to the MIDI instrument
* @throws IllegalArgumentException unless {@code instrument} is between 1 and 128
*/
public static void setInstrument(int instrument) {
validateInstrument(instrument);
channel.programChange(instrument);
/* for recording */
try {
// create a separate track for each instrument change
// each instrument is in its own channel (max = 16 channels and channel 9 typically for percussion)
track = sequence.createTrack();
channelNumber++;
ShortMessage instrumentChange = new ShortMessage(ShortMessage.PROGRAM_CHANGE, channelNumber, instrument, MIDI_MESSAGE_IGNORE_BYTE);
track.add(new MidiEvent(instrumentChange, tick));
}
catch(InvalidMidiDataException e) {
System.out.println(e);
}
}
/**
* Returns the MIDI instrument number (between 1 and 128).
*
* @return the integer corresponding to the MIDI instrument
*/
public static int getInstrument() {
return channel.getProgram();
}
/**
* Sets the velocity to the specified value between 0 (silent) and 127 (loudest).
* The key-down velocity indicates the force with which a note is played.
* It controls the note's volume and/or brightness.
*
* @param val the velocity of the note
* @throws IllegalArgumentException unless {@code velocity} is between 0 and 127
*/
public static void setVelocity(int val) {
validateVelocity(val);
velocity = val;
}
/**
* Sets the tempo to the specified number of beats per minute.
*
* @param beatsPerMinute the number of beats per minute
* @throws IllegalArgumentException unless {@code beatsPerMinute} is a positive integer
*/
public static void setTempo(int beatsPerMinute) {
validateTempo(beatsPerMinute);
tempo = beatsPerMinute;
/* for saving */
// Convert beats per minute to microseconds per quarter note
int mpqn = 60000000 / beatsPerMinute;
byte[] data = new byte[3];
data[0] = (byte) ((mpqn >> 16) & 0xFF);
data[1] = (byte) ((mpqn >> 8) & 0xFF);
data[2] = (byte) (mpqn & 0xFF);
try {
// Create a MetaMessage for the tempo change (0x51 is tempo)
MetaMessage tempoChange = new MetaMessage();
tempoChange.setMessage(0x51, data, data.length);
// Add the MetaMessage to the track
track.add(new MidiEvent(tempoChange, tick));
}
catch(InvalidMidiDataException e) {
System.out.println(e);
}
}
/**
* Plays the specified note for the given duration (measured in beats).
* Uses the current instrument, velocity, and tempo.
* The call {@code playNote(note, beats)} is equivalent to the sequence
* of calls {@code noteOn(note)}, {@code pause(beats)},
* and {@code noteOff(note)}.
*
* @param note the MIDI note number (between 0 and 127)
* @param beats the duration, measured in beats (quarter note = 1 beat)
* @throws IllegalArgumentException unless {@code note} is between 0 and 127
* @throws IllegalArgumentException unless {@code beats} is non-negative
*/
public static void playNote(int note, double beats) {
noteOn(note);
pause(beats);
noteOff(note);
}
/**
* Turns the specified note on.
*
* @param note the MIDI note number (between 0 and 127)
* @throws IllegalArgumentException unless {@code note} is between 0 and 127
*/
public static void noteOn(int note) {
validateNote(note);
if (note == REST) return;
channel.noteOn(note, velocity);
/* for recording */
try {
ShortMessage on = new ShortMessage(ShortMessage.NOTE_ON, channelNumber, note, velocity);
track.add(new MidiEvent(on, tick));
}
catch(InvalidMidiDataException e) {
System.out.println(e);
}
}
/**
* Turns the specified note off.
*
* @param note the MIDI note number (between 0 and 127)
* @throws IllegalArgumentException unless {@code note} is between 0 and 127
*/
public static void noteOff(int note) {
validateNote(note);
if (note == REST) return;
channel.noteOff(note, velocity);
/* for recording */
try {
ShortMessage off = new ShortMessage(ShortMessage.NOTE_OFF, channelNumber, note, 0);
track.add(new MidiEvent(off, tick));
}
catch(InvalidMidiDataException e) {
System.out.println(e);
}
}
/**
* Pauses for the specified duration. The duration is measured in beats,
* where a quarter note is one beat.
*
* @param beats the duration, measured in beats (quarter note = 1 beat)
* @throws IllegalArgumentException unless {@code beats} is non-negative
*/
public static void pause(double beats) {
validateDuration(beats);
try {
Thread.sleep((int) (60.0 / tempo * beats * 1000));
}
catch (InterruptedException e) {
System.out.println("Error sleeping");
}
tick += MIDI_TICKS_PER_QUARTER_NOTE * beats;
}
/**
* Plays the specified notes for the given duration (measured in beats).
* All notes must have the same duration.
* Uses the current instrument, velocity, and tempo.
*
* @param notes the MIDI note numbers (between 0 and 127)
* @param beats the duration, measured in beats (quarter note = 1 beat)
* @throws IllegalArgumentException unless {@code note} is between 0 and 127
* @throws IllegalArgumentException unless {@code beats} is non-negative
*/
public static void playNotes(int[] notes, double beats) {
validateDuration(beats);
for (int note : notes) {
noteOn(note);
}
pause(beats);
for (int note : notes) {
noteOff(note);
}
}
/**
* Plays the specified percussion instrument for the given duration
* (measured in beats). Uses the current velocity and tempo.
*
* @param instrument the MIDI percussion instrument number (between 35 and 81)
* @param beats the duration, measured in beats (quarter note = 1 beat)
* @throws IllegalArgumentException unless {@code instrument} is between 35 and 81
* @throws IllegalArgumentException unless {@code beats} is non-negative
*/
public static void playPercussion(int instrument, double beats) {
validatePercussionInstrument(instrument);
validateDuration(beats);
if (instrument != REST) {
percussionChannel.noteOn(instrument, velocity);
}
pause(beats);
if (instrument != REST) {
percussionChannel.noteOff(instrument);
}
}
public static void percussionOn(int instrument) {
validatePercussionInstrument(instrument);
if (instrument != REST) {
percussionChannel.noteOn(instrument, velocity);
}
}
public static void percussionOn(int instrument, int velocity) {
validatePercussionInstrument(instrument);
validateVelocity(velocity);
if (instrument != REST) {
percussionChannel.noteOn(instrument, velocity);
}
}
public static void percussionOff(int instrument) {
validatePercussionInstrument(instrument);
if (instrument != REST) {
percussionChannel.noteOff(instrument);
}
}
/**
* Turns all notes off, but allows decaying notes to complete.
*/
public static void allNotesOff() {
channel.allNotesOff();
}
/**
* Turns all notes off immediately.
*/
public static void allSoundOff() {
channel.allSoundOff();
}
/**
* Plays the specified MIDI file and waits until the audio file finishes
* playing before continuing.
*
* @param filename the name of the MIDI file
* @throws IllegalArgumentException if {@code filename} is {@code null}
* @throws IllegalArgumentException if {@code filename} is not a MIDI file
* @throws IllegalArgumentException if {@code filename} cannot be read
*/
public static void play(String filename) {
play(filename, !BACKGROUND);
}
/**
* Plays the specified MIDI file in a background thread.
* It is possible to play multiple MIDI files at the same time, e.g., a background
* musical score and sound effects.
*
* @param filename the name of the MIDI file
* @throws IllegalArgumentException if {@code filename} is {@code null}
* @throws IllegalArgumentException if {@code filename} is not a MIDI file
* @throws IllegalArgumentException if {@code filename} cannot be read
*/
public static void playInBackground(String filename) {
play(filename, BACKGROUND);
}
// helper method to player a MIDI file, either in background thread or not
private static void play(String filename, boolean playInBackground) {
try {
// Get and open a sequencer
// (false to not auto-connect to the default synthesizer)
Sequencer sequencer = MidiSystem.getSequencer(false);
sequencer.open();
// Connect the sequencer to the synthesizer
sequencer.getTransmitter().setReceiver(synthesizer.getReceiver());
// Load the MIDI sequence from file
File file = new File(filename);
if (!file.exists()) {
throw new IllegalArgumentException("MIDI file not found: " + filename);
}
Sequence sequence = MidiSystem.getSequence(file);
// Set the sequence to the sequencer
sequencer.setSequence(sequence);
// Add a listener to stop the sequencer when playback is done
sequencer.addMetaEventListener(new MetaEventListener() {
@Override
public void meta(MetaMessage meta) {
if (meta.getType() == 47) { // 47 is the end-of-track meta event
System.out.println("End of track.");
if (!playInBackground) {
synchronized (lock) {
lock.notify();
}
}
// Use a separate thread to close the sequencer after a delay
new Thread(() -> {
try {
// 1 second delay (to help ensure the last note finishes playing)
Thread.sleep(1000);
}
catch (InterruptedException e) {
System.out.println(e);
}
finally {
sequencer.close();
System.out.println("Sequencer closed.");
}
}).start();
}
}
});
// Start the sequencer
sequencer.start();
System.out.println("Playback started.");
// Wait for playback to complete
if (!playInBackground) {
synchronized (lock) {
while (sequencer.isRunning()) {
lock.wait();
}
}
}
}
catch (MidiUnavailableException e) {
System.out.println(e);
System.out.println("MIDI device unavailable.");
}
catch (InvalidMidiDataException e) {
System.out.println(e);
System.out.println("Invalid MIDI data.");
}
catch (IOException e) {
System.out.println(e);
System.out.println("Error reading MIDI file.");
}
catch (InterruptedException e) {
System.out.println(e);
System.out.println("Playback interrupted.");
}
}
/**
* Saves the sequence of notes to the specified MIDI file.
* The file extension must be {@code .mid} or {@code .midi}.
*
* @param filename the filename
* @throws IllegalArgumentException if {@code filename} is {@code null}
* @throws IllegalArgumentException if {@code filename} is the empty string
* @throws IllegalArgumentException if {@code filename} has wrong extension
* @throws IllegalArgumentException if {@code filename} cannot be written
*/
public static void save(String filename) {
if (filename == null) {
throw new IllegalArgumentException("filename is null");
}
if (filename.length() == 0) {
throw new IllegalArgumentException("argument to save() is the empty string");
}
try {
File file = new File(filename);
// handle MIDI file format first
if (filename.endsWith(".mid") || filename.endsWith(".MID") || filename.endsWith(".midi") || filename.endsWith(".MIDI")) {
MidiSystem.write(sequence, SYNCHRONOUS, file);
}
else {
throw new IllegalArgumentException("file extension for saving must be .mid");
}
}
catch (IOException ioe) {
throw new IllegalArgumentException("unable to save file '" + filename + "'", ioe);
}
}
/**
* Test client - plays the first few notes from Axel F by Harold Faltermeyer.
*
* @param args the command-line arguments (none should be specified)
*/
public static void main(String[] args) {
StdMidi.setTempo(220);
StdMidi.setInstrument(SYNTH_BASS_1);
int[] pitches1 = { F4, REST, AF4, REST, F4, F4, BF4, F4, EF4 };
double[] beats1 = { QN, QN, QN, EN, QN, EN, QN, QN, QN };
int[] pitches2 = { F4, REST, C5, REST, F4, F4, DF5, C5, AF4 };
double[] beats2 = { QN, QN, QN, EN, QN, EN, QN, QN, QN };
int[] pitches3 = { F4, C5, F5, F4, EF4, EF4, C4, G4, F4, REST };
double[] beats3 = { QN, QN, QN, EN, QN, EN, QN, QN, DQN, WN };
for (int i = 0; i < pitches1.length; i++)
StdMidi.playNote(pitches1[i], beats1[i]);
for (int i = 0; i < pitches2.length; i++)
StdMidi.playNote(pitches2[i], beats2[i]);
for (int i = 0; i < pitches3.length; i++)
StdMidi.playNote(pitches3[i], beats3[i]);
StdMidi.save("axelf.mid");
StdMidi.play("axelf.mid");
StdMidi.setInstrument(StdMidi.SPACE_VOICE);
for (int i = 0; i < pitches1.length; i++)
StdMidi.playNote(pitches1[i], beats1[i]);
for (int i = 0; i < pitches2.length; i++)
StdMidi.playNote(pitches2[i], beats2[i]);
for (int i = 0; i < pitches3.length; i++)
StdMidi.playNote(pitches3[i], beats3[i]);
}
}