From: Tom Rondeau Date: Sat, 16 Oct 2010 15:13:53 +0000 (-0400) Subject: Adding a FIR filter implemented with its own internal buffer. This one keeps its... X-Git-Url: https://git.gag.com/?a=commitdiff_plain;h=2e633fc33dcbc3e1b5c35323ebe24373d57ea459;p=debian%2Fgnuradio Adding a FIR filter implemented with its own internal buffer. This one keeps its own delay line and just takes in input samples instead of a pointer to an external buffer. The synthesis filter is being updated to use the new FIR implementation. --- diff --git a/gnuradio-core/src/lib/filter/Makefile.am b/gnuradio-core/src/lib/filter/Makefile.am index 6a6532eb..5c7473d0 100644 --- a/gnuradio-core/src/lib/filter/Makefile.am +++ b/gnuradio-core/src/lib/filter/Makefile.am @@ -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 \ diff --git a/gnuradio-core/src/lib/filter/gr_pfb_synthesis_filterbank_ccf.cc b/gnuradio-core/src/lib/filter/gr_pfb_synthesis_filterbank_ccf.cc index b1365bcf..0b31bcf7 100644 --- a/gnuradio-core/src/lib/filter/gr_pfb_synthesis_filterbank_ccf.cc +++ b/gnuradio-core/src/lib/filter/gr_pfb_synthesis_filterbank_ccf.cc @@ -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(d_numchans); + //d_filters = std::vector(d_numchans); + d_filters = std::vector(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 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; } diff --git a/gnuradio-core/src/lib/filter/gr_pfb_synthesis_filterbank_ccf.h b/gnuradio-core/src/lib/filter/gr_pfb_synthesis_filterbank_ccf.h index 4b6235a8..27c8c2c5 100644 --- a/gnuradio-core/src/lib/filter/gr_pfb_synthesis_filterbank_ccf.h +++ b/gnuradio-core/src/lib/filter/gr_pfb_synthesis_filterbank_ccf.h @@ -25,6 +25,7 @@ #define INCLUDED_GR_PFB_SYNTHESIS_FILTERBANK_CCF_H #include +#include class gr_pfb_synthesis_filterbank_ccf; typedef boost::shared_ptr 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 M - * \param taps (vector/list of floats) The prototype filter to populate the filterbank. + * \param numchans (unsigned integer) Specifies the number of + channels M + * \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 &taps); bool d_updated; unsigned int d_numchans; - std::vector d_filters; - std::vector< std::vector > 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 > d_taps; + /*! * Build the polyphase synthesis filterbank. - * \param numchans (unsigned integer) Specifies the number of channels M - * \param taps (vector/list of floats) The prototype filter to populate the filterbank. + * \param numchans (unsigned integer) Specifies the number of + channels M + * \param taps (vector/list of floats) The prototype filter + to populate the filterbank. */ gr_pfb_synthesis_filterbank_ccf (unsigned int numchans, const std::vector &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 &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 index 00000000..e9545549 --- /dev/null +++ b/gnuradio-core/src/lib/filter/gri_fir_filter_with_buffer_ccf.cc @@ -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 +#endif +#include +#include + +gri_fir_filter_with_buffer_ccf::gri_fir_filter_with_buffer_ccf(const std::vector &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 index 00000000..5adc3e23 --- /dev/null +++ b/gnuradio-core/src/lib/filter/gri_fir_filter_with_buffer_ccf.h @@ -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 +#include +#include +#include + +/*! + * \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 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 &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 &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 get_taps () const + { + return gr_reverse(d_taps); + } +}; + +#endif /* INCLUDED_GR_GR_FIR_FILTER_WITH_BUFFER_CCF_H */