From 52ad1d61ad690edfc2380267f9d9304663efaa2d Mon Sep 17 00:00:00 2001 From: zsliu98 <zsliu98@gmail.com> Date: Sun, 27 Aug 2023 23:53:14 -0400 Subject: [PATCH] fix: add process lock --- Source/DSP/ShaperFunctions.h | 8 +++---- Source/DSP/WaveShaper.h | 36 ++++++++++------------------- Source/PluginProcessor.cpp | 44 +++++++++++++++++++++--------------- Source/PluginProcessor.h | 14 +++--------- 4 files changed, 45 insertions(+), 57 deletions(-) diff --git a/Source/DSP/ShaperFunctions.h b/Source/DSP/ShaperFunctions.h index 139e6df..1a84b5d 100644 --- a/Source/DSP/ShaperFunctions.h +++ b/Source/DSP/ShaperFunctions.h @@ -101,16 +101,16 @@ namespace shaper { class SigmodShaper : public Shaper<FloatType> { public: void setParameters(FloatType curve) override { - trueCurve = curve * 2.5 + 0.5; + trueCurve = curve * FloatType(2.5) + FloatType(0.5); b = -basic(0); - k = static_cast<FloatType>(1) / (basic(1) + b); + k = FloatType(1) / (basic(1) + b); } private: FloatType trueCurve, k, b; FloatType basic(FloatType x) const override { - return static_cast<FloatType>(1) / (1 + std::exp(-trueCurve * x)); + return FloatType(1) / (1 + std::exp(-trueCurve * x)); } FloatType shape(FloatType x) const override { @@ -125,7 +125,7 @@ namespace shaper { trueCurve = (curve * static_cast<FloatType>(0.999) + static_cast<FloatType>(0.001)) * juce::MathConstants<FloatType>::pi / 2; b = -basic(0); - k = static_cast<FloatType>(1) / (basic(1) + b); + k = FloatType(1) / (basic(1) + b); } private: diff --git a/Source/DSP/WaveShaper.h b/Source/DSP/WaveShaper.h index 816fa07..deb0796 100644 --- a/Source/DSP/WaveShaper.h +++ b/Source/DSP/WaveShaper.h @@ -22,7 +22,7 @@ You should have received a copy of the GNU General Public License along with ZLI template<typename FloatType> class WaveHelper { public: - WaveHelper(){ + WaveHelper() { setWet(static_cast<FloatType>(zldsp::wet::formatV(zldsp::wet::defaultV))); } @@ -41,7 +41,7 @@ class WaveHelper { FloatType operator()(FloatType x) const { return shape(x); } - shaper::ShaperMixer<FloatType>* getShaper() {return &shaperMixer;} + shaper::ShaperMixer<FloatType> *getShaper() { return &shaperMixer; } private: static constexpr FloatType clip = static_cast<FloatType>(1); @@ -127,12 +127,13 @@ class LRFilters { template<typename FloatType> class WaveShaper { public: - WaveShaper() { + explicit WaveShaper(juce::AudioProcessor &processor) { + processorRef = &processor; filters[0].setCutoffFrequency(zldsp::lowSplit::defaultV); filters[1].setCutoffFrequency(zldsp::highSplit::defaultV); } - shaper::ShaperMixer<FloatType>* getShaper() {return helper.getShaper();} + shaper::ShaperMixer<FloatType> *getShaper() { return helper.getShaper(); } void setWet(FloatType wet) { helper.setWet(wet); @@ -143,6 +144,7 @@ class WaveShaper { } void setCutoffFrequency(FloatType lowFreq, FloatType highFreq) { + const juce::GenericScopedLock<juce::CriticalSection> processLock(processorRef->getCallbackLock()); filters[0].setCutoffFrequency(lowFreq); filters[1].setCutoffFrequency(highFreq); } @@ -156,30 +158,18 @@ class WaveShaper { } void setOverSampleFactor(int overSampleFactor) { + const juce::GenericScopedLock<juce::CriticalSection> processLock(processorRef->getCallbackLock()); idxSampler = static_cast<size_t>(std::min(overSampleFactor, numSamplers - 1)); for (size_t i = 0; i < numBands - 1; ++i) { filters[i].update(overSampleFactor); } + processorRef->setLatencySamples(overSamplers[idxSampler]->getLatencyInSamples()); } void setTypes(size_t type1, size_t type2) { helper.setTypes(type1, type2); } - void setParameters(bool clipFlag, bool effectFlag, float curve, - float wetWeight, bool bandSplit, float low_split, - float high_split, int overSampleFactor) { - helper.setParameters(clipFlag, curve, wetWeight); - effect = effectFlag; - split = bandSplit; - idxSampler = (unsigned int) std::min(overSampleFactor, numSamplers - 1); - filters[0].setCutoffFrequency(low_split); - filters[1].setCutoffFrequency(high_split); - for (size_t i = 0; i < numBands - 1; ++i) { - filters[i].update(idxSampler); - } - } - void reset() noexcept { for (size_t i = 0; i < numBands - 1; ++i) { filters[i].reset(); @@ -190,10 +180,6 @@ class WaveShaper { } } - float getLatencyInSamples() { - return overSamplers[idxSampler]->getLatencyInSamples(); - } - template<typename SampleType> SampleType JUCE_VECTOR_CALLTYPE processSample(SampleType s) noexcept { @@ -216,8 +202,9 @@ class WaveShaper { if (split) { auto sepBlock = juce::dsp::AudioBlock<FloatType>(bufferSeparation) - .getSubBlock(0, (size_t) ((FloatType) std::pow(2.0, idxSampler) * - (FloatType) numSamples)); + .getSubBlock(0, static_cast<size_t> ( + std::pow(FloatType(2), static_cast<FloatType>(idxSampler)) * + static_cast<FloatType>(numSamples))); juce::dsp::AudioBlock<FloatType> blocks[numBands]; std::vector<juce::dsp::ProcessContextReplacing<FloatType>> contexts; for (size_t i = 0; i < numBands; ++i) { @@ -280,6 +267,7 @@ class WaveShaper { } private: + juce::AudioProcessor *processorRef; constexpr static const int numSamplers = 5, numBands = 3; std::atomic<double> sampleRate; WaveHelper<FloatType> helper; diff --git a/Source/PluginProcessor.cpp b/Source/PluginProcessor.cpp index 1d28e3c..04b891d 100644 --- a/Source/PluginProcessor.cpp +++ b/Source/PluginProcessor.cpp @@ -28,9 +28,10 @@ ZLInflatorAudioProcessor::ZLInflatorAudioProcessor() #endif parameters(*this, nullptr, juce::Identifier("ZLInflatorParameters"), zldsp::getParameterLayout()), states(*this, nullptr, juce::Identifier("ZLInflatorStates"), zlstate::getParameterLayout()), - waveShaperAttach(chain.get<waveShaper>(), parameters) { - chain.get<gain1>().setGainDecibels(zldsp::inputGain::defaultV); - chain.get<gain2>().setGainDecibels(zldsp::outputGain::defaultV); + waveShaper(*this), + waveShaperAttach(waveShaper, parameters) { + inGain.setGainDecibels(zldsp::inputGain::defaultV); + outGain.setGainDecibels(zldsp::outputGain::defaultV); parameters.addParameterListener(zldsp::inputGain::ID, this); parameters.addParameterListener(zldsp::outputGain::ID, this); waveShaperAttach.addListeners(); @@ -97,12 +98,20 @@ void ZLInflatorAudioProcessor::prepareToPlay(double sampleRate, reset(); auto channels = static_cast<juce::uint32> (juce::jmin(getMainBusNumInputChannels(), getMainBusNumOutputChannels())); juce::dsp::ProcessSpec spec{sampleRate, static_cast<juce::uint32> (samplesPerBlock), channels}; - chain.prepare(spec); - updateParameters(); + + inGain.prepare(spec); + outGain.prepare(spec); + meterIn.prepare(spec); + meterOut.prepare(spec); + waveShaper.prepare(spec); } void ZLInflatorAudioProcessor::reset() { - chain.reset(); + inGain.reset(); + outGain.reset(); + meterIn.reset(); + meterOut.reset(); + waveShaper.reset(); } void ZLInflatorAudioProcessor::releaseResources() { @@ -127,20 +136,19 @@ bool ZLInflatorAudioProcessor::isBusesLayoutSupported( void ZLInflatorAudioProcessor::processBlock(juce::AudioBuffer<float> &buffer, juce::MidiBuffer &midiMessages) { juce::ScopedNoDenormals noDenormals; + juce::ignoreUnused(midiMessages); auto totalNumInputChannels = getTotalNumInputChannels(); auto totalNumOutputChannels = getTotalNumOutputChannels(); for (auto i = totalNumInputChannels; i < totalNumOutputChannels; ++i) buffer.clear(i, 0, buffer.getNumSamples()); - updateParameters(); - juce::dsp::AudioBlock<float> block(buffer); - chain.process(juce::dsp::ProcessContextReplacing<float>(block)); -} - -void ZLInflatorAudioProcessor::updateParameters() { - setLatencySamples(static_cast<int>(chain.get<waveShaper>().getLatencyInSamples())); + inGain.process(juce::dsp::ProcessContextReplacing<float>(block)); + meterIn.process(juce::dsp::ProcessContextReplacing<float>(block)); + waveShaper.process(juce::dsp::ProcessContextReplacing<float>(block)); + outGain.process(juce::dsp::ProcessContextReplacing<float>(block)); + meterOut.process(juce::dsp::ProcessContextReplacing<float>(block)); } //============================================================================== @@ -180,21 +188,21 @@ juce::AudioProcessor *JUCE_CALLTYPE createPluginFilter() { } MeterSource<float> *ZLInflatorAudioProcessor::getInputMeterSource() { - return &chain.get<meter1>(); + return &meterIn; } MeterSource<float> *ZLInflatorAudioProcessor::getOutputMeterSource() { - return &chain.get<meter2>(); + return &meterOut; } shaper::ShaperMixer<float> *ZLInflatorAudioProcessor::getShaperMixer() { - return chain.get<waveShaper>().getShaper(); + return waveShaper.getShaper(); } void ZLInflatorAudioProcessor::parameterChanged(const juce::String ¶meterID, float newValue) { if (parameterID.equalsIgnoreCase(zldsp::inputGain::ID)) { - chain.get<gain1>().setGainDecibels(newValue); + inGain.setGainDecibels(newValue); } else if (parameterID.equalsIgnoreCase(zldsp::outputGain::ID)) { - chain.get<gain2>().setGainDecibels(newValue); + outGain.setGainDecibels(newValue); } } \ No newline at end of file diff --git a/Source/PluginProcessor.h b/Source/PluginProcessor.h index 397e465..96435b1 100644 --- a/Source/PluginProcessor.h +++ b/Source/PluginProcessor.h @@ -101,16 +101,8 @@ class ZLInflatorAudioProcessor : public juce::AudioProcessor, //============================================================================== JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(ZLInflatorAudioProcessor) - enum { - gain1, - meter1, - waveShaper, - gain2, - meter2 - }; - - using Gain = juce::dsp::Gain<float>; - juce::dsp::ProcessorChain<Gain, MeterSource<float>, WaveShaper<float>, Gain, MeterSource<float>> chain; + juce::dsp::Gain<float> inGain, outGain; + MeterSource<float> meterIn, meterOut; + WaveShaper<float> waveShaper; WaveShaperAttach<float> waveShaperAttach; - void updateParameters(); };