unison I think

This commit is contained in:
Gordon JC Pearce 2024-09-25 22:04:44 +01:00
parent 0805abdf8e
commit c7fad0ee06
8 changed files with 86 additions and 17 deletions

View File

@ -56,9 +56,15 @@ void Chassis::activate() {
s.pitchCV[i] = (440.0f * powf(2, (i - 49) / 12.0f)) / sampleRate;
}
//ic1.ram[0xc6] = 0x42;
//ic1.ram[0xb6] = 0;
//ic1.resetVoices();
// resetvoices
for (uint8_t i=0; i<8; i++) {
s.noteTbl[i] = 0x80;
s.voiceTbl[i] = i;
s.voice[i].phase = (0.7*((rand()%65536)/65536.0f));//(60*s.voice[i].omega*i);
printf("%f %d\n", s.voice[i].phase, i);
}
}
void Chassis::deactivate() {
@ -67,13 +73,33 @@ void Chassis::deactivate() {
}
void Chassis::noteOn(uint8_t note) {
uint32_t i;
// needed for LFO for now
s.keyon = true;
// Unison Voice On
for (uint8_t i=0; i<8; i++ ) {
//s.noteTbl[i] = note;
s.voice[i].on(note, false);
s.voice[i].voicenum=i;
// printf("%f %i\n", s.voice[i].phase, i);
}
//s.voice[vPtr].on(note, true);
}
void Chassis::noteOff(uint8_t note) {
// Unison Voice On
for (uint8_t i=0; i<8; i++ ) {
//s.noteTbl[i] = note;
s.voice[i].off();
}
// s.voice[i].off();
s.keyon=false;
}
void Chassis::doMidi(const MidiEvent *ev, uint32_t count, uint32_t timeLimit) {

View File

@ -64,8 +64,10 @@ class Chassis : public Plugin {
paramChorusMode,
paramPolyMode,
paramUnisonDetune,
paramModWheel,
parameterCount
};

View File

@ -236,6 +236,8 @@
// 019c: 63 bf STAW $FFBF // save flag
// scan keys again
// this populates the key scan table
// and also decides if we need to emit some MIDI
// 019e: 24 ff 1f LXI DE,$1FFF // keypad MUX
// 01a1: 34 50 ff LXI HL,$FF50 // key bitfield
// 01a4: 6a e8 MVI B,$E8 // first column

View File

@ -38,7 +38,11 @@ class Assigner {
uint16_t a = 0, b = 0, c = 0, eal = 0, eah = 0;
uint32_t bc, de, hl, ea = 0;
/*
23:31 < Alipha> gordonjcp: struct reg16 { uint16_t value; uint8_t hi() const { return value >> 8; } uint8_t lo() const { return value;
} };
23:31 < gordonjcp> Alipha
*/
};

View File

@ -300,6 +300,7 @@ void Chassis::initParameter(uint32_t index, Parameter& parameter) {
parameter.midiCC = 93;
break;
/*
case paramPolyMode:
parameter.hints = kParameterIsAutomatable | kParameterIsInteger;
parameter.name = "Poly";
@ -322,8 +323,16 @@ void Chassis::initParameter(uint32_t index, Parameter& parameter) {
}
break;
*/
case paramUnisonDetune:
parameter.hints = kParameterIsAutomatable;
parameter.name = "Detune";
parameter.symbol = "ch_detune";
parameter.ranges.min = 0.0f;
parameter.ranges.max = 1.0f;
parameter.ranges.def = 0.2f;
parameter.midiCC=84;
break;
case paramModWheel:
parameter.hints = kParameterIsAutomatable | kParameterIsHidden;
@ -332,7 +341,7 @@ void Chassis::initParameter(uint32_t index, Parameter& parameter) {
parameter.ranges.min = 0.0f;
parameter.ranges.max = 127.0f;
parameter.ranges.def = 0.0f;
parameter.midiCC = 1;
//parameter.midiCC = 1;
break;
}
// chorus, porta, bend range, key mode still to do
@ -441,8 +450,12 @@ void Chassis::setParameterValue(uint32_t index, float value) {
case paramModWheel:
s.ff64 = (int)value << 1;
break;
case paramPolyMode:
s.polymode = (int)value;
//case paramPolyMode:
// s.polymode = (int)value;
// break;
case paramUnisonDetune:
s.unisonDetune = value;
break;
}
}
@ -530,6 +543,10 @@ float Chassis::getParameterValue(uint32_t index) const {
case paramVCALevel:
return s.patchRam.vca;
break;
case paramUnisonDetune:
return s.unisonDetune;
break;
}
return 0;

View File

@ -42,16 +42,17 @@ void Voice::run(Synth &s, float *buffer, uint32_t samples) {
float fb, res = s.patchRam.vcfReso / 28.0f; // guess
float cut = 248.0f * (powf(2, (vcfenv - 0x1880) / 1143.0f));
cut *= (1-detune[voicenum]);
// now radians
cut = 0.25 * 6.2832 * cut / 48000.0f;
// now correct
cut = cut / (1 + cut);
float sqr = (s.patchRam.switch1 & 0x08) ? 0.65 : 0; //? 0.175 : 0;
float saw = (s.patchRam.switch1 & 0x10) ? 0.83 : 0; //? 0.220 : 0;
float sub = (s.patchRam.sub / 127.0f); // * 0.275;
// noise is 0.8
float sqr = (s.patchRam.switch1 & 0x08) ? 0.65 : 0;
float saw = (s.patchRam.switch1 & 0x10) ? 0.83 : 0;
float sub = (s.patchRam.sub / 127.0f);
float noise = (s.patchRam.noise / 127.0f) * 0.8;
float gain = 0.5*powf(2, (4*s.patchRam.vca / 127.0f) - 1.0f);
@ -101,6 +102,11 @@ void Voice::run(Synth &s, float *buffer, uint32_t samples) {
// out = (2 * y) - 1;
out = y;
lcg = (lcg*519)+3;
out += noise * ((lcg / 2147483647.0f)-1);
// widthDelay = pw;
out *= 0.707;
@ -122,7 +128,7 @@ void Voice::run(Synth &s, float *buffer, uint32_t samples) {
lastpw = pw;
// gain for fully resonant needs to be 128mV output
out = b4 * (0.625);
out = b4 * (0.1625);
buffer[i] += (gain * out * vr58c106);
}

View File

@ -27,6 +27,8 @@ class Synth;
class Voice {
public:
uint8_t note = 60; // per-voice note, set to middle C at 02b1h
float detune[8] = {-0.13, -0.09, -0.05, -0.025, 0.018, 0.06, 0.11, 0.16};
uint8_t voicenum;
void on(uint32_t key, bool reset);
void off();
@ -40,6 +42,8 @@ class Voice {
float omega;
uint16_t vcfenv;
float phase = 0, subosc = 1;
private:
enum { ATTACK,
@ -61,10 +65,10 @@ class Voice {
uint16_t env;
float phase = 0, subosc = 1;
// float env, target;
float delay;
uint8_t pulseStage = 0;
uint32_t lcg;
float lastpw = 0;
float vr58c106 = 0;
@ -80,6 +84,10 @@ class Synth {
uint32_t framesLeft = 0;
uint8_t polymode;
uint8_t noteTbl[8];
uint8_t voiceTbl[8];
float unisonDetune;
bool keyon;
uint8_t ff63 = 0;

View File

@ -296,6 +296,10 @@ h0407:
h0432:
// printf("setting omega for note %d \n", a);
omega = ((s.pitchCV[a + 1] - s.pitchCV[a]) * (s.ff6e / 256.0)) + s.pitchCV[a];
omega *= 1 + (s.unisonDetune*0.25*detune[voicenum]);
//printf("%f %f %d\n", s.unisonDetune, omega, voicenum);
//phase = (2.4*omega*voicenum);
// 0432 onwards calculates the address for the CV
// table at E60 and stacks it
// 043a onwards fetches the value from the divider