Adding a FIR filter implemented with its own internal buffer. This one keeps its...
authorTom Rondeau <trondeau@vt.edu>
Sat, 16 Oct 2010 15:13:53 +0000 (11:13 -0400)
committerTom Rondeau <trondeau@vt.edu>
Sat, 16 Oct 2010 15:13:53 +0000 (11:13 -0400)
The synthesis filter is being updated to use the new FIR implementation.

gnuradio-core/src/lib/filter/Makefile.am
gnuradio-core/src/lib/filter/gr_pfb_synthesis_filterbank_ccf.cc
gnuradio-core/src/lib/filter/gr_pfb_synthesis_filterbank_ccf.h
gnuradio-core/src/lib/filter/gri_fir_filter_with_buffer_ccf.cc [new file with mode: 0644]
gnuradio-core/src/lib/filter/gri_fir_filter_with_buffer_ccf.h [new file with mode: 0644]

index 6a6532eb0ac1df7e599e7909322278bb5d46ad6f..5c7473d06f688954984e034906a1439d17886df4 100644 (file)
@@ -1,5 +1,5 @@
 #
-# Copyright 2001,2002,2004,2005,2006,2007,2008,2009 Free Software Foundation, Inc.
+# Copyright 2001,2002,2004,2005,2006,2007,2008,2009,2010 Free Software Foundation, Inc.
 # 
 # This file is part of GNU Radio
 # 
@@ -190,6 +190,7 @@ libfilter_la_common_SOURCES =               \
        gr_fft_filter_fff.cc            \
        gr_goertzel_fc.cc               \
        gr_filter_delay_fc.cc           \
+       gri_fir_filter_with_buffer_ccf.cc \
        gr_fractional_interpolator_ff.cc \
        gr_fractional_interpolator_cc.cc \
        gr_hilbert_fc.cc                \
@@ -267,6 +268,7 @@ grinclude_HEADERS =                         \
        gr_fft_filter_ccc.h             \
        gr_fft_filter_fff.h             \
        gr_filter_delay_fc.h            \
+       gri_fir_filter_with_buffer_ccf.h \
        gr_fir_sysconfig_x86.h          \
        gr_fir_sysconfig_powerpc.h      \
        gr_fractional_interpolator_ff.h \
