summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gr-filter/grc/CMakeLists.txt1
-rw-r--r--gr-filter/grc/filter_block_tree.xml1
-rw-r--r--gr-filter/grc/rational_resampler_base_xxx.xml86
-rw-r--r--gr-filter/include/filter/CMakeLists.txt1
-rw-r--r--gr-filter/include/filter/rational_resampler_base_XXX.h.t61
-rw-r--r--gr-filter/lib/CMakeLists.txt1
-rw-r--r--gr-filter/lib/fir_filter_XXX_impl.h.t1
-rw-r--r--gr-filter/lib/rational_resampler_base_XXX_impl.cc.t174
-rw-r--r--gr-filter/lib/rational_resampler_base_XXX_impl.h.t72
-rwxr-xr-xgr-filter/python/qa_rational_resampler.py257
-rw-r--r--gr-filter/swig/filter_swig.i18
11 files changed, 672 insertions, 1 deletions
diff --git a/gr-filter/grc/CMakeLists.txt b/gr-filter/grc/CMakeLists.txt
index 3110e0f1b..0747c7240 100644
--- a/gr-filter/grc/CMakeLists.txt
+++ b/gr-filter/grc/CMakeLists.txt
@@ -32,6 +32,7 @@ install(FILES
pfb_channelizer.xml
pfb_decimator.xml
pfb_interpolator.xml
+ rational_resampler_base_xxx.xml
single_pole_iir_filter_xx.xml
DESTINATION ${GRC_BLOCKS_DIR}
COMPONENT "filter_python"
diff --git a/gr-filter/grc/filter_block_tree.xml b/gr-filter/grc/filter_block_tree.xml
index ecc97dd23..de840a3fd 100644
--- a/gr-filter/grc/filter_block_tree.xml
+++ b/gr-filter/grc/filter_block_tree.xml
@@ -43,6 +43,7 @@
<block>pfb_channelizer_ccf</block>
<block>pfb_decimator_ccf</block>
<block>pfb_interpolator_ccf</block>
+ <block>rational_resampler_base_xxx</block>
<block>single_pole_iir_filter_xx</block>
</cat>
</cat>
diff --git a/gr-filter/grc/rational_resampler_base_xxx.xml b/gr-filter/grc/rational_resampler_base_xxx.xml
new file mode 100644
index 000000000..399bfc74c
--- /dev/null
+++ b/gr-filter/grc/rational_resampler_base_xxx.xml
@@ -0,0 +1,86 @@
+<?xml version="1.0"?>
+<!--
+###################################################
+##Rational Resampler Base
+###################################################
+ -->
+<block>
+ <name>Rational Resampler Base</name>
+ <key>rational_resampler_base_xxx</key>
+ <import>from gnuradio import filter</import>
+ <import>from gnuradio.filter import firdes</import>
+ <make>filter.rational_resampler_base_$(type)($interp, $decim, $taps)</make>
+ <callback>set_taps($taps)</callback>
+ <param>
+ <name>Type</name>
+ <key>type</key>
+ <type>enum</type>
+ <option>
+ <name>Complex->Complex (Complex Taps)</name>
+ <key>ccc</key>
+ <opt>input:complex</opt>
+ <opt>output:complex</opt>
+ <opt>taps:complex_vector</opt>
+ </option>
+ <option>
+ <name>Complex->Complex (Real Taps)</name>
+ <key>ccf</key>
+ <opt>input:complex</opt>
+ <opt>output:complex</opt>
+ <opt>taps:real_vector</opt>
+ </option>
+ <option>
+ <name>Float->Complex (Complex Taps)</name>
+ <key>fcc</key>
+ <opt>input:float</opt>
+ <opt>output:complex</opt>
+ <opt>taps:complex_vector</opt>
+ </option>
+ <option>
+ <name>Float->Float (Real Taps)</name>
+ <key>fff</key>
+ <opt>input:float</opt>
+ <opt>output:float</opt>
+ <opt>taps:real_vector</opt>
+ </option>
+ <option>
+ <name>Float->Short (Real Taps)</name>
+ <key>fsf</key>
+ <opt>input:float</opt>
+ <opt>output:short</opt>
+ <opt>taps:real_vector</opt>
+ </option>
+ <option>
+ <name>Short->Complex (Complex Taps)</name>
+ <key>scc</key>
+ <opt>input:short</opt>
+ <opt>output:complex</opt>
+ <opt>taps:complex_vector</opt>
+ </option>
+ </param>
+ <param>
+ <name>Interpolation</name>
+ <key>interp</key>
+ <value>1</value>
+ <type>int</type>
+ </param>
+ <param>
+ <name>Decimation</name>
+ <key>decim</key>
+ <value>1</value>
+ <type>int</type>
+ </param>
+ <param>
+ <name>Taps</name>
+ <key>taps</key>
+ <type>$type.taps</type>
+ </param>
+ <sink>
+ <name>in</name>
+ <type>$type.input</type>
+ </sink>
+ <source>
+ <name>out</name>
+ <type>$type.output</type>
+ </source>
+</block>
diff --git a/gr-filter/include/filter/CMakeLists.txt b/gr-filter/include/filter/CMakeLists.txt
index b0412aaba..9174bfc84 100644
--- a/gr-filter/include/filter/CMakeLists.txt
+++ b/gr-filter/include/filter/CMakeLists.txt
@@ -67,6 +67,7 @@ endmacro(expand_h)
expand_h(fir_filter_XXX ccc ccf fcc fff fsf scc)
expand_h(freq_xlating_fir_filter_XXX ccc ccf fcc fcf scf scc)
expand_h(interp_fir_filter_XXX ccc ccf fcc fff fsf scc)
+expand_h(rational_resampler_base_XXX ccc ccf fcc fff fsf scc)
add_custom_target(filter_generated_includes DEPENDS
${generated_includes}
diff --git a/gr-filter/include/filter/rational_resampler_base_XXX.h.t b/gr-filter/include/filter/rational_resampler_base_XXX.h.t
new file mode 100644
index 000000000..c37eb30a7
--- /dev/null
+++ b/gr-filter/include/filter/rational_resampler_base_XXX.h.t
@@ -0,0 +1,61 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2005,2012 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@ */
+
+#ifndef @GUARD_NAME@
+#define @GUARD_NAME@
+
+#include <filter/api.h>
+#include <gr_block.h>
+
+
+namespace gr {
+ namespace filter {
+
+ /*!
+ * \brief Rational Resampling Polyphase FIR filter with @I_TYPE@
+ * input, @O_TYPE@ output and @TAP_TYPE@ taps.
+ *
+ *\ingroup filter_blk
+ */
+ class FILTER_API @NAME@ : virtual public gr_block
+ {
+ public:
+ // gr::filter::@BASE_NAME@::sptr
+ typedef boost::shared_ptr<@BASE_NAME@> sptr;
+
+ static FILTER_API sptr make(unsigned interpolation,
+ unsigned decimation,
+ const std::vector<@TAP_TYPE@> &taps);
+
+ virtual unsigned interpolation() const = 0;
+ virtual unsigned decimation() const = 0;
+
+ virtual void set_taps(const std::vector<@TAP_TYPE@> &taps) = 0;
+ virtual std::vector<@TAP_TYPE@> taps() const = 0;
+ };
+
+ } /* namespace filter */
+} /* namespace gr */
+
+#endif /* @GUARD_NAME@ */
diff --git a/gr-filter/lib/CMakeLists.txt b/gr-filter/lib/CMakeLists.txt
index 8077baf9c..b3d456ec9 100644
--- a/gr-filter/lib/CMakeLists.txt
+++ b/gr-filter/lib/CMakeLists.txt
@@ -83,6 +83,7 @@ endmacro(expand_cc)
expand_cc(fir_filter_XXX_impl ccc ccf fcc fff fsf scc)
expand_cc(freq_xlating_fir_filter_XXX_impl ccc ccf fcc fcf scf scc)
expand_cc(interp_fir_filter_XXX_impl ccc ccf fcc fff fsf scc)
+expand_cc(rational_resampler_base_XXX_impl ccc ccf fcc fff fsf scc)
########################################################################
diff --git a/gr-filter/lib/fir_filter_XXX_impl.h.t b/gr-filter/lib/fir_filter_XXX_impl.h.t
index d5bf7104d..ef0a7adfe 100644
--- a/gr-filter/lib/fir_filter_XXX_impl.h.t
+++ b/gr-filter/lib/fir_filter_XXX_impl.h.t
@@ -25,7 +25,6 @@
#ifndef @GUARD_NAME@
#define @GUARD_NAME@
-#include <filter/api.h>
#include <filter/fir_filter.h>
#include <filter/@BASE_NAME@.h>
diff --git a/gr-filter/lib/rational_resampler_base_XXX_impl.cc.t b/gr-filter/lib/rational_resampler_base_XXX_impl.cc.t
new file mode 100644
index 000000000..2e9161eeb
--- /dev/null
+++ b/gr-filter/lib/rational_resampler_base_XXX_impl.cc.t
@@ -0,0 +1,174 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2010,2012 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@ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "@IMPL_NAME@.h"
+#include <gr_io_signature.h>
+#include <volk/volk.h>
+#include <stdexcept>
+
+namespace gr {
+ namespace filter {
+
+ @BASE_NAME@::sptr
+ @BASE_NAME@::make(unsigned interpolation,
+ unsigned decimation,
+ const std::vector<@TAP_TYPE@> &taps)
+ {
+ return gnuradio::get_initial_sptr
+ (new @IMPL_NAME@(interpolation, decimation, taps));
+ }
+
+ @IMPL_NAME@::@IMPL_NAME@(unsigned interpolation,
+ unsigned decimation,
+ const std::vector<@TAP_TYPE@> &taps)
+ : gr_block("@BASE_NAME@",
+ gr_make_io_signature(1, 1, sizeof(@I_TYPE@)),
+ gr_make_io_signature(1, 1, sizeof(@O_TYPE@))),
+ d_history(1),
+ d_interpolation(interpolation),
+ d_decimation(decimation),
+ d_ctr(0),
+ d_firs(interpolation),
+ d_updated(false)
+ {
+ if(interpolation == 0)
+ throw std::out_of_range("@IMPL_NAME@: interpolation must be > 0");
+ if(decimation == 0)
+ throw std::out_of_range("@IMPL_NAME@: decimation must be > 0");
+
+ set_relative_rate(1.0 * interpolation / decimation);
+ set_output_multiple(1);
+
+ std::vector<@TAP_TYPE@> dummy_taps;
+
+ for(unsigned i = 0; i < interpolation; i++) {
+ d_firs[i] = new kernel::@FIR_TYPE@(1, dummy_taps);
+ }
+
+ set_taps(taps);
+ install_taps(d_new_taps);
+ }
+
+ @IMPL_NAME@::~@IMPL_NAME@()
+ {
+ int interp = interpolation();
+ for(int i = 0; i < interp; i++) {
+ delete d_firs[i];
+ }
+ }
+
+ void
+ @IMPL_NAME@::set_taps(const std::vector<@TAP_TYPE@> &taps)
+ {
+ d_new_taps = taps;
+ d_updated = true;
+
+ // round up length to a multiple of the interpolation factor
+ int n = taps.size() % interpolation();
+ if(n > 0) {
+ n = interpolation() - n;
+ while(n-- > 0) {
+ d_new_taps.insert(d_new_taps.begin(), 0);
+ }
+ }
+
+ assert(d_new_taps.size() % interpolation() == 0);
+ }
+
+ void
+ @IMPL_NAME@::install_taps(const std::vector<@TAP_TYPE@> &taps)
+ {
+ int nfilters = interpolation();
+ int nt = taps.size() / nfilters;
+
+ assert(nt * nfilters == (int) taps.size());
+
+ std::vector< std::vector <@TAP_TYPE@> > xtaps(nfilters);
+
+ for(int n = 0; n < nfilters; n++)
+ xtaps[n].resize (nt);
+
+ for(int i = 0; i < (int)taps.size(); i++)
+ xtaps[i % nfilters][i / nfilters] = taps[i];
+
+ for(int n = 0; n < nfilters; n++)
+ d_firs[n]->set_taps(xtaps[n]);
+
+ set_history(nt);
+ d_updated = false;
+ }
+
+ std::vector<@TAP_TYPE@>
+ @IMPL_NAME@::taps() const
+ {
+ return d_new_taps;
+ }
+
+ void
+ @IMPL_NAME@::forecast(int noutput_items, gr_vector_int &ninput_items_required)
+ {
+ int nreqd = std::max((unsigned)1, (int)((double) (noutput_items+1) * \
+ decimation() / interpolation()) + history() - 1);
+ unsigned ninputs = ninput_items_required.size();
+ for(unsigned i = 0; i < ninputs; i++)
+ ninput_items_required[i] = nreqd;
+ }
+
+ int
+ @IMPL_NAME@::general_work(int noutput_items,
+ gr_vector_int &ninput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+ {
+ const @I_TYPE@ *in = (const @I_TYPE@ *)input_items[0];
+ @O_TYPE@ *out = (@O_TYPE@ *)output_items[0];
+
+ if(d_updated) {
+ install_taps(d_new_taps);
+ return 0; // history requirement may have increased.
+ }
+
+ unsigned int ctr = d_ctr;
+
+ int i = 0;
+ while(i < noutput_items) {
+ out[i++] = d_firs[ctr]->filter(in);
+ ctr += decimation();
+ while(ctr >= interpolation()) {
+ ctr -= interpolation();
+ in++;
+ }
+ }
+
+ d_ctr = ctr;
+ consume_each(in - (@I_TYPE@*)input_items[0]);
+ return i;
+ }
+
+ } /* namespace filter */
+} /* namespace gr */
diff --git a/gr-filter/lib/rational_resampler_base_XXX_impl.h.t b/gr-filter/lib/rational_resampler_base_XXX_impl.h.t
new file mode 100644
index 000000000..4396656da
--- /dev/null
+++ b/gr-filter/lib/rational_resampler_base_XXX_impl.h.t
@@ -0,0 +1,72 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2005,2012 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@ */
+
+#ifndef @GUARD_NAME@
+#define @GUARD_NAME@
+
+#include <filter/fir_filter.h>
+#include <filter/@BASE_NAME@.h>
+
+namespace gr {
+ namespace filter {
+
+ class FILTER_API @IMPL_NAME@ : public @BASE_NAME@
+ {
+ private:
+ unsigned d_history;
+ unsigned d_interpolation;
+ unsigned d_decimation;
+ unsigned d_ctr;
+ std::vector<@TAP_TYPE@> d_new_taps;
+ std::vector<kernel::@FIR_TYPE@ *> d_firs;
+ bool d_updated;
+
+ void install_taps(const std::vector<@TAP_TYPE@> &taps);
+
+ public:
+ @IMPL_NAME@(unsigned interpolation, unsigned decimation,
+ const std::vector<@TAP_TYPE@> &taps);
+
+ ~@IMPL_NAME@();
+
+ unsigned history() const { return d_history; }
+ void set_history(unsigned history) { d_history = history; }
+
+ unsigned interpolation() const { return d_interpolation; }
+ unsigned decimation() const { return d_decimation; }
+
+ void set_taps(const std::vector<@TAP_TYPE@> &taps);
+ std::vector<@TAP_TYPE@> taps() const;
+
+ void forecast(int noutput_items, gr_vector_int &ninput_items_required);
+ int general_work(int noutput_items,
+ gr_vector_int &ninput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+ };
+
+ } /* namespace filter */
+} /* namespace gr */
+
+#endif /* @GUARD_NAME@ */
diff --git a/gr-filter/python/qa_rational_resampler.py b/gr-filter/python/qa_rational_resampler.py
new file mode 100755
index 000000000..eb86ef542
--- /dev/null
+++ b/gr-filter/python/qa_rational_resampler.py
@@ -0,0 +1,257 @@
+#!/usr/bin/env python
+#
+# Copyright 2005,2006,2007,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.
+#
+
+from gnuradio import gr, gr_unittest
+import filter_swig as filter
+import math
+import random
+import sys
+
+
+def random_floats(n):
+ r = []
+ for x in xrange(n):
+ # r.append(float(random.randint(-32768, 32768)))
+ r.append(float(random.random()))
+ return tuple(r)
+
+
+def reference_dec_filter(src_data, decim, taps):
+ tb = gr.top_block()
+ src = gr.vector_source_f(src_data)
+ op = filter.fir_filter_fff(decim, taps)
+ dst = gr.vector_sink_f()
+ tb.connect(src, op, dst)
+ tb.run()
+ result_data = dst.data()
+ tb = None
+ return result_data
+
+def reference_interp_filter(src_data, interp, taps):
+ tb = gr.top_block()
+ src = gr.vector_source_f(src_data)
+ op = filter.interp_fir_filter_fff(interp, taps)
+ dst = gr.vector_sink_f()
+ tb.connect(src, op, dst)
+ tb.run()
+ result_data = dst.data()
+ tb = None
+ return result_data
+
+def reference_interp_dec_filter(src_data, interp, decim, taps):
+ tb = gr.top_block()
+ src = gr.vector_source_f(src_data)
+ up = filter.interp_fir_filter_fff(interp, (1,))
+ dn = filter.fir_filter_fff(decim, taps)
+ dst = gr.vector_sink_f()
+ tb.connect(src, up, dn, dst)
+ tb.run()
+ result_data = dst.data()
+ tb = None
+ return result_data
+
+
+class test_rational_resampler (gr_unittest.TestCase):
+
+ def setUp(self):
+ random.seed(0)
+
+ def tearDown(self):
+ pass
+
+
+ def test_000_1_to_1(self):
+ taps = (-4, 5)
+ src_data = (234, -4, 23, -56, 45, 98, -23, -7)
+ xr = (1186, -112, 339, -460, -167, 582)
+ expected_result = tuple([float(x) for x in xr])
+
+ tb = gr.top_block()
+ src = gr.vector_source_f(src_data)
+ op = filter.rational_resampler_base_fff(1, 1, taps)
+ dst = gr.vector_sink_f()
+ tb.connect(src, op)
+ tb.connect(op, dst)
+ tb.run()
+ result_data = dst.data()
+ self.assertEqual(expected_result, result_data)
+
+ def test_001_interp(self):
+ taps = [1, 10, 100, 1000, 10000]
+ src_data = (0, 2, 3, 5, 7, 11, 13, 17)
+ interpolation = 3
+ xr = (0,2,20,200,2003,20030,
+ 300,3005,30050,
+ 500,5007,50070,
+ 700,7011,70110,
+ 1100,11013,110130,
+ 1300,13017,130170,
+ 1700.0,17000.0,170000.0)
+ expected_result = tuple([float(x) for x in xr])
+
+ tb = gr.top_block()
+ src = gr.vector_source_f(src_data)
+ op = filter.rational_resampler_base_fff(interpolation, 1, taps)
+ dst = gr.vector_sink_f()
+ tb.connect(src, op)
+ tb.connect(op, dst)
+ tb.run()
+ result_data = dst.data()
+ self.assertEqual(expected_result, result_data)
+
+ def test_002_interp(self):
+ taps = random_floats(31)
+ src_data = random_floats(10000)
+ interpolation = 3
+
+ expected_result = reference_interp_filter(src_data, interpolation, taps)
+
+ tb = gr.top_block()
+ src = gr.vector_source_f(src_data)
+ op = filter.rational_resampler_base_fff(interpolation, 1, taps)
+ dst = gr.vector_sink_f()
+ tb.connect(src, op)
+ tb.connect(op, dst)
+ tb.run()
+ result_data = dst.data()
+
+ N = 1000
+ offset = len(taps)-1
+ self.assertEqual(expected_result[offset:offset+N], result_data[0:N])
+
+ def xtest_003_interp(self):
+ taps = random_floats(9)
+ src_data = random_floats(10000)
+ decimation = 3
+
+ expected_result = reference_dec_filter(src_data, decimation, taps)
+
+ tb = gr.top_block()
+ src = gr.vector_source_f(src_data)
+ op = filter.rational_resampler_base_fff(1, decimation, taps)
+ dst = gr.vector_sink_f()
+ tb.connect(src, op)
+ tb.connect(op, dst)
+ tb.run()
+ result_data = dst.data()
+
+ N = 10
+ offset = 10#len(taps)-1
+ print expected_result[100+offset:100+offset+N]
+ print result_data[100:100+N]
+ #self.assertEqual(expected_result[offset:offset+N], result_data[0:N])
+
+ # FIXME disabled. Triggers hang on SuSE 10.0
+ def xtest_004_decim_random_vals(self):
+ MAX_TAPS = 9
+ MAX_DECIM = 7
+ OUTPUT_LEN = 9
+
+ random.seed(0) # we want reproducibility
+
+ for ntaps in xrange(1, MAX_TAPS + 1):
+ for decim in xrange(1, MAX_DECIM+1):
+ for ilen in xrange(ntaps + decim, ntaps + OUTPUT_LEN*decim):
+ src_data = random_floats(ilen)
+ taps = random_floats(ntaps)
+ expected_result = reference_dec_filter(src_data, decim, taps)
+
+ tb = gr.top_block()
+ src = gr.vector_source_f(src_data)
+ op = filter.rational_resampler_base_fff(1, decim, taps)
+ dst = gr.vector_sink_f()
+ tb.connect(src, op, dst)
+ tb.run()
+ tb = None
+ result_data = dst.data()
+
+ L1 = len(result_data)
+ L2 = len(expected_result)
+ L = min(L1, L2)
+ if False:
+ sys.stderr.write('delta = %2d: ntaps = %d decim = %d ilen = %d\n' % (L2 - L1, ntaps, decim, ilen))
+ sys.stderr.write(' len(result_data) = %d len(expected_result) = %d\n' %
+ (len(result_data), len(expected_result)))
+ self.assertEqual(expected_result[0:L], result_data[0:L])
+
+
+ # FIXME disabled. Triggers hang on SuSE 10.0
+ def xtest_005_interp_random_vals(self):
+ MAX_TAPS = 9
+ MAX_INTERP = 7
+ INPUT_LEN = 9
+
+ random.seed(0) # we want reproducibility
+
+ for ntaps in xrange(1, MAX_TAPS + 1):
+ for interp in xrange(1, MAX_INTERP+1):
+ for ilen in xrange(ntaps, ntaps + INPUT_LEN):
+ src_data = random_floats(ilen)
+ taps = random_floats(ntaps)
+ expected_result = reference_interp_filter(src_data, interp, taps)
+
+ tb = gr.top_block()
+ src = gr.vector_source_f(src_data)
+ op = filter.rational_resampler_base_fff(interp, 1, taps)
+ dst = gr.vector_sink_f()
+ tb.connect(src, op, dst)
+ tb.run()
+ tb = None
+ result_data = dst.data()
+ L1 = len(result_data)
+ L2 = len(expected_result)
+ L = min(L1, L2)
+ #if True or abs(L1-L2) > 1:
+ if False:
+ sys.stderr.write('delta = %2d: ntaps = %d interp = %d ilen = %d\n' % (L2 - L1, ntaps, interp, ilen))
+ #sys.stderr.write(' len(result_data) = %d len(expected_result) = %d\n' %
+ # (len(result_data), len(expected_result)))
+ #self.assertEqual(expected_result[0:L], result_data[0:L])
+ # FIXME check first ntaps+1 answers
+ self.assertEqual(expected_result[ntaps+1:L], result_data[ntaps+1:L])
+
+ def test_006_interp_decim(self):
+ taps = random_floats(31)
+ src_data = random_floats(10000)
+ interp = 3
+ decimation = 2
+
+ expected_result = reference_interp_dec_filter(src_data, interp, decimation, taps)
+
+ tb = gr.top_block()
+ src = gr.vector_source_f(src_data)
+ op = filter.rational_resampler_base_fff(interp, decimation, taps)
+ dst = gr.vector_sink_f()
+ tb.connect(src, op)
+ tb.connect(op, dst)
+ tb.run()
+ result_data = dst.data()
+
+ N = 1000
+ offset = len(taps)/2
+ self.assertFloatTuplesAlmostEqual(expected_result[offset:offset+N], result_data[0:N], 5)
+
+
+if __name__ == '__main__':
+ # FIXME: Disabled, see ticket:210
+ gr_unittest.run(test_rational_resampler, "test_rational_resampler.xml")
+
diff --git a/gr-filter/swig/filter_swig.i b/gr-filter/swig/filter_swig.i
index b72a67f15..5a8ebf975 100644
--- a/gr-filter/swig/filter_swig.i
+++ b/gr-filter/swig/filter_swig.i
@@ -64,6 +64,12 @@
#include "filter/pfb_channelizer_ccf.h"
#include "filter/pfb_decimator_ccf.h"
#include "filter/pfb_interpolator_ccf.h"
+#include "filter/rational_resampler_base_ccc.h"
+#include "filter/rational_resampler_base_ccf.h"
+#include "filter/rational_resampler_base_fcc.h"
+#include "filter/rational_resampler_base_fff.h"
+#include "filter/rational_resampler_base_fsf.h"
+#include "filter/rational_resampler_base_scc.h"
#include "filter/single_pole_iir_filter_cc.h"
#include "filter/single_pole_iir_filter_ff.h"
%}
@@ -104,6 +110,12 @@
%include "filter/pfb_channelizer_ccf.h"
%include "filter/pfb_decimator_ccf.h"
%include "filter/pfb_interpolator_ccf.h"
+%include "filter/rational_resampler_base_ccc.h"
+%include "filter/rational_resampler_base_ccf.h"
+%include "filter/rational_resampler_base_fcc.h"
+%include "filter/rational_resampler_base_fff.h"
+%include "filter/rational_resampler_base_fsf.h"
+%include "filter/rational_resampler_base_scc.h"
%include "filter/single_pole_iir_filter_cc.h"
%include "filter/single_pole_iir_filter_ff.h"
@@ -141,5 +153,11 @@ GR_SWIG_BLOCK_MAGIC2(filter, pfb_arb_resampler_fff);
GR_SWIG_BLOCK_MAGIC2(filter, pfb_channelizer_ccf);
GR_SWIG_BLOCK_MAGIC2(filter, pfb_decimator_ccf);
GR_SWIG_BLOCK_MAGIC2(filter, pfb_interpolator_ccf);
+GR_SWIG_BLOCK_MAGIC2(filter, rational_resampler_base_ccc);
+GR_SWIG_BLOCK_MAGIC2(filter, rational_resampler_base_ccf);
+GR_SWIG_BLOCK_MAGIC2(filter, rational_resampler_base_fcc);
+GR_SWIG_BLOCK_MAGIC2(filter, rational_resampler_base_fff);
+GR_SWIG_BLOCK_MAGIC2(filter, rational_resampler_base_fsf);
+GR_SWIG_BLOCK_MAGIC2(filter, rational_resampler_base_scc);
GR_SWIG_BLOCK_MAGIC2(filter, single_pole_iir_filter_cc);
GR_SWIG_BLOCK_MAGIC2(filter, single_pole_iir_filter_ff);