gearmulator

Emulation of classic VA synths of the late 90s/2000s that are based on Motorola 56300 family DSPs
Log | Files | Refs | Submodules | README | LICENSE

commit 39220c92b5ec75d7fee4f1ded8b3d1ebd4e3ea75
parent 5ead444bdbad763b55051516dd54050d39d34499
Author: dsp56300 <dsp56300@users.noreply.github.com>
Date:   Sat,  5 Mar 2022 16:04:24 +0100

fix midi clock arp sync issues => rewrite midi clock code

Diffstat:
Msource/synthLib/plugin.cpp | 78++++++++++++++++++++++++++++++++++++++----------------------------------------
Msource/synthLib/plugin.h | 3+--
2 files changed, 39 insertions(+), 42 deletions(-)

diff --git a/source/synthLib/plugin.cpp b/source/synthLib/plugin.cpp @@ -5,6 +5,12 @@ #include "os.h" +#if 0 +#define LOGMC(S) LOG(S) +#else +#define LOGMC(S) {} +#endif + using namespace synthLib; namespace synthLib @@ -135,70 +141,62 @@ namespace synthLib if(_bpm < 1.0f) return; + const double ppqPos = _ppqPos; + + constexpr double clockTicksPerQuarter = 24.0; + if(_isPlaying && !m_isPlaying) { - const uint32_t beat = dsp56k::floor_int(_ppqPos); - - if(beat > m_lastKnownBeat) - { - // start - m_isPlaying = true; - m_needsStart = true; - } - m_lastKnownBeat = beat; + m_clockTickPos = (ppqPos - std::floor(ppqPos + 1.0)) * clockTicksPerQuarter; + LOGMC("Start at ppqPos=" << ppqPos << ", clock tick offset " << m_clockTickPos); + m_isPlaying = true; + m_needsStart = true; } else if(m_isPlaying && !_isPlaying) { + LOGMC("Stop at ppqPos=" << ppqPos); + m_isPlaying = false; SMidiEvent evStop; evStop.a = M_STOP; m_midiIn.insert(m_midiIn.begin(), evStop); - m_clockTickPos = 0.0f; + m_clockTickPos = 0.0; } - if(m_isPlaying) - { - constexpr float clockTicksPerQuarter = 24.0f; + if(!m_isPlaying) + return; - const float quartersPerSecond = _bpm / 60.0f; - const float clockTicksPerSecond = clockTicksPerQuarter * quartersPerSecond; - const float samplesPerClock = m_hostSamplerate / clockTicksPerSecond; + const double quartersPerSecond = _bpm / 60.0; + const double clockTicksPerSecond = clockTicksPerQuarter * quartersPerSecond; - const auto clockTickPos = _ppqPos * clockTicksPerQuarter; + const double clocksPerSample = clockTicksPerSecond * m_hostSamplerateInv; - if(m_clockTickPos <= 0.001f || clockTickPos < m_clockTickPos) - m_clockTickPos = std::floor(clockTickPos); + for(uint32_t i=0; i<static_cast<uint32_t>(_sampleCount); ++i) + { + m_clockTickPos += clocksPerSample; - const float offset = clockTickPos - m_clockTickPos; + if (m_clockTickPos < 0.0f) + continue; - const float firstSamplePos = std::max((1.0f - offset) * samplesPerClock, 0.0f); + m_clockTickPos -= 1.0; - const auto max = static_cast<float>(_sampleCount); + LOGMC("insert tick at " << i); - for(float pos = std::floor(firstSamplePos); pos < max; pos += samplesPerClock) - { - const int insertPos = dsp56k::floor_int(pos); + SMidiEvent evClock; + evClock.a = M_TIMINGCLOCK; + evClock.offset = i; - SMidiEvent evClock; + if(m_needsStart) + { + evClock.a = M_START; + insertMidiEvent(evClock); evClock.a = M_TIMINGCLOCK; - evClock.offset = insertPos; - - if(m_needsStart) - { - evClock.a = M_START; - insertMidiEvent(evClock); - evClock.a = M_TIMINGCLOCK; - - m_needsStart = false; - } m_needsStart = false; - - insertMidiEvent(evClock); - - m_clockTickPos += 1.0f; } + + insertMidiEvent(evClock); } } diff --git a/source/synthLib/plugin.h b/source/synthLib/plugin.h @@ -66,7 +66,6 @@ namespace synthLib // MIDI Clock bool m_isPlaying = false; bool m_needsStart = false; - uint32_t m_lastKnownBeat = 0; - float m_clockTickPos = 0.0f; + double m_clockTickPos = 0.0; }; }