|
|
|
@ -118,7 +118,6 @@ mdaEPiano::mdaEPiano() // mdaEPiano::mdaEPiano(audioMasterCallback audioMaster) |
|
|
|
|
voice[v].env = 0.0f; |
|
|
|
|
voice[v].dec = 0.99f; //all notes off
|
|
|
|
|
} |
|
|
|
|
notes[0] = EVENTS_DONE; |
|
|
|
|
volume = 0.2f; |
|
|
|
|
muff = 160.0f; |
|
|
|
|
sustain = activevoices = 0; |
|
|
|
@ -335,61 +334,57 @@ float mdaEPiano::getParameter(int32_t index) { |
|
|
|
|
|
|
|
|
|
void mdaEPiano::process(int16_t *outputs_r, int16_t *outputs_l, int32_t sampleFrames) |
|
|
|
|
{ |
|
|
|
|
int32_t event = 0, frame = 0, frames, v; |
|
|
|
|
int16_t v; |
|
|
|
|
float x, l, r, od = overdrive; |
|
|
|
|
int32_t i; |
|
|
|
|
int16_t frame; |
|
|
|
|
|
|
|
|
|
while (frame < sampleFrames) |
|
|
|
|
for (frame = 0; frame < sampleFrames; frame++) |
|
|
|
|
{ |
|
|
|
|
frames = notes[event++]; |
|
|
|
|
if (frames > sampleFrames) frames = sampleFrames; |
|
|
|
|
frames -= frame; |
|
|
|
|
frame += frames; |
|
|
|
|
|
|
|
|
|
while (--frames >= 0) |
|
|
|
|
VOICE *V = voice; |
|
|
|
|
l = r = 0.0f; |
|
|
|
|
for (v = 0; v < activevoices; v++) |
|
|
|
|
{ |
|
|
|
|
VOICE *V = voice; |
|
|
|
|
l = r = 0.0f; |
|
|
|
|
V->frac += V->delta; //integer-based linear interpolation
|
|
|
|
|
V->pos += V->frac >> 16; |
|
|
|
|
V->frac &= 0xFFFF; |
|
|
|
|
if (V->pos > V->end) V->pos -= V->loop; |
|
|
|
|
//i = waves[V->pos];
|
|
|
|
|
//i = (i << 7) + (V->frac >> 9) * (waves[V->pos + 1] - i) + 0x40400000; //not working on intel mac !?!
|
|
|
|
|
//x = V->env * (*(float *)&i - 3.0f); //fast int->float
|
|
|
|
|
//x = V->env * (float)i / 32768.0f;
|
|
|
|
|
i = waves[V->pos] + ((V->frac * (waves[V->pos + 1] - waves[V->pos])) >> 16); |
|
|
|
|
//x = V->env * (float)i / 32768.0f;
|
|
|
|
|
|
|
|
|
|
for (v = 0; v < activevoices; v++) |
|
|
|
|
{ |
|
|
|
|
V->frac += V->delta; //integer-based linear interpolation
|
|
|
|
|
V->pos += V->frac >> 16; |
|
|
|
|
V->frac &= 0xFFFF; |
|
|
|
|
if (V->pos > V->end) V->pos -= V->loop; |
|
|
|
|
//i = waves[V->pos];
|
|
|
|
|
//i = (i << 7) + (V->frac >> 9) * (waves[V->pos + 1] - i) + 0x40400000; //not working on intel mac !?!
|
|
|
|
|
//x = V->env * (*(float *)&i - 3.0f); //fast int->float
|
|
|
|
|
//x = V->env * (float)i / 32768.0f;
|
|
|
|
|
i = waves[V->pos] + ((V->frac * (waves[V->pos + 1] - waves[V->pos])) >> 16); |
|
|
|
|
x = V->env * (float)i / 32768.0f; |
|
|
|
|
|
|
|
|
|
V->env = V->env * V->dec; //envelope
|
|
|
|
|
|
|
|
|
|
if (x > 0.0f) { |
|
|
|
|
x -= od * x * x; //overdrive
|
|
|
|
|
if (x < -V->env) x = -V->env; |
|
|
|
|
} //+= 0.5f * x * x; }
|
|
|
|
|
|
|
|
|
|
l += V->outl * x; |
|
|
|
|
r += V->outr * x; |
|
|
|
|
|
|
|
|
|
V++; |
|
|
|
|
} |
|
|
|
|
tl += tfrq * (l - tl); //treble boost
|
|
|
|
|
tr += tfrq * (r - tr); |
|
|
|
|
r += treb * (r - tr); |
|
|
|
|
l += treb * (l - tl); |
|
|
|
|
|
|
|
|
|
lfo0 += dlfo * lfo1; //LFO for tremolo and autopan
|
|
|
|
|
lfo1 -= dlfo * lfo0; |
|
|
|
|
l += l * lmod * lfo1; |
|
|
|
|
r += r * rmod * lfo1; //worth making all these local variables?
|
|
|
|
|
|
|
|
|
|
outputs_r[sampleFrames - frames] = static_cast<int16_t>(r * 0x8000); |
|
|
|
|
outputs_l[sampleFrames - frames] = static_cast<int16_t>(l * 0x8000); |
|
|
|
|
V->env = V->env * V->dec; //envelope
|
|
|
|
|
|
|
|
|
|
//if(x>0.0f) { x -= od * x * x; if(x < -V->env) x = -V->env; } //+= 0.5f * x * x; } //overdrive
|
|
|
|
|
|
|
|
|
|
//l += V->outl * x;
|
|
|
|
|
//r += V->outr * x;
|
|
|
|
|
|
|
|
|
|
V++; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
tl += tfrq * (l - tl); //treble boost
|
|
|
|
|
tr += tfrq * (r - tr); |
|
|
|
|
r += treb * (r - tr); |
|
|
|
|
l += treb * (l - tl); |
|
|
|
|
|
|
|
|
|
lfo0 += dlfo * lfo1; //LFO for tremolo and autopan
|
|
|
|
|
lfo1 -= dlfo * lfo0; |
|
|
|
|
l += l * lmod * lfo1; |
|
|
|
|
r += r * rmod * lfo1; //worth making all these local variables?
|
|
|
|
|
|
|
|
|
|
outputs_l[v] = int16_t(l * 0xFFFF) >> REDUCE_LOUDNESS; |
|
|
|
|
outputs_r[v] = int16_t(r * 0xFFFF) >> REDUCE_LOUDNESS; |
|
|
|
|
*/ |
|
|
|
|
|
|
|
|
|
outputs_l[v] = i >> REDUCE_LOUDNESS; |
|
|
|
|
outputs_r[v] = i >> REDUCE_LOUDNESS; |
|
|
|
|
} |
|
|
|
|
/*
|
|
|
|
|
if (frame < sampleFrames) |
|
|
|
|
{ |
|
|
|
|
if (activevoices == 0 && programs[curProgram].param[4] > 0.5f) |
|
|
|
@ -397,16 +392,20 @@ void mdaEPiano::process(int16_t *outputs_r, int16_t *outputs_l, int32_t sampleFr |
|
|
|
|
lfo0 = -0.7071f; //reset LFO phase - good idea?
|
|
|
|
|
lfo1 = 0.7071f; |
|
|
|
|
} |
|
|
|
|
int32_t note = notes[event++]; |
|
|
|
|
int32_t vel = notes[event++]; |
|
|
|
|
noteOn(note, vel); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
*/ |
|
|
|
|
if (fabs(tl) < 1.0e-10) tl = 0.0f; //anti-denormal
|
|
|
|
|
if (fabs(tr) < 1.0e-10) tr = 0.0f; |
|
|
|
|
|
|
|
|
|
for (v = 0; v < activevoices; v++) if (voice[v].env < SILENCE) voice[v] = voice[--activevoices]; |
|
|
|
|
notes[0] = EVENTS_DONE; //mark events buffer as done
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
for (v = 0; v < sampleFrames; v++) |
|
|
|
|
{ |
|
|
|
|
outputs_r[v] = int16_t(o0[v] * 0xFFFF) >> REDUCE_LOUDNESS; |
|
|
|
|
outputs_l[v] = int16_t(o1[v] * 0xFFFF) >> REDUCE_LOUDNESS; |
|
|
|
|
} |
|
|
|
|
*/ |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void mdaEPiano::noteOn(int32_t note, int32_t velocity) |
|
|
|
@ -439,7 +438,7 @@ void mdaEPiano::noteOn(int32_t note, int32_t velocity) |
|
|
|
|
if (note > 60) l += stretch * (float)k; //stretch
|
|
|
|
|
|
|
|
|
|
s = size; |
|
|
|
|
//if(velocity > 40) s += (VstInt32)(sizevel * (float)(velocity - 40)); - no velocity to hardness in ePiano
|
|
|
|
|
//if(velocity > 40) s += (int32_t)(sizevel * (float)(velocity - 40)); - no velocity to hardness in ePiano
|
|
|
|
|
|
|
|
|
|
k = 0; |
|
|
|
|
while (note > (kgrp[k].high + s)) k += 3; //find keygroup
|
|
|
|
@ -489,20 +488,15 @@ void mdaEPiano::noteOn(int32_t note, int32_t velocity) |
|
|
|
|
bool mdaEPiano::processMidiMessage(uint8_t type, uint8_t data1, uint8_t data2) |
|
|
|
|
{ |
|
|
|
|
float* param = programs[curProgram].param; |
|
|
|
|
int32_t npos = 0; |
|
|
|
|
|
|
|
|
|
switch (type) |
|
|
|
|
{ |
|
|
|
|
case 0x80: //note off
|
|
|
|
|
notes[npos++] = 0; //delta
|
|
|
|
|
notes[npos++] = data1 & 0x7F; //note
|
|
|
|
|
notes[npos++] = 0; //vel
|
|
|
|
|
noteOn(data1 & 0x7F, 0); |
|
|
|
|
break; |
|
|
|
|
|
|
|
|
|
case 0x90: //note on
|
|
|
|
|
notes[npos++] = 0; //delta
|
|
|
|
|
notes[npos++] = data1 & 0x7F; //note
|
|
|
|
|
notes[npos++] = data2 & 0x7F; //vel
|
|
|
|
|
noteOn(data1 & 0x7F, data2 & 0x7F); |
|
|
|
|
break; |
|
|
|
|
|
|
|
|
|
case 0xB0: //controller
|
|
|
|
@ -527,9 +521,7 @@ bool mdaEPiano::processMidiMessage(uint8_t type, uint8_t data1, uint8_t data2) |
|
|
|
|
sustain = data2 & 0x40; |
|
|
|
|
if (sustain == 0) |
|
|
|
|
{ |
|
|
|
|
notes[npos++] = 0; |
|
|
|
|
notes[npos++] = SUSTAIN; //end all sustained notes
|
|
|
|
|
notes[npos++] = 0; |
|
|
|
|
noteOn(SUSTAIN, 0); //end all sustained notes
|
|
|
|
|
} |
|
|
|
|
break; |
|
|
|
|
|
|
|
|
@ -551,11 +543,6 @@ bool mdaEPiano::processMidiMessage(uint8_t type, uint8_t data1, uint8_t data2) |
|
|
|
|
default: break; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (npos > EVENTBUFFER) |
|
|
|
|
npos -= 3; //discard events if buffer full!!
|
|
|
|
|
|
|
|
|
|
notes[npos] = EVENTS_DONE; |
|
|
|
|
|
|
|
|
|
return (true); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -639,4 +626,3 @@ bool mdaEPiano::processMidiMessage(uint8_t type, uint8_t data1, uint8_t data2) |
|
|
|
|
return 1; |
|
|
|
|
} |
|
|
|
|
*/ |
|
|
|
|
|
|
|
|
|