I bought a VDRUM kit not long ago that has a MIDI out. I've had a raspberry pi lying around here from a previous project and I've had the idea to use that small computer as recorder.
So I've written a headless application that runs on the PI and listens to the MIDI Out port of the VDRUM kit. Upon receiving an input other than silence i start recording via the jdk libraries and place it on a samba server with timestamp.
That way I save everything I ever play. Now I've setup my audio workstation to receive those MIDI files from the samba share and I noticed, that they often have a very long "silent" part in the beginning of the MIDI file.
Is there a way to programatically remove the silence at the beginning of a midi sequence? I'm new to this MIDI stuff and still learning.
Here's the code that starts and stops the recording:
public void send(MidiMessage message, long timeStamp) {
if (message.getStatus() == 254) {
if (isRecording && timestampOfLastAction.isBefore(LocalTime.now().minus(5, ChronoUnit.SECONDS))) {
String userDirectory = "/home/pi/";
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd HH-mm-ss");
LocalDateTime now = LocalDateTime.now();
String fileName = dtf.format(now) + ".mid";
sequencer.stopRecording();
File midiFile = new File(userDirectory + "/MidiRecorder/" + fileName);
try {
Sequence sequence = sequencer.getSequence();
MidiSystem.write(sequence, 0, midiFile);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Logger.getGlobal().info("STOPPED RECORDING: " + LocalTime.now().toString());
isRecording = false;
}
} else {
timestampOfLastAction = LocalTime.now();
if (!isRecording) {
isRecording = true;
sequencer = null;
try {
sequencer = MidiSystem.getSequencer();
Transmitter transmitter1;
Receiver receiver;
// Open a connection to the default sequencer (as specified by MidiSystem)
sequencer.open();
// Get the transmitter class from your input device
transmitter1 = this.midiDevice.getTransmitter();
// Get the receiver class from your sequencer
receiver = sequencer.getReceiver();
transmitter1.setReceiver(receiver);
Sequence seq = new Sequence(Sequence.PPQ, 24);
// And of course a track to record the input on
Track currentTrack = seq.createTrack();
// Do some sequencer settings
sequencer.setSequence(seq);
sequencer.setTickPosition(0);
sequencer.recordEnable(currentTrack, -1);
// And start recording
sequencer.startRecording();
Logger.getGlobal().info("STARTED RECORDING: " + LocalTime.now().toString());
} catch (Exception e) {
// TODO: handle exception
} finally {
}
}
}
}
You need to shift all MidiEvents
of the Sequence
to remove the leading silence.
private void removeLeadingSilence(Sequence sequence)
{
// Find first event
long firstEventTick = Long.MAX_VALUE;
for (Track track : sequence.getTracks())
{
if (track.size() > 0)
{
firstEventTick = Math.min(firstEventTick, track.get(0).getTick());
}
}
// Shift all events
for (Track track : sequence.getTracks())
{
for (int i = 0; i < track.size(); i++)
{
MidiEvent me = track.get(i);
me.setTick(me.getTick() - firstEventTick);
}
}
}