pitch bender for oscillator, no range setting
This commit is contained in:
parent
c5ca40d22c
commit
6a8e0686a6
|
|
@ -74,6 +74,10 @@
|
||||||
|
|
||||||
pChorusMode,
|
pChorusMode,
|
||||||
|
|
||||||
|
pVcoBend,
|
||||||
|
pVcfBend,
|
||||||
|
pModDepth,
|
||||||
|
|
||||||
parameterCount
|
parameterCount
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -63,7 +63,7 @@ void Assigner::handleMidi(MidiEvent* ev) {
|
||||||
switch (ev->data[1]) {
|
switch (ev->data[1]) {
|
||||||
// handle the following
|
// handle the following
|
||||||
// CC 1 - modwheel
|
// CC 1 - modwheel
|
||||||
// CC 64 - sustain
|
// CC 64 - sustain // FIXME sustain not implemented
|
||||||
// possibly JU-06 CC values
|
// possibly JU-06 CC values
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
|
@ -71,7 +71,9 @@ void Assigner::handleMidi(MidiEvent* ev) {
|
||||||
break; // nothing to do here except in special cases where we don't expect the host to pass on controls
|
break; // nothing to do here except in special cases where we don't expect the host to pass on controls
|
||||||
case 0xc0: // program change
|
case 0xc0: // program change
|
||||||
break;
|
break;
|
||||||
case 0xe0: // pitch bend;
|
case 0xe0: // pitch bend
|
||||||
|
m->bend = (int)(ev->data[1] + (ev->data[2]<<7))/2.6667;
|
||||||
|
//printf("pitch bend %04x\n", (ev->data[1] + (ev->data[2]<<7)));
|
||||||
break;
|
break;
|
||||||
case 0xf0: // sysex
|
case 0xf0: // sysex
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
|
|
@ -139,9 +139,9 @@ void Module::run(Voice* voices, uint32_t blockSize) {
|
||||||
lfoToVcf = (patchRam.vcfLfo * lfoDelay) >> 7; // value is 0-127
|
lfoToVcf = (patchRam.vcfLfo * lfoDelay) >> 7; // value is 0-127
|
||||||
lfoToVcf = (lfo * lfoToVcf) >> 9; // 8 for normalisation plus one additional DSLR EA
|
lfoToVcf = (lfo * lfoToVcf) >> 9; // 8 for normalisation plus one additional DSLR EA
|
||||||
|
|
||||||
int16_t pitchBase = 0x1818, vcfBase = 0;
|
int16_t pitchBase = 0x0c18, vcfBase = 0;
|
||||||
pitchBase += lfoToVco;
|
pitchBase += lfoToVco;
|
||||||
pitchBase += /* pitch bend FIXME */ 0;
|
pitchBase += bend;
|
||||||
|
|
||||||
vcfBase = (patchRam.vcfFreq << 7) + /* vcf bend FIXME */ 0;
|
vcfBase = (patchRam.vcfFreq << 7) + /* vcf bend FIXME */ 0;
|
||||||
vcfBase += lfoToVcf;
|
vcfBase += lfoToVcf;
|
||||||
|
|
@ -170,16 +170,18 @@ void Module::run(Voice* voices, uint32_t blockSize) {
|
||||||
|
|
||||||
// pitch
|
// pitch
|
||||||
uint16_t pitch = pitchBase + (v->note << 8);
|
uint16_t pitch = pitchBase + (v->note << 8);
|
||||||
uint8_t semi = pitch >> 8;
|
int8_t semi = pitch >> 8;
|
||||||
|
semi -= 36;
|
||||||
float frac = (pitch & 0xff) / 256.0;
|
float frac = (pitch & 0xff) / 256.0;
|
||||||
|
if (semi<0) { semi=0; frac = 0; }
|
||||||
|
if (semi>=103) { semi=103; frac = 0; };
|
||||||
float p1 = pitchTable[semi], p2 = pitchTable[semi + 1];
|
float p1 = pitchTable[semi], p2 = pitchTable[semi + 1];
|
||||||
int16_t px = ((p2 - p1) * frac + p1); // interpolated pitch from table
|
int16_t px = ((p2 - p1) * frac + p1); // interpolated pitch from table
|
||||||
|
|
||||||
// octave divider
|
// octave divider
|
||||||
px *= (patchRam.switch1 & 0x07);
|
px *= (patchRam.switch1 & 0x07);
|
||||||
|
|
||||||
v->omega = px / (sampleRate * 8.0f); // FIXME recalculate table using proper scaler
|
v->omega = px / (sampleRate * 4.0f); // FIXME recalculate table using proper scaler
|
||||||
|
|
||||||
// per voice we need to calculate the key follow amount and envelope amount
|
// per voice we need to calculate the key follow amount and envelope amount
|
||||||
v->vcfCut = vcfBase + (((v->env * patchRam.vcfEnv)>>7) * ((patchRam.switch2 & 0x02) ? -1 : 1));
|
v->vcfCut = vcfBase + (((v->env * patchRam.vcfEnv)>>7) * ((patchRam.switch2 & 0x02) ? -1 : 1));
|
||||||
|
|
|
||||||
|
|
@ -43,53 +43,7 @@ class Module {
|
||||||
uint16_t a, d, s, r;
|
uint16_t a, d, s, r;
|
||||||
|
|
||||||
float saw = 0, square = 0, sub = 0, noise = 0, master = 0;
|
float saw = 0, square = 0, sub = 0, noise = 0, master = 0;
|
||||||
|
int16_t bend = 0x0c00;
|
||||||
/*
|
|
||||||
#if 0
|
|
||||||
struct {
|
|
||||||
uint8_t lfoRate = 0x58;
|
|
||||||
uint8_t lfoDelay = 0x00;
|
|
||||||
uint8_t vcoLfo = 0x00;
|
|
||||||
uint8_t pwmLfo = 0x3b;
|
|
||||||
uint8_t noise = 0x00;
|
|
||||||
uint8_t vcfFreq = 0x25; // 1c; // 0x3f80
|
|
||||||
uint8_t vcfReso = 0x6a;
|
|
||||||
uint8_t vcfEnv = 0x25; // 4e;
|
|
||||||
uint8_t vcfLfo = 0x00;
|
|
||||||
uint8_t vcfKey = 0x00; // 47;
|
|
||||||
uint8_t vca = 0x35;
|
|
||||||
uint8_t env_a = 0x00;
|
|
||||||
uint8_t env_d = 0x3c;
|
|
||||||
uint8_t env_s = 0x00; // 0x3f80
|
|
||||||
uint8_t env_r = 0x3c;
|
|
||||||
uint8_t sub = 0x7f;
|
|
||||||
uint8_t switch1 = 0x4a;
|
|
||||||
uint8_t switch2 = 0x18;
|
|
||||||
} patchRam;
|
|
||||||
|
|
||||||
#else
|
|
||||||
struct {
|
|
||||||
uint8_t lfoRate = 0x40;
|
|
||||||
uint8_t lfoDelay = 0x00;
|
|
||||||
uint8_t vcoLfo = 0x00;
|
|
||||||
uint8_t pwmLfo = 0x00;
|
|
||||||
uint8_t noise = 0x01;
|
|
||||||
uint8_t vcfFreq = 0x31;
|
|
||||||
uint8_t vcfReso = 0x7f;
|
|
||||||
uint8_t vcfEnv = 0x00;
|
|
||||||
uint8_t vcfLfo = 0x00;
|
|
||||||
uint8_t vcfKey = 0x7f;
|
|
||||||
uint8_t vca = 0x40;
|
|
||||||
uint8_t env_a = 0x00;
|
|
||||||
uint8_t env_d = 0x00;
|
|
||||||
uint8_t env_s = 0x00; // 0x3f80
|
|
||||||
uint8_t env_r = 0x00;
|
|
||||||
uint8_t sub = 0x00;
|
|
||||||
uint8_t switch1 = 0x22;
|
|
||||||
uint8_t switch2 = 0x1d;
|
|
||||||
} patchRam;
|
|
||||||
#endif
|
|
||||||
*/
|
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
uint8_t lfoRate = 0x1f;
|
uint8_t lfoRate = 0x1f;
|
||||||
|
|
|
||||||
|
|
@ -40,9 +40,9 @@ Voice::Voice() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Voice::on(uint8_t midiNote) {
|
void Voice::on(uint8_t midiNote) {
|
||||||
while (midiNote < 24) midiNote += 12;
|
while (midiNote < 24) midiNote += 12; // limit lowest note to C1
|
||||||
while (midiNote > 108) midiNote -= 12;
|
while (midiNote > 108) midiNote -= 12; // limit highest note to C8
|
||||||
note = midiNote - 24;
|
note = midiNote;
|
||||||
envPhase = 1;
|
envPhase = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -50,16 +50,6 @@ void Voice::off() {
|
||||||
envPhase = 0;
|
envPhase = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// tanh(x)/x approximation, flatline at very high inputs
|
|
||||||
// so might not be safe for very large feedback gains
|
|
||||||
// [limit is 1/15 so very large means ~15 or +23dB]
|
|
||||||
|
|
||||||
float tanhXdX(float x) {
|
|
||||||
return 1 - 0.05 * abs(x);
|
|
||||||
float s = 0.0333, d = 30.0;
|
|
||||||
return 1.0f - s * (d + 1.0f) * x * x / (d + x * x);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Voice::run(Module* m, float* buffer, uint32_t framePos, uint32_t samples) {
|
void Voice::run(Module* m, float* buffer, uint32_t framePos, uint32_t samples) {
|
||||||
// carry out per-voice calculations for each block of samples
|
// carry out per-voice calculations for each block of samples
|
||||||
float out, t, fb;
|
float out, t, fb;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue