stereo chorus
This commit is contained in:
parent
7b138536ef
commit
2ea0409fe7
|
@ -23,12 +23,11 @@
|
||||||
|
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
|
|
||||||
Chorus::Chorus(uint32_t xbufferSize, double xsampleRate) { // no parameters, programs, or states
|
extern double sampleRate;
|
||||||
|
extern uint32_t bufferSize;
|
||||||
|
|
||||||
bufferSize = xbufferSize;
|
Chorus::Chorus() { // no parameters, programs, or states
|
||||||
sampleRate = xsampleRate;
|
|
||||||
|
|
||||||
lpfIn = new float[bufferSize];
|
|
||||||
lpfOut1 = new float[bufferSize];
|
lpfOut1 = new float[bufferSize];
|
||||||
lpfOut2 = new float[bufferSize];
|
lpfOut2 = new float[bufferSize];
|
||||||
ram = new float[DELAYSIZE]; // probably needs to be calculated based on sample rate
|
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;
|
fastPhase = 0;
|
||||||
slowPhase = 0;
|
slowPhase = 0;
|
||||||
|
|
||||||
postFilter1 = new SVF(8000, 1.3);
|
postFilter1l = new SVF(POSTCUTOFF, .546);
|
||||||
postFilter2 = new SVF(8000, 0.54);
|
postFilter2l = new SVF(POSTCUTOFF, 1.324);
|
||||||
|
postFilter1r = new SVF(POSTCUTOFF, .546);
|
||||||
|
postFilter2r = new SVF(POSTCUTOFF, 1.324);
|
||||||
|
|
||||||
// lfo values taken from a rough simulation
|
// lfo values taken from a rough simulation
|
||||||
fastOmega = 6.283 * 5.7 / sampleRate; // approximate, can be adjusted
|
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
|
// zero out the delay buffer
|
||||||
memset(ram, 0, sizeof(float) * DELAYSIZE);
|
memset(ram, 0, sizeof(float) * DELAYSIZE);
|
||||||
memset(lpfIn, 0, sizeof(float) * bufferSize);
|
|
||||||
memset(lpfOut1, 0, sizeof(float) * bufferSize);
|
memset(lpfOut1, 0, sizeof(float) * bufferSize);
|
||||||
memset(lpfOut2, 0, sizeof(float) * bufferSize);
|
memset(lpfOut2, 0, sizeof(float) * bufferSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
Chorus::~Chorus() {
|
Chorus::~Chorus() {
|
||||||
delete lpfIn;
|
|
||||||
delete lpfOut1;
|
delete lpfOut1;
|
||||||
delete lpfOut2;
|
delete lpfOut2;
|
||||||
delete ram;
|
delete ram;
|
||||||
delete postFilter1;
|
delete postFilter1l;
|
||||||
delete postFilter2;
|
delete postFilter2l;
|
||||||
|
delete postFilter1r;
|
||||||
|
delete postFilter2r;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Chorus::run(const float *input, float **outputs, uint32_t frames) {
|
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];
|
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 BASE 0.05
|
||||||
#define AMT 0.00175
|
#define AMT 0.00175
|
||||||
|
|
||||||
|
@ -121,13 +113,15 @@ void Chorus::run(const float *input, float **outputs, uint32_t frames) {
|
||||||
s0 = ram[tap & 0x3ff];
|
s0 = ram[tap & 0x3ff];
|
||||||
out240 = ((s1 - s0) * frac) + s0;
|
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++;
|
||||||
delayptr &= 0x3ff;
|
delayptr &= 0x3ff;
|
||||||
}
|
}
|
||||||
|
|
||||||
postFilter1->runSVF(lpfOut1, lpfOut2, frames);
|
postFilter1l->runSVF(lpfOut1, lpfOut1, frames);
|
||||||
postFilter2->runSVF(lpfOut2, outputs[0], frames);
|
postFilter2l->runSVF(lpfOut1, outputs[0], frames);
|
||||||
memcpy (outputs[1], outputs[0], frames * sizeof(float)); // only mono output for now
|
postFilter1r->runSVF(lpfOut2, lpfOut2, frames);
|
||||||
|
postFilter2r->runSVF(lpfOut2, outputs[1], frames);
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,15 +24,15 @@
|
||||||
// total size of delay line buffer
|
// total size of delay line buffer
|
||||||
#define DELAYSIZE 1028
|
#define DELAYSIZE 1028
|
||||||
|
|
||||||
|
#define POSTCUTOFF 10000
|
||||||
|
|
||||||
class Chorus {
|
class Chorus {
|
||||||
public:
|
public:
|
||||||
Chorus(uint32_t xbufferSize, double xsampleRate);
|
Chorus();
|
||||||
~Chorus();
|
~Chorus();
|
||||||
void run(const float *input, float **outputs, uint32_t frames);
|
void run(const float *input, float **outputs, uint32_t frames);
|
||||||
double sampleRate;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
uint32_t bufferSize;
|
|
||||||
double fastPhase, fastOmega;
|
double fastPhase, fastOmega;
|
||||||
double slowPhase, slowOmega;
|
double slowPhase, slowOmega;
|
||||||
double fastLfo, slowLfo;
|
double fastLfo, slowLfo;
|
||||||
|
@ -43,6 +43,6 @@ class Chorus {
|
||||||
float *lpfIn;
|
float *lpfIn;
|
||||||
float *lpfOut1, *lpfOut2;
|
float *lpfOut1, *lpfOut2;
|
||||||
|
|
||||||
SVF *preFilter, *postFilter1, *postFilter2;
|
SVF *postFilter1l, *postFilter2l, *postFilter1r, *postFilter2r;
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -31,9 +31,7 @@ extern uint32_t bufferSize;
|
||||||
// unit-local global
|
// unit-local global
|
||||||
static float envTc[2];
|
static float envTc[2];
|
||||||
|
|
||||||
// Generator::Generator(uint32_t bufferSize, double xSampleRate) {
|
|
||||||
Generator::Generator() {
|
Generator::Generator() {
|
||||||
// sampleRate = xSampleRate;
|
|
||||||
output = new float[bufferSize];
|
output = new float[bufferSize];
|
||||||
// create the phase increments for each semitone
|
// create the phase increments for each semitone
|
||||||
for (uint8_t i = 0; i < 12; i++) {
|
for (uint8_t i = 0; i < 12; i++) {
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
|
|
||||||
double sampleRate;
|
double sampleRate;
|
||||||
uint32_t bufferSize;
|
uint32_t bufferSize;
|
||||||
|
|
||||||
START_NAMESPACE_DISTRHO
|
START_NAMESPACE_DISTRHO
|
||||||
|
|
||||||
Sonnenlicht::Sonnenlicht() : Plugin(kParameterCount, 0, 0) {
|
Sonnenlicht::Sonnenlicht() : Plugin(kParameterCount, 0, 0) {
|
||||||
|
@ -27,11 +28,10 @@ Sonnenlicht::Sonnenlicht() : Plugin(kParameterCount, 0, 0) {
|
||||||
|
|
||||||
sampleRate = getSampleRate();
|
sampleRate = getSampleRate();
|
||||||
bufferSize = getBufferSize();
|
bufferSize = getBufferSize();
|
||||||
|
|
||||||
genny = new Generator();
|
genny = new Generator();
|
||||||
|
|
||||||
assigner = new Assigner(genny->voices);
|
assigner = new Assigner(genny->voices);
|
||||||
|
chorus = new Chorus();
|
||||||
chorus = new Chorus(getBufferSize(), sampleRate);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Sonnenlicht::~Sonnenlicht() {
|
Sonnenlicht::~Sonnenlicht() {
|
||||||
|
|
Loading…
Reference in New Issue