| 
							- /*
 -   ZynAddSubFX - a software synthesizer
 - 
 -   Alienwah.cpp - "AlienWah" effect
 -   Copyright (C) 2002-2005 Nasca Octavian Paul
 -   Author: Nasca Octavian Paul
 - 
 -   This program is free software; you can redistribute it and/or
 -   modify it under the terms of the GNU General Public License
 -   as published by the Free Software Foundation; either version 2
 -   of the License, or (at your option) any later version.
 - */
 - 
 - #include <cmath>
 - #include <rtosc/port-sugar.h>
 - #include <rtosc/ports.h>
 - #include "../Misc/Allocator.h"
 - #include "Alienwah.h"
 - 
 - namespace zyncarla {
 - 
 - using std::complex;
 - 
 - #define rObject Alienwah
 - #define rBegin [](const char *msg, rtosc::RtData &d) {
 - #define rEnd }
 - 
 - rtosc::Ports Alienwah::ports = {
 -     {"preset::i", rProp(parameter)
 -                   rOptions(wah 1, wah 2, wah 3, wah 4)
 -                   rDoc("Instrument Presets"), 0,
 -                   rBegin;
 -                   rObject *o = (rObject*)d.obj;
 -                   if(rtosc_narguments(msg))
 -                       o->setpreset(rtosc_argument(msg, 0).i);
 -                   else
 -                       d.reply(d.loc, "i", o->Ppreset);
 -                   rEnd},
 -     rEffParVol(rDefault(127), rPresetsAt(3, 93)),
 -     rEffParPan(),
 -     rEffPar(Pfreq,     2, rShort("freq") rPresets(70, 73, 63, 25),
 -             "Effect Frequency"),
 -     rEffPar(Pfreqrnd,  3, rShort("rand"), rPreset(1, 106) rDefault(0),
 -             "Frequency Randomness"),
 -     rEffPar(PLFOtype,  4, rShort("shape"),
 -             rOptions(sine, triangle), rPresets(sine, sine, triangle, triangle),
 -             "LFO Shape"),
 -     rEffPar(PStereo,   5, rShort("stereo"), rPresets(62, 101, 100, 66),
 -             "Stereo Mode"),
 -     rEffPar(Pdepth,    6, rShort("depth"), rPresets(60, 60, 112, 101),
 -             "LFO Depth"),
 -     rEffPar(Pfeedback, 7, rShort("fb"), rPreset(3, 11), rDefault(105),
 -             "Feedback"),
 -     rEffPar(Pdelay,    8, rLinear(1,100), rPresets(25, 17, 31, 47),
 -             rShort("delay"), "Delay"),
 -     rEffPar(Plrcross,  9, rShort("l/r"), rDefault(0), "Left/Right Crossover"),
 -     rEffPar(Pphase,   10, rShort("phase"), rDefault(64), rPreset(2, 42),
 -             rPreset(3, 86), "Phase"),
 - };
 - #undef rBegin
 - #undef rEnd
 - #undef rObject
 - 
 - Alienwah::Alienwah(EffectParams pars)
 -     :Effect(pars),
 -       lfo(pars.srate, pars.bufsize),
 -       oldl(NULL),
 -       oldr(NULL)
 - {
 -     setpreset(Ppreset);
 -     cleanup();
 -     oldclfol = complex<float>(fb, 0.0f);
 -     oldclfor = complex<float>(fb, 0.0f);
 - }
 - 
 - Alienwah::~Alienwah()
 - {
 -     memory.devalloc(oldl);
 -     memory.devalloc(oldr);
 - }
 - 
 - 
 - //Apply the effect
 - void Alienwah::out(const Stereo<float *> &smp)
 - {
 -     float lfol, lfor; //Left/Right LFOs
 -     complex<float> clfol, clfor;
 -     /**\todo Rework, as optimization can be used when the new complex type is
 -      * utilized.
 -      * Before all calculations needed to be done with individual float,
 -      * but now they can be done together*/
 -     lfo.effectlfoout(&lfol, &lfor);
 -     lfol *= depth * PI * 2.0f;
 -     lfor *= depth * PI * 2.0f;
 -     clfol = complex<float>(cosf(lfol + phase) * fb, sinf(lfol + phase) * fb); //rework
 -     clfor = complex<float>(cosf(lfor + phase) * fb, sinf(lfor + phase) * fb); //rework
 - 
 -     for(int i = 0; i < buffersize; ++i) {
 -         float x  = ((float) i) / buffersize_f;
 -         float x1 = 1.0f - x;
 -         //left
 -         complex<float> tmp = clfol * x + oldclfol * x1;
 - 
 -         complex<float> out = tmp * oldl[oldk];
 -         out += (1 - fabs(fb)) * smp.l[i] * pangainL;
 - 
 -         oldl[oldk] = out;
 -         float l = out.real() * 10.0f * (fb + 0.1f);
 - 
 -         //right
 -         tmp = clfor * x + oldclfor * x1;
 - 
 -         out = tmp * oldr[oldk];
 -         out += (1 - fabs(fb)) * smp.r[i] * pangainR;
 - 
 -         oldr[oldk] = out;
 -         float r = out.real() * 10.0f * (fb + 0.1f);
 - 
 - 
 -         if(++oldk >= Pdelay)
 -             oldk = 0;
 -         //LRcross
 -         efxoutl[i] = l * (1.0f - lrcross) + r * lrcross;
 -         efxoutr[i] = r * (1.0f - lrcross) + l * lrcross;
 -     }
 - 
 -     oldclfol = clfol;
 -     oldclfor = clfor;
 - }
 - 
 - //Cleanup the effect
 - void Alienwah::cleanup(void)
 - {
 -     for(int i = 0; i < Pdelay; ++i) {
 -         oldl[i] = complex<float>(0.0f, 0.0f);
 -         oldr[i] = complex<float>(0.0f, 0.0f);
 -     }
 -     oldk = 0;
 - }
 - 
 - 
 - //Parameter control
 - void Alienwah::setdepth(unsigned char _Pdepth)
 - {
 -     Pdepth = _Pdepth;
 -     depth  = Pdepth / 127.0f;
 - }
 - 
 - void Alienwah::setfb(unsigned char _Pfb)
 - {
 -     Pfb = _Pfb;
 -     fb  = fabs((Pfb - 64.0f) / 64.1f);
 -     fb  = sqrtf(fb);
 -     if(fb < 0.4f)
 -         fb = 0.4f;
 -     if(Pfb < 64)
 -         fb = -fb;
 - }
 - 
 - void Alienwah::setvolume(unsigned char _Pvolume)
 - {
 -     Pvolume   = _Pvolume;
 -     outvolume = Pvolume / 127.0f;
 -     if(insertion == 0)
 -         volume = 1.0f;
 -     else
 -         volume = outvolume;
 - }
 - 
 - void Alienwah::setphase(unsigned char _Pphase)
 - {
 -     Pphase = _Pphase;
 -     phase  = (Pphase - 64.0f) / 64.0f * PI;
 - }
 - 
 - void Alienwah::setdelay(unsigned char _Pdelay)
 - {
 -     memory.devalloc(oldl);
 -     memory.devalloc(oldr);
 -     Pdelay = limit<int>(_Pdelay, 1, MAX_ALIENWAH_DELAY);
 -     oldl   = memory.valloc<complex<float>>(Pdelay);
 -     oldr   = memory.valloc<complex<float>>(Pdelay);
 -     cleanup();
 - }
 - 
 - void Alienwah::setpreset(unsigned char npreset)
 - {
 -     const int     PRESET_SIZE = 11;
 -     const int     NUM_PRESETS = 4;
 -     unsigned char presets[NUM_PRESETS][PRESET_SIZE] = {
 -         //AlienWah1
 -         {127, 64, 70, 0,   0, 62,  60,  105, 25, 0, 64},
 -         //AlienWah2
 -         {127, 64, 73, 106, 0, 101, 60,  105, 17, 0, 64},
 -         //AlienWah3
 -         {127, 64, 63, 0,   1, 100, 112, 105, 31, 0, 42},
 -         //AlienWah4
 -         {93,  64, 25, 0,   1, 66,  101, 11,  47, 0, 86}
 -     };
 - 
 -     if(npreset >= NUM_PRESETS)
 -         npreset = NUM_PRESETS - 1;
 -     for(int n = 0; n < PRESET_SIZE; ++n)
 -         changepar(n, presets[npreset][n]);
 -     if(insertion == 0)
 -         changepar(0, presets[npreset][0] / 2);  //lower the volume if this is system effect
 -     Ppreset = npreset;
 - }
 - 
 - 
 - void Alienwah::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:
 -             setdelay(value);
 -             break;
 -         case 9:
 -             setlrcross(value);
 -             break;
 -         case 10:
 -             setphase(value);
 -             break;
 -     }
 - }
 - 
 - unsigned char Alienwah::getpar(int npar) const
 - {
 -     switch(npar) {
 -         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 Pdelay;
 -         case 9:  return Plrcross;
 -         case 10: return Pphase;
 -         default: return 0;
 -     }
 - }
 - 
 - }
 
 
  |