zynaddsubfx

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

commit 63aaf28d2aa4276348db38e49bee100595789229
parent a3d3cf448cc2d782f9ab0015c24378fd7f69aa24
Author: fundamental <mark.d.mccurry@gmail.com>
Date:   Sun, 27 Jun 2010 16:02:35 -0400

Merging Aphaser->Phaser

Conflicts:
	src/Effects/Makefile
	src/Misc/Util.cpp
	src/UI/MasterUI.fl

Diffstat:
Dsrc/Effects/APhaser.cpp | 445-------------------------------------------------------------------------------
Dsrc/Effects/APhaser.h | 86-------------------------------------------------------------------------------
Msrc/Effects/CMakeLists.txt | 1-
Msrc/Effects/EffectMgr.cpp | 3---
Msrc/Effects/EffectMgr.h | 1-
Msrc/Effects/Phaser.cpp | 517+++++++++++++++++++++++++++++++++++++++++++++++++++++--------------------------
Msrc/Effects/Phaser.h | 69++++++++++++++++++++++++++++++++++++++++++++++++++-------------------
Msrc/Misc/Stereo.cpp | 5+++--
Msrc/Misc/Stereo.h | 6+++---
Msrc/Misc/Util.cpp | 14++++++++++++++
Msrc/Misc/Util.h | 4++++
Msrc/UI/EffUI.fl | 313++++++++++++++++---------------------------------------------------------------
Msrc/UI/MasterUI.fl | 20++------------------
13 files changed, 486 insertions(+), 998 deletions(-)

