Browse Source

update LindenbergResearch modules

pull/1639/head
bsp2 6 years ago
parent
commit
a14e043333
12 changed files with 195 additions and 77 deletions
  1. BIN
      plugins/community/repos/LindenbergResearch/design/Korg35VCF.afdesign
  2. +19
    -23
      plugins/community/repos/LindenbergResearch/res/panels/Korg35VCF.svg
  3. +1
    -2
      plugins/community/repos/LindenbergResearch/src/dsp/DSPMath.cpp
  4. +1
    -2
      plugins/community/repos/LindenbergResearch/src/dsp/DSPMath.hpp
  5. +7
    -6
      plugins/community/repos/LindenbergResearch/src/dsp/DSPSystem.hpp
  6. +111
    -27
      plugins/community/repos/LindenbergResearch/src/dsp/Korg35Filter.cpp
  7. +28
    -10
      plugins/community/repos/LindenbergResearch/src/dsp/Korg35Filter.hpp
  8. +4
    -1
      plugins/community/repos/LindenbergResearch/src/dsp/LambertW.cpp
  9. +2
    -2
      plugins/community/repos/LindenbergResearch/src/dsp/WaveShaper.cpp
  10. +18
    -0
      plugins/community/repos/LindenbergResearch/src/dsp/WaveShaper.hpp
  11. +3
    -3
      plugins/community/repos/LindenbergResearch/src/modules/Korg35.cpp
  12. +1
    -1
      plugins/community/repos/LindenbergResearch/src/widgets/LRPanel.cpp

BIN
plugins/community/repos/LindenbergResearch/design/Korg35VCF.afdesign View File


+ 19
- 23
plugins/community/repos/LindenbergResearch/res/panels/Korg35VCF.svg
File diff suppressed because it is too large
View File


+ 1
- 2
plugins/community/repos/LindenbergResearch/src/dsp/DSPMath.cpp View File

