broke digital code out to separate file

This commit is contained in:
Gordon JC Pearce 2024-09-08 22:45:12 +01:00
parent 3f63138b85
commit 1f6188f751
3 changed files with 116 additions and 107 deletions

View File

@ -11,6 +11,7 @@ NAME = chassis
FILES_DSP = \
parameters.cpp \
digital.cpp \
chassis.cpp \
voice.cpp

115
plugin/digital.cpp Normal file
View File

@ -0,0 +1,115 @@
#include "voice.hpp"
#include <cmath>
bool Voice::isFree() {
return ff10 == false;
}
void Voice::on(uint32_t key, bool reset = 0) {
// printf("======================================================================================\n");
// what's with the crazy private variables and all the gotos with crazy labels?
// this code emulates the 78C11 code directly (probably inefficiently)
// to allow for documenting what the variables actually do
// they're really bitfields holding a bit for each voice
// this current implementation doesn't reset the voice
(void)reset;
ff10 = true; // note held from keyboard
ff07 = true; // attack phase
if (note == key) goto h0144;
note = key;
if (ff11) goto h013e;
h0132:
if (ff33) goto h0149; // sustained
ff33 = false;
goto h0149;
h013e:
ff00 = true; // in a real one, voice counter needs programmed
goto h0149;
h0144:
if (!ff11) goto h0132; // unsure, copied from ff10 at start of mainloop
h0149:
// printf("after 0144h, %d %x %x %x %x\n", note, ff07, ff10, ff11, ff33);
// this is in the wrong place really but is the equivalent of programming the counter
// and VCO ramp DAC
omega = (261.63 * powf(2, (note - 60) / 12.0f)) / 48000.0f;
}
void Voice::off() {
bool sustain = false;
ff10 = false;
if (!sustain) { // dummy sustain
ff33 = false;
}
// printf("after note off, %d %x %x %x %x\n", note, ff07, ff10, ff11, ff33);
}
void Voice::gate(Synth &s) {
uint16_t bc, ea = env;
ff11 = ff10;
// 0509
if (!ff11) goto h0538;
// 050e
if (!ff33) goto h0563;
// 0513
if (!ff07) goto h051e;
h0517:
ff07 = false;
h051e:
bc = s.patchRam.env_s << 7; // half scale
if (ea < bc) ea = bc;
ea -= bc;
bc = ea;
ea = (ea * decay_table[s.patchRam.env_d]) >> 16;
ea += s.patchRam.env_s << 7;
// printf("returning from decay phase\n");
goto h0590;
h0538:
// printf("got to 0x0538\n");
if (!ff07) goto h054a; // note on? if not skip ahead
// 053c
if (ff08) goto h0517;
ff07 = false;
h054a:
// printf("release phase\n");
ff33 = false;
ff08 = false;
bc = ea;
ea = (ea * decay_table[s.patchRam.env_r]) >> 16;
// printf("returning from release phase\n");
goto h0590;
h0563:
// printf("attack phase\n");
ff08 = false;
ea += attack_table[s.patchRam.env_a];
if (ea & 0xc000) {
ea = 0x3fff;
ff33 = true;
ff08 = true;
}
h0590:
env = ea;
// printf("%04x %d %d %d %d %d \n", ea, ff07, ff08, ff10, ff11, ff33);
}

View File

@ -22,114 +22,7 @@
#include <cstdio>
bool Voice::isFree() {
return ff10 == false;
}
void Voice::on(uint32_t key, bool reset = 0) {
// printf("======================================================================================\n");
// what's with the crazy private variables and all the gotos with crazy labels?
// this code emulates the 78C11 code directly (probably inefficiently)
// to allow for documenting what the variables actually do
// they're really bitfields holding a bit for each voice
// this current implementation doesn't reset the voice
(void)reset;
ff10 = true; // note held from keyboard
ff07 = true; // attack phase
if (note == key) goto h0144;
note = key;
if (ff11) goto h013e;
h0132:
if (ff33) goto h0149; // sustained
ff33 = false;
goto h0149;
h013e:
ff00 = true; // in a real one, voice counter needs programmed
goto h0149;
h0144:
if (!ff11) goto h0132; // unsure, copied from ff10 at start of mainloop
h0149:
// printf("after 0144h, %d %x %x %x %x\n", note, ff07, ff10, ff11, ff33);
// this is in the wrong place really but is the equivalent of programming the counter
// and VCO ramp DAC
omega = (261.63 * powf(2, (note - 60) / 12.0f)) / 48000.0f;
}
void Voice::off() {
bool sustain = false;
ff10 = false;
if (!sustain) { // dummy sustain
ff33 = false;
}
// printf("after note off, %d %x %x %x %x\n", note, ff07, ff10, ff11, ff33);
}
void Voice::gate(Synth &s) {
uint16_t bc, ea = env;
ff11 = ff10;
// 0509
if (!ff11) goto h0538;
// 050e
if (!ff33) goto h0563;
// 0513
if (!ff07) goto h051e;
h0517:
ff07 = false;
h051e:
bc = s.patchRam.env_s << 7; // half scale
if (ea < bc) ea = bc;
ea -= bc;
bc = ea;
ea = (ea * decay_table[s.patchRam.env_d]) >> 16;
ea += s.patchRam.env_s << 7;
// printf("returning from decay phase\n");
goto h0590;
h0538:
// printf("got to 0x0538\n");
if (!ff07) goto h054a; // note on? if not skip ahead
// 053c
if (ff08) goto h0517;
ff07 = false;
h054a:
// printf("release phase\n");
ff33 = false;
ff08 = false;
bc = ea;
ea = (ea * decay_table[s.patchRam.env_r]) >> 16;
// printf("returning from release phase\n");
goto h0590;
h0563:
// printf("attack phase\n");
ff08 = false;
ea += attack_table[s.patchRam.env_a];
if (ea & 0xc000) {
ea = 0x3fff;
ff33 = true;
ff08 = true;
}
h0590:
env = ea;
// printf("%04x %d %d %d %d %d \n", ea, ff07, ff08, ff10, ff11, ff33);
}
static inline float poly3blep0(float t) {
float t2 = t * t;