Skip to content

Commit

Permalink
fix: add process lock
Browse files Browse the repository at this point in the history
  • Loading branch information
zsliu98 committed Aug 28, 2023
1 parent 693b9b6 commit 52ad1d6
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 57 deletions.
8 changes: 4 additions & 4 deletions Source/DSP/ShaperFunctions.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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:
Expand Down
36 changes: 12 additions & 24 deletions Source/DSP/WaveShaper.h
Original file line number Diff line number Diff line change
Expand Up @@ -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)));
}

Expand All @@ -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);
Expand Down Expand Up @@ -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);
Expand All @@ -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);
}
Expand All @@ -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();
Expand All @@ -190,10 +180,6 @@ class WaveShaper {
}
}

float getLatencyInSamples() {
return overSamplers[idxSampler]->getLatencyInSamples();
}

template<typename SampleType>
SampleType JUCE_VECTOR_CALLTYPE
processSample(SampleType s) noexcept {
Expand All @@ -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) {
Expand Down Expand Up @@ -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;
Expand Down
44 changes: 26 additions & 18 deletions Source/PluginProcessor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down Expand Up @@ -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() {
Expand All @@ -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));
}

//==============================================================================
Expand Down Expand Up @@ -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 &parameterID, 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);
}
}
14 changes: 3 additions & 11 deletions Source/PluginProcessor.h
Original file line number Diff line number Diff line change
Expand Up @@ -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();
};

0 comments on commit 52ad1d6

Please sign in to comment.