Simplify and speed up loading (very very slightly). It would be fastest to add all BPM/stop segments to the array and then sort it once (n log n). It was sorting after every insertion (n^2 log n). This now does simple insertion sort so it's n^2 in the worst case but since upper_bound does a binary search, if the BPM segments are in order this will take n log n in the best case.
That said, you'll notice no difference unless you had thousands of BPM changes in a file.
This commit is contained in:
@@ -4,66 +4,35 @@
|
|||||||
#include "RageUtil.h"
|
#include "RageUtil.h"
|
||||||
#include "RageLog.h"
|
#include "RageLog.h"
|
||||||
#include "NoteTypes.h"
|
#include "NoteTypes.h"
|
||||||
|
#include "Foreach.h"
|
||||||
#include <float.h>
|
#include <float.h>
|
||||||
|
|
||||||
void BPMSegment::SetBPM( float f )
|
|
||||||
{
|
|
||||||
m_fBPS = f / 60.0f;
|
|
||||||
}
|
|
||||||
|
|
||||||
float BPMSegment::GetBPM() const
|
|
||||||
{
|
|
||||||
return m_fBPS * 60.0f;
|
|
||||||
}
|
|
||||||
|
|
||||||
TimingData::TimingData()
|
TimingData::TimingData()
|
||||||
{
|
{
|
||||||
m_fBeat0OffsetInSeconds = 0;
|
m_fBeat0OffsetInSeconds = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int CompareBPMSegments(const BPMSegment &seg1, const BPMSegment &seg2)
|
|
||||||
{
|
|
||||||
return seg1.m_iStartIndex < seg2.m_iStartIndex;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SortBPMSegmentsArray( vector<BPMSegment> &arrayBPMSegments )
|
|
||||||
{
|
|
||||||
sort( arrayBPMSegments.begin(), arrayBPMSegments.end(), CompareBPMSegments );
|
|
||||||
}
|
|
||||||
|
|
||||||
static int CompareStopSegments(const StopSegment &seg1, const StopSegment &seg2)
|
|
||||||
{
|
|
||||||
return seg1.m_iStartRow < seg2.m_iStartRow;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SortStopSegmentsArray( vector<StopSegment> &arrayStopSegments )
|
|
||||||
{
|
|
||||||
sort( arrayStopSegments.begin(), arrayStopSegments.end(), CompareStopSegments );
|
|
||||||
}
|
|
||||||
|
|
||||||
void TimingData::GetActualBPM( float &fMinBPMOut, float &fMaxBPMOut ) const
|
void TimingData::GetActualBPM( float &fMinBPMOut, float &fMaxBPMOut ) const
|
||||||
{
|
{
|
||||||
fMinBPMOut = FLT_MAX;
|
fMinBPMOut = FLT_MAX;
|
||||||
fMaxBPMOut = 0;
|
fMaxBPMOut = 0;
|
||||||
for( unsigned i=0; i<m_BPMSegments.size(); i++ )
|
FOREACH_CONST( BPMSegment, m_BPMSegments, seg )
|
||||||
{
|
{
|
||||||
const BPMSegment &seg = m_BPMSegments[i];
|
const float fBPM = seg->GetBPM();
|
||||||
fMaxBPMOut = max( seg.m_fBPS * 60.0f, fMaxBPMOut );
|
fMaxBPMOut = max( fBPM, fMaxBPMOut );
|
||||||
fMinBPMOut = min( seg.m_fBPS * 60.0f, fMinBPMOut );
|
fMinBPMOut = min( fBPM, fMinBPMOut );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void TimingData::AddBPMSegment( const BPMSegment &seg )
|
void TimingData::AddBPMSegment( const BPMSegment &seg )
|
||||||
{
|
{
|
||||||
m_BPMSegments.push_back( seg );
|
m_BPMSegments.insert( upper_bound(m_BPMSegments.begin(), m_BPMSegments.end(), seg), seg );
|
||||||
SortBPMSegmentsArray( m_BPMSegments );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void TimingData::AddStopSegment( const StopSegment &seg )
|
void TimingData::AddStopSegment( const StopSegment &seg )
|
||||||
{
|
{
|
||||||
m_StopSegments.push_back( seg );
|
m_StopSegments.insert( upper_bound(m_StopSegments.begin(), m_StopSegments.end(), seg), seg );
|
||||||
SortStopSegmentsArray( m_StopSegments );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Change an existing BPM segment, merge identical segments together or insert a new one. */
|
/* Change an existing BPM segment, merge identical segments together or insert a new one. */
|
||||||
@@ -187,10 +156,7 @@ BPMSegment& TimingData::GetBPMSegmentAtBeat( float fBeat )
|
|||||||
{
|
{
|
||||||
static BPMSegment empty;
|
static BPMSegment empty;
|
||||||
if( m_BPMSegments.empty() )
|
if( m_BPMSegments.empty() )
|
||||||
{
|
|
||||||
empty = BPMSegment();
|
|
||||||
return empty;
|
return empty;
|
||||||
}
|
|
||||||
|
|
||||||
int i = GetBPMSegmentIndexAtBeat( fBeat );
|
int i = GetBPMSegmentIndexAtBeat( fBeat );
|
||||||
return m_BPMSegments[i];
|
return m_BPMSegments[i];
|
||||||
|
|||||||
@@ -9,13 +9,13 @@
|
|||||||
|
|
||||||
struct BPMSegment
|
struct BPMSegment
|
||||||
{
|
{
|
||||||
BPMSegment() { m_iStartIndex = -1; m_fBPS = -1; }
|
BPMSegment() : m_iStartIndex(-1), m_fBPS(-1.0f) { }
|
||||||
BPMSegment( int s, float b ) { m_iStartIndex = s; m_fBPS = b/60.0f; }
|
BPMSegment( int s, float b ) { m_iStartIndex = max( 0, s ); SetBPM( b ); }
|
||||||
int m_iStartIndex;
|
int m_iStartIndex;
|
||||||
float m_fBPS;
|
float m_fBPS;
|
||||||
|
|
||||||
void SetBPM( float f );
|
void SetBPM( float f ) { m_fBPS = f / 60.0f; }
|
||||||
float GetBPM() const;
|
float GetBPM() const { return m_fBPS * 60.0f; }
|
||||||
|
|
||||||
bool operator==( const BPMSegment &other ) const
|
bool operator==( const BPMSegment &other ) const
|
||||||
{
|
{
|
||||||
@@ -24,12 +24,13 @@ struct BPMSegment
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
bool operator!=( const BPMSegment &other ) const { return !operator==(other); }
|
bool operator!=( const BPMSegment &other ) const { return !operator==(other); }
|
||||||
|
bool operator<( const BPMSegment &other ) const { return m_iStartIndex < other.m_iStartIndex; }
|
||||||
};
|
};
|
||||||
|
|
||||||
struct StopSegment
|
struct StopSegment
|
||||||
{
|
{
|
||||||
StopSegment() { m_fStopSeconds = -1; m_iStartRow = -1; }
|
StopSegment() : m_iStartRow(-1), m_fStopSeconds(-1.0f) { }
|
||||||
StopSegment( int s, float f ) { m_iStartRow = s; m_fStopSeconds = f; }
|
StopSegment( int s, float f ) { m_iStartRow = max( 0, s ); m_fStopSeconds = max( 0.0f, f ); }
|
||||||
int m_iStartRow;
|
int m_iStartRow;
|
||||||
float m_fStopSeconds;
|
float m_fStopSeconds;
|
||||||
|
|
||||||
@@ -40,6 +41,7 @@ struct StopSegment
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
bool operator!=( const StopSegment &other ) const { return !operator==(other); }
|
bool operator!=( const StopSegment &other ) const { return !operator==(other); }
|
||||||
|
bool operator<( const StopSegment &other ) const { return m_iStartRow < other.m_iStartRow; }
|
||||||
};
|
};
|
||||||
|
|
||||||
class TimingData
|
class TimingData
|
||||||
|
|||||||
Reference in New Issue
Block a user