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. 477
      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,16 +31,16 @@ mdaEPiano::mdaEPiano() // mdaEPiano::mdaEPiano(audioMasterCallback audioMaster)
setProgram(0); setProgram(0);
} }
/* /*
if(audioMaster) if(audioMaster)
{ {
setNumInputs(0); setNumInputs(0);
setNumOutputs(NOUTS); setNumOutputs(NOUTS);
canProcessReplacing(); canProcessReplacing();
isSynth(); isSynth();
setUniqueID('MDAe'); /// setUniqueID('MDAe'); ///
} }
*/ */
waves = (short*)epianoData; waves = (short*)epianoData;
//Waveform data and keymapping //Waveform data and keymapping
@ -54,44 +54,44 @@ 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;
kgrp[2].pos = 16249; kgrp[2].end = 34565; kgrp[2].loop = 6398; kgrp[2].pos = 16249; kgrp[2].end = 34565; kgrp[2].loop = 6398;
kgrp[3].pos = 34566; kgrp[3].end = 41384; kgrp[3].loop = 3938; kgrp[3].pos = 34566; kgrp[3].end = 41384; kgrp[3].loop = 3938;
kgrp[4].pos = 41385; kgrp[4].end = 45760; kgrp[4].loop = 1633; //was 1636; kgrp[4].pos = 41385; kgrp[4].end = 45760; kgrp[4].loop = 1633; //was 1636;
kgrp[5].pos = 45761; kgrp[5].end = 65211; kgrp[5].loop = 5245; kgrp[5].pos = 45761; kgrp[5].end = 65211; kgrp[5].loop = 5245;
kgrp[6].pos = 65212; kgrp[6].end = 72897; kgrp[6].loop = 2937; kgrp[6].pos = 65212; kgrp[6].end = 72897; kgrp[6].loop = 2937;
kgrp[7].pos = 72898; kgrp[7].end = 78626; kgrp[7].loop = 2203; //was 2204; kgrp[7].pos = 72898; kgrp[7].end = 78626; kgrp[7].loop = 2203; //was 2204;
kgrp[8].pos = 78627; kgrp[8].end = 100387; kgrp[8].loop = 6368; kgrp[8].pos = 78627; kgrp[8].end = 100387; kgrp[8].loop = 6368;
kgrp[9].pos = 100388; kgrp[9].end = 116297; kgrp[9].loop = 10452; kgrp[9].pos = 100388; kgrp[9].end = 116297; kgrp[9].loop = 10452;
kgrp[10].pos = 116298; kgrp[10].end = 127661; kgrp[10].loop = 5217; //was 5220; kgrp[10].pos = 116298; kgrp[10].end = 127661; kgrp[10].loop = 5217; //was 5220;
kgrp[11].pos = 127662; kgrp[11].end = 144113; kgrp[11].loop = 3099; kgrp[11].pos = 127662; kgrp[11].end = 144113; kgrp[11].loop = 3099;
kgrp[12].pos = 144114; kgrp[12].end = 152863; kgrp[12].loop = 4284; kgrp[12].pos = 144114; kgrp[12].end = 152863; kgrp[12].loop = 4284;
kgrp[13].pos = 152864; kgrp[13].end = 173107; kgrp[13].loop = 3916; kgrp[13].pos = 152864; kgrp[13].end = 173107; kgrp[13].loop = 3916;
kgrp[14].pos = 173108; kgrp[14].end = 192734; kgrp[14].loop = 2937; kgrp[14].pos = 173108; kgrp[14].end = 192734; kgrp[14].loop = 2937;
kgrp[15].pos = 192735; kgrp[15].end = 204598; kgrp[15].loop = 4732; kgrp[15].pos = 192735; kgrp[15].end = 204598; kgrp[15].loop = 4732;
kgrp[16].pos = 204599; kgrp[16].end = 218995; kgrp[16].loop = 4733; kgrp[16].pos = 204599; kgrp[16].end = 218995; kgrp[16].loop = 4733;
kgrp[17].pos = 218996; kgrp[17].end = 233801; kgrp[17].loop = 2285; kgrp[17].pos = 218996; kgrp[17].end = 233801; kgrp[17].loop = 2285;
kgrp[18].pos = 233802; kgrp[18].end = 248011; kgrp[18].loop = 4098; kgrp[18].pos = 233802; kgrp[18].end = 248011; kgrp[18].loop = 4098;
kgrp[19].pos = 248012; kgrp[19].end = 265287; kgrp[19].loop = 4099; kgrp[19].pos = 248012; kgrp[19].end = 265287; kgrp[19].loop = 4099;
kgrp[20].pos = 265288; kgrp[20].end = 282255; kgrp[20].loop = 3609; kgrp[20].pos = 265288; kgrp[20].end = 282255; kgrp[20].loop = 3609;
kgrp[21].pos = 282256; kgrp[21].end = 293776; kgrp[21].loop = 2446; kgrp[21].pos = 282256; kgrp[21].end = 293776; kgrp[21].loop = 2446;
kgrp[22].pos = 293777; kgrp[22].end = 312566; kgrp[22].loop = 6278; kgrp[22].pos = 293777; kgrp[22].end = 312566; kgrp[22].loop = 6278;
kgrp[23].pos = 312567; kgrp[23].end = 330200; kgrp[23].loop = 2283; kgrp[23].pos = 312567; kgrp[23].end = 330200; kgrp[23].loop = 2283;
kgrp[24].pos = 330201; kgrp[24].end = 348889; kgrp[24].loop = 2689; kgrp[24].pos = 330201; kgrp[24].end = 348889; kgrp[24].loop = 2689;
kgrp[25].pos = 348890; kgrp[25].end = 365675; kgrp[25].loop = 4370; kgrp[25].pos = 348890; kgrp[25].end = 365675; kgrp[25].loop = 4370;
kgrp[26].pos = 365676; kgrp[26].end = 383661; kgrp[26].loop = 5225; kgrp[26].pos = 365676; kgrp[26].end = 383661; kgrp[26].loop = 5225;
kgrp[27].pos = 383662; kgrp[27].end = 393372; kgrp[27].loop = 2811; kgrp[27].pos = 383662; kgrp[27].end = 393372; kgrp[27].loop = 2811;
kgrp[28].pos = 383662; kgrp[28].end = 393372; kgrp[28].loop = 2811; //ghost kgrp[28].pos = 383662; kgrp[28].end = 393372; kgrp[28].loop = 2811; //ghost
kgrp[29].pos = 393373; kgrp[29].end = 406045; kgrp[29].loop = 4522; kgrp[29].pos = 393373; kgrp[29].end = 406045; kgrp[29].loop = 4522;
kgrp[30].pos = 406046; kgrp[30].end = 414486; kgrp[30].loop = 2306; kgrp[30].pos = 406046; kgrp[30].end = 414486; kgrp[30].loop = 2306;
kgrp[31].pos = 406046; kgrp[31].end = 414486; kgrp[31].loop = 2306; //ghost kgrp[31].pos = 406046; kgrp[31].end = 414486; kgrp[31].loop = 2306; //ghost
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
@ -124,26 +124,26 @@ mdaEPiano::mdaEPiano() // mdaEPiano::mdaEPiano(audioMasterCallback audioMaster)
guiUpdate = 0; guiUpdate = 0;
update(); update();
// suspend(); // suspend();
} }
void mdaEPiano::update() //parameter change void mdaEPiano::update() //parameter change
{ {
float * param = programs[curProgram].param; float * param = programs[curProgram].param;
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]);
fine = param[9] - 0.5f; fine = param[9] - 0.5f;
@ -154,9 +154,9 @@ 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,14 +166,14 @@ void mdaEPiano::resume()
mdaEPiano::~mdaEPiano () //destroy any buffers... mdaEPiano::~mdaEPiano () //destroy any buffers...
{ {
if(programs) delete [] programs; if (programs) delete [] programs;
} }
void mdaEPiano::setProgram(int32_t program) void mdaEPiano::setProgram(int32_t program)
{ {
curProgram = program; curProgram = program;
update(); update();
} }
@ -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,51 +223,51 @@ 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;
case 1: strcpy(label, "Envelope Release"); break; case 1: strcpy(label, "Envelope Release"); break;
case 2: strcpy(label, "Hardness"); break; case 2: strcpy(label, "Hardness"); break;
case 3: strcpy(label, "Treble Boost"); break; case 3: strcpy(label, "Treble Boost"); break;
case 4: strcpy(label, "Modulation"); break; case 4: strcpy(label, "Modulation"); break;
case 5: strcpy(label, "LFO Rate"); break; case 5: strcpy(label, "LFO Rate"); break;
case 6: strcpy(label, "Velocity Sense"); break; case 6: strcpy(label, "Velocity Sense"); break;
case 7: strcpy(label, "Stereo Width"); break; case 7: strcpy(label, "Stereo Width"); break;
case 8: strcpy(label, "Polyphony"); break; case 8: strcpy(label, "Polyphony"); break;
@ -274,26 +276,26 @@ 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;
switch(index) switch(index)
{ {
case 2: case 2:
case 3: case 3:
case 9: sprintf(string, "%.0f", 100.0f * param[index] - 50.0f); break; case 9: sprintf(string, "%.0f", 100.0f * param[index] - 50.0f); break;
case 4: if(param[index] > 0.5f) case 4: if(param[index] > 0.5f)
sprintf(string, "Trem %.0f", 200.0f * param[index] - 100.0f); sprintf(string, "Trem %.0f", 200.0f * param[index] - 100.0f);
else else
sprintf(string, "Pan %.0f", 100.0f - 200.0f * param[index]); break; sprintf(string, "Pan %.0f", 100.0f - 200.0f * param[index]); break;
case 5: sprintf(string, "%.2f", (float)exp(6.22f * param[5] - 2.61f)); break; //LFO Hz case 5: sprintf(string, "%.2f", (float)exp(6.22f * param[5] - 2.61f)); break; //LFO Hz
case 7: sprintf(string, "%.0f", 200.0f * param[index]); break; case 7: sprintf(string, "%.0f", 200.0f * param[index]); break;
case 8: sprintf(string, "%d", poly); break; case 8: sprintf(string, "%d", poly); break;
case 10: sprintf(string, "%.1f", 50.0f * param[index] * param[index]); break; case 10: sprintf(string, "%.1f", 50.0f * param[index] * param[index]); break;
@ -302,182 +304,116 @@ 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;
case 8: strcpy(label, "voices"); break; case 8: strcpy(label, "voices"); break;
case 9: case 9:
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 //x = V->env * (*(float *)&i - 3.0f); //fast int->float
x = V->env * (float(i) - 3.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;
V++; V++;
} }
tl += tfrq * (l - tl); //treble boost tl += tfrq * (l - tl); //treble boost
tr += tfrq * (r - tr); tr += tfrq * (r - tr);
r += treb * (r - tr); r += treb * (r - tr);
l += treb * (l - tl); l += treb * (l - tl);
lfo0 += dlfo * lfo1; //LFO for tremolo and autopan lfo0 += dlfo * lfo1; //LFO for tremolo and autopan
lfo1 -= dlfo * lfo0; lfo1 -= dlfo * lfo0;
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?
*out_r++ += static_cast<int16_t>(l * 0x8000); *out_r++ = static_cast<int16_t>(l * 0x8000);
*out_l++ += static_cast<int16_t>(r * 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) if (frame < sampleFrames)
{ {
VOICE *V = voice; if (activevoices == 0 && programs[curProgram].param[4] > 0.5f)
l = r = 0.0f;
for(v=0; v<activevoices; v++)
{ {
V->frac += V->delta; //integer-based linear interpolation lfo0 = -0.7071f; //reset LFO phase - good idea?
V->pos += V->frac >> 16; lfo1 = 0.7071f;
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; 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?
*out0++ = l;
*out1++ = r;
}
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 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,69 +421,143 @@ 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)
{ {
voice[v].dec = (float)exp(-iFs * exp(6.0 + 0.01 * (double)note - 5.0 * param[1])); if (sustain == 0)
{
voice[v].dec = (float)exp(-iFs * exp(6.0 + 0.01 * (double)note - 5.0 * param[1]));
}
else voice[v].note = SUSTAIN;
} }
else voice[v].note = SUSTAIN;
}
} }
} }
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;
@ -556,7 +566,7 @@ int32_t mdaEPiano::processEvents()
if((ev->events[i])->type != kVstMidiType) continue; if((ev->events[i])->type != kVstMidiType) continue;
VstMidiEvent* event = (VstMidiEvent*)ev->events[i]; VstMidiEvent* event = (VstMidiEvent*)ev->events[i];
char* midiData = event->midiData; char* midiData = event->midiData;
switch(midiData[0] & 0xf0) //status byte (all channels) switch(midiData[0] & 0xf0) //status byte (all channels)
{ {
case 0x80: //note off case 0x80: //note off
@ -583,11 +593,11 @@ int32_t mdaEPiano::processEvents()
} }
break; break;
case 0x07: //volume case 0x07: //volume
volume = 0.00002f * (float)(midiData[2] * midiData[2]); volume = 0.00002f * (float)(midiData[2] * midiData[2]);
break; break;
case 0x40: //sustain pedal case 0x40: //sustain pedal
case 0x42: //sustenuto pedal case 0x42: //sustenuto pedal
sustain = midiData[2] & 0x40; sustain = midiData[2] & 0x40;
@ -600,8 +610,8 @@ int32_t mdaEPiano::processEvents()
break; break;
default: //all notes off default: //all notes off
if(midiData[1]>0x7A) if(midiData[1]>0x7A)
{ {
for(int32_t v=0; v<NVOICES; v++) voice[v].dec=0.99f; for(int32_t v=0; v<NVOICES; v++) voice[v].dec=0.99f;
sustain = 0; sustain = 0;
muff = 160.0f; muff = 160.0f;
@ -613,7 +623,7 @@ int32_t mdaEPiano::processEvents()
case 0xC0: //program change case 0xC0: //program change
if(midiData[1]<NPROGS) setProgram(midiData[1]); if(midiData[1]<NPROGS) setProgram(midiData[1]);
break; break;
default: break; default: break;
} }
@ -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