Finalizing the Phase before testing

pull/409/head
abscisys 2 years ago
parent 6ca3e3d340
commit 154cf690cb
  1. 2
      src/Makefile
  2. 123
      src/fx_phaser.cpp
  3. 38
      src/fx_phaser.h
  4. 1
      src/fx_rack.cpp
  5. 1
      src/fx_rack.h

@ -10,7 +10,7 @@ OBJS = main.o kernel.o minidexed.o config.o userinterface.o uimenu.o \
mididevice.o midikeyboard.o serialmididevice.o pckeyboard.o \ mididevice.o midikeyboard.o serialmididevice.o pckeyboard.o \
sysexfileloader.o performanceconfig.o perftimer.o \ sysexfileloader.o performanceconfig.o perftimer.o \
effect_compressor.o effect_platervbstereo.o \ effect_compressor.o effect_platervbstereo.o \
fx.o fx_tape_delay.o fx_shimmer_reverb.o fx_rack.o \ fx.o fx_phaser.o fx_tape_delay.o fx_shimmer_reverb.o fx_rack.o \
uibuttons.o midipin.o uibuttons.o midipin.o
OPTIMIZE = -O3 OPTIMIZE = -O3

@ -2,17 +2,19 @@
#include <cmath> #include <cmath>
PhaserStage::PhaserStage(float32_t sampling_rate, float32_t frequency, float32_t q) : PhaserParameter::PhaserParameter(float32_t sampling_rate, float32_t frequency, float32_t q) :
FXBase(sampling_rate), FXBase(sampling_rate),
frequency_(frequency), frequency_(frequency),
q_(q) q_(q)
{ {
memset(this->z1, 0, 2 * sizeof(float32_t));
memset(this->z2, 0, 2 * sizeof(float32_t));
this->computeCoefficients(); this->computeCoefficients();
} }
void PhaserStage::computeCoefficients() PhaserParameter::~PhaserParameter()
{
}
void PhaserParameter::computeCoefficients()
{ {
float32_t w0 = 2.0f * PI * this->getFrequency() / this->getSamplingRate(); float32_t w0 = 2.0f * PI * this->getFrequency() / this->getSamplingRate();
float32_t alpha = sin(w0) / (2.0f * this->q_); float32_t alpha = sin(w0) / (2.0f * this->q_);
@ -23,36 +25,125 @@ void PhaserStage::computeCoefficients()
this->b2 = this->a2; this->b2 = this->a2;
} }
void PhaserParameter::setFrequency(float32_t frequency)
{
this->frequency_ = constrain(frequency, 0.1, 10.0);
this->computeCoefficients();
}
float32_t PhaserParameter::getFrequency() const
{
return this->frequency_;
}
void PhaserParameter::setQ(float32_t q)
{
this->q_ = constrain(q, 0.5f, 10.0f);
this->computeCoefficients();
}
float32_t PhaserParameter::getQ() const
{
return this->q_;
}
// PhaserStage implementation
PhaserStage::PhaserStage(float32_t sampling_rate, PhaserParameter* params) :
FXBase(sampling_rate),
params_(params)
{
memset(this->z1, 0, 2 * sizeof(float32_t));
memset(this->z2, 0, 2 * sizeof(float32_t));
}
void PhaserStage::process(float32_t inL, float32_t inR, float32_t& outL, float32_t& outR) void PhaserStage::process(float32_t inL, float32_t inR, float32_t& outL, float32_t& outR)
{ {
outL = (this->a0 * inL + this->a1 * this->z1[0] + this->a2 * this->z2[0]) / this->a0; outL = (this->params_->a0 * inL + this->params_->a1 * this->z1[0] + this->params_->a2 * this->z2[0]) / this->params_->a0;
this->z2[0] = this->z1[0]; this->z2[0] = this->z1[0];
this->z2[0] = inL; this->z2[0] = inL;
outR = (this->a0 * inR + this->a1 * this->z1[1] + this->a2 * this->z2[1]) / this->a0; outR = (this->params_->a0 * inR + this->params_->a1 * this->z1[1] + this->params_->a2 * this->z2[1]) / this->params_->a0;
this->z2[1] = this->z1[1]; this->z2[1] = this->z1[1];
this->z2[1] = inR; this->z2[1] = inR;
} }
void PhaserStage::setFrequency(float32_t frequency)
// Phaser implementation
Phaser::Phaser(float32_t sampling_rate, float32_t frequency, float32_t q) :
FX(sampling_rate),
params_(sampling_rate, frequency, q),
phase_(0.0f),
phase_increment_(0.0f)
{ {
this->frequency_ = constrain(frequency, 0.0, 10.0); this->phase_increment_ = 2.0f * PI * frequency / this->getSamplingRate();
this->computeCoefficients(); for(unsigned i = 0; i < NUM_PHASER_STAGES; ++i)
{
this->stages_[i] = new PhaserStage(sampling_rate, &this->params_);
}
} }
float32_t PhaserStage::getFrequency() const Phaser::~Phaser()
{ {
return this->frequency_; for(unsigned i = 0; i < NUM_PHASER_STAGES; ++i)
{
delete this->stages_[i];
}
} }
void PhaserStage::setQ(float32_t q) void Phaser::process(float32_t* left_input, float32_t* right_input, float32_t* left_output, float32_t* right_output, size_t nSamples)
{ {
this->q_ = constrain(q, 0.1f, 1.0f); float sampleL;
this->computeCoefficients(); float sampleR;
for(unsigned i = 0; i < nSamples; ++i)
{
// Process the input sample through each stage of the phaser
sampleL = *left_input;
sampleR = *right_input;
for(unsigned s = 0; s < NUM_PHASER_STAGES; ++s)
{
this->stages_[s]->process(sampleL, sampleR, sampleL, sampleR);
}
// Modulate the output of the phaser using the LFO
*left_output = sampleL * (0.5f + 0.5f * cos(this->phase_));
*right_output = sampleR * (0.5f + 0.5f * cos(this->phase_));;
// Update the phase of the LFO
this->phase_ += this->phase_increment_;
if(this->phase_ > 2.0f * PI) {
this->phase_ -= 2.0 * PI;
}
// Move to next input sample
++left_input;
++right_input;
// Move to next output sample
++left_output;
++right_output;
}
} }
float32_t PhaserStage::getQ() const void Phaser::setFrequency(float32_t frequency)
{ {
return this->q_; this->params_.setFrequency(frequency);
this->phase_increment_ = 2.0f * PI * frequency / this->getSamplingRate();
}
float32_t Phaser::getFrequency() const
{
return this->params_.getFrequency();
} }
void Phaser::setQ(float32_t q)
{
this->params_.setQ(q);
}
float32_t Phaser::getQ() const
{
return this->params_.getQ();
}

