diff --git a/include/MidiTime.h b/include/MidiTime.h index 9ce25a8cf..203e7d5bf 100644 --- a/include/MidiTime.h +++ b/include/MidiTime.h @@ -90,12 +90,15 @@ public: // calculate number of frame that are needed this time f_cnt_t frames( const float framesPerTick ) const; + double getTimeInMilliseconds(bpm_t beatsPerMinute) const; + static MidiTime fromFrames( const f_cnt_t frames, const float framesPerTick ); static tick_t ticksPerTact(); static tick_t ticksPerTact( const TimeSig &sig ); static int stepsPerTact(); static void setTicksPerTact( tick_t tpt ); static MidiTime stepPosition( int step ); + static double ticksToMilliseconds(tick_t ticks, bpm_t beatsPerMinute); private: tick_t m_ticks; diff --git a/include/Song.h b/include/Song.h index be7f9e508..5b6e6899b 100644 --- a/include/Song.h +++ b/include/Song.h @@ -101,14 +101,22 @@ public: { return m_nLoadingTrack; } + inline int getMilliseconds() const { return m_elapsedMilliSeconds; } - inline void setMilliSeconds( float ellapsedMilliSeconds ) + + inline void setToTime( MidiTime const & midiTime ) { - m_elapsedMilliSeconds = ellapsedMilliSeconds; + m_elapsedMilliSeconds = midiTime.getTimeInMilliseconds(getTempo()); } + + inline void setToTimeByTicks(tick_t ticks) + { + m_elapsedMilliSeconds = MidiTime::ticksToMilliseconds(ticks, getTempo()); + } + inline int getTacts() const { return currentTact(); diff --git a/src/core/Song.cpp b/src/core/Song.cpp index af359a881..f40616e21 100644 --- a/src/core/Song.cpp +++ b/src/core/Song.cpp @@ -258,8 +258,7 @@ void Song::processNextBuffer() if( m_playPos[m_playMode] < tl->loopBegin() || m_playPos[m_playMode] >= tl->loopEnd() ) { - m_elapsedMilliSeconds = - ( tl->loopBegin().getTicks() * 60 * 1000 / 48 ) / getTempo(); + setToTime(tl->loopBegin()); m_playPos[m_playMode].setTicks( tl->loopBegin().getTicks() ); emit updateSampleTracks(); @@ -316,8 +315,7 @@ void Song::processNextBuffer() ticks %= ( maxTact * MidiTime::ticksPerTact() ); // wrap milli second counter - m_elapsedMilliSeconds = - ( ticks * 60 * 1000 / 48 ) / getTempo(); + setToTimeByTicks(ticks); m_vstSyncController.setAbsolutePosition( ticks ); } @@ -335,10 +333,7 @@ void Song::processNextBuffer() if( m_playPos[m_playMode] >= tl->loopEnd() ) { m_playPos[m_playMode].setTicks( tl->loopBegin().getTicks() ); - - m_elapsedMilliSeconds = - ( ( tl->loopBegin().getTicks() ) * 60 * 1000 / 48 ) / - getTempo(); + setToTime(tl->loopBegin()); } else if( m_playPos[m_playMode] == tl->loopEnd() - 1 ) { @@ -393,9 +388,7 @@ void Song::processNextBuffer() framesPlayed += framesToPlay; m_playPos[m_playMode].setCurrentFrame( framesToPlay + currentFrame ); - m_elapsedMilliSeconds += - ( ( framesToPlay / framesPerTick ) * 60 * 1000 / 48 ) - / getTempo(); + m_elapsedMilliSeconds += MidiTime::ticksToMilliseconds( framesToPlay / framesPerTick, getTempo()); m_elapsedTacts = m_playPos[Mode_PlaySong].getTact(); m_elapsedTicks = ( m_playPos[Mode_PlaySong].getTicks() % ticksPerTact() ) / 48; } @@ -603,10 +596,9 @@ void Song::updateLength() void Song::setPlayPos( tick_t ticks, PlayModes playMode ) { - m_elapsedTicks += m_playPos[playMode].getTicks() - ticks; - m_elapsedMilliSeconds += - ( ( ( ( ticks - m_playPos[playMode].getTicks() ) ) * 60 * 1000 / 48) / - getTempo() ); + tick_t ticksFromPlayMode = m_playPos[playMode].getTicks(); + m_elapsedTicks += ticksFromPlayMode - ticks; + m_elapsedMilliSeconds += MidiTime::ticksToMilliseconds( ticks - ticksFromPlayMode, getTempo() ); m_playPos[playMode].setTicks( ticks ); m_playPos[playMode].setCurrentFrame( 0.0f ); @@ -673,9 +665,8 @@ void Song::stop() if( tl->savedPos() >= 0 ) { m_playPos[m_playMode].setTicks( tl->savedPos().getTicks() ); - m_elapsedMilliSeconds = - ( ( ( tl->savedPos().getTicks() ) * 60 * 1000 / 48 ) / - getTempo() ); + setToTime(tl->savedPos()); + if( gui && gui->songEditor() && ( tl->autoScroll() == TimeLineWidget::AutoScrollEnabled ) ) { diff --git a/src/core/midi/MidiTime.cpp b/src/core/midi/MidiTime.cpp index b3dda134d..999dcfaf9 100644 --- a/src/core/midi/MidiTime.cpp +++ b/src/core/midi/MidiTime.cpp @@ -155,6 +155,10 @@ f_cnt_t MidiTime::frames( const float framesPerTick ) const return 0; } +double MidiTime::getTimeInMilliseconds(bpm_t beatsPerMinute) const +{ + return ticksToMilliseconds(getTicks(), beatsPerMinute); +} MidiTime MidiTime::fromFrames( const f_cnt_t frames, const float framesPerTick ) { @@ -191,3 +195,9 @@ MidiTime MidiTime::stepPosition( int step ) { return step * ticksPerTact() / stepsPerTact(); } + +double MidiTime::ticksToMilliseconds(tick_t ticks, bpm_t beatsPerMinute) +{ + // 60 * 1000 / 48 = 1250 + return ( ticks * 1250 ) / beatsPerMinute; +} diff --git a/src/gui/TimeLineWidget.cpp b/src/gui/TimeLineWidget.cpp index 06b32ff7f..742da9388 100644 --- a/src/gui/TimeLineWidget.cpp +++ b/src/gui/TimeLineWidget.cpp @@ -371,9 +371,7 @@ void TimeLineWidget::mouseMoveEvent( QMouseEvent* event ) { case MovePositionMarker: m_pos.setTicks( t.getTicks() ); - Engine::getSong()->setMilliSeconds( ( t.getTicks() * - ( 60 * 1000 / 48 ) ) / - Engine::getSong()->getTempo() ); + Engine::getSong()->setToTime(t); m_pos.setCurrentFrame( 0 ); updatePosition(); positionMarkerMoved();