From 2ea0409fe7a9d2ded38dda6ae8a5f58b9dd78452 Mon Sep 17 00:00:00 2001 From: Gordon JC Pearce Date: Tue, 19 Aug 2025 23:33:47 +0100 Subject: [PATCH] stereo chorus --- plugin/chorus.cpp | 40 +++++++++++++++++----------------------- plugin/chorus.hpp | 8 ++++---- plugin/generator.cpp | 2 -- plugin/sonnenlicht.cpp | 6 +++--- 4 files changed, 24 insertions(+), 32 deletions(-) diff --git a/plugin/chorus.cpp b/plugin/chorus.cpp index 79685ca..a07edef 100644 --- a/plugin/chorus.cpp +++ b/plugin/chorus.cpp @@ -23,12 +23,11 @@ #include -Chorus::Chorus(uint32_t xbufferSize, double xsampleRate) { // no parameters, programs, or states +extern double sampleRate; +extern uint32_t bufferSize; - bufferSize = xbufferSize; - sampleRate = xsampleRate; +Chorus::Chorus() { // no parameters, programs, or states - lpfIn = new float[bufferSize]; lpfOut1 = new float[bufferSize]; lpfOut2 = new float[bufferSize]; ram = new float[DELAYSIZE]; // probably needs to be calculated based on sample rate @@ -36,8 +35,10 @@ Chorus::Chorus(uint32_t xbufferSize, double xsampleRate) { // no parameters, pr fastPhase = 0; slowPhase = 0; - postFilter1 = new SVF(8000, 1.3); - postFilter2 = new SVF(8000, 0.54); + postFilter1l = new SVF(POSTCUTOFF, .546); + postFilter2l = new SVF(POSTCUTOFF, 1.324); + postFilter1r = new SVF(POSTCUTOFF, .546); + postFilter2r = new SVF(POSTCUTOFF, 1.324); // lfo values taken from a rough simulation fastOmega = 6.283 * 5.7 / sampleRate; // approximate, can be adjusted @@ -45,18 +46,18 @@ Chorus::Chorus(uint32_t xbufferSize, double xsampleRate) { // no parameters, pr // zero out the delay buffer memset(ram, 0, sizeof(float) * DELAYSIZE); - memset(lpfIn, 0, sizeof(float) * bufferSize); memset(lpfOut1, 0, sizeof(float) * bufferSize); memset(lpfOut2, 0, sizeof(float) * bufferSize); } Chorus::~Chorus() { - delete lpfIn; delete lpfOut1; delete lpfOut2; delete ram; - delete postFilter1; - delete postFilter2; + delete postFilter1l; + delete postFilter2l; + delete postFilter1r; + delete postFilter2r; } void Chorus::run(const float *input, float **outputs, uint32_t frames) { @@ -76,15 +77,6 @@ void Chorus::run(const float *input, float **outputs, uint32_t frames) { ram[delayptr] = input[i]; - // lowpass filter - - // now we need to calculate the delay - // I don't know how long the Solina's delay lines are so I'm guessing 2-4ms for now - // normalised mod depths, from a quick simulation of the LFO block: - // 0deg 0.203 slow 0.635 fast - // 120deg 0.248 slow 0.745 fast - // 240deg 0.252 slow 0.609 fast - #define BASE 0.05 #define AMT 0.00175 @@ -121,13 +113,15 @@ void Chorus::run(const float *input, float **outputs, uint32_t frames) { s0 = ram[tap & 0x3ff]; out240 = ((s1 - s0) * frac) + s0; - lpfOut1[i] = (out0 + out120 + out240) / 3; + lpfOut1[i] = (out0 + (out120 * 0.66) + (out240 * 0.33)); + lpfOut2[i] = (out0 + (out120 * 0.33) + (out240 * 0.66)); delayptr++; delayptr &= 0x3ff; } - postFilter1->runSVF(lpfOut1, lpfOut2, frames); - postFilter2->runSVF(lpfOut2, outputs[0], frames); - memcpy (outputs[1], outputs[0], frames * sizeof(float)); // only mono output for now + postFilter1l->runSVF(lpfOut1, lpfOut1, frames); + postFilter2l->runSVF(lpfOut1, outputs[0], frames); + postFilter1r->runSVF(lpfOut2, lpfOut2, frames); + postFilter2r->runSVF(lpfOut2, outputs[1], frames); } diff --git a/plugin/chorus.hpp b/plugin/chorus.hpp index ecb7b31..657de58 100644 --- a/plugin/chorus.hpp +++ b/plugin/chorus.hpp @@ -24,15 +24,15 @@ // total size of delay line buffer #define DELAYSIZE 1028 +#define POSTCUTOFF 10000 + class Chorus { public: - Chorus(uint32_t xbufferSize, double xsampleRate); + Chorus(); ~Chorus(); void run(const float *input, float **outputs, uint32_t frames); - double sampleRate; private: - uint32_t bufferSize; double fastPhase, fastOmega; double slowPhase, slowOmega; double fastLfo, slowLfo; @@ -43,6 +43,6 @@ class Chorus { float *lpfIn; float *lpfOut1, *lpfOut2; - SVF *preFilter, *postFilter1, *postFilter2; + SVF *postFilter1l, *postFilter2l, *postFilter1r, *postFilter2r; }; #endif diff --git a/plugin/generator.cpp b/plugin/generator.cpp index 5924b8d..03f206f 100644 --- a/plugin/generator.cpp +++ b/plugin/generator.cpp @@ -31,9 +31,7 @@ extern uint32_t bufferSize; // unit-local global static float envTc[2]; -// Generator::Generator(uint32_t bufferSize, double xSampleRate) { Generator::Generator() { - // sampleRate = xSampleRate; output = new float[bufferSize]; // create the phase increments for each semitone for (uint8_t i = 0; i < 12; i++) { diff --git a/plugin/sonnenlicht.cpp b/plugin/sonnenlicht.cpp index 483f881..3cabb5e 100644 --- a/plugin/sonnenlicht.cpp +++ b/plugin/sonnenlicht.cpp @@ -20,6 +20,7 @@ double sampleRate; uint32_t bufferSize; + START_NAMESPACE_DISTRHO Sonnenlicht::Sonnenlicht() : Plugin(kParameterCount, 0, 0) { @@ -27,11 +28,10 @@ Sonnenlicht::Sonnenlicht() : Plugin(kParameterCount, 0, 0) { sampleRate = getSampleRate(); bufferSize = getBufferSize(); + genny = new Generator(); - assigner = new Assigner(genny->voices); - - chorus = new Chorus(getBufferSize(), sampleRate); + chorus = new Chorus(); } Sonnenlicht::~Sonnenlicht() {