firfilter.hpp (3047B)
1 /*============================================================================= 2 // 3 // This software has been released under the terms of the GNU Public 4 // license. See http://www.gnu.org/copyleft/gpl.html for details. 5 // 6 // Copyright 2001 Anders Johansson ajh@atri.curtin.edu.au 7 // 8 //============================================================================= 9 */ 10 11 #ifndef _FIRFILTER_H_ 12 #define _FIRFILTER_H_ 13 14 // Design and implementation of different types of digital filters 15 class TfirFilter 16 { 17 public: 18 enum class Type 19 { 20 LOWPASS = 0, 21 HIGHPASS = 1, 22 BANDPASS = 2, 23 BANDSTOP = 3 24 }; 25 enum class Window 26 { 27 BOX = 0, 28 TRIANGLE = 1, 29 HAMMING = 2, 30 HANNING = 3, 31 BLACKMAN = 4, 32 FLATTOP = 5, 33 KAISER = 6 34 }; 35 36 typedef float _ftype_t; 37 private: 38 static _ftype_t besselizero(_ftype_t x); 39 static void boxcar(int n, _ftype_t* w); 40 static void triang(int n, _ftype_t* w); 41 static void hanning(int n, _ftype_t* w); 42 static void hamming(int n,_ftype_t* w); 43 static void blackman(int n,_ftype_t* w); 44 static void flattop(int n,_ftype_t* w); 45 static void kaiser(int n, _ftype_t* w,_ftype_t b); 46 47 template<class T,class _ftype_t> static _ftype_t dotproduct(int count,const T *buf,const _ftype_t *coefficients) 48 { 49 _ftype_t sum0=0,sum1=0,sum2=0,sum3=0; 50 for (;count>=4;buf+=4,coefficients+=4,count-=4) 51 { 52 sum0+=buf[0]*coefficients[0]; 53 sum1+=buf[1]*coefficients[1]; 54 sum2+=buf[2]*coefficients[2]; 55 sum3+=buf[3]*coefficients[3]; 56 } 57 while (count--) sum0+= *buf++ * *coefficients++; 58 return sum0+sum1+sum2+sum3; 59 } 60 public: 61 // Exported functions 62 //static _ftype_t fir(unsigned int n, _ftype_t* w, _ftype_t* x); 63 static int updateq(unsigned int n, unsigned int xi, _ftype_t* xq, _ftype_t* in); 64 static _ftype_t* design_fir(unsigned int *n, _ftype_t* fc, Type type, Window window, _ftype_t opt); 65 template<class T> static T firfilter(const T *buf, int pos, int len, int count, const _ftype_t *coefficients) 66 { 67 int count1, count2; 68 69 if (pos >= count) 70 { 71 pos -= count; 72 count1 = count; count2 = 0; 73 } 74 else 75 { 76 count2 = pos; 77 count1 = count - pos; 78 pos = len - count1; 79 } 80 81 // high part of window 82 const T *ptr = &buf[pos]; 83 #if 0 84 _ftype_t result=0.0; 85 while (count1--) result += *ptr++ * *coefficients++; 86 // wrapped part of window 87 while (count2--) result += *buf++ * *coefficients++; 88 return T(result); 89 #else 90 _ftype_t r1=dotproduct(count1,ptr,coefficients);coefficients+=count1; 91 _ftype_t r2=dotproduct(count2,buf,coefficients); 92 return T(r1+r2); 93 #endif 94 } 95 }; 96 97 template<> inline TfirFilter::_ftype_t TfirFilter::dotproduct<float,float>(int count,const float *buf,const float *coefficients) 98 { 99 float sum0=0,sum1=0,sum2=0,sum3=0; 100 for (;count>=4;buf+=4,coefficients+=4,count-=4) 101 { 102 sum0+=buf[0]*coefficients[0]; 103 sum1+=buf[1]*coefficients[1]; 104 sum2+=buf[2]*coefficients[2]; 105 sum3+=buf[3]*coefficients[3]; 106 } 107 while (count--) sum0+= *buf++ * *coefficients++; 108 return sum0+sum1+sum2+sum3; 109 } 110 111 #endif