diff --git a/src/Background.cpp b/src/Background.cpp index d8cef11d4e..2761fd3b18 100644 --- a/src/Background.cpp +++ b/src/Background.cpp @@ -426,9 +426,9 @@ void BackgroundImpl::LoadFromRandom( float fFirstBeat, float fEndBeat, const Bac { vector::const_iterator next = iter; next++; - int iSegmentEndRow = (next == timing.m_vTimeSignatureSegments.end()) ? iEndRow : next->m_iStartRow; + int iSegmentEndRow = (next == timing.m_vTimeSignatureSegments.end()) ? iEndRow : next->GetRow(); - for( int i=max(iter->m_iStartRow,iStartRow); iGetNoteRowsPerMeasure() ) + for( int i=max(iter->GetRow(),iStartRow); iGetNoteRowsPerMeasure() ) { // Don't fade. It causes frame rate dip, especially on slower machines. BackgroundDef bd = m_Layer[0].CreateRandomBGA( m_pSong, change.m_def.m_sEffect, m_RandomBGAnimations, this ); @@ -450,7 +450,7 @@ void BackgroundImpl::LoadFromRandom( float fFirstBeat, float fEndBeat, const Bac bool bAtBeginningOfMeasure = false; FOREACH_CONST( TimeSignatureSegment, timing.m_vTimeSignatureSegments, iter ) { - if( (bpmseg.GetRow() - iter->m_iStartRow) % iter->GetNoteRowsPerMeasure() == 0 ) + if( (bpmseg.GetRow() - iter->GetRow()) % iter->GetNoteRowsPerMeasure() == 0 ) { bAtBeginningOfMeasure = true; break; diff --git a/src/NoteField.cpp b/src/NoteField.cpp index 3abb6bf177..5df25d3f79 100644 --- a/src/NoteField.cpp +++ b/src/NoteField.cpp @@ -857,16 +857,16 @@ void NoteField::DrawPrimitives() { vector::const_iterator next = iter; next++; - int iSegmentEndRow = (next == vTimeSignatureSegments.end()) ? iLastRowToDraw : next->m_iStartRow; + int iSegmentEndRow = (next == vTimeSignatureSegments.end()) ? iLastRowToDraw : next->GetRow(); // beat bars every 16th note - int iDrawBeatBarsEveryRows = BeatToNoteRow( ((float)iter->m_iDenominator) / 4 ) / 4; + int iDrawBeatBarsEveryRows = BeatToNoteRow( ((float)iter->GetDen()) / 4 ) / 4; // In 4/4, every 16th beat bar is a measure - int iMeasureBarFrequency = iter->m_iNumerator * 4; + int iMeasureBarFrequency = iter->GetNum() * 4; int iBeatBarsDrawn = 0; - for( int i=iter->m_iStartRow; i < iSegmentEndRow; i += iDrawBeatBarsEveryRows ) + for( int i=iter->GetRow(); i < iSegmentEndRow; i += iDrawBeatBarsEveryRows ) { bool bMeasureBar = iBeatBarsDrawn % iMeasureBarFrequency == 0; BeatBarType type = quarter_beat; @@ -933,11 +933,11 @@ void NoteField::DrawPrimitives() // Time Signature text FOREACH_CONST( TimeSignatureSegment, timing.m_vTimeSignatureSegments, seg ) { - if( seg->m_iStartRow >= iFirstRowToDraw && seg->m_iStartRow <= iLastRowToDraw ) + if( seg->GetRow() >= iFirstRowToDraw && seg->GetRow() <= iLastRowToDraw ) { - float fBeat = NoteRowToBeat(seg->m_iStartRow); + float fBeat = seg->GetBeat(); if( IS_ON_SCREEN(fBeat) ) - DrawTimeSignatureText( fBeat, seg->m_iNumerator, seg->m_iDenominator ); + DrawTimeSignatureText( fBeat, seg->GetNum(), seg->GetDen() ); } } diff --git a/src/NotesLoaderMidi.cpp b/src/NotesLoaderMidi.cpp index 0d2a49b5e6..8a3377b527 100644 --- a/src/NotesLoaderMidi.cpp +++ b/src/NotesLoaderMidi.cpp @@ -687,10 +687,9 @@ static bool LoadFromMidi( const RString &sPath, Song &songOut ) FOREACH_CONST( MidiFileIn::TimeSignatureChange, midi.timeSignatureEvents_, iter ) { - TimeSignatureSegment seg; - seg.m_iStartRow = MidiCountToNoteRow( iter->count ); - seg.m_iNumerator = iter->numerator; - seg.m_iDenominator = iter->denominator; + TimeSignatureSegment seg(MidiCountToNoteRow( iter->count ), + iter->numerator, + iter->denominator); songOut.m_SongTiming.AddTimeSignatureSegment( seg ); } diff --git a/src/NotesLoaderSM.cpp b/src/NotesLoaderSM.cpp index 3497af6534..78a6734eec 100644 --- a/src/NotesLoaderSM.cpp +++ b/src/NotesLoaderSM.cpp @@ -382,15 +382,15 @@ void SMLoader::ProcessTimeSignatures( TimingData &out, const RString sParam ) continue; } - if( seg.m_iNumerator < 1 ) + if( seg.GetNum() < 1 ) { - LOG->UserLog( "Song file", "(UNKNOWN)", "has an invalid time signature change with beat %f, iNumerator %i.", fBeat, seg.m_iNumerator ); + LOG->UserLog( "Song file", "(UNKNOWN)", "has an invalid time signature change with beat %f, iNumerator %i.", fBeat, seg.GetNum() ); continue; } - if( seg.m_iDenominator < 1 ) + if( seg.GetDen() < 1 ) { - LOG->UserLog( "Song file", "(UNKNOWN)", "has an invalid time signature change with beat %f, iDenominator %i.", fBeat, seg.m_iDenominator ); + LOG->UserLog( "Song file", "(UNKNOWN)", "has an invalid time signature change with beat %f, iDenominator %i.", fBeat, seg.GetDen() ); continue; } diff --git a/src/NotesLoaderSMA.cpp b/src/NotesLoaderSMA.cpp index 347399adfa..26101bc5ee 100644 --- a/src/NotesLoaderSMA.cpp +++ b/src/NotesLoaderSMA.cpp @@ -296,9 +296,9 @@ void SMALoader::ProcessBeatsPerMeasure( TimingData &out, const RString sParam ) continue; } - if( seg.m_iNumerator < 1 ) + if( seg.GetNum() < 1 ) { - LOG->UserLog( "Song file", "(UNKNOWN)", "has an invalid time signature change with beat %f, iNumerator %i.", fBeat, seg.m_iNumerator ); + LOG->UserLog( "Song file", "(UNKNOWN)", "has an invalid time signature change with beat %f, iNumerator %i.", fBeat, seg.GetNum() ); continue; } diff --git a/src/NotesWriterSSC.cpp b/src/NotesWriterSSC.cpp index de5658b127..0960496c76 100644 --- a/src/NotesWriterSSC.cpp +++ b/src/NotesWriterSSC.cpp @@ -116,7 +116,7 @@ static void GetTimingTags( vector &lines, TimingData timing, bool bIsSo ASSERT( !timing.m_vTimeSignatureSegments.empty() ); w.Init( "TIMESIGNATURES" ); FOREACH_CONST( TimeSignatureSegment, timing.m_vTimeSignatureSegments, iter ) - w.Write( iter->m_iStartRow, iter->m_iNumerator, iter->m_iDenominator ); + w.Write( iter->GetRow(), iter->GetNum(), iter->GetDen() ); w.Finish(); ASSERT( !timing.m_TickcountSegments.empty() ); diff --git a/src/Player.cpp b/src/Player.cpp index 5caa7b5a65..5bd48778f8 100644 --- a/src/Player.cpp +++ b/src/Player.cpp @@ -2881,7 +2881,7 @@ void Player::CrossedRows( int iLastRowCrossed, const RageTimer &now ) TimeSignatureSegment tSignature = m_Timing->GetTimeSignatureSegmentAtBeat( NoteRowToBeat( iLastRowCrossed ) ); // Most songs are in 4/4 time. The frequency for checking tick counts should reflect that. - iCheckpointFrequencyRows = ROWS_PER_BEAT * tSignature.m_iDenominator / (tSignature.m_iNumerator * 4); + iCheckpointFrequencyRows = ROWS_PER_BEAT * tSignature.GetDen() / (tSignature.GetNum() * 4); } if( iCheckpointFrequencyRows > 0 ) diff --git a/src/ScreenEdit.cpp b/src/ScreenEdit.cpp index 1eedad0540..21c1b874c3 100644 --- a/src/ScreenEdit.cpp +++ b/src/ScreenEdit.cpp @@ -1307,7 +1307,9 @@ void ScreenEdit::InputEdit( const InputEventPlus &input, EditButton EditB ) m_iShiftAnchor = -1; return; } - int beatsPerMeasure = GAMESTATE->m_pCurSong->m_SongTiming.GetTimeSignatureSegmentAtBeat( GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat ).m_iNumerator; + TimingData &sTiming = GAMESTATE->m_pCurSong->m_SongTiming; + float playerBeat = GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat; + int beatsPerMeasure = sTiming.GetTimeSignatureSegmentAtBeat( playerBeat ).GetNum(); switch( EditB ) { @@ -3967,13 +3969,16 @@ void ScreenEdit::HandleTimingDataInformationChoice( TimingDataInformationChoice ); break; case time_signature: + { + TimeSignatureSegment &ts = GetAppropriateTiming().GetTimeSignatureSegmentAtBeat( GetBeat() ); ScreenTextEntry::TextEntry( SM_BackFromTimeSignatureChange, ENTER_TIME_SIGNATURE_VALUE, - ssprintf( "%d/%d", GetAppropriateTiming().GetTimeSignatureSegmentAtBeat( GetBeat() ).m_iNumerator, GetAppropriateTiming().GetTimeSignatureSegmentAtBeat( GetBeat() ).m_iDenominator ), + ssprintf( "%d/%d", ts.GetNum(), ts.GetDen() ), 8 ); break; + } case tickcount: ScreenTextEntry::TextEntry( SM_BackFromTickcountChange, @@ -4259,7 +4264,7 @@ void ScreenEdit::CheckNumberOfNotesAndUndo() return; TimeSignatureSegment curTime = GAMESTATE->m_pCurSong->m_SongTiming.GetTimeSignatureSegmentAtBeat( GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat ); - int rowsPerMeasure = curTime.m_iDenominator * curTime.m_iNumerator; + int rowsPerMeasure = curTime.GetDen() * curTime.GetNum(); for( int row=0; row<=m_NoteDataEdit.GetLastRow(); row+=rowsPerMeasure ) { @@ -4310,7 +4315,9 @@ float ScreenEdit::GetMaximumBeatForNewNote() const /* Round up to the next measure end. Some songs end on weird beats * mid-measure, and it's odd to have movement capped to these weird * beats. */ - int beatsPerMeasure = GAMESTATE->m_pCurSong->m_SongTiming.GetTimeSignatureSegmentAtBeat( GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat ).m_iNumerator; + TimingData &songTiming = GAMESTATE->m_pCurSong->m_SongTiming; + float playerBeat = GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat; + int beatsPerMeasure = songTiming.GetTimeSignatureSegmentAtBeat( playerBeat ).GetNum(); fEndBeat += beatsPerMeasure; fEndBeat = ftruncf( fEndBeat, (float)beatsPerMeasure ); diff --git a/src/TimingData.cpp b/src/TimingData.cpp index 0bf1a8f794..a158c761b7 100644 --- a/src/TimingData.cpp +++ b/src/TimingData.cpp @@ -138,40 +138,40 @@ void TimingData::SetTimeSignatureAtRow( int iRow, int iNumerator, int iDenominat unsigned i; for( i = 0; i < m_vTimeSignatureSegments.size(); i++ ) { - if( m_vTimeSignatureSegments[i].m_iStartRow >= iRow) + if( m_vTimeSignatureSegments[i].GetRow() >= iRow) break; // We found our segment. } - if ( i == m_vTimeSignatureSegments.size() || m_vTimeSignatureSegments[i].m_iStartRow != iRow ) + if ( i == m_vTimeSignatureSegments.size() || m_vTimeSignatureSegments[i].GetRow() != iRow ) { // No specific segmeent here: place one if it differs. if( i == 0 || - ( m_vTimeSignatureSegments[i-1].m_iNumerator != iNumerator - || m_vTimeSignatureSegments[i-1].m_iDenominator != iDenominator ) ) + ( m_vTimeSignatureSegments[i-1].GetNum() != iNumerator + || m_vTimeSignatureSegments[i-1].GetDen() != iDenominator ) ) AddTimeSignatureSegment( TimeSignatureSegment(iRow, iNumerator, iDenominator) ); } else // TimeSignatureSegment being modified is m_vTimeSignatureSegments[i] { - if( i > 0 && m_vTimeSignatureSegments[i-1].m_iNumerator == iNumerator - && m_vTimeSignatureSegments[i-1].m_iDenominator == iDenominator ) + if( i > 0 && m_vTimeSignatureSegments[i-1].GetNum() == iNumerator + && m_vTimeSignatureSegments[i-1].GetDen() == iDenominator ) m_vTimeSignatureSegments.erase( m_vTimeSignatureSegments.begin()+i, m_vTimeSignatureSegments.begin()+i+1 ); else { - m_vTimeSignatureSegments[i].m_iNumerator = iNumerator; - m_vTimeSignatureSegments[i].m_iDenominator = iDenominator; + m_vTimeSignatureSegments[i].SetNum(iNumerator); + m_vTimeSignatureSegments[i].SetDen(iDenominator); } } } void TimingData::SetTimeSignatureNumeratorAtRow( int iRow, int iNumerator ) { - SetTimeSignatureAtRow( iRow, iNumerator, GetTimeSignatureSegmentAtBeat( NoteRowToBeat( iRow ) ).m_iDenominator ); + SetTimeSignatureAtRow( iRow, iNumerator, GetTimeSignatureSegmentAtBeat( NoteRowToBeat( iRow ) ).GetDen() ); } void TimingData::SetTimeSignatureDenominatorAtRow( int iRow, int iDenominator ) { - SetTimeSignatureAtRow( iRow, GetTimeSignatureSegmentAtBeat( NoteRowToBeat( iRow ) ).m_iNumerator, iDenominator ); + SetTimeSignatureAtRow( iRow, GetTimeSignatureSegmentAtBeat( NoteRowToBeat( iRow ) ).GetNum(), iDenominator ); } void TimingData::SetWarpAtRow( int iRow, float fNew ) @@ -586,7 +586,7 @@ int TimingData::GetTimeSignatureSegmentIndexAtRow( int iRow ) const { unsigned i; for (i=0; i < m_vTimeSignatureSegments.size() - 1; i++ ) - if( m_vTimeSignatureSegments[i+1].m_iStartRow > iRow ) + if( m_vTimeSignatureSegments[i+1].GetRow() > iRow ) break; return static_cast(i); } @@ -647,7 +647,7 @@ TimeSignatureSegment& TimingData::GetTimeSignatureSegmentAtRow( int iRow ) { unsigned i; for( i=0; i iRow ) + if( m_vTimeSignatureSegments[i+1].GetRow() > iRow ) break; return m_vTimeSignatureSegments[i]; } @@ -672,12 +672,12 @@ ScrollSegment& TimingData::GetScrollSegmentAtRow( int iRow ) int TimingData::GetTimeSignatureNumeratorAtRow( int iRow ) { - return GetTimeSignatureSegmentAtRow( iRow ).m_iNumerator; + return GetTimeSignatureSegmentAtRow( iRow ).GetNum(); } int TimingData::GetTimeSignatureDenominatorAtRow( int iRow ) { - return GetTimeSignatureSegmentAtRow( iRow ).m_iDenominator; + return GetTimeSignatureSegmentAtRow( iRow ).GetDen(); } ComboSegment& TimingData::GetComboSegmentAtRow( int iRow ) @@ -1044,13 +1044,13 @@ void TimingData::ScaleRegion( float fScale, int iStartIndex, int iEndIndex, bool for( unsigned i = 0; i < m_vTimeSignatureSegments.size(); i++ ) { TimeSignatureSegment &t = m_vTimeSignatureSegments[i]; - const int iSegStartRow = t.m_iStartRow; + const int iSegStartRow = t.GetRow(); if( iSegStartRow < iStartIndex ) continue; else if( iSegStartRow > iEndIndex ) - t.m_iStartRow += lrintf((iEndIndex - iStartIndex) * (fScale - 1)); + t.SetRow(t.GetRow() + lrintf((iEndIndex - iStartIndex) * (fScale - 1))); else - t.m_iStartRow = lrintf((iSegStartRow - iStartIndex) * fScale) + iStartIndex; + t.SetRow(lrintf((iSegStartRow - iStartIndex) * fScale) + iStartIndex); } for( unsigned i = 0; i < m_WarpSegments.size(); i++ ) @@ -1211,9 +1211,9 @@ void TimingData::InsertRows( int iStartRow, int iRowsToAdd ) for( unsigned i = 0; i < m_vTimeSignatureSegments.size(); i++ ) { TimeSignatureSegment &time = m_vTimeSignatureSegments[i]; - if( time.m_iStartRow < iStartRow ) + if( time.GetRow() < iStartRow ) continue; - time.m_iStartRow += iRowsToAdd; + time.SetRow(time.GetRow() + iRowsToAdd); } for( unsigned i = 0; i < m_TickcountSegments.size(); i++ ) @@ -1340,13 +1340,13 @@ void TimingData::DeleteRows( int iStartRow, int iRowsToDelete ) for( unsigned i = 0; i < m_vTimeSignatureSegments.size(); i++ ) { TimeSignatureSegment &time = m_vTimeSignatureSegments[i]; - + int keyRow = time.GetRow(); // Before deleted region: - if( time.m_iStartRow < iStartRow ) + if( keyRow < iStartRow ) continue; // Inside deleted region: - if( time.m_iStartRow < iStartRow+iRowsToDelete ) + if( keyRow < iStartRow+iRowsToDelete ) { m_vTimeSignatureSegments.erase( m_vTimeSignatureSegments.begin()+i, @@ -1358,7 +1358,7 @@ void TimingData::DeleteRows( int iStartRow, int iRowsToDelete ) // After deleted region: - time.m_iStartRow -= iRowsToDelete; + time.SetRow(keyRow - iRowsToDelete); } for( unsigned i = 0; i < m_TickcountSegments.size(); i++ ) @@ -1614,14 +1614,14 @@ void TimingData::NoteRowToMeasureAndBeat( int iNoteRow, int &iMeasureIndexOut, i { vector::const_iterator next = iter; next++; - int iSegmentEndRow = (next == m_vTimeSignatureSegments.end()) ? INT_MAX : next->m_iStartRow; + int iSegmentEndRow = (next == m_vTimeSignatureSegments.end()) ? INT_MAX : next->GetRow(); int iRowsPerMeasureThisSegment = iter->GetNoteRowsPerMeasure(); - if( iNoteRow >= iter->m_iStartRow ) + if( iNoteRow >= iter->GetRow() ) { // iNoteRow lands in this segment - int iNumRowsThisSegment = iNoteRow - iter->m_iStartRow; + int iNumRowsThisSegment = iNoteRow - iter->GetRow(); int iNumMeasuresThisSegment = (iNumRowsThisSegment) / iRowsPerMeasureThisSegment; // don't round up iMeasureIndexOut += iNumMeasuresThisSegment; iBeatIndexOut = iNumRowsThisSegment / iRowsPerMeasureThisSegment; @@ -1631,7 +1631,7 @@ void TimingData::NoteRowToMeasureAndBeat( int iNoteRow, int &iMeasureIndexOut, i else { // iNoteRow lands after this segment - int iNumRowsThisSegment = iSegmentEndRow - iter->m_iStartRow; + int iNumRowsThisSegment = iSegmentEndRow - iter->GetRow(); int iNumMeasuresThisSegment = (iNumRowsThisSegment + iRowsPerMeasureThisSegment - 1) / iRowsPerMeasureThisSegment; // round up iMeasureIndexOut += iNumMeasuresThisSegment; } diff --git a/src/TimingData.h b/src/TimingData.h index 8c66e205f8..a060b77056 100644 --- a/src/TimingData.h +++ b/src/TimingData.h @@ -119,112 +119,6 @@ struct StopSegment bool operator>=( const StopSegment &other ) const { return !operator<(other); } }; -/** - * @brief Identifies when a song changes its time signature. - * - * This only supports simple time signatures. The upper number (called the numerator here, though this isn't - * properly a fraction) is the number of beats per measure. The lower number (denominator here) - * is the note value representing one beat. */ -struct TimeSignatureSegment -{ - /** - * @brief Creates a simple Time Signature Segment with default values. - */ - TimeSignatureSegment() : m_iStartRow(-1), m_iNumerator(4), m_iDenominator(4) { } - /** - * @brief Creates a Time Signature Segment at the given row with a supplied numerator. - * - * The denominator will be 4 if this is called. - * @param r the starting row of the segment. - * @param n the numerator for the segment. - */ - TimeSignatureSegment( int r, int n ): m_iStartRow(max(0, r)), - m_iNumerator(max(1, n)), m_iDenominator(4) {} - /** - * @brief Creates a Time Signature Segment at the given row with a supplied numerator & denominator. - * @param r the starting row of the segment. - * @param n the numerator for the segment. - * @param d the denonimator for the segment. - */ - TimeSignatureSegment( int r, int n, int d ): m_iStartRow(max(0, r)), - m_iNumerator(max(1, n)), m_iDenominator(max(1, d)) {} - /** - * @brief The row in which the TimeSignatureSegment activates. - */ - int m_iStartRow; - /** - * @brief The numerator of the TimeSignatureSegment. - */ - int m_iNumerator; - /** - * @brief The denominator of the TimeSignatureSegment. - */ - int m_iDenominator; - - /** - * @brief Retrieve the number of note rows per measure within the TimeSignatureSegment. - * - * With BeatToNoteRow(1) rows per beat, then we should have BeatToNoteRow(1)*m_iNumerator - * beats per measure. But if we assume that every BeatToNoteRow(1) rows is a quarter note, - * and we want the beats to be 1/m_iDenominator notes, then we should have - * BeatToNoteRow(1)*4 is rows per whole note and thus BeatToNoteRow(1)*4/m_iDenominator is - * rows per beat. Multiplying by m_iNumerator gives rows per measure. - * @returns the number of note rows per measure. - */ - int GetNoteRowsPerMeasure() const { return BeatToNoteRow(1) * 4 * m_iNumerator / m_iDenominator; } - /** - * @brief Compares two TimeSignatureSegments to see if they are equal to each other. - * @param other the other TimeSignatureSegment to compare to. - * @return the equality of the two segments. - */ - bool operator==( const TimeSignatureSegment &other ) const - { - COMPARE( m_iStartRow ); - COMPARE( m_iNumerator ); - COMPARE( m_iDenominator ); - return true; - } - /** - * @brief Compares two TimeSignatureSegments to see if they are not equal to each other. - * @param other the other TimeSignatureSegment to compare to. - * @return the inequality of the two segments. - */ - bool operator!=( const TimeSignatureSegment &other ) const { return !operator==(other); } - /** - * @brief Compares two TimeSignatureSegments to see if one is less than the other. - * @param other the other TimeSignatureSegment to compare to. - * @return the truth/falsehood of if the first is less than the second. - */ - bool operator<( const TimeSignatureSegment &other ) const - { - return m_iStartRow < other.m_iStartRow || - ( m_iStartRow == other.m_iStartRow && - ( m_iNumerator < other.m_iNumerator || - ( m_iNumerator == other.m_iNumerator && m_iDenominator < other.m_iDenominator ))); - } - /** - * @brief Compares two TimeSignatureSegments to see if one is less than or equal to the other. - * @param other the other TimeSignatureSegment to compare to. - * @return the truth/falsehood of if the first is less or equal to than the second. - */ - bool operator<=( const TimeSignatureSegment &other ) const - { - return ( operator<(other) || operator==(other) ); - } - /** - * @brief Compares two TimeSignatureSegments to see if one is greater than the other. - * @param other the other TimeSignatureSegment to compare to. - * @return the truth/falsehood of if the first is greater than the second. - */ - bool operator>( const TimeSignatureSegment &other ) const { return !operator<=(other); } - /** - * @brief Compares two TimeSignatureSegments to see if one is greater than or equal to the other. - * @param other the other TimeSignatureSegment to compare to. - * @return the truth/falsehood of if the first is greater than or equal to the second. - */ - bool operator>= (const TimeSignatureSegment &other ) const { return !operator<(other); } -}; - /** * @brief Identifies when the arrow scroll changes. * diff --git a/src/TimingSegments.cpp b/src/TimingSegments.cpp index a3ce904119..3b7d198c50 100644 --- a/src/TimingSegments.cpp +++ b/src/TimingSegments.cpp @@ -162,6 +162,39 @@ bool BPMSegment::operator<( const BPMSegment &other ) const return false; } +int TimeSignatureSegment::GetNum() const +{ + return this->numerator; +} + +void TimeSignatureSegment::SetNum(const int i) +{ + this->numerator = i; +} + +int TimeSignatureSegment::GetDen() const +{ + return this->denominator; +} + +void TimeSignatureSegment::SetDen(const int i) +{ + this->denominator = i; +} + +int TimeSignatureSegment::GetNoteRowsPerMeasure() const +{ + return BeatToNoteRow(1) * 4 * numerator / denominator; +} + +bool TimeSignatureSegment::operator<( const TimeSignatureSegment &other ) const +{ + LTCOMPARE(GetRow()); + LTCOMPARE(GetNum()); + LTCOMPARE(GetDen()); + return false; +} + diff --git a/src/TimingSegments.h b/src/TimingSegments.h index f901973458..7ed4f1fbc1 100644 --- a/src/TimingSegments.h +++ b/src/TimingSegments.h @@ -439,6 +439,91 @@ private: float bps; }; +/** + * @brief Identifies when a song changes its time signature. + * + * This only supports simple time signatures. The upper number + * (called the numerator here, though this isn't properly a + * fraction) is the number of beats per measure. The lower number + * (denominator here) is the note value representing one beat. */ +struct TimeSignatureSegment : public TimingSegment +{ + /** + * @brief Creates a simple Time Signature Segment with default values. + */ + TimeSignatureSegment(): + TimingSegment(), + numerator(4), denominator(4) { } + /** + * @brief Creates a Time Signature Segment with supplied values. + * + * The denominator will be 4 if this is called. + * @param r the starting row / beat of the segment. + * @param n the numerator for the segment. + */ + template + TimeSignatureSegment( StartType r, int n ): + TimingSegment(max((StartType)0, r)), + numerator(max(1, n)), denominator(4) {} + /** + * @brief Creates a Time Signature Segment with supplied values. + * @param r the starting row of the segment. + * @param n the numerator for the segment. + * @param d the denonimator for the segment. + */ + template + TimeSignatureSegment( StartType r, int n, int d ): + TimingSegment(max((StartType)0, r)), + numerator(max(1, n)), denominator(max(1, d)) {} + + /** + * @brief Get the numerator in this TimeSignatureSegment. + * @return the numerator. */ + int GetNum() const; + + /** + * @brief Set the numerator in this TimeSignatureSegment. + * @param i the numerator. */ + void SetNum(const int i); + + /** + * @brief Get the denominator in this TimeSignatureSegment. + * @return the denominator. */ + int GetDen() const; + + /** + * @brief Set the denominator in this TimeSignatureSegment. + * @param i the denominator. */ + void SetDen(const int i); + + /** + * @brief Retrieve the number of note rows per measure within the TimeSignatureSegment. + * + * With BeatToNoteRow(1) rows per beat, then we should have BeatToNoteRow(1)*m_iNumerator + * beats per measure. But if we assume that every BeatToNoteRow(1) rows is a quarter note, + * and we want the beats to be 1/m_iDenominator notes, then we should have + * BeatToNoteRow(1)*4 is rows per whole note and thus BeatToNoteRow(1)*4/m_iDenominator is + * rows per beat. Multiplying by m_iNumerator gives rows per measure. + * @returns the number of note rows per measure. + */ + int GetNoteRowsPerMeasure() const; + + /** + * @brief Compares two TimeSignatureSegments to see if one is less than the other. + * @param other the other TimeSignatureSegment to compare to. + * @return the truth/falsehood of if the first is less than the second. + */ + bool operator<( const TimeSignatureSegment &other ) const; +private: + /** + * @brief The numerator of the TimeSignatureSegment. + */ + int numerator; + /** + * @brief The denominator of the TimeSignatureSegment. + */ + int denominator; +};