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 b = 1.f / TWOPI * n;
return (b - lround(b)) * TWOPI;
return (b - lroundf(b)) * TWOPI;
}


/**
* @brief Get PLL increment depending on 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 "DSPEffect.hpp"

#define LAMBERT_W_THRESHOLD 10e-10
using namespace rack;

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

namespace dsp {



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

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

protected:
#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
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

float sr;


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

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

#include "Korg35Filter.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) {
this->type = type;
}


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


/**
* @brief Recompute filter parameter
*/
void dsp::Korg35FilterStage::invalidate() {
// only process in dedicated mode
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);
}


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

zn1 = vn + lpf;

float hpf = in - lpf;

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

}


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

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

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


/**
* @brief Recompute filter parameter
*/
void dsp::Korg35Filter::invalidate() {
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);

// 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);
}


/**
* @brief Compute next sample for output depending on filter type
*/
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->process();
float y1 = hpf1->out;

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

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->process();

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

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

out = y;
}


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

// derive samplerate change
lpf->setSamplerate(sr);
lpf1->setSamplerate(sr);
lpf2->setSamplerate(sr);
hpf1->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 "DSPMath.hpp"

#define PI 3.14159265358979323846f

namespace dsp {

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

bool dedicated = false;

float fc;
FilterType type;

float fc;
float alpha, beta;
float zn1;

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


/**
* @brief Actual Korg35 Filter Class
*/
struct Korg35Filter : DSPEffect {
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 in, out;
@@ -68,16 +81,21 @@ struct Korg35Filter : DSPEffect {
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 invalidate() override;
void process() override;
void processLPF();
void processHPF();
void setSamplerate(float sr) override;
};



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

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

namespace dsp {
using namespace dsp;

// fork macro to keep the tree balanced
#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) \
Y6(d1, c12, d2, c23, Y2(d3, c34, d4), c45, d5, c56, d6, c67, d7)


namespace dsp {

class BranchPoint {
};



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

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

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

for (int i = 0; i < rs->getFactor(); i++) {
double x = rs->getUpsampled(STD_CHANNEL)[i];
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
*/
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;
Korg35Filter *filter = new Korg35Filter(engineGetSampleRate());
Korg35Filter *filter = new Korg35Filter(engineGetSampleRate(), Korg35Filter::LPF);

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

@@ -55,7 +55,7 @@ struct Korg35 : LRModule {
void step() override {
filter->fc = params[FREQ_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->invalidate();
@@ -100,7 +100,7 @@ Korg35Widget::Korg35Widget(Korg35 *module) : LRModuleWidget(module) {
// ***** MAIN KNOBS ******
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->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->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);

/* 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;
addChild(gradientDark);
gradients[LRGestalt::DARK] = gradientDark;


Loading…
Cancel
Save