From 071d50b99ca38de1676d34c22d09e672d5fb7831 Mon Sep 17 00:00:00 2001 From: Holger Wirtz Date: Tue, 28 Aug 2018 10:57:22 +0200 Subject: [PATCH] Added missing methods and functions. Everything is ready for a first try. --- MicroMDAPiano.ino | 3 +- mdaEPiano.cpp | 477 ++++++++++++++++++++++++---------------------- mdaEPiano.h | 4 +- 3 files changed, 246 insertions(+), 238 deletions(-) diff --git a/MicroMDAPiano.ino b/MicroMDAPiano.ino index 73905c5..a2ff248 100644 --- a/MicroMDAPiano.ino +++ b/MicroMDAPiano.ino @@ -420,8 +420,7 @@ bool queue_midi_event(uint8_t type, uint8_t data1, uint8_t data2) } else #endif - // ret = dexed->processMidiMessage(type, data1, data2); // TODO!!! - ; + ret = ep->processMidiMessage(type, data1, data2); #ifdef MASTER_KEY_MIDI } diff --git a/mdaEPiano.cpp b/mdaEPiano.cpp index e9c1e6f..ff7ac2d 100644 --- a/mdaEPiano.cpp +++ b/mdaEPiano.cpp @@ -13,13 +13,13 @@ 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]; - if(programs) + if (programs) { //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++, "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); @@ -31,16 +31,16 @@ mdaEPiano::mdaEPiano() // mdaEPiano::mdaEPiano(audioMasterCallback audioMaster) setProgram(0); } -/* - if(audioMaster) - { - setNumInputs(0); - setNumOutputs(NOUTS); - canProcessReplacing(); - isSynth(); - setUniqueID('MDAe'); /// - } -*/ + /* + if(audioMaster) + { + setNumInputs(0); + setNumOutputs(NOUTS); + canProcessReplacing(); + isSynth(); + setUniqueID('MDAe'); /// + } + */ waves = (short*)epianoData; //Waveform data and keymapping @@ -54,44 +54,44 @@ mdaEPiano::mdaEPiano() // mdaEPiano::mdaEPiano(audioMasterCallback audioMaster) kgrp[21].root = 79; kgrp[21].high = 81; //G4 kgrp[24].root = 84; kgrp[24].high = 87; //C5 kgrp[27].root = 91; kgrp[27].high = 93; //G5 - kgrp[30].root = 96; kgrp[30].high =999; //C6 - - 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[2].pos = 16249; kgrp[2].end = 34565; kgrp[2].loop = 6398; - 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[5].pos = 45761; kgrp[5].end = 65211; kgrp[5].loop = 5245; - 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[8].pos = 78627; kgrp[8].end = 100387; kgrp[8].loop = 6368; - 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[11].pos = 127662; kgrp[11].end = 144113; kgrp[11].loop = 3099; - 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[14].pos = 173108; kgrp[14].end = 192734; kgrp[14].loop = 2937; - 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[17].pos = 218996; kgrp[17].end = 233801; kgrp[17].loop = 2285; - 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[20].pos = 265288; kgrp[20].end = 282255; kgrp[20].loop = 3609; - 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[23].pos = 312567; kgrp[23].end = 330200; kgrp[23].loop = 2283; - 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[26].pos = 365676; kgrp[26].end = 383661; kgrp[26].loop = 5225; - kgrp[27].pos = 383662; kgrp[27].end = 393372; kgrp[27].loop = 2811; + kgrp[30].root = 96; kgrp[30].high = 999; //C6 + + 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[2].pos = 16249; kgrp[2].end = 34565; kgrp[2].loop = 6398; + 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[5].pos = 45761; kgrp[5].end = 65211; kgrp[5].loop = 5245; + 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[8].pos = 78627; kgrp[8].end = 100387; kgrp[8].loop = 6368; + 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[11].pos = 127662; kgrp[11].end = 144113; kgrp[11].loop = 3099; + 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[14].pos = 173108; kgrp[14].end = 192734; kgrp[14].loop = 2937; + 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[17].pos = 218996; kgrp[17].end = 233801; kgrp[17].loop = 2285; + 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[20].pos = 265288; kgrp[20].end = 282255; kgrp[20].loop = 3609; + 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[23].pos = 312567; kgrp[23].end = 330200; kgrp[23].loop = 2283; + 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[26].pos = 365676; kgrp[26].end = 383661; kgrp[26].loop = 5225; + 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[29].pos = 393373; kgrp[29].end = 406045; kgrp[29].loop = 4522; - kgrp[30].pos = 406046; kgrp[30].end = 414486; kgrp[30].loop = 2306; + 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[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... - for(int32_t k=0; k<28; k++) + for (int32_t k = 0; k < 28; k++) { int32_t p0 = kgrp[k].end; int32_t p1 = kgrp[k].end - kgrp[k].loop; @@ -99,7 +99,7 @@ mdaEPiano::mdaEPiano() // mdaEPiano::mdaEPiano(audioMasterCallback audioMaster) float xf = 1.0f; 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]); p0--; @@ -109,7 +109,7 @@ mdaEPiano::mdaEPiano() // mdaEPiano::mdaEPiano(audioMasterCallback audioMaster) } //initialise... - for(int32_t v=0; v 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); 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 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]; poly = 1 + (int32_t)(31.9f * param[8]); fine = param[9] - 0.5f; @@ -154,9 +154,9 @@ void mdaEPiano::update() //parameter change void mdaEPiano::resume() -{ +{ //Fs = getSampleRate(); - Fs=SAMPLE_RATE; + Fs = SAMPLE_RATE; iFs = 1.0f / Fs; 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... { - if(programs) delete [] programs; + if (programs) delete [] programs; } void mdaEPiano::setProgram(int32_t program) { - curProgram = program; - update(); + curProgram = program; + 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, - 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); 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[6] = p6; programs[p].param[7] = p7; 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::getProgramName(char *name) { strcpy(name, programs[curProgram].name); } -void mdaEPiano::setBlockSize(int32_t blockSize) { AudioEffectX::setBlockSize(blockSize); } -bool mdaEPiano::getEffectName(char* name) { strcpy(name, "ePiano"); return true; } -bool mdaEPiano::getVendorString(char* text) { strcpy(text, "mda"); return true; } -bool mdaEPiano::getProductString(char* text) { strcpy(text, "mda ePiano"); return true; } + void mdaEPiano::setProgramName(char *name) { strcpy(programs[curProgram].name, name); } + void mdaEPiano::getProgramName(char *name) { strcpy(name, programs[curProgram].name); } + void mdaEPiano::setBlockSize(int32_t blockSize) { AudioEffectX::setBlockSize(blockSize); } + bool mdaEPiano::getEffectName(char* name) { strcpy(name, "ePiano"); 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::getOutputProperties(int32_t index, VstPinProperties* properties) -{ + bool mdaEPiano::getOutputProperties(int32_t index, VstPinProperties* properties) + { if(indexlabel, "ePiano"); @@ -221,51 +223,51 @@ bool mdaEPiano::getOutputProperties(int32_t index, VstPinProperties* properties) return true; } 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) { strcpy(text, programs[index].name); return true; } return false; -} + } -bool mdaEPiano::copyProgram(int32_t destination) -{ + bool mdaEPiano::copyProgram(int32_t destination) + { if(destination 0.5f) + + case 4: if(param[index] > 0.5f) sprintf(string, "Trem %.0f", 200.0f * param[index] - 100.0f); else 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 8: sprintf(string, "%d", poly); 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; strcpy(text, (char *)string); -} + } -void mdaEPiano::getParameterLabel(int32_t index, char *label) -{ + void mdaEPiano::getParameterLabel(int32_t index, char *label) + { switch(index) { case 5: strcpy(label, "Hz"); break; case 8: strcpy(label, "voices"); break; - case 9: + case 9: case 10: strcpy(label, "cents"); break; default: strcpy(label, "%"); } -} + } -void mdaEPiano::guiGetDisplay(int32_t index, char *label) -{ + void mdaEPiano::guiGetDisplay(int32_t index, char *label) + { getParameterName(index, label); strcat(label, " = "); getParameterDisplay(index, label + strlen(label)); getParameterLabel(index, label + strlen(label)); -} + } */ void mdaEPiano::process(int16_t **outputs_r, int16_t **outputs_l, int32_t sampleFrames) { - int16_t* out_l = outputs_r[0]; - int16_t* out_r = outputs_l[0]; - int32_t event=0, frame=0, frames, v; - float x, l, r, od=overdrive; + int16_t* out_l = outputs_r[0]; + int16_t* out_r = outputs_l[0]; + int32_t event = 0, frame = 0, frames, v; + float x, l, r, od = overdrive; int32_t i; - while(framesampleFrames) frames = sampleFrames; + if (frames > sampleFrames) frames = sampleFrames; frames -= frame; frame += frames; - while(--frames>=0) + while (--frames >= 0) { VOICE *V = voice; l = r = 0.0f; - for(v=0; vfrac += V->delta; //integer-based linear interpolation V->pos += V->frac >> 16; 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 = (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 - 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; 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(l * 0x8000); - *out_l++ += static_cast(r * 0x8000); - } - - if(frame 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); + *out_r++ = static_cast(l * 0x8000); + *out_l++ = static_cast(r * 0x8000); } - } - if(fabs(tl)<1.0e-10) tl = 0.0f; //anti-denormal - if(fabs(tr)<1.0e-10) tr = 0.0f; - - for(v=0; vsampleFrames) frames = sampleFrames; - frames -= frame; - frame += frames; - while(--frames>=0) + if (frame < sampleFrames) { - VOICE *V = voice; - l = r = 0.0f; - - for(v=0; v 0.5f) { - 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; if(x < -V->env) x = -V->env; } //+= 0.5f * x * x; } //overdrive - - l += V->outl * x; - r += V->outr * x; - - V++; + lfo0 = -0.7071f; //reset LFO phase - good idea? + lfo1 = 0.7071f; } - 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 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 0) + float l = 99.0f; + int32_t v, vl = 0, k, s; + + if (velocity > 0) { - if(activevoices < poly) //add a note + if (activevoices < poly) //add a note { vl = activevoices; activevoices++; @@ -485,69 +421,143 @@ void mdaEPiano::noteOn(int32_t note, int32_t velocity) } else //steal a note { - for(v=0; v 60) l += stretch * (float)k; //stretch + if (note > 60) l += stretch * (float)k; //stretch 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; - 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 = 32000.0f * iFs * (float)exp(0.05776226505 * l); voice[vl].delta = (int32_t)(65536.0f * l); voice[vl].frac = 0; - if(velocity > 48) k++; //mid velocity sample - if(velocity > 80) k++; //high velocity sample + if (velocity > 48) k++; //mid velocity sample + if (velocity > 80) k++; //high velocity sample voice[vl].pos = kgrp[k].pos; voice[vl].end = kgrp[k].end - 1; voice[vl].loop = kgrp[k].loop; 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 - if(l < (55.0f + 0.4f * (float)note)) l = 55.0f + 0.4f * (float)note; - if(l > 210.0f) l = 210.0f; + if (l < (55.0f + 0.4f * (float)note)) l = 55.0f + 0.4f * (float)note; + if (l > 210.0f) l = 210.0f; voice[vl].ff = l * l * iFs; voice[vl].note = note; //note->pan - if(note < 12) note = 12; - if(note > 108) note = 108; + if (note < 12) note = 12; + if (note > 108) note = 108; l = volume; voice[vl].outr = l + l * width * (float)(note - 60); 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])); } else //note off { - for(v=0; v 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; int32_t npos=0; @@ -556,7 +566,7 @@ int32_t mdaEPiano::processEvents() if((ev->events[i])->type != kVstMidiType) continue; VstMidiEvent* event = (VstMidiEvent*)ev->events[i]; char* midiData = event->midiData; - + switch(midiData[0] & 0xf0) //status byte (all channels) { case 0x80: //note off @@ -583,11 +593,11 @@ int32_t mdaEPiano::processEvents() } break; - + case 0x07: //volume volume = 0.00002f * (float)(midiData[2] * midiData[2]); break; - + case 0x40: //sustain pedal case 0x42: //sustenuto pedal sustain = midiData[2] & 0x40; @@ -600,8 +610,8 @@ int32_t mdaEPiano::processEvents() break; default: //all notes off - if(midiData[1]>0x7A) - { + if(midiData[1]>0x7A) + { for(int32_t v=0; v