I was experimenting trying to write a Java program that uses MIDI, so the program has to array: notes (which contains all the notes that I want to play) and another array times (which specify when the note should be play) the notes and times are grouped three at a time so I can have multiple chords, the problem is that the program only plays a very brief note and then it stops, what am I doing wrong? Bellow is the code, I am using Java 16.
package application;
import javax.sound.midi.InvalidMidiDataException;
import javax.sound.midi.MidiSystem;
import javax.sound.midi.MidiUnavailableException;
import javax.sound.midi.ShortMessage;
public class App {
public static void main(String[] args)
throws MidiUnavailableException, InvalidMidiDataException, InterruptedException {
var receiver = MidiSystem.getReceiver();
int[] notes = { 60, 64, 67, 60, 65, 67, 55, 59, 62, 55, 60, 62, 53, 57, 60, 53, 58, 60 };
int[] times = { 0, 0, 0, 1000, 1000, 1000, 2000, 2000, 2000, 3000, 3000, 3000, 4000, 4000, 4000, 5000, 5000,
5000 };
for (int i = 0; i < notes.length; i++) {
int note = notes[i];
int time = times[i];
System.out.println(note + ":" + time);
receiver.send(new ShortMessage(ShortMessage.NOTE_ON, 0, note, 127), time * 1000);
receiver.send(new ShortMessage(ShortMessage.NOTE_OFF, 0, note, 127), (time + 1000) * 1000);
}
Thread.sleep(7000);
}
}
I think it has something to do with ShortMessage.NOTE_OFF but I am not sure and I can't figure it out.
The problem has most likely to do with your
timesarray.Taken from the oracle java documentation on sequancers
You are blindly assuming that the numbers (1000, 2000, 3000... etc.) is milliseconds, but defined in the api this is defined as
ticks.Like in any music you need to define the subdivisions, and the pulse per ticks (PPQ) for instance quarter notes, 16th notes etc. etc.
In java this is usually done by defining a sequencer, and with these settings, and then creating a track on said sequencer, and then playing notes on that track.
Here is an example i found on the internet.