bool MidiFile::writeTrack(const MidiTrack &t) { write("MTrk", 4); qint64 lenpos = fp->pos(); writeLong(0); // dummy len status = -1; int tick = 0; for (auto i : t.events()) { int ntick = i.first; putvl(ntick - tick); // write tick delta // // if track channel != -1, then use this // channel for all events in this track // if (t.outChannel() != -1) writeEvent(i.second); tick = ntick; } //--------------------------------------------------- // write "End Of Track" Meta // write Track Len // putvl(1); put(0xff); // Meta put(0x2f); // EOT putvl(0); // len 0 qint64 endpos = fp->pos(); fp->seek(lenpos); writeLong(endpos-lenpos-4); // tracklen fp->seek(endpos); return false; }
void MidiFile::writeEvent(const MidiEvent& event) { switch(event.type()) { case ME_NOTEON: writeStatus(ME_NOTEON, event.channel()); put(event.pitch()); put(event.velo()); break; case ME_NOTEOFF: writeStatus(ME_NOTEOFF, event.channel()); put(event.pitch()); put(event.velo()); break; case ME_CONTROLLER: switch(event.controller()) { case CTRL_PROGRAM: writeStatus(ME_PROGRAM, event.channel()); put(event.value() & 0x7f); break; case CTRL_PITCH: { writeStatus(ME_PITCHBEND, event.channel()); int v = event.value() + 8192; put(v & 0x7f); put((v >> 7) & 0x7f); } break; case CTRL_PRESS: writeStatus(ME_AFTERTOUCH, event.channel()); put(event.value() & 0x7f); break; default: writeStatus(ME_CONTROLLER, event.channel()); put(event.controller()); put(event.value() & 0x7f); break; } break; case ME_META: put(ME_META); put(event.metaType()); putvl(event.len()); write(event.edata(), event.len()); resetRunningStatus(); // really ?! break; case ME_SYSEX: put(ME_SYSEX); putvl(event.len() + 1); // including 0xf7 write(event.edata(), event.len()); put(ME_ENDSYSEX); resetRunningStatus(); break; } }