Compare commits

..

5 Commits

Author SHA1 Message Date
Gordon JC Pearce
1c8f451c3a removed a lot of debugging printfs 2024-09-11 23:30:06 +01:00
Gordon JC Pearce
3980a1c966 correct parameter generation 2024-09-11 23:25:41 +01:00
Gordon JC Pearce
620914b500 saneish looking parameters 2024-09-11 21:40:11 +01:00
Gordon JC Pearce
3588c3459b fix labelling 2024-09-11 20:04:34 +01:00
Gordon JC Pearce
561acbc0fb fix uninitialised variable 2024-09-11 19:57:11 +01:00
5 changed files with 126 additions and 125 deletions

View File

@ -40,35 +40,7 @@ void Chassis::initProgramName(uint32_t index, String &programName) {
} }
void Chassis::loadProgram(uint32_t index) { void Chassis::loadProgram(uint32_t index) {
uint8_t paramOrder[16] = { memmove(&s.patchRam, (uint8_t *)patchData + (index * 18), 18);
paramLFORate,
paramLFODelay,
paramVCOLFO,
paramPWMLFO,
paramNoise,
paramVCFFreq,
paramVCFReso,
paramVCFEnv,
paramVCFLFO,
paramVCFKey,
paramVCALevel,
paramAttack,
paramDecay,
paramSustain,
paramRelease,
paramSub};
for (uint i = 0; i < 16; i++) {
setParameterValue(paramOrder[i], (float)patchData[index][i]);
}
setParameterValue(paramVCORange, patchData[index][16] & 0x07);
setParameterValue(paramSaw, (patchData[index][16] & 0x10) ? 127.0f : 0.0f);
setParameterValue(paramSqr, (patchData[index][16] & 0x08) ? 127.0f : 0.0f);
// FIXME chorus switch settings
setParameterValue(paramPWMMode, (patchData[index][17] & 0x01) ? 127.0f : 0.0f);
setParameterValue(paramVCFMode, (patchData[index][17] & 0x02) ? 127.0f : 0.0f);
setParameterValue(paramEnvGate, (patchData[index][17] & 0x04) ? 127.0f : 0.0f);
setParameterValue(paramHPF, (patchData[index][17] & 0x18) >> 3);
} }
// Processing functions // Processing functions
@ -77,8 +49,6 @@ void Chassis::activate() {
// calculate filter coefficients and stuff // calculate filter coefficients and stuff
printf("called activate()\n"); printf("called activate()\n");
// printf("p = %s", patchName[0].c_str());
for (uint8_t i = 0; i < 104; i++) { for (uint8_t i = 0; i < 104; i++) {
s.pitchCV[i] = (440.0f * powf(2, (i - 49) / 12.0f)) / sampleRate; s.pitchCV[i] = (440.0f * powf(2, (i - 49) / 12.0f)) / sampleRate;
} }
@ -87,7 +57,6 @@ void Chassis::activate() {
void Chassis::deactivate() { void Chassis::deactivate() {
// zero out the outputs, maybe // zero out the outputs, maybe
printf("called deactivate()\n"); printf("called deactivate()\n");
// printf("%02x", assign[1]);
} }
void Chassis::noteOn(uint8_t note) { void Chassis::noteOn(uint8_t note) {
@ -97,10 +66,8 @@ void Chassis::noteOn(uint8_t note) {
vPtr++; vPtr++;
if (vPtr == NUM_VOICES) vPtr = 0; if (vPtr == NUM_VOICES) vPtr = 0;
if (s.voice[vPtr].isFree()) { if (s.voice[vPtr].isFree()) {
// printf("voice %d is free, existing note = %d, note = %d\n", vPtr, s.voice[i].note, note);
// if it's an existing note don't reset // if it's an existing note don't reset
s.voice[vPtr].on(note, s.voice[i].note != note); s.voice[vPtr].on(note, s.voice[i].note != note);
// printf("note on %d for voice %d\n", note, vPtr);
break; break;
} }
} }
@ -113,23 +80,19 @@ void Chassis::noteOn(uint8_t note) {
} }
void Chassis::noteOff(uint8_t note) { void Chassis::noteOff(uint8_t note) {
// printf("noteoff %d\n", note);
s.keyon = false; s.keyon = false;
for (uint32_t i = 0; i < NUM_VOICES; i++) { for (uint32_t i = 0; i < NUM_VOICES; i++) {
if (s.voice[i].note == note && !s.voice[i].isFree()) { if (s.voice[i].note == note && !s.voice[i].isFree()) {
s.voice[i].off(); s.voice[i].off();
// printf("note off %d for voice %d\n", note, i);
break; break;
} }
} }
} }
void Chassis::doMidi(const MidiEvent *ev, uint32_t count, uint32_t timeLimit) { void Chassis::doMidi(const MidiEvent *ev, uint32_t count, uint32_t timeLimit) {
// printf("doMidi() handling events from %d to %d\n", lastEvent, timeLimit);
uint32_t i; uint32_t i;
if (count == 0) return; if (count == 0) return;
for (i = lastEvent; i < count; i++) { for (i = lastEvent; i < count; i++) {
// printf("doMidi event number %d of %d %02x %02x\n", i, count, ev[i].data[0], ev[i].data[1]);
if (ev[i].frame > timeLimit) break; if (ev[i].frame > timeLimit) break;
switch (ev[i].data[0]) { switch (ev[i].data[0]) {
case 0x90: case 0x90:
@ -144,14 +107,10 @@ void Chassis::doMidi(const MidiEvent *ev, uint32_t count, uint32_t timeLimit) {
} }
void Chassis::run(const float **, float **outputs, uint32_t frames, const MidiEvent *midiEvents, uint32_t midiEventCount) { void Chassis::run(const float **, float **outputs, uint32_t frames, const MidiEvent *midiEvents, uint32_t midiEventCount) {
// if (midiEventCount > 0) printf("\n--------------------\n");
uint32_t framePos = 0; uint32_t framePos = 0;
uint32_t sizeThisTime; uint32_t sizeThisTime;
s.framesLeft = frames; s.framesLeft = frames;
// printf("\n------------\ncalled run() for %d frames\n",frames);
// flatten the left channel to use as temporary storage, since // flatten the left channel to use as temporary storage, since
// the synth engine only generates a mono channel // the synth engine only generates a mono channel
bzero(outputs[0], sizeof(float) * frames); bzero(outputs[0], sizeof(float) * frames);
@ -166,7 +125,6 @@ void Chassis::run(const float **, float **outputs, uint32_t frames, const MidiEv
s.blockLeft = sampleRate / 238; s.blockLeft = sampleRate / 238;
doMidi(midiEvents, midiEventCount, framePos + s.blockLeft); doMidi(midiEvents, midiEventCount, framePos + s.blockLeft);
// printf("compute params and reset block size\n");
s.lfoDelay(); s.lfoDelay();
s.runLFO(); s.runLFO();
@ -174,26 +132,22 @@ void Chassis::run(const float **, float **outputs, uint32_t frames, const MidiEv
s.voice[i].calcPitch(s); s.voice[i].calcPitch(s);
switch (s.patchRam.switch1 & 0x07) { switch (s.patchRam.switch1 & 0x07) {
case 1: case 0:
s.voice[i].omega /= 2; s.voice[i].omega /= 2;
break; break;
case 4: case 2:
s.voice[i].omega *= 2; s.voice[i].omega *= 2;
default: default:
break; break;
} }
// printf("voice %d note = %02x ff71 = %04x\n",i, s.voice[i].note, s.voice[i].ff71 );
s.voice[i].envelope(s); s.voice[i].envelope(s);
s.voice[i].calcFilter(s); s.voice[i].calcFilter(s);
// printf("voice %d vcf level = %04x\n", i, s.voice[i].vcfenv );
} }
} }
sizeThisTime = (s.framesLeft < s.blockLeft) ? s.framesLeft : s.blockLeft; sizeThisTime = (s.framesLeft < s.blockLeft) ? s.framesLeft : s.blockLeft;
// printf("sL = %d bL = %d, calculating %d frames at %d\n", s.framesLeft, s.blockLeft, sizeThisTime, framePos);
// run each synth voice // run each synth voice
for (uint8_t i = 0; i < NUM_VOICES; i++) { for (uint8_t i = 0; i < NUM_VOICES; i++) {
@ -204,7 +158,6 @@ void Chassis::run(const float **, float **outputs, uint32_t frames, const MidiEv
s.framesLeft -= sizeThisTime; s.framesLeft -= sizeThisTime;
s.blockLeft -= sizeThisTime; s.blockLeft -= sizeThisTime;
} }
// printf("and now run the rest of the process for %d frames\n\n", frames);
// copy left to right // copy left to right
memmove(outputs[1], outputs[0], sizeof(float) * frames); memmove(outputs[1], outputs[0], sizeof(float) * frames);

View File

@ -71,12 +71,12 @@ class Chassis : public Plugin {
protected: protected:
const char *getLabel() const override { return "chassis"; } const char *getLabel() const override { return "chassis"; }
const char *getDescription() const override { const char *getDescription() const override {
return "MIDIVerb emulation, a tribute to Keith Barr"; return "simple polysynth";
} }
const char *getMaker() const override { return "Gordonjcp"; } const char *getMaker() const override { return "Gordonjcp"; }
const char *getLicense() const override { return "ISC"; } const char *getLicense() const override { return "ISC"; }
uint32_t getVersion() const override { return d_version(1, 0, 0); } uint32_t getVersion() const override { return d_version(1, 0, 0); }
int64_t getUniqueId() const override { return d_cconst('P', 'f', 'a', 'u'); } int64_t getUniqueId() const override { return d_cconst('P', 'h', 'e', 'r'); }
// Initialisation // Initialisation
void initAudioPort(bool input, uint32_t index, AudioPort &port) override; void initAudioPort(bool input, uint32_t index, AudioPort &port) override;
@ -101,7 +101,7 @@ class Chassis : public Plugin {
double sampleRate; double sampleRate;
uint32_t lastEvent; uint32_t lastEvent;
// Voice voice[NUM_VOICES]; // Voice voice[NUM_VOICES];
uint8_t vPtr; uint8_t vPtr = 0;
Synth s; Synth s;

View File

@ -18,7 +18,7 @@
#include "chassis.hpp" #include "chassis.hpp"
void Chassis::initParameter(uint32_t index, Parameter &parameter) { void Chassis::initParameter(uint32_t index, Parameter& parameter) {
switch (index) { switch (index) {
case paramLFORate: case paramLFORate:
parameter.hints = kParameterIsAutomatable; parameter.hints = kParameterIsAutomatable;
@ -26,7 +26,7 @@ void Chassis::initParameter(uint32_t index, Parameter &parameter) {
parameter.symbol = "ch_lforate"; parameter.symbol = "ch_lforate";
parameter.ranges.min = 0.0f; parameter.ranges.min = 0.0f;
parameter.ranges.max = 127.0f; parameter.ranges.max = 127.0f;
parameter.ranges.def = 57.0f; parameter.ranges.def = 48.0f;
parameter.midiCC = 3; parameter.midiCC = 3;
break; break;
@ -36,7 +36,7 @@ void Chassis::initParameter(uint32_t index, Parameter &parameter) {
parameter.symbol = "ch_lfodelay"; parameter.symbol = "ch_lfodelay";
parameter.ranges.min = 0.0f; parameter.ranges.min = 0.0f;
parameter.ranges.max = 127.0f; parameter.ranges.max = 127.0f;
parameter.ranges.def = 45.0f; parameter.ranges.def = 0.0f;
parameter.midiCC = 9; parameter.midiCC = 9;
break; break;
@ -45,9 +45,22 @@ void Chassis::initParameter(uint32_t index, Parameter &parameter) {
parameter.name = "Range"; parameter.name = "Range";
parameter.symbol = "ch_vcorange"; parameter.symbol = "ch_vcorange";
parameter.ranges.min = 0.0f; parameter.ranges.min = 0.0f;
parameter.ranges.max = 4.0f; parameter.ranges.max = 2.0f;
parameter.ranges.def = 2.0f; parameter.ranges.def = 1.0f;
parameter.midiCC = 12; parameter.midiCC = 12;
parameter.enumValues.count = 3;
parameter.enumValues.restrictedMode = true;
{
ParameterEnumerationValue* const enumValues = new ParameterEnumerationValue[3];
enumValues[0].value = 0.0f;
enumValues[0].label = "16'";
enumValues[1].value = 1.0f;
enumValues[1].label = "8'";
enumValues[2].value = 2.0f;
enumValues[2].label = "4'";
parameter.enumValues.values = enumValues;
}
break; break;
case paramVCOLFO: case paramVCOLFO:
@ -56,7 +69,7 @@ void Chassis::initParameter(uint32_t index, Parameter &parameter) {
parameter.symbol = "ch_lfo"; parameter.symbol = "ch_lfo";
parameter.ranges.min = 0.0f; parameter.ranges.min = 0.0f;
parameter.ranges.max = 127.0f; parameter.ranges.max = 127.0f;
parameter.ranges.def = 0.0f; parameter.ranges.def = 10.0f;
parameter.midiCC = 13; parameter.midiCC = 13;
break; break;
@ -66,7 +79,7 @@ void Chassis::initParameter(uint32_t index, Parameter &parameter) {
parameter.symbol = "ch_pwm"; parameter.symbol = "ch_pwm";
parameter.ranges.min = 0.0f; parameter.ranges.min = 0.0f;
parameter.ranges.max = 127.0f; parameter.ranges.max = 127.0f;
parameter.ranges.def = 55.0f; parameter.ranges.def = 48.0f;
parameter.midiCC = 14; parameter.midiCC = 14;
break; break;
@ -75,9 +88,20 @@ void Chassis::initParameter(uint32_t index, Parameter &parameter) {
parameter.name = "PWM Mode"; parameter.name = "PWM Mode";
parameter.symbol = "ch_pwmmode"; parameter.symbol = "ch_pwmmode";
parameter.ranges.min = 0.0f; parameter.ranges.min = 0.0f;
parameter.ranges.max = 127.0f; parameter.ranges.max = 1.0f;
parameter.ranges.def = 0.0f; parameter.ranges.def = 1.0f;
parameter.midiCC = 15; parameter.midiCC = 15;
parameter.enumValues.count = 2;
parameter.enumValues.restrictedMode = true;
{
ParameterEnumerationValue* const enumValues = new ParameterEnumerationValue[2];
enumValues[0].value = 0.0f;
enumValues[0].label = "LFO";
enumValues[1].value = 1.0f;
enumValues[1].label = "MAN";
parameter.enumValues.values = enumValues;
}
break; break;
case paramSaw: case paramSaw:
@ -85,8 +109,8 @@ void Chassis::initParameter(uint32_t index, Parameter &parameter) {
parameter.name = "Saw"; parameter.name = "Saw";
parameter.symbol = "ch_saw"; parameter.symbol = "ch_saw";
parameter.ranges.min = 0.0f; parameter.ranges.min = 0.0f;
parameter.ranges.max = 127.0f; parameter.ranges.max = 1.0f;
parameter.ranges.def = 127.0f; parameter.ranges.def = 1.0f;
parameter.midiCC = 17; parameter.midiCC = 17;
break; break;
@ -95,8 +119,8 @@ void Chassis::initParameter(uint32_t index, Parameter &parameter) {
parameter.name = "Square"; parameter.name = "Square";
parameter.symbol = "ch_sqr"; parameter.symbol = "ch_sqr";
parameter.ranges.min = 0.0f; parameter.ranges.min = 0.0f;
parameter.ranges.max = 127.0f; parameter.ranges.max = 1.0f;
parameter.ranges.def = 127.0f; parameter.ranges.def = 1.0f;
parameter.midiCC = 16; parameter.midiCC = 16;
break; break;
@ -125,7 +149,7 @@ void Chassis::initParameter(uint32_t index, Parameter &parameter) {
parameter.name = "HPF"; parameter.name = "HPF";
parameter.symbol = "ch_hpf"; parameter.symbol = "ch_hpf";
parameter.ranges.min = 0.0f; parameter.ranges.min = 0.0f;
parameter.ranges.max = 4.0f; parameter.ranges.max = 3.0f;
parameter.ranges.def = 0.0f; parameter.ranges.def = 0.0f;
parameter.midiCC = 20; parameter.midiCC = 20;
break; break;
@ -136,7 +160,7 @@ void Chassis::initParameter(uint32_t index, Parameter &parameter) {
parameter.symbol = "ch_freq"; parameter.symbol = "ch_freq";
parameter.ranges.min = 0.0f; parameter.ranges.min = 0.0f;
parameter.ranges.max = 127.0f; parameter.ranges.max = 127.0f;
parameter.ranges.def = 0.0f; parameter.ranges.def = 60.0f;
parameter.midiCC = 74; parameter.midiCC = 74;
break; break;
case paramVCFReso: case paramVCFReso:
@ -149,13 +173,24 @@ void Chassis::initParameter(uint32_t index, Parameter &parameter) {
parameter.midiCC = 71; parameter.midiCC = 71;
break; break;
case paramVCFMode: case paramVCFMode:
parameter.hints = kParameterIsAutomatable | kParameterIsBoolean; parameter.hints = kParameterIsAutomatable | kParameterIsInteger;
parameter.name = "Polarity"; parameter.name = "Polarity";
parameter.symbol = "ch_vcfmode"; parameter.symbol = "ch_vcfmode";
parameter.ranges.min = 0.0f; parameter.ranges.min = 0.0f;
parameter.ranges.max = 127.0f; parameter.ranges.max = 1.0f;
parameter.ranges.def = 0.0f; parameter.ranges.def = 1.0f;
parameter.midiCC = 21; parameter.midiCC = 21;
parameter.enumValues.count = 2;
parameter.enumValues.restrictedMode = true;
{
ParameterEnumerationValue* const enumValues = new ParameterEnumerationValue[2];
enumValues[0].value = 0.0f;
enumValues[0].label = "POS";
enumValues[1].value = 1.0f;
enumValues[1].label = "INV";
parameter.enumValues.values = enumValues;
}
break; break;
case paramVCFEnv: case paramVCFEnv:
parameter.hints = kParameterIsAutomatable; parameter.hints = kParameterIsAutomatable;
@ -163,7 +198,7 @@ void Chassis::initParameter(uint32_t index, Parameter &parameter) {
parameter.symbol = "ch_vcfenv"; parameter.symbol = "ch_vcfenv";
parameter.ranges.min = 0.0f; parameter.ranges.min = 0.0f;
parameter.ranges.max = 127.0f; parameter.ranges.max = 127.0f;
parameter.ranges.def = 0.0f; parameter.ranges.def = 46.0f;
parameter.midiCC = 22; parameter.midiCC = 22;
break; break;
case paramVCFLFO: case paramVCFLFO:
@ -181,7 +216,7 @@ void Chassis::initParameter(uint32_t index, Parameter &parameter) {
parameter.symbol = "ch_vcfkey"; parameter.symbol = "ch_vcfkey";
parameter.ranges.min = 0.0f; parameter.ranges.min = 0.0f;
parameter.ranges.max = 127.0f; parameter.ranges.max = 127.0f;
parameter.ranges.def = 0.0f; parameter.ranges.def = 71.0f;
parameter.midiCC = 24; parameter.midiCC = 24;
break; break;
@ -191,7 +226,7 @@ void Chassis::initParameter(uint32_t index, Parameter &parameter) {
parameter.symbol = "ch_attack"; parameter.symbol = "ch_attack";
parameter.ranges.min = 0.0f; parameter.ranges.min = 0.0f;
parameter.ranges.max = 127.0f; parameter.ranges.max = 127.0f;
parameter.ranges.def = 59.0f; parameter.ranges.def = 27.0f;
parameter.midiCC = 73; parameter.midiCC = 73;
break; break;
@ -201,7 +236,7 @@ void Chassis::initParameter(uint32_t index, Parameter &parameter) {
parameter.symbol = "ch_decay"; parameter.symbol = "ch_decay";
parameter.ranges.min = 0.0f; parameter.ranges.min = 0.0f;
parameter.ranges.max = 127.0f; parameter.ranges.max = 127.0f;
parameter.ranges.def = 32.0f; parameter.ranges.def = 57.0f;
parameter.midiCC = 75; parameter.midiCC = 75;
break; break;
@ -211,7 +246,7 @@ void Chassis::initParameter(uint32_t index, Parameter &parameter) {
parameter.symbol = "ch_sustain"; parameter.symbol = "ch_sustain";
parameter.ranges.min = 0.0f; parameter.ranges.min = 0.0f;
parameter.ranges.max = 127.0f; parameter.ranges.max = 127.0f;
parameter.ranges.def = 86.0f; parameter.ranges.def = 57.0f;
parameter.midiCC = 27; parameter.midiCC = 27;
break; break;
@ -221,18 +256,28 @@ void Chassis::initParameter(uint32_t index, Parameter &parameter) {
parameter.symbol = "ch_release"; parameter.symbol = "ch_release";
parameter.ranges.min = 0.0f; parameter.ranges.min = 0.0f;
parameter.ranges.max = 127.0f; parameter.ranges.max = 127.0f;
parameter.ranges.def = 40.0f; parameter.ranges.def = 48.0f;
parameter.midiCC = 72; parameter.midiCC = 72;
break; break;
case paramEnvGate: case paramEnvGate:
parameter.hints = kParameterIsAutomatable | kParameterIsBoolean; parameter.hints = kParameterIsAutomatable | kParameterIsInteger; // | kParameterIsBoolean;
parameter.name = "Env-Gate"; parameter.name = "Env-Gate";
parameter.symbol = "ch_envgate"; parameter.symbol = "ch_envgate";
parameter.ranges.min = 0.0f; parameter.ranges.min = 0.0f;
parameter.ranges.max = 127.0f; parameter.ranges.max = 1.0f;
parameter.ranges.def = 0.0f; parameter.ranges.def = 1.0f;
parameter.midiCC = 25; parameter.midiCC = 25;
parameter.enumValues.count = 2;
parameter.enumValues.restrictedMode = true;
{
ParameterEnumerationValue* const enumValues = new ParameterEnumerationValue[2];
enumValues[0].value = 0.0f;
enumValues[0].label = "ENV";
enumValues[1].value = 1.0f;
enumValues[1].label = "GATE";
parameter.enumValues.values = enumValues;
}
break; break;
case paramVCALevel: case paramVCALevel:
@ -321,16 +366,16 @@ void Chassis::setParameterValue(uint32_t index, float value) {
case paramVCORange: // bits 0-2 of switch 1 case paramVCORange: // bits 0-2 of switch 1
// doesn't look great in Carla because of odd behaviour with small integer knobs // doesn't look great in Carla because of odd behaviour with small integer knobs
s.patchRam.switch1 &= 0xf8; s.patchRam.switch1 &= 0xf8;
s.patchRam.switch1 |= (1 << (int)value); s.patchRam.switch1 |= (1 << (int)(value - 1));
break; break;
case paramSqr: // bit 3 of switch 1 case paramSqr: // bit 3 of switch 1
s.patchRam.switch1 &= 0xf7; s.patchRam.switch1 &= 0xf7;
s.patchRam.switch1 |= (value > 63) << 3; s.patchRam.switch1 |= (value >= 0.5) << 3;
break; break;
case paramSaw: // bit 4 of switch 1 case paramSaw: // bit 4 of switch 1
s.patchRam.switch1 &= 0xef; s.patchRam.switch1 &= 0xef;
s.patchRam.switch1 |= (value > 63) << 4; s.patchRam.switch1 |= (value >= 0.5) << 4;
break; break;
// missing chorus switch // missing chorus switch
@ -338,23 +383,23 @@ void Chassis::setParameterValue(uint32_t index, float value) {
// switch 2 params // switch 2 params
case paramPWMMode: // bit 0 of switch 2 case paramPWMMode: // bit 0 of switch 2
s.patchRam.switch2 &= 0xfe; s.patchRam.switch2 &= 0xfe;
s.patchRam.switch2 |= (value > 63); s.patchRam.switch2 |= (value >= 0.5);
break; break;
case paramVCFMode: // bit 1 of switch 2 case paramVCFMode: // bit 1 of switch 2
s.patchRam.switch2 &= 0xfd; s.patchRam.switch2 &= 0xfd;
s.patchRam.switch2 |= (value > 63) << 1; s.patchRam.switch2 |= (value >= 0.5) << 1;
break; break;
case paramEnvGate: case paramEnvGate:
s.patchRam.switch2 &= 0xfb; s.patchRam.switch2 &= 0xfb;
s.patchRam.switch2 |= (value > 63) << 2; s.patchRam.switch2 |= (value >= 0.5) << 2;
break; break;
case paramHPF: // bits 3-4 of switch 2 case paramHPF: // bits 3-4 of switch 2
// doesn't look great in Carla because of odd behaviour with small integer knobs // doesn't look great in Carla because of odd behaviour with small integer knobs
if (value > 3) value = 3; if (value > 3) value = 3;
s.patchRam.switch2 &= 0xf3; s.patchRam.switch2 &= 0xf3;
s.patchRam.switch2 |= (int)value << 2; s.patchRam.switch2 |= (int)value << 3;
break; break;
case paramModWheel: case paramModWheel:
@ -364,7 +409,6 @@ void Chassis::setParameterValue(uint32_t index, float value) {
} }
float Chassis::getParameterValue(uint32_t index) const { float Chassis::getParameterValue(uint32_t index) const {
// printf("getparametervalue %d\n", index);
switch (index) { switch (index) {
case paramLFORate: case paramLFORate:
return s.patchRam.lfoRate; return s.patchRam.lfoRate;
@ -374,7 +418,16 @@ float Chassis::getParameterValue(uint32_t index) const {
break; break;
case paramVCORange: case paramVCORange:
// FIXME this needs to be better generally // FIXME this needs to be better generally
return (s.patchRam.switch1 & 0x07) << 1; switch (s.patchRam.switch1 & 0x07) {
case 1:
return 0;
break;
case 4:
return 2;
break;
default:
return 1;
}
break; break;
case paramVCOLFO: case paramVCOLFO:
return s.patchRam.vcoLfo; return s.patchRam.vcoLfo;
@ -382,16 +435,15 @@ float Chassis::getParameterValue(uint32_t index) const {
case paramPWMLFO: case paramPWMLFO:
return s.patchRam.pwmLfo * 1.27f; return s.patchRam.pwmLfo * 1.27f;
break; break;
case paramPWMMode:
return (s.patchRam.switch2 & 0x01) ? 127.0f : 0.0f;
break;
case paramPWMMode:
return (s.patchRam.switch2 & 0x01) != 0;
break;
case paramSaw: case paramSaw:
return (s.patchRam.switch1 & 0x10) ? 127.0f : 0.0f; return (s.patchRam.switch1 & 0x10) != 0;
break; break;
case paramSqr: case paramSqr:
return (s.patchRam.switch1 & 0x08) ? 127.0f : 0.0f; return (s.patchRam.switch1 & 0x08) != 0;
break;
case paramSub: case paramSub:
return s.patchRam.sub; return s.patchRam.sub;
@ -418,7 +470,7 @@ float Chassis::getParameterValue(uint32_t index) const {
return s.patchRam.vcfKey; return s.patchRam.vcfKey;
break; break;
case paramVCFMode: case paramVCFMode:
return (s.patchRam.switch2 & 0x02) ? 127.0f : 0.0f; return (s.patchRam.switch2 & 0x02) != 0;
break; break;
case paramAttack: case paramAttack:
@ -435,8 +487,7 @@ float Chassis::getParameterValue(uint32_t index) const {
break; break;
case paramEnvGate: case paramEnvGate:
return (s.patchRam.switch2 & 0x04) ? 127.0f : 0.0f; return (s.patchRam.switch2 & 0x04) != 0;
break;
case paramVCALevel: case paramVCALevel:
return s.patchRam.vca; return s.patchRam.vca;

View File

@ -36,20 +36,17 @@ static inline float poly3blep1(float t) {
void Voice::run(Synth &s, float *buffer, uint32_t samples) { void Voice::run(Synth &s, float *buffer, uint32_t samples) {
float y, out, t; float y, out, t;
// 325, because it needs PW to be from 0 to 0.5
// but really the control range is limited from 0 to 100
// there's a resistor on the panel board to sprag the range
float pw = s.ff4f / 32768.0f; float pw = s.ff4f / 32768.0f;
float fb, res = s.patchRam.vcfReso / 28.0f; // guess float fb, res = s.patchRam.vcfReso / 28.0f; // guess
//float cut = s.patchRam.vcfFreq / 400.0f; // guess
float cut = 248.0f * (powf(2,(vcfenv-0x1880)/1143.0f)); float cut = 248.0f * (powf(2, (vcfenv - 0x1880) / 1143.0f));
// now radians // now radians
cut = 0.25 * 6.2832 * cut / 48000.0f; cut = 0.25 * 6.2832 * cut / 48000.0f;
// now correct // now correct
cut = cut/(1+cut); cut = cut / (1 + cut);
float sqr = (s.patchRam.switch1 & 0x08) ? 0.63 : 0; //? 0.175 : 0; float sqr = (s.patchRam.switch1 & 0x08) ? 0.63 : 0; //? 0.175 : 0;
float saw = (s.patchRam.switch1 & 0x10) ? 0.8 : 0; //? 0.220 : 0; float saw = (s.patchRam.switch1 & 0x10) ? 0.8 : 0; //? 0.220 : 0;
@ -103,7 +100,7 @@ void Voice::run(Synth &s, float *buffer, uint32_t samples) {
out = y; out = y;
// widthDelay = pw; // widthDelay = pw;
//out *= 0.5; out *= 0.707;
for (uint8_t ovs = 0; ovs < 4; ovs++) { for (uint8_t ovs = 0; ovs < 4; ovs++) {
fb = b4; fb = b4;
@ -118,11 +115,11 @@ void Voice::run(Synth &s, float *buffer, uint32_t samples) {
b4 = ((b3 - b4) * cut) + b4; b4 = ((b3 - b4) * cut) + b4;
} }
vr58c106 += ((vcaEnv - vr58c106) * 0.0075); vr58c106 += ((vcaEnv - vr58c106) * 0.005);
lastpw = pw; lastpw = pw;
out = b4 * (0.2); out = b4 * (0.25);
buffer[i] += (gain * b4 * vr58c106); buffer[i] += (gain * out * vr58c106);
} }
} }

View File

@ -112,24 +112,24 @@ class Synth {
// the comments indicate what the defaults are set to // the comments indicate what the defaults are set to
// in the routine at 02c2h, in case they're important // in the routine at 02c2h, in case they're important
struct { struct {
uint8_t lfoRate = 57; // lookup value defaults to 0x0200 uint8_t lfoRate = 0x30; // lookup value defaults to 0x0200
uint8_t lfoDelay = 45; uint8_t lfoDelay = 0x00;
uint8_t vcoLfo = 0; uint8_t vcoLfo = 0x0a;
uint8_t pwmLfo = 55; uint8_t pwmLfo = 0x30;
uint8_t noise = 0; uint8_t noise = 0x00;
uint8_t vcfFreq = 85; // 0x3f80 uint8_t vcfFreq = 0x3c; // 0x3f80
uint8_t vcfReso = 0; uint8_t vcfReso = 0x00;
uint8_t vcfEnv = 0; uint8_t vcfEnv = 0x2e;
uint8_t vcfLfo = 0; uint8_t vcfLfo = 0;
uint8_t vcfKey = 108; uint8_t vcfKey = 0x47;
uint8_t vca = 52; uint8_t vca = 0x28;
uint8_t env_a = 59; uint8_t env_a = 0x1b;
uint8_t env_d = 32; uint8_t env_d = 0x39;
uint8_t env_s = 86; // 0x3f80 uint8_t env_s = 0x39; // 0x3f80
uint8_t env_r = 40; uint8_t env_r = 0x30;
uint8_t sub = 0; uint8_t sub = 0x00;
uint8_t switch1 = 26; uint8_t switch1 = 0x1a;
uint8_t switch2 = 24; uint8_t switch2 = 0x18;
} patchRam; } patchRam;
float pitchCV[104]; float pitchCV[104];