chorus switching

This commit is contained in:
Gordon JC Pearce 2025-12-21 23:30:16 +00:00
parent 8c091c2a05
commit ecc1c82c99
8 changed files with 92 additions and 41 deletions

View File

@ -23,8 +23,7 @@
#include <cstdio> #include <cstdio>
Chorus::Chorus() { Chorus::Chorus() {
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
@ -39,7 +38,7 @@ Chorus::Chorus() {
// lfo values taken from a rough simulation // lfo values taken from a rough simulation
fastOmega = 6.283 * 0.7 / sampleRate; // approximate, can be adjusted fastOmega = 6.283 * 0.7 / sampleRate; // approximate, can be adjusted
// zero out the delay buffer // zero out the delay buffer
memset(ram, 0, sizeof(float) * DELAYSIZE); memset(ram, 0, sizeof(float) * DELAYSIZE);
memset(lpfOut1, 0, sizeof(float) * bufferSize); memset(lpfOut1, 0, sizeof(float) * bufferSize);
@ -47,7 +46,6 @@ Chorus::Chorus() {
} }
Chorus::~Chorus() { Chorus::~Chorus() {
printf("called chorus destructor\n");
delete lpfOut1; delete lpfOut1;
delete lpfOut2; delete lpfOut2;
delete ram; delete ram;
@ -60,6 +58,8 @@ Chorus::~Chorus() {
void Chorus::run(const float* input, float** outputs, uint32_t frames) { void Chorus::run(const float* input, float** outputs, uint32_t frames) {
// actual effects here // actual effects here
// FIXME add highpass filter
// now run the DSP // now run the DSP
float s0 = 0, s1 = 0; float s0 = 0, s1 = 0;
float lfoMod, dly1, frac; float lfoMod, dly1, frac;
@ -72,11 +72,11 @@ void Chorus::run(const float* input, float** outputs, uint32_t frames) {
ram[delayptr] = input[i]; ram[delayptr] = input[i];
#define BASE 0.05 #define BASE 0.005
#define AMT 0.003175 #define AMT 0.00175
// 0 degree delay line // FIXME make this triangle not sine, and move arithmetic out of mainloop
lfoMod = 0.603 * sin(fastPhase); lfoMod = sin(fastPhase);
dly1 = (BASE + (AMT * lfoMod)) * sampleRate; dly1 = (BASE + (AMT * lfoMod)) * sampleRate;
delay = (int)dly1; delay = (int)dly1;
frac = dly1 - delay; frac = dly1 - delay;
@ -95,8 +95,8 @@ void Chorus::run(const float* input, float** outputs, uint32_t frames) {
s0 = ram[tap & 0x3ff]; s0 = ram[tap & 0x3ff];
lpfOut2[i] = ((s1 - s0) * frac) + s0; lpfOut2[i] = ((s1 - s0) * frac) + s0;
// lpfOut1[i] = input[i] + 1.2 * out0; //(out0 + (out120 * 0.66) + (out240 * 0.33)); // lpfOut1[i] = input[i] + 1.2 * out0; //(out0 + (out120 * 0.66) + (out240 * 0.33));
// lpfOut2[i] = input[i] + 1.2 * out120; //(out0 + (out120 * 0.33) + (out240 * 0.66)); // lpfOut2[i] = input[i] + 1.2 * out120; //(out0 + (out120 * 0.33) + (out240 * 0.66));
delayptr++; delayptr++;
delayptr &= 0x3ff; delayptr &= 0x3ff;
@ -112,6 +112,24 @@ void Chorus::run(const float* input, float** outputs, uint32_t frames) {
outputs[0][i] = y + (gain * lpfOut1[i]); outputs[0][i] = y + (gain * lpfOut1[i]);
outputs[1][i] = y + (gain * lpfOut2[i]); outputs[1][i] = y + (gain * lpfOut2[i]);
} }
}
void Chorus::setHpf(uint8_t mode) {
}
void Chorus::setChorus(uint8_t mode) {
// switch chorus mode
switch (mode) {
case 0x60:
gain = 0;
break;
case 0x40:
gain = 1.2;
fastOmega = 6.283 * 0.5 / sampleRate;
break; // approximate, can be adjusted
case 0x00:
gain = 1.2;
fastOmega = 6.283 * 0.9 / sampleRate;
break; // approximate, can be adjusted
}
} }

View File

@ -34,6 +34,8 @@ class Chorus {
Chorus(); Chorus();
~Chorus(); ~Chorus();
void run(const float* input, float** outputs, uint32_t frames); void run(const float* input, float** outputs, uint32_t frames);
void setHpf(uint8_t mode);
void setChorus(uint8_t mode);
private: private:
double fastPhase = 0, fastOmega = 0; double fastPhase = 0, fastOmega = 0;

View File

@ -42,6 +42,8 @@ void Module::run(Voice* voice) {
res = patchRam.vcfReso / 127.0 * 5; res = patchRam.vcfReso / 127.0 * 5;
noise = patchRam.noise / 127.0; noise = patchRam.noise / 127.0;
chorus->setChorus(patchRam.switch1 & 0x60);
if (lfoPhase & 0x4000) if (lfoPhase & 0x4000)
lfo = 0x1fff - (lfoPhase & 0x3fff); lfo = 0x1fff - (lfoPhase & 0x3fff);
else else

View File

@ -22,6 +22,7 @@
#include <stdint.h> #include <stdint.h>
#include "DistrhoPluginInfo.h" #include "DistrhoPluginInfo.h"
#include "chorus.hpp"
extern double sampleRate; extern double sampleRate;
@ -61,9 +62,10 @@ class Module {
uint8_t env_s = 0x30; // 0x3f80 uint8_t env_s = 0x30; // 0x3f80
uint8_t env_r = 0x30; uint8_t env_r = 0x30;
uint8_t sub = 0x40; uint8_t sub = 0x40;
uint8_t switch1 = 0x19; uint8_t switch1 = 0x59;
uint8_t switch2 = 0x018; uint8_t switch2 = 0x18;
} patchRam; } patchRam;
Chorus* chorus;
private: private:
// controls // controls

View File

@ -289,17 +289,17 @@ void Peacock::initParameter(uint32_t index, Parameter& parameter) {
parameter.ranges.def = 40.0f; parameter.ranges.def = 40.0f;
parameter.midiCC = 26; parameter.midiCC = 26;
break; break;
/* /*
case pModWheel: case pModWheel:
parameter.hints = kParameterIsAutomatable | kParameterIsHidden; parameter.hints = kParameterIsAutomatable | kParameterIsHidden;
parameter.name = "Mod wheel"; parameter.name = "Mod wheel";
parameter.symbol = "ch_modwheel"; parameter.symbol = "ch_modwheel";
parameter.ranges.min = 0.0f; parameter.ranges.min = 0.0f;
parameter.ranges.max = 127.0f; parameter.ranges.max = 127.0f;
parameter.ranges.def = 0.0f; parameter.ranges.def = 0.0f;
parameter.midiCC = 1; parameter.midiCC = 1;
break; break;
*/ */
} }
// chorus, porta, bend range, key mode still to do // chorus, porta, bend range, key mode still to do
} }
@ -379,8 +379,21 @@ void Peacock::setParameterValue(uint32_t index, float value) {
m->patchRam.switch1 |= (value >= 0.5) << 4; m->patchRam.switch1 |= (value >= 0.5) << 4;
break; break;
// missing chorus switch case pChorus:
m->patchRam.switch1 &= 0x9f;
switch ((int)value) {
case 0:
m->patchRam.switch1 |= 0x60; // both off
break;
case 1:
m->patchRam.switch1 |= 0x40; // both off
break;
case 2:
default:
break;
}
break;
// switch 2 params // switch 2 params
case pPWMMode: // bit 0 of switch 2 case pPWMMode: // bit 0 of switch 2
m->patchRam.switch2 &= 0xfe; m->patchRam.switch2 &= 0xfe;
@ -400,12 +413,12 @@ void Peacock::setParameterValue(uint32_t index, float value) {
// doesn't look great in Carla because of odd behaviour with small integer knobs // doesn't look great in Carla because of odd behaviour with small integer knobs
if (value > 3) value = 3; if (value > 3) value = 3;
m->patchRam.switch2 &= 0xe7; m->patchRam.switch2 &= 0xe7;
m->patchRam.switch2 |= (3-(int)value )<< 3; m->patchRam.switch2 |= (3 - (int)value) << 3;
break; break;
/* /*
case pModWheel: case pModWheel:
//s.ff64 = (int)value << 1; //s.ff64 = (int)value << 1;
break;*/ break;*/
} }
} }
@ -453,7 +466,7 @@ float Peacock::getParameterValue(uint32_t index) const {
return m->patchRam.noise; return m->patchRam.noise;
break; break;
case pHPF: case pHPF:
return 3-((m->patchRam.switch2 & 0x18) >> 3); return 3 - ((m->patchRam.switch2 & 0x18) >> 3);
break; break;
case pCutoff: case pCutoff:
return m->patchRam.vcfFreq; return m->patchRam.vcfFreq;
@ -493,6 +506,20 @@ float Peacock::getParameterValue(uint32_t index) const {
case pVCALevel: case pVCALevel:
return m->patchRam.vca; return m->patchRam.vca;
break; break;
case pChorus:
switch (m->patchRam.switch1 & 0x60) {
case 0x60:
return 0;
case 0x40:
return 1;
case 0x00:
return 2;
default:
break;
}
} }
return 0; return 0;
} }

