SVF class
This commit is contained in:
parent
43f6d53a56
commit
5e18d3437f
@ -17,8 +17,38 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "barrverb.hpp"
|
#include "barrverb.hpp"
|
||||||
|
|
||||||
#include "rom.h"
|
#include "rom.h"
|
||||||
|
|
||||||
|
SVF::SVF(float cutoff = 0, float q = 0, float samplerate = 0) {
|
||||||
|
z1 = z2 = 0;
|
||||||
|
setFreq(cutoff, q, samplerate);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SVF::setFreq(float cutoff, float q, float samplerate) {
|
||||||
|
z1 = z2 = 0;
|
||||||
|
|
||||||
|
printf("called with %f %f %f\n", cutoff, q, samplerate);
|
||||||
|
w = 2 * tan(3.14159 * (cutoff / samplerate));
|
||||||
|
a = w / q;
|
||||||
|
b = w * w;
|
||||||
|
|
||||||
|
// corrected SVF params, per Fons Adriaensen
|
||||||
|
c1 = (a + b) / (1 + a / 2 + b / 4);
|
||||||
|
c2 = b / (a + b);
|
||||||
|
|
||||||
|
d0 = c1 * c2 / 4;
|
||||||
|
|
||||||
|
printf("c1 %f c2 %f d0 %f\n", c1, c2, d0);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline float SVF::lpStep(float in) {
|
||||||
|
x = in - z1 - z2;
|
||||||
|
z2 += c2 * z1;
|
||||||
|
z1 += c1 * x;
|
||||||
|
return d0 * x + z2;
|
||||||
|
}
|
||||||
|
|
||||||
START_NAMESPACE_DISTRHO
|
START_NAMESPACE_DISTRHO
|
||||||
|
|
||||||
BarrVerb::BarrVerb() : Plugin(kParameterCount, 64, 0) { // one parameter, 64 programs, no states
|
BarrVerb::BarrVerb() : Plugin(kParameterCount, 64, 0) { // one parameter, 64 programs, no states
|
||||||
@ -28,52 +58,8 @@ BarrVerb::BarrVerb() : Plugin(kParameterCount, 64, 0) { // one parameter, 64 pr
|
|||||||
bzero(lowpass, sizeof(float) * getBufferSize());
|
bzero(lowpass, sizeof(float) * getBufferSize());
|
||||||
bzero(ram, sizeof(int16_t) * 16384);
|
bzero(ram, sizeof(int16_t) * 16384);
|
||||||
|
|
||||||
/*
|
f1.setFreq(5916, .6572, getSampleRate());
|
||||||
// calculate SVF params
|
f2.setFreq(9458, 2.536, getSampleRate());
|
||||||
// hardcoded values for now
|
|
||||||
float fc = 5019;
|
|
||||||
float F = fc / 48000; // assume 48kHz
|
|
||||||
float w = 2 * tan(3.14159 * F);
|
|
||||||
float a = w / 0.7845; // 1dB Chebyshev, 2-pole
|
|
||||||
float b = w * w;
|
|
||||||
|
|
||||||
// "corrected" SVF params, per Fons Adriaensen
|
|
||||||
c1_1 = (a + b) / (1 + a / 2 + b / 4);
|
|
||||||
c2_1 = b / (a + b);
|
|
||||||
d0_1 = c1_1 * c2_1 / 4;
|
|
||||||
|
|
||||||
fc = 9433;
|
|
||||||
F = fc / 48000; // assume 48kHz
|
|
||||||
w = 2 * tan(3.14159 * F);
|
|
||||||
a = w / 3.5594; // 1dB Chebyshev, 2-pole
|
|
||||||
b = w * w;
|
|
||||||
|
|
||||||
c1_2 = (a + b) / (1 + a / 2 + b / 4);
|
|
||||||
c2_2 = b / (a + b);
|
|
||||||
d0_2 = c1_2 * c2_2 / 4;*/
|
|
||||||
// calculate SVF params
|
|
||||||
// hardcoded values for now
|
|
||||||
|
|
||||||
float fc = 10000;
|
|
||||||
float F = fc / 48000; // assume 48kHz
|
|
||||||
float w = 2 * tan(3.14159 * F);
|
|
||||||
float a = w / 0.5412; // Butterworth 4-pole first stage
|
|
||||||
float b = w * w;
|
|
||||||
|
|
||||||
// "corrected" SVF params, per Fons Adriaensen
|
|
||||||
c1_1 = (a + b) / (1 + a / 2 + b / 4);
|
|
||||||
c2_1 = b / (a + b);
|
|
||||||
d0_1 = c1_1 * c2_1 / 4;
|
|
||||||
|
|
||||||
fc = 10000;
|
|
||||||
F = fc / 48000; // assume 48kHz
|
|
||||||
w = 2 * tan(3.14159 * F);
|
|
||||||
a = w / 1.3065; // Butterworth 4-pole second stage
|
|
||||||
b = w * w;
|
|
||||||
|
|
||||||
c1_2 = (a + b) / (1 + a / 2 + b / 4);
|
|
||||||
c2_2 = b / (a + b);
|
|
||||||
d0_2 = c1_2 * c2_2 / 4;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialisation functions
|
// Initialisation functions
|
||||||
@ -92,7 +78,7 @@ void BarrVerb::initParameter(uint32_t index, Parameter ¶meter) {
|
|||||||
void BarrVerb::setParameterValue(uint32_t index, float value) {
|
void BarrVerb::setParameterValue(uint32_t index, float value) {
|
||||||
if (index == paramProgram) {
|
if (index == paramProgram) {
|
||||||
program = value;
|
program = value;
|
||||||
prog_offset = (((int)value-1) & 0x3f) << 7;
|
prog_offset = (((int)value - 1) & 0x3f) << 7;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -107,14 +93,13 @@ void BarrVerb::initAudioPort(bool input, uint32_t index, AudioPort &port) {
|
|||||||
port.groupId = kPortGroupStereo;
|
port.groupId = kPortGroupStereo;
|
||||||
Plugin::initAudioPort(input, index, port);
|
Plugin::initAudioPort(input, index, port);
|
||||||
|
|
||||||
if (input && index == 0) port.name="Left In";
|
if (input && index == 0) port.name = "Left In";
|
||||||
if (input && index == 1) port.name="Right In";
|
if (input && index == 1) port.name = "Right In";
|
||||||
if (!input && index == 0) port.name="Left Out";
|
if (!input && index == 0) port.name = "Left Out";
|
||||||
if (!input && index == 1) port.name="Right Out";
|
if (!input && index == 1) port.name = "Right Out";
|
||||||
}
|
}
|
||||||
|
|
||||||
void BarrVerb::initProgramName(uint32_t index, String &programName) {
|
void BarrVerb::initProgramName(uint32_t index, String &programName) {
|
||||||
|
|
||||||
programName = prog_name[index & 0x3f].c_str();
|
programName = prog_name[index & 0x3f].c_str();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -138,26 +123,15 @@ void BarrVerb::deactivate() {
|
|||||||
void BarrVerb::run(const float **inputs, float **outputs, uint32_t frames) {
|
void BarrVerb::run(const float **inputs, float **outputs, uint32_t frames) {
|
||||||
// actual effects here
|
// actual effects here
|
||||||
|
|
||||||
float x;
|
|
||||||
uint16_t opcode;
|
uint16_t opcode;
|
||||||
|
|
||||||
for (uint32_t i = 0; i < frames; i++) {
|
for (uint32_t i = 0; i < frames; i++) {
|
||||||
// smash to mono
|
// smash to mono
|
||||||
lowpass[i] = (inputs[0][i] + inputs[1][i]) / 2;
|
lowpass[i] = f2.lpStep(f1.lpStep((inputs[0][i] + inputs[1][i]) / 2));
|
||||||
|
|
||||||
// 10kHz lowpass filter, 2x oversampling
|
|
||||||
x = lowpass[i] - in_z1 - in_z2;
|
|
||||||
in_z2 += c2_1 * in_z1;
|
|
||||||
in_z1 += c1_1 * x;
|
|
||||||
|
|
||||||
x = (d0_1 * x + in_z2) - in_z12 - in_z22;
|
|
||||||
in_z22 += c2_2 * in_z12;
|
|
||||||
in_z12 += c1_2 * x;
|
|
||||||
lowpass[i] = d0_2 * x + in_z22;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// now run the DSP
|
// now run the DSP
|
||||||
for (uint32_t i=0; i < frames; i+=2) {
|
for (uint32_t i = 0; i < frames; i += 2) {
|
||||||
// run the actual DSP engine for each sample
|
// run the actual DSP engine for each sample
|
||||||
for (uint8_t step = 0; step < 128; step++) {
|
for (uint8_t step = 0; step < 128; step++) {
|
||||||
opcode = rom[prog_offset + step];
|
opcode = rom[prog_offset + step];
|
||||||
@ -183,24 +157,23 @@ void BarrVerb::run(const float **inputs, float **outputs, uint32_t frames) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// clamp
|
// clamp
|
||||||
if (ai > 2047) ai=2047;
|
if (ai > 2047) ai = 2047;
|
||||||
if (ai < -2047) ai=-2047;
|
if (ai < -2047) ai = -2047;
|
||||||
|
|
||||||
|
|
||||||
if (step == 0x00) {
|
if (step == 0x00) {
|
||||||
// load RAM from ADC
|
// load RAM from ADC
|
||||||
ram[ptr] = (int)(lowpass[i] * 2048);
|
ram[ptr] = (int)(lowpass[i] * 2048);
|
||||||
} else if (step == 0x60) {
|
} else if (step == 0x60) {
|
||||||
// output right channel
|
// output right channel
|
||||||
//ai=0;
|
// ai=0;
|
||||||
outputs[1][i] = (float)ai / 2048;
|
outputs[1][i] = (float)ai / 2048;
|
||||||
outputs[1][i+1] = (float)ai / 2048;
|
outputs[1][i + 1] = (float)ai / 2048;
|
||||||
|
|
||||||
} else if (step == 0x70) {
|
} else if (step == 0x70) {
|
||||||
// output left channel
|
// output left channel
|
||||||
//ai=0;
|
// ai=0;
|
||||||
outputs[0][i] = (float)ai / 2048;
|
outputs[0][i] = (float)ai / 2048;
|
||||||
outputs[0][i+1] = (float)ai / 2048;
|
outputs[0][i + 1] = (float)ai / 2048;
|
||||||
} else {
|
} else {
|
||||||
// everything else
|
// everything else
|
||||||
// ADC and DAC operations don't affect the accumulator
|
// ADC and DAC operations don't affect the accumulator
|
||||||
|
@ -21,6 +21,18 @@
|
|||||||
|
|
||||||
#include "DistrhoPlugin.hpp"
|
#include "DistrhoPlugin.hpp"
|
||||||
|
|
||||||
|
class SVF {
|
||||||
|
public:
|
||||||
|
SVF(float cutoff, float q, float samplerate);
|
||||||
|
void setFreq(float cutoff, float q, float samplerate);
|
||||||
|
float lpStep(float in);
|
||||||
|
|
||||||
|
private:
|
||||||
|
float w, a, b;
|
||||||
|
float c1, c2, d0;
|
||||||
|
float z1, z2, x;
|
||||||
|
};
|
||||||
|
|
||||||
START_NAMESPACE_DISTRHO
|
START_NAMESPACE_DISTRHO
|
||||||
|
|
||||||
class BarrVerb : public Plugin {
|
class BarrVerb : public Plugin {
|
||||||
@ -49,19 +61,17 @@ class BarrVerb : public Plugin {
|
|||||||
void setParameterValue(uint32_t index, float value) override;
|
void setParameterValue(uint32_t index, float value) override;
|
||||||
float getParameterValue(uint32_t index) const override;
|
float getParameterValue(uint32_t index) const override;
|
||||||
|
|
||||||
|
|
||||||
void initProgramName(uint32_t index, String &programName) override;
|
void initProgramName(uint32_t index, String &programName) override;
|
||||||
void loadProgram(uint32_t index) override;
|
void loadProgram(uint32_t index) override;
|
||||||
|
|
||||||
|
|
||||||
// Processing
|
// Processing
|
||||||
void activate() override;
|
void activate() override;
|
||||||
void deactivate() override;
|
void deactivate() override;
|
||||||
void run(const float **inputs, float **outputs, uint32_t frames) override;
|
void run(const float **inputs, float **outputs, uint32_t frames) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
// float c1_1, c2_1, d0_1, c1_2, c2_2, d0_2, in_z1, in_z2, in_z12,in_z22, out_z1, out_z2;
|
||||||
float c1_1, c2_1, d0_1, c1_2, c2_2, d0_2, in_z1, in_z2, in_z12,in_z22, out_z1, out_z2;
|
SVF f1, f2;
|
||||||
|
|
||||||
int16_t ai, li, acc;
|
int16_t ai, li, acc;
|
||||||
uint16_t ptr;
|
uint16_t ptr;
|
||||||
|
Loading…
Reference in New Issue
Block a user