From 13ff93a0a50132274f97fb2ecd3c69c83affbc4f Mon Sep 17 00:00:00 2001 From: Gordon JC Pearce Date: Wed, 24 Dec 2025 01:46:37 +0000 Subject: [PATCH] LFO delay, basically feature-complete --- plugin/assigner.cpp | 6 +++++- plugin/assigner.hpp | 1 + plugin/module.cpp | 26 +++++++++++++++++++++++--- plugin/module.hpp | 32 ++++++-------------------------- plugin/peacock.cpp | 1 + 5 files changed, 36 insertions(+), 30 deletions(-) diff --git a/plugin/assigner.cpp b/plugin/assigner.cpp index 0e4f315..3135207 100644 --- a/plugin/assigner.cpp +++ b/plugin/assigner.cpp @@ -110,6 +110,10 @@ void Assigner::noteOn(uint8_t note) { return; } + if ((noteTbl[voiceTbl[0]] & 0x80)) { + m->lfoRampOn(); + } + // loop around the voices for (i = NUM_VOICES - 1; i >= 0; i--) { v = voiceTbl[i]; @@ -137,6 +141,6 @@ void Assigner::noteOn(uint8_t note) { // printf("at end, l=%d e=%d\n", l,e); noteTbl[v] = note; - d_debug("send voice on %3d to voice %d", note, v); + d_debug("send voice on %3d to voice %d", note, i); voice[v].on(note); } diff --git a/plugin/assigner.hpp b/plugin/assigner.hpp index c313a36..9157133 100644 --- a/plugin/assigner.hpp +++ b/plugin/assigner.hpp @@ -27,6 +27,7 @@ class Assigner { Assigner(); void handleMidi(MidiEvent* ev); Voice* voice; + Module *m; private: void noteOn(uint8_t note); // incoming note on (or off, if velocity = 0) diff --git a/plugin/module.cpp b/plugin/module.cpp index 96faf98..99b5d51 100644 --- a/plugin/module.cpp +++ b/plugin/module.cpp @@ -40,9 +40,29 @@ Module::~Module() { delete subBuf; delete pwmBuf; } + +void Module::lfoRampOn() { + lfoDelayState = 1; + lfoDelayTimer = 0; + lfoDelay = 0; +} + void Module::run(Voice* voices, uint32_t blockSize) { // run updates for module board + if (lfoDelayState == 1) { + lfoDelayTimer += lfoDelayTable[patchRam.lfoDelay >> 4]; + if (lfoDelayTimer & 0xc000) lfoDelayState = 2; + } + if ((lfoDelayState == 2)) { + lfoDelay += attackTable[patchRam.lfoDelay]; + } + + if (lfoDelay & 0xc000) { + lfoDelayState = 0; + lfoDelay = 0x3fff; + } + // FIXME break these out to the patch setter a = attackTable[patchRam.env_a]; // attack time coeff looked up in table d = decayTable[patchRam.env_d]; // decay time coeff looked up in table @@ -70,9 +90,10 @@ void Module::run(Voice* voices, uint32_t blockSize) { pw = 0.5 - ((0x2000 + lfo) * patchRam.pwmLfo) / (32768.0f * 128); pw = (patchRam.switch2 & 0x01) ? 0.5 - (patchRam.pwmLfo / 256.0f) : pw; + lfo = (lfo * lfoDelay) >> 14; float master = powf(2, (patchRam.vca / 31.75 - 4.0f)); - float sub = patchRam.sub/ 127.0f; + float sub = patchRam.sub / 127.0f; for (uint32_t i = 0; i < blockSize; i++) { vcaRC = (master - vcaRC) * subTC + vcaRC; @@ -83,7 +104,6 @@ void Module::run(Voice* voices, uint32_t blockSize) { pwmBuf[i] = pwmRC; subBuf[i] = subRC; - if (bufPtr < bufferSize) bufPtr++; } @@ -128,7 +148,7 @@ void Module::run(Voice* voices, uint32_t blockSize) { v->vcfCut = (patchRam.vcfFreq << 7) + ((vcf * v->env) >> 14); v->vcfCut += (lfo * patchRam.vcfLfo) >> 9; - v->vcfCut += (int)((v->note-36) * (patchRam.vcfKey << 1) * 0.375); + v->vcfCut += (int)((v->note - 36) * (patchRam.vcfKey << 1) * 0.375); if (v->vcfCut > 0x3fff) v->vcfCut = 0x3fff; if (v->vcfCut < 0) v->vcfCut = 0; diff --git a/plugin/module.hpp b/plugin/module.hpp index 70cbc8a..a28902f 100644 --- a/plugin/module.hpp +++ b/plugin/module.hpp @@ -33,6 +33,8 @@ class Module { Module(); ~Module(); + void lfoRampOn(); + void run(Voice* voices, uint32_t blockLeft); float res = 0; @@ -47,8 +49,7 @@ class Module { float saw = 0, square = 0, sub = 0, noise = 0; struct { - - uint8_t lfoRate = 0x58; + uint8_t lfoRate = 0x58; uint8_t lfoDelay = 0x00; uint8_t vcoLfo = 0x00; uint8_t pwmLfo = 0x3b; @@ -66,29 +67,6 @@ class Module { uint8_t sub = 0x7f; uint8_t switch1 = 0x4a; uint8_t switch2 = 0x18; - - /* - // VCF tune - uint8_t lfoRate = 0x40; - uint8_t lfoDelay = 0x00; - uint8_t vcoLfo = 0x00; - uint8_t pwmLfo = 0x00; - uint8_t noise = 0x00; - uint8_t vcfFreq = 0x31; // 1c; // 0x3f80 - uint8_t vcfReso = 0x7f; - uint8_t vcfEnv = 0x00; // 4e; - uint8_t vcfLfo = 0x00; - uint8_t vcfKey = 0x7f; // 47; - uint8_t vca = 0x40; - uint8_t env_a = 0x00; - uint8_t env_d = 0x00; - uint8_t env_s = 0x7f; // 0x3f80 - uint8_t env_r = 0x00; - uint8_t sub = 0x00; - uint8_t switch1 = 0x62; - uint8_t switch2 = 0x10; - */ - } patchRam; Chorus* chorus; @@ -104,7 +82,9 @@ class Module { float pwmTC = 0, subTC = 0, mVcaTC = 0; float pwmRC = 0, subRC = 0, vcaRC = 0; - // controls + uint16_t lfoDelay = 0; + uint8_t lfoDelayState = 0; + uint16_t lfoDelayTimer = 0; }; class Voice { diff --git a/plugin/peacock.cpp b/plugin/peacock.cpp index 3b22de6..59ee016 100644 --- a/plugin/peacock.cpp +++ b/plugin/peacock.cpp @@ -32,6 +32,7 @@ Peacock::Peacock() : Plugin(parameterCount, 0, 0) { m = new Module(); ic1 = new Assigner; ic1->voice = voice; + ic1->m = m; m->chorus = chorus; }