|
|
@@ -92,47 +92,43 @@ namespace MidiFileHelpers |
|
|
|
const MidiMessageSequence& tempoEvents,
|
|
|
|
const int timeFormat)
|
|
|
|
{
|
|
|
|
if (timeFormat > 0)
|
|
|
|
{
|
|
|
|
double lastTime = 0.0, correctedTime = 0.0;
|
|
|
|
const double tickLen = 1.0 / (timeFormat & 0x7fff);
|
|
|
|
double secsPerTick = 0.5 * tickLen;
|
|
|
|
const int numEvents = tempoEvents.getNumEvents();
|
|
|
|
if (timeFormat < 0)
|
|
|
|
return time / (-(timeFormat >> 8) * (timeFormat & 0xff));
|
|
|
|
|
|
|
|
for (int i = 0; i < numEvents; ++i)
|
|
|
|
{
|
|
|
|
const MidiMessage& m = tempoEvents.getEventPointer(i)->message;
|
|
|
|
const double eventTime = m.getTimeStamp();
|
|
|
|
double lastTime = 0.0, correctedTime = 0.0;
|
|
|
|
const double tickLen = 1.0 / (timeFormat & 0x7fff);
|
|
|
|
double secsPerTick = 0.5 * tickLen;
|
|
|
|
const int numEvents = tempoEvents.getNumEvents();
|
|
|
|
|
|
|
|
if (eventTime >= time)
|
|
|
|
break;
|
|
|
|
for (int i = 0; i < numEvents; ++i)
|
|
|
|
{
|
|
|
|
const MidiMessage& m = tempoEvents.getEventPointer(i)->message;
|
|
|
|
const double eventTime = m.getTimeStamp();
|
|
|
|
|
|
|
|
correctedTime += (eventTime - lastTime) * secsPerTick;
|
|
|
|
lastTime = eventTime;
|
|
|
|
if (eventTime >= time)
|
|
|
|
break;
|
|
|
|
|
|
|
|
if (m.isTempoMetaEvent())
|
|
|
|
secsPerTick = tickLen * m.getTempoSecondsPerQuarterNote();
|
|
|
|
correctedTime += (eventTime - lastTime) * secsPerTick;
|
|
|
|
lastTime = eventTime;
|
|
|
|
|
|
|
|
while (i + 1 < numEvents)
|
|
|
|
{
|
|
|
|
const MidiMessage& m2 = tempoEvents.getEventPointer(i + 1)->message;
|
|
|
|
if (m.isTempoMetaEvent())
|
|
|
|
secsPerTick = tickLen * m.getTempoSecondsPerQuarterNote();
|
|
|
|
|
|
|
|
if (m2.getTimeStamp() != eventTime)
|
|
|
|
break;
|
|
|
|
while (i + 1 < numEvents)
|
|
|
|
{
|
|
|
|
const MidiMessage& m2 = tempoEvents.getEventPointer(i + 1)->message;
|
|
|
|
|
|
|
|
if (m2.isTempoMetaEvent())
|
|
|
|
secsPerTick = tickLen * m2.getTempoSecondsPerQuarterNote();
|
|
|
|
if (m2.getTimeStamp() != eventTime)
|
|
|
|
break;
|
|
|
|
|
|
|
|
++i;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (m2.isTempoMetaEvent())
|
|
|
|
secsPerTick = tickLen * m2.getTempoSecondsPerQuarterNote();
|
|
|
|
|
|
|
|
return correctedTime + (time - lastTime) * secsPerTick;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
return time / (((timeFormat & 0x7fff) >> 8) * (timeFormat & 0xff));
|
|
|
|
++i;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return correctedTime + (time - lastTime) * secsPerTick;
|
|
|
|
}
|
|
|
|
|
|
|
|
// a comparator that puts all the note-offs before note-ons that have the same time
|
|
|
@@ -336,17 +332,20 @@ void MidiFile::convertTimestampTicksToSeconds() |
|
|
|
findAllTempoEvents (tempoEvents);
|
|
|
|
findAllTimeSigEvents (tempoEvents);
|
|
|
|
|
|
|
|
for (int i = 0; i < tracks.size(); ++i)
|
|
|
|
if (timeFormat != 0)
|
|
|
|
{
|
|
|
|
const MidiMessageSequence& ms = *tracks.getUnchecked(i);
|
|
|
|
|
|
|
|
for (int j = ms.getNumEvents(); --j >= 0;)
|
|
|
|
for (int i = 0; i < tracks.size(); ++i)
|
|
|
|
{
|
|
|
|
MidiMessage& m = ms.getEventPointer(j)->message;
|
|
|
|
const MidiMessageSequence& ms = *tracks.getUnchecked(i);
|
|
|
|
|
|
|
|
m.setTimeStamp (MidiFileHelpers::convertTicksToSeconds (m.getTimeStamp(),
|
|
|
|
tempoEvents,
|
|
|
|
timeFormat));
|
|
|
|
for (int j = ms.getNumEvents(); --j >= 0;)
|
|
|
|
{
|
|
|
|
MidiMessage& m = ms.getEventPointer(j)->message;
|
|
|
|
|
|
|
|
m.setTimeStamp (MidiFileHelpers::convertTicksToSeconds (m.getTimeStamp(),
|
|
|
|
tempoEvents,
|
|
|
|
timeFormat));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|