commit e294741eaf26e1b1d9c1fdd281c8cf1e1954d2d5
parent 6a1fb2627d05b77f2536b9dd6132d924c6f80bde
Author: dsp56300 <dsp56300@users.noreply.github.com>
Date: Thu, 5 Sep 2024 19:51:52 +0200
move midi clock processing to a separate file
Diffstat:
5 files changed, 119 insertions(+), 71 deletions(-)
diff --git a/source/synthLib/CMakeLists.txt b/source/synthLib/CMakeLists.txt
@@ -16,6 +16,7 @@ set(SOURCES
deviceTypes.h
dspMemoryPatch.cpp dspMemoryPatch.h
midiBufferParser.cpp midiBufferParser.h
+ midiClock.cpp midiClock.h
midiToSysex.cpp midiToSysex.h
midiTypes.h
os.cpp os.h
diff --git a/source/synthLib/midiClock.cpp b/source/synthLib/midiClock.cpp
@@ -0,0 +1,84 @@
+#include "midiClock.h"
+
+#include "midiTypes.h"
+
+#include <cmath>
+
+#include "plugin.h"
+
+#if 0
+#define LOGMC(S) LOG(S)
+#else
+#define LOGMC(S) do{}while(false)
+#endif
+
+namespace synthLib
+{
+ static constexpr double ClockTicksPerQuarter = 24.0;
+
+ void MidiClock::process(const float _bpm, const float _ppqPos, const bool _isPlaying, const size_t _sampleCount)
+ {
+ if(_bpm < 1.0f)
+ return;
+
+ 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;
+ }
+ 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;
+ }
+
+ 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;
+
+ if (m_clockTickPos < 0.0f)
+ continue;
+
+ m_clockTickPos -= 1.0;
+
+ LOGMC("insert tick at " << i);
+
+ 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;
+ }
+}
diff --git a/source/synthLib/midiClock.h b/source/synthLib/midiClock.h
@@ -0,0 +1,26 @@
+#pragma once
+
+#include <cstddef>
+
+namespace synthLib
+{
+ class Plugin;
+
+ class MidiClock
+ {
+ public:
+ MidiClock(Plugin& _plugin) : m_plugin(_plugin)
+ {
+ }
+
+ void process(float _bpm, float _ppqPos, bool _isPlaying, size_t _sampleCount);
+ void restart();
+
+ private:
+ 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
@@ -5,12 +5,6 @@
#include "os.h"
-#if 0
-#define LOGMC(S) LOG(S)
-#else
-#define LOGMC(S) do{}while(false)
-#endif
-
using namespace synthLib;
namespace synthLib
@@ -21,6 +15,7 @@ namespace synthLib
: m_resampler(_device->getChannelCountIn(), _device->getChannelCountOut())
, m_device(_device)
, m_deviceSamplerate(_device->getSamplerate())
+ , m_midiClock(*this)
{
}
@@ -128,7 +123,7 @@ namespace synthLib
setState(deviceState);
// MIDI clock has to send the start event again, some device find it confusing and do strange things if there isn't any
- m_needsStart = true;
+ m_midiClock.restart();
updateDeviceLatency();
}
@@ -203,66 +198,7 @@ namespace synthLib
void Plugin::processMidiClock(float _bpm, float _ppqPos, bool _isPlaying, size_t _sampleCount)
{
- if(_bpm < 1.0f)
- return;
-
- const double ppqPos = _ppqPos;
-
- constexpr double clockTicksPerQuarter = 24.0;
-
- if(_isPlaying && !m_isPlaying)
- {
- 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(MidiEventSource::Internal);
- evStop.a = M_STOP;
- m_midiIn.insert(m_midiIn.begin(), evStop);
- m_clockTickPos = 0.0;
- }
-
- if(!m_isPlaying)
- return;
-
- const double quartersPerSecond = _bpm / 60.0;
- const double clockTicksPerSecond = clockTicksPerQuarter * quartersPerSecond;
-
- const double clocksPerSample = clockTicksPerSecond * m_hostSamplerateInv;
-
- for(uint32_t i=0; i<static_cast<uint32_t>(_sampleCount); ++i)
- {
- m_clockTickPos += clocksPerSample;
-
- if (m_clockTickPos < 0.0f)
- continue;
-
- m_clockTickPos -= 1.0;
-
- LOGMC("insert tick at " << i);
-
- SMidiEvent evClock(MidiEventSource::Internal);
- evClock.a = M_TIMINGCLOCK;
- evClock.offset = i;
-
- if(m_needsStart)
- {
- evClock.a = M_START;
- insertMidiEvent(evClock);
- evClock.a = M_TIMINGCLOCK;
-
- m_needsStart = false;
- }
-
- insertMidiEvent(evClock);
- }
+ m_midiClock.process(_bpm, _ppqPos, _isPlaying, _sampleCount);
}
float* Plugin::getDummyBuffer(size_t _minimumSize)
diff --git a/source/synthLib/plugin.h b/source/synthLib/plugin.h
@@ -9,6 +9,7 @@
#include "dsp56kEmu/ringbuffer.h"
#include "deviceTypes.h"
+#include "midiClock.h"
namespace synthLib
{
@@ -25,6 +26,7 @@ namespace synthLib
void setHostSamplerate(float _hostSamplerate, float _preferredDeviceSamplerate);
float getHostSamplerate() const { return m_hostSamplerate; }
+ float getHostSamplerateInv() const { return m_hostSamplerateInv; }
void setBlockSize(uint32_t _blockSize);
@@ -77,10 +79,8 @@ namespace synthLib
uint32_t m_deviceLatencyMidiToOutput = 0;
uint32_t m_deviceLatencyInputToOutput = 0;
- // MIDI Clock
- bool m_isPlaying = false;
- bool m_needsStart = false;
- double m_clockTickPos = 0.0;
+ MidiClock m_midiClock;
+
uint32_t m_extraLatencyBlocks = 1;
float m_deviceSamplerate = 0.0f;