Added missing methods and functions. Everything is ready for a first try.

master
Holger Wirtz 6 years ago
parent 088070cf4c
commit 071d50b99c
  1. 3
      MicroMDAPiano.ino
  2. 329
      mdaEPiano.cpp
  3. 4
      mdaEPiano.h

@ -420,8 +420,7 @@ bool queue_midi_event(uint8_t type, uint8_t data1, uint8_t data2)
} }
else else
#endif #endif
// ret = dexed->processMidiMessage(type, data1, data2); // TODO!!! ret = ep->processMidiMessage(type, data1, data2);
;
#ifdef MASTER_KEY_MIDI #ifdef MASTER_KEY_MIDI
} }

@ -13,13 +13,13 @@
mdaEPiano::mdaEPiano() // mdaEPiano::mdaEPiano(audioMasterCallback audioMaster) : AudioEffectX(audioMaster, NPROGS, NPARAMS) mdaEPiano::mdaEPiano() // mdaEPiano::mdaEPiano(audioMasterCallback audioMaster) : AudioEffectX(audioMaster, NPROGS, NPARAMS)
{ {
Fs = SAMPLE_RATE; iFs = 1.0f/Fs; //just in case... Fs = SAMPLE_RATE; iFs = 1.0f / Fs; //just in case...
programs = new mdaEPianoProgram[NPROGS]; programs = new mdaEPianoProgram[NPROGS];
if(programs) if (programs)
{ {
//fill patches... //fill patches...
int32_t i=0; int32_t i = 0;
fillpatch(i++, "Default", 0.500f, 0.500f, 0.500f, 0.500f, 0.500f, 0.650f, 0.250f, 0.500f, 0.50f, 0.500f, 0.146f, 0.000f); fillpatch(i++, "Default", 0.500f, 0.500f, 0.500f, 0.500f, 0.500f, 0.650f, 0.250f, 0.500f, 0.50f, 0.500f, 0.146f, 0.000f);
fillpatch(i++, "Bright", 0.500f, 0.500f, 1.000f, 0.800f, 0.500f, 0.650f, 0.250f, 0.500f, 0.50f, 0.500f, 0.146f, 0.500f); fillpatch(i++, "Bright", 0.500f, 0.500f, 1.000f, 0.800f, 0.500f, 0.650f, 0.250f, 0.500f, 0.50f, 0.500f, 0.146f, 0.500f);
fillpatch(i++, "Mellow", 0.500f, 0.500f, 0.000f, 0.000f, 0.500f, 0.650f, 0.250f, 0.500f, 0.50f, 0.500f, 0.246f, 0.000f); fillpatch(i++, "Mellow", 0.500f, 0.500f, 0.000f, 0.000f, 0.500f, 0.650f, 0.250f, 0.500f, 0.50f, 0.500f, 0.246f, 0.000f);
@ -31,7 +31,7 @@ mdaEPiano::mdaEPiano() // mdaEPiano::mdaEPiano(audioMasterCallback audioMaster)
setProgram(0); setProgram(0);
} }
/* /*
if(audioMaster) if(audioMaster)
{ {
setNumInputs(0); setNumInputs(0);
@ -40,7 +40,7 @@ mdaEPiano::mdaEPiano() // mdaEPiano::mdaEPiano(audioMasterCallback audioMaster)
isSynth(); isSynth();
setUniqueID('MDAe'); /// setUniqueID('MDAe'); ///
} }
*/ */
waves = (short*)epianoData; waves = (short*)epianoData;
//Waveform data and keymapping //Waveform data and keymapping
@ -54,7 +54,7 @@ mdaEPiano::mdaEPiano() // mdaEPiano::mdaEPiano(audioMasterCallback audioMaster)
kgrp[21].root = 79; kgrp[21].high = 81; //G4 kgrp[21].root = 79; kgrp[21].high = 81; //G4
kgrp[24].root = 84; kgrp[24].high = 87; //C5 kgrp[24].root = 84; kgrp[24].high = 87; //C5
kgrp[27].root = 91; kgrp[27].high = 93; //G5 kgrp[27].root = 91; kgrp[27].high = 93; //G5
kgrp[30].root = 96; kgrp[30].high =999; //C6 kgrp[30].root = 96; kgrp[30].high = 999; //C6
kgrp[0].pos = 0; kgrp[0].end = 8476; kgrp[0].loop = 4400; kgrp[0].pos = 0; kgrp[0].end = 8476; kgrp[0].loop = 4400;
kgrp[1].pos = 8477; kgrp[1].end = 16248; kgrp[1].loop = 4903; kgrp[1].pos = 8477; kgrp[1].end = 16248; kgrp[1].loop = 4903;
@ -91,7 +91,7 @@ mdaEPiano::mdaEPiano() // mdaEPiano::mdaEPiano(audioMasterCallback audioMaster)
kgrp[32].pos = 414487; kgrp[32].end = 422408; kgrp[32].loop = 2169; kgrp[32].pos = 414487; kgrp[32].end = 422408; kgrp[32].loop = 2169;
//extra xfade looping... //extra xfade looping...
for(int32_t k=0; k<28; k++) for (int32_t k = 0; k < 28; k++)
{ {
int32_t p0 = kgrp[k].end; int32_t p0 = kgrp[k].end;
int32_t p1 = kgrp[k].end - kgrp[k].loop; int32_t p1 = kgrp[k].end - kgrp[k].loop;
@ -99,7 +99,7 @@ mdaEPiano::mdaEPiano() // mdaEPiano::mdaEPiano(audioMasterCallback audioMaster)
float xf = 1.0f; float xf = 1.0f;
float dxf = -0.02f; float dxf = -0.02f;
while(xf > 0.0f) while (xf > 0.0f)
{ {
waves[p0] = (short)((1.0f - xf) * (float)waves[p0] + xf * (float)waves[p1]); waves[p0] = (short)((1.0f - xf) * (float)waves[p0] + xf * (float)waves[p1]);
p0--; p0--;
@ -109,7 +109,7 @@ mdaEPiano::mdaEPiano() // mdaEPiano::mdaEPiano(audioMasterCallback audioMaster)
} }
//initialise... //initialise...
for(int32_t v=0; v<NVOICES; v++) for (int32_t v = 0; v < NVOICES; v++)
{ {
voice[v].env = 0.0f; voice[v].env = 0.0f;
voice[v].dec = 0.99f; //all notes off voice[v].dec = 0.99f; //all notes off
@ -133,16 +133,16 @@ void mdaEPiano::update() //parameter change
size = (int32_t)(12.0f * param[2] - 6.0f); size = (int32_t)(12.0f * param[2] - 6.0f);
treb = 4.0f * param[3] * param[3] - 1.0f; //treble gain treb = 4.0f * param[3] * param[3] - 1.0f; //treble gain
if(param[3] > 0.5f) tfrq = 14000.0f; else tfrq = 5000.0f; //treble freq if (param[3] > 0.5f) tfrq = 14000.0f; else tfrq = 5000.0f; //treble freq
tfrq = 1.0f - (float)exp(-iFs * tfrq); tfrq = 1.0f - (float)exp(-iFs * tfrq);
rmod = lmod = param[4] + param[4] - 1.0f; //lfo depth rmod = lmod = param[4] + param[4] - 1.0f; //lfo depth
if(param[4] < 0.5f) rmod = -rmod; if (param[4] < 0.5f) rmod = -rmod;
dlfo = 6.283f * iFs * (float)exp(6.22f * param[5] - 2.61f); //lfo rate dlfo = 6.283f * iFs * (float)exp(6.22f * param[5] - 2.61f); //lfo rate
velsens = 1.0f + param[6] + param[6]; velsens = 1.0f + param[6] + param[6];
if(param[6] < 0.25f) velsens -= 0.75f - 3.0f * param[6]; if (param[6] < 0.25f) velsens -= 0.75f - 3.0f * param[6];
width = 0.03f * param[7]; width = 0.03f * param[7];
poly = 1 + (int32_t)(31.9f * param[8]); poly = 1 + (int32_t)(31.9f * param[8]);
@ -156,7 +156,7 @@ void mdaEPiano::update() //parameter change
void mdaEPiano::resume() void mdaEPiano::resume()
{ {
//Fs = getSampleRate(); //Fs = getSampleRate();
Fs=SAMPLE_RATE; Fs = SAMPLE_RATE;
iFs = 1.0f / Fs; iFs = 1.0f / Fs;
dlfo = 6.283f * iFs * (float)exp(6.22f * programs[curProgram].param[5] - 2.61f); //lfo rate dlfo = 6.283f * iFs * (float)exp(6.22f * programs[curProgram].param[5] - 2.61f); //lfo rate
@ -166,7 +166,7 @@ void mdaEPiano::resume()
mdaEPiano::~mdaEPiano () //destroy any buffers... mdaEPiano::~mdaEPiano () //destroy any buffers...
{ {
if(programs) delete [] programs; if (programs) delete [] programs;
} }
@ -189,7 +189,7 @@ void mdaEPiano::setParameter(int32_t index, float value)
void mdaEPiano::fillpatch(int32_t p, char *name, float p0, float p1, float p2, float p3, float p4, void mdaEPiano::fillpatch(int32_t p, char *name, float p0, float p1, float p2, float p3, float p4,
float p5, float p6, float p7, float p8, float p9, float p10,float p11) float p5, float p6, float p7, float p8, float p9, float p10, float p11)
{ {
strcpy(programs[p].name, name); strcpy(programs[p].name, name);
programs[p].param[0] = p0; programs[p].param[1] = p1; programs[p].param[0] = p0; programs[p].param[1] = p1;
@ -197,21 +197,23 @@ void mdaEPiano::fillpatch(int32_t p, char *name, float p0, float p1, float p2, f
programs[p].param[4] = p4; programs[p].param[5] = p5; programs[p].param[4] = p4; programs[p].param[5] = p5;
programs[p].param[6] = p6; programs[p].param[7] = p7; programs[p].param[6] = p6; programs[p].param[7] = p7;
programs[p].param[8] = p8; programs[p].param[9] = p9; programs[p].param[8] = p8; programs[p].param[9] = p9;
programs[p].param[10]= p10; programs[p].param[11] = p11; programs[p].param[10] = p10; programs[p].param[11] = p11;
} }
float mdaEPiano::getParameter(int32_t index) { return programs[curProgram].param[index]; } float mdaEPiano::getParameter(int32_t index) {
return programs[curProgram].param[index];
}
/* /*
void mdaEPiano::setProgramName(char *name) { strcpy(programs[curProgram].name, name); } void mdaEPiano::setProgramName(char *name) { strcpy(programs[curProgram].name, name); }
void mdaEPiano::getProgramName(char *name) { strcpy(name, programs[curProgram].name); } void mdaEPiano::getProgramName(char *name) { strcpy(name, programs[curProgram].name); }
void mdaEPiano::setBlockSize(int32_t blockSize) { AudioEffectX::setBlockSize(blockSize); } void mdaEPiano::setBlockSize(int32_t blockSize) { AudioEffectX::setBlockSize(blockSize); }
bool mdaEPiano::getEffectName(char* name) { strcpy(name, "ePiano"); return true; } bool mdaEPiano::getEffectName(char* name) { strcpy(name, "ePiano"); return true; }
bool mdaEPiano::getVendorString(char* text) { strcpy(text, "mda"); return true; } bool mdaEPiano::getVendorString(char* text) { strcpy(text, "mda"); return true; }
bool mdaEPiano::getProductString(char* text) { strcpy(text, "mda ePiano"); return true; } bool mdaEPiano::getProductString(char* text) { strcpy(text, "mda ePiano"); return true; }
bool mdaEPiano::getOutputProperties(int32_t index, VstPinProperties* properties) bool mdaEPiano::getOutputProperties(int32_t index, VstPinProperties* properties)
{ {
if(index<NOUTS) if(index<NOUTS)
{ {
if(index) sprintf(properties->label, "ePiano"); if(index) sprintf(properties->label, "ePiano");
@ -221,41 +223,41 @@ bool mdaEPiano::getOutputProperties(int32_t index, VstPinProperties* properties)
return true; return true;
} }
return false; return false;
} }
bool mdaEPiano::getProgramNameIndexed(int32_t category, int32_t index, char* text) bool mdaEPiano::getProgramNameIndexed(int32_t category, int32_t index, char* text)
{ {
if ((unsigned int)index < NPROGS) if ((unsigned int)index < NPROGS)
{ {
strcpy(text, programs[index].name); strcpy(text, programs[index].name);
return true; return true;
} }
return false; return false;
} }
bool mdaEPiano::copyProgram(int32_t destination) bool mdaEPiano::copyProgram(int32_t destination)
{ {
if(destination<NPROGS) if(destination<NPROGS)
{ {
programs[destination] = programs[curProgram]; programs[destination] = programs[curProgram];
return true; return true;
} }
return false; return false;
} }
int32_t mdaEPiano::canDo(char* text) int32_t mdaEPiano::canDo(char* text)
{ {
if(strcmp(text, "receiveVstEvents") == 0) return 1; if(strcmp(text, "receiveVstEvents") == 0) return 1;
if(strcmp(text, "receiveVstMidiEvent") == 0) return 1; if(strcmp(text, "receiveVstMidiEvent") == 0) return 1;
return -1; return -1;
} }
void mdaEPiano::getParameterName(int32_t index, char *label) void mdaEPiano::getParameterName(int32_t index, char *label)
{ {
switch (index) switch (index)
{ {
case 0: strcpy(label, "Envelope Decay"); break; case 0: strcpy(label, "Envelope Decay"); break;
@ -274,11 +276,11 @@ void mdaEPiano::getParameterName(int32_t index, char *label)
case 10: strcpy(label, "Random Tuning"); break; case 10: strcpy(label, "Random Tuning"); break;
default: strcpy(label, "Overdrive"); break; default: strcpy(label, "Overdrive"); break;
} }
} }
void mdaEPiano::getParameterDisplay(int32_t index, char *text) void mdaEPiano::getParameterDisplay(int32_t index, char *text)
{ {
char string[16]; char string[16];
float * param = programs[curProgram].param; float * param = programs[curProgram].param;
@ -302,11 +304,11 @@ void mdaEPiano::getParameterDisplay(int32_t index, char *text)
} }
string[8] = 0; string[8] = 0;
strcpy(text, (char *)string); strcpy(text, (char *)string);
} }
void mdaEPiano::getParameterLabel(int32_t index, char *label) void mdaEPiano::getParameterLabel(int32_t index, char *label)
{ {
switch(index) switch(index)
{ {
case 5: strcpy(label, "Hz"); break; case 5: strcpy(label, "Hz"); break;
@ -315,123 +317,55 @@ void mdaEPiano::getParameterLabel(int32_t index, char *label)
case 10: strcpy(label, "cents"); break; case 10: strcpy(label, "cents"); break;
default: strcpy(label, "%"); default: strcpy(label, "%");
} }
} }
void mdaEPiano::guiGetDisplay(int32_t index, char *label) void mdaEPiano::guiGetDisplay(int32_t index, char *label)
{ {
getParameterName(index, label); getParameterName(index, label);
strcat(label, " = "); strcat(label, " = ");
getParameterDisplay(index, label + strlen(label)); getParameterDisplay(index, label + strlen(label));
getParameterLabel(index, label + strlen(label)); getParameterLabel(index, label + strlen(label));
} }
*/ */
void mdaEPiano::process(int16_t **outputs_r, int16_t **outputs_l, int32_t sampleFrames) void mdaEPiano::process(int16_t **outputs_r, int16_t **outputs_l, int32_t sampleFrames)
{ {
int16_t* out_l = outputs_r[0]; int16_t* out_l = outputs_r[0];
int16_t* out_r = outputs_l[0]; int16_t* out_r = outputs_l[0];
int32_t event=0, frame=0, frames, v; int32_t event = 0, frame = 0, frames, v;
float x, l, r, od=overdrive; float x, l, r, od = overdrive;
int32_t i; int32_t i;
while(frame<sampleFrames) while (frame < sampleFrames)
{ {
frames = notes[event++]; frames = notes[event++];
if(frames>sampleFrames) frames = sampleFrames; if (frames > sampleFrames) frames = sampleFrames;
frames -= frame; frames -= frame;
frame += frames; frame += frames;
while(--frames>=0) while (--frames >= 0)
{ {
VOICE *V = voice; VOICE *V = voice;
l = r = 0.0f; l = r = 0.0f;
for(v=0; v<activevoices; v++) for (v = 0; v < activevoices; v++)
{ {
V->frac += V->delta; //integer-based linear interpolation V->frac += V->delta; //integer-based linear interpolation
V->pos += V->frac >> 16; V->pos += V->frac >> 16;
V->frac &= 0xFFFF; V->frac &= 0xFFFF;
if(V->pos > V->end) V->pos -= V->loop; if (V->pos > V->end) V->pos -= V->loop;
i = waves[V->pos]; i = waves[V->pos];
i = (i << 7) + (V->frac >> 9) * (waves[V->pos + 1] - i) + 0x40400000; i = (i << 7) + (V->frac >> 9) * (waves[V->pos + 1] - i) + 0x40400000;
x = V->env * (*(float *)&i - 3.0f); //fast int->float
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?
*out_r++ += static_cast<int16_t>(l * 0x8000);
*out_l++ += static_cast<int16_t>(r * 0x8000);
}
if(frame<sampleFrames)
{
if(activevoices == 0 && programs[curProgram].param[4] > 0.5f)
{ lfo0 = -0.7071f; lfo1 = 0.7071f; } //reset LFO phase - good idea?
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
}
void mdaEPiano::processReplacing(float **inputs, float **outputs, int32_t sampleFrames)
{
float* out0 = outputs[0];
float* out1 = outputs[1];
int32_t event=0, frame=0, frames, v;
float x, l, r, od=overdrive;
int32_t i;
while(frame<sampleFrames)
{
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++)
{
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 - 3.0f); //fast int->float
//x = V->env * (float)i / 32768.0f; x = V->env * (float(i) - 3.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 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 if (x > 0.0f) {
x -= od * x * x; //overdrive
if (x < -V->env) x = -V->env;
} //+= 0.5f * x * x; }
l += V->outl * x; l += V->outl * x;
r += V->outr * x; r += V->outr * x;
@ -448,36 +382,38 @@ void mdaEPiano::processReplacing(float **inputs, float **outputs, int32_t sample
l += l * lmod * lfo1; l += l * lmod * lfo1;
r += r * rmod * lfo1; //worth making all these local variables? r += r * rmod * lfo1; //worth making all these local variables?
*out0++ = l; *out_r++ = static_cast<int16_t>(l * 0x8000);
*out1++ = r; *out_l++ = static_cast<int16_t>(r * 0x8000);
} }
if(frame<sampleFrames) if (frame < sampleFrames)
{
if (activevoices == 0 && programs[curProgram].param[4] > 0.5f)
{ {
if(activevoices == 0 && programs[curProgram].param[4] > 0.5f) lfo0 = -0.7071f; //reset LFO phase - good idea?
{ lfo0 = -0.7071f; lfo1 = 0.7071f; } //reset LFO phase - good idea? lfo1 = 0.7071f;
}
int32_t note = notes[event++]; int32_t note = notes[event++];
int32_t vel = notes[event++]; int32_t vel = notes[event++];
noteOn(note, vel); noteOn(note, vel);
} }
} }
if(fabs(tl)<1.0e-10) tl = 0.0f; //anti-denormal if (fabs(tl) < 1.0e-10) tl = 0.0f; //anti-denormal
if(fabs(tr)<1.0e-10) tr = 0.0f; if (fabs(tr) < 1.0e-10) tr = 0.0f;
for(v=0; v<activevoices; v++) if(voice[v].env < SILENCE) voice[v] = voice[--activevoices]; for (v = 0; v < activevoices; v++) if (voice[v].env < SILENCE) voice[v] = voice[--activevoices];
notes[0] = EVENTS_DONE; //mark events buffer as done notes[0] = EVENTS_DONE; //mark events buffer as done
} }
void mdaEPiano::noteOn(int32_t note, int32_t velocity) void mdaEPiano::noteOn(int32_t note, int32_t velocity)
{ {
float * param = programs[curProgram].param; float * param = programs[curProgram].param;
float l=99.0f; float l = 99.0f;
int32_t v, vl=0, k, s; int32_t v, vl = 0, k, s;
if(velocity > 0) if (velocity > 0)
{ {
if(activevoices < poly) //add a note if (activevoices < poly) //add a note
{ {
vl = activevoices; vl = activevoices;
activevoices++; activevoices++;
@ -485,56 +421,59 @@ void mdaEPiano::noteOn(int32_t note, int32_t velocity)
} }
else //steal a note else //steal a note
{ {
for(v=0; v<poly; v++) //find quietest voice for (v = 0; v < poly; v++) //find quietest voice
{ {
if(voice[v].env < l) { l = voice[v].env; vl = v; } if (voice[v].env < l) {
l = voice[v].env;
vl = v;
}
} }
} }
k = (note - 60) * (note - 60); k = (note - 60) * (note - 60);
l = fine + random * ((float)(k % 13) - 6.5f); //random & fine tune l = fine + random * ((float)(k % 13) - 6.5f); //random & fine tune
if(note > 60) l += stretch * (float)k; //stretch if (note > 60) l += stretch * (float)k; //stretch
s = size; s = size;
//if(velocity > 40) s += (int32_t)(sizevel * (float)(velocity - 40)); - no velocity to hardness in ePiano //if(velocity > 40) s += (VstInt32)(sizevel * (float)(velocity - 40)); - no velocity to hardness in ePiano
k = 0; k = 0;
while(note > (kgrp[k].high + s)) k += 3; //find keygroup while (note > (kgrp[k].high + s)) k += 3; //find keygroup
l += (float)(note - kgrp[k].root); //pitch l += (float)(note - kgrp[k].root); //pitch
l = 32000.0f * iFs * (float)exp(0.05776226505 * l); l = 32000.0f * iFs * (float)exp(0.05776226505 * l);
voice[vl].delta = (int32_t)(65536.0f * l); voice[vl].delta = (int32_t)(65536.0f * l);
voice[vl].frac = 0; voice[vl].frac = 0;
if(velocity > 48) k++; //mid velocity sample if (velocity > 48) k++; //mid velocity sample
if(velocity > 80) k++; //high velocity sample if (velocity > 80) k++; //high velocity sample
voice[vl].pos = kgrp[k].pos; voice[vl].pos = kgrp[k].pos;
voice[vl].end = kgrp[k].end - 1; voice[vl].end = kgrp[k].end - 1;
voice[vl].loop = kgrp[k].loop; voice[vl].loop = kgrp[k].loop;
voice[vl].env = (3.0f + 2.0f * velsens) * (float)pow(0.0078f * velocity, velsens); //velocity voice[vl].env = (3.0f + 2.0f * velsens) * (float)pow(0.0078f * velocity, velsens); //velocity
if(note > 60) voice[vl].env *= (float)exp(0.01f * (float)(60 - note)); //new! high notes quieter if (note > 60) voice[vl].env *= (float)exp(0.01f * (float)(60 - note)); //new! high notes quieter
l = 50.0f + param[4] * param[4] * muff + muffvel * (float)(velocity - 64); //muffle l = 50.0f + param[4] * param[4] * muff + muffvel * (float)(velocity - 64); //muffle
if(l < (55.0f + 0.4f * (float)note)) l = 55.0f + 0.4f * (float)note; if (l < (55.0f + 0.4f * (float)note)) l = 55.0f + 0.4f * (float)note;
if(l > 210.0f) l = 210.0f; if (l > 210.0f) l = 210.0f;
voice[vl].ff = l * l * iFs; voice[vl].ff = l * l * iFs;
voice[vl].note = note; //note->pan voice[vl].note = note; //note->pan
if(note < 12) note = 12; if (note < 12) note = 12;
if(note > 108) note = 108; if (note > 108) note = 108;
l = volume; l = volume;
voice[vl].outr = l + l * width * (float)(note - 60); voice[vl].outr = l + l * width * (float)(note - 60);
voice[vl].outl = l + l - voice[vl].outr; voice[vl].outl = l + l - voice[vl].outr;
if(note < 44) note = 44; //limit max decay length if (note < 44) note = 44; //limit max decay length
voice[vl].dec = (float)exp(-iFs * exp(-1.0 + 0.03 * (double)note - 2.0f * param[0])); voice[vl].dec = (float)exp(-iFs * exp(-1.0 + 0.03 * (double)note - 2.0f * param[0]));
} }
else //note off else //note off
{ {
for(v=0; v<NVOICES; v++) if(voice[v].note==note) //any voices playing that note? for (v = 0; v < NVOICES; v++) if (voice[v].note == note) //any voices playing that note?
{ {
if(sustain==0) if (sustain == 0)
{ {
voice[v].dec = (float)exp(-iFs * exp(6.0 + 0.01 * (double)note - 5.0 * param[1])); voice[v].dec = (float)exp(-iFs * exp(6.0 + 0.01 * (double)note - 5.0 * param[1]));
} }
@ -543,11 +482,82 @@ void mdaEPiano::noteOn(int32_t note, int32_t velocity)
} }
} }
bool mdaEPiano::processMidiMessage(uint8_t type, uint8_t data1, uint8_t data2)
int32_t mdaEPiano::processEvents()
{ {
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
break;
case 0x90: //note on
notes[npos++] = 0; //delta
notes[npos++] = data1 & 0x7F; //note
notes[npos++] = data2 & 0x7F; //vel
break;
case 0xB0: //controller
switch (data1)
{
case 0x01: //mod wheel
modwhl = 0.0078f * (float)(data2);
if (modwhl > 0.05f) //over-ride pan/trem depth
{
rmod = lmod = modwhl; //lfo depth
if (param[4] < 0.5f) rmod = -rmod;
}
break;
case 0x07: //volume
volume = 0.00002f * (float)(data2 * data2);
break;
case 0x40: //sustain pedal
case 0x42: //sustenuto pedal
sustain = data2 & 0x40;
if (sustain == 0)
{
notes[npos++] = 0;
notes[npos++] = SUSTAIN; //end all sustained notes
notes[npos++] = 0;
}
break;
default: //all notes off
if (data1 > 0x7A)
{
for (int32_t v = 0; v < NVOICES; v++) voice[v].dec = 0.99f;
sustain = 0;
muff = 160.0f;
}
break;
}
break;
case 0xC0: //program change
if (data1 < NPROGS) setProgram(data1);
break;
default: break;
}
if (npos > EVENTBUFFER)
npos -= 3; //discard events if buffer full!!
notes[npos] = EVENTS_DONE;
return (true);
}
/* /*
int32_t mdaEPiano::processEvents()
{
float * param = programs[curProgram].param; float * param = programs[curProgram].param;
int32_t npos=0; int32_t npos=0;
@ -621,7 +631,8 @@ int32_t mdaEPiano::processEvents()
event++; //? event++; //?
} }
notes[npos] = EVENTS_DONE; notes[npos] = EVENTS_DONE;
*/
return 1; return 1;
} }
*/

@ -60,9 +60,7 @@ public:
~mdaEPiano(); ~mdaEPiano();
virtual void process(int16_t **outputs_r, int16_t **outputs_l, int32_t sampleFrames); virtual void process(int16_t **outputs_r, int16_t **outputs_l, int32_t sampleFrames);
virtual void processReplacing(float **inputs, float **outputs, int32_t sampleframes); virtual bool processMidiMessage(uint8_t type, uint8_t data1, uint8_t data2);
virtual int32_t processEvents(); // virtual int32_t processEvents(VstEvents* events);
virtual void setProgram(int32_t program); virtual void setProgram(int32_t program);
//virtual void setProgramName(char *name); //virtual void setProgramName(char *name);
//virtual void getProgramName(char *name); //virtual void getProgramName(char *name);

Loading…
Cancel
Save