diff --git a/plugin/module.cpp b/plugin/module.cpp index a570676..6e82cda 100644 --- a/plugin/module.cpp +++ b/plugin/module.cpp @@ -26,6 +26,11 @@ Module::Module() { void Module::run(Voice* voice) { // run updates for module board +// 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 + r = decayTable[patchRam.env_r]; // release time coeff looked up in table + s = patchRam.env_s << 7; // scale 0x00-0x7f to 0x0000-0x3f80 // work out the "master" cutoff vcfCutoff = patchRam.vcfFreq / 127.0f; vcfCutoff += lfo * (patchRam.vcfLfo/127.0f); @@ -34,18 +39,17 @@ void Module::run(Voice* voice) { for (uint32_t i = 0; i < NUM_VOICES; i++) { switch (voice[i].envPhase) { case 0: // release phase FIXME use an enum I guess - voice[i].env *= decayTable[patchRam.env_r] / 65536.0f; // "RC" decay to zero + voice[i].env = (voice[i].env * d) >> 16; // "RC" decay to zero break; case 1: // attack phase - voice[i].env += attackTable[patchRam.env_a] / 65536.0f; // linear attack to 1 + voice[i].env += a; // linear attack to 0x3fff break; case 2: - float t = patchRam.env_s / 127.0f; - voice[i].env = (voice[i].env - t) * (decayTable[patchRam.env_d] / 65536.0f) + t; + voice[i].env = (((voice[i].env - s) * d) >>16 ) + s; break; } - if (voice[i].env > 1.0f) { - voice[i].env = 1.0f; + if (voice[i].env > 0x3fff) { + voice[i].env = 0x3fff; voice[i].envPhase = 2; // flip to decay } // per voice we need to calculate the key follow amount and envelope amount diff --git a/plugin/module.hpp b/plugin/module.hpp index 22d4492..3a36908 100644 --- a/plugin/module.hpp +++ b/plugin/module.hpp @@ -37,6 +37,9 @@ class Module { // precomputed values for all voices float pw, saw, square, sub; + // "internal state" values for patch parameters + uint16_t a, d, s, r; + struct { uint8_t lfoRate = 0x30; // lookup value defaults to 0x0200 uint8_t lfoDelay = 0x00; @@ -66,7 +69,7 @@ class Voice { void off(); void run(Module* m, float* buffer, uint32_t samples); uint8_t envPhase = 0; - float env = 0; // output amplitude + int16_t env = 0; // output amplitude private: float omega = 0, theta = 0; // phase increment and angle @@ -78,4 +81,4 @@ class Voice { float b1 = 0, b2 = 0, b3 = 0, b4 = 0; }; -#endif \ No newline at end of file +#endif diff --git a/plugin/voice.cpp b/plugin/voice.cpp index abf1d62..025707c 100644 --- a/plugin/voice.cpp +++ b/plugin/voice.cpp @@ -51,13 +51,15 @@ void Voice::run(Module* m, float* buffer, uint32_t samples) { // carry out per-voice calculations for each block of samples float out, t, fb, res; - float cut = 0.00513 + 0.075*env; + float cut = 0.00513 + 0.0000075*env; // printf("%f ", delay); m->saw = 1; m->square = 1; m->sub = .5; m->pw = 0.5; + float amp = env / 4096.0f; + for (uint32_t i = 0; i < samples; i++) { out = delay; delay = 0; @@ -106,7 +108,7 @@ void Voice::run(Module* m, float* buffer, uint32_t samples) { b4 = ((b3 - b4) * cut) + b4; } - buffer[i] += 0.125 * env * b4; + buffer[i] += 0.125 * amp * b4; lastpw = m->pw; } // buffer[0] += 1;