diff options
Diffstat (limited to 'blocklib/filter')
46 files changed, 0 insertions, 4356 deletions
diff --git a/blocklib/filter/.gitignore b/blocklib/filter/.gitignore deleted file mode 100644 index 25d053a52..000000000 --- a/blocklib/filter/.gitignore +++ /dev/null @@ -1 +0,0 @@ -meson.build
\ No newline at end of file diff --git a/blocklib/filter/bench/bm_pfb_channelizer.py b/blocklib/filter/bench/bm_pfb_channelizer.py deleted file mode 100644 index c223118c1..000000000 --- a/blocklib/filter/bench/bm_pfb_channelizer.py +++ /dev/null @@ -1,130 +0,0 @@ -#!/usr/bin/env python3 -# -*- coding: utf-8 -*- - -# -# SPDX-License-Identifier: GPL-3.0 -# -# GNU Radio Python Flow Graph -# Title: Not titled yet -# GNU Radio version: 3.9.0.0-git - -from gnuradio import gr, blocks, streamops, fft -from gnuradio.kernel.filter import firdes -from gnuradio.kernel.fft import window -from gnuradio.schedulers import nbt -import sys -import signal -from argparse import ArgumentParser -import time -from gnuradio import filter - -class benchmark_pfb_channelizer(gr.flowgraph): - - def __init__(self, args): - gr.flowgraph.__init__(self) - - ################################################## - # Variables - ################################################## - nsamples = args.samples - nchans = args.nchans - attn = args.attenuation - bufsize = args.buffer_size - - taps = firdes.low_pass_2(1, nchans, 1 / 2, 1 / 10, attenuation_dB=attn,window=window.BLACKMAN_hARRIS) - - ################################################## - # Blocks - ################################################## - self.nsrc = blocks.null_source() - self.nsnk = blocks.null_sink(nports=nchans) - self.hd = streamops.head(int(nsamples)) - - if not args.cuda: - self.channelizer = filter.pfb_channelizer_cc( - nchans, - taps, - 1.0) - # self.s2ss = streamops.stream_to_streams(gr.sizeof_gr_complex, nchans) - - ################################################## - # Connections - ################################################## - # nsnks = [] - for ii in range(nchans): - # nsnks.append(blocks.null_sink(gr.sizeof_gr_complex*1)) - self.connect(self.channelizer, ii, self.nsnk, ii) - # self.connect(self.s2ss, ii, self.channelizer, ii) - # self.connect(self.channelizer, self.nsnk) - # self.connect(self.hd, 0, self.s2ss, 0) - self.connect([self.nsrc, self.hd, self.channelizer]) - # self.connect(self.nsrc, 0, self.hd, 0) - else: - self.channelizer = filter.pfb_channelizer_cc( - nchans, - taps, - 1.0, - impl=filter.pfb_channelizer_cc.cuda) - # self.s2ss = streamops.stream_to_streams(gr.sizeof_gr_complex, nchans, impl=streamops.stream_to_streams.cuda) - - ################################################## - # Connections - ################################################## - # nsnks = [] - for ii in range(nchans): - # blk = blocks.null_sink(gr.sizeof_gr_complex*1) - # nsnks.append(blk) - self.connect(self.channelizer, ii, self.nsnk, ii).set_custom_buffer(gr.buffer_cuda_properties.make(gr.buffer_cuda_type.D2H).set_buffer_size(bufsize)) - # self.connect(self.s2ss, ii, self.channelizer, ii).set_custom_buffer(gr.buffer_cuda_properties.make(gr.buffer_cuda_type.D2D).set_buffer_size(bufsize)) - # self.connect(self.channelizer, ii, nsnks[ii], 0).set_custom_buffer(gr.buffer_cuda_pinned_properties.make().set_buffer_size(bufsize)) - # self.connect(self.s2ss, ii, self.channelizer, ii).set_custom_buffer(gr.buffer_cuda_pinned_properties.make().set_buffer_size(bufsize)) - - # self.connect(self.channelizer, self.nsnk) - # self.connect(self.hd, 0, self.s2ss, 0).set_custom_buffer(gr.buffer_cuda_properties.make(gr.buffer_cuda_type.H2D).set_buffer_size(bufsize)) - self.connect(self.hd, 0, self.channelizer, 0).set_custom_buffer(gr.buffer_cuda_properties.make(gr.buffer_cuda_type.H2D).set_buffer_size(bufsize)) - # self.connect(self.hd, 0, self.s2ss, 0).set_custom_buffer(gr.buffer_cuda_pinned_properties.make().set_buffer_size(bufsize)) - self.connect(self.nsrc, 0, self.hd, 0).set_custom_buffer(gr.buffer_cpu_vmcirc_properties.make(gr.buffer_cpu_vmcirc_type.AUTO).set_buffer_size(bufsize)) - - # sched = nbt.scheduler_nbt("nbtsched") - # self.add_scheduler(sched) - # sched.add_block_group([x.base() for x in nsnks]) - - # self.validate() - - -def main(top_block_cls=benchmark_pfb_channelizer, options=None): - - parser = ArgumentParser(description='Run a flowgraph iterating over parameters for benchmarking') - parser.add_argument('--rt_prio', help='enable realtime scheduling', action='store_true') - parser.add_argument('--samples', type=int, default=1e8) - parser.add_argument('--nchans', type=int, default=4) - parser.add_argument('--attenuation', type=float, default=70) - parser.add_argument('--buffer_size', type=int, default=8192) - parser.add_argument('--cuda', action='store_true') - - args = parser.parse_args() - print(args) - - if args.rt_prio and gr.enable_realtime_scheduling() != gr.RT_OK: - print("Error: failed to enable real-time scheduling.") - - tb = top_block_cls(args) - - def sig_handler(sig=None, frame=None): - tb.stop() - tb.wait() - sys.exit(0) - - signal.signal(signal.SIGINT, sig_handler) - signal.signal(signal.SIGTERM, sig_handler) - - print("starting ...") - startt = time.time() - tb.start() - - tb.wait() - endt = time.time() - print(f'[PROFILE_TIME]{endt-startt}[PROFILE_TIME]') - -if __name__ == '__main__': - main() diff --git a/blocklib/filter/dc_blocker/dc_blocker.yml b/blocklib/filter/dc_blocker/dc_blocker.yml deleted file mode 100644 index 038a77b40..000000000 --- a/blocklib/filter/dc_blocker/dc_blocker.yml +++ /dev/null @@ -1,40 +0,0 @@ -module: filter -block: dc_blocker -label: DC Blocker -blocktype: sync_block -category: '[Core]/Filters' - -typekeys: - - id: T - type: class - options: - - cf32 - - rf32 - -parameters: -- id: D - label: Delay Line Length - dtype: int - settable: true -- id: long_form - label: Long Form - dtype: bool - settable: false - default: 'true' - -ports: -- domain: stream - id: in - direction: input - type: typekeys/T - -- domain: stream - id: out - direction: output - type: typekeys/T - -implementations: -- id: cpu -# - id: cuda - -file_format: 1 diff --git a/blocklib/filter/dc_blocker/dc_blocker_cpu.cc b/blocklib/filter/dc_blocker/dc_blocker_cpu.cc deleted file mode 100644 index 32c97f6e3..000000000 --- a/blocklib/filter/dc_blocker/dc_blocker_cpu.cc +++ /dev/null @@ -1,79 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2011,2012 Free Software Foundation, Inc. - * - * This file is part of GNU Radio - * - * SPDX-License-Identifier: GPL-3.0-or-later - * - */ - -#include "dc_blocker_cpu.h" -#include "dc_blocker_cpu_gen.h" -#include <volk/volk.h> - -namespace gr { -namespace filter { - -template <class T> -dc_blocker_cpu<T>::dc_blocker_cpu(const typename dc_blocker<T>::block_args& args) - : INHERITED_CONSTRUCTORS(T), - d_length(args.D), - d_long_form(args.long_form), - d_ma_0(args.D), - d_ma_1(args.D) -{ - if (d_long_form) { - d_ma_2 = std::make_unique<kernel::filter::moving_averager<T>>(d_length); - d_ma_3 = std::make_unique<kernel::filter::moving_averager<T>>(d_length); - d_delay_line = std::deque<T>(d_length - 1, 0); - } -} - -template <class T> -int dc_blocker_cpu<T>::group_delay() -{ - if (d_long_form) - return (2 * d_length - 2); - else - return d_length - 1; -} - -template <class T> -work_return_t dc_blocker_cpu<T>::work(work_io& wio) -{ - - auto in = wio.inputs()[0].items<T>(); - auto out = wio.outputs()[0].items<T>(); - auto noutput_items = wio.outputs()[0].n_items; - - if (d_long_form) { - T y1, y2, y3, y4, d; - for (size_t i = 0; i < noutput_items; i++) { - y1 = d_ma_0.filter(in[i]); - y2 = d_ma_1.filter(y1); - y3 = d_ma_2->filter(y2); - y4 = d_ma_3->filter(y3); - - d_delay_line.push_back(d_ma_0.delayed_sig()); - d = d_delay_line[0]; - d_delay_line.pop_front(); - - out[i] = d - y4; - } - } - else { - T y1, y2; - for (size_t i = 0; i < noutput_items; i++) { - y1 = d_ma_0.filter(in[i]); - y2 = d_ma_1.filter(y1); - out[i] = d_ma_0.delayed_sig() - y2; - } - } - - wio.outputs()[0].n_produced = noutput_items; - return work_return_t::OK; -} - -} /* namespace filter */ -} /* namespace gr */ diff --git a/blocklib/filter/dc_blocker/dc_blocker_cpu.h b/blocklib/filter/dc_blocker/dc_blocker_cpu.h deleted file mode 100644 index 76da348b2..000000000 --- a/blocklib/filter/dc_blocker/dc_blocker_cpu.h +++ /dev/null @@ -1,41 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2011,2012 Free Software Foundation, Inc. - * - * This file is part of GNU Radio - * - * SPDX-License-Identifier: GPL-3.0-or-later - * - */ - -#pragma once - -#include <gnuradio/filter/dc_blocker.h> -#include <gnuradio/kernel/filter/moving_averager.h> - -namespace gr { -namespace filter { - -template <class T> -class dc_blocker_cpu : public dc_blocker<T> -{ -public: - dc_blocker_cpu(const typename dc_blocker<T>::block_args& args); - - work_return_t work(work_io&) override; - - int group_delay(); - -protected: - int d_length; - bool d_long_form; - kernel::filter::moving_averager<T> d_ma_0; - kernel::filter::moving_averager<T> d_ma_1; - std::unique_ptr<kernel::filter::moving_averager<T>> d_ma_2; - std::unique_ptr<kernel::filter::moving_averager<T>> d_ma_3; - std::deque<T> d_delay_line; -}; - - -} // namespace filter -} // namespace gr diff --git a/blocklib/filter/examples/.gitignore b/blocklib/filter/examples/.gitignore deleted file mode 100644 index f104652b6..000000000 --- a/blocklib/filter/examples/.gitignore +++ /dev/null @@ -1 +0,0 @@ -*.py diff --git a/blocklib/filter/examples/pfb_channelizer_example.grc b/blocklib/filter/examples/pfb_channelizer_example.grc deleted file mode 100644 index 4cc5d9792..000000000 --- a/blocklib/filter/examples/pfb_channelizer_example.grc +++ /dev/null @@ -1,263 +0,0 @@ -options: - parameters: - author: josh - catch_exceptions: 'True' - category: '[GRC Hier Blocks]' - cmake_opt: '' - comment: '' - copyright: '' - description: '' - gen_cmake: 'On' - gen_linking: dynamic - generate_options: qt_gui - hier_block_src_path: '.:' - id: pfb_channelizer_example - max_nouts: '0' - output_language: python - placement: (0,0) - qt_qss_theme: '' - realtime_scheduling: '' - run: 'True' - run_command: '{python} -u {filename}' - run_options: prompt - sizing_mode: fixed - thread_safe_setters: '' - title: Not titled yet - states: - bus_sink: false - bus_source: false - bus_structure: null - coordinate: [8, 8] - rotation: 0 - state: enabled - -blocks: -- name: samp_rate - id: variable - parameters: - comment: '' - value: '32000' - states: - bus_sink: false - bus_source: false - bus_structure: null - coordinate: [184, 12] - rotation: 0 - state: enabled -- name: analog_noise_source_0 - id: analog_noise_source - parameters: - T: complex - affinity: '' - alias: '' - amplitude: '0.1' - comment: '' - domain: cpu - maxoutbuf: '0' - minoutbuf: '0' - seed: '0' - showports: 'False' - type: analog.noise_t.GAUSSIAN - states: - bus_sink: false - bus_source: false - bus_structure: null - coordinate: [248, 604.0] - rotation: 0 - state: true -- name: analog_sig_source_0 - id: analog_sig_source - parameters: - T: complex - affinity: '' - alias: '' - ampl: '1.0' - comment: '' - domain: cpu - frequency: '10000' - maxoutbuf: '0' - minoutbuf: '0' - offset: '0' - phase: '0' - sampling_freq: samp_rate - showports: 'False' - waveform: analog.waveform_t.COS - states: - bus_sink: false - bus_source: false - bus_structure: null - coordinate: [160, 428.0] - rotation: 0 - state: true -- name: analog_sig_source_0_0 - id: analog_sig_source - parameters: - T: complex - affinity: '' - alias: '' - ampl: '1.0' - comment: '' - domain: cpu - frequency: '1000' - maxoutbuf: '0' - minoutbuf: '0' - offset: '0' - phase: '0' - sampling_freq: samp_rate - showports: 'False' - waveform: analog.waveform_t.COS - states: - bus_sink: false - bus_source: false - bus_structure: null - coordinate: [160, 252.0] - rotation: 0 - state: true -- name: filter_pfb_channelizer_0 - id: filter_pfb_channelizer - parameters: - T: complex - affinity: '' - alias: '' - comment: '' - domain: cpu - maxoutbuf: '0' - minoutbuf: '0' - numchans: '2' - oversample_rate: '1' - showports: 'False' - taps: filterk.firdes.low_pass(1.0, 2.0, 0.45, 0.01) - states: - bus_sink: false - bus_source: false - bus_structure: null - coordinate: [736, 204.0] - rotation: 0 - state: true -- name: import_0 - id: import - parameters: - alias: '' - comment: '' - imports: from gnuradio.kernel import fft as fftk - states: - bus_sink: false - bus_source: false - bus_structure: null - coordinate: [352, 28.0] - rotation: 0 - state: true -- name: import_0_0 - id: import - parameters: - alias: '' - comment: '' - imports: from gnuradio.kernel import filter as filterk - states: - bus_sink: false - bus_source: false - bus_structure: null - coordinate: [456, 28.0] - rotation: 0 - state: true -- name: math_add_0 - id: math_add - parameters: - T: complex - affinity: '' - alias: '' - comment: '' - domain: cpu - maxoutbuf: '0' - minoutbuf: '0' - nports: '3' - showports: 'False' - vlen: '1' - states: - bus_sink: false - bus_source: false - bus_structure: null - coordinate: [416, 388.0] - rotation: 0 - state: true -- name: qtgui_freq_sink_0_0 - id: qtgui_freq_sink - parameters: - T: complex - affinity: '' - alias: '' - bw: samp_rate / 2 - comment: '' - domain: cpu - fc: '0' - fftsize: '1024' - gui_hint: '' - name: '"1"' - nconnections: '1' - showports: 'False' - wintype: '5' - states: - bus_sink: false - bus_source: false - bus_structure: null - coordinate: [1168, 180.0] - rotation: 0 - state: enabled -- name: qtgui_freq_sink_0_0_0 - id: qtgui_freq_sink - parameters: - T: complex - affinity: '' - alias: '' - bw: samp_rate / 2 - comment: '' - domain: cpu - fc: '0' - fftsize: '1024' - gui_hint: '' - name: '"2"' - nconnections: '1' - showports: 'False' - wintype: '5' - states: - bus_sink: false - bus_source: false - bus_structure: null - coordinate: [1096, 372.0] - rotation: 0 - state: enabled -- name: qtgui_freq_sink_0_1 - id: qtgui_freq_sink - parameters: - T: complex - affinity: '' - alias: '' - bw: samp_rate - comment: '' - domain: cpu - fc: '0' - fftsize: '1024' - gui_hint: '' - name: '"ALL"' - nconnections: '1' - showports: 'False' - wintype: '5' - states: - bus_sink: false - bus_source: false - bus_structure: null - coordinate: [720, 404.0] - rotation: 0 - state: enabled - -connections: -- [analog_noise_source_0, '0', math_add_0, '2'] -- [analog_sig_source_0, '0', math_add_0, '1'] -- [analog_sig_source_0_0, '0', math_add_0, '0'] -- [filter_pfb_channelizer_0, '0', qtgui_freq_sink_0_0, '0'] -- [filter_pfb_channelizer_0, '1', qtgui_freq_sink_0_0_0, '0'] -- [math_add_0, '0', filter_pfb_channelizer_0, '0'] -- [math_add_0, '0', qtgui_freq_sink_0_1, '0'] - -metadata: - file_format: 1 diff --git a/blocklib/filter/fir_filter/fir_filter.yml b/blocklib/filter/fir_filter/fir_filter.yml deleted file mode 100644 index 27c495987..000000000 --- a/blocklib/filter/fir_filter/fir_filter.yml +++ /dev/null @@ -1,70 +0,0 @@ -module: filter -block: fir_filter -label: FIR Filter -blocktype: block -category: '[Core]/Filters' - -typekeys: - - id: IN_T - type: class - options: - - cf32 - - rf32 - - ri16 - - - id: OUT_T - type: class - options: - - cf32 - - rf32 - - ri16 - - - id: TAP_T - type: class - options: - - cf32 - - rf32 - -type_inst: - - value: [cf32, cf32, cf32] - label: Complex->Complex (Complex Taps) - - value: [cf32, cf32, rf32] - label: Complex->Complex (Real Taps) - - value: [rf32, cf32, cf32] - label: Float->Complex (Complex Taps) - - value: [rf32, rf32, rf32] - label: Float->Float (Real Taps) - - value: [rf32, ri16, rf32] - label: Float->Short (Real Taps) - - value: [ri16, cf32, cf32] - label: Short->Complex (Complex Taps) - -parameters: -- id: decimation - label: Decimation - dtype: size - settable: false - grc: - default: 1 -- id: taps - label: Taps - dtype: TAP_T - container: vector - settable: true - -ports: -- domain: stream - id: in - direction: input - type: typekeys/IN_T - -- domain: stream - id: out - direction: output - type: typekeys/OUT_T - -implementations: -- id: cpu -# - id: cuda - -file_format: 1 diff --git a/blocklib/filter/fir_filter/fir_filter_cpu.cc b/blocklib/filter/fir_filter/fir_filter_cpu.cc deleted file mode 100644 index bce57909a..000000000 --- a/blocklib/filter/fir_filter/fir_filter_cpu.cc +++ /dev/null @@ -1,90 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2022 Josh Morman - * - * This file is part of GNU Radio - * - * SPDX-License-Identifier: GPL-3.0-or-later - * - */ - -#include "fir_filter_cpu.h" -#include "fir_filter_cpu_gen.h" - -namespace gr { -namespace filter { - -template <class IN_T, class OUT_T, class TAP_T> -fir_filter_cpu<IN_T, OUT_T, TAP_T>::fir_filter_cpu( - const typename fir_filter<IN_T, OUT_T, TAP_T>::block_args& args) - : INHERITED_CONSTRUCTORS(IN_T, OUT_T, TAP_T), d_fir(args.taps) -{ - this->set_relative_rate(1.0 / args.decimation); - this->declare_noconsume(d_fir.ntaps() - 1); - // const int alignment_multiple = volk_get_alignment() / sizeof(float); - // this->set_alignment(std::max(1, alignment_multiple)); -} - -template <class IN_T, class OUT_T, class TAP_T> -void fir_filter_cpu<IN_T, OUT_T, TAP_T>::on_parameter_change(param_action_sptr action) -{ - // This will set the underlying PMT - block::on_parameter_change(action); - - // Do more updating for certain parameters - if (action->id() == fir_filter<IN_T, OUT_T, TAP_T>::id_taps) { - auto taps = pmtf::get_as<std::vector<TAP_T>>(*this->param_taps); - d_fir.set_taps(taps); - this->declare_noconsume(d_fir.ntaps() - 1); - } -} - -template <class IN_T, class OUT_T, class TAP_T> -work_return_t fir_filter_cpu<IN_T, OUT_T, TAP_T>::enforce_constraints(work_io& wio) -{ - // Do forecasting - size_t ninput = wio.inputs()[0].n_items; - size_t noutput = wio.outputs()[0].n_items; - - auto decim = pmtf::get_as<size_t>(*this->param_decimation); - - auto min_ninput = - std::min(noutput * decim + this->noconsume(), ninput - this->noconsume()); - auto noutput_items = std::min(min_ninput / decim, noutput); - - if (noutput_items <= 0) { - return work_return_t::INSUFFICIENT_INPUT_ITEMS; - } - - wio.outputs()[0].n_items = noutput_items; - wio.inputs()[0].n_items = noutput_items * decim; - - return work_return_t::OK; -} - -template <class IN_T, class OUT_T, class TAP_T> -work_return_t fir_filter_cpu<IN_T, OUT_T, TAP_T>::work(work_io& wio) -{ - size_t ninput = wio.inputs()[0].n_items; - size_t noutput = wio.outputs()[0].n_items; - - auto in = wio.inputs()[0].items<IN_T>(); - auto out = wio.outputs()[0].items<OUT_T>(); - - auto decim = pmtf::get_as<size_t>(*this->param_decimation); - - if (decim == 1) { - d_fir.filterN(out, in, noutput); - } - else { - d_fir.filterNdec(out, in, noutput, decim); - } - - wio.consume_each(ninput); - wio.produce_each(noutput); - - return work_return_t::OK; -} - -} /* namespace filter */ -} /* namespace gr */ diff --git a/blocklib/filter/fir_filter/fir_filter_cpu.h b/blocklib/filter/fir_filter/fir_filter_cpu.h deleted file mode 100644 index 6ca61bb87..000000000 --- a/blocklib/filter/fir_filter/fir_filter_cpu.h +++ /dev/null @@ -1,38 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2022 Josh Morman - * - * This file is part of GNU Radio - * - * SPDX-License-Identifier: GPL-3.0-or-later - * - */ - -#pragma once - -#include <gnuradio/filter/fir_filter.h> -#include <gnuradio/kernel/filter/fir_filter.h> - -namespace gr { -namespace filter { - -template <class IN_T, class OUT_T, class TAP_T> -class fir_filter_cpu : public fir_filter<IN_T, OUT_T, TAP_T> -{ -public: - fir_filter_cpu(const typename fir_filter<IN_T, OUT_T, TAP_T>::block_args& args); - - work_return_t work(work_io&) override; - - void on_parameter_change(param_action_sptr action) override; - - -private: - work_return_t enforce_constraints(work_io& wio) override; - - gr::kernel::filter::fir_filter<IN_T, OUT_T, TAP_T> d_fir; -}; - - -} // namespace filter -} // namespace gr diff --git a/blocklib/filter/fir_filter/qa_fir_filter.py b/blocklib/filter/fir_filter/qa_fir_filter.py deleted file mode 100644 index 9e3663f69..000000000 --- a/blocklib/filter/fir_filter/qa_fir_filter.py +++ /dev/null @@ -1,194 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright 2008,2010,2012,2013 Free Software Foundation, Inc. -# -# This file is part of GNU Radio -# -# SPDX-License-Identifier: GPL-3.0-or-later -# -# - - -from gnuradio import gr, gr_unittest, filter, blocks -from gnuradio.kernel.filter import firdes -import math - -def fir_filter(x, taps, decim=1): - y = [] - m = decim *((len(x)-len(taps)+1) // decim) - - for i in range(0, m, decim): - yi = 0 - for j in range(len(taps)): - yi += taps[len(taps) - 1 - j] * x[i + j] - y.append(yi) - return y - - -class test_filter(gr_unittest.TestCase): - - def setUp(self): - self.tb = gr.top_block() - - def tearDown(self): - self.tb = None - - def test_fir_filter_fff_001(self): - decim = 1 - taps = 20 * [0.5, 0.5] - src_data = 40 * [1, 2, 3, 4] - expected_data = fir_filter(src_data, taps, decim) - - src = blocks.vector_source_f(src_data) - op = filter.fir_filter_fff(decim, taps) - dst = blocks.vector_sink_f() - self.tb.connect((src, op, dst)) - self.tb.run() - result_data = dst.data() - self.assertFloatTuplesAlmostEqual(expected_data, result_data, 5) - - def test_fir_filter_fff_002(self): - decim = 4 - taps = 20 * [0.5, 0.5] - src_data = 40 * [1, 2, 3, 4] - expected_data = fir_filter(src_data, taps, decim) - - src = blocks.vector_source_f(src_data) - op = filter.fir_filter_fff(decim, taps) - dst = blocks.vector_sink_f() - self.tb.connect((src, op, dst)) - self.tb.run() - result_data = dst.data() - self.assertFloatTuplesAlmostEqual(expected_data, result_data, 5) - - def test_fir_filter_ccf_001(self): - decim = 1 - taps = 20 * [0.5, 0.5] - src_data = 40 * [1 + 1j, 2 + 2j, 3 + 3j, 4 + 4j] - expected_data = fir_filter(src_data, taps, decim) - - src = blocks.vector_source_c(src_data) - op = filter.fir_filter_ccf(decim, taps) - dst = blocks.vector_sink_c() - self.tb.connect((src, op, dst)) - self.tb.run() - result_data = dst.data() - self.assertComplexTuplesAlmostEqual(expected_data, result_data, 5) - - def test_fir_filter_ccf_002(self): - decim = 4 - taps = 20 * [0.5, 0.5] - src_data = 40 * [1 + 1j, 2 + 2j, 3 + 3j, 4 + 4j] - expected_data = fir_filter(src_data, taps, decim) - - src = blocks.vector_source_c(src_data) - op = filter.fir_filter_ccf(decim, taps) - dst = blocks.vector_sink_c() - self.tb.connect((src, op, dst)) - self.tb.run() - result_data = dst.data() - self.assertComplexTuplesAlmostEqual(expected_data, result_data, 5) - - def test_fir_filter_ccc_001(self): - decim = 1 - taps = 20 * [0.5 + 1j, 0.5 + 1j] - src_data = 40 * [1 + 1j, 2 + 2j, 3 + 3j, 4 + 4j] - expected_data = fir_filter(src_data, taps, decim) - - src = blocks.vector_source_c(src_data) - op = filter.fir_filter_ccc(decim, taps) - dst = blocks.vector_sink_c() - self.tb.connect((src, op, dst)) - self.tb.run() - result_data = dst.data() - self.assertComplexTuplesAlmostEqual(expected_data, result_data, 5) - - def test_fir_filter_ccc_002(self): - decim = 1 - taps = firdes.low_pass(1, 1, 0.1, 0.01) - src_data = [0]*len(taps) + 10 * [1 + 1j, 2 + 2j, 3 + 3j, 4 + 4j] - expected_data = fir_filter(src_data, taps, decim) - - src = blocks.vector_source_c(src_data) - op = filter.fir_filter_ccc(decim, taps) - dst = blocks.vector_sink_c() - self.tb.connect((src, op, dst)) - self.tb.run() - result_data = dst.data() - self.assertComplexTuplesAlmostEqual(expected_data, result_data, 5) - - def test_fir_filter_ccc_003(self): - decim = 4 - taps = 20 * [0.5 + 1j, 0.5 + 1j] - src_data = 40 * [1 + 1j, 2 + 2j, 3 + 3j, 4 + 4j] - expected_data = fir_filter(src_data, taps, decim) - - src = blocks.vector_source_c(src_data) - op = filter.fir_filter_ccc(decim, taps) - dst = blocks.vector_sink_c() - self.tb.connect((src, op, dst)) - self.tb.run() - result_data = dst.data() - self.assertComplexTuplesAlmostEqual(expected_data, result_data, 5) - - def test_fir_filter_scc_001(self): - decim = 1 - taps = 20 * [0.5 + 1j, 0.5 + 1j] - src_data = 40 * [1, 2, 3, 4] - expected_data = fir_filter(src_data, taps, decim) - - src = blocks.vector_source_s(src_data) - op = filter.fir_filter_scc(decim, taps) - dst = blocks.vector_sink_c() - self.tb.connect((src, op, dst)) - self.tb.run() - result_data = dst.data() - self.assertComplexTuplesAlmostEqual(expected_data, result_data, 5) - - def test_fir_filter_scc_002(self): - decim = 4 - taps = 20 * [0.5 + 1j, 0.5 + 1j] - src_data = 40 * [1, 2, 3, 4] - expected_data = fir_filter(src_data, taps, decim) - - src = blocks.vector_source_s(src_data) - op = filter.fir_filter_scc(decim, taps) - dst = blocks.vector_sink_c() - self.tb.connect((src, op, dst)) - self.tb.run() - result_data = dst.data() - self.assertComplexTuplesAlmostEqual(expected_data, result_data, 5) - - def test_fir_filter_fsf_001(self): - decim = 1 - taps = 20 * [0.5, 0.5] - src_data = 40 * [1, 2, 3, 4] - expected_data = fir_filter(src_data, taps, decim) - expected_data = [int(e) for e in expected_data] - - src = blocks.vector_source_f(src_data) - op = filter.fir_filter_fsf(decim, taps) - dst = blocks.vector_sink_s() - self.tb.connect((src, op, dst)) - self.tb.run() - result_data = dst.data() - self.assertComplexTuplesAlmostEqual(expected_data, result_data, 5) - - def test_fir_filter_fsf_002(self): - decim = 4 - taps = 20 * [0.5, 0.5] - src_data = 40 * [1, 2, 3, 4] - expected_data = fir_filter(src_data, taps, decim) - expected_data = [int(e) for e in expected_data] - - src = blocks.vector_source_f(src_data) - op = filter.fir_filter_fsf(decim, taps) - dst = blocks.vector_sink_s() - self.tb.connect((src, op, dst)) - self.tb.run() - result_data = dst.data() - self.assertComplexTuplesAlmostEqual(expected_data, result_data, 5) - - -if __name__ == '__main__': - gr_unittest.run(test_filter) diff --git a/blocklib/filter/iir_filter/iir_filter.yml b/blocklib/filter/iir_filter/iir_filter.yml deleted file mode 100644 index 39b2c246f..000000000 --- a/blocklib/filter/iir_filter/iir_filter.yml +++ /dev/null @@ -1,69 +0,0 @@ -module: filter -block: iir_filter -label: IIR Filter -blocktype: sync_block -category: '[Core]/Filters' - -typekeys: - - id: T_IN - type: class - options: - - cf32 - - rf32 - - id: T_OUT - type: class - options: - - cf32 - - rf32 - - id: TAP_T - type: class - options: - - cf64 - - cf32 - - rf64 - - rf32 -type_inst: - - value: [rf32, rf32, rf64] - label: Float->Float (Double Taps) - - value: [cf32, cf32, rf32] - label: Complex->Complex (Float Taps) - - value: [cf32, cf32, rf64] - label: Complex->Complex (Double Taps) - - value: [cf32, cf32, cf32] - label: Complex->Complex (Complex Taps) - - value: [cf32, cf32, cf64] - label: Complex->Complex (Complex Double Taps) - -parameters: -- id: fftaps - label: Feed Forward Taps - dtype: TAP_T - container: vector - settable: true -- id: fbtaps - label: Feed Back Taps - dtype: TAP_T - container: vector - settable: true -- id: oldstyle - label: Old Style Taps - dtype: bool - default: 'true' - settable: false - -ports: - - domain: stream - id: in - direction: input - type: typekeys/T_IN - - - domain: stream - id: out - direction: output - type: typekeys/T_OUT - -implementations: - - id: cpu -# - id: cuda - -file_format: 1 diff --git a/blocklib/filter/iir_filter/iir_filter_cpu.cc b/blocklib/filter/iir_filter/iir_filter_cpu.cc deleted file mode 100644 index ace7ab312..000000000 --- a/blocklib/filter/iir_filter/iir_filter_cpu.cc +++ /dev/null @@ -1,38 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2022 Josh Morman - * - * This file is part of GNU Radio - * - * SPDX-License-Identifier: GPL-3.0-or-later - * - */ - -#include "iir_filter_cpu.h" -#include "iir_filter_cpu_gen.h" - -namespace gr { -namespace filter { - -template <class T_IN, class T_OUT, class TAP_T> -iir_filter_cpu<T_IN, T_OUT, TAP_T>::iir_filter_cpu( - const typename iir_filter<T_IN, T_OUT, TAP_T>::block_args& args) - : INHERITED_CONSTRUCTORS(T_IN, T_OUT, TAP_T), - d_iir(args.fftaps, args.fbtaps, args.oldstyle) -{ -} - -template <class T_IN, class T_OUT, class TAP_T> -work_return_t iir_filter_cpu<T_IN, T_OUT, TAP_T>::work(work_io& wio) -{ - auto in = wio.inputs()[0].items<T_IN>(); - auto out = wio.outputs()[0].items<T_OUT>(); - auto noutput_items = wio.outputs()[0].n_items; - - d_iir.filter_n(out, in, noutput_items); - wio.produce_each(noutput_items); - return work_return_t::OK; -} - -} /* namespace filter */ -} /* namespace gr */ diff --git a/blocklib/filter/iir_filter/iir_filter_cpu.h b/blocklib/filter/iir_filter/iir_filter_cpu.h deleted file mode 100644 index 556c926e4..000000000 --- a/blocklib/filter/iir_filter/iir_filter_cpu.h +++ /dev/null @@ -1,49 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2022 Josh Morman - * - * This file is part of GNU Radio - * - * SPDX-License-Identifier: GPL-3.0-or-later - * - */ - -#pragma once - -#include <gnuradio/filter/iir_filter.h> - -#include <gnuradio/kernel/filter/iir_filter.h> - -namespace gr { -namespace filter { - -template <class T_IN, class T_OUT, class TAP_T> -class iir_filter_cpu : public iir_filter<T_IN, T_OUT, TAP_T> -{ -public: - iir_filter_cpu(const typename iir_filter<T_IN, T_OUT, TAP_T>::block_args& args); - - work_return_t work(work_io&) override; - -private: - bool d_updated; - kernel::filter::iir_filter<T_IN, T_OUT, TAP_T> d_iir; - - void on_parameter_change(param_action_sptr action) override - { - // This will set the underlying PMT - block::on_parameter_change(action); - auto fftaps = pmtf::get_as<std::vector<TAP_T>>(*this->param_fftaps); - auto fbtaps = pmtf::get_as<std::vector<TAP_T>>(*this->param_fbtaps); - - // Do more updating for certain parameters - if (action->id() == iir_filter<T_IN, T_OUT, TAP_T>::id_fftaps || - action->id() == iir_filter<T_IN, T_OUT, TAP_T>::id_fbtaps) { - d_iir.set_taps(fftaps, fbtaps); - } - } -}; - - -} // namespace filter -} // namespace gr diff --git a/blocklib/filter/include/gnuradio/filter/.gitignore b/blocklib/filter/include/gnuradio/filter/.gitignore deleted file mode 100644 index d53050d7d..000000000 --- a/blocklib/filter/include/gnuradio/filter/.gitignore +++ /dev/null @@ -1 +0,0 @@ -!meson.build diff --git a/blocklib/filter/include/gnuradio/filter/api.h b/blocklib/filter/include/gnuradio/filter/api.h deleted file mode 100644 index 0e90bde23..000000000 --- a/blocklib/filter/include/gnuradio/filter/api.h +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Copyright 2012 Free Software Foundation, Inc. - * - * This file is part of GNU Radio - * - * SPDX-License-Identifier: GPL-3.0-or-later - * - */ - -#pragma once - -#include <gnuradio/attributes.h> - -#ifdef gnuradio_filter_EXPORTS -#define FILTER_API __GR_ATTR_EXPORT -#else -#define FILTER_API __GR_ATTR_IMPORT -#endif diff --git a/blocklib/filter/include/gnuradio/filter/meson.build b/blocklib/filter/include/gnuradio/filter/meson.build deleted file mode 100644 index 2a4f9f1af..000000000 --- a/blocklib/filter/include/gnuradio/filter/meson.build +++ /dev/null @@ -1,11 +0,0 @@ -headers = [ - 'api.h', - # 'single_pole_iir.h', - # 'polyphase_filterbank.h', - # 'firdes.h', - # 'fir_filter.h', - # 'interpolator_taps.h', - # 'mmse_fir_interpolator_ff.h' -] - -install_headers(headers, subdir : 'gnuradio/filter') diff --git a/blocklib/filter/lib/.gitignore b/blocklib/filter/lib/.gitignore deleted file mode 100644 index 01ecb66ff..000000000 --- a/blocklib/filter/lib/.gitignore +++ /dev/null @@ -1 +0,0 @@ -!meson.build
\ No newline at end of file diff --git a/blocklib/filter/lib/meson.build b/blocklib/filter/lib/meson.build deleted file mode 100644 index 85d029726..000000000 --- a/blocklib/filter/lib/meson.build +++ /dev/null @@ -1,60 +0,0 @@ -sources = [ - # 'moving_averager.cc', - # 'fir_filter.cc', - # 'mmse_fir_interpolator_ff.cc', - # 'polyphase_filterbank.cc', - # 'firdes.cc' -] - -filter_sources += sources -filter_deps += [gnuradio_gr_dep, gnuradio_blocklib_fft_dep, volk_dep, fmt_dep, pmtf_dep, gr_kernel_filter_lib_dep] -block_cpp_args = ['-DHAVE_CPU'] -if IMPLEMENT_CUDA - block_cpp_args += '-DHAVE_CUDA' - -# gnuradio_blocklib_filter_cu = library('gnuradio-blocklib-filter-cu', -# filter_cu_sources, -# include_directories : incdir, -# install : true, -# dependencies : [cuda_dep]) - -# gnuradio_blocklib_filter_cu_dep = declare_dependency(include_directories : incdir, -# link_with : gnuradio_blocklib_filter_cu, -# dependencies : cuda_dep) - - filter_deps += [cuda_dep, cusp_dep] -endif - - -incdir = include_directories(['../include/gnuradio/filter','../include']) -gnuradio_blocklib_filter_lib = library('gnuradio-blocklib-filter', - filter_sources, - include_directories : incdir, - install : true, - link_language: 'cpp', - dependencies : filter_deps, - cpp_args : block_cpp_args) - -gnuradio_blocklib_filter_dep = declare_dependency(include_directories : incdir, - link_with : gnuradio_blocklib_filter_lib, - dependencies : filter_deps) - -cmake_conf = configuration_data() -cmake_conf.set('libdir', join_paths(prefix,get_option('libdir'))) -cmake_conf.set('module', 'filter') -cmake.configure_package_config_file( - name : 'gnuradio-filter', - input : join_paths(meson.source_root(),'cmake','Modules','gnuradioConfigModule.cmake.in'), - install_dir : get_option('prefix') / get_option('libdir') / 'cmake' / 'gnuradio', - configuration : cmake_conf -) - -pkg = import('pkgconfig') -libs = [gnuradio_blocklib_filter_lib] # the library/libraries users need to link against -h = ['.'] # subdirectories of ${prefix}/${includedir} to add to header path -pkg.generate(libraries : libs, - subdirs : h, - version : meson.project_version(), - name : 'libgnuradio-filter', - filebase : 'gnuradio-filter', - description : 'GNU Radio Filter Module') diff --git a/blocklib/filter/moving_average/moving_average.yml b/blocklib/filter/moving_average/moving_average.yml deleted file mode 100644 index 4110014c6..000000000 --- a/blocklib/filter/moving_average/moving_average.yml +++ /dev/null @@ -1,50 +0,0 @@ -module: filter -block: moving_average -label: Moving Average -blocktype: block -category: '[Core]/Filters' - -typekeys: - - id: T - type: class - options: - - cf32 - - rf32 - -parameters: -- id: length - label: Length - dtype: size - settable: true -- id: scale - label: Scale - dtype: T - settable: true -- id: max_iter - label: Max Iter - dtype: size - settable: false - default: 4096 -- id: vlen - label: Vector Length - dtype: size - settable: false - default: 1 - - -ports: -- domain: stream - id: in - direction: input - type: typekeys/T - -- domain: stream - id: out - direction: output - type: typekeys/T - -implementations: -- id: cpu -- id: cuda - -file_format: 1 diff --git a/blocklib/filter/moving_average/moving_average_cpu.cc b/blocklib/filter/moving_average/moving_average_cpu.cc deleted file mode 100644 index 14cdcff73..000000000 --- a/blocklib/filter/moving_average/moving_average_cpu.cc +++ /dev/null @@ -1,89 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2008,2010,2013,2017,2018 Free Software Foundation, Inc. - * - * This file is part of GNU Radio - * - * SPDX-License-Identifier: GPL-3.0-or-later - * - */ - -#include "moving_average_cpu.h" -#include "moving_average_cpu_gen.h" -#include <volk/volk.h> - -namespace gr { -namespace filter { - -template <class T> -moving_average_cpu<T>::moving_average_cpu( - const typename moving_average<T>::block_args& args) - : INHERITED_CONSTRUCTORS(T), - d_length(args.length), - d_scale(args.scale), - d_max_iter(args.max_iter), - d_vlen(args.vlen), - d_new_length(args.length), - d_new_scale(args.scale) -{ - d_sum = std::vector<T>(d_vlen); - d_history = std::vector<T>(d_vlen * (d_length - 1)); -} - -template <class T> -work_return_t moving_average_cpu<T>::work(work_io& wio) -{ - if (wio.inputs()[0].n_items < d_length) { - wio.outputs()[0].n_produced = 0; - wio.inputs()[0].n_consumed = 0; - return work_return_t::INSUFFICIENT_INPUT_ITEMS; - } - - if (d_updated) { - d_length = d_new_length; - d_scale = d_new_scale; - d_updated = false; - wio.outputs()[0].n_produced = 0; - wio.inputs()[0].n_consumed = 0; - return work_return_t::OK; - } - - auto in = wio.inputs()[0].items<T>(); - auto out = wio.outputs()[0].items<T>(); - - size_t noutput_items = - std::min((wio.inputs()[0].n_items - d_length), wio.outputs()[0].n_items); - - auto num_iter = (noutput_items > d_max_iter) ? d_max_iter : noutput_items; - auto tr = wio.inputs()[0].buf().total_read(); - - if (tr == 0) { // for the first no history case - for (size_t i = 0; i < num_iter; i++) { - for (size_t elem = 0; elem < d_vlen; elem++) { - d_sum[elem] += in[i * d_vlen + elem]; - out[i * d_vlen + elem] = d_sum[elem] * d_scale; - if (i >= (d_length - 1)) { - d_sum[elem] -= in[(i - (d_length - 1)) * d_vlen + elem]; - } - } - } - } - else { - for (size_t i = 0; i < num_iter; i++) { - for (size_t elem = 0; elem < d_vlen; elem++) { - - d_sum[elem] += in[(i + d_length - 1) * d_vlen + elem]; - out[i * d_vlen + elem] = d_sum[elem] * d_scale; - d_sum[elem] -= in[i * d_vlen + elem]; - } - } - } - - // don't consume the last d_length-1 samples - wio.outputs()[0].n_produced = num_iter; - wio.inputs()[0].n_consumed = tr == 0 ? num_iter - (d_length - 1) : num_iter; - return work_return_t::OK; -} // namespace filter - -} // namespace filter -} /* namespace gr */ diff --git a/blocklib/filter/moving_average/moving_average_cpu.h b/blocklib/filter/moving_average/moving_average_cpu.h deleted file mode 100644 index c9ef0290d..000000000 --- a/blocklib/filter/moving_average/moving_average_cpu.h +++ /dev/null @@ -1,47 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2008,2010,2013,2017,2018 Free Software Foundation, Inc. - * - * This file is part of GNU Radio - * - * SPDX-License-Identifier: GPL-3.0-or-later - * - */ - -#pragma once - -#include <gnuradio/filter/moving_average.h> - -#include <vector> - -namespace gr { -namespace filter { - -template <class T> -class moving_average_cpu : public moving_average<T> -{ -public: - moving_average_cpu(const typename moving_average<T>::block_args& args); - - work_return_t work(work_io&) override; - - int group_delay(); - -protected: - size_t d_length; - T d_scale; - size_t d_max_iter; - size_t d_vlen; - T d_scalar_sum; - std::vector<T> d_sum; - - std::vector<T> d_history; - - size_t d_new_length; - T d_new_scale; - bool d_updated = false; -}; - - -} // namespace filter -} // namespace gr diff --git a/blocklib/filter/moving_average/moving_average_cuda.cc b/blocklib/filter/moving_average/moving_average_cuda.cc deleted file mode 100644 index 68c677d88..000000000 --- a/blocklib/filter/moving_average/moving_average_cuda.cc +++ /dev/null @@ -1,72 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2021 Josh Morman - * - * This file is part of GNU Radio - * - * SPDX-License-Identifier: GPL-3.0-or-later - * - */ - -#include "moving_average_cuda.h" -#include "moving_average_cuda_gen.h" - -namespace gr { -namespace filter { - -template <class T> -moving_average_cuda<T>::moving_average_cuda( - const typename moving_average<T>::block_args& args) - : INHERITED_CONSTRUCTORS(T), - d_length(args.length), - d_scale(args.scale), - d_max_iter(args.max_iter), - d_vlen(args.vlen), - d_new_length(args.length), - d_new_scale(args.scale) -{ - std::vector<T> taps(d_length); - for (size_t i = 0; i < d_length; i++) { - taps[i] = (float)1.0 * d_scale; - } - - p_kernel_full = - std::make_shared<cusp::convolve<T, T>>(taps, cusp::convolve_mode_t::FULL_TRUNC); - p_kernel_valid = - std::make_shared<cusp::convolve<T, T>>(taps, cusp::convolve_mode_t::VALID); -} - -template <class T> -work_return_t moving_average_cuda<T>::work(work_io& wio) -{ - if (wio.inputs()[0].n_items < d_length) { - wio.outputs()[0].n_produced = 0; - wio.inputs()[0].n_consumed = 0; - return work_return_t::INSUFFICIENT_INPUT_ITEMS; - } - - auto in = wio.inputs()[0].items<T>(); - auto out = wio.outputs()[0].items<T>(); - - size_t noutput_items = std::min((wio.inputs()[0].n_items), wio.outputs()[0].n_items); - - // auto num_iter = (noutput_items > d_max_iter) ? d_max_iter : noutput_items; - auto num_iter = noutput_items; - auto tr = wio.inputs()[0].buf().total_read(); - - if (tr == 0) { - p_kernel_full->launch_default_occupancy({ in }, { out }, num_iter); - } - else { - p_kernel_valid->launch_default_occupancy({ in }, { out }, num_iter); - } - - // don't consume the last d_length-1 samples - wio.outputs()[0].n_produced = tr == 0 ? num_iter : num_iter - (d_length - 1); - wio.inputs()[0].n_consumed = - tr == 0 ? num_iter - (d_length - 1) : num_iter - (d_length - 1); - return work_return_t::OK; -} // namespace filter - -} // namespace filter -} /* namespace gr */ diff --git a/blocklib/filter/moving_average/moving_average_cuda.h b/blocklib/filter/moving_average/moving_average_cuda.h deleted file mode 100644 index dbaf0dacd..000000000 --- a/blocklib/filter/moving_average/moving_average_cuda.h +++ /dev/null @@ -1,48 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2021 Josh Morman - * - * This file is part of GNU Radio - * - * SPDX-License-Identifier: GPL-3.0-or-later - * - */ - -#pragma once - -#include <gnuradio/filter/moving_average.h> - -#include <vector> - -#include <cusp/convolve.cuh> - -namespace gr { -namespace filter { - -template <class T> -class moving_average_cuda : public moving_average<T> -{ -public: - moving_average_cuda(const typename moving_average<T>::block_args& args); - - work_return_t work(work_io&) override; - - int group_delay(); - -protected: - size_t d_length; - T d_scale; - size_t d_max_iter; - size_t d_vlen; - - size_t d_new_length; - T d_new_scale; - bool d_updated = false; - - std::shared_ptr<cusp::convolve<T, T>> p_kernel_full; - std::shared_ptr<cusp::convolve<T, T>> p_kernel_valid; -}; - - -} // namespace filter -} // namespace gr diff --git a/blocklib/filter/pfb_arb_resampler/pfb_arb_resampler.yml b/blocklib/filter/pfb_arb_resampler/pfb_arb_resampler.yml deleted file mode 100644 index a95e28a87..000000000 --- a/blocklib/filter/pfb_arb_resampler/pfb_arb_resampler.yml +++ /dev/null @@ -1,79 +0,0 @@ -module: filter -block: pfb_arb_resampler -label: PFB Arbitrary Resampler -blocktype: block -category: '[Core]/Resamplers' - -typekeys: - - id: IN_T - type: class - options: - - cf32 - - rf32 - - id: OUT_T - type: class - options: - - cf32 - - rf32 - - id: TAP_T - type: class - options: - - cf32 - - rf32 - -type_inst: - - value: [cf32, cf32, cf32] - label: Complex->Complex (Complex Taps) - - value: [cf32, cf32, rf32] - label: Complex->Complex (Real Taps) - - value: [rf32, rf32, rf32] - label: Float->Float (Real Taps) - -parameters: -- id: rate - label: Rate - dtype: rf32 - settable: true -- id: taps - label: Taps - dtype: TAP_T - container: vector - settable: true -- id: filter_size - label: Filter Size - dtype: rf32 - settable: false - default: 32 - - -# Example Ports -ports: -- domain: stream - id: in - direction: input - type: typekeys/IN_T - -- domain: stream - id: out - direction: output - type: typekeys/OUT_T - -callbacks: -- id: group_delay - return: size_t - const: true -- id: phase_offset - return: rf32 - args: - - id: freq - dtype: rf32 - - id: fs - dtype: rf32 - const: true - - -implementations: -- id: cpu -# - id: cuda - -file_format: 1
\ No newline at end of file diff --git a/blocklib/filter/pfb_arb_resampler/pfb_arb_resampler_cpu.cc b/blocklib/filter/pfb_arb_resampler/pfb_arb_resampler_cpu.cc deleted file mode 100644 index 8d7a1eceb..000000000 --- a/blocklib/filter/pfb_arb_resampler/pfb_arb_resampler_cpu.cc +++ /dev/null @@ -1,138 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2022 Josh Morman - * - * This file is part of GNU Radio - * - * SPDX-License-Identifier: GPL-3.0-or-later - * - */ - -#include "pfb_arb_resampler_cpu.h" -#include "pfb_arb_resampler_cpu_gen.h" - -namespace gr { -namespace filter { - -template <> -std::vector<gr_complex> -pfb_arb_resampler_cpu<gr_complex, gr_complex, gr_complex>::create_taps(float rate, - size_t flt_size, - float atten) -{ - auto ftaps = create_taps_float(rate, flt_size, atten); - std::vector<gr_complex> ctaps; - for (auto& f : ftaps) { - ctaps.push_back(gr_complex(f, 0.0)); - } - return ctaps; -} - -template <class IN_T, class OUT_T, class TAP_T> -std::vector<TAP_T> pfb_arb_resampler_cpu<IN_T, OUT_T, TAP_T>::create_taps(float rate, - size_t flt_size, - float atten) -{ - return create_taps_float(rate, flt_size, atten); -} - - -template <class IN_T, class OUT_T, class TAP_T> -pfb_arb_resampler_cpu<IN_T, OUT_T, TAP_T>::pfb_arb_resampler_cpu( - const typename pfb_arb_resampler<IN_T, OUT_T, TAP_T>::block_args& args) - : INHERITED_CONSTRUCTORS(IN_T, OUT_T, TAP_T) -{ - - std::vector<TAP_T> taps = args.taps; - if (taps.empty()) { - taps = create_taps(args.rate, args.filter_size, 100.0); - } - - d_resamp = std::make_unique<kernel::filter::pfb_arb_resampler<IN_T, OUT_T, TAP_T>>( - args.rate, taps, args.filter_size); - this->declare_noconsume(d_resamp->taps_per_filter() - 1); - - this->set_relative_rate(args.rate); - if (args.rate >= 1.0f) { - size_t output_multiple = std::max<size_t>(args.rate, args.filter_size); - this->set_output_multiple(output_multiple); - } - - d_padding_samps = this->noconsume(); - d_padding_vec.resize(d_padding_samps * 2 + 1); -} - - -template <class IN_T, class OUT_T, class TAP_T> -work_return_t pfb_arb_resampler_cpu<IN_T, OUT_T, TAP_T>::enforce_constraints(work_io& wio) -{ - auto noutput_items = wio.outputs()[0].n_items; - auto ninput_items = wio.inputs()[0].n_items; - - // Constrain inputs based on outputs - size_t nin = 0; - size_t nout = (noutput_items / this->output_multiple()) * this->output_multiple(); - - if (nout / this->relative_rate() < 1) { - nin = this->relative_rate() + this->noconsume(); - } - else { - nin = nout / this->relative_rate() + this->noconsume(); - } - - if (ninput_items < nin) { - nin = ninput_items; - // Then we have to constrain from input to output - nout = (((ninput_items - this->noconsume()) * this->relative_rate()) / - this->output_multiple()) * - this->output_multiple(); - } - - if (nout < this->output_multiple()) { - return work_return_t::INSUFFICIENT_INPUT_ITEMS; - } - - - wio.inputs()[0].n_items = nin - this->noconsume(); - wio.outputs()[0].n_items = nout; - - return work_return_t::OK; -} - -template <class IN_T, class OUT_T, class TAP_T> -work_return_t pfb_arb_resampler_cpu<IN_T, OUT_T, TAP_T>::work(work_io& wio) -{ - - auto in = wio.inputs()[0].items<IN_T>(); - auto out = wio.outputs()[0].items<OUT_T>(); - - auto nitems = wio.inputs()[0].n_items; - - - if (!d_init_padding) { - d_padding_samps = this->noconsume(); - d_init_padding = true; - } - - int nitems_read; - int processed; - if (d_padding_samps) { - // size_t nfilt = std::min(nfilt, ninput_items); - size_t npad = std::min(nitems, d_padding_samps); - - std::copy(in, in + npad, d_padding_vec.data() + npad); - processed = d_resamp->filter(out, d_padding_vec.data(), npad, nitems_read); - d_padding_samps -= npad; - nitems_read -= npad; - } - else { - processed = d_resamp->filter(out, in, nitems, nitems_read); - } - - wio.consume_each(nitems_read); - wio.produce_each(processed); - return work_return_t::OK; -} - -} /* namespace filter */ -} /* namespace gr */ diff --git a/blocklib/filter/pfb_arb_resampler/pfb_arb_resampler_cpu.h b/blocklib/filter/pfb_arb_resampler/pfb_arb_resampler_cpu.h deleted file mode 100644 index a19a43ad3..000000000 --- a/blocklib/filter/pfb_arb_resampler/pfb_arb_resampler_cpu.h +++ /dev/null @@ -1,130 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2022 Josh Morman - * - * This file is part of GNU Radio - * - * SPDX-License-Identifier: GPL-3.0-or-later - * - */ - -#pragma once - -#include <gnuradio/filter/pfb_arb_resampler.h> -#include <gnuradio/kernel/fft/window.h> -#include <gnuradio/kernel/filter/firdes.h> -#include <gnuradio/kernel/filter/optfir.h> -#include <gnuradio/kernel/filter/pfb_arb_resampler.h> - -using namespace gr::kernel::filter; - -namespace gr { -namespace filter { - -template <class IN_T, class OUT_T, class TAP_T> -class pfb_arb_resampler_cpu : public pfb_arb_resampler<IN_T, OUT_T, TAP_T> -{ -public: - pfb_arb_resampler_cpu( - const typename pfb_arb_resampler<IN_T, OUT_T, TAP_T>::block_args& args); - - work_return_t work(work_io&) override; - virtual size_t group_delay() const override { return d_resamp->group_delay(); } - virtual float phase_offset(float freq, float fs) const override - { - return d_resamp->phase_offset(freq, fs); - }; - -private: - std::unique_ptr<kernel::filter::pfb_arb_resampler<IN_T, OUT_T, TAP_T>> d_resamp; - size_t d_history; - - bool d_init_padding = false; - size_t d_padding_samps = 0; - std::vector<IN_T> d_padding_vec; - - work_return_t enforce_constraints(work_io&) override; - - std::vector<TAP_T> create_taps(float rate, size_t flt_size = 32, float atten = 100); - - std::vector<float> - create_taps_float(float rate, size_t flt_size = 32, float atten = 100) - { - // # Create a filter that covers the full bandwidth of the output signal - - // # If rate >= 1, we need to prevent images in the output, - // # so we have to filter it to less than half the channel - // # width of 0.5. If rate < 1, we need to filter to less - // # than half the output signal's bw to avoid aliasing, so - // # the half-band here is 0.5*rate. - - float percent = 0.80; - if (rate < 1) { - float halfband = 0.5 * rate; - float bw = percent * halfband; - float tb = (percent / 2.0) * halfband; - // float ripple = 0.1; - - - // # As we drop the bw factor, the optfir filter has a harder time converging; - // # using the firdes method here for better results. - return firdes::low_pass_2(flt_size, - flt_size, - bw, - tb, - atten, - gr::kernel::fft::window::window_t::BLACKMAN_HARRIS); - } - else { - float halfband = 0.5; - float bw = percent * halfband; - float tb = (percent / 2.0) * halfband; - float ripple = 0.1; - std::vector<double> dtaps; - - while (true) { - try { - dtaps = gr::kernel::filter::optfir::low_pass( - flt_size, flt_size, bw, bw + tb, ripple, atten); - break; - } catch (std::exception& e) { - ripple += 0.01; - this->d_logger->warn( - "Warning: set ripple to {:4f} dB. If this is a problem, adjust " - "the attenuation or create your own filter taps.", - ripple); - - // # Build in an exit strategy; if we've come this far, it ain't - // working. - if (ripple >= 1.0) { - throw std::runtime_error( - "optfir could not generate an appropriate filter."); - } - } - } - - return std::vector<float>(dtaps.begin(), dtaps.end()); - } - } - - - void on_parameter_change(param_action_sptr action) override - { - // This will set the underlying PMT - block::on_parameter_change(action); - - // Do more updating for certain parameters - if (action->id() == pfb_arb_resampler<IN_T, OUT_T, TAP_T>::id_taps) { - d_resamp->set_taps(pmtf::get_as<std::vector<TAP_T>>(*this->param_taps)); - d_history = d_resamp->taps_per_filter(); - } - else if (action->id() == pfb_arb_resampler<IN_T, OUT_T, TAP_T>::id_rate) { - d_resamp->set_rate(pmtf::get_as<float>(*this->param_rate)); - this->set_relative_rate(pmtf::get_as<float>(*this->param_rate)); - } - } -}; - - -} // namespace filter -} // namespace gr diff --git a/blocklib/filter/pfb_arb_resampler/qa_pfb_arb_resampler.py b/blocklib/filter/pfb_arb_resampler/qa_pfb_arb_resampler.py deleted file mode 100644 index 5e7fab5cf..000000000 --- a/blocklib/filter/pfb_arb_resampler/qa_pfb_arb_resampler.py +++ /dev/null @@ -1,305 +0,0 @@ -#!/usr/bin/env python -# -# Copyright 2012,2013 Free Software Foundation, Inc. -# -# This file is part of GNU Radio -# -# SPDX-License-Identifier: GPL-3.0-or-later -# -# - - -from gnuradio import gr, gr_unittest, fft, filter, blocks -from gnuradio.kernel.filter import firdes -from gnuradio.kernel.fft import window -import math - - -def sig_source_c(samp_rate, freq, amp, N): - t = [float(x) / samp_rate for x in range(N)] - y = [math.cos(2. * math.pi * freq * x) + - 1j * math.sin(2. * math.pi * freq * x) for x in t] - return y - - -def sig_source_f(samp_rate, freq, amp, N): - t = [float(x) / samp_rate for x in range(N)] - y = [math.sin(2. * math.pi * freq * x) for x in t] - return y - - -class test_pfb_arb_resampler(gr_unittest.TestCase): - - def setUp(self): - self.tb = gr.top_block() - - def tearDown(self): - self.tb = None - - def test_fff_000(self): - N = 500 # number of samples to use - fs = 5000.0 # baseband sampling rate - rrate = 2.3421 # resampling rate - - nfilts = 32 - taps = firdes.low_pass_2( - nfilts, - nfilts * fs, - fs / 2, - fs / 10, - attenuation_dB=80, - window=window.BLACKMAN_hARRIS) - - freq = 121.213 - data = sig_source_f(fs, freq, 1, N) - signal = blocks.vector_source_f(data) - pfb = filter.pfb_arb_resampler_fff(rrate, taps, nfilts) - snk = blocks.vector_sink_f() - - self.tb.connect((signal, pfb, snk)) - self.tb.run() - - Ntest = 50 - L = len(snk.data()) - - # Get group delay and estimate of phase offset from the filter itself. - delay = pfb.group_delay() - phase = pfb.phase_offset(freq, fs) - - # Create a timeline offset by the filter's group delay - t = [float(x) / (fs * rrate) for x in range(-delay, L - delay)] - - # Data of the sinusoid at frequency freq with the delay and phase - # offset. - expected_data = [math.sin(2. * math.pi * freq * x + phase) for x in t] - - dst_data = snk.data() - - self.assertFloatTuplesAlmostEqual( - expected_data[-Ntest:], dst_data[-Ntest:], 2) - - def test_ccf_000(self): - N = 5000 # number of samples to use - fs = 5000.0 # baseband sampling rate - rrate = 2.4321 # resampling rate - - nfilts = 32 - taps = firdes.low_pass_2( - nfilts, - nfilts * fs, - fs / 2, - fs / 10, - attenuation_dB=80, - window=window.BLACKMAN_hARRIS) - - freq = 211.123 - data = sig_source_c(fs, freq, 1, N) - signal = blocks.vector_source_c(data) - pfb = filter.pfb_arb_resampler_ccf(rrate, taps, nfilts) - snk = blocks.vector_sink_c() - - self.tb.connect((signal, pfb, snk)) - self.tb.run() - - Ntest = 50 - L = len(snk.data()) - - # Get group delay and estimate of phase offset from the filter itself. - delay = pfb.group_delay() - phase = pfb.phase_offset(freq, fs) - - # Create a timeline offset by the filter's group delay - t = [float(x) / (fs * rrate) for x in range(-delay, L - delay)] - - # Data of the sinusoid at frequency freq with the delay and phase - # offset. - expected_data = [ - math.cos( - 2. * - math.pi * - freq * - x + - phase) + - 1j * - math.sin( - 2. * - math.pi * - freq * - x + - phase) for x in t] - - dst_data = snk.data() - - self.assertComplexTuplesAlmostEqual( - expected_data[-Ntest:], dst_data[-Ntest:], 2) - - def test_ccf_001(self): - N = 50000 # number of samples to use - fs = 5000.0 # baseband sampling rate - rrate = 0.75 # resampling rate - - nfilts = 32 - taps = firdes.low_pass_2( - nfilts, - nfilts * fs, - fs / 4, - fs / 10, - attenuation_dB=80, - window=window.BLACKMAN_hARRIS) - - freq = 211.123 - data = sig_source_c(fs, freq, 1, N) - signal = blocks.vector_source_c(data) - pfb = filter.pfb_arb_resampler_ccf(rrate, taps, nfilts) - snk = blocks.vector_sink_c() - - self.tb.connect((signal, pfb, snk)) - self.tb.run() - - Ntest = 50 - L = len(snk.data()) - - # Get group delay and estimate of phase offset from the filter itself. - delay = pfb.group_delay() - phase = pfb.phase_offset(freq, fs) - - # Create a timeline offset by the filter's group delay - t = [float(x) / (fs * rrate) for x in range(-delay, L - delay)] - - # Data of the sinusoid at frequency freq with the delay and phase - # offset. - expected_data = [ - math.cos( - 2. * - math.pi * - freq * - x + - phase) + - 1j * - math.sin( - 2. * - math.pi * - freq * - x + - phase) for x in t] - - dst_data = snk.data() - - self.assertComplexTuplesAlmostEqual( - expected_data[-Ntest:], dst_data[-Ntest:], 2) - - def test_ccc_000(self): - N = 5000 # number of samples to use - fs = 5000.0 # baseband sampling rate - rrate = 3.4321 # resampling rate - - nfilts = 32 - taps = firdes.complex_band_pass_2( - nfilts, - nfilts * fs, - 50, - 400, - fs / 10, - attenuation_dB=80, - window=window.BLACKMAN_hARRIS) - - freq = 211.123 - data = sig_source_c(fs, freq, 1, N) - signal = blocks.vector_source_c(data) - pfb = filter.pfb_arb_resampler_ccc(rrate, taps, nfilts) - snk = blocks.vector_sink_c() - - self.tb.connect((signal, pfb, snk)) - self.tb.run() - - Ntest = 50 - L = len(snk.data()) - - # Get group delay and estimate of phase offset from the filter itself. - delay = pfb.group_delay() - phase = pfb.phase_offset(freq, fs) - - # Create a timeline offset by the filter's group delay - t = [float(x) / (fs * rrate) for x in range(-delay, L - delay)] - - # Data of the sinusoid at frequency freq with the delay and phase - # offset. - expected_data = [ - math.cos( - 2. * - math.pi * - freq * - x + - phase) + - 1j * - math.sin( - 2. * - math.pi * - freq * - x + - phase) for x in t] - - dst_data = snk.data() - - self.assertComplexTuplesAlmostEqual( - expected_data[-Ntest:], dst_data[-Ntest:], 2) - - def test_ccc_001(self): - N = 50000 # number of samples to use - fs = 5000.0 # baseband sampling rate - rrate = 0.715 # resampling rate - - nfilts = 32 - taps = firdes.complex_band_pass_2( - nfilts, - nfilts * fs, - 50, - 400, - fs / 10, - attenuation_dB=80, - window=window.BLACKMAN_hARRIS) - - freq = 211.123 - data = sig_source_c(fs, freq, 1, N) - signal = blocks.vector_source_c(data) - pfb = filter.pfb_arb_resampler_ccc(rrate, taps, nfilts) - snk = blocks.vector_sink_c() - - self.tb.connect((signal, pfb, snk)) - self.tb.run() - - Ntest = 50 - L = len(snk.data()) - - # Get group delay and estimate of phase offset from the filter itself. - delay = pfb.group_delay() - phase = pfb.phase_offset(freq, fs) - - # Create a timeline offset by the filter's group delay - t = [float(x) / (fs * rrate) for x in range(-delay, L - delay)] - - # Data of the sinusoid at frequency freq with the delay and phase - # offset. - expected_data = [ - math.cos( - 2. * - math.pi * - freq * - x + - phase) + - 1j * - math.sin( - 2. * - math.pi * - freq * - x + - phase) for x in t] - - dst_data = snk.data() - - self.assertComplexTuplesAlmostEqual( - expected_data[-Ntest:], dst_data[-Ntest:], 2) - - -if __name__ == '__main__': - gr_unittest.run(test_pfb_arb_resampler) diff --git a/blocklib/filter/pfb_channelizer/pfb_channelizer.yml b/blocklib/filter/pfb_channelizer/pfb_channelizer.yml deleted file mode 100644 index 7a78cdf44..000000000 --- a/blocklib/filter/pfb_channelizer/pfb_channelizer.yml +++ /dev/null @@ -1,47 +0,0 @@ -module: filter -block: pfb_channelizer -label: PFB Channelizer -blocktype: block -category: '[Core]/Channelizers' - -typekeys: - - id: T - type: class - options: - - cf32 - # - rf32 - - -parameters: -- id: numchans - label: Number of Channels - dtype: size - settable: false -- id: taps - label: Filter Taps - dtype: rf32 - container: vector - settable: false -- id: oversample_rate - label: Oversample Rate - dtype: rf32 - settable: false - -ports: -- domain: stream - id: in - direction: input - type: typekeys/T - # multiplicity: parameters/numchans - -- domain: stream - id: out - direction: output - type: typekeys/T - multiplicity: parameters/numchans - -implementations: -- id: cpu -- id: cuda - -file_format: 1 diff --git a/blocklib/filter/pfb_channelizer/pfb_channelizer_cpu.cc b/blocklib/filter/pfb_channelizer/pfb_channelizer_cpu.cc deleted file mode 100644 index 5f500a6f4..000000000 --- a/blocklib/filter/pfb_channelizer/pfb_channelizer_cpu.cc +++ /dev/null @@ -1,180 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2009,2010,2012,2014 Free Software Foundation, Inc. - * - * This file is part of GNU Radio - * - * SPDX-License-Identifier: GPL-3.0-or-later - * - */ - -#include "pfb_channelizer_cpu.h" -#include "pfb_channelizer_cpu_gen.h" -#include <volk/volk.h> - -namespace gr { -namespace filter { - -template <class T> -pfb_channelizer_cpu<T>::pfb_channelizer_cpu( - const typename pfb_channelizer<T>::block_args& args) - : INHERITED_CONSTRUCTORS(T), - polyphase_filterbank(args.numchans, args.taps), - d_oversample_rate(args.oversample_rate), - d_nchans(args.numchans) -{ - - // The over sampling rate must be rationally related to the number of channels - // in that it must be N/i for i in [1,N], which gives an outputsample rate - // of [fs/N, fs] where fs is the input sample rate. - // This tests the specified input sample rate to see if it conforms to this - // requirement within a few significant figures. - const double srate = d_nfilts / d_oversample_rate; - const double rsrate = round(srate); - if (fabs(srate - rsrate) > 0.00001) - throw std::invalid_argument( - "pfb_channelizer: oversample rate must be N/i for i in [1, N]"); - - this->set_relative_rate(d_oversample_rate / d_nchans); - - // Default channel map. The channel map specifies which input - // goes to which output channel; so out[0] comes from - // channel_map[0]. - d_channel_map.resize(d_nfilts); - for (unsigned int i = 0; i < d_nfilts; i++) { - d_channel_map[i] = i; - } - - // We use a look up table to set the index of the FFT input - // buffer, which equivalently performs the FFT shift operation - // on every other turn when the rate_ratio>1. Also, this - // performs the index 'flip' where the first input goes into the - // last filter. In the pfb_decimator_ccf, we directly index the - // input_items buffers starting with this last; here we start - // with the first and put it into the fft object properly for - // the same effect. - d_rate_ratio = (int)rintf(d_nfilts / d_oversample_rate); - d_idxlut.resize(d_nfilts); - for (unsigned int i = 0; i < d_nfilts; i++) { - d_idxlut[i] = d_nfilts - ((i + d_rate_ratio) % d_nfilts) - 1; - } - - // Calculate the number of filtering rounds to do to evenly - // align the input vectors with the output channels - d_output_multiple = 1; - while ((d_output_multiple * d_rate_ratio) % d_nfilts != 0) - d_output_multiple++; - this->set_output_multiple(d_output_multiple); - - // Use set_taps to also set the history requirement - set_taps(args.taps); - - // because we need a stream_to_streams block for the input, - // only send tags from in[i] -> out[i]. - this->set_tag_propagation_policy(tag_propagation_policy_t::TPP_ONE_TO_ONE); - - d_deinterleaved.resize(d_nchans); -} - -template <class T> -void pfb_channelizer_cpu<T>::set_taps(const std::vector<float>& taps) -{ - // std::scoped_lock guard(d_mutex); - - polyphase_filterbank::set_taps(taps); - // set_history(d_taps_per_filter + 1); - d_history = d_nchans * (d_taps_per_filter + 1); - d_updated = true; -} - - -template <class T> -work_return_t pfb_channelizer_cpu<T>::work(work_io& wio) -{ - // std::scoped_lock guard(d_mutex); - - auto in = wio.inputs()[0].items<T>(); - auto out = wio.outputs()[0].items<T>(); - auto noutput_items = wio.outputs()[0].n_items; - auto ninput_items = wio.inputs()[0].n_items; - - if ((size_t)ninput_items < d_history * d_nchans) { // if we can produce 1 output item - return work_return_t::INSUFFICIENT_INPUT_ITEMS; - } - - if (d_updated) { - d_updated = false; - return work_return_t::OK; // history requirements may have changed. - } - - // includes history - auto total_items = - std::min(ninput_items / d_nchans, noutput_items + (d_history / d_nchans)); - - for (size_t j = 0; j < d_nchans; j++) { - if (d_deinterleaved[j].size() < total_items) { - d_deinterleaved[j].resize(total_items); - } - for (size_t i = 0; i < total_items; i++) { - d_deinterleaved[j][i] = in[i * d_nchans + j]; - } - } - - size_t noutputs = wio.outputs().size(); - noutput_items = total_items - d_history + 1; - - // The following algorithm looks more complex in order to handle - // the cases where we want more that 1 sps for each - // channel. Otherwise, this would boil down into a single loop - // that operates from input_items[0] to [d_nfilts]. - - // When dealing with osps>1, we start not at the last filter, - // but nfilts/osps and then wrap around to the next symbol into - // the other set of filters. - // For details of this operation, see: - // fred harris, Multirate Signal Processing For Communication - // Systems. Upper Saddle River, NJ: Prentice Hall, 2004. - - int n = 1, i = -1, j = 0, oo = 0, last; - int toconsume = (int)rintf(noutput_items / d_oversample_rate); - while (n <= toconsume) { - j = 0; - i = (i + d_rate_ratio) % d_nfilts; - last = i; - while (i >= 0) { - // in = wio.inputs()[j].items<gr_complex>(); - in = d_deinterleaved[j].data(); - d_fft.get_inbuf()[d_idxlut[j]] = d_fir_filters[i].filter(&in[n]); - j++; - i--; - } - - i = d_nfilts - 1; - while (i > last) { - // in = wio.inputs()[j].items<gr_complex>(); - in = d_deinterleaved[j].data(); - d_fft.get_inbuf()[d_idxlut[j]] = d_fir_filters[i].filter(&in[n - 1]); - j++; - i--; - } - - n += (i + d_rate_ratio) >= (int)d_nfilts; - - // despin through FFT - d_fft.execute(); - - // Send to output channels - for (unsigned int nn = 0; nn < noutputs; nn++) { - out = wio.outputs()[nn].items<gr_complex>(); - out[oo] = d_fft.get_outbuf()[d_channel_map[nn]]; - } - oo++; - } - wio.consume_each(toconsume * d_nchans); - // this->produce_each(noutput_items - (d_history / d_nchans - 1), work_output); - wio.produce_each(noutput_items); - return work_return_t::OK; -} - -} /* namespace filter */ -} /* namespace gr */ diff --git a/blocklib/filter/pfb_channelizer/pfb_channelizer_cpu.h b/blocklib/filter/pfb_channelizer/pfb_channelizer_cpu.h deleted file mode 100644 index 9bd442577..000000000 --- a/blocklib/filter/pfb_channelizer/pfb_channelizer_cpu.h +++ /dev/null @@ -1,51 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2009,2010,2012 Free Software Foundation, Inc. - * - * This file is part of GNU Radio - * - * SPDX-License-Identifier: GPL-3.0-or-later - * - */ - -#pragma once - -#include <gnuradio/filter/pfb_channelizer.h> -#include <gnuradio/kernel/filter/polyphase_filterbank.h> - -#include <mutex> - -namespace gr { -namespace filter { - -template <class T> -class pfb_channelizer_cpu : public pfb_channelizer<T>, - kernel::filter::polyphase_filterbank -{ -public: - pfb_channelizer_cpu(const typename pfb_channelizer<T>::block_args& args); - - work_return_t work(work_io&) override; - - int group_delay(); - void set_taps(const std::vector<float>& taps) override; - -private: - bool d_updated = false; - float d_oversample_rate; - std::vector<int> d_idxlut; - int d_rate_ratio; - int d_output_multiple; - std::vector<int> d_channel_map; - std::mutex d_mutex; // mutex to protect set/work access - - size_t d_history = 1; - - size_t d_nchans; - - std::vector<std::vector<T>> d_deinterleaved; -}; - - -} // namespace filter -} // namespace gr diff --git a/blocklib/filter/pfb_channelizer/pfb_channelizer_cuda.cc b/blocklib/filter/pfb_channelizer/pfb_channelizer_cuda.cc deleted file mode 100644 index 9caadb73b..000000000 --- a/blocklib/filter/pfb_channelizer/pfb_channelizer_cuda.cc +++ /dev/null @@ -1,81 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2021 Josh Morman - * - * This file is part of GNU Radio - * - * SPDX-License-Identifier: GPL-3.0-or-later - * - */ - -#include "pfb_channelizer_cuda.h" -#include "pfb_channelizer_cuda_gen.h" - -#include <gnuradio/helper_cuda.h> - -namespace gr { -namespace filter { - -template <class T> -pfb_channelizer_cuda<T>::pfb_channelizer_cuda( - const typename pfb_channelizer<T>::block_args& args) - : INHERITED_CONSTRUCTORS(T), d_nchans(args.numchans) -{ - d_in_items.resize(1); - d_out_items.resize(d_nchans); - - auto new_taps = std::vector<gr_complex>(args.taps.size()); - for (size_t i = 0; i < args.taps.size(); i++) { - new_taps[i] = gr_complex(args.taps[i], 0); - } - - // quantize the overlap to the nchans - d_overlap = d_nchans * ((args.taps.size() + d_nchans - 1) / d_nchans); - checkCudaErrors(cudaMalloc(&d_dev_tail, d_overlap * sizeof(gr_complex))); - checkCudaErrors(cudaMemset(d_dev_tail, 0, d_overlap * sizeof(gr_complex))); - - checkCudaErrors( - cudaMalloc(&d_dev_buf, 16 * 1024 * 1024 * sizeof(gr_complex))); // 4M items max ?? - - p_channelizer = std::make_shared<cusp::channelizer<gr_complex>>(new_taps, d_nchans); - cudaStreamCreate(&d_stream); - p_channelizer->set_stream(d_stream); - - p_deinterleaver = - std::make_shared<cusp::deinterleave>(d_nchans, 1, sizeof(gr_complex)); - - p_deinterleaver->set_stream(d_stream); - // set_output_multiple(nchans); - // set_min_noutput_items(d_overlap+1024); -} - -template <class T> -work_return_t pfb_channelizer_cuda<T>::work(work_io& wio) -{ - // std::scoped_lock guard(d_mutex); - - auto noutput_items = wio.outputs()[0].n_items; - auto ninput_items = wio.inputs()[0].n_items; - - if ((size_t)ninput_items < noutput_items * d_nchans + d_overlap) { - return work_return_t::INSUFFICIENT_INPUT_ITEMS; - } - - d_in_items = wio.all_input_ptrs(); - d_out_items = wio.all_output_ptrs(); - - checkCudaErrors(p_channelizer->launch_default_occupancy( - d_in_items, { d_dev_buf }, (noutput_items + d_overlap / d_nchans))); - - checkCudaErrors(p_deinterleaver->launch_default_occupancy( - { (gr_complex*)d_dev_buf + d_overlap }, d_out_items, noutput_items * d_nchans)); - - cudaStreamSynchronize(d_stream); - - wio.consume_each(noutput_items * d_nchans); - wio.produce_each(noutput_items); - return work_return_t::OK; -} - -} /* namespace filter */ -} /* namespace gr */ diff --git a/blocklib/filter/pfb_channelizer/pfb_channelizer_cuda.h b/blocklib/filter/pfb_channelizer/pfb_channelizer_cuda.h deleted file mode 100644 index 67b2afe4a..000000000 --- a/blocklib/filter/pfb_channelizer/pfb_channelizer_cuda.h +++ /dev/null @@ -1,47 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2021 Josh Morman - * - * This file is part of GNU Radio - * - * SPDX-License-Identifier: GPL-3.0-or-later - * - */ - -#pragma once - -#include <gnuradio/filter/pfb_channelizer.h> -#include <cusp/channelizer.cuh> -#include <cusp/deinterleave.cuh> - -namespace gr { -namespace filter { - -template <class T> -class pfb_channelizer_cuda : public pfb_channelizer<T> -{ -public: - pfb_channelizer_cuda(const typename pfb_channelizer<T>::block_args& args); - - work_return_t work(work_io&) override; - - -private: - size_t d_nchans; - size_t d_taps; - size_t d_overlap; - - void* d_dev_buf; - void* d_dev_tail; - cudaStream_t d_stream; - - std::shared_ptr<cusp::channelizer<gr_complex>> p_channelizer; - std::shared_ptr<cusp::deinterleave> p_deinterleaver; - - std::vector<const void*> d_in_items; - std::vector<void*> d_out_items; -}; - - -} // namespace filter -} // namespace gr diff --git a/blocklib/filter/python/gnuradio/filter/.gitignore b/blocklib/filter/python/gnuradio/filter/.gitignore deleted file mode 100644 index 2926fbdb7..000000000 --- a/blocklib/filter/python/gnuradio/filter/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -!meson.build -!bindings/meson.build
\ No newline at end of file diff --git a/blocklib/filter/python/gnuradio/filter/__init__.py b/blocklib/filter/python/gnuradio/filter/__init__.py deleted file mode 100644 index 335c503ca..000000000 --- a/blocklib/filter/python/gnuradio/filter/__init__.py +++ /dev/null @@ -1,9 +0,0 @@ - -import os - -try: - from .filter_python import * -except ImportError: - dirname, filename = os.path.split(os.path.abspath(__file__)) - __path__.append(os.path.join(dirname, "bindings")) - from .filter_python import * diff --git a/blocklib/filter/python/gnuradio/filter/bindings/firdes_pybind.cc b/blocklib/filter/python/gnuradio/filter/bindings/firdes_pybind.cc deleted file mode 100644 index 5c7e51ae5..000000000 --- a/blocklib/filter/python/gnuradio/filter/bindings/firdes_pybind.cc +++ /dev/null @@ -1,203 +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(firdes.h) */ -/* BINDTOOL_HEADER_FILE_HASH(10cf0c4b9664ba7e2931c2375c13c68c) */ -/***********************************************************************************/ - -#include <pybind11/complex.h> -#include <pybind11/pybind11.h> -#include <pybind11/stl.h> - -namespace py = pybind11; - -#include <gnuradio/kernel/filter/firdes.h> -// pydoc.h is automatically generated in the build directory -// #include <firdes_pydoc.h> - -void bind_firdes(py::module& m) -{ - using firdes = gr::filter::firdes; - - py::class_<firdes, std::shared_ptr<firdes>> firdes_class(m, "firdes"); - - firdes_class - .def_static("window", - &firdes::window, - py::arg("type"), - py::arg("ntaps"), - py::arg("param")) - - - .def_static("low_pass", - &firdes::low_pass, - py::arg("gain"), - py::arg("sampling_freq"), - py::arg("cutoff_freq"), - py::arg("transition_width"), - py::arg("window") = ::gr::kernel::fft::window::window_t::HAMMING, - py::arg("param") = 6.7599999999999998) - - - .def_static("low_pass_2", - &firdes::low_pass_2, - py::arg("gain"), - py::arg("sampling_freq"), - py::arg("cutoff_freq"), - py::arg("transition_width"), - py::arg("attenuation_dB"), - py::arg("window") = ::gr::kernel::fft::window::window_t::HAMMING, - py::arg("param") = 6.7599999999999998) - - - .def_static("high_pass", - &firdes::high_pass, - py::arg("gain"), - py::arg("sampling_freq"), - py::arg("cutoff_freq"), - py::arg("transition_width"), - py::arg("window") = ::gr::kernel::fft::window::window_t::HAMMING, - py::arg("param") = 6.7599999999999998) - - - .def_static("high_pass_2", - &firdes::high_pass_2, - py::arg("gain"), - py::arg("sampling_freq"), - py::arg("cutoff_freq"), - py::arg("transition_width"), - py::arg("attenuation_dB"), - py::arg("window") = ::gr::kernel::fft::window::window_t::HAMMING, - py::arg("param") = 6.7599999999999998) - - - .def_static("band_pass", - &firdes::band_pass, - py::arg("gain"), - py::arg("sampling_freq"), - py::arg("low_cutoff_freq"), - py::arg("high_cutoff_freq"), - py::arg("transition_width"), - py::arg("window") = ::gr::kernel::fft::window::window_t::HAMMING, - py::arg("param") = 6.7599999999999998) - - - .def_static("band_pass_2", - &firdes::band_pass_2, - py::arg("gain"), - py::arg("sampling_freq"), - py::arg("low_cutoff_freq"), - py::arg("high_cutoff_freq"), - py::arg("transition_width"), - py::arg("attenuation_dB"), - py::arg("window") = ::gr::kernel::fft::window::window_t::HAMMING, - py::arg("param") = 6.7599999999999998) - - - .def_static("complex_band_pass", - &firdes::complex_band_pass, - py::arg("gain"), - py::arg("sampling_freq"), - py::arg("low_cutoff_freq"), - py::arg("high_cutoff_freq"), - py::arg("transition_width"), - py::arg("window") = ::gr::kernel::fft::window::window_t::HAMMING, - py::arg("param") = 6.7599999999999998) - - - .def_static("complex_band_pass_2", - &firdes::complex_band_pass_2, - py::arg("gain"), - py::arg("sampling_freq"), - py::arg("low_cutoff_freq"), - py::arg("high_cutoff_freq"), - py::arg("transition_width"), - py::arg("attenuation_dB"), - py::arg("window") = ::gr::kernel::fft::window::window_t::HAMMING, - py::arg("param") = 6.7599999999999998) - - - .def_static("band_reject", - &firdes::band_reject, - py::arg("gain"), - py::arg("sampling_freq"), - py::arg("low_cutoff_freq"), - py::arg("high_cutoff_freq"), - py::arg("transition_width"), - py::arg("window") = ::gr::kernel::fft::window::window_t::HAMMING, - py::arg("param") = 6.7599999999999998) - - - .def_static("band_reject_2", - &firdes::band_reject_2, - py::arg("gain"), - py::arg("sampling_freq"), - py::arg("low_cutoff_freq"), - py::arg("high_cutoff_freq"), - py::arg("transition_width"), - py::arg("attenuation_dB"), - py::arg("window") = ::gr::kernel::fft::window::window_t::HAMMING, - py::arg("param") = 6.7599999999999998) - - - .def_static("complex_band_reject", - &firdes::complex_band_reject, - py::arg("gain"), - py::arg("sampling_freq"), - py::arg("low_cutoff_freq"), - py::arg("high_cutoff_freq"), - py::arg("transition_width"), - py::arg("window") = ::gr::kernel::fft::window::window_t::HAMMING, - py::arg("param") = 6.7599999999999998) - - - .def_static("complex_band_reject_2", - &firdes::complex_band_reject_2, - py::arg("gain"), - py::arg("sampling_freq"), - py::arg("low_cutoff_freq"), - py::arg("high_cutoff_freq"), - py::arg("transition_width"), - py::arg("attenuation_dB"), - py::arg("window") = ::gr::kernel::fft::window::window_t::HAMMING, - py::arg("param") = 6.7599999999999998) - - - .def_static("hilbert", - &firdes::hilbert, - py::arg("ntaps") = 19, - py::arg("windowtype") = - ::gr::kernel::fft::window::window_t::RECTANGULAR, - py::arg("param") = 6.7599999999999998) - - - .def_static("root_raised_cosine", - &firdes::root_raised_cosine, - py::arg("gain"), - py::arg("sampling_freq"), - py::arg("symbol_rate"), - py::arg("alpha"), - py::arg("ntaps")) - - - .def_static("gaussian", - &firdes::gaussian, - py::arg("gain"), - py::arg("spb"), - py::arg("bt"), - py::arg("ntaps")) - - ; -} diff --git a/blocklib/filter/python/gnuradio/filter/bindings/meson.build b/blocklib/filter/python/gnuradio/filter/bindings/meson.build deleted file mode 100644 index 6097165d2..000000000 --- a/blocklib/filter/python/gnuradio/filter/bindings/meson.build +++ /dev/null @@ -1,2 +0,0 @@ -# filter_pybind_sources = [files('firdes_pybind.cc')] + filter_pybind_sources -# filter_pybind_names = ['firdes'] + filter_pybind_names
\ No newline at end of file diff --git a/blocklib/filter/python/gnuradio/filter/meson.build b/blocklib/filter/python/gnuradio/filter/meson.build deleted file mode 100644 index 2e0b56032..000000000 --- a/blocklib/filter/python/gnuradio/filter/meson.build +++ /dev/null @@ -1,54 +0,0 @@ -# not autogenerated -# can be autogenerated when there is a way to figure out the top level imports -###################### -# Python Bindings ### -###################### - -# Generate _python.cc for each block -fs = import('fs') -if fs.exists('bindings/meson.build') -subdir('bindings') -endif -srcs = ['__init__.py'] - -foreach s: srcs -configure_file(copy: true, - input: s, - output: s -) -endforeach - -d = { - 'blocks' : filter_pybind_names, - 'module' : 'filter', - 'imports' : ['gnuradio.gr','gnuradio.fft'] -} - -gen_filter_pybind = custom_target('gen_filter_pybind', - output : ['filter_pybind.cc'], - command : ['python3', join_paths(SCRIPTS_DIR,'process_module_pybind.py'), - '--blocks', d['blocks'], - '--imports', d['imports'], - '--module', d['module'], - '--output_file', '@OUTPUT@', - '--build_dir', join_paths(meson.build_root())], - install : false) - -filter_pybind_sources += gen_filter_pybind - -gnuradio_blocklib_filter_pybind = py3.extension_module('filter_python', - filter_pybind_sources, - include_directories: ['../../../lib', incdir_numpy], - dependencies : [gnuradio_blocklib_filter_dep, python3_dep, pybind11_dep], - link_language : 'cpp', - install : true, - install_dir : join_paths(py3_install_dir,'gnuradio','filter') -) - -gnuradio_blocklib_filter_pybind_dep = declare_dependency(include_directories : incdir, - link_with : gnuradio_blocklib_filter_pybind, - dependencies : filter_deps) - - -# Target for pure python -install_data(srcs, install_dir : join_paths(py3_install_dir,'gnuradio','filter')) diff --git a/blocklib/filter/test/.gitignore b/blocklib/filter/test/.gitignore deleted file mode 100644 index 01ecb66ff..000000000 --- a/blocklib/filter/test/.gitignore +++ /dev/null @@ -1 +0,0 @@ -!meson.build
\ No newline at end of file diff --git a/blocklib/filter/test/cuda/qa_moving_average_cuda.py b/blocklib/filter/test/cuda/qa_moving_average_cuda.py deleted file mode 100644 index 6bdbf4a7c..000000000 --- a/blocklib/filter/test/cuda/qa_moving_average_cuda.py +++ /dev/null @@ -1,232 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright 2013,2017 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, blocks, filter -import numpy as np - -import math, random - -def make_random_complex_tuple(L, scale=1): - result = [] - for x in range(L): - result.append(scale*complex(2*random.random()-1, - 2*random.random()-1)) - return tuple(result) - -def make_random_float_tuple(L, scale=1): - result = [] - for x in range(L): - result.append(scale*(2*random.random()-1)) - return tuple(result) - -class test_moving_average(gr_unittest.TestCase): - - def setUp(self): - random.seed(0) - self.tb = gr.flowgraph() - - def tearDown(self): - self.tb = None - - # These tests will always pass and are therefore useless. 100 random numbers [-1,1) are - # getting summed up and scaled with 0.001. Then, an assertion verifies a result near 0, - # which is the case even if the block is malfunctioning. - - def test_01(self): - tb = self.tb - - N = 10000 - data = make_random_float_tuple(N, 1) - expected_result = N*[0,] - - src = blocks.vector_source_f(data, False) - op = filter.moving_average_ff(100, 0.001, impl=filter.moving_average_ff.cuda) - dst = blocks.vector_sink_f() - - tb.connect(src, op).set_custom_buffer(gr.buffer_cuda_properties.make(gr.buffer_cuda_type.H2D)) - tb.connect(op, dst).set_custom_buffer(gr.buffer_cuda_properties.make(gr.buffer_cuda_type.D2H)) - tb.run() - - dst_data = dst.data() - - # make sure result is close to zero - self.assertFloatTuplesAlmostEqual(expected_result, dst_data, 1) - - def test_02(self): - tb = self.tb - - N = 10000 - data = make_random_complex_tuple(N, 1) - expected_result = N*[0,] - - src = blocks.vector_source_c(data, False) - op = filter.moving_average_cc(100, 0.001, impl=filter.moving_average_cc.cuda) - dst = blocks.vector_sink_c() - - tb.connect(src, op).set_custom_buffer(gr.buffer_cuda_properties.make(gr.buffer_cuda_type.H2D)) - tb.connect(op, dst).set_custom_buffer(gr.buffer_cuda_properties.make(gr.buffer_cuda_type.D2H)) - tb.run() - - dst_data = dst.data() - - # make sure result is close to zero - self.assertComplexTuplesAlmostEqual(expected_result, dst_data, 1) - - def test_moving_sum(self): - tb = self.tb - - N = 10000 - filt_len = 14 - data = [1.0] * N - expected_result = N*[filt_len,] - expected_result[0:filt_len-1] = list(range(1, filt_len)) - - src = blocks.vector_source_f(data, False) - op = filter.moving_average_ff(filt_len, 1.0, impl=filter.moving_average_ff.cuda) - dst = blocks.vector_sink_f() - - tb.connect(src, op).set_custom_buffer(gr.buffer_cuda_properties.make(gr.buffer_cuda_type.H2D)) - tb.connect(op, dst).set_custom_buffer(gr.buffer_cuda_properties.make(gr.buffer_cuda_type.D2H)) - tb.run() - - dst_data = dst.data() - - self.assertFloatTuplesAlmostEqual(expected_result, dst_data, 4) - - def test_moving_sum2(self): - tb = self.tb - - - filt_len = 3 - data = list(range(1,11)) - expected_result = [] - for ii in range(10): - sum = 0.0 - for jj in range(filt_len): - if (ii - jj ) >= 0: - sum += data[ii-jj] - expected_result.append(sum) - - src = blocks.vector_source_f(data, False) - op = filter.moving_average_ff(filt_len, 1.0, 4, impl=filter.moving_average_ff.cuda) - dst = blocks.vector_sink_f() - - tb.connect(src, op).set_custom_buffer(gr.buffer_cuda_properties.make(gr.buffer_cuda_type.H2D)) - tb.connect(op, dst).set_custom_buffer(gr.buffer_cuda_properties.make(gr.buffer_cuda_type.D2H)) - tb.run() - - dst_data = dst.data() - - self.assertFloatTuplesAlmostEqual(expected_result, dst_data, 4) - - def test_moving_avg3(self): - tb = self.tb - - N = 100000 - filt_len = 64 - data = list(make_random_float_tuple(N, scale=1)) - expected_result = [] - for ii in range(N): - sum = 0.0 - for jj in range(filt_len): - if (ii - jj ) >= 0: - sum += data[ii-jj] - expected_result.append(float(sum / N)) - - src = blocks.vector_source_f(data, False) - op = filter.moving_average_ff(filt_len, 1.0 / N, 4000, impl=filter.moving_average_ff.cuda) - dst = blocks.vector_sink_f() - - tb.connect(src, op).set_custom_buffer(gr.buffer_cuda_properties.make(gr.buffer_cuda_type.H2D)) - tb.connect(op, dst).set_custom_buffer(gr.buffer_cuda_properties.make(gr.buffer_cuda_type.D2H)) - tb.run() - - dst_data = dst.data() - - self.assertFloatTuplesAlmostEqual(expected_result, dst_data, 7) - - # This tests implement own moving average to verify correct behaviour of the block - - # def test_03(self): - # tb = self.tb - - # vlen = 5 - # N = 10*vlen - # data = make_random_float_tuple(N, 2**10) - # data = [int(d*1000) for d in data] - # src = blocks.vector_source_i(data, False) - # one_to_many = blocks.stream_to_streams(gr.sizeof_int, vlen) - # one_to_vector = blocks.stream_to_vector(gr.sizeof_int, vlen) - # many_to_vector = blocks.streams_to_vector(gr.sizeof_int, vlen) - # isolated = [ filter.moving_average_ii(100, 1) for i in range(vlen)] - # dut = filter.moving_average_ii(100, 1, vlen=vlen) - # dut_dst = blocks.vector_sink_i(vlen=vlen) - # ref_dst = blocks.vector_sink_i(vlen=vlen) - - # tb.connect(src, one_to_many) - # tb.connect(src, one_to_vector) #, dut, dut_dst) - # tb.connect(one_to_vector, dut) - # tb.connect(dut, dut_dst) - # tb.connect(many_to_vector, ref_dst) - # for idx, single in enumerate(isolated): - # tb.connect((one_to_many,idx), single, (many_to_vector,idx)) - - # tb.run() - - # dut_data = dut_dst.data() - # ref_data = ref_dst.data() - - # # make sure result is close to zero - # self.assertTupleEqual(dut_data, ref_data) - - # def test_04(self): - # tb = self.tb - - # N = 10000 # number of samples - # history = 100 # num of samples to average - # data = make_random_complex_tuple(N, 1) # generate random data - - # # pythonic MA filter - # data_padded = (history-1)*[0.0+1j*0.0]+list(data) # history - # expected_result = [] - # moving_sum = sum(data_padded[:history-1]) - # for i in range(N): - # moving_sum += data_padded[i+history-1] - # expected_result.append(moving_sum) - # moving_sum -= data_padded[i] - - # src = blocks.vector_source_c(data, False) - # op = filter.moving_average_cc(history, 1) - # dst = blocks.vector_sink_c() - - # tb.connect(src, op) - # tb.connect(op, dst) - # tb.run() - - # dst_data = dst.data() - - # # make sure result is close to zero - # self.assertComplexTuplesAlmostEqual(expected_result, dst_data, 4) - -if __name__ == '__main__': - gr_unittest.run(test_moving_average) diff --git a/blocklib/filter/test/meson.build b/blocklib/filter/test/meson.build deleted file mode 100644 index ea9e53dcb..000000000 --- a/blocklib/filter/test/meson.build +++ /dev/null @@ -1,10 +0,0 @@ -################################################### -# QA -################################################### - -if GR_ENABLE_PYTHON - test('qa_fir_filter', find_program('qa_fir_filter.py'), env: TEST_ENV) - test('qa_iir_filter', find_program('qa_iir_filter.py'), env: TEST_ENV) - test('qa_pfb_channelizer', find_program('qa_pfb_channelizer.py'), env: TEST_ENV) - # test('qa_moving_average', find_program('qa_moving_average.py'), env: TEST_ENV) -endif diff --git a/blocklib/filter/test/qa_fir_filter.py b/blocklib/filter/test/qa_fir_filter.py deleted file mode 100644 index e19040a2c..000000000 --- a/blocklib/filter/test/qa_fir_filter.py +++ /dev/null @@ -1,196 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright 2008,2010,2012,2013 Free Software Foundation, Inc. -# -# This file is part of GNU Radio -# -# SPDX-License-Identifier: GPL-3.0-or-later -# -# - - -from gnuradio import gr, gr_unittest, filter, blocks -from gnuradio.kernel.filter import firdes -import math - -def fir_filter(x, taps, decim=1): - y = [] - # x2 = (len(taps) - 1) * [0, ] + x - x2 = x - m = decim *((len(x)-len(taps)+1) // decim) - - for i in range(0, m, decim): - yi = 0 - for j in range(len(taps)): - yi += taps[len(taps) - 1 - j] * x2[i + j] - y.append(yi) - return y - - -class test_filter(gr_unittest.TestCase): - - def setUp(self): - self.tb = gr.top_block() - - def tearDown(self): - self.tb = None - - def test_fir_filter_fff_001(self): - decim = 1 - taps = 20 * [0.5, 0.5] - src_data = 40 * [1, 2, 3, 4] - expected_data = fir_filter(src_data, taps, decim) - - src = blocks.vector_source_f(src_data) - op = filter.fir_filter_fff(decim, taps) - dst = blocks.vector_sink_f() - self.tb.connect((src, op, dst)) - self.tb.run() - result_data = dst.data() - self.assertFloatTuplesAlmostEqual(expected_data, result_data, 5) - - def test_fir_filter_fff_002(self): - decim = 4 - taps = 20 * [0.5, 0.5] - src_data = 40 * [1, 2, 3, 4] - expected_data = fir_filter(src_data, taps, decim) - - src = blocks.vector_source_f(src_data) - op = filter.fir_filter_fff(decim, taps) - dst = blocks.vector_sink_f() - self.tb.connect((src, op, dst)) - self.tb.run() - result_data = dst.data() - self.assertFloatTuplesAlmostEqual(expected_data, result_data, 5) - - def test_fir_filter_ccf_001(self): - decim = 1 - taps = 20 * [0.5, 0.5] - src_data = 40 * [1 + 1j, 2 + 2j, 3 + 3j, 4 + 4j] - expected_data = fir_filter(src_data, taps, decim) - - src = blocks.vector_source_c(src_data) - op = filter.fir_filter_ccf(decim, taps) - dst = blocks.vector_sink_c() - self.tb.connect((src, op, dst)) - self.tb.run() - result_data = dst.data() - self.assertComplexTuplesAlmostEqual(expected_data, result_data, 5) - - def test_fir_filter_ccf_002(self): - decim = 4 - taps = 20 * [0.5, 0.5] - src_data = 40 * [1 + 1j, 2 + 2j, 3 + 3j, 4 + 4j] - expected_data = fir_filter(src_data, taps, decim) - - src = blocks.vector_source_c(src_data) - op = filter.fir_filter_ccf(decim, taps) - dst = blocks.vector_sink_c() - self.tb.connect((src, op, dst)) - self.tb.run() - result_data = dst.data() - self.assertComplexTuplesAlmostEqual(expected_data, result_data, 5) - - def test_fir_filter_ccc_001(self): - decim = 1 - taps = 20 * [0.5 + 1j, 0.5 + 1j] - src_data = 40 * [1 + 1j, 2 + 2j, 3 + 3j, 4 + 4j] - expected_data = fir_filter(src_data, taps, decim) - - src = blocks.vector_source_c(src_data) - op = filter.fir_filter_ccc(decim, taps) - dst = blocks.vector_sink_c() - self.tb.connect((src, op, dst)) - self.tb.run() - result_data = dst.data() - self.assertComplexTuplesAlmostEqual(expected_data, result_data, 5) - - def test_fir_filter_ccc_002(self): - decim = 1 - taps = firdes.low_pass(1, 1, 0.1, 0.01) - src_data = [0]*len(taps) + 10 * [1 + 1j, 2 + 2j, 3 + 3j, 4 + 4j] - expected_data = fir_filter(src_data, taps, decim) - - src = blocks.vector_source_c(src_data) - op = filter.fir_filter_ccc(decim, taps) - dst = blocks.vector_sink_c() - self.tb.connect((src, op, dst)) - self.tb.run() - result_data = dst.data() - self.assertComplexTuplesAlmostEqual(expected_data, result_data, 5) - - def test_fir_filter_ccc_003(self): - decim = 4 - taps = 20 * [0.5 + 1j, 0.5 + 1j] - src_data = 40 * [1 + 1j, 2 + 2j, 3 + 3j, 4 + 4j] - expected_data = fir_filter(src_data, taps, decim) - - src = blocks.vector_source_c(src_data) - op = filter.fir_filter_ccc(decim, taps) - dst = blocks.vector_sink_c() - self.tb.connect((src, op, dst)) - self.tb.run() - result_data = dst.data() - self.assertComplexTuplesAlmostEqual(expected_data, result_data, 5) - - def test_fir_filter_scc_001(self): - decim = 1 - taps = 20 * [0.5 + 1j, 0.5 + 1j] - src_data = 40 * [1, 2, 3, 4] - expected_data = fir_filter(src_data, taps, decim) - - src = blocks.vector_source_s(src_data) - op = filter.fir_filter_scc(decim, taps) - dst = blocks.vector_sink_c() - self.tb.connect((src, op, dst)) - self.tb.run() - result_data = dst.data() - self.assertComplexTuplesAlmostEqual(expected_data, result_data, 5) - - def test_fir_filter_scc_002(self): - decim = 4 - taps = 20 * [0.5 + 1j, 0.5 + 1j] - src_data = 40 * [1, 2, 3, 4] - expected_data = fir_filter(src_data, taps, decim) - - src = blocks.vector_source_s(src_data) - op = filter.fir_filter_scc(decim, taps) - dst = blocks.vector_sink_c() - self.tb.connect((src, op, dst)) - self.tb.run() - result_data = dst.data() - self.assertComplexTuplesAlmostEqual(expected_data, result_data, 5) - - def test_fir_filter_fsf_001(self): - decim = 1 - taps = 20 * [0.5, 0.5] - src_data = 40 * [1, 2, 3, 4] - expected_data = fir_filter(src_data, taps, decim) - expected_data = [int(e) for e in expected_data] - - src = blocks.vector_source_f(src_data) - op = filter.fir_filter_fsf(decim, taps) - dst = blocks.vector_sink_s() - self.tb.connect((src, op, dst)) - self.tb.run() - result_data = dst.data() - self.assertComplexTuplesAlmostEqual(expected_data, result_data, 5) - - def test_fir_filter_fsf_002(self): - decim = 4 - taps = 20 * [0.5, 0.5] - src_data = 40 * [1, 2, 3, 4] - expected_data = fir_filter(src_data, taps, decim) - expected_data = [int(e) for e in expected_data] - - src = blocks.vector_source_f(src_data) - op = filter.fir_filter_fsf(decim, taps) - dst = blocks.vector_sink_s() - self.tb.connect((src, op, dst)) - self.tb.run() - result_data = dst.data() - self.assertComplexTuplesAlmostEqual(expected_data, result_data, 5) - - -if __name__ == '__main__': - gr_unittest.run(test_filter) diff --git a/blocklib/filter/test/qa_iir_filter.py b/blocklib/filter/test/qa_iir_filter.py deleted file mode 100644 index 305f7cbd5..000000000 --- a/blocklib/filter/test/qa_iir_filter.py +++ /dev/null @@ -1,403 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright 2004,2007,2010,2013 Free Software Foundation, Inc. -# -# This file is part of GNU Radio -# -# SPDX-License-Identifier: GPL-3.0-or-later -# -# - - -from gnuradio import gr, gr_unittest, filter, blocks - - -class test_iir_filter(gr_unittest.TestCase): - - def setUp(self): - self.tb = gr.top_block() - - def tearDown(self): - self.tb = None - - def test_iir_direct_001(self): - src_data = (1, 2, 3, 4, 5, 6, 7, 8) - fftaps = () - fbtaps = () - expected_result = (0, 0, 0, 0, 0, 0, 0, 0) - src = blocks.vector_source_f(src_data) - op = filter.iir_filter_ffd(fftaps, fbtaps) - dst = blocks.vector_sink_f() - self.tb.connect(src, op) - self.tb.connect(op, dst) - self.tb.run() - result_data = dst.data() - self.assertFloatTuplesAlmostEqual(expected_result, result_data) - - def test_iir_direct_002(self): - src_data = (1, 2, 3, 4, 5, 6, 7, 8) - fftaps = (2,) - fbtaps = (0,) - expected_result = (2, 4, 6, 8, 10, 12, 14, 16) - src = blocks.vector_source_f(src_data) - op = filter.iir_filter_ffd(fftaps, fbtaps) - dst = blocks.vector_sink_f() - self.tb.connect(src, op) - self.tb.connect(op, dst) - self.tb.run() - result_data = dst.data() - self.assertFloatTuplesAlmostEqual(expected_result, result_data) - - def test_iir_direct_003(self): - src_data = (1, 2, 3, 4, 5, 6, 7, 8) - fftaps = (2, 11) - fbtaps = (0, 0) - expected_result = (2, 15, 28, 41, 54, 67, 80, 93) - src = blocks.vector_source_f(src_data) - op = filter.iir_filter_ffd(fftaps, fbtaps) - dst = blocks.vector_sink_f() - self.tb.connect(src, op) - self.tb.connect(op, dst) - self.tb.run() - result_data = dst.data() - self.assertFloatTuplesAlmostEqual(expected_result, result_data) - - def test_iir_direct_004(self): - src_data = (1, 2, 3, 4, 5, 6, 7, 8) - fftaps = (2, 11) - fbtaps = (0, -1) - expected_result = (2, 13, 15, 26, 28, 39, 41, 52) - src = blocks.vector_source_f(src_data) - op = filter.iir_filter_ffd(fftaps, fbtaps) - dst = blocks.vector_sink_f() - self.tb.connect(src, op) - self.tb.connect(op, dst) - self.tb.run() - result_data = dst.data() - self.assertFloatTuplesAlmostEqual(expected_result, result_data) - - def test_iir_direct_005(self): - src_data = (1, 2, 3, 4, 5, 6, 7, 8) - fftaps = (2, 11, 0) - fbtaps = (0, -1, 3) - expected_result = (2, 13, 21, 59, 58, 186, 68, 583) - src = blocks.vector_source_f(src_data) - op = filter.iir_filter_ffd(fftaps, fbtaps) - dst = blocks.vector_sink_f() - self.tb.connect(src, op) - self.tb.connect(op, dst) - self.tb.run() - result_data = dst.data() - self.assertFloatTuplesAlmostEqual(expected_result, result_data) - - def test_iir_direct_006(self): - src_data = (1, 2, 3, 4, 5, 6, 7, 8) - expected_result = (2, 13, 21, 59, 58, 186, 68, 583) - fftaps = (2, 1) - fbtaps = (0, -1) - src = blocks.vector_source_f(src_data) - op = filter.iir_filter_ffd(fftaps, fbtaps) - fftaps = (2, 11, 0) - fbtaps = (0, -1, 3) - # FIXME: implement set_taps as generalized callback - # op.set_taps(fftaps, fbtaps) - op.set_fftaps(fftaps) - op.set_fbtaps(fbtaps) - dst = blocks.vector_sink_f() - self.tb.connect(src, op) - self.tb.connect(op, dst) - self.tb.run() - result_data = dst.data() - self.assertFloatTuplesAlmostEqual(expected_result, result_data) - - def test_iir_direct_007(self): - src_data = (1, 2, 3, 4, 5, 6, 7, 8) - expected_result = (2, 2, 5, 5, 8, 8, 11, 11) - fftaps = (2, 1) - fbtaps = (0, -1) - src = blocks.vector_source_f(src_data) - op = filter.iir_filter_ffd(fftaps, fbtaps) - fftaps = (2, 0, 1) - fbtaps = (0, -1) - # FIXME: implement set_taps as generalized callback - # op.set_taps(fftaps, fbtaps) - op.set_fftaps(fftaps) - op.set_fbtaps(fbtaps) - dst = blocks.vector_sink_f() - self.tb.connect(src, op) - self.tb.connect(op, dst) - self.tb.run() - result_data = dst.data() - self.assertFloatTuplesAlmostEqual(expected_result, result_data) - - def test_iir_direct_008(self): - src_data = (1, 2, 3, 4, 5, 6, 7, 8) - expected_result = (2, 4, 4, 10, 18, 14, 26, 56) - fftaps = (2,) - fbtaps = (0, 1) - src = blocks.vector_source_f(src_data) - op = filter.iir_filter_ffd(fftaps, fbtaps) - fftaps_data = (1) - fbtaps = (0, 0, -1, 3) - # FIXME: implement set_taps as generalized callback - # op.set_taps(fftaps, fbtaps) - op.set_fftaps(fftaps) - op.set_fbtaps(fbtaps) - dst = blocks.vector_sink_f() - self.tb.connect(src, op) - self.tb.connect(op, dst) - self.tb.run() - result_data = dst.data() - self.assertFloatTuplesAlmostEqual(expected_result, result_data) - - def test_iir_ccf_001(self): - src_data = ( - 1 + 1j, - 2 + 2j, - 3 + 3j, - 4 + 4j, - 5 + 5j, - 6 + 6j, - 7 + 7j, - 8 + 8j) - expected_result = ( - 2 + 2j, - (6 + 6j), - (12 + 12j), - (20 + 20j), - (30 + 30j), - (42 + 42j), - (56 + 56j), - (72 + 72j)) - fftaps = (2,) - fbtaps = (0, 1) - src = blocks.vector_source_c(src_data) - op = filter.iir_filter_ccf(fftaps, fbtaps) - dst = blocks.vector_sink_c() - - self.tb.connect(src, op) - self.tb.connect(op, dst) - self.tb.run() - - result_data = dst.data() - self.assertFloatTuplesAlmostEqual(expected_result, result_data) - - def test_iir_ccf_002(self): - src_data = ( - 1 + 1j, - 2 + 2j, - 3 + 3j, - 4 + 4j, - 5 + 5j, - 6 + 6j, - 7 + 7j, - 8 + 8j) - expected_result = ( - 2 + 2j, - (6 + 6j), - (12 + 12j), - (20 + 20j), - (30 + 30j), - (42 + 42j), - (56 + 56j), - (72 + 72j)) - - src = blocks.vector_source_c(src_data) - op = filter.iir_filter_ccf([1], [1]) - dst = blocks.vector_sink_c() - - fftaps = (2,) - fbtaps = (0, 1) - # FIXME: implement set_taps as generalized callback - # op.set_taps(fftaps, fbtaps) - op.set_fftaps(fftaps) - op.set_fbtaps(fbtaps) - - self.tb.connect(src, op) - self.tb.connect(op, dst) - self.tb.run() - - result_data = dst.data() - self.assertFloatTuplesAlmostEqual(expected_result, result_data) - - def test_iir_ccd_001(self): - src_data = ( - 1 + 1j, - 2 + 2j, - 3 + 3j, - 4 + 4j, - 5 + 5j, - 6 + 6j, - 7 + 7j, - 8 + 8j) - expected_result = ( - 2 + 2j, - (6 + 6j), - (12 + 12j), - (20 + 20j), - (30 + 30j), - (42 + 42j), - (56 + 56j), - (72 + 72j)) - fftaps = (2,) - fbtaps = (0, 1) - src = blocks.vector_source_c(src_data) - op = filter.iir_filter_ccd(fftaps, fbtaps) - dst = blocks.vector_sink_c() - - self.tb.connect(src, op) - self.tb.connect(op, dst) - self.tb.run() - - result_data = dst.data() - self.assertFloatTuplesAlmostEqual(expected_result, result_data) - - def test_iir_ccd_002(self): - src_data = ( - 1 + 1j, - 2 + 2j, - 3 + 3j, - 4 + 4j, - 5 + 5j, - 6 + 6j, - 7 + 7j, - 8 + 8j) - expected_result = ( - 2 + 2j, - (6 + 6j), - (12 + 12j), - (20 + 20j), - (30 + 30j), - (42 + 42j), - (56 + 56j), - (72 + 72j)) - - src = blocks.vector_source_c(src_data) - op = filter.iir_filter_ccd([1], [1]) - dst = blocks.vector_sink_c() - - fftaps = (2,) - fbtaps = (0, 1) - # FIXME: implement set_taps as generalized callback - # op.set_taps(fftaps, fbtaps) - op.set_fftaps(fftaps) - op.set_fbtaps(fbtaps) - - self.tb.connect(src, op) - self.tb.connect(op, dst) - self.tb.run() - - result_data = dst.data() - self.assertFloatTuplesAlmostEqual(expected_result, result_data) - - def test_iir_ccc_001(self): - src_data = ( - 1 + 1j, - 2 + 2j, - 3 + 3j, - 4 + 4j, - 5 + 5j, - 6 + 6j, - 7 + 7j, - 8 + 8j) - expected_result = (4j, 12j, 24j, 40j, 60j, 84j, 112j, 144j) - fftaps = (2 + 2j,) - fbtaps = (0, 1) - src = blocks.vector_source_c(src_data) - op = filter.iir_filter_ccc(fftaps, fbtaps) - dst = blocks.vector_sink_c() - - self.tb.connect(src, op) - self.tb.connect(op, dst) - self.tb.run() - - result_data = dst.data() - self.assertFloatTuplesAlmostEqual(expected_result, result_data) - - def test_iir_ccc_002(self): - src_data = ( - 1 + 1j, - 2 + 2j, - 3 + 3j, - 4 + 4j, - 5 + 5j, - 6 + 6j, - 7 + 7j, - 8 + 8j) - expected_result = (4j, 12j, 24j, 40j, 60j, 84j, 112j, 144j) - - src = blocks.vector_source_c(src_data) - op = filter.iir_filter_ccc([1], [1]) - dst = blocks.vector_sink_c() - - fftaps = (2 + 2j,) - fbtaps = (0, 1) - # FIXME: implement set_taps as generalized callback - # op.set_taps(fftaps, fbtaps) - op.set_fftaps(fftaps) - op.set_fbtaps(fbtaps) - - self.tb.connect(src, op) - self.tb.connect(op, dst) - self.tb.run() - - result_data = dst.data() - self.assertFloatTuplesAlmostEqual(expected_result, result_data) - - def test_iir_ccz_001(self): - src_data = ( - 1 + 1j, - 2 + 2j, - 3 + 3j, - 4 + 4j, - 5 + 5j, - 6 + 6j, - 7 + 7j, - 8 + 8j) - expected_result = (4j, 12j, 24j, 40j, 60j, 84j, 112j, 144j) - fftaps = (2 + 2j,) - fbtaps = (0, 1) - src = blocks.vector_source_c(src_data) - op = filter.iir_filter_ccz(fftaps, fbtaps) - dst = blocks.vector_sink_c() - - self.tb.connect(src, op) - self.tb.connect(op, dst) - self.tb.run() - - result_data = dst.data() - self.assertFloatTuplesAlmostEqual(expected_result, result_data) - - def test_iir_ccz_002(self): - src_data = ( - 1 + 1j, - 2 + 2j, - 3 + 3j, - 4 + 4j, - 5 + 5j, - 6 + 6j, - 7 + 7j, - 8 + 8j) - expected_result = (4j, 12j, 24j, 40j, 60j, 84j, 112j, 144j) - - src = blocks.vector_source_c(src_data) - op = filter.iir_filter_ccz([1], [1]) - dst = blocks.vector_sink_c() - - fftaps = (2 + 2j,) - fbtaps = (0, 1) - # FIXME: implement set_taps as generalized callback - # op.set_taps(fftaps, fbtaps) - op.set_fftaps(fftaps) - op.set_fbtaps(fbtaps) - - self.tb.connect(src, op) - self.tb.connect(op, dst) - self.tb.run() - - result_data = dst.data() - self.assertFloatTuplesAlmostEqual(expected_result, result_data) - - -if __name__ == '__main__': - gr_unittest.run(test_iir_filter) diff --git a/blocklib/filter/test/qa_moving_average.py b/blocklib/filter/test/qa_moving_average.py deleted file mode 100644 index 47fac453a..000000000 --- a/blocklib/filter/test/qa_moving_average.py +++ /dev/null @@ -1,232 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright 2013,2017 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, blocks, filter -import numpy as np - -import math, random - -def make_random_complex_tuple(L, scale=1): - result = [] - for x in range(L): - result.append(scale*complex(2*random.random()-1, - 2*random.random()-1)) - return tuple(result) - -def make_random_float_tuple(L, scale=1): - result = [] - for x in range(L): - result.append(scale*(2*random.random()-1)) - return tuple(result) - -class test_moving_average(gr_unittest.TestCase): - - def setUp(self): - random.seed(0) - self.tb = gr.flowgraph() - - def tearDown(self): - self.tb = None - - # These tests will always pass and are therefore useless. 100 random numbers [-1,1) are - # getting summed up and scaled with 0.001. Then, an assertion verifies a result near 0, - # which is the case even if the block is malfunctioning. - - def test_01(self): - tb = self.tb - - N = 10000 - data = make_random_float_tuple(N, 1) - expected_result = N*[0,] - - src = blocks.vector_source_f(data, False) - op = filter.moving_average_ff(100, 0.001) - dst = blocks.vector_sink_f() - - tb.connect(src, op) - tb.connect(op, dst) - tb.run() - - dst_data = dst.data() - - # make sure result is close to zero - self.assertFloatTuplesAlmostEqual(expected_result, dst_data, 1) - - def test_02(self): - tb = self.tb - - N = 10000 - data = make_random_complex_tuple(N, 1) - expected_result = N*[0,] - - src = blocks.vector_source_c(data, False) - op = filter.moving_average_cc(100, 0.001) - dst = blocks.vector_sink_c() - - tb.connect(src, op) - tb.connect(op, dst) - tb.run() - - dst_data = dst.data() - - # make sure result is close to zero - self.assertComplexTuplesAlmostEqual(expected_result, dst_data, 1) - - def test_moving_sum(self): - tb = self.tb - - N = 10000 - filt_len = 14 - data = [1.0] * N - expected_result = N*[filt_len,] - expected_result[0:filt_len-1] = list(range(1, filt_len)) - - src = blocks.vector_source_f(data, False) - op = filter.moving_average_ff(filt_len, 1.0) - dst = blocks.vector_sink_f() - - tb.connect(src, op) - tb.connect(op, dst) - tb.run() - - dst_data = dst.data() - - self.assertFloatTuplesAlmostEqual(expected_result, dst_data, 4) - - def test_moving_sum2(self): - tb = self.tb - - - filt_len = 3 - data = list(range(1,11)) - expected_result = [] - for ii in range(10): - sum = 0.0 - for jj in range(filt_len): - if (ii - jj ) >= 0: - sum += data[ii-jj] - expected_result.append(sum) - - src = blocks.vector_source_f(data, False) - op = filter.moving_average_ff(filt_len, 1.0, 4) - dst = blocks.vector_sink_f() - - tb.connect(src, op) - tb.connect(op, dst) - tb.run() - - dst_data = dst.data() - - self.assertFloatTuplesAlmostEqual(expected_result, dst_data, 4) - - def test_moving_avg3(self): - tb = self.tb - - N = 100000 - filt_len = 64 - data = list(make_random_float_tuple(N, scale=1)) - expected_result = [] - for ii in range(N): - sum = 0.0 - for jj in range(filt_len): - if (ii - jj ) >= 0: - sum += data[ii-jj] - expected_result.append(float(sum / N)) - - src = blocks.vector_source_f(data, False) - op = filter.moving_average_ff(filt_len, 1.0 / N, 4000) - dst = blocks.vector_sink_f() - - tb.connect(src, op) - tb.connect(op, dst) - tb.run() - - dst_data = dst.data() - - self.assertFloatTuplesAlmostEqual(expected_result, dst_data, 7) - - # This tests implement own moving average to verify correct behaviour of the block - - # def test_03(self): - # tb = self.tb - - # vlen = 5 - # N = 10*vlen - # data = make_random_float_tuple(N, 2**10) - # data = [int(d*1000) for d in data] - # src = blocks.vector_source_i(data, False) - # one_to_many = blocks.stream_to_streams(gr.sizeof_int, vlen) - # one_to_vector = blocks.stream_to_vector(gr.sizeof_int, vlen) - # many_to_vector = blocks.streams_to_vector(gr.sizeof_int, vlen) - # isolated = [ filter.moving_average_ii(100, 1) for i in range(vlen)] - # dut = filter.moving_average_ii(100, 1, vlen=vlen) - # dut_dst = blocks.vector_sink_i(vlen=vlen) - # ref_dst = blocks.vector_sink_i(vlen=vlen) - - # tb.connect(src, one_to_many) - # tb.connect(src, one_to_vector) #, dut, dut_dst) - # tb.connect(one_to_vector, dut) - # tb.connect(dut, dut_dst) - # tb.connect(many_to_vector, ref_dst) - # for idx, single in enumerate(isolated): - # tb.connect((one_to_many,idx), single, (many_to_vector,idx)) - - # tb.run() - - # dut_data = dut_dst.data() - # ref_data = ref_dst.data() - - # # make sure result is close to zero - # self.assertTupleEqual(dut_data, ref_data) - - # def test_04(self): - # tb = self.tb - - # N = 10000 # number of samples - # history = 100 # num of samples to average - # data = make_random_complex_tuple(N, 1) # generate random data - - # # pythonic MA filter - # data_padded = (history-1)*[0.0+1j*0.0]+list(data) # history - # expected_result = [] - # moving_sum = sum(data_padded[:history-1]) - # for i in range(N): - # moving_sum += data_padded[i+history-1] - # expected_result.append(moving_sum) - # moving_sum -= data_padded[i] - - # src = blocks.vector_source_c(data, False) - # op = filter.moving_average_cc(history, 1) - # dst = blocks.vector_sink_c() - - # tb.connect(src, op) - # tb.connect(op, dst) - # tb.run() - - # dst_data = dst.data() - - # # make sure result is close to zero - # self.assertComplexTuplesAlmostEqual(expected_result, dst_data, 4) - -if __name__ == '__main__': - gr_unittest.run(test_moving_average) diff --git a/blocklib/filter/test/qa_pfb_arb_resampler.py b/blocklib/filter/test/qa_pfb_arb_resampler.py deleted file mode 100644 index 993dea934..000000000 --- a/blocklib/filter/test/qa_pfb_arb_resampler.py +++ /dev/null @@ -1,305 +0,0 @@ -#!/usr/bin/env python -# -# Copyright 2012,2013 Free Software Foundation, Inc. -# -# This file is part of GNU Radio -# -# SPDX-License-Identifier: GPL-3.0-or-later -# -# - - -from gnuradio import gr, gr_unittest, fft, filter, blocks -from gnuradio.kernel.filter import firdes -from gnuradio.kernel.fft import window -import math - - -def sig_source_c(samp_rate, freq, amp, N): - t = [float(x) / samp_rate for x in range(N)] - y = [math.cos(2. * math.pi * freq * x) + - 1j * math.sin(2. * math.pi * freq * x) for x in t] - return y - - -def sig_source_f(samp_rate, freq, amp, N): - t = [float(x) / samp_rate for x in range(N)] - y = [math.sin(2. * math.pi * freq * x) for x in t] - return y - - -class test_pfb_arb_resampler(gr_unittest.TestCase): - - def setUp(self): - self.tb = gr.top_block() - - def tearDown(self): - self.tb = None - - def test_fff_000(self): - N = 500 # number of samples to use - fs = 5000.0 # baseband sampling rate - rrate = 2.3421 # resampling rate - - nfilts = 32 - taps = firdes.low_pass_2( - nfilts, - nfilts * fs, - fs / 2, - fs / 10, - attenuation_dB=80, - window=window.BLACKMAN_hARRIS) - - freq = 121.213 - data = sig_source_f(fs, freq, 1, N) - signal = blocks.vector_source_f(data) - pfb = filter.pfb_arb_resampler_fff(rrate, taps, nfilts) - snk = blocks.vector_sink_f() - - self.tb.connect((signal, pfb, snk)) - self.tb.run() - - Ntest = 50 - L = len(snk.data()) - - # Get group delay and estimate of phase offset from the filter itself. - delay = pfb.group_delay() - phase = pfb.phase_offset(freq, fs) - - # Create a timeline offset by the filter's group delay - t = [float(x) / (fs * rrate) for x in range(-delay, L - delay)] - - # Data of the sinusoid at frequency freq with the delay and phase - # offset. - expected_data = [math.sin(2. * math.pi * freq * x + phase) for x in t] - - dst_data = snk.data() - - self.assertFloatTuplesAlmostEqual( - expected_data[-Ntest:], dst_data[-Ntest:], 2) - - # def test_ccf_000(self): - # N = 5000 # number of samples to use - # fs = 5000.0 # baseband sampling rate - # rrate = 2.4321 # resampling rate - - # nfilts = 32 - # taps = firdes.low_pass_2( - # nfilts, - # nfilts * fs, - # fs / 2, - # fs / 10, - # attenuation_dB=80, - # window=window.BLACKMAN_hARRIS) - - # freq = 211.123 - # data = sig_source_c(fs, freq, 1, N) - # signal = blocks.vector_source_c(data) - # pfb = filter.pfb_arb_resampler_ccf(rrate, taps, nfilts) - # snk = blocks.vector_sink_c() - - # self.tb.connect((signal, pfb, snk)) - # self.tb.run() - - # Ntest = 50 - # L = len(snk.data()) - - # # Get group delay and estimate of phase offset from the filter itself. - # delay = pfb.group_delay() - # phase = pfb.phase_offset(freq, fs) - - # # Create a timeline offset by the filter's group delay - # t = [float(x) / (fs * rrate) for x in range(-delay, L - delay)] - - # # Data of the sinusoid at frequency freq with the delay and phase - # # offset. - # expected_data = [ - # math.cos( - # 2. * - # math.pi * - # freq * - # x + - # phase) + - # 1j * - # math.sin( - # 2. * - # math.pi * - # freq * - # x + - # phase) for x in t] - - # dst_data = snk.data() - - # self.assertComplexTuplesAlmostEqual( - # expected_data[-Ntest:], dst_data[-Ntest:], 2) - - # def test_ccf_001(self): - # N = 50000 # number of samples to use - # fs = 5000.0 # baseband sampling rate - # rrate = 0.75 # resampling rate - - # nfilts = 32 - # taps = firdes.low_pass_2( - # nfilts, - # nfilts * fs, - # fs / 4, - # fs / 10, - # attenuation_dB=80, - # window=window.BLACKMAN_hARRIS) - - # freq = 211.123 - # data = sig_source_c(fs, freq, 1, N) - # signal = blocks.vector_source_c(data) - # pfb = filter.pfb_arb_resampler_ccf(rrate, taps, nfilts) - # snk = blocks.vector_sink_c() - - # self.tb.connect((signal, pfb, snk)) - # self.tb.run() - - # Ntest = 50 - # L = len(snk.data()) - - # # Get group delay and estimate of phase offset from the filter itself. - # delay = pfb.group_delay() - # phase = pfb.phase_offset(freq, fs) - - # # Create a timeline offset by the filter's group delay - # t = [float(x) / (fs * rrate) for x in range(-delay, L - delay)] - - # # Data of the sinusoid at frequency freq with the delay and phase - # # offset. - # expected_data = [ - # math.cos( - # 2. * - # math.pi * - # freq * - # x + - # phase) + - # 1j * - # math.sin( - # 2. * - # math.pi * - # freq * - # x + - # phase) for x in t] - - # dst_data = snk.data() - - # self.assertComplexTuplesAlmostEqual( - # expected_data[-Ntest:], dst_data[-Ntest:], 2) - - # def test_ccc_000(self): - # N = 5000 # number of samples to use - # fs = 5000.0 # baseband sampling rate - # rrate = 3.4321 # resampling rate - - # nfilts = 32 - # taps = firdes.complex_band_pass_2( - # nfilts, - # nfilts * fs, - # 50, - # 400, - # fs / 10, - # attenuation_dB=80, - # window=window.BLACKMAN_hARRIS) - - # freq = 211.123 - # data = sig_source_c(fs, freq, 1, N) - # signal = blocks.vector_source_c(data) - # pfb = filter.pfb_arb_resampler_ccc(rrate, taps, nfilts) - # snk = blocks.vector_sink_c() - - # self.tb.connect((signal, pfb, snk)) - # self.tb.run() - - # Ntest = 50 - # L = len(snk.data()) - - # # Get group delay and estimate of phase offset from the filter itself. - # delay = pfb.group_delay() - # phase = pfb.phase_offset(freq, fs) - - # # Create a timeline offset by the filter's group delay - # t = [float(x) / (fs * rrate) for x in range(-delay, L - delay)] - - # # Data of the sinusoid at frequency freq with the delay and phase - # # offset. - # expected_data = [ - # math.cos( - # 2. * - # math.pi * - # freq * - # x + - # phase) + - # 1j * - # math.sin( - # 2. * - # math.pi * - # freq * - # x + - # phase) for x in t] - - # dst_data = snk.data() - - # self.assertComplexTuplesAlmostEqual( - # expected_data[-Ntest:], dst_data[-Ntest:], 2) - - # def test_ccc_001(self): - # N = 50000 # number of samples to use - # fs = 5000.0 # baseband sampling rate - # rrate = 0.715 # resampling rate - - # nfilts = 32 - # taps = firdes.complex_band_pass_2( - # nfilts, - # nfilts * fs, - # 50, - # 400, - # fs / 10, - # attenuation_dB=80, - # window=window.BLACKMAN_hARRIS) - - # freq = 211.123 - # data = sig_source_c(fs, freq, 1, N) - # signal = blocks.vector_source_c(data) - # pfb = filter.pfb_arb_resampler_ccc(rrate, taps, nfilts) - # snk = blocks.vector_sink_c() - - # self.tb.connect((signal, pfb, snk)) - # self.tb.run() - - # Ntest = 50 - # L = len(snk.data()) - - # # Get group delay and estimate of phase offset from the filter itself. - # delay = pfb.group_delay() - # phase = pfb.phase_offset(freq, fs) - - # # Create a timeline offset by the filter's group delay - # t = [float(x) / (fs * rrate) for x in range(-delay, L - delay)] - - # # Data of the sinusoid at frequency freq with the delay and phase - # # offset. - # expected_data = [ - # math.cos( - # 2. * - # math.pi * - # freq * - # x + - # phase) + - # 1j * - # math.sin( - # 2. * - # math.pi * - # freq * - # x + - # phase) for x in t] - - # dst_data = snk.data() - - # self.assertComplexTuplesAlmostEqual( - # expected_data[-Ntest:], dst_data[-Ntest:], 2) - - -if __name__ == '__main__': - gr_unittest.run(test_pfb_arb_resampler) diff --git a/blocklib/filter/test/qa_pfb_channelizer.py b/blocklib/filter/test/qa_pfb_channelizer.py deleted file mode 100644 index b0d98c1b3..000000000 --- a/blocklib/filter/test/qa_pfb_channelizer.py +++ /dev/null @@ -1,149 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright 2012-2014 Free Software Foundation, Inc. -# -# This file is part of GNU Radio -# -# SPDX-License-Identifier: GPL-3.0-or-later -# -# - - -from gnuradio import gr, gr_unittest, fft, filter, blocks, streamops, math as grmath -from gnuradio.kernel.filter import firdes -from gnuradio.kernel.fft import window -import math -import cmath - - -def sig_source_c(samp_rate, freq, amp, N): - t = [float(x) / samp_rate for x in range(N)] - y = [math.cos(2. * math.pi * freq * x) + - 1j * math.sin(2. * math.pi * freq * x) for x in t] - return y - - -class test_pfb_channelizer(gr_unittest.TestCase): - - def setUp(self): - self.tb = gr.flowgraph() - self.freqs = [110., -513., 203., -230, 121] - # Number of channels to channelize. - self.M = len(self.freqs) - # Number of samples to use. - self.N = 1000 - # Baseband sampling rate. - self.fs = 5000 - # Input samp rate to channelizer. - self.ifs = self.M * self.fs - - self.taps = firdes.low_pass_2( - 1, self.ifs, self.fs / 2, self.fs / 10, - attenuation_dB=80, - window=window.BLACKMAN_hARRIS) - - self.Ntest = 50 - - def tearDown(self): - self.tb = None - - def test_0000(self): - self.check_channelizer(filter.pfb_channelizer_cc( - self.M, taps=self.taps, oversample_rate=1)) - - - # def test_0001(self): - # self.check_channelizer(filter.pfb.channelizer_hier_ccf( - # self.M, n_filterbanks=1, taps=self.taps)) - - # def test_0002(self): - # """Test roundig error handling for oversample rate (ok).""" - # channels, oversample = 36, 25. - # filter.pfb.channelizer_ccf(channels, taps=self.taps, - # oversample_rate=channels / oversample) - - def test_0003(self): - """Test roundig error handling for oversample rate, (bad).""" - # pybind11 raises ValueError instead of TypeError - self.assertRaises(ValueError, - filter.pfb_channelizer_cc, - 36, taps=self.taps, oversample_rate=10.1334) - - - def check_channelizer(self, channelizer_block): - signals = list() - add = grmath.add_cc(len(self.freqs)) - for i in range(len(self.freqs)): - f = self.freqs[i] + i * self.fs - data = sig_source_c(self.ifs, f, 1, self.N) - signals.append(blocks.vector_source_c(data)) - self.tb.connect(signals[i],0 , add, i) - - s2ss = streamops.deinterleave(self.M) - - # self.tb.connect(add, 0, s2ss, 0) - self.tb.connect(add, channelizer_block) - - snks = list() - for i in range(self.M): - snks.append(blocks.vector_sink_c()) - # self.tb.connect(s2ss,i, channelizer_block,i) - self.tb.connect(channelizer_block, i, snks[i],0) - - self.tb.run() - - L = len(snks[0].data()) - - expected_data = self.get_expected_data(L) - received_data = [snk.data() for snk in snks] - - for expected, received in zip(expected_data, received_data): - self.compare_data(expected, received) - - def compare_data(self, expected, received): - Ntest = 50 - expected = expected[-Ntest:] - received = received[-Ntest:] - expected = [x / expected[0] for x in expected] - received = [x / received[0] for x in received] - self.assertComplexTuplesAlmostEqual(expected, received, 3) - - def get_freq(self, data): - freqs = [] - for r1, r2 in zip(data[:-1], data[1:]): - diff = cmath.phase(r1) - cmath.phase(r2) - if diff > math.pi: - diff -= 2 * math.pi - if diff < -math.pi: - diff += 2 * math.pi - freqs.append(diff) - freq = float(sum(freqs)) / len(freqs) - freq /= 2 * math.pi - return freq - - def get_expected_data(self, L): - - # Filter delay is the normal delay of each arm - tpf = math.ceil(len(self.taps) / float(self.M)) - delay = -(tpf - 1.0) / 2.0 - delay = int(delay) - - # Create a time scale that's delayed to match the filter delay - t = [float(x) / self.fs for x in range(delay, L + delay)] - - # Create known data as complex sinusoids at the different baseband freqs - # the different channel numbering is due to channelizer output order. - expected_data = [[math.cos(2. * - math.pi * - f * - x) + - 1j * - math.sin(2. * - math.pi * - f * - x) for x in t] for f in self.freqs] - return expected_data - - -if __name__ == '__main__': - gr_unittest.run(test_pfb_channelizer) |