// 
// Copyright(c) 1993-1996 Tony Kirke
// author="Tony Kirke" *
/*
 * SPUC - Signal processing using C++ - A DSP library
 * 
 * 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, or (at your option)
 * any later version.
 * 
 * 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 for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef IIR_1ST
#define IIR_1ST
#include <iostream>
using namespace std;
namespace SPUC {
//! \brief  Template Class for 1st Order iir filter
//!
//! \ingroup iir
//!   Template for 1st Order IIR filter<p>
//!   The filter is assumed the first order low pass digital filter 
//!   generated by the bilinear transform of a first order analog 
//!   filter.
//!   \f$ G(z) =  \frac{1+z^-1}{1-a*z^-1} \f$ <p>where a is real and |a| < 1
//!   Note: Not normalized
template <class Numeric> class iir_1st
{
    protected:   
    	double gain;                    
    	Numeric out;
        Numeric previous_out;
		Numeric previous_in;
        
    public:
        iir_1st(double A=0) : gain(A) {
        	previous_in = previous_out = out = 0 ; }
		void set_coeff(double A) { gain=A;}
		//! Constructor reading coefficient from a file.
		iir_1st(const char* file)
		  {
			FILE *iirf = fopen(file,"r"); 
			fscanf(iirf,"%lf",&gain);
			fclose(iirf);
			previous_in = previous_out = out = 0;
		  }             
		//! Print out coefficients
		void print() {
			cout << "IIR Coefficient gain = " << gain << "\n";
		}
		//! Input new sample and calculate output
		Numeric clock(Numeric input) {
		  // Shift previous outputs and calculate new output */
		  //	out = gain*previous_out + (1-gain)*input;
		  out = gain*previous_out + (input+previous_in);
		  previous_out = out;
		  previous_in = input;
		  return(out);
		}
		//! Reset
		void reset() {
		  previous_in = previous_out = out = 0;
		}
};                                               
} // namespace SPUC 
#endif
