00001 // 00002 // author="Tony Kirke" 00003 // Copyright(c) 1993-1996 Tony Kirke 00004 /* 00005 * SPUC - Signal processing using C++ - A DSP library 00006 * 00007 * This program is free software; you can redistribute it and/or modify 00008 * it under the terms of the GNU General Public License as published by 00009 * the Free Software Foundation; either version 2, or (at your option) 00010 * any later version. 00011 * 00012 * This program is distributed in the hope that it will be useful, 00013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00015 * GNU General Public License for more details. 00016 * 00017 * You should have received a copy of the GNU General Public License 00018 * along with this program; if not, write to the Free Software 00019 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 00020 */ 00021 #ifndef FARROW 00022 #define FARROW 00023 #include <complex.h> 00024 namespace SPUC { 00032 00033 00034 00035 00036 00037 00038 00039 00040 00041 00042 00043 template <class Numeric> class farrow 00044 { 00045 public: 00046 long num_taps; 00047 Numeric* coeff; 00048 protected: 00049 Numeric* z; 00050 Numeric output; 00051 00052 public: 00054 Numeric out() { return(output); } 00056 Numeric check(long i) { return(z[i]); } 00058 farrow(char order) : num_taps(order) { 00059 int i; 00060 coeff = new Numeric[num_taps+1]; 00061 z = new Numeric[num_taps+2]; 00062 for (i=0;i<=num_taps;i++) { 00063 z[i] = 0; 00064 coeff[i] = 0; 00065 } 00066 } 00068 void reset(void) { 00069 int i; 00070 for (i=0;i<=num_taps;i++) z[i] = 0; 00071 output = 0; 00072 } 00073 ~farrow(void) { 00074 delete [] coeff; 00075 delete [] z; 00076 } 00078 void input(Numeric in) { 00079 int i; 00081 for (i=num_taps+1;i>0;i--) z[i] = z[i-1]; 00083 z[0] = in; 00084 } 00085 00089 Numeric update(Numeric in, double offset) { 00090 int i; 00092 for (i=num_taps+1;i>0;i--) z[i] = z[i-1]; 00094 z[0] = in; 00096 if (num_taps == 1) return(in); 00097 else if (num_taps == 2) calculate_coeff2(); 00098 else if (num_taps == 3) calculate_coeff3(); 00099 else if (num_taps == 4) calculate_coeff4(); 00101 return(fir(offset)); 00102 } 00104 Numeric fir(double offset) { 00106 double gain = offset; 00107 output = coeff[0]; 00108 for (int i=1;i<num_taps;i++) { 00109 output += offset*coeff[i]; 00110 offset *= gain; 00111 } 00112 return(output); 00113 } 00115 Numeric rephase(double offset) { 00116 if (num_taps == 1) return(z[0]); 00117 else if (num_taps == 2) calculate_coeff2(); 00118 else if (num_taps == 3) calculate_coeff3(); 00119 else if (num_taps == 4) calculate_coeff4(); 00120 return(fir(offset)); 00121 } 00123 void calculate_coeff2(void) { 00125 coeff[1] = z[0] - z[1]; 00126 coeff[0] = z[1]; 00127 } 00129 void calculate_coeff3(void) { 00131 coeff[2] = z[0] - 2*z[1] + z[2]; 00132 coeff[1] = z[0] - z[2]; 00133 coeff[0] = ((Numeric)2)*z[1]; 00134 } 00136 void calculate_coeff3a(void) { 00138 coeff[2] = (z[0] - z[1] - z[2] + z[3]); 00139 coeff[1] = -z[0] + ((Numeric)3)*z[1] - z[2] - z[3]; 00140 coeff[0] = ((Numeric)2)*z[2]; 00141 } 00143 void calculate_coeff4(void) { 00144 coeff[3] = -z[3] + ((Numeric)3)*z[2] - ((Numeric)3)*z[1] + z[0]; 00145 coeff[2] = ((Numeric)3)*z[3] - ((Numeric)6)*z[2] + ((Numeric)3)*z[1]; 00146 coeff[1] = ((Numeric)-2)*z[3] - ((Numeric)3)*z[2] + ((Numeric)6)*z[1] - z[0]; 00147 coeff[0] = ((Numeric)6)*z[2]; 00148 } 00149 }; 00150 } 00151 #endif