summaryrefslogtreecommitdiff
path: root/attic/muse_qt4_evolution/synti/zynaddsubfx/Synth/Envelope.C
diff options
context:
space:
mode:
Diffstat (limited to 'attic/muse_qt4_evolution/synti/zynaddsubfx/Synth/Envelope.C')
-rw-r--r--attic/muse_qt4_evolution/synti/zynaddsubfx/Synth/Envelope.C165
1 files changed, 165 insertions, 0 deletions
diff --git a/attic/muse_qt4_evolution/synti/zynaddsubfx/Synth/Envelope.C b/attic/muse_qt4_evolution/synti/zynaddsubfx/Synth/Envelope.C
new file mode 100644
index 00000000..a0194022
--- /dev/null
+++ b/attic/muse_qt4_evolution/synti/zynaddsubfx/Synth/Envelope.C
@@ -0,0 +1,165 @@
+/*
+ ZynAddSubFX - a software synthesizer
+
+ Envelope.C - Envelope implementation
+ Copyright (C) 2002-2005 Nasca Octavian Paul
+ Author: Nasca Octavian Paul
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of version 2 of the GNU General Public License
+ as published by the Free Software Foundation.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License (version 2) for more details.
+
+ You should have received a copy of the GNU General Public License (version 2)
+ along with this program; if not, write to the Free Software Foundation,
+ Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+*/
+
+#include <stdio.h>
+#include "Envelope.h"
+
+Envelope::Envelope(EnvelopeParams *envpars,REALTYPE basefreq){
+ int i;
+ envpoints=envpars->Penvpoints;
+ if (envpoints>MAX_ENVELOPE_POINTS) envpoints=MAX_ENVELOPE_POINTS;
+ envsustain=(envpars->Penvsustain==0)?-1:envpars->Penvsustain;
+ forcedrelase=envpars->Pforcedrelease;
+ envstretch=pow(440.0/basefreq,envpars->Penvstretch/64.0);
+ linearenvelope=envpars->Plinearenvelope;
+
+ if (envpars->Pfreemode==0) envpars->converttofree();
+
+ REALTYPE bufferdt=SOUND_BUFFER_SIZE/(REALTYPE)SAMPLE_RATE;
+
+ int mode=envpars->Envmode;
+
+ //for amplitude envelopes
+ if ((mode==1)&&(linearenvelope==0)) mode=2;//change to log envelope
+ if ((mode==2)&&(linearenvelope!=0)) mode=1;//change to linear
+
+ for (i=0;i<MAX_ENVELOPE_POINTS;i++) {
+ REALTYPE tmp=envpars->getdt(i)/1000.0*envstretch;
+ if (tmp>bufferdt) envdt[i]=bufferdt/tmp;
+ else envdt[i]=2.0;//any value larger than 1
+
+ switch (mode){
+ case 2:envval[i]=(1.0-envpars->Penvval[i]/127.0)*MIN_ENVELOPE_DB;
+ break;
+ case 3:envval[i]=(pow(2,6.0*fabs(envpars->Penvval[i]-64.0)/64.0)-1.0)*100.0;
+ if (envpars->Penvval[i]<64) envval[i]=-envval[i];
+ break;
+ case 4:envval[i]=(envpars->Penvval[i]-64.0)/64.0*6.0;//6 octaves (filtru)
+ break;
+ case 5:envval[i]=(envpars->Penvval[i]-64.0)/64.0*10;
+ break;
+ default:envval[i]=envpars->Penvval[i]/127.0;
+ };
+
+ };
+
+ envdt[0]=1.0;
+
+ currentpoint=1;//the envelope starts from 1
+ keyreleased=0;
+ t=0.0;
+ envfinish=0;
+ inct=envdt[1];
+ envoutval=0.0;
+};
+
+Envelope::~Envelope(){
+};
+
+
+/*
+ * Relase the key (note envelope)
+ */
+void Envelope::relasekey(){
+ if (keyreleased==1) return;
+ keyreleased=1;
+ if (forcedrelase!=0) t=0.0;
+};
+
+/*
+ * Envelope Output
+ */
+REALTYPE Envelope::envout(){
+ REALTYPE out;
+
+ if (envfinish!=0) {//if the envelope is finished
+ envoutval=envval[envpoints-1];
+ return(envoutval);
+ };
+ if ((currentpoint==envsustain+1)&&(keyreleased==0)) {//if it is sustaining now
+ envoutval=envval[envsustain];
+ return(envoutval);
+ };
+
+ if ((keyreleased!=0) && (forcedrelase!=0)){//do the forced release
+
+ int tmp=(envsustain<0) ? (envpoints-1):(envsustain+1);//if there is no sustain point, use the last point for release
+
+ if (envdt[tmp]<0.00000001) out=envval[tmp];
+ else out=envoutval+(envval[tmp]-envoutval)*t;
+ t+=envdt[tmp]*envstretch;
+
+ if (t>=1.0) {
+ currentpoint=envsustain+2;
+ forcedrelase=0;
+ t=0.0;
+ inct=envdt[currentpoint];
+ if ((currentpoint>=envpoints)||(envsustain<0)) envfinish=1;
+ };
+ return(out);
+ };
+ if (inct>=1.0) out=envval[currentpoint];
+ else out=envval[currentpoint-1]+(envval[currentpoint]-envval[currentpoint-1])*t;
+
+ t+=inct;
+ if (t>=1.0){
+ if (currentpoint>=envpoints-1) envfinish=1;
+ else currentpoint++;
+ t=0.0;
+ inct=envdt[currentpoint];
+ };
+
+ envoutval=out;
+ return (out);
+};
+
+/*
+ * Envelope Output (dB)
+ */
+REALTYPE Envelope::envout_dB(){
+ REALTYPE out;
+ if (linearenvelope!=0) return (envout());
+
+ if ((currentpoint==1)&&((keyreleased==0)||(forcedrelase==0))) {//first point is always lineary interpolated
+ REALTYPE v1=dB2rap(envval[0]);
+ REALTYPE v2=dB2rap(envval[1]);
+ out=v1+(v2-v1)*t;
+
+ t+=inct;
+ if (t>=1.0) {
+ t=0.0;
+ inct=envdt[2];
+ currentpoint++;
+ out=v2;
+ };
+
+ if (out>0.001) envoutval=rap2dB(out);
+ else envoutval=-40.0;
+ } else out=dB2rap(envout());
+
+ return(out);
+};
+
+int Envelope::finished(){
+ return(envfinish);
+};
+