@ -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 ;
}
}
*/