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]); } }