You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
MiniDexed/src/fx_phaser.cpp

142 lines
3.0 KiB

#include "fx_phaser.h"
#include <algorithm>
#include <cmath>
Phaser::AllpassDelay::AllpassDelay() :
a1_(0.0f)
{
this->reset();
}
Phaser::AllpassDelay::~AllpassDelay()
{
}
void Phaser::AllpassDelay::reset()
{
memset(this->z_, 0, 2 * sizeof(float32_t));
}
void Phaser::AllpassDelay::processSample(float32_t inL, float32_t inR, float32_t& outL, float32_t& outR)
{
outL = inL * -this->a1_ + this->z_[0];
this->z_[0] = outL * this->a1_ + inL;
outR = inR * -this->a1_ + this->z_[1];
this->z_[1] = outR * this->a1_ + inR;
}
void Phaser::AllpassDelay::setDelay(float32_t delay)
{
this->a1_ = (1.0f - delay) / (1.0f + delay);
}
Phaser::Phaser(float32_t sampling_rate, float32_t rate, float32_t depth, float32_t feedback) :
FXElement(sampling_rate),
lfo_(sampling_rate, LFO::Waveform::Sine, 0.0f, 2.5f),
depth_(0.0f),
feedback_(0.0f),
dmin_(0.0f),
dmax_(0.0f)
{
this->setRate(rate);
this->setDepth(depth);
this->setFeedback(feedback);
this->setFrequencyRange(440.0f, 1600.0f);
this->reset();
}
Phaser::~Phaser()
{
}
void Phaser::reset()
{
memset(this->z_, 0, 2 * sizeof(float32_t));
for(unsigned i = 0; i < this->nb_stages_; ++i)
{
this->stages_[i].reset();
}
this->lfo_.reset();
}
void Phaser::processSample(float32_t inL, float32_t inR, float32_t& outL, float32_t& outR)
{
float32_t d = this->dmin_ + (this->dmax_ - this->dmin_) * ((1.0f + this->lfo_.process()) / 2.0f);
float32_t sampleL = inL + this->feedback_ * this->z_[0];
float32_t sampleR = inR + this->feedback_ * this->z_[1];
for(unsigned i = 0; i < this->nb_stages_; ++i)
{
this->stages_[i].setDelay(d);
this->stages_[i].processSample(sampleL, sampleR, sampleL, sampleR);
}
this->z_[0] = sampleL;
this->z_[1] = sampleR;
outL = inL + this->z_[0] * this->depth_;
outR = inR + this->z_[1] * this->depth_;
}
void Phaser::setFrequencyRange(float32_t min_frequency, float32_t max_frequency)
{
this->dmin_ = 2.0f * std::min(min_frequency, max_frequency) / this->getSamplingRate();
this->dmax_ = 2.0f * std::max(min_frequency, max_frequency) / this->getSamplingRate();
}
void Phaser::setRate(float32_t rate)
{
rate = constrain(rate, 0.0f, 1.0f);
this->lfo_.setNormalizedFrequency(rate);
}
inline float32_t Phaser::getRate() const
{
return this->lfo_.getNormalizedFrequency();
}
void Phaser::setDepth(float32_t depth)
{
depth = constrain(depth, 0.0f, 1.0f);
this->depth_ = depth;
}
inline float32_t Phaser::getDepth() const
{
return this->depth_;
}
void Phaser::setFeedback(float32_t feedback)
{
feedback = constrain(feedback, 0.0f, 0.97f);
this->feedback_ = feedback;
}
inline float32_t Phaser::getFeedback() const
{
return this->feedback_;
}
void Phaser::setNbStages(unsigned nb_stages)
{
if(nb_stages < 2)
{
nb_stages = 2;
}
else if(nb_stages > MAX_NB_PHASES)
{
nb_stages = MAX_NB_PHASES;
}
this->nb_stages_ = nb_stages;
}
unsigned Phaser::getNbStages() const
{
return this->nb_stages_;
}