Skip to content

Commit

Permalink
AudioEngine: fix application of m_fNextBpm
Browse files Browse the repository at this point in the history
previously, `AudioEngine::getBpmAtColumn` returned `m_fNextBpm` in case neither an external JACK timebase controller nor the `Timeline` is used.

This is potentially harmful since `m_fNextBpm` was intended to be a transient property until the `AudioEngine` applied this tempo - requested by the user via either UI interaction or MIDI/OSC message - during the next processing cycle in `updateBpmAndTickSize`. In case `getBpmAtColumn` was used inbetween setting `m_fNextBpm` and the next processing cycle, a wrong value would be returned. And since this function is part of `TransportPosition::computeFrameFromTick` and `computeTickFromFrame` things can get messy (and got messy within the JACK integration tests)
  • Loading branch information
theGreatWhiteShark committed Oct 31, 2024
1 parent 3084f27 commit fd4d284
Showing 1 changed file with 16 additions and 2 deletions.
18 changes: 16 additions & 2 deletions src/core/AudioEngine/AudioEngine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -710,7 +710,19 @@ void AudioEngine::updateBpmAndTickSize( std::shared_ptr<TransportPosition> pPos

const float fOldBpm = pPos->getBpm();

const float fNewBpm = getBpmAtColumn( pPos->getColumn() );
float fNewBpm = getBpmAtColumn( pPos->getColumn() );
// If we are in Pattern mode or Timeline is not activated in Song Mode +
// there is no external application controling tempo of Hydrogen, we are
// free to apply a new tempo. This was set by the user either via UI or
// MIDI/OSC message.
if ( pHydrogen->getJackTimebaseState() !=
JackAudioDriver::Timebase::Listener &&
( ( pSong != nullptr && ! pSong->getIsTimelineActivated() ) ||
pHydrogen->getMode() != Song::Mode::Song ) &&
fNewBpm != m_fNextBpm ) {
fNewBpm = m_fNextBpm;
}

if ( fNewBpm != fOldBpm ) {
pPos->setBpm( fNewBpm );
if ( pPos == m_pTransportPosition ) {
Expand Down Expand Up @@ -1186,8 +1198,10 @@ float AudioEngine::getBpmAtColumn( int nColumn ) {
#if AUDIO_ENGINE_DEBUG
AE_DEBUGLOG( QString( "BPM changed via Widget, OSC, or MIDI from [%1] to [%2]." )
.arg( fBpm ).arg( pAudioEngine->getNextBpm() ) );
// We do not return AudioEngine::m_fNextBpm since it is considered
// transient until applied in updateBpmAndTickSize(). It's not the
// current tempo.
#endif
fBpm = pAudioEngine->getNextBpm();
}
}
return fBpm;
Expand Down

0 comments on commit fd4d284

Please sign in to comment.