commit 0e0e47e8cdeb83074cea60a0fc2df7ff6a2dd217
parent cac44090604c8582f8484ab999c7a8f70cc45c31
Author: fundamental <mark.d.mccurry@gmail.com>
Date: Sun, 2 May 2010 14:15:49 -0400
Merge branch 'master' into nio
Conflicts:
src/Effects/Effect.h
src/Effects/EffectMgr.cpp
src/Effects/EffectMgr.h
src/Samples/Sample.cpp
src/Samples/Sample.h
src/Tests/EchoTest.h
src/Tests/SampleTest.h
Diffstat:
35 files changed, 1041 insertions(+), 317 deletions(-)
diff --git a/AUTHORS.txt b/AUTHORS.txt
@@ -17,4 +17,5 @@ Contributors:
James Morris (Memory leaks in FLTK GUI)
Alan Calvert (Portions of New IO)
Stephen Parry (DSSI rebuild)
+ Ryan Billing (APhaser)
diff --git a/ChangeLog b/ChangeLog
@@ -989,3 +989,10 @@
14 Feb 2010 (Stephen Parry)
- DSSI Support Repaired
+14 Feb 2010 (Mark McCurry)
+ - Made the Echo attempt to adjust the delay instead of erasing it
+ when length is changed
+
+02 May 2010 (Mark McCurry)
+ - Merging in cleanup from effects and adding APhaser by Ryan Billing
+
diff --git a/HISTORY.txt b/HISTORY.txt
@@ -1,3 +1,13 @@
+2.4.1 (In Beta)
+ - Azerty layout
+ - XML bug fixes
+ - Vibrato/Unison additions
+ - Reverb rewrite
+ - DSSI support enabled
+ - Adding APhaser
+ - other bugfixes
+ - code cleanup
+
2.4.0 (21 Jun 2009)
- extended mono functionality
- legato mode
diff --git a/src/Effects/APhaser.cpp b/src/Effects/APhaser.cpp
@@ -0,0 +1,450 @@
+/*
+
+ APhaser.C - Approximate digital model of an analog JFET phaser.
+ Analog modeling implemented by Ryan Billing aka Transmogrifox.
+ November, 2009
+
+ Credit to:
+ ///////////////////
+ ZynAddSubFX - a software synthesizer
+
+ Phaser.C - Phaser effect
+ Copyright (C) 2002-2005 Nasca Octavian Paul
+ Author: Nasca Octavian Paul
+
+ Modified for rakarrack by Josep Andreu
+
+ DSP analog modeling theory & practice largely influenced by various CCRMA publications, particularly works by Julius O. Smith.
+ ////////////////////
+
+
+ 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 <cmath>
+#include "APhaser.h"
+#include <cstdio>
+#include <iostream>
+using namespace std;
+#define PHASER_LFO_SHAPE 2
+#define ONE_ 0.99999f // To prevent LFO ever reaching 1.0 for filter stability purposes
+#define ZERO_ 0.00001f // Same idea as above.
+
+Analog_Phaser::Analog_Phaser(const int & insertion_, REALTYPE *efxoutl_, REALTYPE *efxoutr_)
+ :Effect(insertion_, efxoutl_, efxoutr_, NULL, 0)
+{
+ lxn1 = NULL;
+ lyn1 = NULL;
+ rxn1 = NULL;
+ ryn1 = NULL;
+
+ offset = new REALTYPE[12]; //model mismatch between JFET devices
+ offset[0] = -0.2509303f;
+ offset[1] = 0.9408924f;
+ offset[2] = 0.998f;
+ offset[3] = -0.3486182f;
+ offset[4] = -0.2762545f;
+ offset[5] = -0.5215785f;
+ offset[6] = 0.2509303f;
+ offset[7] = -0.9408924f;
+ offset[8] = -0.998f;
+ offset[9] = 0.3486182f;
+ offset[10] = 0.2762545f;
+ offset[11] = 0.5215785f;
+
+ barber = 0; //Deactivate barber pole phasing by default
+
+ mis = 1.0f;
+ Rmin = 625.0f; // 2N5457 typical on resistance at Vgs = 0
+ Rmax = 22000.0f; // Resistor parallel to FET
+ Rmx = Rmin/Rmax;
+ Rconst = 1.0f + Rmx; // Handle parallel resistor relationship
+ C = 0.00000005f; // 50 nF
+ CFs = (float) 2.0f*(float)SAMPLE_RATE*C;
+ invperiod = 1.0f / ((float) SOUND_BUFFER_SIZE);
+
+
+ Ppreset = 0;
+ setpreset (Ppreset);
+ cleanup ();
+};
+
+Analog_Phaser::~Analog_Phaser()
+{
+
+ if(lxn1 != NULL)
+ delete[]lxn1;
+
+ if(lyn1 != NULL)
+ delete[]lyn1;
+
+ if(rxn1 != NULL)
+ delete[]rxn1;
+
+ if(ryn1 != NULL)
+ delete[]ryn1;
+
+ if(offset != NULL)
+ delete[]offset;
+};
+
+
+/*
+ * Effect output
+ */
+void Analog_Phaser::out(const Stereo<REALTYPE *> &input)
+{
+ int i, j;
+ float lfol, lfor, lgain, rgain, bl, br, gl, gr, rmod, lmod, d, hpfr, hpfl;
+ lgain = 0.0;
+ rgain = 0.0;
+
+ //initialize hpf
+ hpfl = 0.0;
+ hpfr = 0.0;
+
+ lfo.effectlfoout (&lfol, &lfor);
+ lmod = lfol*width + depth;
+ rmod = lfor*width + depth;
+
+ if(lmod > ONE_)
+ lmod = ONE_;
+ else if(lmod < ZERO_)
+ lmod = ZERO_;
+ if(rmod > ONE_)
+ rmod = ONE_;
+ else if(rmod < ZERO_)
+ rmod = ZERO_;
+
+ if(Phyper != 0)
+ {
+ lmod *= lmod; //Triangle wave squared is approximately sin on bottom, tri on top
+ rmod *= rmod; //Result is exponential sweep more akin to filter in synth with exponential generator circuitry.
+ };
+
+ lmod = sqrtf(1.0f - lmod); //gl,gr is Vp - Vgs. Typical FET drain-source resistance follows constant/[1-sqrt(Vp - Vgs)]
+ rmod = sqrtf(1.0f - rmod);
+
+ rdiff = (rmod - oldrgain) * invperiod;
+ ldiff = (lmod - oldlgain) * invperiod;
+
+ gl = oldlgain;
+ gr = oldrgain;
+
+ oldlgain = lmod;
+ oldrgain = rmod;
+
+ for (i = 0; i < SOUND_BUFFER_SIZE; i++)
+ {
+
+ gl += ldiff; // Linear interpolation between LFO samples
+ gr += rdiff;
+
+ float lxn = input.l()[i];
+ float rxn = input.r()[i];
+
+
+ if (barber) {
+ gl = fmodf((gl + 0.25f) , ONE_);
+ gr = fmodf((gr + 0.25f) , ONE_);
+ };
+
+
+ //cout << lxn << " vs ";
+ //Left channel
+ for (j = 0; j < Pstages; j++)
+ { //Phasing routine
+ mis = 1.0f + offsetpct*offset[j];
+ d = (1.0f + 2.0f*(0.25f + gl)*hpfl*hpfl*distortion) * mis; //This is symmetrical. FET is not, so this deviates slightly, however sym dist. is better sounding than a real FET.
+ Rconst = 1.0f + mis*Rmx;
+ bl = (Rconst - gl )/ (d*Rmin); // This is 1/R. R is being modulated to control filter fc.
+ lgain = (CFs - bl)/(CFs + bl);
+
+ lyn1[j] = lgain * (lxn + lyn1[j]) - lxn1[j];
+ //lyn1[j] += DENORMAL_GUARD;
+ hpfl = lyn1[j] + (1.0f-lgain)*lxn1[j]; //high pass filter -- Distortion depends on the high-pass part of the AP stage.
+
+ lxn1[j] = lxn;
+ lxn = lyn1[j];
+ if (j==1) lxn += fbl; //Insert feedback after first phase stage
+ };
+ //cout << lxn << endl;
+
+ //Right channel
+ for (j = 0; j < Pstages; j++)
+ { //Phasing routine
+ mis = 1.0f + offsetpct*offset[j];
+ d = (1.0f + 2.0f*(0.25f + gr)*hpfr*hpfr*distortion) * mis; // distortion
+ Rconst = 1.0f + mis*Rmx;
+ br = (Rconst - gr )/ (d*Rmin);
+ rgain = (CFs - br)/(CFs + br);
+
+ ryn1[j] = rgain * (rxn + ryn1[j]) - rxn1[j];
+ //ryn1[j] += DENORMAL_GUARD;
+ hpfr = ryn1[j] + (1.0f-rgain)*rxn1[j]; //high pass filter
+
+ rxn1[j] = rxn;
+ rxn = ryn1[j];
+ if (j==1) rxn += fbr; //Insert feedback after first phase stage
+ }
+
+ //cout << fb << ' ' << input.l()[i] - lxn << endl;
+ //cout << "input" << input.l()[i] << "output:" << lxn << endl;
+
+ fbl = lxn * fb;
+ fbr = rxn * fb;
+ efxoutl[i] = lxn;
+ efxoutr[i] = rxn;
+
+ }
+
+ if(Poutsub != 0)
+ for(i = 0; i < SOUND_BUFFER_SIZE; i++)
+ {
+ efxoutl[i] *= -1.0f;
+ efxoutr[i] *= -1.0f;
+ };
+};
+
+/*
+ * Cleanup the effect
+ */
+void Analog_Phaser::cleanup()
+{
+ fbl = 0.0;
+ fbr = 0.0;
+ oldlgain = 0.0;
+ oldrgain = 0.0;
+ for(int i = 0; i < Pstages; i++)
+ {
+ lxn1[i] = 0.0;
+
+ lyn1[i] = 0.0;
+
+ rxn1[i] = 0.0;
+
+ ryn1[i] = 0.0;
+
+ };
+};
+
+/*
+ * Parameter control
+ */
+void Analog_Phaser::setwidth(unsigned char Pwidth)
+{
+ this->Pwidth = Pwidth;
+ width = ((float)Pwidth / 127.0f);
+};
+
+
+void Analog_Phaser::setfb(unsigned char Pfb)
+{
+ this->Pfb = Pfb;
+ fb = (float) (Pfb - 64) / 64.2f;
+};
+
+void Analog_Phaser::setvolume(unsigned char Pvolume)
+{
+ cout << "setting volume" << (int) Pvolume << endl;
+ this->Pvolume = Pvolume;
+ // outvolume is needed in calling program
+ if(insertion == 0) {
+ outvolume = pow(0.01, (1.0 - Pvolume / 127.0)) * 4.0;
+ volume = 1.0;
+ }
+ else
+ volume = outvolume = Pvolume / 127.0;
+};
+
+void Analog_Phaser::setdistortion(unsigned char Pdistortion)
+{
+ this->Pdistortion = Pdistortion;
+ distortion = (float)Pdistortion / 127.0f;
+};
+
+void Analog_Phaser::setoffset(unsigned char Poffset)
+{
+ this->Poffset = Poffset;
+ offsetpct = (float)Poffset / 127.0f;
+};
+
+void Analog_Phaser::setstages(unsigned char Pstages)
+{
+
+ if(lxn1 != NULL)
+ delete[]lxn1;
+
+ if(lyn1 != NULL)
+ delete[]lyn1;
+
+ if(rxn1 != NULL)
+ delete[]rxn1;
+
+ if(ryn1 != NULL)
+ delete[]ryn1;
+
+
+ if(Pstages >= MAX_PHASER_STAGES)
+ Pstages = MAX_PHASER_STAGES ;
+ this->Pstages = Pstages;
+
+
+ lxn1 = new REALTYPE[Pstages];
+ lyn1 = new REALTYPE[Pstages];
+
+ rxn1 = new REALTYPE[Pstages];
+ ryn1 = new REALTYPE[Pstages];
+
+ cleanup();
+};
+
+void Analog_Phaser::setdepth(unsigned char Pdepth)
+{
+ this->Pdepth = Pdepth;
+ depth = (float)(Pdepth - 64) / 127.0f; //Pdepth input should be 0-127. depth shall range 0-0.5 since we don't need to shift the full spectrum.
+};
+
+
+void Analog_Phaser::setpreset(unsigned char npreset)
+{
+ const int PRESET_SIZE = 13;
+ const int NUM_PRESETS = 6;
+ unsigned char presets[NUM_PRESETS][PRESET_SIZE] = {
+ //Phaser1
+ {64, 20, 14, 0, 1, 64, 110, 40, 4, 10, 0, 64, 1},
+ //Phaser2
+ {64, 20, 14, 5, 1, 64, 110, 40, 6, 10, 0, 70, 1},
+ //Phaser3
+ {64, 20, 9, 0, 0, 64, 40, 40, 8, 10, 0, 60, 0},
+ //Phaser4
+ {64, 20, 14, 10, 0, 64, 110, 80, 7, 10, 1, 45, 1},
+ //Phaser5
+ {25, 20, 240, 10, 0, 64, 25, 16, 8, 100, 0, 25, 0},
+ //Phaser6
+ {64, 20, 1, 10, 1, 64, 110, 40, 12, 10, 0, 70, 1}
+ };
+ if(npreset >= NUM_PRESETS)
+ npreset = NUM_PRESETS - 1;
+ for(int n = 0; n < PRESET_SIZE; n++)
+ changepar(n, presets[npreset][n]);
+ Ppreset = npreset;
+};
+
+
+void Analog_Phaser::changepar(int npar, unsigned char value)
+{
+ switch(npar)
+ {
+ case 0:
+ setvolume(value);
+ break;
+ case 1:
+ setdistortion(value);
+ break;
+ case 2:
+ lfo.Pfreq = value;
+ lfo.updateparams();
+ break;
+ case 3:
+ lfo.Prandomness = value;
+ lfo.updateparams ();
+ break;
+ case 4:
+ lfo.PLFOtype = value;
+ lfo.updateparams();
+ barber = 0;
+ if (value == 2) barber = 1;
+ break;
+ case 5:
+ lfo.Pstereo = value;
+ lfo.updateparams();
+ break;
+ case 6:
+ setwidth(value);
+ break;
+ case 7:
+ setfb(value);
+ break;
+ case 8:
+ setstages(value);
+ break;
+ case 9:
+ setoffset(value);
+ break;
+ case 10:
+ if (value > 1)
+ value = 1;
+ Poutsub = value;
+ break;
+ case 11:
+ setdepth(value);
+ break;
+ case 12:
+ if (value > 1)
+ value = 1;
+ Phyper = value;
+ break;
+ };
+};
+
+unsigned char Analog_Phaser::getpar(int npar) const
+{
+ switch(npar)
+ {
+ case 0:
+ return(Pvolume);
+ break;
+ case 1:
+ return(Pdistortion);
+ break;
+ case 2:
+ return(lfo.Pfreq);
+ break;
+ case 3:
+ return(lfo.Prandomness);
+ break;
+ case 4:
+ return(lfo.PLFOtype);
+ break;
+ case 5:
+ return(lfo.Pstereo);
+ break;
+ case 6:
+ return(Pwidth);
+ break;
+ case 7:
+ return(Pfb);
+ break;
+ case 8:
+ return(Pstages);
+ break;
+ case 9:
+ return(Poffset);
+ break;
+ case 10:
+ return(Poutsub);
+ break;
+ case 11:
+ return(Pdepth);
+ break;
+ case 12:
+ return(Phyper);
+ break;
+
+ default:
+ return(0);
+ }
+}
diff --git a/src/Effects/APhaser.h b/src/Effects/APhaser.h
@@ -0,0 +1,86 @@
+/*
+ ZynAddSubFX - a software synthesizer
+
+ Phaser.h - Phaser effect
+ Copyright (C) 2002-2005 Nasca Octavian Paul
+ Author: Nasca Octavian Paul
+
+ Modified for rakarrack by Josep Andreu
+
+ Further modified for rakarrack by Ryan Billing (Transmogrifox) to model Analog Phaser behavior 2009
+
+ 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
+
+*/
+
+#ifndef APHASER_H
+#define APHASER_H
+#include "../globals.h"
+#include "Effect.h"
+#include "EffectLFO.h"
+
+#define MAX_PHASER_STAGES 12
+
+class Analog_Phaser:public Effect
+{
+ public:
+ Analog_Phaser(const int & insertion_, REALTYPE * efxoutl_, REALTYPE * efxoutr_);
+ ~Analog_Phaser();
+ void out(const Stereo<REALTYPE *> &input);
+ void setpreset(unsigned char npreset);
+ void changepar(int npar, unsigned char value);
+ unsigned char getpar(int npar) const;
+ void cleanup();
+ //unsigned char Ppreset;
+
+ private:
+ //Phaser parameters
+ EffectLFO lfo; //Phaser modulator
+ unsigned char Pvolume; //Used in Process.C to set wet/dry mix
+ unsigned char Pdistortion; //Model distortion added by FET element
+ unsigned char Pwidth; //Phaser width (LFO amplitude)
+ unsigned char Pfb; //feedback
+ unsigned char Poffset; //Model mismatch between variable resistors
+ unsigned char Pstages; //Number of first-order All-Pass stages
+ unsigned char Poutsub; //if I wish to subtract the output instead of the adding it
+ unsigned char Phyper; //lfo^2 -- converts tri into hyper-sine
+ unsigned char Pdepth; //Depth of phaser sweep
+ unsigned char Pbarber; //Enable parber pole phasing
+
+
+ //Control parameters
+ void setvolume(unsigned char Pvolume);
+ void setdistortion(unsigned char Pdistortion);
+ void setwidth(unsigned char Pwidth);
+ void setfb(unsigned char Pfb);
+ void setoffset(unsigned char Poffset);
+ void setstages(unsigned char Pstages);
+ void setdepth(unsigned char Pdepth);
+
+ //Internal Variables
+ bool barber; //Barber pole phasing flag
+ REALTYPE distortion, fb, width, offsetpct, fbl, fbr, depth;
+ REALTYPE *lxn1, *lyn1,*rxn1, *ryn1, *offset;
+ REALTYPE oldlgain, oldrgain, rdiff, ldiff, invperiod;
+
+ float mis;
+ float Rmin; // 2N5457 typical on resistance at Vgs = 0
+ float Rmax; // Resistor parallel to FET
+ float Rmx; // Rmin/Rmax to avoid division in loop
+ float Rconst; // Handle parallel resistor relationship
+ float C; // Capacitor
+ float CFs; // A constant derived from capacitor and resistor relationships
+};
+
+#endif
diff --git a/src/Effects/Alienwah.cpp b/src/Effects/Alienwah.cpp
@@ -46,7 +46,7 @@ Alienwah::~Alienwah()
/*
* Apply the effect
*/
-void Alienwah::out(REALTYPE *smpsl, REALTYPE *smpsr)
+void Alienwah::out(const Stereo<float *> &smp)
{
REALTYPE lfol, lfor; //Left/Right LFOs
complex<REALTYPE> clfol, clfor, out, tmp;
@@ -67,7 +67,7 @@ void Alienwah::out(REALTYPE *smpsl, REALTYPE *smpsr)
tmp = clfol * x + oldclfol * x1;
out = tmp * oldl[oldk];
- out.real() += (1 - fabs(fb)) * smpsr[i] * (1.0 - panning);
+ out.real() += (1 - fabs(fb)) * smp.l()[i] * (1.0 - panning);
oldl[oldk] = out;
REALTYPE l = out.real() * 10.0 * (fb + 0.1);
@@ -76,7 +76,7 @@ void Alienwah::out(REALTYPE *smpsl, REALTYPE *smpsr)
tmp = clfor * x + oldclfor * x1;
out = tmp * oldr[oldk];
- out.real() += (1 - fabs(fb)) * smpsr[i] * (1.0 - panning);
+ out.real() += (1 - fabs(fb)) * smp.r()[i] * (1.0 - panning);
oldr[oldk] = out;
REALTYPE r = out.real() * 10.0 * (fb + 0.1);
@@ -110,13 +110,13 @@ void Alienwah::cleanup()
* Parameter control
*/
-void Alienwah::setdepth(const unsigned char &Pdepth)
+void Alienwah::setdepth(unsigned char Pdepth)
{
this->Pdepth = Pdepth;
depth = (Pdepth / 127.0);
}
-void Alienwah::setfb(const unsigned char &Pfb)
+void Alienwah::setfb(unsigned char Pfb)
{
this->Pfb = Pfb;
fb = fabs((Pfb - 64.0) / 64.1);
@@ -127,7 +127,7 @@ void Alienwah::setfb(const unsigned char &Pfb)
fb = -fb;
}
-void Alienwah::setvolume(const unsigned char &Pvolume)
+void Alienwah::setvolume(unsigned char Pvolume)
{
this->Pvolume = Pvolume;
outvolume = Pvolume / 127.0;
@@ -137,25 +137,25 @@ void Alienwah::setvolume(const unsigned char &Pvolume)
volume = outvolume;
}
-void Alienwah::setpanning(const unsigned char &Ppanning)
+void Alienwah::setpanning(unsigned char Ppanning)
{
this->Ppanning = Ppanning;
panning = Ppanning / 127.0;
}
-void Alienwah::setlrcross(const unsigned char &Plrcross)
+void Alienwah::setlrcross(unsigned char Plrcross)
{
this->Plrcross = Plrcross;
lrcross = Plrcross / 127.0;
}
-void Alienwah::setphase(const unsigned char &Pphase)
+void Alienwah::setphase(unsigned char Pphase)
{
this->Pphase = Pphase;
phase = (Pphase - 64.0) / 64.0 * PI;
}
-void Alienwah::setdelay(const unsigned char &Pdelay)
+void Alienwah::setdelay(unsigned char Pdelay)
{
if(oldl != NULL)
delete [] oldl;
@@ -190,12 +190,12 @@ void Alienwah::setpreset(unsigned char npreset)
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 system effect
+ changepar(0, presets[npreset][0] / 2); //lower the volume if this is system effect
Ppreset = npreset;
}
-void Alienwah::changepar(const int &npar, const unsigned char &value)
+void Alienwah::changepar(int npar, unsigned char value)
{
switch(npar) {
case 0:
@@ -238,7 +238,7 @@ void Alienwah::changepar(const int &npar, const unsigned char &value)
}
}
-unsigned char Alienwah::getpar(const int &npar) const
+unsigned char Alienwah::getpar(int npar) const
{
switch(npar) {
case 0:
diff --git a/src/Effects/Alienwah.h b/src/Effects/Alienwah.h
@@ -46,11 +46,11 @@ class Alienwah:public Effect
REALTYPE *const efxoutl_,
REALTYPE *const efxoutr_);
~Alienwah();
- void out(REALTYPE *const smpsl, REALTYPE *const smpsr);
+ void out(const Stereo<float *> &smp);
void setpreset(unsigned char npreset);
- void changepar(const int &npar, const unsigned char &value);
- unsigned char getpar(const int &npar) const;
+ void changepar(int npar, unsigned char value);
+ unsigned char getpar(int npar) const;
void cleanup();
private:
@@ -66,13 +66,13 @@ class Alienwah:public Effect
//Control Parameters
- void setvolume(const unsigned char &Pvolume);
- void setpanning(const unsigned char &Ppanning);
- void setdepth(const unsigned char &Pdepth);
- void setfb(const unsigned char &Pfb);
- void setlrcross(const unsigned char &Plrcross);
- void setdelay(const unsigned char &Pdelay);
- void setphase(const unsigned char &Pphase);
+ void setvolume(unsigned char Pvolume);
+ void setpanning(unsigned char Ppanning);
+ void setdepth(unsigned char Pdepth);
+ void setfb(unsigned char Pfb);
+ void setlrcross(unsigned char Plrcross);
+ void setdelay(unsigned char Pdelay);
+ void setphase(unsigned char Pphase);
//Internal Values
REALTYPE panning, fb, depth, lrcross, phase;
diff --git a/src/Effects/CMakeLists.txt b/src/Effects/CMakeLists.txt
@@ -10,6 +10,7 @@ set(zynaddsubfx_effect_SRCS
EQ.cpp
Phaser.cpp
Reverb.cpp
+ APhaser.cpp
)
add_library(zynaddsubfx_effect STATIC
diff --git a/src/Effects/Chorus.cpp b/src/Effects/Chorus.cpp
@@ -35,9 +35,6 @@ Chorus::Chorus(const int &insertion_,
{
dlk = 0;
drk = 0;
- //maxdelay=(int)(MAX_CHORUS_DELAY/1000.0*SAMPLE_RATE);
- //delayl=new REALTYPE[maxdelay];
- //delayr=new REALTYPE[maxdelay];
setpreset(Ppreset);
@@ -71,18 +68,7 @@ REALTYPE Chorus::getdelay(REALTYPE xlfo)
return result;
}
-/*
- * Apply the effect
- */
-void Chorus::out(REALTYPE *smpsl, REALTYPE *smpsr)
-{
- const Stereo<AuSample> input(AuSample(SOUND_BUFFER_SIZE, smpsl), AuSample(
- SOUND_BUFFER_SIZE,
- smpsr));
- out(input);
-}
-
-void Chorus::out(const Stereo<AuSample> &input)
+void Chorus::out(const Stereo<float *> &input)
{
const REALTYPE one = 1.0;
dl1 = dl2;
@@ -92,7 +78,7 @@ void Chorus::out(const Stereo<AuSample> &input)
dl2 = getdelay(lfol);
dr2 = getdelay(lfor);
- for(int i = 0; i < input.l().size(); i++) {
+ for(int i = 0; i < SOUND_BUFFER_SIZE; i++) {
REALTYPE inl = input.l()[i];
REALTYPE inr = input.r()[i];
//LRcross
@@ -137,14 +123,14 @@ void Chorus::out(const Stereo<AuSample> &input)
}
if(Poutsub != 0)
- for(int i = 0; i < input.l().size(); i++) {
+ for(int i = 0; i < SOUND_BUFFER_SIZE; i++) {
efxoutl[i] *= -1.0;
efxoutr[i] *= -1.0;
}
;
- for(int i = 0; i < input.l().size(); i++) {
+ for(int i = 0; i < SOUND_BUFFER_SIZE; i++) {
efxoutl[i] *= panning;
efxoutr[i] *= (1.0 - panning);
}
@@ -162,24 +148,24 @@ void Chorus::cleanup()
/*
* Parameter control
*/
-void Chorus::setdepth(const unsigned char &Pdepth)
+void Chorus::setdepth(unsigned char Pdepth)
{
this->Pdepth = Pdepth;
depth = (pow(8.0, (Pdepth / 127.0) * 2.0) - 1.0) / 1000.0; //seconds
}
-void Chorus::setdelay(const unsigned char &Pdelay)
+void Chorus::setdelay(unsigned char Pdelay)
{
this->Pdelay = Pdelay;
delay = (pow(10.0, (Pdelay / 127.0) * 2.0) - 1.0) / 1000.0; //seconds
}
-void Chorus::setfb(const unsigned char &Pfb)
+void Chorus::setfb(unsigned char Pfb)
{
this->Pfb = Pfb;
fb = (Pfb - 64.0) / 64.1;
}
-void Chorus::setvolume(const unsigned char &Pvolume)
+void Chorus::setvolume(unsigned char Pvolume)
{
this->Pvolume = Pvolume;
outvolume = Pvolume / 127.0;
@@ -189,13 +175,13 @@ void Chorus::setvolume(const unsigned char &Pvolume)
volume = outvolume;
}
-void Chorus::setpanning(const unsigned char &Ppanning)
+void Chorus::setpanning(unsigned char Ppanning)
{
this->Ppanning = Ppanning;
panning = Ppanning / 127.0;
}
-void Chorus::setlrcross(const unsigned char &Plrcross)
+void Chorus::setlrcross(unsigned char Plrcross)
{
this->Plrcross = Plrcross;
lrcross = Plrcross / 127.0;
@@ -236,7 +222,7 @@ void Chorus::setpreset(unsigned char npreset)
}
-void Chorus::changepar(const int &npar, const unsigned char &value)
+void Chorus::changepar(int npar, unsigned char value)
{
switch(npar) {
case 0:
@@ -288,7 +274,7 @@ void Chorus::changepar(const int &npar, const unsigned char &value)
}
}
-unsigned char Chorus::getpar(const int &npar) const
+unsigned char Chorus::getpar(int npar) const
{
switch(npar) {
case 0:
diff --git a/src/Effects/Chorus.h b/src/Effects/Chorus.h
@@ -25,7 +25,7 @@
#include "../globals.h"
#include "Effect.h"
#include "EffectLFO.h"
-#include "../Samples/AuSample.h"
+#include "../Samples/Sample.h"
#include "../Misc/Stereo.h"
#define MAX_CHORUS_DELAY 250.0 //ms
@@ -37,8 +37,7 @@ class Chorus:public Effect
Chorus(const int &insetion_, REALTYPE *efxoutl_, REALTYPE *efxoutr_);
/**Destructor*/
~Chorus();
- void out(REALTYPE *smpsl, REALTYPE *smpsr);
- void out(const Stereo<AuSample> &input);
+ void out(const Stereo<float *> &input);
void setpreset(unsigned char npreset);
/**
* Sets the value of the chosen variable
@@ -58,7 +57,7 @@ class Chorus:public Effect
* @param npar number of chosen parameter
* @param value the new value
*/
- void changepar(const int &npar, const unsigned char &value);
+ void changepar(int npar, unsigned char value);
/**
* Gets the value of the chosen variable
*
@@ -77,7 +76,7 @@ class Chorus:public Effect
* @param npar number of chosen parameter
* @return the value of the parameter
*/
- unsigned char getpar(const int &npar) const;
+ unsigned char getpar(int npar) const;
void cleanup();
private:
@@ -94,19 +93,18 @@ class Chorus:public Effect
//Parameter Controls
- void setvolume(const unsigned char &Pvolume);
- void setpanning(const unsigned char &Ppanning);
- void setdepth(const unsigned char &Pdepth);
- void setdelay(const unsigned char &Pdelay);
- void setfb(const unsigned char &Pfb);
- void setlrcross(const unsigned char &Plrcross);
+ void setvolume(unsigned char Pvolume);
+ void setpanning(unsigned char Ppanning);
+ void setdepth(unsigned char Pdepth);
+ void setdelay(unsigned char Pdelay);
+ void setfb(unsigned char Pfb);
+ void setlrcross(unsigned char Plrcross);
//Internal Values
REALTYPE depth, delay, fb, lrcross, panning;
REALTYPE dl1, dl2, dr1, dr2, lfol, lfor;
int maxdelay;
- Stereo<AuSample> delaySample;
- //REALTYPE *delayl,*delayr;
+ Stereo<Sample> delaySample;
int dlk, drk, dlhi, dlhi2;
REALTYPE getdelay(REALTYPE xlfo);
REALTYPE dllo, mdel;
diff --git a/src/Effects/Distorsion.cpp b/src/Effects/Distorsion.cpp
@@ -260,7 +260,7 @@ void Distorsion::applyfilters(REALTYPE *efxoutl, REALTYPE *efxoutr)
/*
* Effect output
*/
-void Distorsion::out(REALTYPE *smpsl, REALTYPE *smpsr)
+void Distorsion::out(const Stereo<float *> &smp)
{
int i;
REALTYPE l, r, lout, rout;
@@ -271,14 +271,14 @@ void Distorsion::out(REALTYPE *smpsl, REALTYPE *smpsr)
if(Pstereo != 0) { //Stereo
for(i = 0; i < SOUND_BUFFER_SIZE; i++) {
- efxoutl[i] = smpsl[i] * inputvol * panning;
- efxoutr[i] = smpsr[i] * inputvol * (1.0 - panning);
+ efxoutl[i] = smp.l()[i] * inputvol * panning;
+ efxoutr[i] = smp.r()[i] * inputvol * (1.0 - panning);
}
}
else {
for(i = 0; i < SOUND_BUFFER_SIZE; i++)
efxoutl[i] =
- (smpsl[i] * panning + smpsr[i] * (1.0 - panning)) * inputvol;
+ (smp.l()[i] * panning + smp.r()[i] * (1.0 - panning)) * inputvol;
;
}
@@ -315,7 +315,7 @@ void Distorsion::out(REALTYPE *smpsl, REALTYPE *smpsr)
/*
* Parameter control
*/
-void Distorsion::setvolume(const unsigned char &Pvolume)
+void Distorsion::setvolume(unsigned char Pvolume)
{
this->Pvolume = Pvolume;
@@ -330,20 +330,20 @@ void Distorsion::setvolume(const unsigned char &Pvolume)
cleanup();
}
-void Distorsion::setpanning(const unsigned char &Ppanning)
+void Distorsion::setpanning(unsigned char Ppanning)
{
this->Ppanning = Ppanning;
panning = (Ppanning + 0.5) / 127.0;
}
-void Distorsion::setlrcross(const unsigned char &Plrcross)
+void Distorsion::setlrcross(unsigned char Plrcross)
{
this->Plrcross = Plrcross;
lrcross = Plrcross / 127.0 * 1.0;
}
-void Distorsion::setlpf(const unsigned char &Plpf)
+void Distorsion::setlpf(unsigned char Plpf)
{
this->Plpf = Plpf;
REALTYPE fr = exp(pow(Plpf / 127.0, 0.5) * log(25000.0)) + 40;
@@ -351,7 +351,7 @@ void Distorsion::setlpf(const unsigned char &Plpf)
lpfr->setfreq(fr);
}
-void Distorsion::sethpf(const unsigned char &Phpf)
+void Distorsion::sethpf(unsigned char Phpf)
{
this->Phpf = Phpf;
REALTYPE fr = exp(pow(Phpf / 127.0, 0.5) * log(25000.0)) + 20.0;
@@ -391,7 +391,7 @@ void Distorsion::setpreset(unsigned char npreset)
}
-void Distorsion::changepar(const int &npar, const unsigned char &value)
+void Distorsion::changepar(int npar, unsigned char value)
{
switch(npar) {
case 0:
@@ -439,7 +439,7 @@ void Distorsion::changepar(const int &npar, const unsigned char &value)
}
}
-unsigned char Distorsion::getpar(const int &npar) const
+unsigned char Distorsion::getpar(int npar) const
{
switch(npar) {
case 0:
diff --git a/src/Effects/Distorsion.h b/src/Effects/Distorsion.h
@@ -38,32 +38,32 @@ class Distorsion:public Effect
public:
Distorsion(const int &insertion, REALTYPE *efxoutl_, REALTYPE *efxoutr_);
~Distorsion();
- void out(REALTYPE *smpsl, REALTYPE *smpr);
+ void out(const Stereo<float *> &smp);
void setpreset(unsigned char npreset);
- void changepar(const int &npar, const unsigned char &value);
- unsigned char getpar(const int &npar) const;
+ void changepar(int npar, unsigned char value);
+ unsigned char getpar(int npar) const;
void cleanup();
void applyfilters(REALTYPE *efxoutl, REALTYPE *efxoutr);
private:
//Parametrii
- unsigned char Pvolume; //Volumul or E/R
- unsigned char Ppanning; //Panning
- unsigned char Plrcross; // L/R Mixing
- unsigned char Pdrive; //the input amplification
- unsigned char Plevel; //the output amplification
- unsigned char Ptype; //Distorsion type
- unsigned char Pnegate; //if the input is negated
- unsigned char Plpf; //lowpass filter
- unsigned char Phpf; //highpass filter
- unsigned char Pstereo; //0=mono,1=stereo
+ unsigned char Pvolume; //Volume or E/R
+ unsigned char Ppanning; //Panning
+ unsigned char Plrcross; // L/R Mixing
+ unsigned char Pdrive; //the input amplification
+ unsigned char Plevel; //the output amplification
+ unsigned char Ptype; //Distorsion type
+ unsigned char Pnegate; //if the input is negated
+ unsigned char Plpf; //lowpass filter
+ unsigned char Phpf; //highpass filter
+ unsigned char Pstereo; //0=mono,1=stereo
unsigned char Pprefiltering; //if you want to do the filtering before the distorsion
- void setvolume(const unsigned char &Pvolume);
- void setpanning(const unsigned char &Ppanning);
- void setlrcross(const unsigned char &Plrcross);
- void setlpf(const unsigned char &Plpf);
- void sethpf(const unsigned char &Phpf);
+ void setvolume(unsigned char Pvolume);
+ void setpanning(unsigned char Ppanning);
+ void setlrcross(unsigned char Plrcross);
+ void setlpf(unsigned char Plpf);
+ void sethpf(unsigned char Phpf);
//Real Parameters
REALTYPE panning, lrcross;
diff --git a/src/Effects/DynamicFilter.cpp b/src/Effects/DynamicFilter.cpp
@@ -46,7 +46,7 @@ DynamicFilter::~DynamicFilter()
/*
* Apply the effect
*/
-void DynamicFilter::out(REALTYPE *smpsl, REALTYPE *smpsr)
+void DynamicFilter::out(const Stereo<float *> &smp)
{
int i;
if(filterpars->changed) {
@@ -62,10 +62,10 @@ void DynamicFilter::out(REALTYPE *smpsl, REALTYPE *smpsr)
REALTYPE q = filterpars->getq();
for(i = 0; i < SOUND_BUFFER_SIZE; i++) {
- efxoutl[i] = smpsl[i];
- efxoutr[i] = smpsr[i];
+ efxoutl[i] = smp.l()[i];
+ efxoutr[i] = smp.r()[i];
- REALTYPE x = (fabs(smpsl[i]) + fabs(smpsr[i])) * 0.5;
+ REALTYPE x = (fabs(smp.l()[i]) + fabs(smp.l()[i])) * 0.5;
ms1 = ms1 * (1.0 - ampsmooth) + x * ampsmooth + 1e-10;
}
@@ -110,14 +110,14 @@ void DynamicFilter::cleanup()
* Parameter control
*/
-void DynamicFilter::setdepth(const unsigned char &Pdepth)
+void DynamicFilter::setdepth(unsigned char Pdepth)
{
this->Pdepth = Pdepth;
depth = pow((Pdepth / 127.0), 2.0);
}
-void DynamicFilter::setvolume(const unsigned char &Pvolume)
+void DynamicFilter::setvolume(unsigned char Pvolume)
{
this->Pvolume = Pvolume;
outvolume = Pvolume / 127.0;
@@ -127,14 +127,14 @@ void DynamicFilter::setvolume(const unsigned char &Pvolume)
volume = outvolume;
}
-void DynamicFilter::setpanning(const unsigned char &Ppanning)
+void DynamicFilter::setpanning(unsigned char Ppanning)
{
this->Ppanning = Ppanning;
panning = Ppanning / 127.0;
}
-void DynamicFilter::setampsns(const unsigned char &Pampsns)
+void DynamicFilter::setampsns(unsigned char Pampsns)
{
ampsns = pow(Pampsns / 127.0, 2.5) * 10.0;
if(Pampsnsinv != 0)
@@ -270,7 +270,7 @@ void DynamicFilter::setpreset(unsigned char npreset)
}
-void DynamicFilter::changepar(const int &npar, const unsigned char &value)
+void DynamicFilter::changepar(int npar, unsigned char value)
{
switch(npar) {
case 0:
@@ -312,7 +312,7 @@ void DynamicFilter::changepar(const int &npar, const unsigned char &value)
}
}
-unsigned char DynamicFilter::getpar(const int &npar) const
+unsigned char DynamicFilter::getpar(int npar) const
{
switch(npar) {
case 0:
diff --git a/src/Effects/DynamicFilter.h b/src/Effects/DynamicFilter.h
@@ -33,11 +33,11 @@ class DynamicFilter:public Effect
public:
DynamicFilter(int insetion_, REALTYPE *efxoutl_, REALTYPE *efxoutr_);
~DynamicFilter();
- void out(REALTYPE *smpsl, REALTYPE *smpsr);
+ void out(const Stereo<float *> &smp);
void setpreset(unsigned char npreset);
- void changepar(const int &npar, const unsigned char &value);
- unsigned char getpar(const int &npar) const;
+ void changepar(int npar, unsigned char value);
+ unsigned char getpar(int npar) const;
void cleanup();
// void setdryonly();
@@ -53,10 +53,10 @@ class DynamicFilter:public Effect
unsigned char Pampsmooth; //how smooth the input amplitude changes the filter
//Parameter Control
- void setvolume(const unsigned char &Pvolume);
- void setpanning(const unsigned char &Ppanning);
- void setdepth(const unsigned char &Pdepth);
- void setampsns(const unsigned char &Pampsns);
+ void setvolume(unsigned char Pvolume);
+ void setpanning(unsigned char Ppanning);
+ void setdepth(unsigned char Pdepth);
+ void setampsns(unsigned char Pampsns);
void reinitfilter();
diff --git a/src/Effects/EQ.cpp b/src/Effects/EQ.cpp
@@ -45,9 +45,6 @@ EQ::EQ(const int &insertion_, REALTYPE *efxoutl_, REALTYPE *efxoutr_)
EQ::~EQ()
{}
-/*
- * Cleanup the effect
- */
void EQ::cleanup()
{
for(int i = 0; i < MAX_EQ_BANDS; i++) {
@@ -56,17 +53,12 @@ void EQ::cleanup()
}
}
-
-
-/*
- * Effect output
- */
-void EQ::out(REALTYPE *smpsl, REALTYPE *smpsr)
+void EQ::out(const Stereo<float *> &smp)
{
int i;
for(i = 0; i < SOUND_BUFFER_SIZE; i++) {
- efxoutl[i] = smpsl[i] * volume;
- efxoutr[i] = smpsr[i] * volume;
+ efxoutl[i] = smp.l()[i] * volume;
+ efxoutr[i] = smp.r()[i] * volume;
}
for(i = 0; i < MAX_EQ_BANDS; i++) {
@@ -81,7 +73,7 @@ void EQ::out(REALTYPE *smpsl, REALTYPE *smpsr)
/*
* Parameter control
*/
-void EQ::setvolume(const unsigned char &Pvolume)
+void EQ::setvolume(unsigned char Pvolume)
{
this->Pvolume = Pvolume;
@@ -113,7 +105,7 @@ void EQ::setpreset(unsigned char npreset)
}
-void EQ::changepar(const int &npar, const unsigned char &value)
+void EQ::changepar(int npar, unsigned char value)
{
switch(npar) {
case 0:
@@ -167,7 +159,7 @@ void EQ::changepar(const int &npar, const unsigned char &value)
}
}
-unsigned char EQ::getpar(const int &npar) const
+unsigned char EQ::getpar(int npar) const
{
switch(npar) {
case 0:
diff --git a/src/Effects/EQ.h b/src/Effects/EQ.h
@@ -33,17 +33,17 @@ class EQ:public Effect
public:
EQ(const int &insertion_, REALTYPE *efxoutl_, REALTYPE *efxoutr_);
~EQ();
- void out(REALTYPE *smpsl, REALTYPE *smpr);
+ void out(const Stereo<float *> &smp);
void setpreset(unsigned char npreset);
- void changepar(const int &npar, const unsigned char &value);
- unsigned char getpar(const int &npar) const;
+ void changepar(int npar, unsigned char value);
+ unsigned char getpar(int npar) const;
void cleanup();
REALTYPE getfreqresponse(REALTYPE freq);
private:
//Parameters
unsigned char Pvolume; /**<Volume*/
- void setvolume(const unsigned char &Pvolume);
+ void setvolume(unsigned char Pvolume);
struct {
//parameters
diff --git a/src/Effects/Echo.cpp b/src/Effects/Echo.cpp
@@ -3,7 +3,9 @@
Echo.C - Echo effect
Copyright (C) 2002-2005 Nasca Octavian Paul
+ Copyright (C) 2009-2010 Mark McCurry
Author: Nasca Octavian Paul
+ Mark McCurry
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
@@ -21,95 +23,93 @@
*/
#include <cmath>
-#include <iostream>
#include "Echo.h"
+#define MAX_DELAY 2
+
Echo::Echo(const int &insertion_,
REALTYPE *const efxoutl_,
REALTYPE *const efxoutr_)
:Effect(insertion_, efxoutl_, efxoutr_, NULL, 0),
Pvolume(50), Ppanning(64), //Pdelay(60),
Plrdelay(100), Plrcross(100), Pfb(40), Phidamp(60),
- lrdelay(0), delaySample(1), old(0.0)
+ delayTime(1), lrdelay(0),
+ delay(new REALTYPE[(int)(MAX_DELAY * SAMPLE_RATE)],
+ new REALTYPE[(int)(MAX_DELAY * SAMPLE_RATE)]),
+ old(0.0), pos(0), delta(1), ndelta(1)
{
+ initdelays();
setpreset(Ppreset);
}
-Echo::~Echo() {}
+Echo::~Echo()
+{
+ delete[] delay.l();
+ delete[] delay.r();
+}
/*
* Cleanup the effect
*/
void Echo::cleanup()
{
- delaySample.l().clear();
- delaySample.r().clear();
+ memset(delay.l(),0,MAX_DELAY*SAMPLE_RATE*sizeof(REALTYPE));
+ memset(delay.r(),0,MAX_DELAY*SAMPLE_RATE*sizeof(REALTYPE));
old = Stereo<REALTYPE>(0.0);
}
+inline int max(int a, int b)
+{
+ return a > b ? a : b;
+}
/*
* Initialize the delays
*/
void Echo::initdelays()
{
- /**\todo make this adjust insted of destroy old delays*/
- kl = 0;
- kr = 0;
- dl = (int)(1 + delay.getiVal() * SAMPLE_RATE - lrdelay);
- if(dl < 1)
- dl = 1;
- dr = (int)(1 + delay.getiVal() * SAMPLE_RATE + lrdelay);
- if(dr < 1)
- dr = 1;
-
- delaySample.l() = AuSample(dl);
- delaySample.r() = AuSample(dr);
+ cleanup();
+ //number of seconds to delay left chan
+ float dl = delayCtl.getiVal() - lrdelay;
- old = Stereo<REALTYPE>(0.0);
-}
+ //number of seconds to delay right chan
+ float dr = delayCtl.getiVal() + lrdelay;
-/*
- * Effect output
- */
-void Echo::out(REALTYPE *const smpsl, REALTYPE *const smpsr)
-{
- Stereo<AuSample> input(AuSample(SOUND_BUFFER_SIZE, smpsl), AuSample(
- SOUND_BUFFER_SIZE,
- smpsr));
- out(input);
+ ndelta.l() = max(1,(int) (dl * SAMPLE_RATE));
+ ndelta.r() = max(1,(int) (dr * SAMPLE_RATE));
}
-void Echo::out(const Stereo<AuSample> &input)
+void Echo::out(const Stereo<float *> &input)
{
-//void Echo::out(const Stereo<AuSample> & input){ //ideal
- REALTYPE l, r, ldl, rdl; /**\todo move l+r->? ldl+rdl->?*/
+ REALTYPE ldl, rdl;
- for(int i = 0; i < input.l().size(); i++) {
- ldl = delaySample.l()[kl];
- rdl = delaySample.r()[kr];
- l = ldl * (1.0 - lrcross) + rdl * lrcross;
- r = rdl * (1.0 - lrcross) + ldl * lrcross;
- ldl = l;
- rdl = r;
+ for(int i = 0; i < SOUND_BUFFER_SIZE; ++i) {
+ ldl = delay.l()[pos.l()];
+ rdl = delay.r()[pos.r()];
+ ldl = ldl * (1.0 - lrcross) + rdl * lrcross;
+ rdl = rdl * (1.0 - lrcross) + ldl * lrcross;
efxoutl[i] = ldl * 2.0;
efxoutr[i] = rdl * 2.0;
-
ldl = input.l()[i] * panning - ldl * fb;
rdl = input.r()[i] * (1.0 - panning) - rdl * fb;
//LowPass Filter
- delaySample.l()[kl] = ldl = ldl * hidamp + old.l() * (1.0 - hidamp);
- delaySample.r()[kr] = rdl = rdl * hidamp + old.r() * (1.0 - hidamp);
- old.l() = ldl;
- old.r() = rdl;
-
- if(++kl >= dl)
- kl = 0;
- if(++kr >= dr)
- kr = 0;
+ old.l() = delay.l()[(pos.l()+delta.l())%(MAX_DELAY * SAMPLE_RATE)] = ldl * hidamp + old.l() * (1.0 - hidamp);
+ old.r() = delay.r()[(pos.r()+delta.r())%(MAX_DELAY * SAMPLE_RATE)] = rdl * hidamp + old.r() * (1.0 - hidamp);
+
+ //increment
+ ++pos.l();// += delta.l();
+ ++pos.r();// += delta.r();
+
+ //ensure that pos is still in bounds
+ pos.l() %= MAX_DELAY * SAMPLE_RATE;
+ pos.r() %= MAX_DELAY * SAMPLE_RATE;
+
+ //adjust delay if needed
+ delta.l() = (15*delta.l() + ndelta.l())/16;
+ delta.r() = (15*delta.r() + ndelta.r())/16;
}
}
@@ -117,7 +117,7 @@ void Echo::out(const Stereo<AuSample> &input)
/*
* Parameter control
*/
-void Echo::setvolume(const unsigned char &Pvolume)
+void Echo::setvolume(unsigned char Pvolume)
{
this->Pvolume = Pvolume;
@@ -132,45 +132,45 @@ void Echo::setvolume(const unsigned char &Pvolume)
cleanup();
}
-void Echo::setpanning(const unsigned char &Ppanning)
+void Echo::setpanning(unsigned char Ppanning)
{
this->Ppanning = Ppanning;
panning = (Ppanning + 0.5) / 127.0;
}
-void Echo::setdelay(const unsigned char &Pdelay)
+void Echo::setdelay(unsigned char Pdelay)
{
- delay.setmVal(Pdelay);
+ delayCtl.setmVal(Pdelay);
//this->Pdelay=Pdelay;
//delay=1+(int)(Pdelay/127.0*SAMPLE_RATE*1.5);//0 .. 1.5 sec
initdelays();
}
-void Echo::setlrdelay(const unsigned char &Plrdelay)
+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;
+ (pow(2, fabs(Plrdelay - 64.0) / 64.0 * 9) - 1.0) / 1000.0;
if(Plrdelay < 64.0)
tmp = -tmp;
- lrdelay = (int) tmp;
+ lrdelay = tmp;
initdelays();
}
-void Echo::setlrcross(const unsigned char &Plrcross)
+void Echo::setlrcross(unsigned char Plrcross)
{
this->Plrcross = Plrcross;
lrcross = Plrcross / 127.0 * 1.0;
}
-void Echo::setfb(const unsigned char &Pfb)
+void Echo::setfb(unsigned char Pfb)
{
this->Pfb = Pfb;
fb = Pfb / 128.0;
}
-void Echo::sethidamp(const unsigned char &Phidamp)
+void Echo::sethidamp(unsigned char Phidamp)
{
this->Phidamp = Phidamp;
hidamp = 1.0 - Phidamp / 127.0;
@@ -213,7 +213,7 @@ void Echo::setpreset(unsigned char npreset)
}
-void Echo::changepar(const int &npar, const unsigned char &value)
+void Echo::changepar(int npar, unsigned char value)
{
switch(npar) {
case 0:
@@ -240,7 +240,7 @@ void Echo::changepar(const int &npar, const unsigned char &value)
}
}
-unsigned char Echo::getpar(const int &npar) const
+unsigned char Echo::getpar(int npar) const
{
switch(npar) {
case 0:
@@ -250,7 +250,7 @@ unsigned char Echo::getpar(const int &npar) const
return Ppanning;
break;
case 2:
- return delay.getmVal();
+ return delayCtl.getmVal();
break;
case 3:
return Plrdelay;
diff --git a/src/Effects/Echo.h b/src/Effects/Echo.h
@@ -25,8 +25,8 @@
#include "../globals.h"
#include "Effect.h"
-#include "../Samples/AuSample.h"
#include "../Misc/Stereo.h"
+#include "../Samples/Sample.h"
#include "../Controls/DelayCtl.h"
/**Echo Effect*/
@@ -51,15 +51,7 @@ class Echo:public Effect
*/
~Echo();
- /**
- * Outputs the echo to efxoutl and efxoutr
- * @param smpsl Sample from Left channel
- * @param smpsr Sample from Right channel
- * \todo try to figure out if smpsl should be const *const
- * or not (It should be)
- */
- void out(REALTYPE *const smpsl, REALTYPE *const smpr);
- void out(const Stereo<AuSample> &input);
+ void out(const Stereo<float *> &input);
/**
* Sets the state of Echo to the specified preset
@@ -81,7 +73,7 @@ class Echo:public Effect
* @param npar number of chosen parameter
* @param value the new value
*/
- void changepar(const int &npar, const unsigned char &value);
+ void changepar(int npar, unsigned char value);
/**
* Gets the specified parameter
@@ -97,7 +89,7 @@ class Echo:public Effect
* @param npar number of chosen parameter
* @return value of parameter
*/
- unsigned char getpar(const int &npar) const;
+ unsigned char getpar(int npar) const;
int getnumparams();
@@ -108,31 +100,38 @@ class Echo:public Effect
void setdryonly();
private:
//Parameters
- char Pvolume; /**<#1 Volume or Dry/Wetness*/
+ char Pvolume; /**<#1 Volume or Dry/Wetness*/
char Ppanning; /**<#2 Panning*/
- DelayCtl delay; /**<#3 Delay of the Echo*/
+ DelayCtl delayCtl; /**<#3 Delay of the Echo*/
char Plrdelay; /**<#4 L/R delay difference*/
char Plrcross; /**<#5 L/R Mixing*/
- char Pfb; /**<#6Feedback*/
- char Phidamp; /**<#7Dampening of the Echo*/
+ char Pfb; /**<#6Feedback*/
+ char Phidamp; /**<#7Dampening of the Echo*/
- void setvolume(const unsigned char &Pvolume);
- void setpanning(const unsigned char &Ppanning);
- void setdelay(const unsigned char &Pdelay);
- void setlrdelay(const unsigned char &Plrdelay);
- void setlrcross(const unsigned char &Plrcross);
- void setfb(const unsigned char &Pfb);
- void sethidamp(const unsigned char &Phidamp);
+ void setvolume(unsigned char Pvolume);
+ void setpanning(unsigned char Ppanning);
+ void setdelay(unsigned char Pdelay);
+ void setlrdelay(unsigned char Plrdelay);
+ void setlrcross(unsigned char Plrcross);
+ void setfb(unsigned char Pfb);
+ void sethidamp(unsigned char Phidamp);
//Real Parameters
- REALTYPE panning, lrcross, fb, hidamp; //needs better names
- int dl, dr, lrdelay; //needs better names
+ REALTYPE panning, lrcross, fb, hidamp;
+ //Left/Right delay lengths
+ Stereo<int> delayTime;
+ float lrdelay;
void initdelays();
- Stereo<AuSample> delaySample;
+ //2 channel ring buffer
+ Stereo<REALTYPE *> delay;
Stereo<REALTYPE> old;
- int kl, kr;
+ //position of reading/writing from delaysample
+ Stereo<int> pos;
+ //step size for delay buffer
+ Stereo<int> delta;
+ Stereo<int> ndelta;
};
#endif
diff --git a/src/Effects/Effect.cpp b/src/Effects/Effect.cpp
@@ -23,10 +23,15 @@
#include "Effect.h"
#include "../Params/FilterParams.h"
-
Effect::Effect(bool insertion_, REALTYPE *const efxoutl_,
REALTYPE *const efxoutr_, FilterParams *filterpars_,
const unsigned char &Ppreset_)
:Ppreset(Ppreset_), efxoutl(efxoutl_), efxoutr(efxoutr_),
- filterpars(filterpars_), insertion(insertion_) {}
+ filterpars(filterpars_), insertion(insertion_)
+{}
+
+void Effect::out(REALTYPE *const smpsl, REALTYPE *const smpsr)
+{
+ out(Stereo<float *>(smpsl,smpsr));
+};
diff --git a/src/Effects/Effect.h b/src/Effects/Effect.h
@@ -25,6 +25,8 @@
#include "../Misc/Util.h"
#include "../globals.h"
+#include "../Params/FilterParams.h"
+#include "../Misc/Stereo.h"
class FilterParams;
@@ -56,12 +58,12 @@ class Effect
/**Change parameter npar to value
* @param npar chosen parameter
* @param value chosen new value*/
- virtual void changepar(const int &npar, const unsigned char &value) = 0;
+ virtual void changepar(int npar, unsigned char value) = 0;
/**Get the value of parameter npar
* @param npar chosen parameter
* @return the value of the parameter in an unsigned char or 0 if it
* does not exist*/
- virtual unsigned char getpar(const int &npar) const = 0;
+ virtual unsigned char getpar(int npar) const = 0;
/**Output result of effect based on the given buffers
*
* This method should result in the effect generating its results
@@ -71,7 +73,8 @@ class Effect
* @param smpsl Input buffer for the Left channel
* @param smpsr Input buffer for the Right channel
*/
- virtual void out(REALTYPE *const smpsl, REALTYPE *const smpsr) = 0;
+ void out(REALTYPE *const smpsl, REALTYPE *const smpsr);
+ virtual void out(const Stereo<float *> &smp) = 0;
/**Reset the state of the effect*/
virtual void cleanup() {}
/**This is only used for EQ (for user interface)*/
@@ -82,7 +85,7 @@ class Effect
unsigned char Ppreset; /**<Currently used preset*/
REALTYPE *const efxoutl; /**<Effect out Left Channel*/
REALTYPE *const efxoutr; /**<Effect out Right Channel*/
- /**\todo make efxoutl and efxoutr private and replace them with a StereoSample*/
+ /**\todo make efxoutl and efxoutr private and replace them with a Stereo<float*>*/
REALTYPE outvolume;/**<This is the volume of effect and is public because
* it is needed in system effects.
@@ -96,7 +99,7 @@ class Effect
protected:
const bool insertion;/**<If Effect is an insertion effect, insertion=1
- *otherwise, it should be insertion=0*/
+ *otherwise, it should be insertion=0*/
};
#endif
diff --git a/src/Effects/EffectMgr.cpp b/src/Effects/EffectMgr.cpp
@@ -31,6 +31,9 @@
#include "../Misc/XMLwrapper.h"
#include "../Params/FilterParams.h"
+#include <iostream>
+using namespace std;
+>>>>>>> master:src/Effects/EffectMgr.cpp
EffectMgr::EffectMgr(int insertion_, pthread_mutex_t *mutex_)
:insertion(insertion_),
@@ -111,6 +114,9 @@ void EffectMgr::changeeffect(int nefx_)
case 8:
efx = new DynamicFilter(insertion, efxoutl, efxoutr);
break;
+ case 9:
+ efx = new Analog_Phaser(insertion, efxoutl, efxoutr);
+ break;
//put more effect here
default:
efx = NULL;
diff --git a/src/Effects/EffectMgr.h b/src/Effects/EffectMgr.h
@@ -32,6 +32,14 @@ class Effect;
class FilterParams;
class XMLwrapper;
+#include "Distorsion.h"
+#include "EQ.h"
+#include "DynamicFilter.h"
+#include "APhaser.h"
+#include "../Misc/XMLwrapper.h"
+#include "../Params/FilterParams.h"
+#include "../Params/Presets.h"
+
/**Effect manager, an interface betwen the program and effects*/
class EffectMgr:public Presets
{
diff --git a/src/Effects/Makefile b/src/Effects/Makefile
@@ -2,7 +2,7 @@ include ../Makefile.inc
objects=Alienwah.o Chorus.o Echo.o Effect.o \
EffectLFO.o EffectMgr.o Phaser.o Reverb.o \
- Distorsion.o EQ.o DynamicFilter.o
+ Distorsion.o EQ.o DynamicFilter.o APhaser.o
all: $(objects)
diff --git a/src/Effects/Phaser.cpp b/src/Effects/Phaser.cpp
@@ -38,7 +38,7 @@ Phaser::~Phaser()
/*
* Effect output
*/
-void Phaser::out(REALTYPE *smpsl, REALTYPE *smpsr)
+void Phaser::out(const Stereo<float *> &smp)
{
int i, j;
REALTYPE lfol, lfor, lgain, rgain, tmp;
@@ -69,8 +69,8 @@ void Phaser::out(REALTYPE *smpsl, REALTYPE *smpsr)
REALTYPE x1 = 1.0 - x;
REALTYPE gl = lgain * x + oldgain.left() * x1;
REALTYPE gr = rgain * x + oldgain.right() * x1;
- REALTYPE inl = smpsl[i] * panning + fbl;
- REALTYPE inr = smpsr[i] * (1.0 - panning) + fbr;
+ REALTYPE inl = smp.l()[i] * panning + fbl;
+ REALTYPE inr = smp.r()[i] * (1.0 - panning) + fbr;
//Left channel
for(j = 0; j < Pstages * 2; j++) { //Phasing routine
@@ -121,20 +121,20 @@ void Phaser::cleanup()
/*
* Parameter control
*/
-void Phaser::setdepth(const unsigned char &Pdepth)
+void Phaser::setdepth(unsigned char Pdepth)
{
this->Pdepth = Pdepth;
depth = (Pdepth / 127.0);
}
-void Phaser::setfb(const unsigned char &Pfb)
+void Phaser::setfb(unsigned char Pfb)
{
this->Pfb = Pfb;
fb = (Pfb - 64.0) / 64.1;
}
-void Phaser::setvolume(const unsigned char &Pvolume)
+void Phaser::setvolume(unsigned char Pvolume)
{
this->Pvolume = Pvolume;
outvolume = Pvolume / 127.0;
@@ -144,29 +144,29 @@ void Phaser::setvolume(const unsigned char &Pvolume)
volume = outvolume;
}
-void Phaser::setpanning(const unsigned char &Ppanning)
+void Phaser::setpanning(unsigned char Ppanning)
{
this->Ppanning = Ppanning;
panning = Ppanning / 127.0;
}
-void Phaser::setlrcross(const unsigned char &Plrcross)
+void Phaser::setlrcross(unsigned char Plrcross)
{
this->Plrcross = Plrcross;
lrcross = Plrcross / 127.0;
}
-void Phaser::setstages(const unsigned char &Pstages)
+void Phaser::setstages(unsigned char Pstages)
{
if(Pstages >= MAX_PHASER_STAGES)
this->Pstages = MAX_PHASER_STAGES - 1;
else
this->Pstages = Pstages;
- old = Stereo<AuSample>(Pstages * 2);
+ old = Stereo<Sample>(Pstages * 2);
cleanup();
}
-void Phaser::setphase(const unsigned char &Pphase)
+void Phaser::setphase(unsigned char Pphase)
{
this->Pphase = Pphase;
phase = (Pphase / 127.0);
@@ -199,7 +199,7 @@ void Phaser::setpreset(unsigned char npreset)
}
-void Phaser::changepar(const int &npar, const unsigned char &value)
+void Phaser::changepar(int npar, unsigned char value)
{
switch(npar) {
case 0:
@@ -248,7 +248,7 @@ void Phaser::changepar(const int &npar, const unsigned char &value)
}
}
-unsigned char Phaser::getpar(const int &npar) const
+unsigned char Phaser::getpar(int npar) const
{
switch(npar) {
case 0:
diff --git a/src/Effects/Phaser.h b/src/Effects/Phaser.h
@@ -24,7 +24,7 @@
#define PHASER_H
#include "../globals.h"
#include "../Misc/Stereo.h"
-#include "../Samples/AuSample.h"
+#include "../Samples/Sample.h"
#include "Effect.h"
#include "EffectLFO.h"
@@ -35,10 +35,10 @@ class Phaser:public Effect
public:
Phaser(const int &insetion_, REALTYPE *efxoutl_, REALTYPE *efxoutr_);
~Phaser();
- void out(REALTYPE *smpsl, REALTYPE *smpsr);
+ void out(const Stereo<float *> &smp);
void setpreset(unsigned char npreset);
- void changepar(const int &npar, const unsigned char &value);
- unsigned char getpar(const int &npar) const;
+ void changepar(int npar, unsigned char value);
+ unsigned char getpar(int npar) const;
void cleanup();
void setdryonly();
@@ -49,26 +49,23 @@ class Phaser:public Effect
unsigned char Ppanning;
unsigned char Pdepth; /**<the depth of the Phaser*/
unsigned char Pfb; /**<feedback*/
- unsigned char Plrcross; /**<feedback*/
+ unsigned char Plrcross; /**<crossover*/
unsigned char Pstages;
unsigned char Poutsub; /**<if I wish to substract the output instead of the adding it*/
unsigned char Pphase;
- //Control Parametrii
- void setvolume(const unsigned char &Pvolume);
- void setpanning(const unsigned char &Ppanning);
- void setdepth(const unsigned char &Pdepth);
- void setfb(const unsigned char &Pfb);
- void setlrcross(const unsigned char &Plrcross);
- void setstages(const unsigned char &Pstages);
- void setphase(const unsigned char &Pphase);
+ //Control Parameters
+ void setvolume(unsigned char Pvolume);
+ void setpanning(unsigned char Ppanning);
+ void setdepth(unsigned char Pdepth);
+ void setfb(unsigned char Pfb);
+ void setlrcross(unsigned char Plrcross);
+ void setstages(unsigned char Pstages);
+ void setphase(unsigned char Pphase);
//Internal Values
- //int insertion; //inherited from Effect
REALTYPE panning, fb, depth, lrcross, fbl, fbr, phase;
- //REALTYPE *oldl,*oldr;
- Stereo<AuSample> old;
- //REALTYPE oldlgain,oldrgain;
+ Stereo<Sample> old;
Stereo<REALTYPE> oldgain;
};
diff --git a/src/Effects/Reverb.cpp b/src/Effects/Reverb.cpp
@@ -165,14 +165,14 @@ void Reverb::processmono(int ch, REALTYPE *output)
/*
* Effect output
*/
-void Reverb::out(REALTYPE *smps_l, REALTYPE *smps_r)
+void Reverb::out(const Stereo<float *> &smp)
{
int i;
if((Pvolume == 0) && (insertion != 0))
return;
for(i = 0; i < SOUND_BUFFER_SIZE; i++)
- inputbuf[i] = (smps_l[i] + smps_r[i]) / 2.0;
+ inputbuf[i] = (smp.l()[i] + smp.r()[i]) / 2.0;
;
if(idelay != NULL) {
@@ -215,7 +215,7 @@ void Reverb::out(REALTYPE *smps_l, REALTYPE *smps_r)
/*
* Parameter control
*/
-void Reverb::setvolume(const unsigned char &Pvolume)
+void Reverb::setvolume(unsigned char Pvolume)
{
this->Pvolume = Pvolume;
if(insertion == 0) {
@@ -229,13 +229,13 @@ void Reverb::setvolume(const unsigned char &Pvolume)
}
}
-void Reverb::setpan(const unsigned char &Ppan)
+void Reverb::setpan(unsigned char Ppan)
{
this->Ppan = Ppan;
pan = (REALTYPE)Ppan / 127.0;
}
-void Reverb::settime(const unsigned char &Ptime)
+void Reverb::settime(unsigned char Ptime)
{
int i;
REALTYPE t;
@@ -271,7 +271,7 @@ void Reverb::setlohidamp(unsigned char Plohidamp)
}
}
-void Reverb::setidelay(const unsigned char &Pidelay)
+void Reverb::setidelay(unsigned char Pidelay)
{
REALTYPE delay;
this->Pidelay = Pidelay;
@@ -290,13 +290,13 @@ void Reverb::setidelay(const unsigned char &Pidelay)
}
}
-void Reverb::setidelayfb(const unsigned char &Pidelayfb)
+void Reverb::setidelayfb(unsigned char Pidelayfb)
{
this->Pidelayfb = Pidelayfb;
idelayfb = Pidelayfb / 128.0;
}
-void Reverb::sethpf(const unsigned char &Phpf)
+void Reverb::sethpf(unsigned char Phpf)
{
this->Phpf = Phpf;
if(Phpf == 0) { //No HighPass
@@ -313,7 +313,7 @@ void Reverb::sethpf(const unsigned char &Phpf)
}
}
-void Reverb::setlpf(const unsigned char &Plpf)
+void Reverb::setlpf(unsigned char Plpf)
{
this->Plpf = Plpf;
if(Plpf == 127) { //No LowPass
@@ -405,7 +405,7 @@ void Reverb::settype(unsigned char Ptype)
}
}
-void Reverb::setroomsize(const unsigned char &Proomsize)
+void Reverb::setroomsize(unsigned char Proomsize)
{
this->Proomsize = Proomsize;
if(Proomsize == 0)
@@ -418,7 +418,7 @@ void Reverb::setroomsize(const unsigned char &Proomsize)
settype(Ptype);
}
-void Reverb::setbandwidth(const unsigned char &Pbandwidth) {
+void Reverb::setbandwidth(unsigned char Pbandwidth) {
this->Pbandwidth = Pbandwidth;
REALTYPE v = Pbandwidth / 127.0;
if(bandwidth)
@@ -468,7 +468,7 @@ void Reverb::setpreset(unsigned char npreset)
}
-void Reverb::changepar(const int &npar, const unsigned char &value)
+void Reverb::changepar(int npar, unsigned char value)
{
switch(npar) {
case 0:
@@ -511,7 +511,7 @@ void Reverb::changepar(const int &npar, const unsigned char &value)
}
}
-unsigned char Reverb::getpar(const int &npar) const
+unsigned char Reverb::getpar(int npar) const
{
switch(npar) {
case 0:
diff --git a/src/Effects/Reverb.h b/src/Effects/Reverb.h
@@ -40,12 +40,12 @@ class Reverb:public Effect
public:
Reverb(const int &insertion_, REALTYPE *efxoutl_, REALTYPE *efxoutr_);
~Reverb();
- void out(REALTYPE *smps_l, REALTYPE *smps_r);
+ void out(const Stereo<float *> &smp);
void cleanup();
void setpreset(unsigned char npreset);
- void changepar(const int &npar, const unsigned char &value);
- unsigned char getpar(const int &npar) const;
+ void changepar(int npar, unsigned char value);
+ unsigned char getpar(int npar) const;
private:
//Parametrii
@@ -90,17 +90,17 @@ class Reverb:public Effect
unsigned char Pbandwidth;
//parameter control
- void setvolume(const unsigned char &Pvolume);
- void setpan(const unsigned char &Ppan);
- void settime(const unsigned char &Ptime);
+ void setvolume(unsigned char Pvolume);
+ void setpan(unsigned char Ppan);
+ void settime(unsigned char Ptime);
void setlohidamp(unsigned char Plohidamp);
- void setidelay(const unsigned char &Pidelay);
- void setidelayfb(const unsigned char &Pidelayfb);
- void sethpf(const unsigned char &Phpf);
- void setlpf(const unsigned char &Plpf);
+ void setidelay(unsigned char Pidelay);
+ void setidelayfb(unsigned char Pidelayfb);
+ void sethpf(unsigned char Phpf);
+ void setlpf(unsigned char Plpf);
void settype(unsigned char Ptype);
- void setroomsize(const unsigned char &Proomsize);
- void setbandwidth(const unsigned char &Pbandwidth);
+ void setroomsize(unsigned char Proomsize);
+ void setbandwidth(unsigned char Pbandwidth);
REALTYPE pan, erbalance;
//Parameters
diff --git a/src/Samples/CMakeLists.txt b/src/Samples/CMakeLists.txt
@@ -1,6 +1,4 @@
set(zynaddsubfx_samples_SRCS
- AuSample.cpp
- FqSample.cpp
Sample.cpp
)
diff --git a/src/Samples/Makefile b/src/Samples/Makefile
@@ -1,6 +1,6 @@
include ../Makefile.inc
-objects=Sample.o AuSample.o FqSample.o
+objects=Sample.o
all: $(objects)
diff --git a/src/Samples/Sample.cpp b/src/Samples/Sample.cpp
@@ -20,8 +20,12 @@
*/
#include <cmath>
#include <cstring>//for memcpy/memset
+
+#include <iostream>
#include "Sample.h"
+using namespace std;
+
#warning TODO Think about renaming Sample to Frame
/**\TODO start using pointer math here as these will be Frequency called
* functions throughout the code*/
@@ -163,6 +167,10 @@ Sample &Sample::append(const Sample &smp)
Sample Sample::subSample(int a, int b) const
{
return Sample(b-a, buffer+a);
+ delete buffer;
+
+ buffer = nbuffer;
+ bufferSize = nbufferSize;
}
REALTYPE Sample::max() const
diff --git a/src/Tests/CMakeLists.txt b/src/Tests/CMakeLists.txt
@@ -1,6 +1,6 @@
unit_test(ControllerTest ControllerTest.h ../Params/Controller.h)
unit_test(EchoTest EchoTest.h ../Effects/Echo.h)
-unit_test(SampleTest SampleTest.h ../Samples/AuSample.h)
+unit_test(SampleTest SampleTest.h ../Samples/Sample.h)
unit_test(MicrotonalTest MicrotonalTest.h ../Misc/Microtonal.h)
unit_test(XMLwrapperTest XMLwrapperTest.h ../Misc/XMLwrapper.h)
unit_test(ADnoteTest AdNoteTest.h ../Synth/ADnote.h)
diff --git a/src/Tests/EchoTest.h b/src/Tests/EchoTest.h
@@ -22,24 +22,31 @@
#include <cxxtest/TestSuite.h>
#include <cmath>
#include <cstdlib>
+#include <iostream>
#include "../Effects/Echo.h"
#include "../globals.h"
-//int SOUND_BUFFER_SIZE=256;
+
+using namespace std;
+
class EchoTest:public CxxTest::TestSuite
{
public:
void setUp() {
outL = new float[SOUND_BUFFER_SIZE];
for(int i = 0; i < SOUND_BUFFER_SIZE; ++i)
- *(outL + i) = 0;
+ outL[i] = 0.0;
outR = new float[SOUND_BUFFER_SIZE];
for(int i = 0; i < SOUND_BUFFER_SIZE; ++i)
- *(outR + i) = 0;
- input = new Stereo<AuSample>(SOUND_BUFFER_SIZE);
+ outR[i] = 0.0;
+ input = new Stereo<REALTYPE *>(new REALTYPE[SOUND_BUFFER_SIZE],new REALTYPE[SOUND_BUFFER_SIZE]);
+ for(int i = 0; i < SOUND_BUFFER_SIZE; ++i)
+ input->l()[i] = input->r()[i] = 0.0f;
testFX = new Echo(true, outL, outR);
}
void tearDown() {
+ delete[] input->r();
+ delete[] input->l();
delete input;
delete[] outL;
delete[] outR;
@@ -60,7 +67,11 @@ class EchoTest:public CxxTest::TestSuite
void testClear() {
char DELAY = 2;
testFX->changepar(DELAY, 127);
- *input = Stereo<AuSample>(AuSample(SOUND_BUFFER_SIZE, 1.0));
+
+ //flood with high input
+ for(int i = 0; i < SOUND_BUFFER_SIZE; ++i)
+ input->r()[i] = input->l()[i] = 1.0;
+
for(int i = 0; i < 500; ++i)
testFX->out(*input);
for(int i = 0; i < SOUND_BUFFER_SIZE; ++i) {
@@ -80,7 +91,10 @@ class EchoTest:public CxxTest::TestSuite
}
//Insures that the proper decay occurs with high feedback
void testDecaywFb() {
- *input = Stereo<AuSample>(AuSample(SOUND_BUFFER_SIZE, 1.0));
+
+ //flood with high input
+ for(int i = 0; i < SOUND_BUFFER_SIZE; ++i)
+ input->r()[i] = input->l()[i] = 1.0;
char FEEDBACK = 5;
testFX->changepar(FEEDBACK, 127);
for(int i = 0; i < 100; ++i)
@@ -91,19 +105,18 @@ class EchoTest:public CxxTest::TestSuite
}
float amp = abs(outL[0] + outR[0]) / 2;
//reset input to zero
- *input = Stereo<AuSample>(SOUND_BUFFER_SIZE);
+ for(int i = 0; i < SOUND_BUFFER_SIZE; ++i)
+ input->r()[i] = input->l()[i] = 0.0;
+
//give the echo time to fade based upon zero input and high feedback
for(int i = 0; i < 50; ++i)
testFX->out(*input);
- TS_ASSERT_LESS_THAN(abs(outL[0] + outR[0]) / 2, amp);
+ TS_ASSERT_LESS_THAN_EQUALS(abs(outL[0] + outR[0]) / 2, amp);
}
-
-
-
private:
- Stereo<AuSample> *input;
+ Stereo<REALTYPE *> *input;
float *outR, *outL;
Echo *testFX;
};
diff --git a/src/Tests/SampleTest.h b/src/Tests/SampleTest.h
@@ -20,34 +20,34 @@
*/
#include <cxxtest/TestSuite.h>
-#include "../Samples/AuSample.h"
+#include "../Samples/Sample.h"
class SampleTest:public CxxTest::TestSuite
{
public:
void testInit() {
- AuSample smp(10);
+ Sample smp(10);
TS_ASSERT_EQUALS(smp.size(), 10);
for(int i = 0; i < 20; ++i)
TS_ASSERT_EQUALS(smp[i], 0.0);
- AuSample nsmp(5, 15.0);
+ Sample nsmp(5, 15.0);
TS_ASSERT_EQUALS(nsmp.size(), 5);
TS_ASSERT_EQUALS(nsmp[4], 15.0);
}
void testAssign() {
- AuSample smp(3);
+ Sample smp(3);
smp[0] = 0;
smp[1] = 1;
smp[2] = 2;
- AuSample nsmp(40);
+ Sample nsmp(40);
nsmp = smp;
TS_ASSERT_EQUALS(smp.size(), nsmp.size());
for(int i = 0; i < 29; ++i)
TS_ASSERT_EQUALS(smp[i], nsmp[i]);
}
void testBounds() {
- AuSample smp(0);
+ Sample smp(0);
TS_ASSERT(smp.size() != 0);
}
@@ -55,16 +55,16 @@ class SampleTest:public CxxTest::TestSuite
float *fl = new float[50];
for(int i = 0; i < 50; ++i)
*(fl + i) = i;
- AuSample smp(2);
- smp = AuSample(50, fl);
+ Sample smp(2);
+ smp = Sample(50, fl);
delete [] fl;
for(int i = 0; i < 50; ++i)
TS_ASSERT_DELTA(smp[i], i, 0.001);
- smp = AuSample(3);
+ smp = Sample(3);
}
void testClear() {
- AuSample smp(50);
+ Sample smp(50);
for(int i = 0; i < 50; ++i)
smp[i] = 10;
smp.clear();
diff --git a/src/UI/EffUI.fl b/src/UI/EffUI.fl
@@ -1,5 +1,5 @@
# data file for the Fltk User Interface Designer (fluid)
-version 1.0109
+version 1.0300
header_name {.h}
code_name {.cc}
decl {//Copyright (c) 2002-2005 Nasca Octavian Paul} {}
@@ -155,7 +155,7 @@ return(log(freq/20.0)/log(1000.0));} {}
decl {int maxdB;} {}
}
-class EffUI {open : {public Fl_Group,public PresetsUI_}
+class EffUI {: {public Fl_Group,public PresetsUI_}
} {
Function {EffUI(int x,int y, int w, int h, const char *label=0):Fl_Group(x,y,w,h,label)} {} {
code {eff=NULL;
@@ -167,6 +167,7 @@ effreverbwindow->hide();//delete (effreverbwindow);
effechowindow->hide();//delete (effechowindow);
effchoruswindow->hide();//delete (effchoruswindow);
effphaserwindow->hide();//delete (effphaserwindow);
+effaphaserwindow->hide();//delete (effaphaserwindow);
effalienwahwindow->hide();//delete (effalienwahwindow);
effdistorsionwindow->hide();//delete (effdistorsionwindow);
effeqwindow->hide();//delete (effeqwindow);
@@ -179,7 +180,7 @@ if (filterwindow!=NULL){
}
Function {make_null_window()} {} {
Fl_Window effnullwindow {
- xywh {287 379 380 95} type Double box PLASTIC_UP_BOX color 221 labelfont 1 hide
+ xywh {216 539 380 95} type Double box PLASTIC_UP_BOX color 221 labelfont 1 hide
class Fl_Group
} {
Fl_Text_Display {} {
@@ -188,11 +189,10 @@ if (filterwindow!=NULL){
}
}
}
- Function {make_reverb_window()} {open
- } {
- Fl_Window effreverbwindow {open
- xywh {343 337 380 95} type Double box PLASTIC_UP_BOX color 221 labelfont 1
- class Fl_Group visible
+ Function {make_reverb_window()} {} {
+ Fl_Window effreverbwindow {
+ xywh {343 337 380 95} type Double box PLASTIC_UP_BOX color 221 labelfont 1 hide
+ class Fl_Group
} {
Fl_Text_Display {} {
label {Reverb }
@@ -344,7 +344,7 @@ if (eff->geteffectpar(10)==2) revp12->activate();
callback {int x=64;
if (Fl::event_button1()) x=(int)o->value();
else o->value(x);
-eff->seteffectpar(11,x);} selected
+eff->seteffectpar(11,x);}
tooltip RoomSize xywh {200 10 25 25} box ROUND_UP_BOX labelfont 1 labelsize 8 align 8 minimum 1 maximum 127 step 1
class WidgetPDial
}
@@ -704,6 +704,134 @@ refresh(eff);}
}
}
}
+ Function {make_analog_phaser_window()} {selected
+ } {
+ Fl_Window effaphaserwindow {
+ xywh {292 251 380 95} type Double box PLASTIC_UP_BOX color 221 labelfont 1 hide
+ code0 {putchar('a'); putchar('b'); putchar('c');}
+ class Fl_Group
+ } {
+ Fl_Choice aphaserp {
+ label Preset
+ callback {eff->changepreset((int)o->value());
+refresh(eff);}
+ xywh {10 15 90 15} down_box BORDER_BOX color 14 selection_color 0 labelfont 1 labelsize 10 align 5 textfont 1 textsize 10 textcolor 7
+ } {
+ MenuItem {} {
+ label {Phaser 1}
+ xywh {30 30 100 20} labelfont 1 labelsize 10 labelcolor 7
+ }
+ MenuItem {} {
+ label {Phaser 2}
+ xywh {40 40 100 20} labelfont 1 labelsize 10 labelcolor 7
+ }
+ MenuItem {} {
+ label {Phaser 3}
+ xywh {50 50 100 20} labelfont 1 labelsize 10 labelcolor 7
+ }
+ MenuItem {} {
+ label {Phaser 4}
+ xywh {60 60 100 20} labelfont 1 labelsize 10 labelcolor 7
+ }
+ MenuItem {} {
+ label {Phaser 5}
+ xywh {70 70 100 20} labelfont 1 labelsize 10 labelcolor 7
+ }
+ MenuItem {} {
+ label {Phaser 6}
+ xywh {80 80 100 20} labelfont 1 labelsize 10 labelcolor 7
+ }
+ }
+ Fl_Text_Display {} {
+ label APhaser
+ xywh {260 10 10 20} box NO_BOX labeltype EMBOSSED_LABEL labelfont 1 labelsize 22 align 8
+ }
+ Fl_Dial aphaser0 {
+ label Vol
+ callback {eff->seteffectpar(0,(int) o->value());}
+ tooltip {Effect Volume} xywh {10 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 11 maximum 127
+ class WidgetPDial
+ }
+ Fl_Dial aphaser1 {
+ label dist
+ callback {eff->seteffectpar(1,(int) o->value());}
+ tooltip Distortion xywh {45 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 11 maximum 127
+ class WidgetPDial
+ }
+ Fl_Dial aphaser2 {
+ label Freq
+ callback {eff->seteffectpar(2,(int) o->value());}
+ tooltip {LFO frequency} xywh {85 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 11 maximum 127
+ class WidgetPDial
+ }
+ Fl_Dial aphaser3 {
+ label rnd
+ callback {eff->seteffectpar(3,(int) o->value());}
+ tooltip Randomness xywh {120 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 11 when 4 maximum 127
+ class WidgetPDial
+ }
+ Fl_Choice aphaser4 {
+ label {LFO type}
+ callback {eff->seteffectpar(4,(int) o->value());}
+ tooltip {LFO function} xywh {155 50 40 15} down_box BORDER_BOX labelfont 1 labelsize 10 align 130 textsize 8
+ } {
+ MenuItem {} {
+ label SINE
+ xywh {15 15 100 20} labelfont 1 labelsize 10
+ }
+ MenuItem {} {
+ label TRI
+ xywh {25 25 100 20} labelfont 1 labelsize 10
+ }
+ }
+ Fl_Dial aphaser5 {
+ label {St.df}
+ callback {eff->seteffectpar(5,(int) o->value());}
+ tooltip {Left/Right Channel Phase Shift} xywh {200 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 11 maximum 127
+ class WidgetPDial
+ }
+ Fl_Dial aphaser6 {
+ label Dpth
+ callback {eff->seteffectpar(6,(int) o->value());}
+ tooltip {LFO Depth} xywh {235 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 11 maximum 127
+ class WidgetPDial
+ }
+ Fl_Dial aphaser7 {
+ label Fb
+ callback {eff->seteffectpar(7,(int) o->value());}
+ tooltip Feedback xywh {270 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 11 maximum 127
+ class WidgetPDial
+ }
+ Fl_Counter aphaser8 {
+ label Stages
+ callback {eff->seteffectpar(8,(int) o->value());}
+ xywh {305 55 35 15} type Simple labelfont 1 labelsize 11 minimum 0 maximum 127 step 1
+ code0 {o->range(1,MAX_PHASER_STAGES);}
+ }
+ Fl_Dial aphaser9 {
+ label offset
+ callback {eff->seteffectpar(9,(int) o->value());}
+ tooltip offset xywh {345 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 11 maximum 127
+ class WidgetPDial
+ }
+ Fl_Check_Button aphaser10 {
+ label Substract
+ callback {eff->seteffectpar(10,(int) o->value());}
+ tooltip {inverts output} xywh {185 10 74 20} box THIN_UP_BOX down_box DOWN_BOX color 230 labelfont 1 labelsize 10
+ }
+ Fl_Dial aphaser11 {
+ label Depth
+ callback {eff->seteffectpar(11,(int) o->value());}
+ xywh {155 10 25 25} box ROUND_UP_BOX labelfont 1 labelsize 10 maximum 127
+ class WidgetPDial
+ }
+ Fl_Check_Button aphaser12 {
+ label {hyp.}
+ callback {eff->seteffectpar(12,(int) o->value());}
+ tooltip hyper xywh {100 10 55 15} down_box DOWN_BOX
+ }
+ }
+ }
Function {make_alienwah_window()} {} {
Fl_Window effalienwahwindow {
xywh {538 250 380 95} type Double box PLASTIC_UP_BOX color 221 labelfont 1 hide
@@ -1251,6 +1379,7 @@ make_reverb_window();
make_echo_window();
make_chorus_window();
make_phaser_window();
+make_analog_phaser_window();
make_alienwah_window();
make_distorsion_window();
make_eq_window();
@@ -1264,6 +1393,7 @@ effreverbwindow->position(px,py);
effechowindow->position(px,py);
effchoruswindow->position(px,py);
effphaserwindow->position(px,py);
+effaphaserwindow->position(px,py);
effalienwahwindow->position(px,py);
effdistorsionwindow->position(px,py);
effeqwindow->position(px,py);
@@ -1271,8 +1401,7 @@ effdynamicfilterwindow->position(px,py);
refresh(eff);} {}
}
- Function {refresh(EffectMgr *eff_)} {open
- } {
+ Function {refresh(EffectMgr *eff_)} {} {
code {eff=eff_;
this->hide();
@@ -1281,6 +1410,7 @@ effreverbwindow->hide();
effechowindow->hide();
effchoruswindow->hide();
effphaserwindow->hide();
+effaphaserwindow->hide();
effalienwahwindow->hide();
effdistorsionwindow->hide();
effeqwindow->hide();
@@ -1416,6 +1546,24 @@ switch(eff->geteffect()){
effdynamicfilterwindow->show();
break;
+ case 9://make_analog_phaser_window();
+ aphaserp->value(eff->getpreset());
+ aphaser0->value(eff->geteffectpar(0));
+ aphaser1->value(eff->geteffectpar(1));
+ aphaser2->value(eff->geteffectpar(2));
+ aphaser3->value(eff->geteffectpar(3));
+ aphaser4->value(eff->geteffectpar(4));
+ aphaser5->value(eff->geteffectpar(5));
+ aphaser6->value(eff->geteffectpar(6));
+ aphaser7->value(eff->geteffectpar(7));
+ aphaser8->value(eff->geteffectpar(8));
+ aphaser9->value(eff->geteffectpar(9));
+ aphaser10->value(eff->geteffectpar(10));
+ aphaser11->value(eff->geteffectpar(11));
+ aphaser12->value(eff->geteffectpar(12));
+ putchar('?');
+ effaphaserwindow->show();
+ break;
default:effnullwindow->show();
break;
};
diff --git a/src/UI/MasterUI.fl b/src/UI/MasterUI.fl
@@ -699,8 +699,8 @@ pthread_mutex_unlock(&master->mutex);}
xywh {0 80 390 160}
} {
Fl_Group {} {
- label {System Effects} open
- xywh {0 100 390 140} box ENGRAVED_FRAME labeltype EMBOSSED_LABEL labelsize 15 align 25
+ label {System Effects}
+ xywh {0 100 390 140} box ENGRAVED_FRAME labeltype EMBOSSED_LABEL labelsize 15 align 25 hide
} {
Fl_Counter syseffnocounter {
label {Sys.Effect No.}
@@ -756,6 +756,10 @@ syseffectui->refresh(master->sysefx[nsyseff]);}
label DynFilter
xywh {90 90 100 20} labelfont 1 labelsize 10
}
+ MenuItem {} {
+ label APhaser
+ xywh {0 0 36 21}
+ }
}
Fl_Group syseffectuigroup {
xywh {5 140 380 95} box FLAT_BOX color 48
@@ -786,7 +790,7 @@ pthread_mutex_unlock(&master->mutex);}
}
Fl_Group {} {
label {Insertion Effects}
- xywh {0 100 390 140} box ENGRAVED_FRAME labeltype EMBOSSED_LABEL labelsize 15 align 25 hide
+ xywh {0 100 390 140} box ENGRAVED_FRAME labeltype EMBOSSED_LABEL labelsize 15 align 25
} {
Fl_Counter inseffnocounter {
label {Ins.Effect No.}
@@ -855,6 +859,10 @@ inseffectui->show();}
label DynFilter
xywh {100 100 100 20} labelfont 1 labelsize 10
}
+ MenuItem {} {
+ label APhaser selected
+ xywh {0 0 36 21} labelfont 1 labelsize 10
+ }
}
Fl_Group inseffectuigroup {
xywh {5 140 380 95} box FLAT_BOX color 48