From db4fdf68ff004ac0a4cd5a2697ed1553f819da90 Mon Sep 17 00:00:00 2001 From: Jens Ahrensfeld Date: Mon, 18 Aug 2025 18:22:55 +0200 Subject: [PATCH] fixed MidiClock now working with ardour --- src/plug/JK_MidiClock.cpp | 81 +++++++++++++++++---------------------- src/plug/JK_MidiClock.h | 7 +--- 2 files changed, 38 insertions(+), 50 deletions(-) diff --git a/src/plug/JK_MidiClock.cpp b/src/plug/JK_MidiClock.cpp index 509f958..a8fb9d5 100644 --- a/src/plug/JK_MidiClock.cpp +++ b/src/plug/JK_MidiClock.cpp @@ -31,9 +31,7 @@ JK_MidiClock::JK_MidiClock() m_stopMessage = new MidiMessage(MidiMessage::midiStop()); m_clockMessage = new MidiMessage(MidiMessage::midiClock()); m_songPositionMessage = new MidiMessage(MidiMessage::songPositionPointer(0)); - m_last_sample_pos_sync = 0; - m_syncSamplePos = 0; - m_syncNext_smp_f = 0; + m_sample_remain = 0; } //================================================================================================= void JK_MidiClock::generateMidiclock(const AudioPlayHead::CurrentPositionInfo &posInfo, @@ -61,9 +59,6 @@ void JK_MidiClock::generateMidiclock(const AudioPlayHead::CurrentPositionInfo &p const int clockDistanceInSamples = roundToInt(clockDistanceInSamples_f); const double quant = (60.0 / posInfo.bpm) * sampleRate; - const double hostSamplePos_f = hostPpqPosition * quant; - - double syncSamplePos_f = hostSamplePos_f; if (posInfo.isPlaying || posInfo.isRecording) { @@ -81,7 +76,7 @@ void JK_MidiClock::generateMidiclock(const AudioPlayHead::CurrentPositionInfo &p sendSongPositionPointerMessage(m_ppqToStartSyncAt, 0, midiBuffer); SynthDebug("m_ppqToStartSyncAt %f", m_ppqToStartSyncAt); } - m_syncNext_smp_f = m_ppqToStartSyncAt * quant + clockDistanceInSamples_f; + m_sample_remain = clockDistanceInSamples; } else @@ -116,13 +111,10 @@ void JK_MidiClock::generateMidiclock(const AudioPlayHead::CurrentPositionInfo &p m_syncFlag = 0; } } - m_syncNext_smp_f = m_ppqToStartSyncAt * quant + clockDistanceInSamples_f; + m_sample_remain = clockDistanceInSamples; } } - int64 syncSamplePos = (int64)std::round(syncSamplePos_f); - double sample_offset = syncSamplePos_f - m_syncSamplePos; - for (int posInBuffer = 0; posInBuffer < bufferSize; ++posInBuffer) { m_syncPpqPosition = hostPpqPosition + (posInBuffer * ppqPerSample); @@ -159,47 +151,46 @@ void JK_MidiClock::generateMidiclock(const AudioPlayHead::CurrentPositionInfo &p } } } + } + + //For best timing we should never interupt Midiclock messages! + //Seems that some slaves constantly adjusting their internal clock + //to Midiclock even if they are in stop mode. + int buffer_remain = bufferSize; + int posInBuffer = 0; + int buffer_consume = 0; + while(buffer_remain) + { + if (m_sample_remain > buffer_remain) + { + m_sample_remain -= buffer_remain; + buffer_consume = buffer_remain; + } + else + { + buffer_consume = m_sample_remain; + m_sample_remain = 0; + } -#if 0 - //For best timing we should never interupt Midiclock messages! - //Seems that some slaves constantly adjusting their internal clock - //to Midiclock even if they are in stop mode. - double sample_pos = (double)posInBuffer + sample_offset; - double distance = fabs(syncSamplePos_f-m_last_sample_pos_sync); - if ((syncSamplePos % clockDistanceInSamples) == 0 and sample_pos >= 0) - { - SynthDebug("Distance (soll) : %f", clockDistanceInSamples_f); - SynthDebug("Distance (ist) : %f", distance); - SynthDebug("syncSamplePos_f : %f", syncSamplePos_f); + buffer_remain -= buffer_consume; + posInBuffer += buffer_consume; - SynthDebug("sample_offset : %f", sample_offset); -// SynthDebug("MidiClock at Sample Sync: %d | PPQ Host: %f | PPQ Sync: %f", syncSamplePos-m_last_sample_pos_sync, hostPpqPosition-m_last_ppq_pos_host, m_syncPpqPosition-m_last_syncPpqPosition); - SynthDebug("MidiClock at Sample Sync: %f, diff %f", sample_pos, syncSamplePos_f-m_last_sample_pos_sync); - m_last_sample_pos_sync = syncSamplePos_f; - m_last_ppq_pos_host = hostPpqPosition; - m_last_syncPpqPosition = m_syncPpqPosition; - midiBuffer->addEvent(*m_clockMessage, roundToInt(sample_pos)); - } - m_syncSamplePos = ++syncSamplePos; - syncSamplePos_f += 1.0; -#else - double curr_sample_pos = hostSamplePos_f + (double)posInBuffer; - if (fabs(curr_sample_pos - m_syncNext_smp_f) <= 0.5) + if (buffer_remain == 0) { + break; + } + + if (m_sample_remain == 0) + { + m_sample_remain = clockDistanceInSamples; SynthDebug("posInBuffer : %d", posInBuffer); - SynthDebug("hostSamplePos_f : %f", hostSamplePos_f); - SynthDebug("hostSamplePos_f + posInbuffer : %f", hostSamplePos_f + posInBuffer); SynthDebug("clockDistanceInSamples_f (soll) : %f", clockDistanceInSamples_f); - SynthDebug("clockDistanceInSamples_f (ist) : %f", curr_sample_pos - m_last_sample_pos_sync); + SynthDebug("hostPpqPosition : %f", hostPpqPosition); + SynthDebug("hostPpqPosition (Q) : %f", getNearestInPPQ(hostPpqPosition, 96)); + SynthDebug("hostSamplePos (Q) : %f", getNearestInPPQ(hostPpqPosition, 96) * quant); - m_syncNext_smp_f += clockDistanceInSamples_f; - m_last_sample_pos_sync = curr_sample_pos; - SynthDebug("m_syncNext_smp_f : %f", m_syncNext_smp_f); midiBuffer->addEvent(*m_clockMessage, roundToInt(posInBuffer)); - } - -#endif } m_wasPlaying = true; @@ -215,9 +206,9 @@ void JK_MidiClock::generateMidiclock(const AudioPlayHead::CurrentPositionInfo &p } m_syncPpqPosition = hostPpqPosition; - m_syncNext_smp_f = hostSamplePos_f + clockDistanceInSamples_f; m_syncFlag = startSlave_; m_wasPlaying = false; + } } diff --git a/src/plug/JK_MidiClock.h b/src/plug/JK_MidiClock.h index 9d54ebb..94e4007 100644 --- a/src/plug/JK_MidiClock.h +++ b/src/plug/JK_MidiClock.h @@ -52,11 +52,7 @@ private: bool m_followSongPosition; uint8 m_syncFlag; int m_ppqOffset; - double m_last_sample_pos_sync; - double m_last_ppq_pos_host; - double m_last_syncPpqPosition; - double m_syncSamplePos; - double m_syncNext_smp_f; + int m_sample_remain; static const int cycleEnd_ = 1; static const int startSlave_ = 2; @@ -71,6 +67,7 @@ private: const double sampleRate, const double ppqPerSample); double getNearestSixteenthInPPQ(const double ppqPosition) {return ceil(ppqPosition * 4.0) / 4.0;} + double getNearestInPPQ(const double ppqPosition, double quantizer) {return ceil(ppqPosition * quantizer / 4) / (quantizer / 4);} JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(JK_MidiClock); };