Main Page | Class Hierarchy | Alphabetical List | Class List | File List | Class Members

Filter.h

00001 #ifndef INCLUDE_FILTER_H
00002 #define INCLUDE_FILTER_H
00003 /*
00004  * This is the Loris C++ Class Library, implementing analysis, 
00005  * manipulation, and synthesis of digitized sounds using the Reassigned 
00006  * Bandwidth-Enhanced Additive Sound Model.
00007  *
00008  * Loris is Copyright (c) 1999-2004 by Kelly Fitz and Lippold Haken
00009  *
00010  * This program is free software; you can redistribute it and/or modify
00011  * it under the terms of the GNU General Public License as published by
00012  * the Free Software Foundation; either version 2 of the License, or
00013  * (at your option) any later version.
00014  *
00015  * This program is distributed in the hope that it will be useful,
00016  * but WITHOUT ANY WARRANTY, without even the implied warranty of
00017  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00018  * GNU General Public License for more details.
00019  *
00020  * You should have received a copy of the GNU General Public License
00021  * along with this program; if not, write to the Free Software
00022  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00023  *
00024  *
00025  * Filter.h
00026  *
00027  * Definition of class Loris::Filter, a generic ARMA digital filter.
00028  *
00029  * Kelly Fitz, 1 Sept 1999
00030  * loris@cerlsoundgroup.org
00031  *
00032  * http://www.cerlsoundgroup.org/Loris/
00033  *
00034  */
00035 
00036 #include "Exception.h"
00037 #include "Notifier.h"
00038 
00039 #include <algorithm>
00040 #include <deque>
00041 #include <functional>
00042 #include <numeric>
00043 #include <vector>
00044 
00045 //  begin namespace
00046 namespace Loris {
00047 
00048 // ---------------------------------------------------------------------------
00049 //  class Filter
00050 //
00051 //  Filter is an Direct Form II realization of a filter specified
00052 //  by its difference equation coefficients and (optionally) gain,  
00053 //  applied to the filter output (defaults to 1.). Coefficients are
00054 //  specified and stored in order of increasing delay.
00055 //
00056 //  Filter is a leaf class, do not subclass.
00057 //
00058 class Filter
00059 {
00060 //  --- interface ---
00061 public:
00062     //  default construction:
00063     Filter( void );
00064     
00065     //  initialized construction:
00066     //
00067     //  If template members are allowed, then the coefficients
00068     //  can be stored in any kind of iterator range, otherwise,
00069     //  they must be in an array of doubles.
00070     //
00071 #if !defined(NO_TEMPLATE_MEMBERS)
00072     template<typename IterT1, typename IterT2>
00073     Filter( IterT1 ma_begin, IterT1 ma_end, //  feed-forward coeffs
00074             IterT2 ar_begin, IterT2 ar_end, //  feedback coeffs
00075             double gain = 1. );
00076 #else
00077     Filter( const double * ma_begin, const double * ma_end, //  feed-forward coeffs
00078             const double * ar_begin, const double * ar_end, //  feedback coeffs
00079             double gain = 1. );
00080 #endif
00081 
00082     //  copy and assignment do not copy the delay line state:
00083     Filter( const Filter & other );
00084     Filter & operator=( const Filter & rhs );
00085 
00086     //  compute next filtered sample from input sample:             
00087     double sample( double input );
00088 
00089     //  function call operator:
00090     double operator() ( double input ) { return sample(input); }
00091     
00092     //  clear the delay line:
00093     void clear( void );
00094     
00095 //  --- implementation ---
00096     //  delay line:
00097     std::deque< double > _delayline;
00098         
00099     //  ARMA coefficients:
00100     std::vector< double > _maCoefs, _arCoefs;   
00101     
00102     //  filter gain (applied to output)
00103     double _gain;       
00104 
00105 };  //  end of class Filter
00106 
00107 // ---------------------------------------------------------------------------
00108 //  constructor
00109 // ---------------------------------------------------------------------------
00110 //  If template members are allowed, then the coefficients
00111 //  can be stored in any kind of iterator range, otherwise,
00112 //  they must be in an array of doubles.
00113 //
00114 #if !defined(NO_TEMPLATE_MEMBERS)
00115 template<typename IterT1, typename IterT2>
00116 Filter::Filter( IterT1 ma_begin, IterT1 ma_end, //  feed-forward coeffs
00117                 IterT2 ar_begin, IterT2 ar_end, //  feedback coeffs
00118                 double gain ) :
00119 #else
00120 inline 
00121 Filter::Filter( const double * ma_begin, const double * ma_end, //  feed-forward coeffs
00122                 const double * ar_begin, const double * ar_end, //  feedback coeffs
00123                 double gain ) :
00124 #endif
00125     _maCoefs( ma_begin, ma_end ),
00126     _arCoefs( ar_begin, ar_end ),
00127     _delayline( std::max( ma_end-ma_begin, ar_end-ar_begin ) - 1, 0. ),
00128     _gain( gain )
00129 {
00130     if ( *ar_begin == 0. )
00131     {
00132         Throw( InvalidObject, "Tried to create a Filter with zero AR coefficient at zero delay." );
00133     }
00134 
00135     debugger << "constructing a Filter with " << _maCoefs.size();
00136     debugger << " feed-forward coefficients and " << _arCoefs.size();
00137     debugger << " feedback coefficients, with a delay lines of length ";
00138     debugger << _delayline.size() << std::endl;
00139     if ( *ar_begin != 1. )
00140     {
00141         //  scale all filter coefficients by a[0]:
00142         std::transform( _maCoefs.begin(), _maCoefs.end(), _maCoefs.begin(),
00143                         std::bind2nd( std::divides<double>(), *ar_begin ) );
00144         std::transform( _arCoefs.begin(), _arCoefs.end(), _arCoefs.begin(), 
00145                         std::bind2nd( std::divides<double>(), *ar_begin ) );
00146         _arCoefs[0] = 1.;
00147     }
00148     debugger << _maCoefs[0] << " " << _maCoefs[1] << " " << _maCoefs[2] << " " << _maCoefs[3] << " " << std::endl;
00149     debugger << _arCoefs[0] << " " << _arCoefs[2] << " " << _arCoefs[2] << " " << _arCoefs[3] << " " << std::endl;
00150 }
00151 
00152 
00153 }   //  end of namespace Loris
00154 
00155 #endif /* ndef INCLUDE_FILTER_H */

Generated on Thu Apr 14 22:01:55 2005 for Loris by doxygen 1.3.4