Refactor TimingData::ScaleRegion(), fixes 297.

This commit is contained in:
Thai Pangsakulyanont
2011-06-26 13:43:30 +07:00
parent c71789b7e7
commit 68f95ce056
4 changed files with 70 additions and 124 deletions
+17 -1
View File
@@ -334,7 +334,23 @@ static inline float ToBeat(int row) { return NoteRowToBeat(row); }
*/
static inline float ToBeat(float beat) { return beat; }
/**
* @brief Scales the position.
* @param T start - the starting row of the scaling region
* @param T length - the length of the scaling region
* @param T newLength - the new length of the scaling region
* @param T position - the position to scale
* @return T the scaled position
*/
template<typename T>
inline T ScalePosition( T start, T length, T newLength, T position )
{
if( position < start )
return position;
if( position >= start + length )
return position - length + newLength;
return start + (position - start) * newLength / length;
}
#endif
+14 -121
View File
@@ -1026,149 +1026,43 @@ void TimingData::ScaleRegion( float fScale, int iStartIndex, int iEndIndex, bool
ASSERT( iStartIndex >= 0 );
ASSERT( iStartIndex < iEndIndex );
int length = iEndIndex - iStartIndex;
int newLength = lrintf( fScale * length );
for ( unsigned i = 0; i < m_BPMSegments.size(); i++ )
{
BPMSegment &b = m_BPMSegments[i];
const int iSegStart = b.GetRow();
if( iSegStart < iStartIndex )
continue;
else if( iSegStart > iEndIndex )
b.SetRow( b.GetRow() + lrintf( (iEndIndex - iStartIndex) * (fScale - 1) ) );
else
b.SetRow( lrintf( (iSegStart - iStartIndex) * fScale ) + iStartIndex );
}
m_BPMSegments[i].Scale( iStartIndex, length, newLength );
for( unsigned i = 0; i < m_StopSegments.size(); i++ )
{
StopSegment &s = m_StopSegments[i];
const int iSegStartRow = s.GetRow();
if( iSegStartRow < iStartIndex )
continue;
else if( iSegStartRow > iEndIndex )
s.SetRow(s.GetRow() + lrintf((iEndIndex - iStartIndex) * (fScale - 1)));
else
s.SetRow(lrintf((iSegStartRow - iStartIndex) * fScale) + iStartIndex);
}
m_StopSegments[i].Scale( iStartIndex, length, newLength );
for( unsigned i = 0; i < m_vTimeSignatureSegments.size(); i++ )
{
TimeSignatureSegment &t = m_vTimeSignatureSegments[i];
const int iSegStartRow = t.GetRow();
if( iSegStartRow < iStartIndex )
continue;
else if( iSegStartRow > iEndIndex )
t.SetRow(t.GetRow() + lrintf((iEndIndex - iStartIndex) * (fScale - 1)));
else
t.SetRow(lrintf((iSegStartRow - iStartIndex) * fScale) + iStartIndex);
}
m_vTimeSignatureSegments[i].Scale( iStartIndex, length, newLength );
for( unsigned i = 0; i < m_WarpSegments.size(); i++ )
{
WarpSegment &w = m_WarpSegments[i];
const int iSegStartRow = w.GetRow();
const int iSegEndRow = iSegStartRow + BeatToNoteRow( w.GetLength() );
if( iSegEndRow >= iStartIndex )
{
if( iSegEndRow > iEndIndex )
w.SetLength(w.GetLength() +
NoteRowToBeat(lrintf((iEndIndex - iStartIndex) * (fScale - 1))));
else
w.SetLength(NoteRowToBeat(lrintf((iSegEndRow - iStartIndex) * fScale)));
}
if( iSegStartRow < iStartIndex )
continue;
else if( iSegStartRow > iEndIndex )
w.SetRow(w.GetRow() + lrintf((iEndIndex - iStartIndex) * (fScale - 1)));
else
w.SetRow(lrintf((iSegStartRow - iStartIndex) * fScale) + iStartIndex);
}
m_WarpSegments[i].Scale( iStartIndex, length, newLength );
for ( unsigned i = 0; i < m_TickcountSegments.size(); i++ )
{
TickcountSegment &t = m_TickcountSegments[i];
const int iSegStart = t.GetRow();
if( iSegStart < iStartIndex )
continue;
else if( iSegStart > iEndIndex )
t.SetRow(t.GetRow() + lrintf( (iEndIndex - iStartIndex) * (fScale - 1) ));
else
t.SetRow(lrintf( (iSegStart - iStartIndex) * fScale ) + iStartIndex);
}
m_TickcountSegments[i].Scale( iStartIndex, length, newLength );
for ( unsigned i = 0; i < m_ComboSegments.size(); i++ )
{
ComboSegment &c = m_ComboSegments[i];
const int iSegStart = c.GetRow();
if( iSegStart < iStartIndex )
continue;
else if( iSegStart > iEndIndex )
c.SetRow(c.GetRow() + lrintf( (iEndIndex - iStartIndex) * (fScale - 1) ));
else
c.SetRow(lrintf( (iSegStart - iStartIndex) * fScale ) + iStartIndex);
}
m_ComboSegments[i].Scale( iStartIndex, length, newLength );
for ( unsigned i = 0; i < m_LabelSegments.size(); i++ )
{
LabelSegment &l = m_LabelSegments[i];
const int iSegStart = l.GetRow();
if( iSegStart < iStartIndex )
continue;
else if( iSegStart > iEndIndex )
l.SetRow(l.GetRow() + lrintf( (iEndIndex - iStartIndex) * (fScale - 1) ));
else
l.SetRow(lrintf( (iSegStart - iStartIndex) * fScale ) + iStartIndex);
}
m_LabelSegments[i].Scale( iStartIndex, length, newLength );
for ( unsigned i = 0; i < m_SpeedSegments.size(); i++ )
{
SpeedSegment &s = m_SpeedSegments[i];
const int iSegStart = s.GetRow();
if( iSegStart < iStartIndex )
continue;
else if( iSegStart > iEndIndex )
s.SetRow(s.GetRow() + lrintf( (iEndIndex - iStartIndex) * (fScale - 1) ));
else
s.SetRow(lrintf( (iSegStart - iStartIndex) * fScale ) + iStartIndex);
}
m_SpeedSegments[i].Scale( iStartIndex, length, newLength );
for( unsigned i = 0; i < m_FakeSegments.size(); i++ )
{
FakeSegment &f = m_FakeSegments[i];
const int iSegStartRow = f.GetRow();
const int iSegEndRow = iSegStartRow + BeatToNoteRow( f.GetLength() );
if( iSegEndRow >= iStartIndex )
{
if( iSegEndRow > iEndIndex )
f.SetLength(f.GetLength()
+ NoteRowToBeat(lrintf((iEndIndex - iStartIndex) * (fScale - 1))));
else
f.SetLength(NoteRowToBeat(lrintf((iSegEndRow - iStartIndex) * fScale)));
}
if( iSegStartRow < iStartIndex )
continue;
else if( iSegStartRow > iEndIndex )
f.SetRow(f.GetRow()
+ lrintf((iEndIndex - iStartIndex) * (fScale - 1)));
else
f.SetRow(lrintf((iSegStartRow - iStartIndex) * fScale) + iStartIndex);
}
m_FakeSegments[i].Scale( iStartIndex, length, newLength );
for( unsigned i = 0; i < m_ScrollSegments.size(); i++ )
{
ScrollSegment &s = m_ScrollSegments[i];
const int iSegStartRow = s.GetRow();
if( iSegStartRow < iStartIndex )
continue;
else if( iSegStartRow > iEndIndex )
s.SetRow(s.GetRow() + lrintf((iEndIndex - iStartIndex) * (fScale - 1)));
else
s.SetRow(lrintf((iSegStartRow - iStartIndex) * fScale) + iStartIndex);
}
m_ScrollSegments[i].Scale( iStartIndex, length, newLength );
// adjust BPM changes to preserve timing
if( bAdjustBPM )
{
int iNewEndIndex = lrintf( (iEndIndex - iStartIndex) * fScale ) + iStartIndex;
int iNewEndIndex = iStartIndex + newLength;
float fEndBPMBeforeScaling = GetBPMAtRow(iNewEndIndex);
// adjust BPM changes "between" iStartIndex and iNewEndIndex
@@ -1186,7 +1080,6 @@ void TimingData::ScaleRegion( float fScale, int iStartIndex, int iEndIndex, bool
// set BPM at iStartIndex and iNewEndIndex.
SetBPMAtRow( iStartIndex, GetBPMAtRow(iStartIndex) * fScale );
SetBPMAtRow( iNewEndIndex, fEndBPMBeforeScaling );
}
}
+27 -2
View File
@@ -5,7 +5,6 @@
BaseTimingSegment::~BaseTimingSegment() {}
void BaseTimingSegment::SetRow(const int s)
{
this->startingRow = s;
@@ -26,6 +25,11 @@ float BaseTimingSegment::GetBeat() const
return NoteRowToBeat(GetRow());
}
void BaseTimingSegment::Scale( int start, int length, int newLength )
{
SetRow( ScalePosition( start, length, newLength, GetRow() ) );
}
/* ======================================================
Here comes the actual timing segments implementation!! */
@@ -40,6 +44,16 @@ void FakeSegment::SetLength(const float b)
this->lengthBeats = b;
}
void FakeSegment::Scale( int start, int length, int newLength )
{
float startBeat = GetBeat();
float endBeat = startBeat + GetLength();
float newStartBeat = ScalePosition( NoteRowToBeat(start), NoteRowToBeat(length), NoteRowToBeat(newLength), startBeat );
float newEndBeat = ScalePosition( NoteRowToBeat(start), NoteRowToBeat(length), NoteRowToBeat(newLength), endBeat );
SetLength( newEndBeat - newStartBeat );
TimingSegment<FakeSegment>::Scale( start, length, newLength );
}
bool FakeSegment::operator<( const FakeSegment &other ) const
{
LTCOMPARE(GetRow());
@@ -60,8 +74,19 @@ void WarpSegment::SetLength(const float b)
this->lengthBeats = b;
}
void WarpSegment::Scale( int start, int length, int newLength )
{
// XXX: this function is duplicated, there should be a better way
float startBeat = GetBeat();
float endBeat = startBeat + GetLength();
float newStartBeat = ScalePosition( NoteRowToBeat(start), NoteRowToBeat(length), NoteRowToBeat(newLength), startBeat );
float newEndBeat = ScalePosition( NoteRowToBeat(start), NoteRowToBeat(length), NoteRowToBeat(newLength), endBeat );
SetLength( newEndBeat - newStartBeat );
TimingSegment<WarpSegment>::Scale( start, length, newLength );
}
bool WarpSegment::operator<( const WarpSegment &other ) const
{
{
LTCOMPARE(GetRow());
LTCOMPARE(GetLength());
return false;
+12
View File
@@ -27,6 +27,14 @@ struct BaseTimingSegment
virtual ~BaseTimingSegment();
/**
* @brief Scales itself.
* @param start Starting row
* @param length Length in rows
* @param newLength The new length in rows
*/
virtual void Scale( int start, int length, int newLength );
/**
* @brief Set the starting row of the BaseTimingSegment.
*
@@ -177,6 +185,8 @@ struct FakeSegment : public TimingSegment<FakeSegment>
* @param b the length in beats. */
void SetLength(const float b);
void Scale( int start, int length, int newLength );
/**
* @brief Compares two FakeSegments to see if one is less than the other.
* @param other the other FakeSegment to compare to.
@@ -236,6 +246,8 @@ struct WarpSegment : public TimingSegment<WarpSegment>
* @param b the length in beats. */
void SetLength(const float b);
void Scale( int start, int length, int newLength );
/*
* @brief Compares two WarpSegments to see if one is less than the other.
* @param other the other WarpSegment to compare to.