bool midi_file_write(const midi & m, const char * fn) { ofstream out(fn, ios_base::out | ios_base::binary); if (out.fail()) return false; printHeader(m, out); int lengths[m.trackCount()]; uint16_t ff = getFileFormat(m); if (m.trackCount()) { lengths[0] = writeTrack(m.tracks(0), out, m.getTicksPerQuaterNote(), true); for (unsigned i = 1; i < m.trackCount(); ++i) { if (ff < 2) lengths[i] = writeTrack(m.tracks(i), out); else lengths[i] = writeTrack(m.tracks(i), out, m.getTicksPerQuaterNote(), true); } } out.seekp(14, ios_base::beg); for (unsigned i = 0; i < m.trackCount(); ++i) { out.seekp(4, ios_base::cur); printUint32_t(lengths[i] - 8, out); out.seekp(lengths[i] - 8, ios_base::cur); } out.close(); return out.fail(); }
void printHeader(const midi& m, ostream &out) { out.write("MThd\0\0\0\6", 8); if (m.trackCount() == 0) throw "No tracks! Cannot save a file."; else if (m.trackCount() == 1) printUint16_t(1, out); else { printUint16_t(getFileFormat(m), out); } printUint16_t(m.trackCount(), out); printUint16_t((uint16_t) m.getTicksPerQuaterNote(), out); }
uint16_t getFileFormat(const midi& m) { if (m.trackCount() <= 1) return 0; uint16_t ff = 1; for (unsigned i = 1; i < m.trackCount(); ++i) { if (m.tracks(i).getTrackTempo() != m.tracks(0).getTrackTempo()) { ff = 2; break; } } return ff; }
void align_midi_events(midi & m, const tracktempo & newtempo) { for (unsigned int i = 0; i < m.trackCount(); i++) { tracktempo oldtempo = m.tracks(i).getTrackTempo(); for (unsigned int j = 0; j < m.tracks(i).eventCount(); j++) { align_midi_event(m.tracks(i), j, newtempo); m.tracks(i).setTrackTempo(newtempo); } } }