zynaddsubfx

ZynAddSubFX open source synthesizer
Log | Files | Refs | Submodules | LICENSE

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:
MAUTHORS.txt | 1+
MChangeLog | 7+++++++
MHISTORY.txt | 10++++++++++
Asrc/Effects/APhaser.cpp | 450+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/Effects/APhaser.h | 86+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/Effects/Alienwah.cpp | 26+++++++++++++-------------
Msrc/Effects/Alienwah.h | 20++++++++++----------
Msrc/Effects/CMakeLists.txt | 1+
Msrc/Effects/Chorus.cpp | 38++++++++++++--------------------------
Msrc/Effects/Chorus.h | 24+++++++++++-------------
Msrc/Effects/Distorsion.cpp | 22+++++++++++-----------
Msrc/Effects/Distorsion.h | 36++++++++++++++++++------------------
Msrc/Effects/DynamicFilter.cpp | 20++++++++++----------
Msrc/Effects/DynamicFilter.h | 14+++++++-------
Msrc/Effects/EQ.cpp | 20++++++--------------
Msrc/Effects/EQ.h | 8++++----
Msrc/Effects/Echo.cpp | 122++++++++++++++++++++++++++++++++++++++++----------------------------------------
Msrc/Effects/Echo.h | 53++++++++++++++++++++++++++---------------------------
Msrc/Effects/Effect.cpp | 9+++++++--
Msrc/Effects/Effect.h | 13++++++++-----
Msrc/Effects/EffectMgr.cpp | 6++++++
Msrc/Effects/EffectMgr.h | 8++++++++
Msrc/Effects/Makefile | 2+-
Msrc/Effects/Phaser.cpp | 26+++++++++++++-------------
Msrc/Effects/Phaser.h | 31++++++++++++++-----------------
Msrc/Effects/Reverb.cpp | 26+++++++++++++-------------
Msrc/Effects/Reverb.h | 24++++++++++++------------
Msrc/Samples/CMakeLists.txt | 2--
Msrc/Samples/Makefile | 2+-
Msrc/Samples/Sample.cpp | 8++++++++
Msrc/Tests/CMakeLists.txt | 2+-
Msrc/Tests/EchoTest.h | 37+++++++++++++++++++++++++------------
Msrc/Tests/SampleTest.h | 20++++++++++----------
Msrc/UI/EffUI.fl | 170+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------
Msrc/UI/MasterUI.fl | 14+++++++++++---
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