fix sync delay

This commit is contained in:
Armin 2026-08-15 13:54:42 +02:00
commit 2e85d45983
4 changed files with 35 additions and 3 deletions

View file

@ -231,6 +231,13 @@ public:
} }
} }
static float syncTimeMs (int index, double bpm)
{
const int idx = std::clamp (index, 0, numDivisions - 1);
const double secondsPerBeat = 60.0 / std::max (1.0, bpm);
return static_cast<float> (divisionBeats[static_cast<std::size_t> (idx)] * secondsPerBeat * 1000.0);
}
private: private:
static float softClip (float x) static float softClip (float x)
{ {

View file

@ -57,6 +57,22 @@ public:
panKnob.setValueTextFunction ([] (double v) { return juce::String (juce::roundToInt (v * 100.0)) + "%"; }); panKnob.setValueTextFunction ([] (double v) { return juce::String (juce::roundToInt (v * 100.0)) + "%"; });
onToggle.setInverted (true); onToggle.setInverted (true);
syncToggle.onClick = [this]
{
if (syncToggle.getToggleState())
return;
const int index = juce::roundToInt (proc.apvts.getRawParameterValue (ParameterIDs::timeSync)->load());
const float ms = mindball::DelayEngine::syncTimeMs (index, proc.getCurrentBpm());
if (auto* timeParam = proc.apvts.getParameter (ParameterIDs::time))
{
timeParam->beginChangeGesture();
timeParam->setValueNotifyingHost (timeParam->convertTo0to1 (juce::roundToInt (ms)));
timeParam->endChangeGesture();
}
};
buildInfo.setJustificationType (juce::Justification::centredRight); buildInfo.setJustificationType (juce::Justification::centredRight);
buildInfo.setFont (juce::Font (juce::Font::getDefaultMonospacedFontName(), 9.0f, 0)); buildInfo.setFont (juce::Font (juce::Font::getDefaultMonospacedFontName(), 9.0f, 0));

View file

@ -84,6 +84,11 @@ bool MindballAudioProcessor::isBusesLayoutSupported (const BusesLayout& layouts)
&& (mainIn == juce::AudioChannelSet::mono() || mainIn == juce::AudioChannelSet::stereo()); && (mainIn == juce::AudioChannelSet::mono() || mainIn == juce::AudioChannelSet::stereo());
} }
double MindballAudioProcessor::getCurrentBpm() const
{
return lastBpm.load (std::memory_order_relaxed);
}
void MindballAudioProcessor::processBlock (juce::AudioBuffer<float>& buffer, juce::MidiBuffer&) void MindballAudioProcessor::processBlock (juce::AudioBuffer<float>& buffer, juce::MidiBuffer&)
{ {
juce::ScopedNoDenormals noDenormals; juce::ScopedNoDenormals noDenormals;
@ -109,13 +114,14 @@ void MindballAudioProcessor::processBlock (juce::AudioBuffer<float>& buffer, juc
} }
wasBypassed = false; wasBypassed = false;
double bpm = 120.0; double bpm = lastBpm.load (std::memory_order_relaxed);
if (auto* playHead = getPlayHead()) if (auto* playHead = getPlayHead())
{ {
juce::AudioPlayHead::CurrentPositionInfo pos; juce::AudioPlayHead::CurrentPositionInfo pos;
if (playHead->getCurrentPosition (pos)) if (playHead->getCurrentPosition (pos) && pos.bpm > 0)
bpm = pos.bpm > 0 ? pos.bpm : 120.0; bpm = pos.bpm;
} }
lastBpm.store (bpm, std::memory_order_relaxed);
mindball::DelayEngine::Params p; mindball::DelayEngine::Params p;
p.feedback = *apvts.getRawParameterValue (ParameterIDs::feedback); p.feedback = *apvts.getRawParameterValue (ParameterIDs::feedback);

View file

@ -53,6 +53,8 @@ public:
void getStateInformation (juce::MemoryBlock& destData) override; void getStateInformation (juce::MemoryBlock& destData) override;
void setStateInformation (const void* data, int sizeInBytes) override; void setStateInformation (const void* data, int sizeInBytes) override;
double getCurrentBpm() const;
float getDryMeterL() const { return dryMeterL.load (std::memory_order_relaxed); } float getDryMeterL() const { return dryMeterL.load (std::memory_order_relaxed); }
float getDryMeterR() const { return dryMeterR.load (std::memory_order_relaxed); } float getDryMeterR() const { return dryMeterR.load (std::memory_order_relaxed); }
float getWetMeterL() const { return wetMeterL.load (std::memory_order_relaxed); } float getWetMeterL() const { return wetMeterL.load (std::memory_order_relaxed); }
@ -70,6 +72,7 @@ private:
float meterDryL = 0.0f, meterDryR = 0.0f; float meterDryL = 0.0f, meterDryR = 0.0f;
float meterWetL = 0.0f, meterWetR = 0.0f; float meterWetL = 0.0f, meterWetR = 0.0f;
float meterDecay = 0.0f; float meterDecay = 0.0f;
std::atomic<double> lastBpm { 120.0 };
std::atomic<float> dryMeterL { 0.0f }, dryMeterR { 0.0f }; std::atomic<float> dryMeterL { 0.0f }, dryMeterR { 0.0f };
std::atomic<float> wetMeterL { 0.0f }, wetMeterR { 0.0f }; std::atomic<float> wetMeterL { 0.0f }, wetMeterR { 0.0f };
}; };