/*
  ZynAddSubFX - a software synthesizer

  APhaser.h - Phaser effect
  Copyright (C) 2002-2005 Nasca Octavian Paul
  Author: Nasca Octavian Paul

  Modified for rakarrack by Josep Andreu and Ryan Billing

  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 "../../../typedefs.h"

#ifdef SHR3D_SFX_CORE_RAKARRACK

#include "../common/Defines.h"
#include "../common/EffectLFO.h"


class AnalogPhaser
{
public:
  AnalogPhaser();
  void processBlock(const f32* const* inBlock, f32** outBlock, i32 blockSize);
  void setpreset(i32 npreset);
  void changepar(i32 npar, i32 value);
  i32 getpar(i32 npar);
  void cleanup();
  
  f32 outvolume;

private:
  //Phaser parameters
  EffectLFO lfo;		//Phaser modulator
  i32 Pvolume;        //Used in Process.C to set wet/dry mix
  i32 Pdistortion;    //Model distortion added by FET element
  i32 Pwidth;		//Phaser width (LFO amplitude)
  i32 Pfb;		//feedback
  i32 Poffset;	//Model mismatch between variable resistors
  i32 Pstages;	//Number of first-order All-Pass stages
  i32 Poutsub;	//if I wish to subtract the output instead of the adding it
  i32 Phyper;		//lfo^2 -- converts tri into hyper-sine
  i32 Pdepth;         //Depth of phaser sweep
  i32 Pbarber;         //Enable barber pole phasing

  //Control parameters
  void setvolume(i32 Pvolume);
  void setdistortion(i32 Pdistortion);
  void setwidth(i32 Pwidth);
  void setfb(i32 Pfb);
  void setoffset(i32 Poffset);
  void setstages(i32 Pstages);
  void setdepth(i32 Pdepth);

  //Internal Variables
  bool barber = 0;			//Barber pole phasing flag
  f32 distortion, fb, width, offsetpct, fbl, fbr, depth;
  f32 lxn1[MAX_PHASER_STAGES];
  f32 lyn1[MAX_PHASER_STAGES];
  f32 rxn1[MAX_PHASER_STAGES];
  f32 ryn1[MAX_PHASER_STAGES];
  f32 offset[MAX_PHASER_STAGES] = {
    -0.2509303f, 0.9408924f, 0.998f, -0.3486182f,
    -0.2762545f, -0.5215785f, 0.2509303f, -0.9408924f,
    -0.998f, 0.3486182f, 0.2762545f, 0.5215785f
  };
  f32 oldlgain, oldrgain, rdiff, ldiff, invperiod;

  f32 mis = 1.0f;
  f32 Rmin = 625.0f;	// 2N5457 typical on resistance at Vgs = 0
  f32 Rmax = 22000.0f;	// Resistor parallel to FET
  f32 Rmx = Rmin / Rmax;		// Rmin/Rmax to avoid division in loop
  f32 Rconst = 1.0f + Rmx;      // Handle parallel resistor relationship
  f32 C = 0.00000005f;	     // 50 nF	Capacitor
  f32 CFs;		// A constant derived from capacitor and resistor relationships
};

#endif // SHR3D_SFX_CORE_RAKARRACK

#endif