View File

@ -28,17 +28,16 @@ Peacock::Peacock() : Plugin(parameterCount, 0, 0) {
sampleRate = getSampleRate(); sampleRate = getSampleRate();
bufferSize = getBufferSize(); bufferSize = getBufferSize();
chorus = new Chorus();
m = new Module(); m = new Module();
ic1 = new Assigner; ic1 = new Assigner;
ic1->voice = voice; ic1->voice = voice;
chorus = new Chorus(); m->chorus = chorus;
} }
Peacock::~Peacock() { Peacock::~Peacock() {
printf("peacock destructor\n");
} }
void Peacock::initAudioPort(bool input, uint32_t index, AudioPort& port) { void Peacock::initAudioPort(bool input, uint32_t index, AudioPort& port) {

View File

@ -51,5 +51,4 @@ void SVF::runSVF(const float *input, float *output, uint32_t frames) {
z1 += c1 * x; z1 += c1 * x;
output[i] = d0 * x + z2; output[i] = d0 * x + z2;
} }
// printf("%f\n", x);
} }

View File

@ -182,7 +182,6 @@ DistrhoUIPeacock::DistrhoUIPeacock() : UI(Art::backgroundWidth, Art::backgroundH
} }
DistrhoUIPeacock::~DistrhoUIPeacock() { DistrhoUIPeacock::~DistrhoUIPeacock() {
printf("Called destructor for UI\n");
} }
/* /*
void DistrhoUIPeacock::programLoaded(uint32_t index) { void DistrhoUIPeacock::programLoaded(uint32_t index) {
@ -325,13 +324,16 @@ void DistrhoUIPeacock::imageButtonClicked(ImageButton* imgBtn, int) {
setParameterValue(pSaw, (sw1 & 0x10) ? 1.0f : 0.0f); setParameterValue(pSaw, (sw1 & 0x10) ? 1.0f : 0.0f);
break; break;
case btnCh0: case btnCh0:
sw1 = (sw1 & 0x1f) | 0x20; sw1 = (sw1 & 0x9f) | 0x20;
setParameterValue(pChorus, 0);
break; break;
case btnCh1: case btnCh1:
sw1 = (sw1 & 0x1f) | 0x40; sw1 = (sw1 & 0x9f) | 0x40;
setParameterValue(pChorus, 1);
break; break;
case btnCh2: case btnCh2:
sw1 = (sw1 & 0x1f); sw1 = (sw1 & 0x9f);
setParameterValue(pChorus, 2);
break; break;
default: default: