#include "fx_shimmer_reverb.h" #define TAIL , -1 ShimmerReverb::ShimmerReverb(float32_t sampling_frequency) : FXElement(sampling_frequency, 1.2f), pitch_shifter_(sampling_frequency, PITCH_SHIFTER_TRANSPOSE_BOUNDARY), lp_filter_(sampling_frequency, SVF::FilterMode::SVF_LP), hp_filter_(sampling_frequency, SVF::FilterMode::SVF_HP), reverberator_(sampling_frequency), texture_(0.0f), lp_cutoff_(0.0f), hp_cutoff_(0.0f), lpq_(0.0f), amount_(0.0f), feedback_(0.0f), cutoff_(0.0f) { this->setInputGain(0.2f); this->setDiffusion(0.7f); this->setCutoff(1.0f); this->reset(); } ShimmerReverb::~ShimmerReverb() { } void ShimmerReverb::reset() { this->pitch_shifter_.reset(); this->lp_filter_.reset(); this->hp_filter_.reset(); this->reverberator_.reset(); } void ShimmerReverb::processSample(float32_t inL, float32_t inR, float32_t& outL, float32_t& outR) { this->pitch_shifter_.processSample(inL, inR, outL, outR); this->lp_filter_.processSample(outL, outR, outL, outR); this->hp_filter_.processSample(outL, outR, outL, outR); this->reverberator_.processSample(outL, outR, outL, outR); outL *= this->OutputLevelCorrector; outR *= this->OutputLevelCorrector; } void ShimmerReverb::setInputGain(float32_t input_gain) { this->reverberator_.setInputGain(input_gain); } float32_t ShimmerReverb::getInputGain() const { return this->reverberator_.getInputGain(); } void ShimmerReverb::setDiffusion(float32_t diffusion) { this->reverberator_.setDiffusion(diffusion); } float32_t ShimmerReverb::getDiffusion() const { return this->reverberator_.getDiffusion(); } void ShimmerReverb::setTime(float32_t time) { this->reverberator_.setTime(time); } float32_t ShimmerReverb::getTime() const { return this->reverberator_.getTime(); } void ShimmerReverb::setReverbAmount(float32_t amount) { amount = constrain(amount, 0.0f, 1.0f); if(this->amount_ != amount) { this->amount_ = amount; this->updateReverberatorCoefficients(); } } void ShimmerReverb::setTexture(float32_t texture) { texture = constrain(texture, 0.0f, 1.0f); if(this->texture_ != texture) { this->texture_ = texture; this->updateFilterCoefficients(); } } float32_t ShimmerReverb::getTexture() const { return this->texture_; } void ShimmerReverb::setFeedback(float32_t feedback) { feedback = constrain(feedback, 0.0f, 1.0f); if(this->feedback_ != feedback) { this->feedback_ = feedback; this->updateFilterCoefficients(); this->updateReverberatorCoefficients(); } } float32_t ShimmerReverb::getFeedback() const { return this->feedback_; } void ShimmerReverb::setCutoff(float32_t cutoff) { cutoff = constrain(cutoff, 0.0f, 1.0f); if(this->cutoff_ != cutoff) { this->cutoff_ = cutoff; this->updateFilterCoefficients(); } } void ShimmerReverb::updateFilterCoefficients() { this->lp_cutoff_ = constrain(0.50f * semitoneToRatio((this->cutoff_ < 0.5f ? this->cutoff_ - 0.5f : 0.0f ) * 216.0f), 0.0f, 0.499f); this->hp_cutoff_ = constrain(0.25f * semitoneToRatio((this->cutoff_ < 0.5f ? -0.5f : this->cutoff_ - 1.0f) * 216.0f), 0.0f, 0.499f); this->lpq_ = 1.0f + 3.0f * (1.0f - this->feedback_) * (0.5f - this->lp_cutoff_); this->lp_filter_.setFQ(this->lp_cutoff_, this->lpq_); this->hp_filter_.setFQ(this->hp_cutoff_, 1.0f); this->reverberator_.setLP(0.6f + 0.37f * this->feedback_); } void ShimmerReverb::updateReverberatorCoefficients() { float32_t reverb_amount = this->amount_ * 0.95f; reverb_amount += this->feedback_ * (2.0f - this->feedback_); reverb_amount = constrain(reverb_amount, 0.0f, 1.0f); this->setTime(0.35f + 0.63f * reverb_amount); } void ShimmerReverb::setPitch(float32_t pitch) { this->pitch_shifter_.setTranspose(pitch); } float32_t ShimmerReverb::getPitch() const { return this->pitch_shifter_.getTranspose(); } void ShimmerReverb::setSize(float32_t size) { this->pitch_shifter_.setSize(size); } float32_t ShimmerReverb::getSize() const { return this->pitch_shifter_.getSize(); }