diff options
author | mormj <mormjb@gmail.com> | 2020-11-18 10:10:17 -0500 |
---|---|---|
committer | mormj <34754695+mormj@users.noreply.github.com> | 2020-12-17 08:30:02 -0500 |
commit | 436e40867e05274f58cdff778da7d520cd100809 (patch) | |
tree | 17c512979d5c09682c97829b98c08971f83eb7a4 /gr-filter/python | |
parent | df01f13a0cea8899a49b8f6edbd089741f1135c5 (diff) |
filter: replace rational_resampler_base with rational_resampler
The bulk of the rational resampler code is named rational_resampler_base
and only in Python is the automatic designing of filters if taps are not
specified. This pushes that code into the C++ classes (which get
binded) so rational_resampler.py can go away, removing a layer of
wrapping
Diffstat (limited to 'gr-filter/python')
-rw-r--r-- | gr-filter/python/filter/CMakeLists.txt | 1 | ||||
-rw-r--r-- | gr-filter/python/filter/__init__.py | 1 | ||||
-rw-r--r-- | gr-filter/python/filter/bindings/CMakeLists.txt | 2 | ||||
-rw-r--r-- | gr-filter/python/filter/bindings/docstrings/rational_resampler_pydoc_template.h (renamed from gr-filter/python/filter/bindings/docstrings/rational_resampler_base_pydoc_template.h) | 0 | ||||
-rw-r--r-- | gr-filter/python/filter/bindings/python_bindings.cc | 4 | ||||
-rw-r--r-- | gr-filter/python/filter/bindings/rational_resampler_base_python.cc | 63 | ||||
-rw-r--r-- | gr-filter/python/filter/bindings/rational_resampler_python.cc | 62 | ||||
-rw-r--r-- | gr-filter/python/filter/qa_rational_resampler.py | 14 | ||||
-rw-r--r-- | gr-filter/python/filter/rational_resampler.py | 145 |
9 files changed, 72 insertions, 220 deletions
diff --git a/gr-filter/python/filter/CMakeLists.txt b/gr-filter/python/filter/CMakeLists.txt index 765af55868..1fb908fe68 100644 --- a/gr-filter/python/filter/CMakeLists.txt +++ b/gr-filter/python/filter/CMakeLists.txt @@ -15,7 +15,6 @@ GR_PYTHON_INSTALL( freq_xlating_fft_filter.py optfir.py pfb.py - rational_resampler.py file_taps_loader.py DESTINATION ${GR_PYTHON_DIR}/gnuradio/filter ) diff --git a/gr-filter/python/filter/__init__.py b/gr-filter/python/filter/__init__.py index 8e1fa48c68..e08457e6e0 100644 --- a/gr-filter/python/filter/__init__.py +++ b/gr-filter/python/filter/__init__.py @@ -23,7 +23,6 @@ except ImportError: from .filterbank import * from .freq_xlating_fft_filter import * -from .rational_resampler import * from . import pfb from . import optfir diff --git a/gr-filter/python/filter/bindings/CMakeLists.txt b/gr-filter/python/filter/bindings/CMakeLists.txt index 47fa64cafe..1757159ba3 100644 --- a/gr-filter/python/filter/bindings/CMakeLists.txt +++ b/gr-filter/python/filter/bindings/CMakeLists.txt @@ -46,7 +46,7 @@ list(APPEND filter_python_files pfb_synthesizer_ccf_python.cc pm_remez_python.cc polyphase_filterbank_python.cc - rational_resampler_base_python.cc + rational_resampler_python.cc single_pole_iir_python.cc single_pole_iir_filter_cc_python.cc single_pole_iir_filter_ff_python.cc diff --git a/gr-filter/python/filter/bindings/docstrings/rational_resampler_base_pydoc_template.h b/gr-filter/python/filter/bindings/docstrings/rational_resampler_pydoc_template.h index a187d6f1ef..a187d6f1ef 100644 --- a/gr-filter/python/filter/bindings/docstrings/rational_resampler_base_pydoc_template.h +++ b/gr-filter/python/filter/bindings/docstrings/rational_resampler_pydoc_template.h diff --git a/gr-filter/python/filter/bindings/python_bindings.cc b/gr-filter/python/filter/bindings/python_bindings.cc index e7daa19c30..8147847e4a 100644 --- a/gr-filter/python/filter/bindings/python_bindings.cc +++ b/gr-filter/python/filter/bindings/python_bindings.cc @@ -58,7 +58,7 @@ void bind_pfb_interpolator_ccf(py::module&); void bind_pfb_synthesizer_ccf(py::module&); void bind_pm_remez(py::module&); void bind_polyphase_filterbank(py::module&); -void bind_rational_resampler_base(py::module&); +void bind_rational_resampler(py::module&); void bind_single_pole_iir(py::module&); void bind_single_pole_iir_filter_cc(py::module&); void bind_single_pole_iir_filter_ff(py::module&); @@ -125,7 +125,7 @@ PYBIND11_MODULE(filter_python, m) bind_pfb_synthesizer_ccf(m); bind_pm_remez(m); bind_polyphase_filterbank(m); - bind_rational_resampler_base(m); + bind_rational_resampler(m); bind_single_pole_iir(m); bind_single_pole_iir_filter_cc(m); bind_single_pole_iir_filter_ff(m); diff --git a/gr-filter/python/filter/bindings/rational_resampler_base_python.cc b/gr-filter/python/filter/bindings/rational_resampler_base_python.cc deleted file mode 100644 index 09083e798b..0000000000 --- a/gr-filter/python/filter/bindings/rational_resampler_base_python.cc +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright 2020 Free Software Foundation, Inc. - * - * This file is part of GNU Radio - * - * SPDX-License-Identifier: GPL-3.0-or-later - * - */ - -/***********************************************************************************/ -/* This file is automatically generated using bindtool and can be manually edited */ -/* The following lines can be configured to regenerate this file during cmake */ -/* If manual edits are made, the following tags should be modified accordingly. */ -/* BINDTOOL_GEN_AUTOMATIC(0) */ -/* BINDTOOL_USE_PYGCCXML(0) */ -/* BINDTOOL_HEADER_FILE(rational_resampler_base.h) */ -/* BINDTOOL_HEADER_FILE_HASH(8c16e10c6c05947272429eefa70c443e) */ -/***********************************************************************************/ - -#include <pybind11/complex.h> -#include <pybind11/pybind11.h> -#include <pybind11/stl.h> - -namespace py = pybind11; - -#include <gnuradio/filter/rational_resampler_base.h> - -template <class IN_T, class OUT_T, class TAP_T> -void bind_rational_resampler_base_template(py::module& m, const char* classname) -{ - using rational_resampler_base = - gr::filter::rational_resampler_base<IN_T, OUT_T, TAP_T>; - - py::class_<rational_resampler_base, - gr::block, - gr::basic_block, - std::shared_ptr<rational_resampler_base>>(m, classname) - .def(py::init(&gr::filter::rational_resampler_base<IN_T, OUT_T, TAP_T>::make), - py::arg("interpolation"), - py::arg("decimation"), - py::arg("taps")) - - .def("set_taps", &rational_resampler_base::set_taps, py::arg("taps")) - .def("taps", &rational_resampler_base::taps) - .def("interpolation", &rational_resampler_base::interpolation) - .def("decimation", &rational_resampler_base::decimation); -} - -void bind_rational_resampler_base(py::module& m) -{ - bind_rational_resampler_base_template<gr_complex, gr_complex, gr_complex>( - m, "rational_resampler_base_ccc"); - bind_rational_resampler_base_template<gr_complex, gr_complex, float>( - m, "rational_resampler_base_ccf"); - bind_rational_resampler_base_template<float, gr_complex, gr_complex>( - m, "rational_resampler_base_fcc"); - bind_rational_resampler_base_template<float, float, float>( - m, "rational_resampler_base_fff"); - bind_rational_resampler_base_template<float, std::int16_t, float>( - m, "rational_resampler_base_fsf"); - bind_rational_resampler_base_template<std::int16_t, gr_complex, gr_complex>( - m, "rational_resampler_base_scc"); -} diff --git a/gr-filter/python/filter/bindings/rational_resampler_python.cc b/gr-filter/python/filter/bindings/rational_resampler_python.cc new file mode 100644 index 0000000000..0f77b73415 --- /dev/null +++ b/gr-filter/python/filter/bindings/rational_resampler_python.cc @@ -0,0 +1,62 @@ +/* + * Copyright 2020 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * SPDX-License-Identifier: GPL-3.0-or-later + * + */ + +/***********************************************************************************/ +/* This file is automatically generated using bindtool and can be manually edited */ +/* The following lines can be configured to regenerate this file during cmake */ +/* If manual edits are made, the following tags should be modified accordingly. */ +/* BINDTOOL_GEN_AUTOMATIC(0) */ +/* BINDTOOL_USE_PYGCCXML(0) */ +/* BINDTOOL_HEADER_FILE(rational_resampler.h) */ +/* BINDTOOL_HEADER_FILE_HASH(79b3bf084bb620b66770a08c158f7ad9) */ +/***********************************************************************************/ + +#include <pybind11/complex.h> +#include <pybind11/pybind11.h> +#include <pybind11/stl.h> + +namespace py = pybind11; + +#include <gnuradio/filter/rational_resampler.h> + +template <class IN_T, class OUT_T, class TAP_T> +void bind_rational_resampler_template(py::module& m, const char* classname) +{ + using rational_resampler = gr::filter::rational_resampler<IN_T, OUT_T, TAP_T>; + + py::class_<rational_resampler, + gr::block, + gr::basic_block, + std::shared_ptr<rational_resampler>>(m, classname) + .def(py::init(&gr::filter::rational_resampler<IN_T, OUT_T, TAP_T>::make), + py::arg("interpolation"), + py::arg("decimation"), + py::arg("taps") = std::vector<TAP_T>(), + py::arg("fractional_bw") = 0.0) + + .def("set_taps", &rational_resampler::set_taps, py::arg("taps")) + .def("taps", &rational_resampler::taps) + .def("interpolation", &rational_resampler::interpolation) + .def("decimation", &rational_resampler::decimation); +} + +void bind_rational_resampler(py::module& m) +{ + bind_rational_resampler_template<gr_complex, gr_complex, gr_complex>( + m, "rational_resampler_ccc"); + bind_rational_resampler_template<gr_complex, gr_complex, float>( + m, "rational_resampler_ccf"); + bind_rational_resampler_template<float, gr_complex, gr_complex>( + m, "rational_resampler_fcc"); + bind_rational_resampler_template<float, float, float>(m, "rational_resampler_fff"); + bind_rational_resampler_template<float, std::int16_t, float>( + m, "rational_resampler_fsf"); + bind_rational_resampler_template<std::int16_t, gr_complex, gr_complex>( + m, "rational_resampler_scc"); +} diff --git a/gr-filter/python/filter/qa_rational_resampler.py b/gr-filter/python/filter/qa_rational_resampler.py index bd4122d93d..4c67dc793b 100644 --- a/gr-filter/python/filter/qa_rational_resampler.py +++ b/gr-filter/python/filter/qa_rational_resampler.py @@ -76,7 +76,7 @@ class test_rational_resampler (gr_unittest.TestCase): tb = gr.top_block() src = blocks.vector_source_f(src_data) - op = filter.rational_resampler_base_fff(1, 1, taps) + op = filter.rational_resampler_fff(1, 1, taps) dst = blocks.vector_sink_f() tb.connect(src, op) tb.connect(op, dst) @@ -99,7 +99,7 @@ class test_rational_resampler (gr_unittest.TestCase): tb = gr.top_block() src = blocks.vector_source_f(src_data) - op = filter.rational_resampler_base_fff(interpolation, 1, taps) + op = filter.rational_resampler_fff(interpolation, 1, taps) dst = blocks.vector_sink_f() tb.connect(src, op) tb.connect(op, dst) @@ -117,7 +117,7 @@ class test_rational_resampler (gr_unittest.TestCase): tb = gr.top_block() src = blocks.vector_source_f(src_data) - op = filter.rational_resampler_base_fff(interpolation, 1, taps) + op = filter.rational_resampler_fff(interpolation, 1, taps) dst = blocks.vector_sink_f() tb.connect(src, op) tb.connect(op, dst) @@ -137,7 +137,7 @@ class test_rational_resampler (gr_unittest.TestCase): tb = gr.top_block() src = blocks.vector_source_f(src_data) - op = filter.rational_resampler_base_fff(1, decimation, taps) + op = filter.rational_resampler_fff(1, decimation, taps) dst = blocks.vector_sink_f() tb.connect(src, op) tb.connect(op, dst) @@ -168,7 +168,7 @@ class test_rational_resampler (gr_unittest.TestCase): tb = gr.top_block() src = blocks.vector_source_f(src_data) - op = filter.rational_resampler_base_fff(1, decim, taps) + op = filter.rational_resampler_fff(1, decim, taps) dst = blocks.vector_sink_f() tb.connect(src, op, dst) tb.run() @@ -206,7 +206,7 @@ class test_rational_resampler (gr_unittest.TestCase): tb = gr.top_block() src = blocks.vector_source_f(src_data) - op = filter.rational_resampler_base_fff(interp, 1, taps) + op = filter.rational_resampler_fff(interp, 1, taps) dst = blocks.vector_sink_f() tb.connect(src, op, dst) tb.run() @@ -238,7 +238,7 @@ class test_rational_resampler (gr_unittest.TestCase): tb = gr.top_block() src = blocks.vector_source_f(src_data) - op = filter.rational_resampler_base_fff(interp, decimation, taps) + op = filter.rational_resampler_fff(interp, decimation, taps) dst = blocks.vector_sink_f() tb.connect(src, op) tb.connect(op, dst) diff --git a/gr-filter/python/filter/rational_resampler.py b/gr-filter/python/filter/rational_resampler.py deleted file mode 100644 index 1af9698e2b..0000000000 --- a/gr-filter/python/filter/rational_resampler.py +++ /dev/null @@ -1,145 +0,0 @@ -# -# Copyright 2005,2007 Free Software Foundation, Inc. -# -# This file is part of GNU Radio -# -# SPDX-License-Identifier: GPL-3.0-or-later -# -# - - -import math -from gnuradio import gr -from . import filter_python as filter - -_plot = None - - -def design_filter(interpolation, decimation, fractional_bw): - """ - Given the interpolation rate, decimation rate and a fractional bandwidth, - design a set of taps. - - Args: - interpolation: interpolation factor (integer > 0) - decimation: decimation factor (integer > 0) - fractional_bw: fractional bandwidth in (0, 0.5) 0.4 works well. (float) - Returns: - : sequence of numbers - """ - - if fractional_bw >= 0.5 or fractional_bw <= 0: - raise ValueError("Invalid fractional_bandwidth, must be in (0, 0.5)") - - beta = 7.0 - halfband = 0.5 - rate = float(interpolation) / float(decimation) - if(rate >= 1.0): - trans_width = halfband - fractional_bw - mid_transition_band = halfband - trans_width / 2.0 - else: - trans_width = rate*(halfband - fractional_bw) - mid_transition_band = rate*halfband - trans_width / 2.0 - - taps = filter.firdes.low_pass(interpolation, # gain - interpolation, # Fs - mid_transition_band, # trans mid point - trans_width, # transition width - filter.firdes.WIN_KAISER, - beta) # beta - - return taps - - - -class _rational_resampler_base(gr.hier_block2): - """ - base class for all rational resampler variants. - """ - def __init__(self, resampler_base, - interpolation, decimation, taps=None, fractional_bw=None): - """ - Rational resampling polyphase FIR filter. - - Either taps or fractional_bw may be specified, but not both. - If neither is specified, a reasonable default, 0.4, is used as - the fractional_bw. - - Args: - interpolation: interpolation factor (integer > 0) - decimation: decimation factor (integer > 0) - taps: optional filter coefficients (sequence) - fractional_bw: fractional bandwidth in (0, 0.5), measured at final freq (use 0.4) (float) - """ - - if not isinstance(interpolation, int) or interpolation < 1: - raise ValueError("interpolation must be an integer >= 1") - - if not isinstance(decimation, int) or decimation < 1: - raise ValueError("decimation must be an integer >= 1") - - if taps is None and fractional_bw is None: - fractional_bw = 0.4 - - d = math.gcd(interpolation, decimation) - - # If we have user-provided taps and the interp and decim - # values have a common divisor, we don't reduce these values - # by the GCD but issue a warning to the user that this might - # increase the complexity of the filter. - if taps and (d > 1): - gr.log.info("Rational resampler has user-provided taps but interpolation ({0}) and decimation ({1}) have a GCD of {2}, which increases the complexity of the filterbank. Consider reducing these values by the GCD.".format(interpolation, decimation, d)) - - # If we don't have user-provided taps, reduce the interp and - # decim values by the GCD (if there is one) and then define - # the taps from these new values. - if taps is None: - interpolation = interpolation // d - decimation = decimation // d - taps = design_filter(interpolation, decimation, fractional_bw) - - self.resampler = resampler_base(interpolation, decimation, taps) - gr.hier_block2.__init__(self, "rational_resampler", - gr.io_signature(1, 1, self.resampler.input_signature().sizeof_stream_item(0)), - gr.io_signature(1, 1, self.resampler.output_signature().sizeof_stream_item(0))) - - self.connect(self, self.resampler, self) - - def taps(self): - return self.resampler.taps() - -class rational_resampler_fff(_rational_resampler_base): - def __init__(self, interpolation, decimation, taps=None, fractional_bw=None): - """ - Rational resampling polyphase FIR filter with - float input, float output and float taps. - """ - _rational_resampler_base.__init__(self, filter.rational_resampler_base_fff, - interpolation, decimation, taps, fractional_bw) - -class rational_resampler_ccf(_rational_resampler_base): - def __init__(self, interpolation, decimation, taps=None, fractional_bw=None): - """ - Rational resampling polyphase FIR filter with - complex input, complex output and float taps. - """ - _rational_resampler_base.__init__(self, filter.rational_resampler_base_ccf, - interpolation, decimation, taps, fractional_bw) - -class rational_resampler_ccc(_rational_resampler_base): - def __init__(self, interpolation, decimation, taps=None, fractional_bw=None): - """ - Rational resampling polyphase FIR filter with - complex input, complex output and complex taps. - """ - _rational_resampler_base.__init__(self, filter.rational_resampler_base_ccc, - interpolation, decimation, taps, fractional_bw) - -class rational_resampler_fcc(_rational_resampler_base): - def __init__(self, interpolation, decimation, taps=None, fractional_bw=None): - """ - Rational resampling polyphase FIR filter with - float input, complex output and complex taps. - """ - _rational_resampler_base.__init__(self, filter.rational_resampler_base_fcc, - interpolation, decimation, taps, fractional_bw) |