#include "fx_flanger.h" #include #define MAX_FLANGER_DELAY 20.0f Flanger::Flanger(float32_t sampling_rate, float32_t delay_time, float32_t frequency, float32_t depth, float32_t feedback) : FXElement(sampling_rate), MaxDelayLineSize(static_cast(2.0f * MAX_FLANGER_DELAY * sampling_rate / 1000.0f)), delay_line_index_(0), lfo_phase_(0.0f) { this->delay_lineL_ = new float32_t[this->MaxDelayLineSize]; this->delay_lineR_ = new float32_t[this->MaxDelayLineSize]; this->setDelayTime(delay_time); this->setFrequency(frequency); this->setDepth(depth); this->setFeedback(feedback); } Flanger::~Flanger() { delete[] this->delay_lineL_; delete[] this->delay_lineR_; } void Flanger::processSample(float32_t inL, float32_t inR, float32_t& outL, float32_t& outR) { static float32_t M2PI = 2.0f * PI; // Calculate the delay time based on the depth and rate parameters float32_t delay = this->getDelayTime() + this->getDepth() * std::sin(this->lfo_phase_); // Convert the delay time to samples unsigned delay_samples = static_cast(delay * this->getSamplingRate() / 1000.0f); // mix the input audio with the delayed audio and the feedback signal outL = inL + this->delay_lineL_[(this->delay_line_index_ + this->delay_line_size_ - delay_samples) % this->delay_line_size_] * (1.0 - this->getFeedback()); outR = inR + this->delay_lineR_[(this->delay_line_index_ + this->delay_line_size_ - delay_samples) % this->delay_line_size_] * (1.0 - this->getFeedback()); // Update the delay buffer with the mixed audio and the feedback signal this->delay_lineL_[this->delay_line_index_] = inL + outL * this->getFeedback(); this->delay_lineR_[this->delay_line_index_] = inR + outR * this->getFeedback(); this->delay_line_index_ = (this->delay_line_index_ + 1) % this->delay_line_size_; this->lfo_phase_ += this->lfo_phase_increment_; if(this->lfo_phase_ > M2PI) { this->lfo_phase_ -= M2PI; } } void Flanger::setDelayTime(float32_t delayMS) { this->delay_time_ms_ = constrain(delayMS, 1.0f, MAX_FLANGER_DELAY); this->adjustDelayCofficients(); } float32_t Flanger::getDelayTime() const { return this->delay_time_ms_; } void Flanger::setFrequency(float32_t frequency) { frequency = constrain(frequency, 0.1f, 1.0f); this->frequency_ = frequency; this->lfo_phase_increment_ = 2.0f * PI * frequency / this->getSamplingRate(); } float32_t Flanger::getFrequency() const { return this->frequency_; } void Flanger::setDepth(float32_t depth) { this->depth_ = constrain(depth, 0.0f, MAX_FLANGER_DELAY); this->adjustDelayCofficients(); } float32_t Flanger::getDepth() const { return this->depth_; } void Flanger::setFeedback(float32_t feedback) { this->feedback_ = constrain(feedback, 0.0f, 1.0f); } float32_t Flanger::getFeedback() const { return this->feedback_; } void Flanger::adjustDelayCofficients() { this->delay_line_size_ = static_cast(this->getSamplingRate() * (this->getDelayTime() + this->getDepth()) / 1000.0f); }