#include "voice.hpp" #include 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); }