0
$\begingroup$

I tried to understand the following source code of a Phaser:

#define SR (44100.f)  //sample rate
#define F_PI (3.14159f)

 class Phaser{
 public:
     Phaser()  //initialise to some usefull defaults...
      : _fb( .7f )
      , _lfoPhase( 0.f )
      , _depth( 1.f )
      , _zm1( 0.f )
  {
    Range( 440.f, 1600.f );
    Rate( .5f );
  }

  void Range( float fMin, float fMax ){ // Hz
      _dmin = fMin / (SR/2.f);
      _dmax = fMax / (SR/2.f);
  }

  void Rate( float rate ){ // cps
      _lfoInc = 2.f * F_PI * (rate / SR);
  }

  void Feedback( float fb ){ // 0 -> <1.
      _fb = fb;
  }

  void Depth( float depth ){  // 0 -> 1.
      _depth = depth;
  }

  float Update( float inSamp ){
      //calculate and update phaser sweep lfo...
      float d  = _dmin + (_dmax-_dmin) * ((sin( _lfoPhase ) +  1.f)/2.f);
      _lfoPhase += _lfoInc;
      if( _lfoPhase >= F_PI * 2.f )
          _lfoPhase -= F_PI * 2.f;

      //update filter coeffs
      for( int i=0; i<6; i++ )
          _alps[i].Delay( d );

      //calculate output
      float y =     _alps[0].Update(
                   _alps[1].Update(
                    _alps[2].Update(
                     _alps[3].Update(
                      _alps[4].Update(
                       _alps[5].Update( inSamp + _zm1 * _fb ))))));
      _zm1 = y;

      return inSamp + y * _depth;
  }
 private:
     class AllpassDelay{
     public:
      AllpassDelay()
          : _a1( 0.f )
          , _zm1( 0.f )
          {}

      void Delay( float delay ){ //sample delay time
          _a1 = (1.f - delay) / (1.f + delay);
      }

      float Update( float inSamp ){
          float y = inSamp * -_a1 + _zm1;
          _zm1 = y * _a1 + inSamp;

          return y;
      }
  private:
      float _a1, _zm1;
  };

  AllpassDelay _alps[6];

  float _dmin, _dmax; //range
  float _fb; //feedback
  float _lfoPhase;
  float _lfoInc;
  float _depth;

  float _zm1;

};

I understood most of it but i can´t find out what the purpose of the _zm1 variables is. There are two of them one in the AllpassDelay class, which are never used and one in the Phaser class which modifies the feedback. Can someone explain me what this does? Thanks

$\endgroup$

1 Answer 1

0
$\begingroup$

_zm1 is the internal state variable of the allpass. The allpass is an IIR filter and hence it's current output is dependent on past inputs and outputs. This is the way to keep track of this.

In this particular case it's implemented using a set of coupled difference equation in so-called "Transposed Form II" filter topology. So $zm_1[n] = y[n]*a_1+x[n]*b_1 $ . For a first order allpass we have $b_1 = 1$

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.