mirror of
https://codeberg.org/armin/mindball.git
synced 2026-09-01 03:40:49 +02:00
fix sync delay
This commit is contained in:
parent
482d5c3cbd
commit
2e85d45983
4 changed files with 35 additions and 3 deletions
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -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));
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
|
||||||
|
|
@ -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 };
|
||||||
};
|
};
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue