Refactor TimingData::ScaleRegion(), fixes 297.
This commit is contained in:
+17
-1
@@ -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
@@ -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
@@ -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;
|
||||
|
||||
@@ -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.
|
||||
|
||||
Reference in New Issue
Block a user