index b1365bcf904946d85f5504b3ea3d9fdb3ffaea54..0b31bcf72e7cba77a6a7614ead65a61dc7889b93 100644 (file)
@@ -48,16 +48,18 @@ gr_pfb_synthesis_filterbank_ccf::gr_pfb_synthesis_filterbank_ccf
                          numchans),
     d_updated (false), d_numchans(numchans)
 {
-  d_filters = std::vector<gr_fir_ccf*>(d_numchans);
+  //d_filters = std::vector<gr_fir_ccf*>(d_numchans);
+  d_filters = std::vector<gri_fir_filter_with_buffer_ccf*>(d_numchans);
 
-  d_buffer = new gr_complex*[d_numchans];
+  //d_buffer = new gr_complex*[d_numchans];
 
   // Create an FIR filter for each channel and zero out the taps
   std::vector<float> vtaps(0, d_numchans);
   for(unsigned int i = 0; i < d_numchans; i++) {
-    d_filters[i] = gr_fir_util::create_gr_fir_ccf(vtaps);
-    d_buffer[i] = new gr_complex[65535];
-    memset(d_buffer[i], 0, 65535*sizeof(gr_complex));
+    d_filters[i] = new gri_fir_filter_with_buffer_ccf(vtaps);
+    //d_filters[i] = gr_fir_util::create_gr_fir_ccf(vtaps);
+    //d_buffer[i] = new gr_complex[65535];
+    //memset(d_buffer[i], 0, 65535*sizeof(gr_complex));
   }
 
   // Now, actually set the filters' taps
@@ -134,7 +136,7 @@ gr_pfb_synthesis_filterbank_ccf::work (int noutput_items,
   gr_complex *out = (gr_complex *) output_items[0];
   int numsigs = input_items.size();
   int ndiff   = d_numchans - numsigs;
-  int nhalf = (int)ceil((float)numsigs/2.0f);
+  unsigned int nhalf = (unsigned int)ceil((float)numsigs/2.0f);
 
   if (d_updated) {
     d_updated = false;
@@ -165,18 +167,22 @@ gr_pfb_synthesis_filterbank_ccf::work (int noutput_items,
     d_fft->execute();
 
     for(i = 0; i < d_numchans; i++) {
-      d_buffer[i][n+d_taps_per_filter-1] = d_fft->get_outbuf()[i];
-      out[d_numchans-i-1] = d_filters[d_numchans-i-1]->filter(&d_buffer[i][n]);
+      //d_buffer[i][n+d_taps_per_filter-1] = d_fft->get_outbuf()[i];
+      //out[d_numchans-i-1] = d_filters[d_numchans-i-1]->filter(&d_buffer[i][n]);
+      out[d_numchans-i-1] = d_filters[d_numchans-i-1]->filter(d_fft->get_outbuf()[i]);
     }
     out += d_numchans;
   }
 
   // Move the last chunk of memory to the front for the next entry
   // this make sure that the first taps_per_filter values are correct
+
+  /*
   for(i = 0; i < d_numchans; i++) {
     memcpy(d_buffer[i], &d_buffer[i][n],
           (d_taps_per_filter)*sizeof(gr_complex));
   }
+  */
 
   return noutput_items;
 }
index 4b6235a8b597867c59317b63a65b7ed2ef25f9b8..27c8c2c5088d63d3e892ff6d2a35a16541bff3ef 100644 (file)
@@ -25,6 +25,7 @@
 #define        INCLUDED_GR_PFB_SYNTHESIS_FILTERBANK_CCF_H
 
 #include <gr_sync_interpolator.h>
+#include <gri_fir_filter_with_buffer_ccf.h>
 
 class gr_pfb_synthesis_filterbank_ccf;
 typedef boost::shared_ptr<gr_pfb_synthesis_filterbank_ccf> gr_pfb_synthesis_filterbank_ccf_sptr;
@@ -49,24 +50,29 @@ class gr_pfb_synthesis_filterbank_ccf : public gr_sync_interpolator
  private:
   /*!
    * Build the polyphase synthesis filterbank.
-   * \param numchans (unsigned integer) Specifies the number of channels <EM>M</EM>
-   * \param taps    (vector/list of floats) The prototype filter to populate the filterbank.
+   * \param numchans (unsigned integer) Specifies the number of 
+                     channels <EM>M</EM>
+   * \param taps    (vector/list of floats) The prototype filter to
+                    populate the filterbank.
    */
   friend gr_pfb_synthesis_filterbank_ccf_sptr gr_make_pfb_synthesis_filterbank_ccf 
       (unsigned int numchans, const std::vector<float> &taps);
 
   bool                    d_updated;
   unsigned int             d_numchans;
-  std::vector<gr_fir_ccf*> d_filters;
-  std::vector< std::vector<float> > d_taps;
   unsigned int             d_taps_per_filter;
   gri_fft_complex         *d_fft;
-  gr_complex             **d_buffer;
+  //gr_complex             **d_buffer;
+  std::vector< gri_fir_filter_with_buffer_ccf*> d_filters;
+  std::vector< std::vector<float> > d_taps;
+
 
   /*!
    * Build the polyphase synthesis filterbank.
-   * \param numchans (unsigned integer) Specifies the number of channels <EM>M</EM>
-   * \param taps    (vector/list of floats) The prototype filter to populate the filterbank.
+   * \param numchans (unsigned integer) Specifies the number of
+                     channels <EM>M</EM>
+   * \param taps    (vector/list of floats) The prototype filter
+                    to populate the filterbank.
    */
   gr_pfb_synthesis_filterbank_ccf (unsigned int numchans, 
                                   const std::vector<float> &taps);
@@ -76,7 +82,8 @@ public:
   
   /*!
    * Resets the filterbank's filter taps with the new prototype filter
-   * \param taps    (vector/list of floats) The prototype filter to populate the filterbank.
+   * \param taps    (vector/list of floats) The prototype filter to
+                    populate the filterbank.
    */
   void set_taps (const std::vector<float> &taps);
 
diff --git a/gnuradio-core/src/lib/filter/gri_fir_filter_with_buffer_ccf.cc b/gnuradio-core/src/lib/filter/gri_fir_filter_with_buffer_ccf.cc
new file mode 100644 (file)
index 0000000..e954554
--- /dev/null
@@ -0,0 +1,81 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2010 Free Software Foundation, Inc.
+ * 
+ * This file is part of GNU Radio
+ * 
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ * 
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <gri_fir_filter_with_buffer_ccf.h>
+#include <cstdio>
+
+gri_fir_filter_with_buffer_ccf::gri_fir_filter_with_buffer_ccf(const std::vector<float> &taps)
+{
+  d_buffer = NULL;
+  set_taps(taps);
+}
+
+gri_fir_filter_with_buffer_ccf::~gri_fir_filter_with_buffer_ccf()
+{
+  free(d_buffer);
+}
+
+gr_complex 
+gri_fir_filter_with_buffer_ccf::filter (gr_complex input)
+{
+#if 0
+  unsigned int i;
+  
+  for(i = ntaps()-1; i > 0; i--) {
+    d_buffer[i] = d_buffer[i-1];
+  }
+  d_buffer[0] = input;
+
+  gr_complex out = d_buffer[0]*d_taps[0];
+  for(i = 1; i < ntaps(); i++) {
+    out += d_buffer[i]*d_taps[i];
+  }
+  return out;
+
+#else
+  unsigned int i;
+
+  d_buffer[d_idx] = input;
+  d_buffer[d_idx+ntaps()] = input;
+  //d_idx = (d_idx + 1) % ntaps();
+  d_idx++;
+  if(d_idx == ntaps())
+    d_idx = 0;
+
+  gr_complex out = d_buffer[d_idx]*d_taps[0];
+  for(i = 1; i < ntaps(); i++) {
+    out += d_buffer[d_idx + i]*d_taps[i];
+  }
+  return out;
+#endif
+}
+
+void
+gri_fir_filter_with_buffer_ccf::filterN (gr_complex output[],
+                                        const gr_complex input[],
+                                        unsigned long n)
+{
+
+}
diff --git a/gnuradio-core/src/lib/filter/gri_fir_filter_with_buffer_ccf.h b/gnuradio-core/src/lib/filter/gri_fir_filter_with_buffer_ccf.h
new file mode 100644 (file)
index 0000000..5adc3e2
--- /dev/null
@@ -0,0 +1,130 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2010 Free Software Foundation, Inc.
+ * 
+ * This file is part of GNU Radio
+ * 
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ * 
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+/*
+ * WARNING: This file is automatically generated by generate_gr_fir_XXX.py
+ * Any changes made to this file will be overwritten.
+ */
+
+
+#ifndef INCLUDED_GRI_FIR_FILTER_WITH_BUFFER_H
+#define INCLUDED_GRI_FIR_FILTER_WITH_BUFFER_H
+
+#include <vector>
+#include <gr_types.h>
+#include <gr_reverse.h>
+#include <string.h>
+
+/*!
+ * \brief FIR with internal buffer for gr_complex input, 
+          gr_complex output and float taps
+ * \ingroup filter
+ * 
+ */
+
+class gri_fir_filter_with_buffer_ccf {
+
+protected:
+  std::vector<float>   d_taps;         // reversed taps
+  gr_complex           *d_buffer;
+  unsigned int          d_idx;
+
+public:
+
+  // CONSTRUCTORS
+
+  /*!
+   * \brief construct new FIR with given taps.
+   *
+   * Note that taps must be in forward order, e.g., coefficient 0 is
+   * stored in new_taps[0], coefficient 1 is stored in
+   * new_taps[1], etc.
+   */
+  gri_fir_filter_with_buffer_ccf (const std::vector<float> &taps);
+
+  ~gri_fir_filter_with_buffer_ccf ();
+
+  // MANIPULATORS
+
+  /*!
+   * \brief compute a single output value.
+   *
+   * \p input must have ntaps() valid entries.
+   * input[0] .. input[ntaps() - 1] are referenced to compute the output value.
+   *
+   * \returns the filtered input value.
+   */
+  gr_complex filter (gr_complex input);
+
+  /*!
+   * \brief compute an array of N output values.
+   *
+   * \p input must have (n - 1 + ntaps()) valid entries.
+   * input[0] .. input[n - 1 + ntaps() - 1] are referenced to compute the output values.
+   */
+  void filterN (gr_complex output[], const gr_complex input[],
+               unsigned long n);
+
+  /*!
+   * \brief compute an array of N output values, decimating the input
+   *
+   * \p input must have (decimate * (n - 1) + ntaps()) valid entries.
+   * input[0] .. input[decimate * (n - 1) + ntaps() - 1] are referenced to 
+   * compute the output values.
+   */
+  void filterNdec (gr_complex output[], const gr_complex input[],
+                  unsigned long n, unsigned decimate);
+
+  /*!
+   * \brief install \p new_taps as the current taps.
+   */
+  void set_taps (const std::vector<float> &taps)
+  {
+    d_taps = gr_reverse(taps);
+    //d_taps = (taps);
+
+    if(d_buffer != NULL)
+      free(d_buffer);
+    
+    // FIXME: memalign this to 16-byte boundaries for SIMD later
+    d_buffer = (gr_complex*)malloc(sizeof(gr_complex) * 2 * d_taps.size());
+    memset(d_buffer, 0x00, sizeof(gr_complex) * 2 * d_taps.size());
+    d_idx = 0;
+  }
+
+  // ACCESSORS
+
+  /*!
+   * \return number of taps in filter.
+   */
+  unsigned ntaps () const { return d_taps.size (); }
+
+  /*!
+   * \return current taps
+   */
+  const std::vector<float> get_taps () const
+  {
+    return gr_reverse(d_taps);
+  }
+};
+
+#endif /* INCLUDED_GR_GR_FIR_FILTER_WITH_BUFFER_CCF_H */