summaryrefslogtreecommitdiff
path: root/muse_qt4_evolution/synti/zynaddsubfx/Effects/Echo.C
diff options
context:
space:
mode:
Diffstat (limited to 'muse_qt4_evolution/synti/zynaddsubfx/Effects/Echo.C')
-rw-r--r--muse_qt4_evolution/synti/zynaddsubfx/Effects/Echo.C240
1 files changed, 240 insertions, 0 deletions
diff --git a/muse_qt4_evolution/synti/zynaddsubfx/Effects/Echo.C b/muse_qt4_evolution/synti/zynaddsubfx/Effects/Echo.C
new file mode 100644
index 00000000..a35ee1ba
--- /dev/null
+++ b/muse_qt4_evolution/synti/zynaddsubfx/Effects/Echo.C
@@ -0,0 +1,240 @@
+/*
+ ZynAddSubFX - a software synthesizer
+
+ Echo.C - Echo effect
+ 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 <stdlib.h>
+#include <math.h>
+#include "Echo.h"
+
+Echo::Echo(int insertion_,REALTYPE *efxoutl_,REALTYPE *efxoutr_){
+ efxoutl=efxoutl_;
+ efxoutr=efxoutr_;
+ filterpars=NULL;
+
+ insertion=insertion_;
+ //default values
+ Ppreset=0;
+ Pvolume=50;
+ Ppanning=64;
+ Pdelay=60;
+ Plrdelay=100;
+ Plrcross=100;
+ Pfb=40;
+ Phidamp=60;
+
+ ldelay=NULL;
+ rdelay=NULL;
+ lrdelay=0;
+
+ setpreset(Ppreset);
+ cleanup();
+};
+
+Echo::~Echo(){
+ delete[] ldelay;
+ delete[] rdelay;
+};
+
+/*
+ * Cleanup the effect
+ */
+void Echo::cleanup(){
+ int i;
+ for (i=0;i<dl;i++) ldelay[i]=0.0;
+ for (i=0;i<dr;i++) rdelay[i]=0.0;
+ oldl=0.0;
+ oldr=0.0;
+};
+
+
+/*
+ * Initialize the delays
+ */
+void Echo::initdelays(){
+ kl=0;kr=0;
+ dl=delay-lrdelay;if (dl<1) dl=1;
+ dr=delay+lrdelay;if (dr<1) dr=1;
+
+ if (ldelay!=NULL) delete [] ldelay;
+ if (rdelay!=NULL) delete [] rdelay;
+ ldelay=new REALTYPE[dl];
+ rdelay=new REALTYPE[dr];
+
+ cleanup();
+};
+
+/*
+ * Effect output
+ */
+void Echo::out(REALTYPE *smpsl,REALTYPE *smpsr){
+ int i;
+ REALTYPE l,r,ldl,rdl;
+
+ for (i=0;i<SOUND_BUFFER_SIZE;i++){
+ ldl=ldelay[kl];
+ rdl=rdelay[kr];
+ l=ldl*(1.0-lrcross)+rdl*lrcross;
+ r=rdl*(1.0-lrcross)+ldl*lrcross;
+ ldl=l;rdl=r;
+
+ efxoutl[i]=ldl*2.0;
+ efxoutr[i]=rdl*2.0;
+ ldl=smpsl[i]*panning-ldl*fb;
+ rdl=smpsr[i]*(1.0-panning)-rdl*fb;
+
+ //LowPass Filter
+ ldelay[kl]=ldl=ldl*hidamp+oldl*(1.0-hidamp);
+ rdelay[kr]=rdl=rdl*hidamp+oldr*(1.0-hidamp);
+ oldl=ldl;
+ oldr=rdl;
+
+ if (++kl>=dl) kl=0;
+ if (++kr>=dr) kr=0;
+ };
+
+};
+
+
+/*
+ * Parameter control
+ */
+void Echo::setvolume(unsigned char Pvolume){
+ this->Pvolume=Pvolume;
+
+ if (insertion==0) {
+ outvolume=pow(0.01,(1.0-Pvolume/127.0))*4.0;
+ volume=1.0;
+ } else {
+ volume=outvolume=Pvolume/127.0;
+ };
+ if (Pvolume==0) cleanup();
+
+};
+
+void Echo::setpanning(unsigned char Ppanning){
+ this->Ppanning=Ppanning;
+ panning=(Ppanning+0.5)/127.0;
+};
+
+void Echo::setdelay(unsigned char Pdelay){
+ this->Pdelay=Pdelay;
+ delay=1+(int)(Pdelay/127.0*SAMPLE_RATE*1.5);//0 .. 1.5 sec
+ initdelays();
+};
+
+void Echo::setlrdelay(unsigned char Plrdelay){
+ REALTYPE tmp;
+ this->Plrdelay=Plrdelay;
+ tmp=(pow(2,fabs(Plrdelay-64.0)/64.0*9)-1.0)/1000.0*SAMPLE_RATE;
+ if (Plrdelay<64.0) tmp=-tmp;
+ lrdelay=(int) tmp;
+ initdelays();
+};
+
+void Echo::setlrcross(unsigned char Plrcross){
+ this->Plrcross=Plrcross;
+ lrcross=Plrcross/127.0*1.0;
+};
+
+void Echo::setfb(unsigned char Pfb){
+ this->Pfb=Pfb;
+ fb=Pfb/128.0;
+};
+
+void Echo::sethidamp(unsigned char Phidamp){
+ this->Phidamp=Phidamp;
+ hidamp=1.0-Phidamp/127.0;
+};
+
+void Echo::setpreset(unsigned char npreset){
+ const int PRESET_SIZE=7;
+ const int NUM_PRESETS=9;
+ unsigned char presets[NUM_PRESETS][PRESET_SIZE]={
+ //Echo 1
+ {67,64,35,64,30,59,0},
+ //Echo 2
+ {67,64,21,64,30,59,0},
+ //Echo 3
+ {67,75,60,64,30,59,10},
+ //Simple Echo
+ {67,60,44,64,30,0,0},
+ //Canyon
+ {67,60,102,50,30,82,48},
+ //Panning Echo 1
+ {67,64,44,17,0,82,24},
+ //Panning Echo 2
+ {81,60,46,118,100,68,18},
+ //Panning Echo 3
+ {81,60,26,100,127,67,36},
+ //Feedback Echo
+ {62,64,28,64,100,90,55}};
+
+
+ if (npreset>=NUM_PRESETS) npreset=NUM_PRESETS-1;
+ for (int n=0;n<PRESET_SIZE;n++) changepar(n,presets[npreset][n]);
+ if (insertion!=0) changepar(0,presets[npreset][0]/2);//lower the volume if this is insertion effect
+ Ppreset=npreset;
+};
+
+
+void Echo::changepar(int npar,unsigned char value){
+ switch (npar){
+ case 0: setvolume(value);
+ break;
+ case 1: setpanning(value);
+ break;
+ case 2: setdelay(value);
+ break;
+ case 3: setlrdelay(value);
+ break;
+ case 4: setlrcross(value);
+ break;
+ case 5: setfb(value);
+ break;
+ case 6: sethidamp(value);
+ break;
+ };
+};
+
+unsigned char Echo::getpar(int npar){
+ switch (npar){
+ case 0: return(Pvolume);
+ break;
+ case 1: return(Ppanning);
+ break;
+ case 2: return(Pdelay);
+ break;
+ case 3: return(Plrdelay);
+ break;
+ case 4: return(Plrcross);
+ break;
+ case 5: return(Pfb);
+ break;
+ case 6: return(Phidamp);
+ break;
+ };
+ return(0);//in case of bogus parameter number
+};
+
+
+
+