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. 40
      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 \
sysexfileloader.o performanceconfig.o perftimer.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
OPTIMIZE = -O3

@ -2,17 +2,19 @@
#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),
frequency_(frequency),
q_(q)
{
memset(this->z1, 0, 2 * sizeof(float32_t));
memset(this->z2, 0, 2 * sizeof(float32_t));
this->computeCoefficients();
}
void PhaserStage::computeCoefficients()
PhaserParameter::~PhaserParameter()
{
}
void PhaserParameter::computeCoefficients()
{
float32_t w0 = 2.0f * PI * this->getFrequency() / this->getSamplingRate();
float32_t alpha = sin(w0) / (2.0f * this->q_);
@ -23,36 +25,125 @@ void PhaserStage::computeCoefficients()
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)
{
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] = 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] = 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->computeCoefficients();
this->phase_increment_ = 2.0f * PI * frequency / this->getSamplingRate();
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);
this->computeCoefficients();
float sampleL;
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"
class PhaserStage : public FXBase
class PhaserStage;
class PhaserParameter : public FXBase
{
DISALLOW_COPY_AND_ASSIGN(PhaserStage);
friend class PhaserStage;
DISALLOW_COPY_AND_ASSIGN(PhaserParameter);
public:
PhaserStage(float32_t sampling_rate, float32_t frequency = 0.5f, float32_t q = 1.0f);
void process(float32_t inL, float32_t inR, float32_t& outL, float32_t& outR);
PhaserParameter(float32_t sampling_rate, float32_t frequency = 0.5f, float32_t q = 1.0f);
virtual ~PhaserParameter();
void setFrequency(float32_t frequency);
inline float32_t getFrequency() const;
@ -42,7 +44,20 @@ private:
float32_t q_; // Q factor for the filters
float32_t a0, a1, a2, b1, b2; // Coefficients for the stage's filter
float32_t z1[2], z2[2]; // State variables 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
};
#define NUM_PHASER_STAGES 6
@ -52,11 +67,20 @@ class Phaser : public FX
DISALLOW_COPY_AND_ASSIGN(Phaser);
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 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:
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_chain_()
{
this->registerFX(new Phaser(sampling_rate));
this->registerFX(new TapeDelay(sampling_rate));
this->registerFX(new ShimmerReverb(sampling_rate));
}

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

Loading…
Cancel
Save