TimingData::ShiftRows violated an important invariant of TimingData: any
given beat can have no more than one StopSegment or BPMSegment--more than one just doesn't make sense. Split out TimingData::InsertRows, TimingData::DeleteRows; delete rows in between before shifting data up.
This commit is contained in:
@@ -319,28 +319,73 @@ void TimingData::ScaleRegion( float fScale, int iStartIndex, int iEndIndex )
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TimingData::ShiftRows( int iStartRow, int iRowsToShift )
|
void TimingData::InsertRows( int iStartRow, int iRowsToAdd )
|
||||||
{
|
{
|
||||||
for( unsigned i = 0; i < m_BPMSegments.size(); i++ )
|
for( unsigned i = 0; i < m_BPMSegments.size(); i++ )
|
||||||
{
|
{
|
||||||
int &iSegStart = m_BPMSegments[i].m_iStartIndex;
|
BPMSegment &bpm = m_BPMSegments[i];
|
||||||
if( iSegStart < iStartRow )
|
if( bpm.m_iStartIndex < iStartRow )
|
||||||
continue;
|
continue;
|
||||||
|
bpm.m_iStartIndex += iRowsToAdd;
|
||||||
iSegStart += iRowsToShift;
|
|
||||||
iSegStart = max( iSegStart, iStartRow );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for( unsigned i = 0; i < m_StopSegments.size(); i++ )
|
for( unsigned i = 0; i < m_StopSegments.size(); i++ )
|
||||||
{
|
{
|
||||||
int &iSegStartRow = m_StopSegments[i].m_iStartRow;
|
StopSegment &stop = m_StopSegments[i];
|
||||||
if( iSegStartRow < iStartRow )
|
if( stop.m_iStartRow < iStartRow )
|
||||||
continue;
|
continue;
|
||||||
iSegStartRow += iRowsToShift;
|
stop.m_iStartRow += iRowsToAdd;
|
||||||
iSegStartRow = max( iSegStartRow, iStartRow );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Delete BPMChanges and StopSegments in [iStartRow,iRowsToDelete), and shift down. */
|
||||||
|
void TimingData::DeleteRows( int iStartRow, int iRowsToDelete )
|
||||||
|
{
|
||||||
|
/* Remember the BPM at the end of the region being deleted. */
|
||||||
|
float fNewBPM = this->GetBPMAtBeat( NoteRowToBeat(iStartRow+iRowsToDelete) );
|
||||||
|
|
||||||
|
/* We're moving rows up. Delete any BPM changes and stops in the region being
|
||||||
|
* deleted. */
|
||||||
|
for( unsigned i = 0; i < m_BPMSegments.size(); i++ )
|
||||||
|
{
|
||||||
|
BPMSegment &bpm = m_BPMSegments[i];
|
||||||
|
if( bpm.m_iStartIndex < iStartRow )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if( bpm.m_iStartIndex < iStartRow+iRowsToDelete )
|
||||||
|
{
|
||||||
|
m_BPMSegments.erase( m_BPMSegments.begin()+i, m_BPMSegments.begin()+i+1 );
|
||||||
|
--i;
|
||||||
|
}
|
||||||
|
|
||||||
|
bpm.m_iStartIndex -= iRowsToDelete;
|
||||||
|
}
|
||||||
|
|
||||||
|
for( unsigned i = 0; i < m_StopSegments.size(); i++ )
|
||||||
|
{
|
||||||
|
StopSegment &stop = m_StopSegments[i];
|
||||||
|
if( stop.m_iStartRow < iStartRow )
|
||||||
|
continue;
|
||||||
|
if( stop.m_iStartRow < iStartRow+iRowsToDelete )
|
||||||
|
{
|
||||||
|
m_StopSegments.erase( m_StopSegments.begin()+i, m_StopSegments.begin()+i+1 );
|
||||||
|
--i;
|
||||||
|
}
|
||||||
|
|
||||||
|
stop.m_iStartRow -= iRowsToDelete;
|
||||||
|
}
|
||||||
|
|
||||||
|
this->SetBPMAtRow( iStartRow, fNewBPM );
|
||||||
|
}
|
||||||
|
|
||||||
|
void TimingData::ShiftRows( int iStartRow, int iRowsToShift )
|
||||||
|
{
|
||||||
|
if( iRowsToShift > 0 )
|
||||||
|
InsertRows( iStartRow, iRowsToShift );
|
||||||
|
else
|
||||||
|
DeleteRows( iStartRow, -iRowsToShift );
|
||||||
|
}
|
||||||
|
|
||||||
bool TimingData::HasBpmChanges() const
|
bool TimingData::HasBpmChanges() const
|
||||||
{
|
{
|
||||||
return m_BPMSegments.size()>1;
|
return m_BPMSegments.size()>1;
|
||||||
|
|||||||
@@ -95,6 +95,8 @@ public:
|
|||||||
// a BPM change or a stop occurs at row 1704, we'll move it to row
|
// a BPM change or a stop occurs at row 1704, we'll move it to row
|
||||||
// 1680).
|
// 1680).
|
||||||
void ScaleRegion( float fScale = 1, int iStartRow = 0, int iEndRow = MAX_NOTE_ROW );
|
void ScaleRegion( float fScale = 1, int iStartRow = 0, int iEndRow = MAX_NOTE_ROW );
|
||||||
|
void InsertRows( int iStartRow, int iRowsToAdd );
|
||||||
|
void DeleteRows( int iStartRow, int iRowsToDelete );
|
||||||
void ShiftRows( int iStartRow, int iRowsToShift );
|
void ShiftRows( int iStartRow, int iRowsToShift );
|
||||||
|
|
||||||
CString m_sFile; // informational only
|
CString m_sFile; // informational only
|
||||||
|
|||||||
Reference in New Issue
Block a user