@@ -33,10 +33,9 @@ float cliph(float in, float clip) {
*/ */
float wrapTWOPI(float n) { float wrapTWOPI(float n) {
float b = 1.f / TWOPI * n; float b = 1.f / TWOPI * n;
return (b - lround(b)) * TWOPI;
return (b - lroundf(b)) * TWOPI;
} }



/** /**
* @brief Get PLL increment depending on frequency * @brief Get PLL increment depending on frequency
* @param frq Frequency * @param frq Frequency


+ 1
- 2
plugins/community/repos/LindenbergResearch/src/dsp/DSPMath.hpp View File

@@ -6,10 +6,9 @@
#include "dsp/resampler.hpp" #include "dsp/resampler.hpp"
#include "DSPEffect.hpp" #include "DSPEffect.hpp"


#define LAMBERT_W_THRESHOLD 10e-10
using namespace rack; using namespace rack;


const static float TWOPI = (float) M_PI * 2;
const static float TWOPI = lroundf(M_PI * 2.);


namespace dsp { namespace dsp {




+ 7
- 6
plugins/community/repos/LindenbergResearch/src/dsp/DSPSystem.hpp View File

@@ -50,13 +50,14 @@ struct DSPSystem {


protected: protected:
#ifdef _MSC_VER #ifdef _MSC_VER
DSPPort input[NUM_IN + 1];
DSPPort output[NUM_OUT + 1];
DSPParam param[NUM_PARAM + 1];
// (note) +1 to avoid "illegal zero-sized array" errors
DSPPort input[NUM_IN + 1];
DSPPort output[NUM_OUT + 1];
DSPParam param[NUM_PARAM + 1];
#else #else
DSPPort input[NUM_IN + 1] = {};
DSPPort output[NUM_OUT + 1] = {};
DSPParam param[NUM_PARAM] = {};
DSPPort input[NUM_IN] = {};
DSPPort output[NUM_OUT] = {};
DSPParam param[NUM_PARAM] = {};
#endif #endif


float sr; float sr;


+ 111
- 27
plugins/community/repos/LindenbergResearch/src/dsp/Korg35Filter.cpp View File

@@ -18,15 +18,24 @@


#include "Korg35Filter.hpp" #include "Korg35Filter.hpp"
#include "DSPEffect.hpp" #include "DSPEffect.hpp"
#include "DSPMath.hpp"




/**
* @brief Construct a new Korg35 filter stage
* @param sr SampleRate
* @param type Lowpass / Highpass
*/
dsp::Korg35FilterStage::Korg35FilterStage(float sr, FilterType type) : DSPEffect(sr) { dsp::Korg35FilterStage::Korg35FilterStage(float sr, FilterType type) : DSPEffect(sr) {
this->type = type; this->type = type;
} }




/**
* @brief Init stage
*/
void dsp::Korg35FilterStage::init() { void dsp::Korg35FilterStage::init() {
type = LPF1;
type = LP_STAGE;
alpha = 1.f; alpha = 1.f;
beta = 1.f; beta = 1.f;
zn1 = 0; zn1 = 0;
@@ -34,19 +43,25 @@ void dsp::Korg35FilterStage::init() {
} }




/**
* @brief Recompute filter parameter
*/
void dsp::Korg35FilterStage::invalidate() { void dsp::Korg35FilterStage::invalidate() {
// only process in dedicated mode // only process in dedicated mode
if (!dedicated) return; if (!dedicated) return;


float wd = 2 * PI * fc;
float T = 1 / sr;
float wa = (2 / T) * tan(wd * T / 2);
float g = wa * T / 2;
float wd = TWOPI * fc;
float T = 1.f / sr;
float wa = (2.f / T) * tanf(wd * T / 2.f);
float g = wa * T / 2.f;


alpha = g / (1.f + g); alpha = g / (1.f + g);
} }




/**
* @brief Update filter and compute next sample
*/
void dsp::Korg35FilterStage::process() { void dsp::Korg35FilterStage::process() {
// v(n) // v(n)
float vn = (in - zn1) * alpha; float vn = (in - zn1) * alpha;
@@ -55,80 +70,149 @@ void dsp::Korg35FilterStage::process() {


zn1 = vn + lpf; zn1 = vn + lpf;


float hpf = in - lpf;

// switch filter type // switch filter type
if (type == LPF1) {
if (type == LP_STAGE) {
out = lpf; out = lpf;
} else { } else {
float hpf = in - lpf;
out = hpf; out = hpf;
} }


} }




/**
* @brief Init main filter
*/
void dsp::Korg35Filter::init() { void dsp::Korg35Filter::init() {
fc = sr / 2;
fc = sr / 2.f;
peak = 0.f; peak = 0.f;


lpf->init();
/* lowpass stages */
lpf1->init();
lpf2->init();

/* highpass stages */
hpf1->init(); hpf1->init();
hpf2->init(); hpf2->init();
} }




/**
* @brief Recompute filter parameter
*/
void dsp::Korg35Filter::invalidate() { void dsp::Korg35Filter::invalidate() {
float frqHz = MAX_FREQUENCY / 1000.f * powf(1000.f, fc); float frqHz = MAX_FREQUENCY / 1000.f * powf(1000.f, fc);


float wd = 2 * PI * frqHz;
float T = 1 / sr;
float wa = (2 / T) * tan(wd * T / 2);
float g = wa * T / 2;
float wd = TWOPI * frqHz;
float T = 1.f / sr;
float wa = (2.f / T) * tanf(wd * T / 2.f);
float g = wa * T / 2.f;


float G = g / (1.f + g); float G = g / (1.f + g);


// set alphas
lpf->alpha = G;
hpf1->alpha = G;
hpf2->alpha = G;


hpf2->beta = -1.f * G / (1.f + g);
lpf->beta = 1.f / (1.f + g);
if (type == HPF) {
/* HIGHPASS */
lpf1->alpha = G;
hpf1->alpha = G;
hpf2->alpha = G;

hpf2->beta = -1.f * G / (1.f + g);
lpf1->beta = 1.f / (1.f + g);
} else {
/* LOWPASS */
lpf1->alpha = G;
lpf2->alpha = G;
hpf1->alpha = G;

lpf2->beta = (peak - peak * G) / (1.f + g);
hpf1->beta = -1.f / (1.f + g);
}


Ga = 1.f / (1.f - peak * G + peak * G * G); Ga = 1.f / (1.f - peak * G + peak * G * G);
} }




/**
* @brief Compute next sample for output depending on filter type
*/
void dsp::Korg35Filter::process() { void dsp::Korg35Filter::process() {
type == LPF ? processLPF() : processHPF();
}


/**
* @brief Do the lowpass filtering and oversampling
*/
void dsp::Korg35Filter::processLPF() {
lpf1->in = in;
lpf1->process();
float y1 = lpf1->out;

float s35h = hpf1->getFeedback() + lpf2->getFeedback();

float u = Ga * (y1 + s35h);
//float y = peak * fastatan(sat * u * 0.1) * 10.f;

u = tanhf(sat * u * 0.1) * 10.f;

lpf2->in = u;
lpf2->process();

float y = peak * lpf2->out;


hpf1->in = y;
hpf1->process();


if (peak > 0) {
y *= 1.f / peak; // normalize
}

out = y;
}


/**
* @brief Do the highpass filtering and oversampling
*/
void dsp::Korg35Filter::processHPF() {
hpf1->in = in; hpf1->in = in;
hpf1->process(); hpf1->process();
float y1 = hpf1->out; float y1 = hpf1->out;


float s35h = hpf2->getFeedback() + lpf->getFeedback();
float s35h = hpf2->getFeedback() + lpf1->getFeedback();


float u = Ga * (y1 + s35h); float u = Ga * (y1 + s35h);
float y = peak * u;

y = tanh(sat * y);
float y = peak * fastatan(sat * u * 0.1) * 10.f;


hpf2->in = y; hpf2->in = y;
hpf2->process(); hpf2->process();


lpf->in = hpf2->out;
lpf->process();
lpf1->in = hpf2->out;
lpf1->process();


if (peak > 0) { if (peak > 0) {
y *= 1 / peak; // normalize
y *= 1.f / peak; // normalize
} }


out = y; out = y;
} }




/**
* @brief Update samplerate
* @param sr SR
*/
void dsp::Korg35Filter::setSamplerate(float sr) { void dsp::Korg35Filter::setSamplerate(float sr) {
DSPEffect::setSamplerate(sr); DSPEffect::setSamplerate(sr);


// derive samplerate change // derive samplerate change
lpf->setSamplerate(sr);
lpf1->setSamplerate(sr);
lpf2->setSamplerate(sr);
hpf1->setSamplerate(sr); hpf1->setSamplerate(sr);
hpf2->setSamplerate(sr); hpf2->setSamplerate(sr);




+ 28
- 10
plugins/community/repos/LindenbergResearch/src/dsp/Korg35Filter.hpp View File

@@ -23,20 +23,22 @@
#include "engine.hpp" #include "engine.hpp"
#include "DSPMath.hpp" #include "DSPMath.hpp"


#define PI 3.14159265358979323846f

namespace dsp { namespace dsp {


/**
* @brief Represents one filter stage
*/
struct Korg35FilterStage : DSPEffect { struct Korg35FilterStage : DSPEffect {
enum FilterType { enum FilterType {
LPF1, // lowpass stage
HPF1 // highpass stage
LP_STAGE, // lowpass stage
HP_STAGE // highpass stage
}; };


bool dedicated = false; bool dedicated = false;


float fc;
FilterType type; FilterType type;

float fc;
float alpha, beta; float alpha, beta;
float zn1; float zn1;


@@ -56,10 +58,21 @@ struct Korg35FilterStage : DSPEffect {
}; };




/**
* @brief Actual Korg35 Filter Class
*/
struct Korg35Filter : DSPEffect { struct Korg35Filter : DSPEffect {
static constexpr float MAX_FREQUENCY = 20000.f; static constexpr float MAX_FREQUENCY = 20000.f;


Korg35FilterStage *lpf, *hpf1, *hpf2;
enum FilterType {
LPF, // lowpass
HPF // highpass
};


Korg35FilterStage *lpf1, *lpf2, *hpf1, *hpf2;
FilterType type;

float Ga; float Ga;


float in, out; float in, out;
@@ -68,16 +81,21 @@ struct Korg35Filter : DSPEffect {
float fc, peak, sat; float fc, peak, sat;




Korg35Filter(float sr) : DSPEffect(sr) {
lpf = new Korg35FilterStage(sr, Korg35FilterStage::LPF1);
hpf1 = new Korg35FilterStage(sr, Korg35FilterStage::HPF1);
hpf2 = new Korg35FilterStage(sr, Korg35FilterStage::HPF1);
Korg35Filter(float sr, FilterType type) : DSPEffect(sr) {
Korg35Filter::type = type;

lpf1 = new Korg35FilterStage(sr, Korg35FilterStage::LP_STAGE);
lpf2 = new Korg35FilterStage(sr, Korg35FilterStage::LP_STAGE);
hpf1 = new Korg35FilterStage(sr, Korg35FilterStage::HP_STAGE);
hpf2 = new Korg35FilterStage(sr, Korg35FilterStage::HP_STAGE);
} }




void init() override; void init() override;
void invalidate() override; void invalidate() override;
void process() override; void process() override;
void processLPF();
void processHPF();
void setSamplerate(float sr) override; void setSamplerate(float sr) override;
}; };




+ 4
- 1
plugins/community/repos/LindenbergResearch/src/dsp/LambertW.cpp View File

@@ -16,7 +16,7 @@
#include <cmath> #include <cmath>
#include "Horner.h" #include "Horner.h"


namespace dsp {
using namespace dsp;


// fork macro to keep the tree balanced // fork macro to keep the tree balanced
#define Y2(d1, c12, d2) \ #define Y2(d1, c12, d2) \
@@ -32,6 +32,9 @@ namespace dsp {
#define Y7(d1, c12, d2, c23, d3, c34, d4, c45, d5, c56, d6, c67, d7) \ #define Y7(d1, c12, d2, c23, d3, c34, d4, c45, d5, c56, d6, c67, d7) \
Y6(d1, c12, d2, c23, Y2(d3, c34, d4), c45, d5, c56, d6, c67, d7) Y6(d1, c12, d2, c23, Y2(d3, c34, d4), c45, d5, c56, d6, c67, d7)



namespace dsp {

class BranchPoint { class BranchPoint {
}; };




+ 2
- 2
plugins/community/repos/LindenbergResearch/src/dsp/WaveShaper.cpp View File

@@ -67,14 +67,14 @@ void WaveShaper::process() {
return; return;
} }


rs->doUpsample(STD_CHANNEL, in);
rs->doUpsample(STD_CHANNEL, beforeComputation(in));


for (int i = 0; i < rs->getFactor(); i++) { for (int i = 0; i < rs->getFactor(); i++) {
double x = rs->getUpsampled(STD_CHANNEL)[i]; double x = rs->getUpsampled(STD_CHANNEL)[i];
rs->data[STD_CHANNEL][i] = compute(x); rs->data[STD_CHANNEL][i] = compute(x);
} }


out = rs->getDownsampled(STD_CHANNEL);
out = afterComputation(rs->getDownsampled(STD_CHANNEL));
} }






+ 18
- 0
plugins/community/repos/LindenbergResearch/src/dsp/WaveShaper.hpp View File

@@ -86,6 +86,24 @@ public:
* @return Output sample * @return Output sample
*/ */
virtual double compute(double x) { return x; } virtual double compute(double x) { return x; }


/**
* @brief Virtual function called before actual oversampling is performed
*
* @param x Input sample
* @return Ouput sample
*/
virtual double beforeComputation(double x) { return x; }


/**
* @brief Virtual function called after actual oversampling is performed
*
* @param x Input sample
* @return Output sample
*/
virtual double afterComputation(double x) { return x; }
}; };






+ 3
- 3
plugins/community/repos/LindenbergResearch/src/modules/Korg35.cpp View File

@@ -47,7 +47,7 @@ struct Korg35 : LRModule {
}; };


LRKnob *frqKnob, *peakKnob, *saturateKnob; LRKnob *frqKnob, *peakKnob, *saturateKnob;
Korg35Filter *filter = new Korg35Filter(engineGetSampleRate());
Korg35Filter *filter = new Korg35Filter(engineGetSampleRate(), Korg35Filter::LPF);


Korg35() : LRModule(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS) {} Korg35() : LRModule(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS) {}


@@ -55,7 +55,7 @@ struct Korg35 : LRModule {
void step() override { void step() override {
filter->fc = params[FREQ_PARAM].value; filter->fc = params[FREQ_PARAM].value;
filter->peak = params[PEAK_PARAM].value; filter->peak = params[PEAK_PARAM].value;
filter->sat = params[SAT_PARAM].value;
filter->sat = quadraticBipolar(params[SAT_PARAM].value);


filter->in = inputs[FILTER_INPUT].value; filter->in = inputs[FILTER_INPUT].value;
filter->invalidate(); filter->invalidate();
@@ -100,7 +100,7 @@ Korg35Widget::Korg35Widget(Korg35 *module) : LRModuleWidget(module) {
// ***** MAIN KNOBS ****** // ***** MAIN KNOBS ******
module->frqKnob = LRKnob::create<LRBigKnob>(Vec(32.5, 74.4), module, Korg35::FREQ_PARAM, 0.f, 1.f, 1.f); module->frqKnob = LRKnob::create<LRBigKnob>(Vec(32.5, 74.4), module, Korg35::FREQ_PARAM, 0.f, 1.f, 1.f);
module->peakKnob = LRKnob::create<LRBigKnob>(Vec(32.5, 144.4), module, Korg35::PEAK_PARAM, 0.001f, 2.0, 0.001f); module->peakKnob = LRKnob::create<LRBigKnob>(Vec(32.5, 144.4), module, Korg35::PEAK_PARAM, 0.001f, 2.0, 0.001f);
module->saturateKnob = LRKnob::create<LRMiddleKnob>(Vec(40, 244.4), module, Korg35::SAT_PARAM, 1.f, 1.5, 0.0f);
module->saturateKnob = LRKnob::create<LRMiddleKnob>(Vec(40, 244.4), module, Korg35::SAT_PARAM, 1.f, 2.5, 1.0f);


module->frqKnob->setIndicatorColors(nvgRGBAf(0.9f, 0.9f, 0.9f, 1.0f)); module->frqKnob->setIndicatorColors(nvgRGBAf(0.9f, 0.9f, 0.9f, 1.0f));
module->peakKnob->setIndicatorColors(nvgRGBAf(0.9f, 0.9f, 0.9f, 1.0f)); module->peakKnob->setIndicatorColors(nvgRGBAf(0.9f, 0.9f, 0.9f, 1.0f));


+ 1
- 1
plugins/community/repos/LindenbergResearch/src/widgets/LRPanel.cpp View File

@@ -31,7 +31,7 @@ void LRPanel::init() {
addChild(patinaWidgetClassic); addChild(patinaWidgetClassic);


/* setup gradient variants */ /* setup gradient variants */
auto gradientDark = new LRGradientWidget(box.size, nvgRGBAf(.6f, .6f, .6f, 0.3f), nvgRGBAf(0.0f, 0.0f, 0.0f, 0.2f), Vec(100, -120));
auto gradientDark = new LRGradientWidget(box.size, nvgRGBAf(.6f, .6f, .6f, 0.3f), nvgRGBAf(0.2f, 0.0f, 0.0f, 0.2f), Vec(50, 20));
gradientDark->visible = false; gradientDark->visible = false;
addChild(gradientDark); addChild(gradientDark);
gradients[LRGestalt::DARK] = gradientDark; gradients[LRGestalt::DARK] = gradientDark;


Loading…
Cancel
Save