diff --git a/src/Effects/APhaser.cpp b/src/Effects/APhaser.cpp @@ -1,445 +0,0 @@ -/* - - APhaser.cpp - 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.cpp - 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_); - }; - - - //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 - }; - - //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 - } - - - 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) -{ - 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 @@ -1,86 +0,0 @@ -/* - 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.cpp 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/CMakeLists.txt b/src/Effects/CMakeLists.txt @@ -10,7 +10,6 @@ set(zynaddsubfx_effect_SRCS EQ.cpp Phaser.cpp Reverb.cpp - APhaser.cpp ) add_library(zynaddsubfx_effect STATIC diff --git a/src/Effects/EffectMgr.cpp b/src/Effects/EffectMgr.cpp @@ -113,9 +113,6 @@ 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 @@ -35,7 +35,6 @@ 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" diff --git a/src/Effects/Phaser.cpp b/src/Effects/Phaser.cpp @@ -1,9 +1,18 @@ /* + + Phaser.cpp - Phasing and Approximate digital model of an analog JFET phaser. + Analog modeling implemented by Ryan Billing aka Transmogrifox. ZynAddSubFX - a software synthesizer Phaser.cpp - Phaser effect Copyright (C) 2002-2005 Nasca Octavian Paul + Copyright (C) 2009-2010 Ryan Billing + Copyright (C) 2010-2010 Mark McCurry Author: Nasca Octavian Paul + Ryan Billing + Mark McCurry + + 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 @@ -21,89 +30,212 @@ */ #include <cmath> +#include <algorithm> #include "Phaser.h" + +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. Phaser::Phaser(const int &insertion_, REALTYPE *efxoutl_, REALTYPE *efxoutr_) - :Effect(insertion_, efxoutl_, efxoutr_, NULL, 0), old(1), oldgain(0.0) + :Effect(insertion_, efxoutl_, efxoutr_, NULL, 0), xn1(NULL), yn1(NULL), diff(0.0), old(NULL), oldgain(0.0), + fb(0.0) { + analog_setup(); setpreset(Ppreset); cleanup(); } -Phaser::~Phaser() -{} +void Phaser::analog_setup() +{ + //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); +} +Phaser::~Phaser() +{ + if(xn1.l) + delete[] xn1.l; + if(yn1.l) + delete[] yn1.l; + if(xn1.r) + delete[] xn1.r; + if(yn1.r) + delete[] yn1.r; +} /* * Effect output */ -void Phaser::out(const Stereo<float *> &smp) +void Phaser::out(const Stereo<REALTYPE *> &input) { - int i, j; - REALTYPE lfol, lfor, lgain, rgain, tmp; + if(Panalog) + AnalogPhase(input); + else + normalPhase(input); +} - lfo.effectlfoout(&lfol, &lfor); - lgain = lfol; - rgain = lfor; - lgain = (exp(lgain * PHASER_LFO_SHAPE) - 1) / (exp(PHASER_LFO_SHAPE) - 1.0); - rgain = (exp(rgain * PHASER_LFO_SHAPE) - 1) / (exp(PHASER_LFO_SHAPE) - 1.0); +void Phaser::AnalogPhase(const Stereo<REALTYPE *> &input) +{ + Stereo<REALTYPE> gain(0.0), lfoVal(0.0), mod(0.0), g(0.0), b(0.0), hpf(0.0); + lfo.effectlfoout(&lfoVal.l, &lfoVal.r); + mod.l = lfoVal.l*width + (depth - 0.5f); + mod.r = lfoVal.r*width + (depth - 0.5f); - lgain = 1.0 - phase * (1.0 - depth) - (1.0 - phase) * lgain * depth; - rgain = 1.0 - phase * (1.0 - depth) - (1.0 - phase) * rgain * depth; + mod.l = limit(mod.l, ZERO_, ONE_); + mod.r = limit(mod.r, ZERO_, ONE_); - if(lgain > 1.0) - lgain = 1.0; - else - if(lgain < 0.0) - lgain = 0.0; - if(rgain > 1.0) - rgain = 1.0; - else - if(rgain < 0.0) - rgain = 0.0; + if(Phyper) { + //Triangle wave squared is approximately sin on bottom, tri on top + //Result is exponential sweep more akin to filter in synth with + //exponential generator circuitry. + mod.l *= mod.l; + mod.r *= mod.r; + } + + //g.l,g.r is Vp - Vgs. Typical FET drain-source resistance follows constant/[1-sqrt(Vp - Vgs)] + mod.l = sqrtf(1.0f - mod.l); + mod.r = sqrtf(1.0f - mod.r); + + diff.r = (mod.r - oldgain.r) * invperiod; + diff.l = (mod.l - oldgain.l) * invperiod; + + g = oldgain; + oldgain = mod; + + for (int i = 0; i < SOUND_BUFFER_SIZE; i++) { + g.l += diff.l;// Linear interpolation between LFO samples + g.r += diff.r; + + Stereo<REALTYPE> xn(input.l[i] * panning, + input.r[i] * (1.0f - panning)); + + if (barber) { + g.l = fmodf((g.l + 0.25f), ONE_); + g.r = fmodf((g.r + 0.25f), ONE_); + } + + xn.l = applyPhase(xn.l, g.l, fb.l, hpf.l, yn1.l, xn1.l); + xn.r = applyPhase(xn.r, g.r, fb.r, hpf.r, yn1.r, xn1.r); + + + fb.l = xn.l * feedback; + fb.r = xn.r * feedback; + efxoutl[i] = xn.l; + efxoutr[i] = xn.r; + } + + if(Poutsub) { + invSignal(efxoutl, SOUND_BUFFER_SIZE); + invSignal(efxoutr, SOUND_BUFFER_SIZE); + } +} + +REALTYPE Phaser::applyPhase(REALTYPE x, REALTYPE g, REALTYPE fb, + REALTYPE &hpf, REALTYPE *yn1, REALTYPE *xn1) +{ + for(int j = 0; j < Pstages; j++) { //Phasing routine + mis = 1.0f + offsetpct*offset[j]; + + //This is symmetrical. + //FET is not, so this deviates slightly, however sym dist. is + //better sounding than a real FET. + float d = (1.0f + 2.0f*(0.25f + g)*hpf*hpf*distortion) * mis; + Rconst = 1.0f + mis*Rmx; + + // This is 1/R. R is being modulated to control filter fc. + float b = (Rconst - g)/ (d*Rmin); + float gain = (CFs - b)/(CFs + b); + yn1[j] = gain * (x + yn1[j]) - xn1[j]; + + //high pass filter: + //Distortion depends on the high-pass part of the AP stage. + hpf = yn1[j] + (1.0f-gain)*xn1[j]; + + xn1[j] = x; + x = yn1[j]; + if (j==1) + x += fb; //Insert feedback after first phase stage + } + return x; +} +void Phaser::normalPhase(const Stereo<REALTYPE *> &input) +{ + Stereo<REALTYPE> gain(0.0), lfoVal(0.0); + + lfo.effectlfoout(&lfoVal.l, &lfoVal.r); + gain.l = (exp(lfoVal.l * PHASER_LFO_SHAPE) - 1) / (exp(PHASER_LFO_SHAPE) - 1.0); + gain.r = (exp(lfoVal.r * PHASER_LFO_SHAPE) - 1) / (exp(PHASER_LFO_SHAPE) - 1.0); + + gain.l = 1.0 - phase * (1.0 - depth) - (1.0 - phase) * gain.l * depth; + gain.r = 1.0 - phase * (1.0 - depth) - (1.0 - phase) * gain.r * depth; - for(i = 0; i < SOUND_BUFFER_SIZE; i++) { + gain.l = limit(gain.l, ZERO_, ONE_); + gain.r = limit(gain.r, ZERO_, ONE_); + + for(int i = 0; i < SOUND_BUFFER_SIZE; i++) { REALTYPE x = (REALTYPE) i / SOUND_BUFFER_SIZE; REALTYPE x1 = 1.0 - x; - REALTYPE gl = lgain * x + oldgain.l * x1; - REALTYPE gr = rgain * x + oldgain.r * x1; - 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 - tmp = old.l[j]; - old.l[j] = gl * tmp + inl; - inl = tmp - gl *old.l[j]; - } - //Right channel - for(j = 0; j < Pstages * 2; j++) { //Phasing routine - tmp = old.r[j]; - old.r[j] = gr * tmp + inr; - inr = tmp - gr *old.r[j]; - } + //TODO think about making panning an external feature + Stereo<REALTYPE> xn(input.l[i] * panning + fb.l, + input.r[i] * (1.0 - panning) + fb.r); + + Stereo<REALTYPE> g(gain.l * x + oldgain.l * x1, + gain.r * x + oldgain.r * x1); + + xn.l = applyPhase(xn.l, g.l, old.l); + xn.r = applyPhase(xn.r, g.r, old.r); + //Left/Right crossing - REALTYPE l = inl; - REALTYPE r = inr; - inl = l * (1.0 - lrcross) + r * lrcross; - inr = r * (1.0 - lrcross) + l * lrcross; - - fbl = inl * fb; - fbr = inr * fb; - efxoutl[i] = inl; - efxoutr[i] = inr; + crossover(xn.l, xn.r, lrcross); + + fb.l = xn.l * feedback; + fb.r = xn.r * feedback; + efxoutl[i] = xn.l; + efxoutr[i] = xn.r; } - oldgain = Stereo<REALTYPE>(lgain, rgain); + oldgain = gain; - if(Poutsub != 0) - for(i = 0; i < SOUND_BUFFER_SIZE; i++) { - efxoutl[i] *= -1.0; - efxoutr[i] *= -1.0; - } - ; + if(Poutsub) { + invSignal(efxoutl, SOUND_BUFFER_SIZE); + invSignal(efxoutr, SOUND_BUFFER_SIZE); + } +} + +REALTYPE Phaser::applyPhase(REALTYPE x, REALTYPE g, REALTYPE *old) +{ + for(int j = 0; j < Pstages * 2; j++) { //Phasing routine + REALTYPE tmp = old[j]; + old[j] = g * tmp + x; + x = tmp - g *old[j]; + } + return x; } /* @@ -111,27 +243,32 @@ void Phaser::out(const Stereo<float *> &smp) */ void Phaser::cleanup() { - fbl = 0.0; - fbr = 0.0; - oldgain = Stereo<REALTYPE>(0.0); - old.l.clear(); - old.r.clear(); + fb = oldgain = Stereo<REALTYPE>(0.0); + for(int i = 0; i < Pstages * 2; i++) { + old.l[i] = 0.0; + old.r[i] = 0.0; + } + for(int i = 0; i < Pstages; i++) { + xn1.l[i] = 0.0; + yn1.l[i] = 0.0; + xn1.r[i] = 0.0; + yn1.r[i] = 0.0; + } } /* * Parameter control */ -void Phaser::setdepth(unsigned char Pdepth) +void Phaser::setwidth(unsigned char Pwidth) { - this->Pdepth = Pdepth; - depth = (Pdepth / 127.0); + this->Pwidth = Pwidth; + width = ((float)Pwidth / 127.0f); } - void Phaser::setfb(unsigned char Pfb) { this->Pfb = Pfb; - fb = (Pfb - 64.0) / 64.1; + feedback = (float) (Pfb - 64) / 64.2f; } void Phaser::setvolume(unsigned char Pvolume) @@ -147,7 +284,7 @@ void Phaser::setvolume(unsigned char Pvolume) void Phaser::setpanning(unsigned char Ppanning) { this->Ppanning = Ppanning; - panning = Ppanning / 127.0; + panning = (float)Ppanning / 127.0; } void Phaser::setlrcross(unsigned char Plrcross) @@ -156,13 +293,41 @@ void Phaser::setlrcross(unsigned char Plrcross) lrcross = Plrcross / 127.0; } +void Phaser::setdistortion(unsigned char Pdistortion) +{ + this->Pdistortion = Pdistortion; + distortion = (float)Pdistortion / 127.0f; +} + +void Phaser::setoffset(unsigned char Poffset) +{ + this->Poffset = Poffset; + offsetpct = (float)Poffset / 127.0f; +} + void Phaser::setstages(unsigned char Pstages) { - if(Pstages >= MAX_PHASER_STAGES) - this->Pstages = MAX_PHASER_STAGES - 1; - else - this->Pstages = Pstages; - old = Stereo<Sample>(Pstages * 2); + if(xn1.l) + delete[] xn1.l; + if(yn1.l) + delete[] yn1.l; + if(xn1.r) + delete[] xn1.r; + if(yn1.r) + delete[] yn1.r; + + + this->Pstages = min(MAX_PHASER_STAGES, (int)Pstages); + + old = Stereo<REALTYPE *>(new REALTYPE[Pstages * 2], + new REALTYPE[Pstages * 2]); + + xn1 = Stereo<REALTYPE *>(new REALTYPE[Pstages], + new REALTYPE[Pstages]); + + yn1 = Stereo<REALTYPE *>(new REALTYPE[Pstages], + new REALTYPE[Pstages]); + cleanup(); } @@ -172,24 +337,34 @@ void Phaser::setphase(unsigned char Pphase) phase = (Pphase / 127.0); } +void Phaser::setdepth(unsigned char Pdepth) +{ + this->Pdepth = Pdepth; + depth = (float)(Pdepth) / 127.0f; +} + void Phaser::setpreset(unsigned char npreset) { - const int PRESET_SIZE = 12; - const int NUM_PRESETS = 6; + const int PRESET_SIZE = 15; + const int NUM_PRESETS = 12; unsigned char presets[NUM_PRESETS][PRESET_SIZE] = { - //Phaser1 - {64, 64, 36, 0, 0, 64, 110, 64, 1, 0, 0, 20}, - //Phaser2 - {64, 64, 35, 0, 0, 88, 40, 64, 3, 0, 0, 20}, - //Phaser3 - {64, 64, 31, 0, 0, 66, 68, 107, 2, 0, 0, 20}, - //Phaser4 - {39, 64, 22, 0, 0, 66, 67, 10, 5, 0, 1, 20}, - //Phaser5 - {64, 64, 20, 0, 1, 110, 67, 78, 10, 0, 0, 20}, - //Phaser6 - {64, 64, 53, 100, 0, 58, 37, 78, 3, 0, 0, 20} + //Phaser + //0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 + {64, 64, 36, 0, 0, 64, 110, 64, 1, 0, 0, 20, 0, 0, 0}, + {64, 64, 35, 0, 0, 88, 40, 64, 3, 0, 0, 20, 0, 0, 0}, + {64, 64, 31, 0, 0, 66, 68, 107, 2, 0, 0, 20, 0, 0, 0}, + {39, 64, 22, 0, 0, 66, 67, 10, 5, 0, 1, 20, 0, 0, 0}, + {64, 64, 20, 0, 1, 110, 67, 78, 10, 0, 0, 20, 0, 0, 0}, + {64, 64, 53, 100, 0, 58, 37, 78, 3, 0, 0, 20, 0, 0, 0}, + //APhaser + //0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 + {64, 64, 14, 0, 1, 64, 64, 40, 4, 10, 0, 110, 1, 20, 1}, + {64, 64, 14, 5, 1, 64, 70, 40, 6, 10, 0, 110, 1, 20, 1}, + {64, 64, 9, 0, 0, 64, 60, 40, 8, 10, 0, 40, 0, 20, 1}, + {64, 64, 14, 10, 0, 64, 45, 80, 7, 10, 1, 110, 1, 20, 1}, + {25, 64, 127, 10, 0, 64, 25, 16, 8, 100, 0, 25, 0, 20, 1}, + {64, 64, 1, 10, 1, 64, 70, 40, 12, 10, 0, 110, 1, 20, 1} }; if(npreset >= NUM_PRESETS) npreset = NUM_PRESETS - 1; @@ -202,93 +377,97 @@ void Phaser::setpreset(unsigned char npreset) void Phaser::changepar(int npar, unsigned char value) { switch(npar) { - case 0: - setvolume(value); - break; - case 1: - setpanning(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(); - break; - case 5: - lfo.Pstereo = value; - lfo.updateparams(); - break; - case 6: - setdepth(value); - break; - case 7: - setfb(value); - break; - case 8: - setstages(value); - break; - case 9: - setlrcross(value); - break; - case 10: - if(value > 1) - Poutsub = 1; - else - Poutsub = value; - break; - case 11: - setphase(value); - break; + case 0: + setvolume(value); + break; + case 1: + setpanning(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 = (2 == value); + break; + case 5: + lfo.Pstereo = value; + lfo.updateparams(); + break; + case 6: + setdepth(value); + break; + case 7: + setfb(value); + break; + case 8: + setstages(value); + break; + case 9: + setlrcross(value); + setoffset(value); + break; + case 10: + Poutsub = min((int)value,1); + break; + case 11: + setphase(value); + setwidth(value); + break; + case 12: + Phyper = min((int)value, 1); + break; + case 13: + setdistortion(value); + break; + case 14: + Panalog = value; + break; } } unsigned char Phaser::getpar(int npar) const { switch(npar) { - case 0: - return Pvolume; - break; - case 1: - return Ppanning; - 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 Pdepth; - break; - case 7: - return Pfb; - break; - case 8: - return Pstages; - break; - case 9: - return Plrcross; - break; - case 10: - return Poutsub; - break; - case 11: - return Pphase; - break; - default: - return 0; + case 0: + return Pvolume; + case 1: + return Ppanning; + case 2: + return lfo.Pfreq; + case 3: + return lfo.Prandomness; + case 4: + return lfo.PLFOtype; + case 5: + return lfo.Pstereo; + case 6: + return Pdepth; + case 7: + return Pfb; + case 8: + return Pstages; + case 9: + return Plrcross; + return Poffset; + case 10: + return Poutsub; + case 11: + return Pphase; + return Pwidth; + case 12: + return Phyper; + case 13: + return Pdistortion; + case 14: + return Panalog; + default: + return 0; } } - diff --git a/src/Effects/Phaser.h b/src/Effects/Phaser.h @@ -3,7 +3,11 @@ Phaser.h - Phaser effect Copyright (C) 2002-2005 Nasca Octavian Paul + Copyright (C) 2009-2010 Ryan Billing + Copyright (C) 2010-2010 Mark McCurry Author: Nasca Octavian Paul + Ryan Billing + 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 @@ -23,50 +27,77 @@ #ifndef PHASER_H #define PHASER_H #include "../globals.h" -#include "../Misc/Stereo.h" -#include "../Samples/Sample.h" #include "Effect.h" #include "EffectLFO.h" #define MAX_PHASER_STAGES 12 -/**Phaser Effect*/ + class Phaser:public Effect { public: - Phaser(const int &insetion_, REALTYPE *efxoutl_, REALTYPE *efxoutr_); + Phaser(const int &insertion_, REALTYPE *efxoutl_, REALTYPE *efxoutr_); ~Phaser(); - void out(const Stereo<float *> &smp); + 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(); - void setdryonly(); private: - //Parametrii Phaser - EffectLFO lfo; /**<lfo-ul Phaser*/ - unsigned char Pvolume; + //Phaser parameters + EffectLFO lfo; //Phaser modulator + unsigned char Pvolume; //Used to set wet/dry mix unsigned char Ppanning; - unsigned char Pdepth; /**<the depth of the Phaser*/ - unsigned char Pfb; /**<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 Pdistortion; //Model distortion added by FET element + unsigned char Pdepth; //Depth of phaser sweep + unsigned char Pwidth; //Phaser width (LFO amplitude) + unsigned char Pfb; //feedback + unsigned char Poffset; //Model mismatch between variable resistors + unsigned char Plrcross; //crossover + unsigned char Pstages; //Number of first-order All-Pass stages + unsigned char Poutsub; //if I wish to subtract the output instead of adding unsigned char Pphase; + unsigned char Phyper; //lfo^2 -- converts tri into hyper-sine + unsigned char Pbarber; //Enable parber pole phasing + unsigned char Panalog; - //Control Parameters + //Control parameters void setvolume(unsigned char Pvolume); void setpanning(unsigned char Ppanning); void setdepth(unsigned char Pdepth); void setfb(unsigned char Pfb); + void setdistortion(unsigned char Pdistortion); + void setwidth(unsigned char Pwidth); + void setoffset(unsigned char Poffset); void setlrcross(unsigned char Plrcross); void setstages(unsigned char Pstages); void setphase(unsigned char Pphase); - //Internal Values - REALTYPE panning, fb, depth, lrcross, fbl, fbr, phase; - Stereo<Sample> old; - Stereo<REALTYPE> oldgain; + //Internal Variables + bool barber; //Barber pole phasing flag + REALTYPE distortion, width, offsetpct; + REALTYPE panning, feedback, depth, lrcross, phase; + Stereo<REALTYPE *> old, xn1, yn1; + Stereo<REALTYPE> diff, oldgain, fb; + REALTYPE invperiod; + REALTYPE offset[12]; + + float mis; + float Rmin; // 3N5457 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 + + void analog_setup(); + void AnalogPhase(const Stereo<REALTYPE *> &input); + //analog case + REALTYPE applyPhase(REALTYPE x, REALTYPE g, REALTYPE fb, + REALTYPE &hpf, REALTYPE *yn1, REALTYPE *xn1); + + void normalPhase(const Stereo<REALTYPE *> &input); + REALTYPE applyPhase(REALTYPE x, REALTYPE g, REALTYPE *old); }; #endif diff --git a/src/Misc/Stereo.cpp b/src/Misc/Stereo.cpp @@ -30,9 +30,10 @@ Stereo<T>::Stereo(const T &val) {} template<class T> -void Stereo<T>::operator=(const Stereo<T> &nstr) +Stereo<T> &Stereo<T>::operator=(const Stereo<T> &nstr) { - l = nstr.l; + l = nstr.l; r = nstr.r; + return *this; } diff --git a/src/Misc/Stereo.h b/src/Misc/Stereo.h @@ -33,10 +33,10 @@ struct Stereo Stereo() {}; ~Stereo() {} - void operator=(const Stereo<T> &smp); + Stereo<T> &operator=(const Stereo<T> &smp); - T l; - T r; + //data + T l, r; }; #include "Stereo.cpp" #endif diff --git a/src/Misc/Util.cpp b/src/Misc/Util.cpp @@ -153,3 +153,17 @@ std::string legalizeFilename(std::string filename) return filename; } +void invSignal(REALTYPE *sig, size_t len) +{ + for(int i = 0; i < len; i++) + sig[i] *= -1.0f; +} + +void crossover(REALTYPE &a, REALTYPE &b, REALTYPE crossover) +{ + REALTYPE tmpa = a; + REALTYPE tmpb = b; + a = tmpa * (1.0 - crossover) + tmpb * crossover; + b = tmpb * (1.0 - crossover) + tmpa * crossover; +} + diff --git a/src/Misc/Util.h b/src/Misc/Util.h @@ -53,6 +53,10 @@ extern REALTYPE *denormalkillbuf; /**<the buffer to add noise in order to avoid extern Config config; +void invSignal(REALTYPE *sig, size_t len); + +void crossover(REALTYPE &a, REALTYPE &b, REALTYPE crossover); + template<class T> std::string stringFrom(T x) { diff --git a/src/UI/EffUI.fl b/src/UI/EffUI.fl @@ -167,7 +167,6 @@ 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); @@ -585,14 +584,14 @@ refresh(eff);} } Function {make_phaser_window()} {} { Fl_Window effphaserwindow { - xywh {389 213 380 95} type Double box PLASTIC_UP_BOX color 221 labelfont 1 hide + xywh {75 25 380 95} type Double box PLASTIC_UP_BOX color 221 labelfont 1 hide class Fl_Group } { Fl_Choice phaserp { 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 + xywh {10 15 100 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} @@ -618,163 +617,66 @@ refresh(eff);} label {Phaser 6} xywh {80 80 100 20} labelfont 1 labelsize 10 labelcolor 7 } - } - Fl_Text_Display {} { - label Phaser - xywh {275 10 10 20} box NO_BOX labeltype EMBOSSED_LABEL labelfont 1 labelsize 22 align 8 - } - Fl_Dial phaserp0 { - 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 phaserp1 { - label Pan - callback {eff->seteffectpar(1,(int) o->value());} - xywh {45 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 11 maximum 127 - class WidgetPDial - } - Fl_Dial phaserp2 { - 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 phaserp3 { - label Rnd - callback {eff->seteffectpar(3,(int) o->value());} - tooltip {LFO randomness} xywh {120 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 11 when 4 maximum 127 - class WidgetPDial - } - Fl_Dial phaserp5 { - 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 phaserp6 { - 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 phaserp7 { - 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_Dial phaserp9 { - label {L/R} - callback {eff->seteffectpar(9,(int) o->value());} - tooltip {Channel Routing} xywh {345 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 11 maximum 127 - class WidgetPDial - } - Fl_Check_Button phaserp10 { - 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_Choice phaserp4 { - 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_Counter phaserp8 { - 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 phaserp11 { - label Phase - callback {eff->seteffectpar(11,(int) o->value());} - xywh {155 10 25 25} box ROUND_UP_BOX labelfont 1 labelsize 10 maximum 127 - class WidgetPDial - } - } - } - Function {make_analog_phaser_window()} {} { - Fl_Window effaphaserwindow {selected - xywh {292 251 380 95} type Double box PLASTIC_UP_BOX color 221 labelfont 1 hide - 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} + label {APhaser 1} xywh {40 40 100 20} labelfont 1 labelsize 10 labelcolor 7 } MenuItem {} { - label {Phaser 3} + label {APhaser 2} xywh {50 50 100 20} labelfont 1 labelsize 10 labelcolor 7 } MenuItem {} { - label {Phaser 4} + label {APhaser 3} xywh {60 60 100 20} labelfont 1 labelsize 10 labelcolor 7 } MenuItem {} { - label {Phaser 5} + label {APhaser 4} xywh {70 70 100 20} labelfont 1 labelsize 10 labelcolor 7 } MenuItem {} { - label {Phaser 6} + label {APhaser 5} xywh {80 80 100 20} labelfont 1 labelsize 10 labelcolor 7 } + MenuItem {} { + label {APhaser 6} selected + xywh {90 90 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 + label Phaser + xywh {275 10 10 20} box NO_BOX labeltype EMBOSSED_LABEL labelfont 1 labelsize 22 align 8 } - Fl_Dial aphaser0 { + Fl_Dial phaserp0 { 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 + Fl_Dial phaserp1 { + label Pan callback {eff->seteffectpar(1,(int) o->value());} - tooltip Distortion xywh {45 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 11 maximum 127 + xywh {45 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 11 maximum 127 class WidgetPDial } - Fl_Dial aphaser2 { + Fl_Dial phaserp2 { 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 + tooltip {LFO frequency} xywh {85 45 25 25} box ROUND_UP_BOX labelfont 1 labelsize 11 maximum 127 class WidgetPDial } - Fl_Dial aphaser3 { - label rnd + Fl_Dial phaserp3 { + 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 + tooltip {LFO randomness} xywh {120 45 25 25} box ROUND_UP_BOX labelfont 1 labelsize 11 when 4 maximum 127 class WidgetPDial } - Fl_Choice aphaser4 { - label {LFO type} + Fl_Choice phaserp4 { + label LFO 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 + tooltip {LFO function} xywh {245 55 40 15} down_box BORDER_BOX labelfont 1 labelsize 10 align 130 textsize 8 } { MenuItem {} { - label SINE + label SIN xywh {15 15 100 20} labelfont 1 labelsize 10 } MenuItem {} { @@ -782,51 +684,62 @@ refresh(eff);} xywh {25 25 100 20} labelfont 1 labelsize 10 } } - Fl_Dial aphaser5 { + Fl_Dial phaserp5 { 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 + tooltip {Left/Right Channel Phase Shift} xywh {155 45 25 25} box ROUND_UP_BOX labelfont 1 labelsize 11 maximum 127 class WidgetPDial } - Fl_Dial aphaser6 { + Fl_Dial phaserp6 { 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 + tooltip {LFO Depth} xywh {120 5 25 25} box ROUND_UP_BOX labelfont 1 labelsize 10 maximum 127 class WidgetPDial } - Fl_Dial aphaser7 { + Fl_Dial phaserp7 { 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 + tooltip Feedback xywh {185 45 25 25} box ROUND_UP_BOX labelfont 1 labelsize 11 maximum 127 class WidgetPDial } - Fl_Counter aphaser8 { + Fl_Counter phaserp8 { 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 + xywh {290 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 + Fl_Dial phaserp9 { + label {L/R} callback {eff->seteffectpar(9,(int) o->value());} - tooltip offset xywh {345 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 11 maximum 127 + tooltip {Channel Routing} xywh {215 45 25 25} box ROUND_UP_BOX labelfont 1 labelsize 11 maximum 127 class WidgetPDial } - Fl_Check_Button aphaser10 { + Fl_Check_Button phaserp10 { 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 + tooltip {inverts output} xywh {200 10 74 20} box THIN_UP_BOX down_box DOWN_BOX color 230 labelfont 1 labelsize 10 } - Fl_Dial aphaser11 { - label Depth + Fl_Dial phaserp11 { + label Phase callback {eff->seteffectpar(11,(int) o->value());} - xywh {155 10 25 25} box ROUND_UP_BOX labelfont 1 labelsize 10 maximum 127 + xywh {155 5 25 25} box ROUND_UP_BOX labelfont 1 labelsize 10 maximum 127 class WidgetPDial } - Fl_Check_Button aphaser12 { + Fl_Check_Button phaserp12 { label {hyp.} callback {eff->seteffectpar(12,(int) o->value());} - tooltip hyper xywh {100 10 55 15} down_box DOWN_BOX + tooltip hyper xywh {245 35 55 15} down_box DOWN_BOX + } + Fl_Dial phaserp13 { + label dist + callback {eff->seteffectpar(13,(int) o->value());} + tooltip Distortion xywh {340 50 25 25} box ROUND_UP_BOX labelfont 1 labelsize 11 maximum 127 + class WidgetPDial + } + Fl_Check_Button phaserp14 { + label Analog + callback {eff->seteffectpar(14,(int) o->value());} + xywh {305 35 70 15} down_box DOWN_BOX } } } @@ -1377,7 +1290,6 @@ 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(); @@ -1391,7 +1303,6 @@ 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); @@ -1399,7 +1310,8 @@ effdynamicfilterwindow->position(px,py); refresh(eff);} {} } - Function {refresh(EffectMgr *eff_)} {} { + Function {refresh(EffectMgr *eff_)} {open + } { code {eff=eff_; this->hide(); @@ -1408,7 +1320,6 @@ effreverbwindow->hide(); effechowindow->hide(); effchoruswindow->hide(); effphaserwindow->hide(); -effaphaserwindow->hide(); effalienwahwindow->hide(); effdistorsionwindow->hide(); effeqwindow->hide(); @@ -1481,6 +1392,9 @@ switch(eff->geteffect()){ phaserp9->value(eff->geteffectpar(9)); phaserp10->value(eff->geteffectpar(10)); phaserp11->value(eff->geteffectpar(11)); + phaserp12->value(eff->geteffectpar(12)); + phaserp13->value(eff->geteffectpar(13)); + phaserp14->value(eff->geteffectpar(14)); effphaserwindow->show(); break; case 5: @@ -1544,30 +1458,14 @@ switch(eff->geteffect()){ effdynamicfilterwindow->show(); break; - case 9://make_analog_phaser_window(); - aphaserp->value(eff->getpreset()); - aphaser0->value(eff->geteffectpar(0));if (eff->insertion!=0) aphaser0->label("D/W"); - 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)); - effaphaserwindow->show(); - break; default:effnullwindow->show(); break; }; this->show();} {} } - Function {refresh()} {} { + Function {refresh()} {open + } { code {refresh(eff);} {} } decl {EffectMgr *eff;} {} @@ -1940,79 +1838,6 @@ refresh(eff);} } } } - Function {make_analog_phaser_window()} {} { - Fl_Window effaphaserwindow { - xywh {367 295 230 95} type Double box PLASTIC_UP_BOX color 221 labelfont 1 hide - code0 {} - 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 {105 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 aphaser2 { - label Freq - callback {eff->seteffectpar(2,(int) o->value());} - tooltip {LFO frequency} xywh {50 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 {90 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 {135 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 {175 55 35 15} type Simple labelfont 1 labelsize 11 minimum 0 maximum 127 step 1 - code0 {o->range(1,MAX_PHASER_STAGES);} - } - } - } Function {make_alienwah_window()} {} { Fl_Window effalienwahwindow { xywh {367 170 230 95} type Double box PLASTIC_UP_BOX color 221 labelfont 1 hide @@ -2409,7 +2234,6 @@ 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(); @@ -2423,7 +2247,6 @@ 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); @@ -2440,7 +2263,6 @@ effreverbwindow->hide(); effechowindow->hide(); effchoruswindow->hide(); effphaserwindow->hide(); -effaphaserwindow->hide(); effalienwahwindow->hide(); effdistorsionwindow->hide(); effeqwindow->hide(); @@ -2525,17 +2347,6 @@ switch(eff->geteffect()){ effdynamicfilterwindow->show(); break; - case 9: - aphaserp->value(eff->getpreset()); - aphaser0->value(eff->geteffectpar(0));if (eff->insertion!=0) dfp0->label("D/W"); - aphaser2->value(eff->geteffectpar(2)); - aphaser6->value(eff->geteffectpar(6)); - aphaser7->value(eff->geteffectpar(7)); - aphaser8->value(eff->geteffectpar(8)); - - - effaphaserwindow->show(); - break; default:effnullwindow->show(); break; }; diff --git a/src/UI/MasterUI.fl b/src/UI/MasterUI.fl @@ -1,5 +1,5 @@ # data file for the Fltk User Interface Designer (fluid) -version 1.0107 +version 1.0110 header_name {.h} code_name {.cc} decl {//Copyright (c) 2002-2009 Nasca Octavian Paul} {} @@ -756,10 +756,6 @@ syseffectui->refresh(master->sysefx[nsyseff]);} label DynFilter xywh {90 90 100 20} labelfont 1 labelsize 10 } - MenuItem {} { - label APhaser - xywh {0 0 36 21} labelfont 1 labelsize 10 - } } Fl_Group syseffectuigroup { xywh {5 140 380 95} box FLAT_BOX color 48 @@ -859,10 +855,6 @@ inseffectui->show();} label DynFilter xywh {100 100 100 20} labelfont 1 labelsize 10 } - MenuItem {} { - label APhaser - xywh {0 0 36 21} labelfont 1 labelsize 10 - } } Fl_Group inseffectuigroup { xywh {5 140 380 95} box FLAT_BOX color 48 @@ -1380,10 +1372,6 @@ simplesyseffectui->refresh(master->sysefx[nsyseff]);} label DynFilter xywh {100 100 100 20} labelfont 1 labelsize 10 } - MenuItem {} { - label Aphaser - xywh {0 0 40 25} labelfont 1 labelsize 10 - } } Fl_Group simplesyseffectuigroup { xywh {350 95 235 95} box FLAT_BOX color 48 @@ -1437,7 +1425,7 @@ if (master->Pinsparts[ninseff]!=-1) { master->insefx[ninseff]->changeeffect((int) o->value()); pthread_mutex_unlock(&master->mutex); simpleinseffectui->refresh(master->insefx[ninseff]); -simpleinseffectui->show();} +simpleinseffectui->show();} selected xywh {515 80 70 15} down_box BORDER_BOX labelsize 10 align 5 code0 {o->value(master->insefx[ninseff]->geteffect());} code1 {if (master->Pinsparts[ninseff]== -1) o->deactivate();} @@ -1478,10 +1466,6 @@ simpleinseffectui->show();} label DynFilter xywh {110 110 100 20} labelfont 1 labelsize 10 } - MenuItem {} { - label Aphaser - xywh {0 0 40 25} labelfont 1 labelsize 10 - } } Fl_Group simpleinseffectuigroup { xywh {350 95 234 95} box FLAT_BOX color 48