pitch bender for oscillator, no range setting
This commit is contained in:
parent
c5ca40d22c
commit
6a8e0686a6
|
|
@ -74,6 +74,10 @@
|
|||
|
||||
pChorusMode,
|
||||
|
||||
pVcoBend,
|
||||
pVcfBend,
|
||||
pModDepth,
|
||||
|
||||
parameterCount
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -63,7 +63,7 @@ void Assigner::handleMidi(MidiEvent* ev) {
|
|||
switch (ev->data[1]) {
|
||||
// handle the following
|
||||
// CC 1 - modwheel
|
||||
// CC 64 - sustain
|
||||
// CC 64 - sustain // FIXME sustain not implemented
|
||||
// possibly JU-06 CC values
|
||||
default:
|
||||
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
|
||||
case 0xc0: // program change
|
||||
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;
|
||||
case 0xf0: // sysex
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -139,9 +139,9 @@ void Module::run(Voice* voices, uint32_t blockSize) {
|
|||
lfoToVcf = (patchRam.vcfLfo * lfoDelay) >> 7; // value is 0-127
|
||||
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 += /* pitch bend FIXME */ 0;
|
||||
pitchBase += bend;
|
||||
|
||||
vcfBase = (patchRam.vcfFreq << 7) + /* vcf bend FIXME */ 0;
|
||||
vcfBase += lfoToVcf;
|
||||
|
|
@ -170,16 +170,18 @@ void Module::run(Voice* voices, uint32_t blockSize) {
|
|||
|
||||
// pitch
|
||||
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;
|
||||
|
||||
if (semi<0) { semi=0; frac = 0; }
|
||||
if (semi>=103) { semi=103; frac = 0; };
|
||||
float p1 = pitchTable[semi], p2 = pitchTable[semi + 1];
|
||||
int16_t px = ((p2 - p1) * frac + p1); // interpolated pitch from table
|
||||
|
||||
// octave divider
|
||||
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
|
||||
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;
|
||||
|
||||
float saw = 0, square = 0, sub = 0, noise = 0, master = 0;
|
||||
|
||||
/*
|
||||
#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
|
||||
*/
|
||||
int16_t bend = 0x0c00;
|
||||
|
||||
struct {
|
||||
uint8_t lfoRate = 0x1f;
|
||||
|
|
|
|||
|
|
@ -40,9 +40,9 @@ Voice::Voice() {
|
|||
}
|
||||
|
||||
void Voice::on(uint8_t midiNote) {
|
||||
while (midiNote < 24) midiNote += 12;
|
||||
while (midiNote > 108) midiNote -= 12;
|
||||
note = midiNote - 24;
|
||||
while (midiNote < 24) midiNote += 12; // limit lowest note to C1
|
||||
while (midiNote > 108) midiNote -= 12; // limit highest note to C8
|
||||
note = midiNote;
|
||||
envPhase = 1;
|
||||
}
|
||||
|
||||
|
|
@ -50,16 +50,6 @@ void Voice::off() {
|
|||
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) {
|
||||
// carry out per-voice calculations for each block of samples
|
||||
float out, t, fb;
|
||||
|
|
|
|||
Loading…
Reference in New Issue