@ -20,14 +20,16 @@
#include "fx.h" #include "fx.h"
class PhaserStage : public FXBase class PhaserStage;
class PhaserParameter : public FXBase
{ {
DISALLOW_COPY_AND_ASSIGN(PhaserStage); friend class PhaserStage;
DISALLOW_COPY_AND_ASSIGN(PhaserParameter);
public: public:
PhaserStage(float32_t sampling_rate, float32_t frequency = 0.5f, float32_t q = 1.0f); PhaserParameter(float32_t sampling_rate, float32_t frequency = 0.5f, float32_t q = 1.0f);
virtual ~PhaserParameter();
void process(float32_t inL, float32_t inR, float32_t& outL, float32_t& outR);
void setFrequency(float32_t frequency); void setFrequency(float32_t frequency);
inline float32_t getFrequency() const; inline float32_t getFrequency() const;
@ -42,6 +44,19 @@ private:
float32_t q_; // Q factor for the filters float32_t q_; // Q factor for the filters
float32_t a0, a1, a2, b1, b2; // Coefficients for the stage's filter float32_t a0, a1, a2, b1, b2; // Coefficients for the stage's filter
};
class PhaserStage : public FXBase
{
DISALLOW_COPY_AND_ASSIGN(PhaserStage);
public:
PhaserStage(float32_t sampling_rate, PhaserParameter* params);
void process(float32_t inL, float32_t inR, float32_t& outL, float32_t& outR);
private:
PhaserParameter* params_; // All paremters of the phaser including the inner coefficients
float32_t z1[2], z2[2]; // State variables for the stage's filter float32_t z1[2], z2[2]; // State variables for the stage's filter
}; };
@ -52,11 +67,20 @@ class Phaser : public FX
DISALLOW_COPY_AND_ASSIGN(Phaser); DISALLOW_COPY_AND_ASSIGN(Phaser);
public: public:
Phaser(float32_t sampling_rate, float32_t frequency, float32_t q); Phaser(float32_t sampling_rate, float32_t frequency = 0.5f, float32_t q = 1.0f);
virtual ~Phaser(); virtual ~Phaser();
virtual void process(float32_t* left_input, float32_t* right_input, float32_t* left_output, float32_t* right_output, size_t nSamples) override; virtual void process(float32_t* left_input, float32_t* right_input, float32_t* left_output, float32_t* right_output, size_t nSamples) override;
void setFrequency(float32_t frequency);
inline float32_t getFrequency() const;
void setQ(float32_t q);
inline float32_t getQ() const;
private: private:
PhaserStage stages_[NUM_PHASER_STAGES]; PhaserParameter params_;
float32_t phase_; // Current phase of the LFO
float32_t phase_increment_; // Amount to increment the phase at each sample
PhaserStage* stages_[NUM_PHASER_STAGES];
}; };

@ -45,6 +45,7 @@ FXRack::FXRack(float32_t sampling_rate) :
FX(sampling_rate), FX(sampling_rate),
fx_chain_() fx_chain_()
{ {
this->registerFX(new Phaser(sampling_rate));
this->registerFX(new TapeDelay(sampling_rate)); this->registerFX(new TapeDelay(sampling_rate));
this->registerFX(new ShimmerReverb(sampling_rate)); this->registerFX(new ShimmerReverb(sampling_rate));
} }

@ -20,6 +20,7 @@
#pragma once #pragma once
#include "fx.h" #include "fx.h"
#include "fx_phaser.h"
#include "fx_tape_delay.h" #include "fx_tape_delay.h"
#include "fx_shimmer_reverb.h" #include "fx_shimmer_reverb.h"

Loading…
Cancel
Save