#ifndef FIR_CC #define FIR_CC /* Copyright (c) 1994 Ohio Board of Regents and the University of Cincinnati. All Rights Reserved. ------------------------------------------------------------------ */ // FIR.cc // This template class implements an nth order FIR filter, where n // is specified by the user. To use it, #include "FIR.cc" at the top of // the file you'd like to use it in. Then include a declaration similar // to the following: // FIR filter(3) // // Replace "double" with whatever type you'd like it to input and output, // and "3" with whatever order filter you'd like to use. If you specify // a 0 or a 1 for a filter order, an error message is generated. #include template class FIR { public: FIR(int n = 1000); ~FIR(); inline Type getAvg(); inline void clear(); inline int numDatapoints() { return(num_valid); }; inline void update(Type); private: unsigned int size, num_valid, index; Type current_sum; Type *fir_array; }; // This is the constructor code for the class FIR. The integer passed into // it is the order of the filter. template inline FIR::FIR(int n) { if (n <= 1) { cerr << "A window size of " << n <<" makes NO sense!" << endl; } size = n; num_valid = 0; current_sum = 0; index = 0; fir_array = new Type[size]; for (register unsigned int i = 0; i < size;i++) { fir_array[i] = 0; } } // This is the destructor method for the class FIR. It deletes the // dynamically created array pointed at by "fir_array." template inline FIR::~FIR() { delete [] fir_array; } template inline void FIR::clear() { num_valid = 0; for (register unsigned int i = 0; i < size; i++) { fir_array[i] = 0; } } // This is the method which calculates and returns the current // output of the filter. If the filter isn't full yet, then the // average is computed on the valid data only. The return type is // whatever the template was initialized with. template inline Type FIR::getAvg() { if( num_valid < size ) { if( num_valid != 0 ){ return ( current_sum / num_valid ); } else { return 0; } } else { return ( current_sum / (Type)size ); } } // This is the method that updates the current state of the filter with // a new data point. The type of the new data should be the same as // the type that the filter was initialized with. The variable // num_valid will overflow if this method is called more than 2*INT_MAX // times. To avoid an extra computation, this check isn't made by the // method. template inline void FIR::update(Type new_element) { current_sum = current_sum + new_element; current_sum = current_sum - fir_array[index]; fir_array[index] = new_element; if (num_valid < size){ num_valid++; } index++; if( index == size ){ index = 0; } } #endif