00001 #ifndef FIRMI 00002 #define FIRMI 00003 #include <fir.h> 00004 // 00005 // Copyright(c) 1993-1996 Tony Kirke 00006 // author="Tony Kirke" * 00007 /* 00008 * SPUC - Signal processing using C++ - A DSP library 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, or (at your option) 00013 * 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., 675 Mass Ave, Cambridge, MA 02139, USA. 00023 */ 00024 namespace SPUC { 00028 00029 00030 template <class Numeric> class fir_multi_interp : public fir<Numeric> 00031 { 00032 public: 00033 long num_low; 00034 long channels; 00035 long rate; 00036 long phase; 00037 long auto_mode; 00038 00039 public: 00041 void skip() { phase++; phase = phase%rate; }; 00043 void set_rate(long r) { rate = r; num_low = (fir<Numeric>::num_taps/r - 1);} 00044 void set_automatic(void) { auto_mode = 1;}; 00045 void set_manual(int def_phase=0) { auto_mode = 0; phase=def_phase;}; 00046 00047 00049 fir_multi_interp<Numeric>(void) : phase(0), auto_mode(1), channels(1) { }; 00050 fir_multi_interp<Numeric>(long n, long m) : phase(0), auto_mode(1), channels(m) 00051 { 00052 int i; 00053 int mn = m*n; 00054 fir<Numeric>::num_taps = n; 00055 if (mn>0) { 00056 fir<Numeric>::coeff = new Numeric[n]; 00057 fir<Numeric>::z = new Numeric[mn]; 00058 for (i=0;i<n;i++) fir<Numeric>::coeff[i] = 0; 00059 for (i=0;i<mn;i++) fir<Numeric>::z[i] = 0; 00060 } 00061 }; 00062 void reset() { 00063 fir<Numeric>::reset(); 00064 phase = 0; 00065 } 00066 void input(Numeric in) { 00067 int i; 00068 // Update history of inputs 00069 for (i=channels*num_low;i>0;i--) fir<Numeric>::z[i] = fir<Numeric>::z[i-1]; 00070 // Add new input 00071 fir<Numeric>::z[0] = in; 00072 } 00074 Numeric clock(long set_phase) { 00075 phase = set_phase; 00076 return(clock()); 00077 } 00080 Numeric clock(void) { 00081 // Perform FIR 00082 Numeric output; 00083 int i; 00084 for (output=0,i=0;i<num_low;i++) { 00085 output += fir<Numeric>::coeff[(i+1)*rate+phase]*fir<Numeric>::z[i*channels]; 00086 } 00087 // Increment to next polyphase filter 00088 if (auto_mode) phase++; 00089 phase = phase%rate; 00090 return(output); 00091 } 00092 00093 }; 00094 } // namespace SPUC 00095 #endif