I have a midiFile with 5 different tracks, my goal is to separate each track into a different midiFile:
this is what i have done by now, only the first one is working but the rest no so much:
std::unique_ptr<FileInputStream> fileStream(file.createInputStream());
if (fileStream == nullptr || !fileStream->openedOk())
{
DBG("Failed to open file stream!");
return;
}
MidiFile midiFile;
if (midiFile.readFrom(*fileStream))
{
DBG("MIDI file successfully loaded!");
// Get the time format
short timeFormat = midiFile.getTimeFormat();
// Store global meta events
MidiMessageSequence globalMetaEvents;
// Extract global meta events from the first track
if (midiFile.getNumTracks() > 0)
{
const MidiMessageSequence* firstTrack = midiFile.getTrack(0);
for (int i = 0; i < firstTrack->getNumEvents(); ++i)
{
const MidiMessage& msg = firstTrack->getEventPointer(i)->message;
if (msg.isMetaEvent() && !msg.isTrackNameEvent() && !msg.isTextMetaEvent())
{
globalMetaEvents.addEvent(msg);
}
}
}
for (int i = 0; i < midiFile.getNumTracks(); i++)
{
MidiFile singleTrackFile;
singleTrackFile.setTicksPerQuarterNote(timeFormat);
// Add global meta events to the new file
MidiMessageSequence newTrack = globalMetaEvents;
// Add track events
newTrack.addSequence(*midiFile.getTrack(i), 0, 0, midiFile.getLastTimestamp() + 1);
singleTrackFile.addTrack(newTrack);
// Get the name of the track (if available)
String trackName = "Track_" + String(i + 1);
for (int j = 0; j < newTrack.getNumEvents(); ++j)
{
const MidiMessage& msg = newTrack.getEventPointer(j)->message;
if (msg.isTrackNameEvent())
{
trackName = msg.getTextFromTextMetaEvent();
break;
}
}
// Sanitize the track name for use as a filename
trackName = File::createLegalFileName(trackName);
File newFile = file.getSiblingFile(trackName + ".mid");
if (auto outputStream = std::unique_ptr<FileOutputStream>(newFile.createOutputStream()))
{
singleTrackFile.writeTo(*outputStream);
files.add(newFile);
DBG("File created: " + newFile.getFullPathName());
}
else
{
DBG("Failed to create output stream for: " + newFile.getFullPathName());
}
