/* ============================================================================== Reverb.h Created: 30 Dec 2023 8:38:55pm Author: binya ============================================================================== */ #pragma once #include #include "Effect.h" #include /** This is a simple Effect class that wraps around Gin's SimpleVerb implementation */ class Reverb final : public Effect { public: Reverb() = default; void initialize(int numChannels, int fxSampleRate) override { int numEffects = numChannels / 2 + numChannels % 2; channelGinReverbs.resize(numEffects); for (int ch = 0; ch < numEffects; ch++) { channelGinReverbs[ch] = std::make_unique(); channelGinReverbs[ch]->setSampleRate(float(fxSampleRate)); channelGinReverbs[ch]->setParameters(0.f, 0.f, 1.f, 0.f, 1.f, 0.f, 0.f); } } // The intended ranges of these values are in PluginParameters.h void updateParams(float size, float damping, float predelay, float lows, float highs, float mix) const { for (const auto& channelGinReverb : channelGinReverbs) { channelGinReverb->setParameters( juce::jmap(size, PluginParameters::REVERB_SIZE_RANGE.getStart(), PluginParameters::REVERB_SIZE_RANGE.getEnd(), 0.f, 1.f), juce::jmap(damping, PluginParameters::REVERB_DAMPING_RANGE.getStart(), PluginParameters::REVERB_DAMPING_RANGE.getEnd(), 0.f, 1.f), float(sqrtf(predelay / 250.f)), // conversions to counteract the faders in this algorithm juce::jmap(highs, PluginParameters::REVERB_HIGHS_RANGE.getStart(), PluginParameters::REVERB_HIGHS_RANGE.getEnd(), 0.3f, 1.f), 1.f - juce::jmap(lows, PluginParameters::REVERB_LOWS_RANGE.getStart(), PluginParameters::REVERB_LOWS_RANGE.getEnd(), 0.3f, 1.f), mix, (1.f - mix) / 2.f ); } } void updateParams(const SamplerParameters& sampleSound, bool) override { updateParams( sampleSound.reverbSize->get(), sampleSound.reverbDamping->get(), sampleSound.reverbPredelay->get(), sampleSound.reverbLows->get(), sampleSound.reverbHighs->get(), sampleSound.reverbMix->get() ); } void process(juce::AudioBuffer& buffer, int numSamples, int startSample = 0) override { bool lastIsMono = buffer.getNumChannels() % 2 == 1; for (int ch = 0; ch < buffer.getNumChannels(); ch += 2) { // I modified the header of the process method to work easier with this code, you'll need to do the same to get it to compile // void SimpleVerb::process (const float* in1, const float* in2, float* out1, float* out2, int numSamples) if (lastIsMono && ch == buffer.getNumChannels() - 1) channelGinReverbs[ch / 2]->process( buffer.getReadPointer(ch, startSample), buffer.getReadPointer(ch, startSample), buffer.getWritePointer(ch, startSample), buffer.getWritePointer(ch, startSample), numSamples); else channelGinReverbs[ch / 2]->process( buffer.getReadPointer(ch, startSample), buffer.getReadPointer(ch + 1, startSample), buffer.getWritePointer(ch, startSample), buffer.getWritePointer(ch + 1, startSample), numSamples); } } private: std::vector> channelGinReverbs; };