Skip to content

Instantly share code, notes, and snippets.

@dtinth
Created March 25, 2011 09:00
Show Gist options
  • Save dtinth/886571 to your computer and use it in GitHub Desktop.
Save dtinth/886571 to your computer and use it in GitHub Desktop.
the relevant part
enum
{
FOUND_WARP,
FOUND_WARP_DESTINATION,
FOUND_BPM_CHANGE,
FOUND_STOP,
FOUND_MARKER,
NOT_FOUND
};
void TimingData::GetBeatAndBPSFromElapsedTimeNoOffset( float fElapsedTime, float &fBeatOut, float &fBPSOut, bool &bFreezeOut, bool &bDelayOut, int &iWarpBeginOut, float &fWarpLengthOut ) const
{
vector<BPMSegment>::const_iterator itBPMS = m_BPMSegments.begin();
vector<WarpSegment>::const_iterator itWS = m_WarpSegments.begin();
vector<StopSegment>::const_iterator itSS = m_StopSegments.begin();
// these vector must already be sorted
// maybe go through these vectors one time to see if it's really sorted
int iLastRow = 0;
float fLastTime = -m_fBeat0OffsetInSeconds;
float fBPS = GetBPMAtRow(0) / 60.0;
float bIsWarping = false;
float fWarpDestination = 0.0;
for( ;; )
{
int iEventRow = INT_MAX;
int iEventType = NOT_FOUND;
if( bIsWarping && BeatToNoteRow(fWarpDestination) < iEventRow )
{
iEventRow = BeatToNoteRow(fWarpDestination);
iEventType = FOUND_WARP_DESTINATION;
}
if( itWS != m_WarpSegments.end() && itWS->m_iStartRow < iEventRow )
{
iEventRow = itWS->m_iStartRow;
iEventType = FOUND_WARP;
}
if( itBPMS != m_BPMSegments.end() && itBPMS->m_iStartRow < iEventRow )
{
iEventRow = itBPMS->m_iStartRow;
iEventType = FOUND_BPM_CHANGE;
}
if( itSS != m_StopSegments.end() && itSS->m_iStartRow < iEventRow )
{
iEventRow = itSS->m_iStartRow;
iEventType = FOUND_STOP;
}
if( iEventType == NOT_FOUND )
{
break;
}
float fTimeToNextEvent = bIsWarping ? 0 : NoteRowToBeat( iEventRow - iLastRow ) / fBPS;
float fNextEventTime = fLastTime + fTimeToNextEvent;
if ( fElapsedTime < fNextEventTime )
{
break;
}
fLastTime = fNextEventTime;
switch( iEventType )
{
case FOUND_WARP_DESTINATION:
bIsWarping = false;
break;
case FOUND_WARP:
bIsWarping = true;
if( itWS->m_fEndBeat > fWarpDestination )
{
fWarpDestination = itWS->m_fEndBeat;
}
itWS ++;
break;
case FOUND_BPM_CHANGE:
fBPS = itBPMS->m_fBPS;
itBPMS ++;
break;
case FOUND_STOP:
fTimeToNextEvent = bIsWarping ? 0 : itSS->m_fStopSeconds;
fNextEventTime = fLastTime + fTimeToNextEvent;
const bool bIsDelay = itSS->m_bDelay;
if ( fElapsedTime < fNextEventTime )
{
bFreezeOut = !bIsDelay;
bDelayOut = bIsDelay;
fBeatOut = NoteRowToBeat( itSS->m_iStartRow );
fBPSOut = fBPS;
return;
}
fLastTime = fNextEventTime;
itSS ++;
break;
}
iLastRow = iEventRow;
}
fBeatOut = NoteRowToBeat( iLastRow ) + (fElapsedTime - fLastTime) * fBPS;
fBPSOut = fBPS;
}
float TimingData::GetElapsedTimeFromBeatNoOffset( float fBeat ) const
{
vector<BPMSegment>::const_iterator itBPMS = m_BPMSegments.begin();
vector<WarpSegment>::const_iterator itWS = m_WarpSegments.begin();
vector<StopSegment>::const_iterator itSS = m_StopSegments.begin();
int iLastRow = 0;
float fLastTime = -m_fBeat0OffsetInSeconds;
float fBPS = GetBPMAtRow(0) / 60.0;
float bIsWarping = false;
float fWarpDestination = 0.0;
for( ;; )
{
int iEventRow = INT_MAX;
int iEventType = NOT_FOUND;
if( bIsWarping && BeatToNoteRow(fWarpDestination) < iEventRow )
{
iEventRow = BeatToNoteRow(fWarpDestination);
iEventType = FOUND_WARP_DESTINATION;
}
if( itWS != m_WarpSegments.end() && itWS->m_iStartRow < iEventRow )
{
iEventRow = itWS->m_iStartRow;
iEventType = FOUND_WARP;
}
if( itBPMS != m_BPMSegments.end() && itBPMS->m_iStartRow < iEventRow )
{
iEventRow = itBPMS->m_iStartRow;
iEventType = FOUND_BPM_CHANGE;
}
if( itSS != m_StopSegments.end() && itSS->m_bDelay && itSS->m_iStartRow < iEventRow )
{
iEventRow = itSS->m_iStartRow;
iEventType = FOUND_STOP;
}
if( BeatToNoteRow(fBeat) < iEventRow )
{
iEventRow = BeatToNoteRow(fBeat);
iEventType = FOUND_MARKER;
}
if( itSS != m_StopSegments.end() && !itSS->m_bDelay && itSS->m_iStartRow < iEventRow )
{
iEventRow = itSS->m_iStartRow;
iEventType = FOUND_STOP;
}
float fTimeToNextEvent = bIsWarping ? 0 : NoteRowToBeat( iEventRow - iLastRow ) / fBPS;
float fNextEventTime = fLastTime + fTimeToNextEvent;
fLastTime = fNextEventTime;
switch( iEventType )
{
case FOUND_WARP_DESTINATION:
bIsWarping = false;
break;
case FOUND_WARP:
bIsWarping = true;
if( itWS->m_fEndBeat > fWarpDestination )
{
fWarpDestination = itWS->m_fEndBeat;
}
itWS ++;
break;
case FOUND_BPM_CHANGE:
fBPS = itBPMS->m_fBPS;
itBPMS ++;
break;
case FOUND_STOP:
fTimeToNextEvent = bIsWarping ? 0 : itSS->m_fStopSeconds;
fNextEventTime = fLastTime + fTimeToNextEvent;
fLastTime = fNextEventTime;
itSS ++;
break;
case FOUND_MARKER:
return fLastTime;
}
iLastRow = iEventRow;
}
// won't reach here, unless BeatToNoteRow(fBeat > INT_MAX) (impossible)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment