diff --git a/source/DSP/GainedOscillator.h b/source/DSP/GainedOscillator.h index fd51b7d7..6ba5af80 100644 --- a/source/DSP/GainedOscillator.h +++ b/source/DSP/GainedOscillator.h @@ -43,7 +43,7 @@ class GainedOscillator osc.setFrequency (newValue, force); } - void setOscShape (int newShape); + void setOscShape (OscShape::Values newShape) { nextOsc.store (newShape); } /** * @brief Sets the gain for the oscillator in the processorChain. @@ -69,9 +69,7 @@ class GainedOscillator template void process (const ProcessContext& context) noexcept { - //TODO: lock in audio thread!!! This should/could be a try lock and the other one a lock, - // so we only lock in the other place. But are these actuallty different threads though? - std::lock_guard lock (processMutex); + updateOscillators(); processorChain.process (context); } @@ -85,7 +83,9 @@ class GainedOscillator gainIndex }; - std::mutex processMutex; + std::atomic currentOsc { OscShape::none }, nextOsc { { OscShape::saw } }; + + void updateOscillators(); bool isActive = true; @@ -99,23 +99,28 @@ class GainedOscillator //==================================================================================================== -template -void GainedOscillator::setOscShape (int newShape) +template +void GainedOscillator::updateOscillators() { - auto& osc = processorChain.template get (); + //compare the current osc type with the (buffered next osc type). Get outta here if they the same + const auto nextOscBuf { nextOsc.load() }; + if (currentOsc == nextOscBuf) + return; + //this is to make sure we preserve the same gain after we re-init, right? bool wasActive = isActive; isActive = true; - switch (newShape) + auto& osc = processorChain.template get(); + switch (nextOscBuf) { case OscShape::none: + osc.initialise ([&] (T /*x*/) { return T (0); }); isActive = false; break; case OscShape::saw: { - std::lock_guard lock (processMutex); osc.initialise ([](T x) { //this is a sawtooth wave; as x goes from -pi to pi, y goes from -1 to 1 @@ -126,7 +131,6 @@ void GainedOscillator::setOscShape (int newShape) case OscShape::sawTri: { - std::lock_guard lock (processMutex); osc.initialise ([](T x) { T y = juce::jmap (x, T (-juce::MathConstants::pi), T (juce::MathConstants::pi), T (-1), T (1)) / 2; @@ -142,7 +146,6 @@ void GainedOscillator::setOscShape (int newShape) case OscShape::triangle: { - std::lock_guard lock (processMutex); osc.initialise ([](T x) { if (x < 0) @@ -156,7 +159,6 @@ void GainedOscillator::setOscShape (int newShape) case OscShape::pulse: { - std::lock_guard lock (processMutex); osc.initialise ([](T x) { if (x < 0) @@ -169,8 +171,6 @@ void GainedOscillator::setOscShape (int newShape) case OscShape::noise: { - std::lock_guard lock (processMutex); - osc.initialise ([&](T /*x*/) { return distribution (generator); @@ -190,4 +190,6 @@ void GainedOscillator::setOscShape (int newShape) else setGain (0); } + + currentOsc.store (nextOscBuf); } diff --git a/source/DSP/PhatOscillators.h b/source/DSP/PhatOscillators.h index d5b67b4b..70ff9324 100644 --- a/source/DSP/PhatOscillators.h +++ b/source/DSP/PhatOscillators.h @@ -68,7 +68,7 @@ class PhatOscillators : public juce::AudioProcessorValueTreeState::Listener } void setOscFreq (OscId oscNum, int newMidiNote); - void setOscShape (OscId oscNum, int newShape); + void setOscShape (OscId oscNum, OscShape::Values newShape); void setOscTuning (OscId oscNum, float newTuning); void setOscSub (float newSub) @@ -203,9 +203,9 @@ void PhatOscillators::parameterChanged (const juce::String& parameterID, floa else if (parameterID == osc2TuningID.getParamID ()) setOscTuning (OscId::osc2Index, newValue); else if (parameterID == osc1ShapeID.getParamID ()) - setOscShape (OscId::osc1Index, (int) newValue); + setOscShape (OscId::osc1Index, static_cast (newValue)); else if (parameterID == osc2ShapeID.getParamID ()) - setOscShape (OscId::osc2Index, (int) newValue); + setOscShape (OscId::osc2Index, static_cast (newValue)); else if (parameterID == oscSubID.getParamID ()) setOscSub (newValue); else if (parameterID == oscMixID.getParamID ()) @@ -318,7 +318,7 @@ void PhatOscillators::setOscFreq (OscId oscNum, int newMidiNote) } template -void PhatOscillators::setOscShape (OscId oscNum, int newShape) +void PhatOscillators::setOscShape (OscId oscNum, OscShape::Values newShape) { switch (oscNum) { diff --git a/source/DSP/ProPhatSynthesiser.h b/source/DSP/ProPhatSynthesiser.h index 6c82179c..dc65a21a 100644 --- a/source/DSP/ProPhatSynthesiser.h +++ b/source/DSP/ProPhatSynthesiser.h @@ -169,15 +169,10 @@ void ProPhatSynthesiser::setEffectParam ([[maybe_unused]] juce::StringRef par template void ProPhatSynthesiser::noteOn (const int midiChannel, const int midiNoteNumber, const float velocity) { - { - //TODO lock in the audio thread?? - const juce::ScopedLock sl (lock); - - //don't start new voices in current buffer call if we have filled all voices already. - //voicesBeingKilled should be reset after each renderNextBlock call - if (voicesBeingKilled.size () >= Constants::numVoices) - return; - } + //don't start new voices in current buffer call if we have filled all voices already. + //voicesBeingKilled should be reset after each renderNextBlock call + if (voicesBeingKilled.size() >= Constants::numVoices) + return; Synthesiser::noteOn (midiChannel, midiNoteNumber, velocity); } diff --git a/source/DSP/ProPhatVoice.h b/source/DSP/ProPhatVoice.h index 770f7004..5fb5a107 100644 --- a/source/DSP/ProPhatVoice.h +++ b/source/DSP/ProPhatVoice.h @@ -496,8 +496,10 @@ void ProPhatVoice::updateLfo() { T lfoOut; { - //TODO: LOCK IN AUDIO THREAD - std::lock_guard lock (lfoMutex); + std::unique_lock lck (lfoMutex, std::defer_lock); + if (! lck.try_lock()) + return; + lfoOut = lfo.processSample (T (0)) * lfoAmount; } diff --git a/source/Utility/Helpers.h b/source/Utility/Helpers.h index 8c26d2ee..e32023d0 100644 --- a/source/Utility/Helpers.h +++ b/source/Utility/Helpers.h @@ -218,7 +218,7 @@ struct Selection struct OscShape : public Selection { - enum + enum Values { none = 0, saw,