Mercurial > hg > svcore
changeset 613:eb1b517f5eeb sv-v1.7
* Support SMPTE timecode in MIDI files (fixes #2739160)
author | Chris Cannam |
---|---|
date | Tue, 29 Sep 2009 10:34:57 +0000 |
parents | 75f154085a4d |
children | 87b81f959706 |
files | data/fileio/MIDIFileReader.cpp data/fileio/MIDIFileReader.h |
diffstat | 2 files changed, 28 insertions(+), 19 deletions(-) [+] |
line wrap: on
line diff
--- a/data/fileio/MIDIFileReader.cpp Fri Sep 25 12:02:22 2009 +0000 +++ b/data/fileio/MIDIFileReader.cpp Tue Sep 29 10:34:57 2009 +0000 @@ -58,7 +58,10 @@ MIDIFileReader::MIDIFileReader(QString path, MIDIFileImportPreferenceAcquirer *acquirer, size_t mainModelSampleRate) : + m_smpte(false), m_timingDivision(0), + m_fps(0), + m_subframes(0), m_format(MIDI_FILE_BAD_FORMAT), m_numberOfTracks(0), m_trackByteCount(0), @@ -416,23 +419,14 @@ m_numberOfTracks = midiBytesToInt(midiHeader.substr(10,2)); m_timingDivision = midiBytesToInt(midiHeader.substr(12,2)); - if (m_format == MIDI_SEQUENTIAL_TRACK_FILE) { -#ifdef MIDI_DEBUG - cerr << "MIDIFileReader::parseHeader()" - << "- can't load sequential track file" - << endl; -#endif - return false; + if (m_timingDivision >= 32768) { + m_smpte = true; + m_fps = 256 - (m_timingDivision >> 8); + m_subframes = (m_timingDivision & 0xff); + } else { + m_smpte = false; } -#ifdef MIDI_DEBUG - if (m_timingDivision < 0) { - cerr << "MIDIFileReader::parseHeader()" - << " - file uses SMPTE timing" - << endl; - } -#endif - return true; } @@ -706,7 +700,7 @@ if (!noteOffFound) { MIDITrack::iterator j = m_midiComposition[track].end(); --j; - (*i)->setDuration((*j)->getTime() - (*i)->getTime()); + (*i)->setDuration((*j)->getTime() - (*i)->getTime()); } } } @@ -957,7 +951,14 @@ for (MIDITrack::const_iterator i = track.begin(); i != track.end(); ++i) { - RealTime rt = getTimeForMIDITime((*i)->getTime()); + RealTime rt; + unsigned long midiTime = (*i)->getTime(); + + if (m_smpte) { + rt = RealTime::frame2RealTime(midiTime, m_fps * m_subframes); + } else { + rt = getTimeForMIDITime(midiTime); + } // We ignore most of these event types for now, though in // theory some of the text ones could usefully be incorporated @@ -1006,8 +1007,13 @@ if ((*i)->getVelocity() == 0) break; // effective note-off else { - RealTime endRT = getTimeForMIDITime((*i)->getTime() + - (*i)->getDuration()); + RealTime endRT; + unsigned long endMidiTime = (*i)->getTime() + (*i)->getDuration(); + if (m_smpte) { + endRT = RealTime::frame2RealTime(endMidiTime, m_fps * m_subframes); + } else { + endRT = getTimeForMIDITime(endMidiTime); + } long startFrame = RealTime::realTime2Frame (rt, model->getSampleRate());
--- a/data/fileio/MIDIFileReader.h Fri Sep 25 12:02:22 2009 +0000 +++ b/data/fileio/MIDIFileReader.h Tue Sep 29 10:34:57 2009 +0000 @@ -108,7 +108,10 @@ bool skipToNextTrack(); + bool m_smpte; int m_timingDivision; // pulses per quarter note + int m_fps; // if smpte + int m_subframes; // if smpte MIDIFileFormatType m_format; unsigned int m_numberOfTracks;