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 cf56e913557347b409b33db5e3892aab4565c332
parent e294741eaf26e1b1d9c1fdd281c8cf1e1954d2d5
Author: dsp56300 <dsp56300@users.noreply.github.com>
Date:   Thu,  5 Sep 2024 23:50:32 +0200

continue sending midi clock if sequencer is stopped, fixes not running arps in multiple synths while sequencer is not playing

Diffstat:
Mdoc/changelog.txt | 5+++++
Msource/synthLib/midiClock.cpp | 71+++++++++++++++++++++++++++++++++++++++--------------------------------
Msource/synthLib/midiClock.h | 13+++++++------
Msource/synthLib/plugin.cpp | 2+-
4 files changed, 52 insertions(+), 39 deletions(-)

diff --git a/doc/changelog.txt b/doc/changelog.txt @@ -11,6 +11,7 @@ Framework: - [Fix] Crash when dragging a patch from Patch Manager to a part slot - [Fix] Crash when dragging a patch on an empty area in grid view - [Fix] Drag target slot rectangles displayed in grid view for areas without content +- [Fix] Continue MIDI clock generation while DAW sequencer is stopped NodalRed2x: @@ -28,15 +29,19 @@ NodalRed2x: versions when hovering - [Fix] Crash when toggling filter distortion on a part that shares the same MIDI channel with another part +- [Fix] Arpeggiator stopped while DAW sequencer not running Vavra: - [Imp] Mixer balance knobs now reset to center instead of total left +- [Fix] Arpeggiator stopped while DAW sequencer not running + Xenia: - [Fix] Typos in play parameter names (mkruselj) - [Fix] Arp not working in Multi mode +- [Fix] Arpeggiator stopped while DAW sequencer not running 1.3.19 diff --git a/source/synthLib/midiClock.cpp b/source/synthLib/midiClock.cpp @@ -6,6 +6,8 @@ #include "plugin.h" +#include "dsp56kEmu/logging.h" + #if 0 #define LOGMC(S) LOG(S) #else @@ -21,34 +23,23 @@ namespace synthLib if(_bpm < 1.0f) return; + const double quartersPerSecond = _bpm / 60.0; + const double clockTicksPerSecond = ClockTicksPerQuarter * quartersPerSecond; + + const double hostSamplerateInv = m_plugin.getHostSamplerateInv(); + + const double clocksPerSample = clockTicksPerSecond * hostSamplerateInv; + if(_isPlaying && !m_isPlaying) { - const double ppqPos = _ppqPos; - 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; + start(_ppqPos); } else if(m_isPlaying && !_isPlaying) { - LOGMC("Stop at ppqPos=" << ppqPos); - - m_isPlaying = false; - - SMidiEvent evStop(MidiEventSource::Internal); - evStop.a = M_STOP; - m_plugin.insertMidiEvent(evStop); - m_clockTickPos = 0.0; + LOGMC("Stop at ppqPos=" << _ppqPos); + stop(); } - if(!m_isPlaying) - return; - - const double quartersPerSecond = _bpm / 60.0; - const double clockTicksPerSecond = ClockTicksPerQuarter * quartersPerSecond; - - const double clocksPerSample = clockTicksPerSecond * m_plugin.getHostSamplerateInv(); - for(uint32_t i=0; i<static_cast<uint32_t>(_sampleCount); ++i) { m_clockTickPos += clocksPerSample; @@ -63,22 +54,38 @@ namespace synthLib SMidiEvent evClock(MidiEventSource::Internal); evClock.a = M_TIMINGCLOCK; evClock.offset = i; - - if(m_needsStart) - { - evClock.a = M_START; - m_plugin.insertMidiEvent(evClock); - evClock.a = M_TIMINGCLOCK; - - m_needsStart = false; - } - m_plugin.insertMidiEvent(evClock); } } void MidiClock::restart() { - m_needsStart = true; + stop(); + } + + void MidiClock::start(const float _ppqPos) + { + const double ppqPos = _ppqPos; + const auto quarterPos = (ppqPos - std::floor(ppqPos + 1.0)); + + m_clockTickPos = quarterPos * (ClockTicksPerQuarter); + + m_isPlaying = true; + + LOGMC("Start at ppqPos=" << ppqPos << ", clock tick offset " << m_clockTickPos); + + SMidiEvent evClock(MidiEventSource::Internal); + evClock.a = M_START; + evClock.offset = 0; + m_plugin.insertMidiEvent(evClock); + } + + void MidiClock::stop() + { + m_isPlaying = false; + + SMidiEvent evStop(MidiEventSource::Internal); + evStop.a = M_STOP; + m_plugin.insertMidiEvent(evStop); } } diff --git a/source/synthLib/midiClock.h b/source/synthLib/midiClock.h @@ -1,6 +1,7 @@ #pragma once #include <cstddef> +#include <cstdint> namespace synthLib { @@ -9,18 +10,19 @@ namespace synthLib class MidiClock { public: - MidiClock(Plugin& _plugin) : m_plugin(_plugin) - { - } + explicit MidiClock(Plugin& _plugin) : m_plugin(_plugin) {} void process(float _bpm, float _ppqPos, bool _isPlaying, size_t _sampleCount); + void restart(); private: + void stop(); + void start(float _ppqPos); + Plugin& m_plugin; bool m_isPlaying = false; - bool m_needsStart = false; double m_clockTickPos = 0.0; }; -} -\ No newline at end of file +} diff --git a/source/synthLib/plugin.cpp b/source/synthLib/plugin.cpp @@ -196,7 +196,7 @@ namespace synthLib return true; } - void Plugin::processMidiClock(float _bpm, float _ppqPos, bool _isPlaying, size_t _sampleCount) + void Plugin::processMidiClock(const float _bpm, const float _ppqPos, const bool _isPlaying, const size_t _sampleCount) { m_midiClock.process(_bpm, _ppqPos, _isPlaying, _sampleCount); }