/* Holds data for translating beats<->seconds. */ #include "global.h" #include "TimingData.h" #include "PrefsManager.h" TimingData::TimingData() { m_fBeat0OffsetInSeconds = 0; } static int CompareBPMSegments(const BPMSegment &seg1, const BPMSegment &seg2) { return seg1.m_fStartBeat < seg2.m_fStartBeat; } void SortBPMSegmentsArray( vector &arrayBPMSegments ) { sort( arrayBPMSegments.begin(), arrayBPMSegments.end(), CompareBPMSegments ); } static int CompareStopSegments(const StopSegment &seg1, const StopSegment &seg2) { return seg1.m_fStartBeat < seg2.m_fStartBeat; } void SortStopSegmentsArray( vector &arrayStopSegments ) { sort( arrayStopSegments.begin(), arrayStopSegments.end(), CompareStopSegments ); } void TimingData::GetActualBPM( float &fMinBPMOut, float &fMaxBPMOut ) const { fMaxBPMOut = 0; fMinBPMOut = 100000; // inf for( unsigned i=0; i 0 && fabsf(m_BPMSegments[i-1].m_fBPM - fBPM) < 0.009f ) m_BPMSegments.erase( m_BPMSegments.begin()+i, m_BPMSegments.begin()+i+1); else m_BPMSegments[i].m_fBPM = fBPM; } } float TimingData::GetBPMAtBeat( float fBeat ) const { unsigned i; for( i=0; i fBeat ) break; return m_BPMSegments[i].m_fBPM; } BPMSegment& TimingData::GetBPMSegmentAtBeat( float fBeat ) { unsigned i; for( i=0; i fBeat ) break; return m_BPMSegments[i]; } void TimingData::GetBeatAndBPSFromElapsedTime( float fElapsedTime, float &fBeatOut, float &fBPSOut, bool &bFreezeOut ) const { // LOG->Trace( "GetBeatAndBPSFromElapsedTime( fElapsedTime = %f )", fElapsedTime ); // This function is a nightmare. Don't even try to understand it. :-) fElapsedTime += PREFSMAN->m_fGlobalOffsetSeconds; fElapsedTime += m_fBeat0OffsetInSeconds; for( unsigned i=0; i fSecondsInThisSegment ) { // this BPMSegement is NOT the current segment fElapsedTime -= fSecondsInThisSegment; continue; } // this BPMSegment IS the current segment float fBeatEstimate = fStartBeatThisSegment + fElapsedTime*fBPS; for( j=0; j m_StopSegments[j].m_fStartBeat || m_StopSegments[j].m_fStartBeat > fStartBeatNextSegment ) continue; // this freeze lies within this BPMSegment if( m_StopSegments[j].m_fStartBeat > fBeatEstimate ) break; fElapsedTime -= m_StopSegments[j].m_fStopSeconds; // re-estimate fBeatEstimate = fStartBeatThisSegment + fElapsedTime*fBPS; if( fBeatEstimate < m_StopSegments[j].m_fStartBeat ) { fBeatOut = m_StopSegments[j].m_fStartBeat; fBPSOut = fBPS; bFreezeOut = true; return; } } fBeatOut = fBeatEstimate; fBPSOut = fBPS; bFreezeOut = false; return; } } float TimingData::GetElapsedTimeFromBeat( float fBeat ) const { float fElapsedTime = 0; fElapsedTime -= PREFSMAN->m_fGlobalOffsetSeconds; fElapsedTime -= m_fBeat0OffsetInSeconds; for( unsigned j=0; j= fBeat ) break; fElapsedTime += m_StopSegments[j].m_fStopSeconds; } for( unsigned i=0; i