diff options
Diffstat (limited to 'blocklib')
302 files changed, 34 insertions, 22110 deletions
diff --git a/blocklib/analog/.gitignore b/blocklib/analog/.gitignore deleted file mode 100644 index 25d053a52..000000000 --- a/blocklib/analog/.gitignore +++ /dev/null @@ -1 +0,0 @@ -meson.build
\ No newline at end of file diff --git a/blocklib/analog/agc/agc.yml b/blocklib/analog/agc/agc.yml deleted file mode 100644 index fb40998ea..000000000 --- a/blocklib/analog/agc/agc.yml +++ /dev/null @@ -1,43 +0,0 @@ -module: analog -block: agc -label: AGC -blocktype: sync_block -category: '[Core]/Level Controllers' - -typekeys: - - id: T - type: class - options: - - cf32 - - rf32 - -# float rate = 1e-4, float reference = 1.0, float gain = 1.0) -parameters: -- id: rate - label: Rate - dtype: rf32 - default: 1e-4 -- id: reference - label: Reference - dtype: rf32 - default: 1.0 -- id: gain - label: Gain - dtype: rf32 - default: 1.0 - -ports: -- domain: stream - id: in - direction: input - type: typekeys/T - -- domain: stream - id: out - direction: output - type: typekeys/T - -implementations: -- id: cpu - -file_format: 1 diff --git a/blocklib/analog/agc/agc_cpu.cc b/blocklib/analog/agc/agc_cpu.cc deleted file mode 100644 index 4cbf20cab..000000000 --- a/blocklib/analog/agc/agc_cpu.cc +++ /dev/null @@ -1,27 +0,0 @@ -#include "agc_cpu.h" -#include "agc_cpu_gen.h" - -namespace gr { -namespace analog { - -template <class T> -agc_cpu<T>::agc_cpu(const typename agc<T>::block_args& args) - : INHERITED_CONSTRUCTORS(T), - kernel::analog::agc<T>(args.rate, args.reference, args.gain, 65536) -{ -} - -template <class T> -work_return_t agc_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; - kernel::analog::agc<T>::scaleN(out, in, noutput_items); - - wio.outputs()[0].n_produced = noutput_items; - return work_return_t::OK; -} - -} // namespace analog -} // namespace gr diff --git a/blocklib/analog/agc/agc_cpu.h b/blocklib/analog/agc/agc_cpu.h deleted file mode 100644 index 0ea29190d..000000000 --- a/blocklib/analog/agc/agc_cpu.h +++ /dev/null @@ -1,20 +0,0 @@ -#pragma once - -#include <gnuradio/analog/agc.h> -#include <gnuradio/kernel/analog/agc.h> - -namespace gr { -namespace analog { - -template <class T> -class agc_cpu : public agc<T>, kernel::analog::agc<T> -{ -public: - agc_cpu(const typename agc<T>::block_args& args); - work_return_t work(work_io&) override; - -protected: -}; - -} // namespace analog -} // namespace gr diff --git a/blocklib/analog/enums.yml b/blocklib/analog/enums.yml deleted file mode 100644 index 64bd5b2d0..000000000 --- a/blocklib/analog/enums.yml +++ /dev/null @@ -1,24 +0,0 @@ -waveform_t: - # type: uint32_t # Only specify if necessary - enumerators: - - id: constant - value: 100 # unnecessary - label: Constant - - id: sin - label: Sine - - id: cos - label: Cosine - - id: square - label: Square - - id: triangle - label: Triangle - - id: sawtooth - label: Saw Tooth - -noise_t: - enumerators: - - id: uniform - value: 200 # unnecessary - - id: gaussian - - id: laplacian - - id: impulse diff --git a/blocklib/analog/examples/fm_rx.grc b/blocklib/analog/examples/fm_rx.grc deleted file mode 100644 index c9920cda0..000000000 --- a/blocklib/analog/examples/fm_rx.grc +++ /dev/null @@ -1,207 +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: fm_rx - 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: fm_deviation_hz - id: variable - parameters: - comment: '' - value: 75e3 - states: - bus_sink: false - bus_source: false - bus_structure: null - coordinate: [400, 20.0] - rotation: 0 - state: true -- name: freq - id: variable - parameters: - comment: '' - value: '90500000' - states: - bus_sink: false - bus_source: false - bus_structure: null - coordinate: [288, 20.0] - rotation: 0 - state: enabled -- name: in_rate - id: variable - parameters: - comment: '' - value: samp_rate - states: - bus_sink: false - bus_source: false - bus_structure: null - coordinate: [192, 84.0] - rotation: 0 - state: enabled -- name: samp_rate - id: variable - parameters: - comment: '' - value: '4000000' - states: - bus_sink: false - bus_source: false - bus_structure: null - coordinate: [184, 12] - rotation: 0 - state: enabled -- name: analog_fm_deemph_0 - id: analog_fm_deemph - parameters: - affinity: '' - alias: '' - comment: '' - fs: '400000' - impl: cpu - maxoutbuf: '0' - minoutbuf: '0' - showports: 'False' - tau: 75e-6 - states: - bus_sink: false - bus_source: false - bus_structure: null - coordinate: [688, 220.0] - rotation: 0 - state: true -- name: analog_quadrature_demod_0 - id: analog_quadrature_demod - parameters: - affinity: '' - alias: '' - comment: '' - gain: in_rate/(2*math.pi*fm_deviation_hz) - impl: cpu - maxoutbuf: '0' - minoutbuf: '0' - showports: 'False' - states: - bus_sink: false - bus_source: false - bus_structure: null - coordinate: [368, 276.0] - rotation: 0 - state: true -- name: blocks_null_source_0 - id: blocks_null_source - parameters: - affinity: '' - alias: '' - comment: '' - impl: cpu - itemsize: '0' - maxoutbuf: '0' - minoutbuf: '0' - nports: '1' - showports: 'False' - states: - bus_sink: false - bus_source: false - bus_structure: null - coordinate: [96, 460.0] - rotation: 0 - state: true -- name: import_0 - id: import - parameters: - alias: '' - comment: '' - imports: import math - states: - bus_sink: false - bus_source: false - bus_structure: null - coordinate: [528, 28.0] - rotation: 0 - state: true -- name: qtgui_time_sink_0 - id: qtgui_time_sink - parameters: - T: float - affinity: '' - alias: '' - comment: '' - gui_hint: '' - impl: cpu - name: '"hello"' - nconnections: '1' - samp_rate: samp_rate - showports: 'False' - size: '10240' - states: - bus_sink: false - bus_source: false - bus_structure: null - coordinate: [1016, 188.0] - rotation: 0 - state: true -- name: soapy_hackrf_source_0 - id: soapy_hackrf_source - parameters: - T: complex - affinity: '' - alias: '' - amp: 'False' - bandwidth: '0' - center_freq: freq - comment: '' - dev_args: '' - device: '' - gain: '16' - impl: cpu - maxoutbuf: '0' - minoutbuf: '0' - samp_rate: samp_rate - showports: 'False' - vga: '16' - states: - bus_sink: false - bus_source: false - bus_structure: null - coordinate: [112, 284.0] - rotation: 0 - state: disabled - -connections: -- [analog_fm_deemph_0, '0', qtgui_time_sink_0, '0'] -- [analog_quadrature_demod_0, '0', analog_fm_deemph_0, '0'] -- [blocks_null_source_0, '0', analog_quadrature_demod_0, '0'] -- [soapy_hackrf_source_0, '0', analog_quadrature_demod_0, '0'] - -metadata: - file_format: 1 diff --git a/blocklib/analog/examples/fm_rx.py b/blocklib/analog/examples/fm_rx.py deleted file mode 100755 index 630a3a183..000000000 --- a/blocklib/analog/examples/fm_rx.py +++ /dev/null @@ -1,185 +0,0 @@ -#!/usr/bin/env python3 -# -*- coding: utf-8 -*- - -# -# SPDX-License-Identifier: GPL-3.0 -# -# GNU Radio Python Flow Graph -# Title: Not titled yet -# Author: josh -# GNU Radio version: 0.2.0 - -from packaging.version import Version as StrictVersion - -if __name__ == '__main__': - import ctypes - import sys - if sys.platform.startswith('linux'): - try: - x11 = ctypes.cdll.LoadLibrary('libX11.so') - x11.XInitThreads() - except: - print("Warning: failed to XInitThreads()") - -from PyQt5 import Qt -from gnuradio import qtgui -from gnuradio.kernel.filter import firdes -import sip -from gnuradio import analog -from gnuradio import blocks -from gnuradio import gr -#from gnuradio.filter import firdes -#from gnuradio.fft import window -import sys -import signal -from argparse import ArgumentParser -#from gnuradio.eng_arg import eng_float, intx -#from gnuradio import eng_notation -import math - - - -from gnuradio import qtgui - -class fm_rx(Qt.QWidget): - def start(self): - self.fg.start() - - def stop(self): - self.fg.stop() - - def wait(self): - self.fg.wait() - - def connect(self,*args): - return self.fg.connect(*args) - - def msg_connect(self,*args): - return self.fg.connect(*args) - - def __init__(self): - self.fg = gr.flowgraph("Not titled yet") - Qt.QWidget.__init__(self) - self.setWindowTitle("Not titled yet") - try: - self.setWindowIcon(Qt.QIcon.fromTheme('gnuradio-grc')) - except: - pass - self.top_scroll_layout = Qt.QVBoxLayout() - self.setLayout(self.top_scroll_layout) - self.top_scroll = Qt.QScrollArea() - self.top_scroll.setFrameStyle(Qt.QFrame.NoFrame) - self.top_scroll_layout.addWidget(self.top_scroll) - self.top_scroll.setWidgetResizable(True) - self.top_widget = Qt.QWidget() - self.top_scroll.setWidget(self.top_widget) - self.top_layout = Qt.QVBoxLayout(self.top_widget) - self.top_grid_layout = Qt.QGridLayout() - self.top_layout.addLayout(self.top_grid_layout) - - self.settings = Qt.QSettings("GNU Radio", "fm_rx") - - try: - if StrictVersion(Qt.qVersion()) < StrictVersion("5.0.0"): - self.restoreGeometry(self.settings.value("geometry").toByteArray()) - else: - self.restoreGeometry(self.settings.value("geometry")) - except: - pass - - ################################################## - # Variables - ################################################## - self.samp_rate = samp_rate = 4000000 - self.in_rate = in_rate = samp_rate - self.freq = freq = 90500000 - self.fm_deviation_hz = fm_deviation_hz = 75e3 - - ################################################## - # Blocks - ################################################## - self.qtgui_time_sink_0 = qtgui.time_sink_f(10240,samp_rate,"hello",1) - self._qtgui_time_sink_0_win = sip.wrapinstance(self.qtgui_time_sink_0.qwidget(), Qt.QWidget) - self.top_layout.addWidget(self._qtgui_time_sink_0_win) - self.blocks_null_source_0 = blocks.null_source( 1,0, impl=blocks.null_source.cpu) - self.analog_quadrature_demod_0 = analog.quadrature_demod( in_rate/(2*math.pi*fm_deviation_hz), impl=analog.quadrature_demod.cpu) - self.analog_fm_deemph_0 = analog.fm_deemph( 400000,75e-6, impl=analog.fm_deemph.cpu) - - - - ################################################## - # Connections - ################################################## - self.connect((self.analog_fm_deemph_0, 0), (self.qtgui_time_sink_0, 0)) - self.connect((self.analog_quadrature_demod_0, 0), (self.analog_fm_deemph_0, 0)) - self.connect((self.blocks_null_source_0, 0), (self.analog_quadrature_demod_0, 0)) - - - def closeEvent(self, event): - self.settings = Qt.QSettings("GNU Radio", "fm_rx") - self.settings.setValue("geometry", self.saveGeometry()) - self.stop() - self.wait() - - event.accept() - - def get_samp_rate(self): - return self.samp_rate - - def set_samp_rate(self, samp_rate): - self.samp_rate = samp_rate - self.set_in_rate(self.samp_rate) - - def get_in_rate(self): - return self.in_rate - - def set_in_rate(self, in_rate): - self.in_rate = in_rate - - def get_freq(self): - return self.freq - - def set_freq(self, freq): - self.freq = freq - - def get_fm_deviation_hz(self): - return self.fm_deviation_hz - - def set_fm_deviation_hz(self, fm_deviation_hz): - self.fm_deviation_hz = fm_deviation_hz - - - - -def main(flowgraph_cls=fm_rx, options=None): - - if StrictVersion("4.5.0") <= StrictVersion(Qt.qVersion()) < StrictVersion("5.0.0"): - style = gr.prefs().get_string('qtgui', 'style', 'raster') - Qt.QApplication.setGraphicsSystem(style) - qapp = Qt.QApplication(sys.argv) - - fg = flowgraph_cls() - rt = gr.runtime() - - rt.initialize(fg.fg) - rt.start() - - fg.show() - - def sig_handler(sig=None, frame=None): - rt.stop() - rt.wait() - - Qt.QApplication.quit() - - signal.signal(signal.SIGINT, sig_handler) - signal.signal(signal.SIGTERM, sig_handler) - - timer = Qt.QTimer() - timer.start(500) - timer.timeout.connect(lambda: None) - - qapp.exec_() - -if __name__ == '__main__': - main() diff --git a/blocklib/analog/fm_deemph/fm_deemph.yml b/blocklib/analog/fm_deemph/fm_deemph.yml deleted file mode 100644 index 598d91382..000000000 --- a/blocklib/analog/fm_deemph/fm_deemph.yml +++ /dev/null @@ -1,116 +0,0 @@ -module: analog -block: fm_deemph -label: FM Deemphasis IIR Filter -blocktype: hier_block -category: '[Core]/Modulators' - -# Example Parameters -parameters: -- id: fs - label: Sampling Rate - dtype: int - grc: - default: 400000 -- id: tau - label: Tau - dtype: rf64 - default: 75e-6 - - -# Example Ports -ports: -- domain: stream - id: in - direction: input - type: rf32 - -- domain: stream - id: out - direction: output - type: rf32 - -implementations: -- id: cpu -# - id: cuda - -file_format: 1 - -doc: - brief: FM Deemphasis IIR filter - detail: |- - - - Args: - fs: sampling frequency in Hz (float) - tau: Time constant in seconds (75us in US and South Korea, 50us everywhere else) (float) - - An analog deemphasis filter: - - R - o------/\/\/\/---+----o - | - = C - | - --- - - Has this transfer function: - - 1 1 - ---- --- - RC tau - H(s) = ---------- = ---------- - 1 1 - s + ---- s + --- - RC tau - - And has its -3 dB response, due to the pole, at - - |H(j w_c)|^2 = 1/2 => s = j w_c = j (1/(RC)) - - Historically, this corner frequency of analog audio deemphasis filters - been specified by the RC time constant used, called tau. - So w_c = 1/tau. - - FWIW, for standard tau values, some standard analog components would be: - tau = 75 us = (50K)(1.5 nF) = (50 ohms)(1.5 uF) - tau = 50 us = (50K)(1.0 nF) = (50 ohms)(1.0 uF) - - In specifying tau for this digital deemphasis filter, tau specifies - the *digital* corner frequency, w_c, desired. - - The digital deemphasis filter design below, uses the - "bilinear transformation" method of designing digital filters: - - 1. Convert digital specifications into the analog domain, by prewarping - digital frequency specifications into analog frequencies. - - w_a = (2/T)tan(wT/2) - - 2. Use an analog filter design technique to design the filter. - - 3. Use the bilinear transformation to convert the analog filter design to a - digital filter design. - - H(z) = H(s)| - s = (2/T)(1-z^-1)/(1+z^-1) - - - w_ca 1 1 - (-1) z^-1 - H(z) = ---- * ----------- * ----------------------- - 2 fs -w_ca -w_ca - 1 - ----- 1 + ----- - 2 fs 2 fs - 1 - ----------- z^-1 - -w_ca - 1 - ----- - 2 fs - - We use this design technique, because it is an easy way to obtain a filter - design with the -6 dB/octave roll-off required of the deemphasis filter. - - Jackson, Leland B., _Digital_Filters_and_Signal_Processing_Second_Edition_, - Kluwer Academic Publishers, 1989, pp 201-212 - - Orfanidis, Sophocles J., _Introduction_to_Signal_Processing_, Prentice Hall, - 1996, pp 573-583 - """
\ No newline at end of file diff --git a/blocklib/analog/fm_deemph/fm_deemph_cpu.cc b/blocklib/analog/fm_deemph/fm_deemph_cpu.cc deleted file mode 100644 index b7691333a..000000000 --- a/blocklib/analog/fm_deemph/fm_deemph_cpu.cc +++ /dev/null @@ -1,47 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2022 FIXME - * - * This file is part of GNU Radio - * - * SPDX-License-Identifier: GPL-3.0-or-later - * - */ - -#include "fm_deemph_cpu.h" -#include "fm_deemph_cpu_gen.h" - -#include <gnuradio/filter/iir_filter.h> - -namespace gr { -namespace analog { - -fm_deemph_cpu::fm_deemph_cpu(block_args args) : INHERITED_CONSTRUCTORS -{ - // Digital corner frequency - auto w_c = 1.0 / args.tau; - - // Prewarped analog corner frequency - auto w_ca = 2.0 * args.fs * tanf(w_c / (2.0 * args.fs)); - - // Resulting digital pole, zero, and gain term from the bilinear - // transformation of H(s) = w_ca / (s + w_ca) to - // H(z) = b0 (1 - z1 z^-1)/(1 - p1 z^-1) - auto k = -w_ca / (2.0 * args.fs); - auto z1 = -1.0; - auto p1 = (1.0 + k) / (1.0 - k); - auto b0 = -k / (1.0 - k); - - std::vector<double> btaps{ b0 * 1.0, b0 * -z1 }; - std::vector<double> ataps{ 1.0, -p1 }; - - // Since H(s = 0) = 1.0, then H(z = 1) = 1.0 and has 0 dB gain at DC - - deemph = filter::iir_filter_ffd::make({ btaps, ataps, false }); - hier_block::connect(self(), 0, deemph, 0); - hier_block::connect(deemph, 0, self(), 0); -} - - -} // namespace analog -} // namespace gr
\ No newline at end of file diff --git a/blocklib/analog/fm_deemph/fm_deemph_cpu.h b/blocklib/analog/fm_deemph/fm_deemph_cpu.h deleted file mode 100644 index c7a14c59a..000000000 --- a/blocklib/analog/fm_deemph/fm_deemph_cpu.h +++ /dev/null @@ -1,29 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2022 FIXME - * - * This file is part of GNU Radio - * - * SPDX-License-Identifier: GPL-3.0-or-later - * - */ - -#pragma once - -#include <gnuradio/analog/fm_deemph.h> -#include <gnuradio/filter/iir_filter.h> - -namespace gr { -namespace analog { - -class fm_deemph_cpu : public virtual fm_deemph -{ -public: - fm_deemph_cpu(block_args args); - -private: - filter::iir_filter_ffd::sptr deemph; -}; - -} // namespace analog -} // namespace gr
\ No newline at end of file diff --git a/blocklib/analog/include/gnuradio/analog/.gitignore b/blocklib/analog/include/gnuradio/analog/.gitignore deleted file mode 100644 index d53050d7d..000000000 --- a/blocklib/analog/include/gnuradio/analog/.gitignore +++ /dev/null @@ -1 +0,0 @@ -!meson.build diff --git a/blocklib/analog/include/gnuradio/analog/meson.build b/blocklib/analog/include/gnuradio/analog/meson.build deleted file mode 100644 index e69de29bb..000000000 --- a/blocklib/analog/include/gnuradio/analog/meson.build +++ /dev/null diff --git a/blocklib/analog/lib/.gitignore b/blocklib/analog/lib/.gitignore deleted file mode 100644 index 01ecb66ff..000000000 --- a/blocklib/analog/lib/.gitignore +++ /dev/null @@ -1 +0,0 @@ -!meson.build
\ No newline at end of file diff --git a/blocklib/analog/lib/meson.build b/blocklib/analog/lib/meson.build deleted file mode 100644 index bbe0f9769..000000000 --- a/blocklib/analog/lib/meson.build +++ /dev/null @@ -1,54 +0,0 @@ -analog_deps += [gnuradio_gr_dep, gr_kernel_math_lib_dep, gr_kernel_analog_lib_dep, gnuradio_blocklib_filter_dep, - volk_dep, fmt_dep, pmtf_dep] - -# analog_sources += 'kernel/agc.cc' -block_cpp_args = ['-DHAVE_CPU', '-DHAVE_HIER'] -# if IMPLEMENT_CUDA -# block_cpp_args += '-DHAVE_CUDA' - -# gnuradio_blocklib_analog_cu = library('gnuradio-blocklib-analog-cu', -# analog_cu_sources, -# include_directories : incdir, -# install : true, -# dependencies : [cuda_dep]) - -# gnuradio_blocklib_analog_cu_dep = declare_dependency(include_directories : incdir, -# link_with : gnuradio_blocklib_analog_cu, -# dependencies : cuda_dep) - -# analog_deps += [gnuradio_blocklib_analog_cu_dep, cuda_dep] - -# endif - -incdir = include_directories(['../include/gnuradio/analog','../include']) -gnuradio_blocklib_analog_lib = library('gnuradio-blocklib-analog', - analog_sources, - include_directories : incdir, - install : true, - link_language: 'cpp', - dependencies : analog_deps, - cpp_args : block_cpp_args) - -gnuradio_blocklib_analog_dep = declare_dependency(include_directories : incdir, - link_with : gnuradio_blocklib_analog_lib, - dependencies : analog_deps) - -cmake_conf = configuration_data() -cmake_conf.set('libdir', join_paths(prefix,get_option('libdir'))) -cmake_conf.set('module', 'analog') -cmake.configure_package_config_file( - name : 'gnuradio-analog', - 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_analog_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-analog', - filebase : 'gnuradio-analog', - description : 'GNU Radio Analog Module') diff --git a/blocklib/analog/noise_source/noise_source.yml b/blocklib/analog/noise_source/noise_source.yml deleted file mode 100644 index fabee1abe..000000000 --- a/blocklib/analog/noise_source/noise_source.yml +++ /dev/null @@ -1,45 +0,0 @@ -module: analog -block: noise_source -label: Noise Source -blocktype: sync_block -category: '[Core]/Waveform Generators' -includes: - - gnuradio/analog/enums.h - -typekeys: - - id: T - type: class - options: - - cf32 - - rf32 - - ri32 - - ri16 - -parameters: -- id: type - label: Type - dtype: enums/noise_t - settable: true - is_enum: true # this should be handled better -- id: amplitude - label: Amplitude - dtype: rf32 - settable: true -- id: seed - label: Seed - dtype: ru64 - settable: false - default: 0 - -# Example Ports -ports: -- domain: stream - id: out - direction: output - type: typekeys/T - -implementations: -- id: cpu -# - id: cuda - -file_format: 1
\ No newline at end of file diff --git a/blocklib/analog/noise_source/noise_source_cpu.cc b/blocklib/analog/noise_source/noise_source_cpu.cc deleted file mode 100644 index 1fecb3b29..000000000 --- a/blocklib/analog/noise_source/noise_source_cpu.cc +++ /dev/null @@ -1,77 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2004,2010,2012,2018 Free Software Foundation, Inc. - * Copyright 2022 Josh Morman - * - * This file is part of GNU Radio - * - * SPDX-License-Identifier: GPL-3.0-or-later - * - */ - -#include "noise_source_cpu.h" -#include "noise_source_cpu_gen.h" - -namespace gr { -namespace analog { - -template <class T> -noise_source_cpu<T>::noise_source_cpu(const typename noise_source<T>::block_args& args) - : INHERITED_CONSTRUCTORS(T), d_rng(args.seed) -{ -} - -template <> -noise_source_cpu<gr_complex>::noise_source_cpu( - const typename noise_source<gr_complex>::block_args& args) - : INHERITED_CONSTRUCTORS(gr_complex), d_rng(args.seed) -{ - // param_amplitude gets set in the INHERITED_CONSTRUCTORS from the noise_source - // autogen class but for complex, needs the 1/sqrt(2) factor - *param_amplitude = args.amplitude / sqrtf(2.0f); -} - -template <class T> -work_return_t noise_source_cpu<T>::work(work_io& wio) - -{ - auto out = wio.outputs()[0].items<T>(); - auto noutput_items = wio.outputs()[0].n_items; - - auto type = pmtf::get_as<int>(*this->param_type); - auto ampl = pmtf::get_as<float>(*this->param_amplitude); - - switch (static_cast<noise_t>(type)) { - case noise_t::UNIFORM: - for (size_t i = 0; i < noutput_items; i++) { - out[i] = static_cast<T>(ampl * ((d_rng.ran1() * 2.0) - 1.0)); - } - break; - - case noise_t::GAUSSIAN: - for (size_t i = 0; i < noutput_items; i++) { - out[i] = static_cast<T>(ampl * d_rng.gasdev()); - } - break; - - case noise_t::LAPLACIAN: - for (size_t i = 0; i < noutput_items; i++) { - out[i] = static_cast<T>(ampl * d_rng.laplacian()); - } - break; - - case noise_t::IMPULSE: // FIXME changeable impulse settings - for (size_t i = 0; i < noutput_items; i++) { - out[i] = static_cast<T>(ampl * d_rng.impulse(9)); - } - break; - default: - throw std::runtime_error("invalid type"); - } - - wio.produce_each(noutput_items); - return work_return_t::OK; -} - -} /* namespace analog */ -} /* namespace gr */ diff --git a/blocklib/analog/noise_source/noise_source_cpu.h b/blocklib/analog/noise_source/noise_source_cpu.h deleted file mode 100644 index acff4ff74..000000000 --- a/blocklib/analog/noise_source/noise_source_cpu.h +++ /dev/null @@ -1,33 +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/analog/noise_source.h> -#include <gnuradio/kernel/math/random.h> - -namespace gr { -namespace analog { - -template <class T> -class noise_source_cpu : public noise_source<T> -{ -public: - noise_source_cpu(const typename noise_source<T>::block_args& args); - - work_return_t work(work_io&) override; - -private: - kernel::math::random d_rng; -}; - - -} // namespace analog -} // namespace gr diff --git a/blocklib/analog/python/gnuradio/analog/.gitignore b/blocklib/analog/python/gnuradio/analog/.gitignore deleted file mode 100644 index 25d053a52..000000000 --- a/blocklib/analog/python/gnuradio/analog/.gitignore +++ /dev/null @@ -1 +0,0 @@ -meson.build
\ No newline at end of file diff --git a/blocklib/analog/python/gnuradio/analog/__init__.py b/blocklib/analog/python/gnuradio/analog/__init__.py deleted file mode 100644 index 3c278fc3a..000000000 --- a/blocklib/analog/python/gnuradio/analog/__init__.py +++ /dev/null @@ -1,12 +0,0 @@ - -import os - -try: - from .analog_python import * -except ImportError: - dirname, filename = os.path.split(os.path.abspath(__file__)) - __path__.append(os.path.join(dirname, "bindings")) - from .analog_python import * - - -# from .fm_deemph_hier import *
\ No newline at end of file diff --git a/blocklib/analog/python/gnuradio/analog/fm_deemph_hier.py b/blocklib/analog/python/gnuradio/analog/fm_deemph_hier.py deleted file mode 100644 index 093110110..000000000 --- a/blocklib/analog/python/gnuradio/analog/fm_deemph_hier.py +++ /dev/null @@ -1,36 +0,0 @@ -# -# Copyright 2005,2007,2012 Free Software Foundation, Inc. -# -# This file is part of GNU Radio -# -# SPDX-License-Identifier: GPL-3.0-or-later -# -# - - -from gnuradio import gr, filter -import math - - -def fm_deemph_hier(self, fs, tau): - # Digital corner frequency - w_c = 1.0 / tau - - # Prewarped analog corner frequency - w_ca = 2.0 * fs * math.tan(w_c / (2.0 * fs)) - - # Resulting digital pole, zero, and gain term from the bilinear - # transformation of H(s) = w_ca / (s + w_ca) to - # H(z) = b0 (1 - z1 z^-1)/(1 - p1 z^-1) - k = -w_ca / (2.0 * fs) - z1 = -1.0 - p1 = (1.0 + k) / (1.0 - k) - b0 = -k / (1.0 - k) - - btaps = [b0 * 1.0, b0 * -z1] - ataps = [1.0, -p1] - - # Since H(s = 0) = 1.0, then H(z = 1) = 1.0 and has 0 dB gain at DC - - deemph = filter.iir_filter_ffd(btaps, ataps, False) - self.connect((self, deemph, self)) diff --git a/blocklib/analog/quadrature_demod/quadrature_demod.yml b/blocklib/analog/quadrature_demod/quadrature_demod.yml deleted file mode 100644 index 0b28aa965..000000000 --- a/blocklib/analog/quadrature_demod/quadrature_demod.yml +++ /dev/null @@ -1,57 +0,0 @@ -module: analog -block: quadrature_demod -label: Quadrature Demod -blocktype: block -category: '[Core]/Modulators' - -doc: - brief: "quadrature demodulator: complex in, float out" - detail: |- - This can be used to demod FM, FSK, GMSK, etc. The input is complex - baseband, output is the signal frequency in relation to the sample - rate, multiplied with the gain. - - Mathematically, this block calculates the product of the one-sample - delayed input and the conjugate undelayed signal, and then calculates - the argument of the resulting complex number: - - y[n] = \mathrm{arg}\left(x[n] \, \bar x [n-1]\right). - - Let x be a complex sinusoid with amplitude A>0, (absolute) - frequency f\in\mathbb R and phase \phi_0\in[0;2\pi] sampled at - f_s>0 so, without loss of generality, - - x[n]= A e^{j2\pi( \frac f{f_s} n + \phi_0)}\f - - then - - y[n] = \mathrm{arg}\left(A e^{j2\pi\left( \frac f{f_s} n + \phi_0\right)} \overline{A e^{j2\pi( \frac f{f_s} (n-1) + \phi_0)}}\right)\ = \mathrm{arg}\left(A^2 e^{j2\pi\left( \frac f{f_s} n + \phi_0\right)} e^{-j2\pi( \frac f{f_s} (n-1) + \phi_0)}\right)\ = \mathrm{arg}\left( A^2 e^{j2\pi\left( \frac f{f_s} n + \phi_0 - \frac f{f_s} (n-1) - \phi_0\right)}\right)\ = \mathrm{arg}\left( A^2 e^{j2\pi\left( \frac f{f_s} n - \frac f{f_s} (n-1)\right)}\right)\ = \mathrm{arg}\left( A^2 e^{j2\pi\left( \frac f{f_s} \left(n-(n-1)\right)\right)}\right)\ = \mathrm{arg}\left( A^2 e^{j2\pi \frac f{f_s}}\right) \intertext{$A$ is real, so is $A^2$ and hence only \textit{scales}, therefore $\mathrm{arg}(\cdot)$ is invariant:} = \mathrm{arg}\left(e^{j2\pi \frac f{f_s}}\right)\= \frac f{f_s}\\ - - -# Example Parameters -parameters: -- id: gain - label: Gain - dtype: rf32 - settable: true - grc: - hide: part - default: samp_rate/(2*math.pi*fsk_deviation_hz) - -ports: -- domain: stream - id: in - direction: input - type: cf32 - -- domain: stream - id: out - direction: output - type: rf32 - - -implementations: -- id: cpu -# - id: cuda - -file_format: 1 diff --git a/blocklib/analog/quadrature_demod/quadrature_demod_cpu.cc b/blocklib/analog/quadrature_demod/quadrature_demod_cpu.cc deleted file mode 100644 index 30f7614b9..000000000 --- a/blocklib/analog/quadrature_demod/quadrature_demod_cpu.cc +++ /dev/null @@ -1,50 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2004,2005,2010,2012 Free Software Foundation, Inc. - * Copyright 2022 Josh Morman - * - * This file is part of GNU Radio - * - * SPDX-License-Identifier: GPL-3.0-or-later - * - */ - -#include "quadrature_demod_cpu.h" -#include "quadrature_demod_cpu_gen.h" - -#include <gnuradio/kernel/math/math.h> -#include <volk/volk.h> - -namespace gr { -namespace analog { - -quadrature_demod_cpu::quadrature_demod_cpu(block_args args) : INHERITED_CONSTRUCTORS -{ - // FIXME: do volk alignment -} - -work_return_t quadrature_demod_cpu::work(work_io& wio) -{ - auto in = wio.inputs()[0].items<gr_complex>(); - auto out = wio.outputs()[0].items<float>(); - auto noutput_items = wio.outputs()[0].n_items; - auto ninput_items = wio.inputs()[0].n_items; - - // because of the history requirement, input needs to be 1 more than what we produce - auto to_produce = std::min(ninput_items - (d_history - 1), noutput_items); - auto gain = pmtf::get_as<float>(*this->param_gain); - - std::vector<gr_complex> tmp(to_produce); - volk_32fc_x2_multiply_conjugate_32fc(&tmp[0], &in[1], &in[0], to_produce); - for (size_t i = 0; i < to_produce; i++) { - out[i] = gain * gr::kernel::math::fast_atan2f(imag(tmp[i]), real(tmp[i])); - } - - wio.produce_each(to_produce); - wio.consume_each(to_produce); - return work_return_t::OK; -} - - -} // namespace analog -} // namespace gr diff --git a/blocklib/analog/quadrature_demod/quadrature_demod_cpu.h b/blocklib/analog/quadrature_demod/quadrature_demod_cpu.h deleted file mode 100644 index ce6c058e2..000000000 --- a/blocklib/analog/quadrature_demod/quadrature_demod_cpu.h +++ /dev/null @@ -1,30 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2004,2012 Free Software Foundation, Inc. - * Copyright 2022 Josh Morman - * - * This file is part of GNU Radio - * - * SPDX-License-Identifier: GPL-3.0-or-later - * - */ - -#pragma once - -#include <gnuradio/analog/quadrature_demod.h> - -namespace gr { -namespace analog { - -class quadrature_demod_cpu : public virtual quadrature_demod -{ -public: - quadrature_demod_cpu(block_args args); - work_return_t work(work_io&) override; - -private: - size_t d_history = 2; -}; - -} // namespace analog -} // namespace gr
\ No newline at end of file diff --git a/blocklib/analog/random_source/random_source.yml b/blocklib/analog/random_source/random_source.yml deleted file mode 100644 index 6e592a389..000000000 --- a/blocklib/analog/random_source/random_source.yml +++ /dev/null @@ -1,59 +0,0 @@ -module: analog -block: random_source -label: Random Source -blocktype: grc - -category: '[Core]/Waveform Generators' - -typekeys: - - id: T - type: class - options: - - ri32 - - ri16 - - ri8 - -grc: - flags: [python] - templates: - imports: |- - from gnuradio import blocks - import numpy - make: |- - blocks.vector_source_${T.fcn}(list(map(int, numpy.random.randint(${min}, ${max}, - ${num_samps}))), ${repeat}) - -# Example Parameters -parameters: -- id: min - label: Minimum - dtype: typekeys/T - grc: - default: 0 -- id: max - label: Maximum - dtype: typekeys/T - grc: - default: 2 -- id: num_samps - label: Num Samples - dtype: size - grc: - default: 1000 -- id: repeat - label: Repeat - dtype: bool - grc: - default: true - -# Example Ports -ports: -- domain: stream - id: out - direction: output - type: typekeys/T - -implementations: -- id: cpu - -file_format: 1 diff --git a/blocklib/analog/sig_source/.gitignore b/blocklib/analog/sig_source/.gitignore deleted file mode 100644 index 25d053a52..000000000 --- a/blocklib/analog/sig_source/.gitignore +++ /dev/null @@ -1 +0,0 @@ -meson.build
\ No newline at end of file diff --git a/blocklib/analog/sig_source/sig_source.yml b/blocklib/analog/sig_source/sig_source.yml deleted file mode 100644 index 48252319e..000000000 --- a/blocklib/analog/sig_source/sig_source.yml +++ /dev/null @@ -1,67 +0,0 @@ -module: analog -block: sig_source -label: Signal Source -blocktype: sync_block -category: '[Core]/Waveform Generators' -includes: - - gnuradio/analog/enums.h - -typekeys: - - id: T - type: class - options: - - cf32 - - rf32 - - ri32 - - ri16 - - ri8 - -parameters: -- id: sampling_freq - label: Sampling Freq - dtype: rf64 - settable: true - grc: - default: samp_rate -- id: waveform - label: Waveform - dtype: enums/waveform_t - is_enum: true - settable: true - grc: - default: analog.waveform.sin -- id: frequency - label: Wave Freq - dtype: rf64 - settable: true - grc: - default: 1000 -- id: ampl - label: Amplitude - dtype: rf64 - settable: true - grc: - default: 1.0 -- id: offset - label: Offset - dtype: T - settable: true - default: 0 -- id: phase - label: Phase - dtype: rf64 - settable: true - default: 0 - -# Example Ports -ports: -- domain: stream - id: out - direction: output - type: typekeys/T - -implementations: -- id: cpu -# - id: cuda - -file_format: 1
\ No newline at end of file diff --git a/blocklib/analog/sig_source/sig_source_cpu.cc b/blocklib/analog/sig_source/sig_source_cpu.cc deleted file mode 100644 index 3510ba021..000000000 --- a/blocklib/analog/sig_source/sig_source_cpu.cc +++ /dev/null @@ -1,215 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2022 Josh Morman - * - * This file is part of GNU Radio - * - * SPDX-License-Identifier: GPL-3.0-or-later - * - */ - -#include "sig_source_cpu.h" -#include "sig_source_cpu_gen.h" - -#include <gnuradio/kernel/math/math.h> -#include <algorithm> - -namespace gr { -namespace analog { - -template <class T> -sig_source_cpu<T>::sig_source_cpu(const typename sig_source<T>::block_args& args) - : INHERITED_CONSTRUCTORS(T) -{ - this->set_frequency(args.frequency); - this->set_phase(args.phase); -} - -template <typename T> -work_return_t sig_source_cpu<T>::work(work_io& wio) -{ - auto optr = wio.outputs()[0].items<T>(); - auto noutput_items = wio.outputs()[0].n_items; - - T t; - std::scoped_lock l(d_mutex); - - auto offset = pmtf::get_as<T>(*this->param_offset); - auto ampl = pmtf::get_as<float>(*this->param_ampl); - auto waveform = static_cast<waveform_t>(pmtf::get_as<int>(*this->param_waveform)); - - switch (waveform) { - case waveform_t::CONSTANT: - t = (T)ampl + offset; - std::fill_n(optr, noutput_items, t); - break; - - case waveform_t::SIN: - d_nco.sin(optr, noutput_items, ampl); - if (offset == 0) - break; - - for (size_t i = 0; i < noutput_items; i++) { - optr[i] += offset; - } - break; - case waveform_t::COS: - d_nco.cos(optr, noutput_items, ampl); - if (offset == 0) - break; - - for (size_t i = 0; i < noutput_items; i++) { - optr[i] += offset; - } - break; - - /* The square wave is high from -PI to 0. */ - case waveform_t::SQUARE: - t = (T)ampl + offset; - for (size_t i = 0; i < noutput_items; i++) { - if (d_nco.get_phase() < 0) - optr[i] = t; - else - optr[i] = offset; - d_nco.step(); - } - break; - - /* The triangle wave rises from -PI to 0 and falls from 0 to PI. */ - case waveform_t::TRIANGLE: - for (size_t i = 0; i < noutput_items; i++) { - double t = ampl * d_nco.get_phase() / GR_M_PI; - if (d_nco.get_phase() < 0) - optr[i] = static_cast<T>(t + ampl + offset); - else - optr[i] = static_cast<T>(-1 * t + ampl + offset); - d_nco.step(); - } - break; - - /* The saw tooth wave rises from -PI to PI. */ - case waveform_t::SAWTOOTH: - for (size_t i = 0; i < noutput_items; i++) { - t = static_cast<T>(ampl * d_nco.get_phase() / (2 * GR_M_PI) + ampl / 2 + - offset); - optr[i] = t; - d_nco.step(); - } - break; - default: - throw std::runtime_error("analog::sig_source: invalid waveform"); - } - - wio.produce_each(noutput_items); - return work_return_t::OK; -} - -template <> -work_return_t sig_source_cpu<gr_complex>::work(work_io& wio) - -{ - auto optr = wio.outputs()[0].items<gr_complex>(); - auto noutput_items = wio.outputs()[0].n_items; - - gr_complex t; - std::scoped_lock l(d_mutex); - - auto offset = pmtf::get_as<gr_complex>(*this->param_offset); - auto ampl = pmtf::get_as<float>(*this->param_ampl); - auto waveform = static_cast<waveform_t>(pmtf::get_as<int>(*this->param_waveform)); - - switch (waveform) { - case waveform_t::CONSTANT: - t = (gr_complex)ampl + offset; - std::fill_n(optr, noutput_items, t); - break; - - case waveform_t::SIN: - case waveform_t::COS: - d_nco.sincos(optr, noutput_items, ampl); - if (offset == gr_complex(0, 0)) - break; - - for (size_t i = 0; i < noutput_items; i++) { - optr[i] += offset; - } - break; - - /* Implements a real square wave high from -PI to 0. - * The imaginary square wave leads by 90 deg. - */ - case waveform_t::SQUARE: - for (size_t i = 0; i < noutput_items; i++) { - if (d_nco.get_phase() < -1 * GR_M_PI / 2) - optr[i] = gr_complex(ampl, 0) + offset; - else if (d_nco.get_phase() < 0) - optr[i] = gr_complex(ampl, ampl) + offset; - else if (d_nco.get_phase() < GR_M_PI / 2) - optr[i] = gr_complex(0, ampl) + offset; - else - optr[i] = offset; - d_nco.step(); - } - break; - - /* Implements a real triangle wave rising from -PI to 0 and - * falling from 0 to PI. The imaginary triangle wave leads by - * 90 deg. - */ - case waveform_t::TRIANGLE: - for (size_t i = 0; i < noutput_items; i++) { - if (d_nco.get_phase() < -1 * GR_M_PI / 2) { - optr[i] = gr_complex(ampl * d_nco.get_phase() / GR_M_PI + ampl, - -1 * ampl * d_nco.get_phase() / GR_M_PI - ampl / 2) + - offset; - } - else if (d_nco.get_phase() < 0) { - optr[i] = gr_complex(ampl * d_nco.get_phase() / GR_M_PI + ampl, - ampl * d_nco.get_phase() / GR_M_PI + ampl / 2) + - offset; - } - else if (d_nco.get_phase() < GR_M_PI / 2) { - optr[i] = gr_complex(-1 * ampl * d_nco.get_phase() / GR_M_PI + ampl, - ampl * d_nco.get_phase() / GR_M_PI + ampl / 2) + - offset; - } - else { - optr[i] = - gr_complex(-1 * ampl * d_nco.get_phase() / GR_M_PI + ampl, - -1 * ampl * d_nco.get_phase() / GR_M_PI + 3 * ampl / 2) + - offset; - } - d_nco.step(); - } - break; - - /* Implements a real saw tooth wave rising from -PI to PI. - * The imaginary saw tooth wave leads by 90 deg. - */ - case waveform_t::SAWTOOTH: - for (size_t i = 0; i < noutput_items; i++) { - if (d_nco.get_phase() < -1 * GR_M_PI / 2) { - optr[i] = - gr_complex(ampl * d_nco.get_phase() / (2 * GR_M_PI) + ampl / 2, - ampl * d_nco.get_phase() / (2 * GR_M_PI) + 5 * ampl / 4) + - offset; - } - else { - optr[i] = - gr_complex(ampl * d_nco.get_phase() / (2 * GR_M_PI) + ampl / 2, - ampl * d_nco.get_phase() / (2 * GR_M_PI) + ampl / 4) + - offset; - } - d_nco.step(); - } - break; - default: - throw std::runtime_error("analog::sig_source: invalid waveform"); - } - - wio.produce_each(noutput_items); - return work_return_t::OK; -} - -} /* namespace analog */ -} /* namespace gr */ diff --git a/blocklib/analog/sig_source/sig_source_cpu.h b/blocklib/analog/sig_source/sig_source_cpu.h deleted file mode 100644 index a950c6094..000000000 --- a/blocklib/analog/sig_source/sig_source_cpu.h +++ /dev/null @@ -1,58 +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/analog/sig_source.h> -#include <gnuradio/kernel/math/fxpt_nco.h> -#include <gnuradio/kernel/math/math.h> -#include <mutex> - -namespace gr { -namespace analog { - -template <class T> -class sig_source_cpu : public sig_source<T> -{ -public: - sig_source_cpu(const typename sig_source<T>::block_args& args); - - work_return_t work(work_io&) override; - - - 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() == sig_source<T>::id_phase) { - auto phase = pmtf::get_as<double>(*this->param_phase); - d_nco.set_phase(phase); - } - else if (action->id() == sig_source<T>::id_frequency) { - auto freq = pmtf::get_as<double>(*this->param_frequency); - auto samp_freq = pmtf::get_as<double>(*this->param_sampling_freq); - d_nco.set_freq(2 * GR_M_PI * freq / samp_freq); - } - } - - -private: - // Declare private variables here - gr::kernel::math::fxpt_nco d_nco; - - // sig_source has some non thread safe accessors (for now) - std::mutex d_mutex; -}; - - -} // namespace analog -} // namespace gr diff --git a/blocklib/analog/test/.gitignore b/blocklib/analog/test/.gitignore deleted file mode 100644 index 01ecb66ff..000000000 --- a/blocklib/analog/test/.gitignore +++ /dev/null @@ -1 +0,0 @@ -!meson.build
\ No newline at end of file diff --git a/blocklib/analog/test/meson.build b/blocklib/analog/test/meson.build deleted file mode 100644 index 8c3ed151a..000000000 --- a/blocklib/analog/test/meson.build +++ /dev/null @@ -1,9 +0,0 @@ -################################################### -# QA -################################################### - -if GR_ENABLE_PYTHON - test('qa_sig_source', find_program('qa_sig_source.py'), env: TEST_ENV) - test('qa_noise', find_program('qa_noise.py'), env: TEST_ENV) - test('qa_quadrature_demod', find_program('qa_quadrature_demod.py'), env: TEST_ENV) -endif diff --git a/blocklib/analog/test/qa_agc.py b/blocklib/analog/test/qa_agc.py deleted file mode 100644 index 7e3a08286..000000000 --- a/blocklib/analog/test/qa_agc.py +++ /dev/null @@ -1,497 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright 2004,2007,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, analog, blocks - - -class test_agc(gr_unittest.TestCase): - - def setUp(self): - self.tb = gr.flowgraph() - - def tearDown(self): - self.tb = None - - def test_001_sets(self): - agc = analog.agc_cc(1e-3, 1, 1) - - agc.set_rate(1) - agc.set_reference(1.1) - agc.set_gain(1.1) - agc.set_max_gain(100) - - self.assertAlmostEqual(agc.rate(), 1) - self.assertAlmostEqual(agc.reference(), 1.1) - self.assertAlmostEqual(agc.gain(), 1.1) - self.assertAlmostEqual(agc.max_gain(), 100) - - def test_001(self): - ''' Test the complex AGC loop (single rate input) ''' - tb = self.tb - - expected_result = ( - (100 + 0j), - (72.89209747314453 + 52.9592170715332j), - (25.089027404785156 + 77.2160873413086j), - (-22.611034393310547 + 69.58960723876953j), - (-53.35764694213867 + 38.766597747802734j), - (-59.4586067199707 - 2.7399494229030097e-06j), - (-43.3734245300293 - 31.51263999938965j), - (-14.941386222839355 - 45.984867095947266j), - (13.478157997131348 - 41.48149490356445j), - (31.838510513305664 - 23.13202476501465j), - (35.51927947998047 + 3.3255341804760974e-06j), - (25.94291114807129 + 18.848634719848633j), - (8.949296951293945 + 27.543113708496094j), - (-8.085277557373047 + 24.883914947509766j), - (-19.13165283203125 + 13.899954795837402j), - (-21.383323669433594 - 2.987417019539862e-06j), - (-15.65035343170166 - 11.370650291442871j), - (-5.4110236167907715 - 16.653427124023438j), - (4.900828838348389 - 15.083191871643066j), - (11.62836742401123 - 8.448498725891113j), - (13.036169052124023 + 2.4410530841123546e-06j), - (9.572690963745117 + 6.954970359802246j), - (3.3217051029205322 + 10.223164558410645j), - (-3.0204410552978516 + 9.295955657958984j), - (-7.197745323181152 + 5.229465007781982j), - (-8.107251167297363 - 1.8916969111160142e-06j), - (-5.983887195587158 - 4.347550392150879j), - (-2.087981939315796 - 6.426152229309082j), - (1.9100888967514038 - 5.87864351272583j), - (4.581503391265869 - 3.3286550045013428j), - (5.196768760681152 + 1.4596606661143596e-06j), - (3.864729881286621 + 2.807892322540283j), - (1.359479308128357 + 4.184051513671875j), - (-1.2544355392456055 + 3.8607518672943115j), - (-3.036635398864746 + 2.2062432765960693j), - (-3.4781548976898193 - 1.137218077928992e-06j), - (-2.613386869430542 - 1.8987380266189575j), - (-0.9293051958084106 - 2.8601105213165283j), - (0.8672783374786377 - 2.6692051887512207j), - (2.1244049072265625 - 1.5434693098068237j), - (2.463329315185547 + 9.225283861269418e-07j), - (1.8744803667068481 + 1.3618910312652588j), - (0.6752913594245911 + 2.078335762023926j), - (-0.6386655569076538 + 1.9656078815460205j), - (-1.5857415199279785 + 1.1521075963974j), - (-1.864084243774414 - 7.840082503207668e-07j), - (-1.438162922859192 - 1.0448874235153198j), - (-0.5252984762191772 - 1.6167048215866089j), - (0.5036717653274536 - 1.5501397848129272j), - (1.2676655054092407 - 0.9210119843482971j)) - - sampling_freq = 100 - src1 = analog.sig_source_c(sampling_freq, analog.GR_SIN_WAVE, - sampling_freq * 0.10, 100.0) - dst1 = blocks.vector_sink_c() - head = streamops.head(gr.sizeof_gr_complex, int(5 * sampling_freq * 0.10)) - - agc = analog.agc_cc(1e-3, 1, 1) - - tb.connect(src1, head) - tb.connect(head, agc) - tb.connect(agc, dst1) - - tb.run() - dst_data = dst1.data() - self.assertComplexTuplesAlmostEqual(expected_result, dst_data, 4) - - def test_002_sets(self): - agc = analog.agc_ff(1e-3, 1, 1) - - agc.set_rate(1) - agc.set_reference(1.1) - agc.set_gain(1.1) - agc.set_max_gain(100) - - self.assertAlmostEqual(agc.rate(), 1) - self.assertAlmostEqual(agc.reference(), 1.1) - self.assertAlmostEqual(agc.gain(), 1.1) - self.assertAlmostEqual(agc.max_gain(), 100) - - def test_002(self): - ''' Test the floating point AGC loop (single rate input) ''' - tb = self.tb - - expected_result = ( - 0.0, - 58.83704376220703, - 89.69985961914062, - 81.26403045654297, - 45.50606918334961, - -3.3625440210016677e-06, - -42.9488639831543, - -65.50326538085938, - -59.368656158447266, - -33.26097869873047, - 4.995997642254224e-06, - 31.423521041870117, - 47.950958251953125, - 43.48566436767578, - 24.37834358215332, - -5.4677821026416495e-06, - -23.06298828125, - -35.21844482421875, - -31.964082717895508, - -17.93484115600586, - 5.396469077822985e-06, - 16.998228073120117, - 25.982229232788086, - 23.60628318786621, - 13.260700225830078, - -4.97806149724056e-06, - -12.598825454711914, - -19.282241821289062, - -17.543500900268555, - -9.870061874389648, - 4.467380676942412e-06, - 9.407480239868164, - 14.422045707702637, - 13.14553451538086, - 7.410478591918945, - -3.91256025977782e-06, - -7.092466354370117, - -10.896439552307129, - -9.955231666564941, - -5.62628698348999, - 3.411524403418298e-06, - 5.413146018981934, - 8.338950157165527, - 7.640974521636963, - 4.332027435302734, - -2.95963241114805e-06, - -4.19495964050293, - -6.483736991882324, - -5.962202072143555, - -3.3931667804718018) - - sampling_freq = 100 - src1 = analog.sig_source_f(sampling_freq, analog.GR_SIN_WAVE, - sampling_freq * 0.10, 100.0) - dst1 = blocks.vector_sink_f() - head = streamops.head(gr.sizeof_float, int(5 * sampling_freq * 0.10)) - - agc = analog.agc_ff(1e-3, 1, 1) - - tb.connect(src1, head) - tb.connect(head, agc) - tb.connect(agc, dst1) - - tb.run() - dst_data = dst1.data() - self.assertFloatTuplesAlmostEqual(expected_result, dst_data, 4) - - def test_003_sets(self): - agc = analog.agc2_cc(1e-3, 1e-1, 1, 1) - - agc.set_attack_rate(1) - agc.set_decay_rate(2) - agc.set_reference(1.1) - agc.set_gain(1.1) - agc.set_max_gain(100) - - self.assertAlmostEqual(agc.attack_rate(), 1) - self.assertAlmostEqual(agc.decay_rate(), 2) - self.assertAlmostEqual(agc.reference(), 1.1) - self.assertAlmostEqual(agc.gain(), 1.1) - self.assertAlmostEqual(agc.max_gain(), 100) - - def test_003(self): - ''' Test the complex AGC loop (attack and decay rate inputs) ''' - tb = self.tb - - expected_result = \ - ((100 + 0j), - (0.8090173602104187 + 0.5877856016159058j), - (0.3090175688266754 + 0.9510582685470581j), - (-0.309017539024353 + 0.9510582089424133j), - (-0.8090170621871948 + 0.5877852439880371j), - (-1.000004529953003 - 4.608183701293456e-08j), - (-0.8090165853500366 - 0.587785005569458j), - (-0.3090173006057739 - 0.9510576725006104j), - (0.3090173900127411 - 0.951057493686676j), - (0.8090166449546814 - 0.5877848863601685j), - (1.0000040531158447 + 9.362654651567937e-08j), - (0.809016227722168 + 0.5877848267555237j), - (0.3090171217918396 + 0.9510573148727417j), - (-0.3090173006057739 + 0.9510571360588074j), - (-0.8090163469314575 + 0.5877846479415894j), - (-1.000003695487976 - 1.39708305368913e-07j), - (-0.8090159296989441 - 0.5877846479415894j), - (-0.30901697278022766 - 0.951056957244873j), - (0.30901727080345154 - 0.9510568976402283j), - (0.809016227722168 - 0.5877844095230103j), - (1.000003457069397 + 1.87252979344521e-07j), - (0.809015691280365 + 0.5877845287322998j), - (0.3090168535709381 + 0.9510567784309387j), - (-0.30901727080345154 + 0.951056718826294j), - (-0.8090161085128784 + 0.5877842903137207j), - (-1.0000033378601074 - 2.3333473109232727e-07j), - (-0.8090156316757202 - 0.5877845287322998j), - (-0.3090168237686157 - 0.9510566592216492j), - (0.3090173006057739 - 0.9510565400123596j), - (0.8090160489082336 - 0.5877842307090759j), - (1.0000032186508179 + 2.8087941927879e-07j), - (0.8090155124664307 + 0.5877845287322998j), - (0.30901676416397095 + 0.9510567784309387j), - (-0.3090173006057739 + 0.9510565400123596j), - (-0.8090160489082336 + 0.5877841711044312j), - (-1.0000033378601074 - 3.2696124208086985e-07j), - (-0.8090155124664307 - 0.5877845883369446j), - (-0.30901673436164856 - 0.9510567784309387j), - (0.3090173602104187 - 0.9510565400123596j), - (0.8090160489082336 - 0.5877841114997864j), - (1.0000033378601074 + 3.745059302673326e-07j), - (0.8090154528617859 + 0.5877846479415894j), - (0.3090166747570038 + 0.9510567784309387j), - (-0.3090174198150635 + 0.9510565400123596j), - (-0.8090161681175232 + 0.5877841114997864j), - (-1.0000032186508179 - 4.2058766780428414e-07j), - (-0.8090154528617859 - 0.5877846479415894j), - (-0.309016615152359 - 0.9510567784309387j), - (0.30901747941970825 - 0.9510564804077148j), - (0.8090161681175232 - 0.5877840518951416j)) - - sampling_freq = 100 - src1 = analog.sig_source_c(sampling_freq, analog.GR_SIN_WAVE, - sampling_freq * 0.10, 100) - dst1 = blocks.vector_sink_c() - head = streamops.head(gr.sizeof_gr_complex, int(5 * sampling_freq * 0.10)) - - agc = analog.agc2_cc(1e-2, 1e-3, 1, 1) - - tb.connect(src1, head) - tb.connect(head, agc) - tb.connect(agc, dst1) - - tb.run() - dst_data = dst1.data() - self.assertComplexTuplesAlmostEqual(expected_result, dst_data, 4) - - def test_004_sets(self): - agc = analog.agc2_ff(1e-3, 1e-1, 1, 1) - - agc.set_attack_rate(1) - agc.set_decay_rate(2) - agc.set_reference(1.1) - agc.set_gain(1.1) - agc.set_max_gain(100) - - self.assertAlmostEqual(agc.attack_rate(), 1) - self.assertAlmostEqual(agc.decay_rate(), 2) - self.assertAlmostEqual(agc.reference(), 1.1) - self.assertAlmostEqual(agc.gain(), 1.1) - self.assertAlmostEqual(agc.max_gain(), 100) - - def test_004(self): - ''' Test the floating point AGC loop (attack and decay rate inputs) ''' - tb = self.tb - - expected_result = \ - (0.0, - 58.83704376220703, - 40.194339752197266, - 2.9184224605560303, - 0.6760660409927368, - -6.79303795436681e-08, - -1.4542515277862549, - -1.9210143089294434, - -1.0450801849365234, - -0.6193966865539551, - 1.3429632872430375e-07, - 1.4308913946151733, - 1.9054334163665771, - 1.044317603111267, - 0.619373619556427, - -2.003930177352231e-07, - -1.4308818578720093, - -1.905427098274231, - -1.0443172454833984, - -0.6193735599517822, - 2.6858961632569844e-07, - 1.4308820962905884, - 1.9054267406463623, - 1.0443172454833984, - 0.6193734407424927, - -3.3468785431978176e-07, - -1.4308820962905884, - -1.9054267406463623, - -1.0443171262741089, - -0.6193735599517822, - 4.0288449554282124e-07, - 1.430882215499878, - 1.905427098274231, - 1.0443170070648193, - 0.6193734407424927, - -4.689827903803234e-07, - -1.430882453918457, - -1.9054268598556519, - -1.0443170070648193, - -0.6193733811378479, - 5.371793463382346e-07, - 1.4308825731277466, - 1.9054265022277832, - 1.0443170070648193, - 0.6193733811378479, - -6.032776127540274e-07, - -1.4308825731277466, - -1.9054265022277832, - -1.0443168878555298, - -0.6193733811378479) - - sampling_freq = 100 - src1 = analog.sig_source_f(sampling_freq, analog.GR_SIN_WAVE, - sampling_freq * 0.10, 100) - dst1 = blocks.vector_sink_f() - head = streamops.head(gr.sizeof_float, int(5 * sampling_freq * 0.10)) - - agc = analog.agc2_ff(1e-2, 1e-3, 1, 1) - - tb.connect(src1, head) - tb.connect(head, agc) - tb.connect(agc, dst1) - - tb.run() - dst_data = dst1.data() - self.assertFloatTuplesAlmostEqual(expected_result, dst_data, 4) - - def test_005(self): - ''' Test the complex AGC loop (attack and decay rate inputs) ''' - tb = self.tb - - expected_result = \ - ((100+0j), - (0.8090173602104187 + 0.5877856016159058j), - (0.3090175688266754 + 0.9510582685470581j), - (-0.309017539024353 + 0.9510582089424133j), - (-0.8090170621871948 + 0.5877852439880371j), - (-1.000004529953003 - 4.608183701293456e-08j), - (-0.8090165853500366 - 0.587785005569458j), - (-0.3090173006057739 - 0.9510576725006104j), - (0.3090173900127411 - 0.951057493686676j), - (0.8090166449546814 - 0.5877848863601685j), - (1.0000040531158447 + 9.362654651567937e-08j), - (0.809016227722168 + 0.5877848267555237j), - (0.3090171217918396 + 0.9510573148727417j), - (-0.3090173006057739 + 0.9510571360588074j), - (-0.8090163469314575 + 0.5877846479415894j), - (-1.000003695487976 - 1.39708305368913e-07j), - (-0.8090159296989441 - 0.5877846479415894j), - (-0.30901697278022766 - 0.951056957244873j), - (0.30901727080345154 - 0.9510568976402283j), - (0.809016227722168 - 0.5877844095230103j), - (1.000003457069397 + 1.87252979344521e-07j), - (0.809015691280365 + 0.5877845287322998j), - (0.3090168535709381 + 0.9510567784309387j), - (-0.30901727080345154 + 0.951056718826294j), - (-0.8090161085128784 + 0.5877842903137207j), - (-1.0000033378601074 - 2.3333473109232727e-07j), - (-0.8090156316757202 - 0.5877845287322998j), - (-0.3090168237686157 - 0.9510566592216492j), - (0.3090173006057739 - 0.9510565400123596j), - (0.8090160489082336 - 0.5877842307090759j), - (1.0000032186508179 + 2.8087941927879e-07j), - (0.8090155124664307 + 0.5877845287322998j), - (0.30901676416397095 + 0.9510567784309387j), - (-0.3090173006057739 + 0.9510565400123596j), - (-0.8090160489082336 + 0.5877841711044312j), - (-1.0000033378601074 - 3.2696124208086985e-07j), - (-0.8090155124664307 - 0.5877845883369446j), - (-0.30901673436164856 - 0.9510567784309387j), - (0.3090173602104187 - 0.9510565400123596j), - (0.8090160489082336 - 0.5877841114997864j), - (1.0000033378601074 + 3.745059302673326e-07j), - (0.8090154528617859 + 0.5877846479415894j), - (0.3090166747570038 + 0.9510567784309387j), - (-0.3090174198150635 + 0.9510565400123596j), - (-0.8090161681175232 + 0.5877841114997864j), - (-1.0000032186508179 - 4.2058766780428414e-07j), - (-0.8090154528617859 - 0.5877846479415894j), - (-0.309016615152359 - 0.9510567784309387j), - (0.30901747941970825 - 0.9510564804077148j), - (0.8090161681175232 - 0.5877840518951416j)) - - sampling_freq = 100 - src1 = analog.sig_source_c(sampling_freq, analog.GR_SIN_WAVE, - sampling_freq * 0.10, 100) - dst1 = blocks.vector_sink_c() - head = streamops.head(gr.sizeof_gr_complex, int(5 * sampling_freq * 0.10)) - - agc = analog.agc2_cc(1e-2, 1e-3, 1, 1) - - tb.connect(src1, head) - tb.connect(head, agc) - tb.connect(agc, dst1) - - tb.run() - dst_data = dst1.data() - self.assertComplexTuplesAlmostEqual(expected_result, dst_data, 4) - - def test_006_sets(self): - agc = analog.agc3_cc(1e-3, 1e-1, 1) - - agc.set_attack_rate(1) - agc.set_decay_rate(2) - agc.set_reference(1.1) - agc.set_gain(1.1) - - self.assertAlmostEqual(agc.attack_rate(), 1) - self.assertAlmostEqual(agc.decay_rate(), 2) - self.assertAlmostEqual(agc.reference(), 1.1) - self.assertAlmostEqual(agc.gain(), 1.1) - - def test_006(self): - ''' Test the complex AGC loop (attack and decay rate inputs) ''' - tb = self.tb - - sampling_freq = 100 - N = int(5 * sampling_freq) - src1 = analog.sig_source_c(sampling_freq, analog.GR_SIN_WAVE, - sampling_freq * 0.10, 100) - dst1 = blocks.vector_sink_c() - head = streamops.head(gr.sizeof_gr_complex, N) - - ref = 1 - agc = analog.agc3_cc(1e-2, 1e-3, ref) - - tb.connect(src1, head) - tb.connect(head, agc) - tb.connect(agc, dst1) - - tb.run() - dst_data = dst1.data() - M = 100 - result = [abs(x) for x in dst_data[N - M:]] - self.assertFloatTuplesAlmostEqual(result, M * [ref, ], 4) - - def test_100(self): - ''' Test complex feedforward agc with constant input ''' - - length = 8 - gain = 2 - - input_data = 8 * (0.0,) + 24 * (1.0,) + 24 * (0.0,) - expected_result = (8 + length - 1) * (0.0,) + 24 * (gain * 1.0,) + (0,) - - src = blocks.vector_source_c(input_data) - agc = analog.feedforward_agc_cc(8, 2.0) - dst = blocks.vector_sink_c() - self.tb.connect(src, agc, dst) - - self.tb.run() - dst_data = dst.data()[0:len(expected_result)] - - self.assertComplexTuplesAlmostEqual(expected_result, dst_data, 4) - - -if __name__ == '__main__': - gr_unittest.run(test_agc) diff --git a/blocklib/analog/test/qa_noise.py b/blocklib/analog/test/qa_noise.py deleted file mode 100644 index 282656a99..000000000 --- a/blocklib/analog/test/qa_noise.py +++ /dev/null @@ -1,40 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright 2007,2010,2012 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, analog - - -class test_noise_source(gr_unittest.TestCase): - - def setUp(self): - self.tb = gr.top_block() - - def tearDown(self): - self.tb = None - - def test_001(self): - # Just confirm that we can instantiate a noise source - op = analog.noise_source_f(analog.noise_t.GAUSSIAN, 10, 10) - - def test_002(self): - # Test get methods - set_type = analog.noise_t.GAUSSIAN - set_ampl = 10 - op = analog.noise_source_f(set_type, set_ampl, 10) - get_type = op.type() - get_ampl = op.amplitude() - - self.assertEqual(get_type, set_type) - self.assertEqual(get_ampl, set_ampl) - - -if __name__ == '__main__': - gr_unittest.run(test_noise_source) diff --git a/blocklib/analog/test/qa_quadrature_demod.py b/blocklib/analog/test/qa_quadrature_demod.py deleted file mode 100644 index f8b955014..000000000 --- a/blocklib/analog/test/qa_quadrature_demod.py +++ /dev/null @@ -1,55 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright 2012,2013 Free Software Foundation, Inc. -# -# This file is part of GNU Radio -# -# SPDX-License-Identifier: GPL-3.0-or-later -# -# - - -import cmath - -from gnuradio import gr, gr_unittest, analog, blocks - - -class test_quadrature_demod(gr_unittest.TestCase): - - def setUp(self): - self.tb = gr.top_block() - - def tearDown(self): - self.tb = None - - def test_quad_demod_001(self): - f = 1000.0 - fs = 8000.0 - - src_data = [] - for i in range(200): - ti = i / fs - src_data.append(cmath.exp(2j * cmath.pi * f * ti)) - - src_data = [0, ] + src_data # to account for history - - # f/fs is a quarter turn per sample. - # Set the gain based on this to get 1 out. - gain = 1.0 / (cmath.pi / 4) - - expected_result = [0, ] + 199 * [1.0] - - src = blocks.vector_source_c(src_data) - op = analog.quadrature_demod(gain) - dst = blocks.vector_sink_f() - - self.tb.connect(src, op) - self.tb.connect(op, dst) - self.tb.run() - - result_data = dst.data() - self.assertComplexTuplesAlmostEqual(expected_result, result_data, 5) - - -if __name__ == '__main__': - gr_unittest.run(test_quadrature_demod) diff --git a/blocklib/analog/test/qa_sig_source.py b/blocklib/analog/test/qa_sig_source.py deleted file mode 100644 index 45e479889..000000000 --- a/blocklib/analog/test/qa_sig_source.py +++ /dev/null @@ -1,224 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright 2004, 2007, 2010, 2012, 2013, 2020 Free Software Foundation, Inc. -# -# This file is part of GNU Radio -# -# SPDX-License-Identifier: GPL-3.0-or-later -# -# - - -import math -# import pmt -from gnuradio import gr, gr_unittest, analog, blocks, streamops - - -class test_sig_source(gr_unittest.TestCase): - def setUp(self): - self.tb = gr.top_block() - - def tearDown(self): - self.tb = None - - def test_const_f(self): - tb = self.tb - expected_result = [1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5] - src1 = analog.sig_source_f(1e6, analog.waveform_t.CONSTANT, 0, 1.5) - op = streamops.head(10) - dst1 = blocks.vector_sink_f() - tb.connect(src1, op) - tb.connect(op, dst1) - tb.run() - dst_data = dst1.data() - self.assertEqual(expected_result, dst_data) - - def test_const_i(self): - tb = self.tb - expected_result = [1, 1, 1, 1] - src1 = analog.sig_source_i(1e6, analog.waveform_t.CONSTANT, 0, 1) - op = streamops.head(4) - dst1 = blocks.vector_sink_i() - tb.connect(src1, op) - tb.connect(op, dst1) - tb.run() - dst_data = dst1.data() - self.assertEqual(expected_result, dst_data) - - def test_const_b(self): - tb = self.tb - expected_result = [1, 1, 1, 1] - src1 = analog.sig_source_b(1e6, analog.waveform_t.CONSTANT, 0, 1) - op = streamops.head(4) - dst1 = blocks.vector_sink_b() - tb.connect(src1, op) - tb.connect(op, dst1) - tb.run() - dst_data = dst1.data() - self.assertEqual(expected_result, dst_data) - - def test_sine_f(self): - tb = self.tb - sqrt2 = math.sqrt(2) / 2 - expected_result = [0, sqrt2, 1, sqrt2, 0, -sqrt2, -1, -sqrt2, 0] - src1 = analog.sig_source_f(8, analog.waveform_t.SIN, 1.0, 1.0) - op = streamops.head(9) - dst1 = blocks.vector_sink_f() - tb.connect(src1, op) - tb.connect(op, dst1) - tb.run() - dst_data = dst1.data() - self.assertFloatTuplesAlmostEqual(expected_result, dst_data, 5) - - def test_sine_b(self): - tb = self.tb - sqrt2 = math.sqrt(2) / 2 - temp_result = [0, sqrt2, 1, sqrt2, 0, -sqrt2, -1, -sqrt2, 0] - amp = 8 - expected_result = tuple([int(z * amp) for z in temp_result]) - src1 = analog.sig_source_b(8, analog.waveform_t.SIN, 1.0, amp) - op = streamops.head(9) - dst1 = blocks.vector_sink_b() - tb.connect(src1, op) - tb.connect(op, dst1) - tb.run() - dst_data = dst1.data() - # Let the python know we are dealing with signed int behind scenes - dst_data_signed = [b if b < 127 else (256 - b) * -1 for b in dst_data] - self.assertFloatTuplesAlmostEqual(expected_result, dst_data_signed) - - def test_cosine_f(self): - tb = self.tb - sqrt2 = math.sqrt(2) / 2 - expected_result = [1, sqrt2, 0, -sqrt2, -1, -sqrt2, 0, sqrt2, 1] - src1 = analog.sig_source_f(8, analog.waveform_t.COS, 1.0, 1.0) - op = streamops.head(9) - dst1 = blocks.vector_sink_f() - tb.connect(src1, op) - tb.connect(op, dst1) - tb.run() - dst_data = dst1.data() - self.assertFloatTuplesAlmostEqual(expected_result, dst_data, 5) - - def test_cosine_c(self): - tb = self.tb - sqrt2 = math.sqrt(2) / 2 - sqrt2j = 1j * math.sqrt(2) / 2 - expected_result = [ - 1, sqrt2 + sqrt2j, 1j, -sqrt2 + sqrt2j, -1, -sqrt2 - sqrt2j, -1j, - sqrt2 - sqrt2j, 1 - ] - src1 = analog.sig_source_c(8, analog.waveform_t.COS, 1.0, 1.0) - op = streamops.head(9) - dst1 = blocks.vector_sink_c() - tb.connect(src1, op) - tb.connect(op, dst1) - tb.run() - dst_data = dst1.data() - self.assertFloatTuplesAlmostEqual(expected_result, dst_data, 5) - - def test_sqr_c(self): - tb = self.tb # arg6 is a bit before -PI/2 - expected_result = [1j, 1j, 0, 0, 1, 1, 1 + 0j, 1 + 1j, 1j] - src1 = analog.sig_source_c(8, analog.waveform_t.SQUARE, 1.0, 1.0) - op = streamops.head(9) - dst1 = blocks.vector_sink_c() - tb.connect(src1, op) - tb.connect(op, dst1) - tb.run() - dst_data = dst1.data() - self.assertEqual(expected_result, dst_data) - - def test_tri_c(self): - tb = self.tb - expected_result = [ - 1 + .5j, .75 + .75j, .5 + 1j, .25 + .75j, 0 + .5j, .25 + .25j, - .5 + 0j, .75 + .25j, 1 + .5j - ] - src1 = analog.sig_source_c(8, analog.waveform_t.TRIANGLE, 1.0, 1.0) - op = streamops.head(9) - dst1 = blocks.vector_sink_c() - tb.connect(src1, op) - tb.connect(op, dst1) - tb.run() - dst_data = dst1.data() - self.assertComplexTuplesAlmostEqual(expected_result, dst_data, 5) - - def test_saw_c(self): - tb = self.tb - expected_result = [ - .5 + .25j, .625 + .375j, .75 + .5j, .875 + .625j, 0 + .75j, - .125 + .875j, .25 + 1j, .375 + .125j, .5 + .25j - ] - src1 = analog.sig_source_c(8, analog.waveform_t.SAWTOOTH, 1.0, 1.0) - op = streamops.head(9) - dst1 = blocks.vector_sink_c() - tb.connect(src1, op) - tb.connect(op, dst1) - tb.run() - dst_data = dst1.data() - self.assertComplexTuplesAlmostEqual(expected_result, dst_data, 5) - - def test_sqr_f(self): - tb = self.tb - expected_result = [0, 0, 0, 0, 1, 1, 1, 1, 0] - src1 = analog.sig_source_f(8, analog.waveform_t.SQUARE, 1.0, 1.0) - op = streamops.head(9) - dst1 = blocks.vector_sink_f() - tb.connect(src1, op) - tb.connect(op, dst1) - tb.run() - dst_data = dst1.data() - self.assertEqual(expected_result, dst_data) - - def test_tri_f(self): - tb = self.tb - expected_result = [1, .75, .5, .25, 0, .25, .5, .75, 1] - src1 = analog.sig_source_f(8, analog.waveform_t.TRIANGLE, 1.0, 1.0) - op = streamops.head(9) - dst1 = blocks.vector_sink_f() - tb.connect(src1, op) - tb.connect(op, dst1) - tb.run() - dst_data = dst1.data() - self.assertFloatTuplesAlmostEqual(expected_result, dst_data, 5) - - def test_saw_f(self): - tb = self.tb - expected_result = [.5, .625, .75, .875, 0, .125, .25, .375, .5] - src1 = analog.sig_source_f(8, analog.waveform_t.SAWTOOTH, 1.0, 1.0) - op = streamops.head(9) - dst1 = blocks.vector_sink_f() - tb.connect(src1, op) - tb.connect(op, dst1) - tb.run() - dst_data = dst1.data() - self.assertFloatTuplesAlmostEqual(expected_result, dst_data, 5) - - # def test_cmd_msg(self): - # src = analog.sig_source_c(8, analog.GR_SIN_WAVE, 1.0, 1.0) - # op = streamops.head(gr.sizeof_gr_complex, 9) - # snk = blocks.vector_sink_c() - # self.tb.connect(src, op, snk) - # self.assertAlmostEqual(src.frequency(), 1.0) - - # frequency = 3.0 - # amplitude = 10 - # offset = -1.0 - - # src._post( - # pmt.to_pmt('cmd'), - # pmt.to_pmt({ - # "freq": frequency, - # "ampl": amplitude, - # "offset": offset - # })) - # self.tb.run() - - # self.assertAlmostEqual(src.frequency(), frequency) - # self.assertAlmostEqual(src.amplitude(), amplitude) - # self.assertAlmostEqual(src.offset(), offset) - - -if __name__ == '__main__': - gr_unittest.run(test_sig_source) diff --git a/blocklib/audio/.gitignore b/blocklib/audio/.gitignore deleted file mode 100644 index 25d053a52..000000000 --- a/blocklib/audio/.gitignore +++ /dev/null @@ -1 +0,0 @@ -meson.build
\ No newline at end of file diff --git a/blocklib/audio/alsa_sink/alsa_sink.yml b/blocklib/audio/alsa_sink/alsa_sink.yml deleted file mode 100644 index 009b0c9b1..000000000 --- a/blocklib/audio/alsa_sink/alsa_sink.yml +++ /dev/null @@ -1,49 +0,0 @@ -module: audio -block: alsa_sink -label: ALSA Sink -blocktype: sync_block -category: '[Core]/Audio' - -# Example Parameters -parameters: -- id: sampling_rate - label: Sampling Rate - dtype: ru32 - settable: false - default: 0 - grc: - hide: part -- id: device_name - label: Device Name - dtype: string - settable: false - grc: - hide: part -- id: num_inputs - label: Num Inputs - dtype: size - settable: false - default: 1 - grc: - hide: part -- id: ok_to_block - label: OK to Block - dtype: bool - settable: false - default: 'true' - grc: - hide: part - -# Example Ports -ports: -- domain: stream - id: in - direction: input - type: rf32 - multiplicity: parameters/num_inputs - -implementations: -- id: cpu -# - id: cuda - -file_format: 1 diff --git a/blocklib/audio/alsa_sink/alsa_sink_cpu.cc b/blocklib/audio/alsa_sink/alsa_sink_cpu.cc deleted file mode 100644 index e396c4e0e..000000000 --- a/blocklib/audio/alsa_sink/alsa_sink_cpu.cc +++ /dev/null @@ -1,521 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2022 Josh Morman - * - * This file is part of GNU Radio - * - * SPDX-License-Identifier: GPL-3.0-or-later - * - */ - -#include "alsa_sink_cpu.h" -#include "alsa_sink_cpu_gen.h" - -#include <chrono> -#include <future> -#include <thread> - -#include <gnuradio/prefs.h> - -namespace gr { -namespace audio { - - -static bool CHATTY_DEBUG = true; - -static snd_pcm_format_t acceptable_formats[] = { - // these are in our preferred order... - SND_PCM_FORMAT_S32, - SND_PCM_FORMAT_S16 -}; - -#define NELEMS(x) (sizeof(x) / sizeof(x[0])) - -static std::string default_device_name() -{ - return prefs::get_string("audio_alsa", "default_output_device", "default"); -} - -static double default_period_time() -{ - return std::max(0.001, prefs::get_double("audio_alsa", "period_time", 0.010)); -} - -static int default_nperiods() -{ - return std::max(2L, prefs::get_long("audio_alsa", "nperiods", 32)); -} - - -alsa_sink_cpu::alsa_sink_cpu(block_args args) - : INHERITED_CONSTRUCTORS, - d_sampling_rate(args.sampling_rate), - d_device_name(args.device_name.empty() ? default_device_name() : args.device_name), - d_nperiods(default_nperiods()), - d_period_time_us((size_t)(default_period_time() * 1e6)), - d_special_case_mono_to_stereo(false), - d_ok_to_block(args.ok_to_block), - d_num_inputs(args.num_inputs) -{ - CHATTY_DEBUG = prefs::get_bool("audio_alsa", "verbose", false); - - int error = -1; - int dir; - - // open the device for playback - int attempts = 10; - while ((error != 0) && (attempts-- > 0)) { - snd_pcm_t* t = nullptr; - error = snd_pcm_open(&t, d_device_name.c_str(), SND_PCM_STREAM_PLAYBACK, 0); - d_pcm_handle.set(t); - if (error < 0) { - std::this_thread::sleep_for(std::chrono::milliseconds(10)); - } - } - if (args.ok_to_block == false) - snd_pcm_nonblock(d_pcm_handle.get(), 1); - if (error < 0) { - d_logger->error("[{:s}]: {:s}", d_device_name, snd_strerror(error)); - throw std::runtime_error("audio_alsa_sink"); - } - - // Fill params with a full configuration space for a PCM. - error = snd_pcm_hw_params_any(d_pcm_handle.get(), d_hw_params.get()); - if (error < 0) - bail("broken configuration for playback", error); - - if (CHATTY_DEBUG) - gri_alsa_dump_hw_params(d_pcm_handle.get(), d_hw_params.get(), stdout); - - // now that we know how many channels the h/w can handle, set input signature - unsigned int umin_chan, umax_chan; - snd_pcm_hw_params_get_channels_min(d_hw_params.get(), &umin_chan); - snd_pcm_hw_params_get_channels_max(d_hw_params.get(), &umax_chan); - unsigned int min_chan = std::min(umin_chan, 1000U); - unsigned int max_chan = std::min(umax_chan, 1000U); - - // As a special case, if the hw's min_chan is two, we'll accept - // a single input and handle the duplication ourselves. - if (min_chan == 2) { - min_chan = 1; - d_special_case_mono_to_stereo = true; - } - - if (args.num_inputs < min_chan) { - throw std::runtime_error(fmt::format( - "Detected hardware requires at least {} input channels", min_chan)); - } - if (args.num_inputs > max_chan) { - throw std::runtime_error(fmt::format( - "Detected hardware supports no more than {} input channels", max_chan)); - } - // fill in portions of the d_hw_params that we know now... - - // Specify the access methods we implement - // For now, we only handle RW_INTERLEAVED... - snd_pcm_access_mask_t* access_mask; - snd_pcm_access_mask_t** access_mask_ptr = - &access_mask; // FIXME: workaround for compiler warning - snd_pcm_access_mask_alloca(access_mask_ptr); - snd_pcm_access_mask_none(access_mask); - snd_pcm_access_mask_set(access_mask, SND_PCM_ACCESS_RW_INTERLEAVED); - // snd_pcm_access_mask_set(access_mask, SND_PCM_ACCESS_RW_NONINTERLEAVED); - - if ((error = snd_pcm_hw_params_set_access_mask( - d_pcm_handle.get(), d_hw_params.get(), access_mask)) < 0) - bail("failed to set access mask", error); - - // set sample format - if (!gri_alsa_pick_acceptable_format(d_pcm_handle.get(), - d_hw_params.get(), - acceptable_formats, - NELEMS(acceptable_formats), - &d_format, - "audio_alsa_sink", - CHATTY_DEBUG)) - throw std::runtime_error("audio_alsa_sink"); - - // sampling rate - unsigned int orig_sampling_rate = d_sampling_rate; - if ((error = snd_pcm_hw_params_set_rate_near( - d_pcm_handle.get(), d_hw_params.get(), &d_sampling_rate, 0)) < 0) - bail("failed to set rate near", error); - - if (orig_sampling_rate != d_sampling_rate) { - d_logger->info("[{:s}]: unable to support sampling rate {:d}\n\tCard " - "requested {:d} instead.", - snd_pcm_name(d_pcm_handle.get()), - orig_sampling_rate, - d_sampling_rate); - } - - /* - * ALSA transfers data in units of "periods". - * We indirectly determine the underlying buffersize by specifying - * the number of periods we want (typically 4) and the length of each - * period in units of time (typically 1ms). - */ - unsigned int min_nperiods, max_nperiods; - snd_pcm_hw_params_get_periods_min(d_hw_params.get(), &min_nperiods, &dir); - snd_pcm_hw_params_get_periods_max(d_hw_params.get(), &max_nperiods, &dir); - - unsigned int orig_nperiods = d_nperiods; - d_nperiods = std::min(std::max(min_nperiods, d_nperiods), max_nperiods); - - // adjust period time so that total buffering remains more-or-less constant - d_period_time_us = (d_period_time_us * orig_nperiods) / d_nperiods; - - error = snd_pcm_hw_params_set_periods( - d_pcm_handle.get(), d_hw_params.get(), d_nperiods, 0); - if (error < 0) - bail("set_periods failed", error); - - dir = 0; - error = snd_pcm_hw_params_set_period_time_near( - d_pcm_handle.get(), d_hw_params.get(), &d_period_time_us, &dir); - if (error < 0) - bail("set_period_time_near failed", error); - - dir = 0; - error = snd_pcm_hw_params_get_period_size(d_hw_params.get(), &d_period_size, &dir); - if (error < 0) - bail("get_period_size failed", error); - - set_output_multiple(d_period_size); -} - -bool alsa_sink_cpu::start() -{ - int nchan = d_num_inputs; - int err; - - // Check the state of the stream - // Ensure that the pcm is in a state where we can still mess with the hw_params - snd_pcm_state_t state; - state = snd_pcm_state(d_pcm_handle.get()); - if (state == SND_PCM_STATE_RUNNING) - return true; // If stream is running, don't change any parameters - else if (state == SND_PCM_STATE_XRUN) - snd_pcm_prepare( - d_pcm_handle.get()); // Prepare stream on underrun, and we can set parameters; - - bool special_case = nchan == 1 && d_special_case_mono_to_stereo; - if (special_case) - nchan = 2; - - err = snd_pcm_hw_params_set_channels(d_pcm_handle.get(), d_hw_params.get(), nchan); - - if (err < 0) { - output_error_msg("set_channels failed", err); - return false; - } - - // set the parameters into the driver... - err = snd_pcm_hw_params(d_pcm_handle.get(), d_hw_params.get()); - if (err < 0) { - output_error_msg("snd_pcm_hw_params failed", err); - return false; - } - - // get current s/w params - err = snd_pcm_sw_params_current(d_pcm_handle.get(), d_sw_params.get()); - if (err < 0) - bail("snd_pcm_sw_params_current", err); - - // Tell the PCM device to wait to start until we've filled - // it's buffers half way full. This helps avoid audio underruns. - - err = snd_pcm_sw_params_set_start_threshold( - d_pcm_handle.get(), d_sw_params.get(), d_nperiods * d_period_size / 2); - if (err < 0) - bail("snd_pcm_sw_params_set_start_threshold", err); - - // store the s/w params - err = snd_pcm_sw_params(d_pcm_handle.get(), d_sw_params.get()); - if (err < 0) - bail("snd_pcm_sw_params", err); - - d_buffer.resize(d_period_size * nchan * snd_pcm_format_size(d_format, 1)); - - if (CHATTY_DEBUG) { - d_debug_logger->debug("[{:s}]: sample resolution = {:d} bits", - snd_pcm_name(d_pcm_handle.get()), - snd_pcm_hw_params_get_sbits(d_hw_params.get())); - } - - switch (d_format) { - case SND_PCM_FORMAT_S16: - if (special_case) { - d_worker = [this](work_io& wio) { return this->work_s16_1x2(wio); }; - } - else { - d_worker = [this](work_io& wio) { return this->work_s16(wio); }; - } - break; - - case SND_PCM_FORMAT_S32: - if (special_case) { - d_worker = [this](work_io& wio) { return this->work_s32_1x2(wio); }; - } - else { - d_worker = [this](work_io& wio) { return this->work_s32(wio); }; - } - break; - - default: - throw std::runtime_error("Unsupported PCM format returned from ALSA"); - } - - return true; -} - -work_return_t alsa_sink_cpu::work(work_io& wio) - -{ - // assert((noutput_items % d_period_size) == 0); - - // this is a call through std::function - return d_worker(wio); -} - - -/* - * Work function that deals with float to S16 conversion - */ -work_return_t alsa_sink_cpu::work_s16(work_io& wio) -{ - typedef int16_t sample_t; // the type of samples we're creating - static const float scale_factor = std::pow(2.0f, 16 - 1) - 1; - - size_t nchan = wio.inputs().size(); - auto noutput_items = wio.min_ninput_items(); - std::vector<const float*> in_ptrs(nchan); - for (size_t i = 0; i < wio.inputs().size(); i++) { - in_ptrs[i] = wio.inputs()[i].items<float>(); - } - auto in = in_ptrs.data(); - sample_t* buf = reinterpret_cast<sample_t*>(d_buffer.data()); - int bi; - size_t n; - - size_t sizeof_frame = nchan * sizeof(sample_t); - assert(d_buffer.size() == d_period_size * sizeof_frame); - - for (n = 0; n < noutput_items; n += d_period_size) { - // process one period of data - bi = 0; - for (size_t i = 0; i < d_period_size; i++) { - for (size_t chan = 0; chan < nchan; chan++) { - buf[bi++] = (sample_t)(in[chan][i] * scale_factor); - } - } - - // update src pointers - for (size_t chan = 0; chan < nchan; chan++) - in[chan] += d_period_size; - - if (!write_buffer(buf, d_period_size, sizeof_frame)) - return work_return_t::DONE; // No fixing this problem. Say - // we're done. - } - - wio.consume_each(n); - return work_return_t::OK; -} - -/* - * Work function that deals with float to S32 conversion - */ -work_return_t alsa_sink_cpu::work_s32(work_io& wio) -{ - typedef int32_t sample_t; // the type of samples we're creating - static const float scale_factor = std::pow(2.0f, 32 - 1) - 1; - - size_t nchan = wio.inputs().size(); - auto noutput_items = wio.min_ninput_items(); - std::vector<const float*> in_ptrs(nchan); - for (size_t i = 0; i < wio.inputs().size(); i++) { - in_ptrs[i] = wio.inputs()[i].items<float>(); - } - auto in = in_ptrs.data(); - sample_t* buf = reinterpret_cast<sample_t*>(d_buffer.data()); - int bi; - size_t n; - - size_t sizeof_frame = nchan * sizeof(sample_t); - assert(d_buffer.size() == d_period_size * sizeof_frame); - - for (n = 0; n < noutput_items; n += d_period_size) { - // process one period of data - bi = 0; - for (size_t i = 0; i < d_period_size; i++) { - for (size_t chan = 0; chan < nchan; chan++) { - buf[bi++] = (sample_t)(in[chan][i] * scale_factor); - } - } - - // update src pointers - for (size_t chan = 0; chan < nchan; chan++) - in[chan] += d_period_size; - - if (!write_buffer(buf, d_period_size, sizeof_frame)) - return work_return_t::DONE; // No fixing this problem. Say - // we're done. - } - - wio.consume_each(n); - return work_return_t::OK; -} - -/* - * Work function that deals with float to S16 conversion and - * mono to stereo kludge. - */ -work_return_t alsa_sink_cpu::work_s16_1x2(work_io& wio) -{ - typedef int16_t sample_t; // the type of samples we're creating - static const float scale_factor = std::pow(2.0f, 16 - 1) - 1; - - assert(wio.inputs().size() == 1); - static const size_t nchan = 2; - auto noutput_items = wio.min_ninput_items(); - std::vector<const float*> in_ptrs(nchan); - for (size_t i = 0; i < wio.inputs().size(); i++) { - in_ptrs[i] = wio.inputs()[i].items<float>(); - } - auto in = in_ptrs.data(); - sample_t* buf = reinterpret_cast<sample_t*>(d_buffer.data()); - int bi; - size_t n; - - size_t sizeof_frame = nchan * sizeof(sample_t); - assert(d_buffer.size() == d_period_size * sizeof_frame); - - for (n = 0; n < noutput_items; n += d_period_size) { - // process one period of data - bi = 0; - for (size_t i = 0; i < d_period_size; i++) { - sample_t t = (sample_t)(in[0][i] * scale_factor); - buf[bi++] = t; - buf[bi++] = t; - } - - // update src pointers - in[0] += d_period_size; - - if (!write_buffer(buf, d_period_size, sizeof_frame)) - return work_return_t::DONE; // No fixing this problem. Say - // we're done. - } - - wio.consume_each(n); - return work_return_t::OK; -} - -/* - * Work function that deals with float to S32 conversion and - * mono to stereo kludge. - */ -work_return_t alsa_sink_cpu::work_s32_1x2(work_io& wio) -{ - typedef int32_t sample_t; // the type of samples we're creating - static const float scale_factor = std::pow(2.0f, 32 - 1) - 1; - - static size_t nchan = 2; - auto noutput_items = wio.min_ninput_items(); - std::vector<const float*> in_ptrs(nchan); - for (size_t i = 0; i < wio.inputs().size(); i++) { - in_ptrs[i] = wio.inputs()[i].items<float>(); - } - auto in = in_ptrs.data(); - sample_t* buf = reinterpret_cast<sample_t*>(d_buffer.data()); - int bi; - size_t n; - - size_t sizeof_frame = nchan * sizeof(sample_t); - assert(d_buffer.size() == d_period_size * sizeof_frame); - - for (n = 0; n < noutput_items; n += d_period_size) { - // process one period of data - bi = 0; - for (size_t i = 0; i < d_period_size; i++) { - sample_t t = (sample_t)(in[0][i] * scale_factor); - buf[bi++] = t; - buf[bi++] = t; - } - - // update src pointers - in[0] += d_period_size; - - if (!write_buffer(buf, d_period_size, sizeof_frame)) - return work_return_t::DONE; // No fixing this problem. Say - // we're done. - } - - wio.consume_each(n); - return work_return_t::OK; -} - -bool alsa_sink_cpu::write_buffer(const void* vbuffer, - unsigned nframes, - unsigned sizeof_frame) -{ - const unsigned char* buffer = (const unsigned char*)vbuffer; - - while (nframes > 0) { - int r = snd_pcm_writei(d_pcm_handle.get(), buffer, nframes); - if (r == -EAGAIN) { - if (d_ok_to_block == true) - continue; // try again - break; - } - else if (r == -EPIPE) { // underrun - d_nunderuns++; - // we need to have an lvalue, async pitfall! - auto future_local = std::async(::fputs, "aU", stderr); - - if ((r = snd_pcm_prepare(d_pcm_handle.get())) < 0) { - output_error_msg("snd_pcm_prepare failed. Can't recover from underrun", - r); - return false; - } - continue; // try again - } -#ifdef ESTRPIPE - else if (r == -ESTRPIPE) { // h/w is suspended (whatever that means) - // This is apparently related to power management - d_nsuspends++; - if ((r = snd_pcm_resume(d_pcm_handle.get())) < 0) { - output_error_msg("failed to resume from suspend", r); - return false; - } - continue; // try again - } -#endif - else if (r < 0) { - output_error_msg("snd_pcm_writei failed", r); - return false; - } - - nframes -= r; - buffer += r * sizeof_frame; - } - - return true; -} - -void alsa_sink_cpu::output_error_msg(const char* msg, int err) -{ - d_logger->error( - "[{:s}]: {:s}: {:s}", snd_pcm_name(d_pcm_handle.get()), msg, snd_strerror(err)); -} - -void alsa_sink_cpu::bail(const char* msg, int err) -{ - output_error_msg(msg, err); - throw std::runtime_error("audio_alsa_sink"); -} - - -} // namespace audio -} // namespace gr
\ No newline at end of file diff --git a/blocklib/audio/alsa_sink/alsa_sink_cpu.h b/blocklib/audio/alsa_sink/alsa_sink_cpu.h deleted file mode 100644 index fdbd13325..000000000 --- a/blocklib/audio/alsa_sink/alsa_sink_cpu.h +++ /dev/null @@ -1,68 +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 "../lib/alsa_internal.h" -#include <gnuradio/audio/alsa_sink.h> - -#include <functional> - -namespace gr { -namespace audio { - -class alsa_sink_cpu : public virtual alsa_sink -{ -public: - alsa_sink_cpu(block_args args); - work_return_t work(work_io&) override; - -private: - // TODO: change to std::function - - - unsigned int d_sampling_rate; - std::string d_device_name; - alsa_internal::sndpcm_wrap d_pcm_handle; - alsa_internal::hwparam_wrap d_hw_params; - alsa_internal::swparam_wrap d_sw_params; - snd_pcm_format_t d_format; - unsigned int d_nperiods; - unsigned int d_period_time_us; // microseconds - snd_pcm_uframes_t d_period_size = 0; // in frames - std::vector<char> d_buffer; - work_t d_worker = nullptr; // the work method to use - bool d_special_case_mono_to_stereo; - - // random stats - int d_nunderuns = 0; // count of underruns - int d_nsuspends = 0; // count of suspends - bool d_ok_to_block; // defaults to "true", controls blocking/non-block I/O - size_t d_num_inputs; - - void output_error_msg(const char* msg, int err); - void bail(const char* msg, int err); - - bool start() override; - -protected: - bool write_buffer(const void* buffer, unsigned nframes, unsigned sizeof_frame); - - work_return_t work_s16(work_io& wio); - - work_return_t work_s16_1x2(work_io& wio); - - work_return_t work_s32(work_io& wio); - - work_return_t work_s32_1x2(work_io& wio); -}; - -} // namespace audio -} // namespace gr
\ No newline at end of file diff --git a/blocklib/audio/examples/.gitignore b/blocklib/audio/examples/.gitignore deleted file mode 100644 index f104652b6..000000000 --- a/blocklib/audio/examples/.gitignore +++ /dev/null @@ -1 +0,0 @@ -*.py diff --git a/blocklib/audio/examples/alsa_tones.grc b/blocklib/audio/examples/alsa_tones.grc deleted file mode 100644 index 6d319df9e..000000000 --- a/blocklib/audio/examples/alsa_tones.grc +++ /dev/null @@ -1,154 +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: alsa_tones - 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_sig_source_0 - id: analog_sig_source - parameters: - T: float - affinity: '' - alias: '' - ampl: '0.25' - comment: '' - domain: cpu - frequency: '440' - 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: [344, 324.0] - rotation: 0 - state: enabled -- name: analog_sig_source_0_0 - id: analog_sig_source - parameters: - T: float - affinity: '' - alias: '' - ampl: '0.25' - comment: '' - domain: cpu - frequency: '554.4' - 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: [336, 132.0] - rotation: 0 - state: true -- name: audio_alsa_sink_0 - id: audio_alsa_sink - parameters: - affinity: '' - alias: '' - comment: '' - device_name: '"pulse"' - domain: cpu - num_inputs: '1' - ok_to_block: 'True' - sampling_rate: samp_rate - showports: 'False' - states: - bus_sink: false - bus_source: false - bus_structure: null - coordinate: [872, 292.0] - rotation: 0 - state: true -- name: import_0 - id: import - parameters: - alias: '' - comment: '' - imports: from gnuradio import analog - states: - bus_sink: false - bus_source: false - bus_structure: null - coordinate: [296, 12.0] - rotation: 0 - state: true -- name: math_add_0 - id: math_add - parameters: - T: float - affinity: '' - alias: '' - comment: '' - domain: cpu - maxoutbuf: '0' - minoutbuf: '0' - nports: '2' - showports: 'False' - vlen: '1' - states: - bus_sink: false - bus_source: false - bus_structure: null - coordinate: [664, 304.0] - rotation: 0 - state: enabled - -connections: -- [analog_sig_source_0, '0', math_add_0, '1'] -- [analog_sig_source_0_0, '0', math_add_0, '0'] -- [math_add_0, '0', audio_alsa_sink_0, '0'] - -metadata: - file_format: 1 diff --git a/blocklib/audio/include/gnuradio/audio/.gitignore b/blocklib/audio/include/gnuradio/audio/.gitignore deleted file mode 100644 index 01ecb66ff..000000000 --- a/blocklib/audio/include/gnuradio/audio/.gitignore +++ /dev/null @@ -1 +0,0 @@ -!meson.build
\ No newline at end of file diff --git a/blocklib/audio/include/gnuradio/audio/meson.build b/blocklib/audio/include/gnuradio/audio/meson.build deleted file mode 100644 index 80941fc75..000000000 --- a/blocklib/audio/include/gnuradio/audio/meson.build +++ /dev/null @@ -1,3 +0,0 @@ -headers = [] - -install_headers(headers, subdir : 'gnuradio/audio')
\ No newline at end of file diff --git a/blocklib/audio/lib/.gitignore b/blocklib/audio/lib/.gitignore deleted file mode 100644 index 01ecb66ff..000000000 --- a/blocklib/audio/lib/.gitignore +++ /dev/null @@ -1 +0,0 @@ -!meson.build
\ No newline at end of file diff --git a/blocklib/audio/lib/alsa_internal.cc b/blocklib/audio/lib/alsa_internal.cc deleted file mode 100644 index 793d0d0fe..000000000 --- a/blocklib/audio/lib/alsa_internal.cc +++ /dev/null @@ -1,172 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2004 Free Software Foundation, Inc. - * - * This file is part of GNU Radio - * - * SPDX-License-Identifier: GPL-3.0-or-later - * - */ - -#ifdef HAVE_CONFIG_H -#warning "ALSA CONFIG H" -#include "config.h" -#endif - -#include <gnuradio/logger.h> - -#include "alsa_internal.h" - -#include <algorithm> - -static snd_pcm_access_t access_types[] = { SND_PCM_ACCESS_MMAP_INTERLEAVED, - SND_PCM_ACCESS_MMAP_NONINTERLEAVED, - SND_PCM_ACCESS_MMAP_COMPLEX, - SND_PCM_ACCESS_RW_INTERLEAVED, - SND_PCM_ACCESS_RW_NONINTERLEAVED }; - -static snd_pcm_format_t format_types[] = { - // SND_PCM_FORMAT_UNKNOWN, - SND_PCM_FORMAT_S8, - SND_PCM_FORMAT_U8, - SND_PCM_FORMAT_S16_LE, - SND_PCM_FORMAT_S16_BE, - SND_PCM_FORMAT_U16_LE, - SND_PCM_FORMAT_U16_BE, - SND_PCM_FORMAT_S24_LE, - SND_PCM_FORMAT_S24_BE, - SND_PCM_FORMAT_U24_LE, - SND_PCM_FORMAT_U24_BE, - SND_PCM_FORMAT_S32_LE, - SND_PCM_FORMAT_S32_BE, - SND_PCM_FORMAT_U32_LE, - SND_PCM_FORMAT_U32_BE, - SND_PCM_FORMAT_FLOAT_LE, - SND_PCM_FORMAT_FLOAT_BE, - SND_PCM_FORMAT_FLOAT64_LE, - SND_PCM_FORMAT_FLOAT64_BE, - SND_PCM_FORMAT_IEC958_SUBFRAME_LE, - SND_PCM_FORMAT_IEC958_SUBFRAME_BE, - SND_PCM_FORMAT_MU_LAW, - SND_PCM_FORMAT_A_LAW, - SND_PCM_FORMAT_IMA_ADPCM, - SND_PCM_FORMAT_MPEG, - SND_PCM_FORMAT_GSM, - SND_PCM_FORMAT_SPECIAL, - SND_PCM_FORMAT_S24_3LE, - SND_PCM_FORMAT_S24_3BE, - SND_PCM_FORMAT_U24_3LE, - SND_PCM_FORMAT_U24_3BE, - SND_PCM_FORMAT_S20_3LE, - SND_PCM_FORMAT_S20_3BE, - SND_PCM_FORMAT_U20_3LE, - SND_PCM_FORMAT_U20_3BE, - SND_PCM_FORMAT_S18_3LE, - SND_PCM_FORMAT_S18_3BE, - SND_PCM_FORMAT_U18_3LE, - SND_PCM_FORMAT_U18_3BE -}; - -static unsigned int test_rates[] = { 8000, 16000, 22050, 32000, - 44100, 48000, 96000, 192000 }; - -#define NELEMS(x) (sizeof(x) / sizeof(x[0])) - -void gri_alsa_dump_hw_params(snd_pcm_t* pcm, snd_pcm_hw_params_t* hwparams, FILE* fp) -{ - fprintf(fp, "PCM name: %s\n", snd_pcm_name(pcm)); - - fprintf(fp, "Access types:\n"); - for (unsigned i = 0; i < NELEMS(access_types); i++) { - snd_pcm_access_t at = access_types[i]; - fprintf(fp, - " %-20s %s\n", - snd_pcm_access_name(at), - snd_pcm_hw_params_test_access(pcm, hwparams, at) == 0 ? "YES" : "NO"); - } - - fprintf(fp, "Formats:\n"); - for (unsigned i = 0; i < NELEMS(format_types); i++) { - snd_pcm_format_t ft = format_types[i]; - if (0) - fprintf(fp, - " %-20s %s\n", - snd_pcm_format_name(ft), - snd_pcm_hw_params_test_format(pcm, hwparams, ft) == 0 ? "YES" : "NO"); - else { - if (snd_pcm_hw_params_test_format(pcm, hwparams, ft) == 0) - fprintf(fp, " %-20s YES\n", snd_pcm_format_name(ft)); - } - } - - fprintf(fp, "Number of channels\n"); - unsigned int min_chan, max_chan; - snd_pcm_hw_params_get_channels_min(hwparams, &min_chan); - snd_pcm_hw_params_get_channels_max(hwparams, &max_chan); - fprintf(fp, " min channels: %d\n", min_chan); - fprintf(fp, " max channels: %d\n", max_chan); - unsigned int chan; - max_chan = std::min(max_chan, 16U); // truncate display... - for (chan = min_chan; chan <= max_chan; chan++) { - fprintf(fp, - " %d channels\t%s\n", - chan, - snd_pcm_hw_params_test_channels(pcm, hwparams, chan) == 0 ? "YES" : "NO"); - } - - fprintf(fp, "Sample Rates:\n"); - unsigned int min_rate, max_rate; - int min_dir, max_dir; - - snd_pcm_hw_params_get_rate_min(hwparams, &min_rate, &min_dir); - snd_pcm_hw_params_get_rate_max(hwparams, &max_rate, &max_dir); - fprintf(fp, " min rate: %7d (dir = %d)\n", min_rate, min_dir); - fprintf(fp, " max rate: %7d (dir = %d)\n", max_rate, max_dir); - for (unsigned i = 0; i < NELEMS(test_rates); i++) { - unsigned int rate = test_rates[i]; - fprintf(fp, - " %6u %s\n", - rate, - snd_pcm_hw_params_test_rate(pcm, hwparams, rate, 0) == 0 ? "YES" : "NO"); - } - - fflush(fp); -} - -bool gri_alsa_pick_acceptable_format(snd_pcm_t* pcm, - snd_pcm_hw_params_t* hwparams, - snd_pcm_format_t acceptable_formats[], - unsigned nacceptable_formats, - snd_pcm_format_t* selected_format, - const char* error_msg_tag, - bool verbose) -{ - int err; - gr::logger_ptr logger, debug_logger; - gr::configure_default_loggers( - logger, debug_logger, "gri_alsa_pick_acceptable_format"); - - // pick a format that we like... - for (unsigned i = 0; i < nacceptable_formats; i++) { - if (snd_pcm_hw_params_test_format(pcm, hwparams, acceptable_formats[i]) == 0) { - err = snd_pcm_hw_params_set_format(pcm, hwparams, acceptable_formats[i]); - if (err < 0) { - logger->error("{:s}[{:s}]: failed to set format: {:s}", - error_msg_tag, - snd_pcm_name(pcm), - snd_strerror(err)); - return false; - } - debug_logger->info("{:s}[{:s}]: using {:s}", - error_msg_tag, - snd_pcm_name(pcm), - snd_pcm_format_name(acceptable_formats[i])); - *selected_format = acceptable_formats[i]; - return true; - } - } - - logger->error( - "{:s}[{:s}]: failed to find acceptable format", error_msg_tag, snd_pcm_name(pcm)); - return false; -} diff --git a/blocklib/audio/lib/alsa_internal.h b/blocklib/audio/lib/alsa_internal.h deleted file mode 100644 index 0147cb1b6..000000000 --- a/blocklib/audio/lib/alsa_internal.h +++ /dev/null @@ -1,89 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2004 Free Software Foundation, Inc. - * - * This file is part of GNU Radio - * - * SPDX-License-Identifier: GPL-3.0-or-later - * - */ - -#pragma once - -#include <alsa/asoundlib.h> -#include <cstdio> -#include <stdexcept> - -void gri_alsa_dump_hw_params(snd_pcm_t* pcm, snd_pcm_hw_params_t* hwparams, FILE* fp); - -bool gri_alsa_pick_acceptable_format(snd_pcm_t* pcm, - snd_pcm_hw_params_t* hwparams, - snd_pcm_format_t acceptable_formats[], - unsigned nacceptable_formats, - snd_pcm_format_t* selected_format, - const char* error_msg_tag, - bool verbose); - -namespace gr { -namespace audio { -namespace alsa_internal { -// hw/sw params RAII wrapper. -template <typename T, int Alloc(T**), void Free(T*)> -class param_wrap -{ -public: - param_wrap() - { - const int err = Alloc(&d_param); - if (err) { - throw std::runtime_error("failed to allocate ALSA params. Error code " + - std::to_string(err)); - } - } - param_wrap(const param_wrap&) = delete; - param_wrap& operator=(const param_wrap&) = delete; - T* get() { return d_param; } - ~param_wrap() { Free(d_param); } - -private: - T* d_param = nullptr; -}; -typedef param_wrap<snd_pcm_hw_params_t, snd_pcm_hw_params_malloc, snd_pcm_hw_params_free> - hwparam_wrap; -typedef param_wrap<snd_pcm_sw_params_t, snd_pcm_sw_params_malloc, snd_pcm_sw_params_free> - swparam_wrap; - -class sndpcm_wrap -{ -public: - sndpcm_wrap(snd_pcm_t* in = nullptr) : d_pcm_handle(in) {} - sndpcm_wrap(const sndpcm_wrap&) = delete; - sndpcm_wrap(sndpcm_wrap&&) = delete; - sndpcm_wrap& operator=(const sndpcm_wrap&) = delete; - sndpcm_wrap& operator=(sndpcm_wrap&&) = delete; - ~sndpcm_wrap() { close(); } - void close() - { - if (d_pcm_handle == nullptr) { - return; - } - if (snd_pcm_state(d_pcm_handle) == SND_PCM_STATE_RUNNING) { - snd_pcm_drop(d_pcm_handle); - } - snd_pcm_close(d_pcm_handle); - d_pcm_handle = nullptr; - } - void set(snd_pcm_t* ptr) - { - close(); - d_pcm_handle = ptr; - } - snd_pcm_t* get() noexcept { return d_pcm_handle; } - -private: - snd_pcm_t* d_pcm_handle; -}; - -} // namespace alsa_internal -} // namespace audio -} // namespace gr diff --git a/blocklib/audio/lib/meson.build b/blocklib/audio/lib/meson.build deleted file mode 100644 index d0530e463..000000000 --- a/blocklib/audio/lib/meson.build +++ /dev/null @@ -1,42 +0,0 @@ -audio_sources += [ - 'alsa_internal.cc' -] - -alsa_dep = dependency('alsa', required: true) - -audio_deps += [gnuradio_gr_dep, volk_dep, fmt_dep, pmtf_dep, alsa_dep] - -block_cpp_args = ['-DHAVE_CPU'] - -incdir = include_directories(['../include/gnuradio/audio','../include']) -gnuradio_blocklib_audio_lib = library('gnuradio-blocklib-audio', - audio_sources, - include_directories : incdir, - install : true, - link_language: 'cpp', - dependencies : audio_deps, - cpp_args : block_cpp_args) - -gnuradio_blocklib_audio_dep = declare_dependency(include_directories : incdir, - link_with : gnuradio_blocklib_audio_lib, - dependencies : audio_deps) - -cmake_conf = configuration_data() -cmake_conf.set('libdir', join_paths(prefix,get_option('libdir'))) -cmake_conf.set('module', 'audio') -cmake.configure_package_config_file( - name : 'gnuradio-audio', - 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_audio_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-audio', - filebase : 'gnuradio-audio', - description : 'GNU Radio Audio Module') diff --git a/blocklib/audio/python/gnuradio/audio/.gitignore b/blocklib/audio/python/gnuradio/audio/.gitignore deleted file mode 100644 index 25d053a52..000000000 --- a/blocklib/audio/python/gnuradio/audio/.gitignore +++ /dev/null @@ -1 +0,0 @@ -meson.build
\ No newline at end of file diff --git a/blocklib/audio/python/gnuradio/audio/__init__.py b/blocklib/audio/python/gnuradio/audio/__init__.py deleted file mode 100644 index e87741f28..000000000 --- a/blocklib/audio/python/gnuradio/audio/__init__.py +++ /dev/null @@ -1,9 +0,0 @@ - -import os - -try: - from .audio_python import * -except ImportError: - dirname, filename = os.path.split(os.path.abspath(__file__)) - __path__.append(os.path.join(dirname, "bindings")) - from .audio_python import * diff --git a/blocklib/audio/test/.gitignore b/blocklib/audio/test/.gitignore deleted file mode 100644 index d53050d7d..000000000 --- a/blocklib/audio/test/.gitignore +++ /dev/null @@ -1 +0,0 @@ -!meson.build diff --git a/blocklib/audio/test/meson.build b/blocklib/audio/test/meson.build deleted file mode 100644 index a3efa7246..000000000 --- a/blocklib/audio/test/meson.build +++ /dev/null @@ -1,3 +0,0 @@ -################################################### -# QA -################################################### diff --git a/blocklib/blocks/nop_source/nop_source.yml b/blocklib/blocks/nop_source/nop_source.yml deleted file mode 100644 index a3b3a04de..000000000 --- a/blocklib/blocks/nop_source/nop_source.yml +++ /dev/null @@ -1,33 +0,0 @@ -module: blocks -block: nop_source -label: Nop Source -blocktype: sync_block -category: '[Core]/Debug Tools' - -parameters: -- id: nports - label: Num. Ports - dtype: size - default: 1 - settable: false -- id: itemsize - label: Item Size - dtype: size - settable: false - default: 0 - grc: - hide: part - -ports: -- domain: stream - id: out - direction: output - type: untyped - size: parameters/itemsize - multiplicity: parameters/nports - -implementations: -- id: cpu -# - id: cuda - -file_format: 1 diff --git a/blocklib/blocks/nop_source/nop_source_cpu.cc b/blocklib/blocks/nop_source/nop_source_cpu.cc deleted file mode 100644 index 3dd30fe6f..000000000 --- a/blocklib/blocks/nop_source/nop_source_cpu.cc +++ /dev/null @@ -1,29 +0,0 @@ -/* -*- c++ -*- */ -/* - * This file is part of GNU Radio - * - * SPDX-License-Identifier: GPL-3.0-or-later - * - */ - -#include "nop_source_cpu.h" -#include "nop_source_cpu_gen.h" - -namespace gr { -namespace blocks { - -nop_source_cpu::nop_source_cpu(block_args args) : INHERITED_CONSTRUCTORS {} - -work_return_t nop_source_cpu::work(work_io& wio) -{ - for (auto& out : wio.outputs()) { - auto noutput_items = out.n_items; - out.n_produced = noutput_items; - } - - return work_return_t::OK; -} - - -} // namespace blocks -} // namespace gr
\ No newline at end of file diff --git a/blocklib/blocks/nop_source/nop_source_cpu.h b/blocklib/blocks/nop_source/nop_source_cpu.h deleted file mode 100644 index 9daef2d64..000000000 --- a/blocklib/blocks/nop_source/nop_source_cpu.h +++ /dev/null @@ -1,27 +0,0 @@ -/* -*- c++ -*- */ -/* - * This file is part of GNU Radio - * - * SPDX-License-Identifier: GPL-3.0-or-later - * - */ - -#pragma once - -#include <gnuradio/blocks/nop_source.h> - -namespace gr { -namespace blocks { - -class nop_source_cpu : public nop_source -{ -public: - nop_source_cpu(block_args args); - work_return_t work(work_io&) override; - -protected: - size_t d_nports; -}; - -} // namespace blocks -} // namespace gr diff --git a/blocklib/fec/include/gnuradio/fec/.gitignore b/blocklib/fec/include/gnuradio/fec/.gitignore deleted file mode 100644 index d53050d7d..000000000 --- a/blocklib/fec/include/gnuradio/fec/.gitignore +++ /dev/null @@ -1 +0,0 @@ -!meson.build diff --git a/blocklib/fec/include/gnuradio/fec/api.h b/blocklib/fec/include/gnuradio/fec/api.h deleted file mode 100644 index f0a0de2d4..000000000 --- a/blocklib/fec/include/gnuradio/fec/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_fec_EXPORTS -#define FEC_API __GR_ATTR_EXPORT -#else -#define FEC_API __GR_ATTR_IMPORT -#endif diff --git a/blocklib/fec/include/gnuradio/fec/meson.build b/blocklib/fec/include/gnuradio/fec/meson.build deleted file mode 100644 index b95e69612..000000000 --- a/blocklib/fec/include/gnuradio/fec/meson.build +++ /dev/null @@ -1,6 +0,0 @@ -headers = [ - 'api.h', - 'rs.h' -] - -install_headers(headers, subdir : 'gnuradio/fec') diff --git a/blocklib/fec/include/gnuradio/fec/rs.h b/blocklib/fec/include/gnuradio/fec/rs.h deleted file mode 100644 index ae05c79eb..000000000 --- a/blocklib/fec/include/gnuradio/fec/rs.h +++ /dev/null @@ -1,41 +0,0 @@ -#include <gnuradio/fec/api.h> -/* User include file for the Reed-Solomon codec - * Copyright 2002, Phil Karn KA9Q - * May be used under the terms of the GNU General Public License (GPL) - */ - -/* General purpose RS codec, 8-bit symbols */ -FEC_API void encode_rs_char(void* rs, unsigned char* data, unsigned char* parity); -FEC_API int decode_rs_char(void* rs, unsigned char* data, int* eras_pos, int no_eras); -FEC_API void* init_rs_char(unsigned int symsize, - unsigned int gfpoly, - unsigned int fcr, - unsigned int prim, - unsigned int nroots); -FEC_API void free_rs_char(void* rs); - -/* General purpose RS codec, integer symbols */ -FEC_API void encode_rs_int(void* rs, int* data, int* parity); -FEC_API int decode_rs_int(void* rs, int* data, int* eras_pos, int no_eras); -FEC_API void* init_rs_int(unsigned int symsize, - unsigned int gfpoly, - unsigned int fcr, - unsigned int prim, - unsigned int nroots); -FEC_API void free_rs_int(void* rs); - -/* CCSDS standard (255,223) RS codec with conventional (*not* dual-basis) - * symbol representation - */ -FEC_API void encode_rs_8(unsigned char* data, unsigned char* parity); -FEC_API int decode_rs_8(unsigned char* data, int* eras_pos, int no_eras); - -/* CCSDS standard (255,223) RS codec with dual-basis symbol representation - */ -FEC_API void encode_rs_ccsds(unsigned char* data, unsigned char* parity); -FEC_API int decode_rs_ccsds(unsigned char* data, int* eras_pos, int no_eras); - -/* Tables to map from conventional->dual (Taltab) and - * dual->conventional (Tal1tab) bases - */ -extern unsigned char Taltab[], Tal1tab[]; diff --git a/blocklib/fec/lib/.gitignore b/blocklib/fec/lib/.gitignore deleted file mode 100644 index 01ecb66ff..000000000 --- a/blocklib/fec/lib/.gitignore +++ /dev/null @@ -1 +0,0 @@ -!meson.build
\ No newline at end of file diff --git a/blocklib/fec/lib/meson.build b/blocklib/fec/lib/meson.build deleted file mode 100644 index ecf8cef44..000000000 --- a/blocklib/fec/lib/meson.build +++ /dev/null @@ -1,21 +0,0 @@ -subdir('reed-solomon') - -cmake_conf = configuration_data() -cmake_conf.set('libdir', join_paths(prefix,get_option('libdir'))) -cmake_conf.set('module', 'fec') -cmake.configure_package_config_file( - name : 'gnuradio-fec', - 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_fec_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-fec', - filebase : 'gnuradio-fec', - description : 'GNU Radio FEC Module') diff --git a/blocklib/fec/lib/reed-solomon/Makefile.in.karn b/blocklib/fec/lib/reed-solomon/Makefile.in.karn deleted file mode 100644 index 8550b4158..000000000 --- a/blocklib/fec/lib/reed-solomon/Makefile.in.karn +++ /dev/null @@ -1,99 +0,0 @@ -# Copyright 2002 Phil Karn, KA9Q -# May be used under the terms of the GNU General Public License (GPL) -# @configure_input@ -srcdir = @srcdir@ -prefix = @prefix@ -exec_prefix=@exec_prefix@ -VPATH = @srcdir@ -CC=@CC@ - -CFLAGS=@CFLAGS@ @ARCH_OPTION@ -Wall - -LIB= encode_rs_char.o encode_rs_int.o encode_rs_8.o \ - decode_rs_char.o decode_rs_int.o decode_rs_8.o \ - init_rs_char.o init_rs_int.o ccsds_tab.o \ - encode_rs_ccsds.o decode_rs_ccsds.o ccsds_tal.o - -all: librs.a librs.so.@SO_VERSION@ - -test: rstest - ./rstest - -rstest: rstest.o exercise_int.o exercise_char.o exercise_8.o exercise_ccsds.o \ - librs.a - gcc -g -o $@ $^ - -install: all - install -D -m 644 -p librs.a librs.so.@SO_VERSION@ @libdir@ - (cd @libdir@;ln -f -s librs.so.@SO_VERSION@ librs.so) - ldconfig - install -m 644 -p rs.h @includedir@ - install -m 644 rs.3 @mandir@/man3 - -librs.a: $(LIB) - ar rv $@ $^ - -librs.so.@SO_VERSION@: librs.a - gcc -shared -Xlinker -soname=librs.so.@SO_NAME@ -o $@ -Wl,-whole-archive $^ -Wl,-no-whole-archive -lc - -encode_rs_char.o: encode_rs.c - gcc $(CFLAGS) -c -o $@ $^ - -encode_rs_int.o: encode_rs.c - gcc -DBIGSYM=1 $(CFLAGS) -c -o $@ $^ - -encode_rs_8.o: encode_rs.c - gcc -DFIXED=1 $(CFLAGS) -c -o $@ $^ - -decode_rs_char.o: decode_rs.c - gcc $(CFLAGS) -c -o $@ $^ - -decode_rs_int.o: decode_rs.c - gcc -DBIGSYM=1 $(CFLAGS) -c -o $@ $^ - -decode_rs_8.o: decode_rs.c - gcc -DFIXED=1 $(CFLAGS) -c -o $@ $^ - -init_rs_char.o: init_rs.c - gcc $(CFLAGS) -c -o $@ $^ - -init_rs_int.o: init_rs.c - gcc -DBIGSYM=1 $(CFLAGS) -c -o $@ $^ - -ccsds_tab.o: ccsds_tab.c - -ccsds_tab.c: gen_ccsds - ./gen_ccsds > ccsds_tab.c - -gen_ccsds: gen_ccsds.o init_rs_char.o - gcc -o $@ $^ - -gen_ccsds.o: gen_ccsds.c - gcc $(CFLAGS) -c -o $@ $^ - -ccsds_tal.o: ccsds_tal.c - -ccsds_tal.c: gen_ccsds_tal - ./gen_ccsds_tal > ccsds_tal.c - -exercise_char.o: exercise.c - gcc $(CFLAGS) -c -o $@ $^ - -exercise_int.o: exercise.c - gcc -DBIGSYM=1 $(CFLAGS) -c -o $@ $^ - -exercise_8.o: exercise.c - gcc -DFIXED=1 $(CFLAGS) -c -o $@ $^ - -exercise_ccsds.o: exercise.c - gcc -DCCSDS=1 $(CFLAGS) -c -o $@ $^ - - -clean: - rm -f *.o *.a ccsds_tab.c ccsds_tal.c gen_ccsds gen_ccsds_tal \ - rstest librs.so.@SO_VERSION@ - -distclean: clean - rm -f config.log config.cache config.status config.h makefile - - diff --git a/blocklib/fec/lib/reed-solomon/README b/blocklib/fec/lib/reed-solomon/README deleted file mode 100644 index 5c867638e..000000000 --- a/blocklib/fec/lib/reed-solomon/README +++ /dev/null @@ -1,2 +0,0 @@ -This code is from http://people.qualcomm.com/karn/code/fec -It is based on reed-soloman-3.1.1 (1 Jan 2002). diff --git a/blocklib/fec/lib/reed-solomon/README.karn b/blocklib/fec/lib/reed-solomon/README.karn deleted file mode 100644 index f30644ffe..000000000 --- a/blocklib/fec/lib/reed-solomon/README.karn +++ /dev/null @@ -1,22 +0,0 @@ -This package implements a general purpose Reed-Solomon encoding and decoding -facility. See the rs.3 man page for details. - -To install, simply do the following after extracting this tarball into -an empty directory: - -./configure -make -make install - -The command "make test" runs a battery of encode/decode tests using a -variety of RS codes using random data and random errors. Each test -should pass with an "OK"; if any fail, please let me know so I can -track down the problem. - -Phil Karn (karn@ka9q.net) 1 Jan 2002 - -Copyright 2002, Phil Karn, KA9Q -This software may be used under the terms of the GNU General Public License (GPL). - - - diff --git a/blocklib/fec/lib/reed-solomon/ccsds.c b/blocklib/fec/lib/reed-solomon/ccsds.c deleted file mode 100644 index 6bdadff10..000000000 --- a/blocklib/fec/lib/reed-solomon/ccsds.c +++ /dev/null @@ -1,10 +0,0 @@ -/* Reed-Solomon decoder - * Copyright 2002 Phil Karn, KA9Q - * May be used under the terms of the GNU General Public License (GPL) - */ - -#define FIXED -#include "fixed.h" - -#include "decode_rs.h" -#include "encode_rs.h" diff --git a/blocklib/fec/lib/reed-solomon/ccsds.h b/blocklib/fec/lib/reed-solomon/ccsds.h deleted file mode 100644 index 52746f583..000000000 --- a/blocklib/fec/lib/reed-solomon/ccsds.h +++ /dev/null @@ -1 +0,0 @@ -extern unsigned char Taltab[], Tal1tab[]; diff --git a/blocklib/fec/lib/reed-solomon/ccsds_tab.c b/blocklib/fec/lib/reed-solomon/ccsds_tab.c deleted file mode 100644 index 63a3f366e..000000000 --- a/blocklib/fec/lib/reed-solomon/ccsds_tab.c +++ /dev/null @@ -1,45 +0,0 @@ -/* This has been generated with gen_ccsds */ - -char CCSDS_alpha_to[] = { -0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80,0x87,0x89,0x95,0xad,0xdd,0x3d,0x7a,0xf4, -0x6f,0xde,0x3b,0x76,0xec,0x5f,0xbe,0xfb,0x71,0xe2,0x43,0x86,0x8b,0x91,0xa5,0xcd, -0x1d,0x3a,0x74,0xe8,0x57,0xae,0xdb,0x31,0x62,0xc4,0x0f,0x1e,0x3c,0x78,0xf0,0x67, -0xce,0x1b,0x36,0x6c,0xd8,0x37,0x6e,0xdc,0x3f,0x7e,0xfc,0x7f,0xfe,0x7b,0xf6,0x6b, -0xd6,0x2b,0x56,0xac,0xdf,0x39,0x72,0xe4,0x4f,0x9e,0xbb,0xf1,0x65,0xca,0x13,0x26, -0x4c,0x98,0xb7,0xe9,0x55,0xaa,0xd3,0x21,0x42,0x84,0x8f,0x99,0xb5,0xed,0x5d,0xba, -0xf3,0x61,0xc2,0x03,0x06,0x0c,0x18,0x30,0x60,0xc0,0x07,0x0e,0x1c,0x38,0x70,0xe0, -0x47,0x8e,0x9b,0xb1,0xe5,0x4d,0x9a,0xb3,0xe1,0x45,0x8a,0x93,0xa1,0xc5,0x0d,0x1a, -0x34,0x68,0xd0,0x27,0x4e,0x9c,0xbf,0xf9,0x75,0xea,0x53,0xa6,0xcb,0x11,0x22,0x44, -0x88,0x97,0xa9,0xd5,0x2d,0x5a,0xb4,0xef,0x59,0xb2,0xe3,0x41,0x82,0x83,0x81,0x85, -0x8d,0x9d,0xbd,0xfd,0x7d,0xfa,0x73,0xe6,0x4b,0x96,0xab,0xd1,0x25,0x4a,0x94,0xaf, -0xd9,0x35,0x6a,0xd4,0x2f,0x5e,0xbc,0xff,0x79,0xf2,0x63,0xc6,0x0b,0x16,0x2c,0x58, -0xb0,0xe7,0x49,0x92,0xa3,0xc1,0x05,0x0a,0x14,0x28,0x50,0xa0,0xc7,0x09,0x12,0x24, -0x48,0x90,0xa7,0xc9,0x15,0x2a,0x54,0xa8,0xd7,0x29,0x52,0xa4,0xcf,0x19,0x32,0x64, -0xc8,0x17,0x2e,0x5c,0xb8,0xf7,0x69,0xd2,0x23,0x46,0x8c,0x9f,0xb9,0xf5,0x6d,0xda, -0x33,0x66,0xcc,0x1f,0x3e,0x7c,0xf8,0x77,0xee,0x5b,0xb6,0xeb,0x51,0xa2,0xc3,0x00, -}; - -char CCSDS_index_of[] = { -255, 0, 1, 99, 2,198,100,106, 3,205,199,188,101,126,107, 42, - 4,141,206, 78,200,212,189,225,102,221,127, 49,108, 32, 43,243, - 5, 87,142,232,207,172, 79,131,201,217,213, 65,190,148,226,180, -103, 39,222,240,128,177, 50, 53,109, 69, 33, 18, 44, 13,244, 56, - 6,155, 88, 26,143,121,233,112,208,194,173,168, 80,117,132, 72, -202,252,218,138,214, 84, 66, 36,191,152,149,249,227, 94,181, 21, -104, 97, 40,186,223, 76,241, 47,129,230,178, 63, 51,238, 54, 16, -110, 24, 70,166, 34,136, 19,247, 45,184, 14, 61,245,164, 57, 59, - 7,158,156,157, 89,159, 27, 8,144, 9,122, 28,234,160,113, 90, -209, 29,195,123,174, 10,169,145, 81, 91,118,114,133,161, 73,235, -203,124,253,196,219, 30,139,210,215,146, 85,170, 67, 11, 37,175, -192,115,153,119,150, 92,250, 82,228,236, 95, 74,182,162, 22,134, -105,197, 98,254, 41,125,187,204,224,211, 77,140,242, 31, 48,220, -130,171,231, 86,179,147, 64,216, 52,176,239, 38, 55, 12, 17, 68, -111,120, 25,154, 71,116,167,193, 35, 83,137,251, 20, 93,248,151, - 46, 75,185, 96, 15,237, 62,229,246,135,165, 23, 58,163, 60,183, -}; - -char CCSDS_poly[] = { - 0,249, 59, 66, 4, 43,126,251, 97, 30, 3,213, 50, 66,170, 5, - 24, 5,170, 66, 50,213, 3, 30, 97,251,126, 43, 4, 66, 59,249, - 0, -}; diff --git a/blocklib/fec/lib/reed-solomon/ccsds_tal.c b/blocklib/fec/lib/reed-solomon/ccsds_tal.c deleted file mode 100644 index e579eef4d..000000000 --- a/blocklib/fec/lib/reed-solomon/ccsds_tal.c +++ /dev/null @@ -1,40 +0,0 @@ -/* This has been generated with gen_ccsds_tal */ - -unsigned char Taltab[] = { - -0x00,0x7b,0xaf,0xd4,0x99,0xe2,0x36,0x4d,0xfa,0x81,0x55,0x2e,0x63,0x18,0xcc,0xb7, -0x86,0xfd,0x29,0x52,0x1f,0x64,0xb0,0xcb,0x7c,0x07,0xd3,0xa8,0xe5,0x9e,0x4a,0x31, -0xec,0x97,0x43,0x38,0x75,0x0e,0xda,0xa1,0x16,0x6d,0xb9,0xc2,0x8f,0xf4,0x20,0x5b, -0x6a,0x11,0xc5,0xbe,0xf3,0x88,0x5c,0x27,0x90,0xeb,0x3f,0x44,0x09,0x72,0xa6,0xdd, -0xef,0x94,0x40,0x3b,0x76,0x0d,0xd9,0xa2,0x15,0x6e,0xba,0xc1,0x8c,0xf7,0x23,0x58, -0x69,0x12,0xc6,0xbd,0xf0,0x8b,0x5f,0x24,0x93,0xe8,0x3c,0x47,0x0a,0x71,0xa5,0xde, -0x03,0x78,0xac,0xd7,0x9a,0xe1,0x35,0x4e,0xf9,0x82,0x56,0x2d,0x60,0x1b,0xcf,0xb4, -0x85,0xfe,0x2a,0x51,0x1c,0x67,0xb3,0xc8,0x7f,0x04,0xd0,0xab,0xe6,0x9d,0x49,0x32, -0x8d,0xf6,0x22,0x59,0x14,0x6f,0xbb,0xc0,0x77,0x0c,0xd8,0xa3,0xee,0x95,0x41,0x3a, -0x0b,0x70,0xa4,0xdf,0x92,0xe9,0x3d,0x46,0xf1,0x8a,0x5e,0x25,0x68,0x13,0xc7,0xbc, -0x61,0x1a,0xce,0xb5,0xf8,0x83,0x57,0x2c,0x9b,0xe0,0x34,0x4f,0x02,0x79,0xad,0xd6, -0xe7,0x9c,0x48,0x33,0x7e,0x05,0xd1,0xaa,0x1d,0x66,0xb2,0xc9,0x84,0xff,0x2b,0x50, -0x62,0x19,0xcd,0xb6,0xfb,0x80,0x54,0x2f,0x98,0xe3,0x37,0x4c,0x01,0x7a,0xae,0xd5, -0xe4,0x9f,0x4b,0x30,0x7d,0x06,0xd2,0xa9,0x1e,0x65,0xb1,0xca,0x87,0xfc,0x28,0x53, -0x8e,0xf5,0x21,0x5a,0x17,0x6c,0xb8,0xc3,0x74,0x0f,0xdb,0xa0,0xed,0x96,0x42,0x39, -0x08,0x73,0xa7,0xdc,0x91,0xea,0x3e,0x45,0xf2,0x89,0x5d,0x26,0x6b,0x10,0xc4,0xbf, -}; - -unsigned char Tal1tab[] = { -0x00,0xcc,0xac,0x60,0x79,0xb5,0xd5,0x19,0xf0,0x3c,0x5c,0x90,0x89,0x45,0x25,0xe9, -0xfd,0x31,0x51,0x9d,0x84,0x48,0x28,0xe4,0x0d,0xc1,0xa1,0x6d,0x74,0xb8,0xd8,0x14, -0x2e,0xe2,0x82,0x4e,0x57,0x9b,0xfb,0x37,0xde,0x12,0x72,0xbe,0xa7,0x6b,0x0b,0xc7, -0xd3,0x1f,0x7f,0xb3,0xaa,0x66,0x06,0xca,0x23,0xef,0x8f,0x43,0x5a,0x96,0xf6,0x3a, -0x42,0x8e,0xee,0x22,0x3b,0xf7,0x97,0x5b,0xb2,0x7e,0x1e,0xd2,0xcb,0x07,0x67,0xab, -0xbf,0x73,0x13,0xdf,0xc6,0x0a,0x6a,0xa6,0x4f,0x83,0xe3,0x2f,0x36,0xfa,0x9a,0x56, -0x6c,0xa0,0xc0,0x0c,0x15,0xd9,0xb9,0x75,0x9c,0x50,0x30,0xfc,0xe5,0x29,0x49,0x85, -0x91,0x5d,0x3d,0xf1,0xe8,0x24,0x44,0x88,0x61,0xad,0xcd,0x01,0x18,0xd4,0xb4,0x78, -0xc5,0x09,0x69,0xa5,0xbc,0x70,0x10,0xdc,0x35,0xf9,0x99,0x55,0x4c,0x80,0xe0,0x2c, -0x38,0xf4,0x94,0x58,0x41,0x8d,0xed,0x21,0xc8,0x04,0x64,0xa8,0xb1,0x7d,0x1d,0xd1, -0xeb,0x27,0x47,0x8b,0x92,0x5e,0x3e,0xf2,0x1b,0xd7,0xb7,0x7b,0x62,0xae,0xce,0x02, -0x16,0xda,0xba,0x76,0x6f,0xa3,0xc3,0x0f,0xe6,0x2a,0x4a,0x86,0x9f,0x53,0x33,0xff, -0x87,0x4b,0x2b,0xe7,0xfe,0x32,0x52,0x9e,0x77,0xbb,0xdb,0x17,0x0e,0xc2,0xa2,0x6e, -0x7a,0xb6,0xd6,0x1a,0x03,0xcf,0xaf,0x63,0x8a,0x46,0x26,0xea,0xf3,0x3f,0x5f,0x93, -0xa9,0x65,0x05,0xc9,0xd0,0x1c,0x7c,0xb0,0x59,0x95,0xf5,0x39,0x20,0xec,0x8c,0x40, -0x54,0x98,0xf8,0x34,0x2d,0xe1,0x81,0x4d,0xa4,0x68,0x08,0xc4,0xdd,0x11,0x71,0xbd, -}; diff --git a/blocklib/fec/lib/reed-solomon/char.c b/blocklib/fec/lib/reed-solomon/char.c deleted file mode 100644 index 1aea39c75..000000000 --- a/blocklib/fec/lib/reed-solomon/char.c +++ /dev/null @@ -1,9 +0,0 @@ -/* Reed-Solomon decoder - * Copyright 2002 Phil Karn, KA9Q - * May be used under the terms of the GNU General Public License (GPL) - */ - -#include "char.h" - -#include "decode_rs.h" -#include "encode_rs.h" diff --git a/blocklib/fec/lib/reed-solomon/char.h b/blocklib/fec/lib/reed-solomon/char.h deleted file mode 100644 index 80435b633..000000000 --- a/blocklib/fec/lib/reed-solomon/char.h +++ /dev/null @@ -1,58 +0,0 @@ -/* Include file to configure the RS codec for character symbols - * - * Copyright 2002, Phil Karn, KA9Q - * May be used under the terms of the GNU General Public License (GPL) - */ - -#define DTYPE unsigned char - -#include <gnuradio/fec/api.h> - -/* Reed-Solomon codec control block */ -struct rs { - unsigned int mm; /* Bits per symbol */ - unsigned int nn; /* Symbols per block (= (1<<mm)-1) */ - unsigned char* alpha_to; /* log lookup table */ - unsigned char* index_of; /* Antilog lookup table */ - unsigned char* genpoly; /* Generator polynomial */ - unsigned int nroots; /* Number of generator roots = number of parity symbols */ - unsigned char fcr; /* First consecutive root, index form */ - unsigned char prim; /* Primitive element, index form */ - unsigned char iprim; /* prim-th root of 1, index form */ - int* modnn_table; /* modnn lookup table, 512 entries */ -}; - -static inline unsigned int modnn(struct rs* rs, unsigned int x) -{ - while (x >= rs->nn) { - x -= rs->nn; - x = (x >> rs->mm) + (x & rs->nn); - } - return x; -} -#define MODNN(x) modnn(rs, x) - -#define MM (rs->mm) -#define NN (rs->nn) -#define ALPHA_TO (rs->alpha_to) -#define INDEX_OF (rs->index_of) -#define GENPOLY (rs->genpoly) -#define NROOTS (rs->nroots) -#define FCR (rs->fcr) -#define PRIM (rs->prim) -#define IPRIM (rs->iprim) -#define A0 (NN) - -#define ENCODE_RS encode_rs_char -#define DECODE_RS decode_rs_char -#define INIT_RS init_rs_char -#define FREE_RS free_rs_char - -FEC_API void ENCODE_RS(void* p, DTYPE* data, DTYPE* parity); -FEC_API int DECODE_RS(void* p, DTYPE* data, int* eras_pos, int no_eras); -FEC_API void* INIT_RS(unsigned int symsize, - unsigned int gfpoly, - unsigned int fcr, - unsigned int prim, - unsigned int nroots); -FEC_API void FREE_RS(void* p); diff --git a/blocklib/fec/lib/reed-solomon/decode_rs.h b/blocklib/fec/lib/reed-solomon/decode_rs.h deleted file mode 100644 index 0b0799bf9..000000000 --- a/blocklib/fec/lib/reed-solomon/decode_rs.h +++ /dev/null @@ -1,273 +0,0 @@ -/* Reed-Solomon decoder - * Copyright 2002 Phil Karn, KA9Q - * May be used under the terms of the GNU General Public License (GPL) - */ - -#ifdef DEBUG -#include <stdio.h> -#endif - -#include <string.h> - -#ifndef NULL -#define NULL ((void*)0) -#endif - -#define min(a, b) ((a) < (b) ? (a) : (b)) - -int DECODE_RS( -#ifndef FIXED - void* p, -#endif - DTYPE* data, - int* eras_pos, - int no_eras) -{ - -#ifndef FIXED - struct rs* rs = (struct rs*)p; -#endif - int deg_lambda, el, deg_omega; - int i, j, r, k; -#ifdef MAX_ARRAY - DTYPE u, q, tmp, num1, num2, den, discr_r; - DTYPE lambda[MAX_ARRAY], s[MAX_ARRAY]; /* Err+Eras Locator poly - * and syndrome poly */ - DTYPE b[MAX_ARRAY], t[MAX_ARRAY], omega[MAX_ARRAY]; - DTYPE root[MAX_ARRAY], reg[MAX_ARRAY], loc[MAX_ARRAY]; -#else - DTYPE u, q, tmp, num1, num2, den, discr_r; - DTYPE lambda[NROOTS + 1], s[NROOTS]; /* Err+Eras Locator poly - * and syndrome poly */ - DTYPE b[NROOTS + 1], t[NROOTS + 1], omega[NROOTS + 1]; - DTYPE root[NROOTS], reg[NROOTS + 1], loc[NROOTS]; -#endif - int syn_error, count; - - /* form the syndromes; i.e., evaluate data(x) at roots of g(x) */ - for (i = 0; (unsigned int)i < NROOTS; i++) - s[i] = data[0]; - - for (j = 1; (unsigned int)j < NN; j++) { - for (i = 0; (unsigned int)i < NROOTS; i++) { - if (s[i] == 0) { - s[i] = data[j]; - } - else { - s[i] = data[j] ^ ALPHA_TO[MODNN(INDEX_OF[s[i]] + (FCR + i) * PRIM)]; - } - } - } - - /* Convert syndromes to index form, checking for nonzero condition */ - syn_error = 0; - for (i = 0; (unsigned int)i < NROOTS; i++) { - syn_error |= s[i]; - s[i] = INDEX_OF[s[i]]; - } - - if (!syn_error) { - /* if syndrome is zero, data[] is a codeword and there are no - * errors to correct. So return data[] unmodified - */ - count = 0; - goto finish; - } - memset(&lambda[1], 0, NROOTS * sizeof(lambda[0])); - lambda[0] = 1; - - if (no_eras > 0) { - /* Init lambda to be the erasure locator polynomial */ - lambda[1] = ALPHA_TO[MODNN(PRIM * (NN - 1 - eras_pos[0]))]; - for (i = 1; i < no_eras; i++) { - u = MODNN(PRIM * (NN - 1 - eras_pos[i])); - for (j = i + 1; j > 0; j--) { - tmp = INDEX_OF[lambda[j - 1]]; - if (tmp != A0) - lambda[j] ^= ALPHA_TO[MODNN(u + tmp)]; - } - } - -#if DEBUG >= 1 - /* Test code that verifies the erasure locator polynomial just constructed - Needed only for decoder debugging. */ - - /* find roots of the erasure location polynomial */ - for (i = 1; i <= no_eras; i++) - reg[i] = INDEX_OF[lambda[i]]; - - count = 0; - for (i = 1, k = IPRIM - 1; i <= NN; i++, k = MODNN(k + IPRIM)) { - q = 1; - for (j = 1; j <= no_eras; j++) - if (reg[j] != A0) { - reg[j] = MODNN(reg[j] + j); - q ^= ALPHA_TO[reg[j]]; - } - if (q != 0) - continue; - /* store root and error location number indices */ - root[count] = i; - loc[count] = k; - count++; - } - if (count != no_eras) { - printf("count = %d no_eras = %d\n lambda(x) is WRONG\n", count, no_eras); - count = -1; - goto finish; - } -#if DEBUG >= 2 - printf("\n Erasure positions as determined by roots of Eras Loc Poly:\n"); - for (i = 0; i < count; i++) - printf("%d ", loc[i]); - printf("\n"); -#endif -#endif - } - for (i = 0; (unsigned int)i < NROOTS + 1; i++) - b[i] = INDEX_OF[lambda[i]]; - - /* - * Begin Berlekamp-Massey algorithm to determine error+erasure - * locator polynomial - */ - r = no_eras; - el = no_eras; - while ((unsigned int)(++r) <= NROOTS) { /* r is the step number */ - /* Compute discrepancy at the r-th step in poly-form */ - discr_r = 0; - for (i = 0; i < r; i++) { - if ((lambda[i] != 0) && (s[r - i - 1] != A0)) { - discr_r ^= ALPHA_TO[MODNN(INDEX_OF[lambda[i]] + s[r - i - 1])]; - } - } - discr_r = INDEX_OF[discr_r]; /* Index form */ - if (discr_r == A0) { - /* 2 lines below: B(x) <-- x*B(x) */ - memmove(&b[1], b, NROOTS * sizeof(b[0])); - b[0] = A0; - } - else { - /* 7 lines below: T(x) <-- lambda(x) - discr_r*x*b(x) */ - t[0] = lambda[0]; - for (i = 0; (unsigned int)i < NROOTS; i++) { - if (b[i] != A0) - t[i + 1] = lambda[i + 1] ^ ALPHA_TO[MODNN(discr_r + b[i])]; - else - t[i + 1] = lambda[i + 1]; - } - if (2 * el <= r + no_eras - 1) { - el = r + no_eras - el; - /* - * 2 lines below: B(x) <-- inv(discr_r) * - * lambda(x) - */ - for (i = 0; (unsigned int)i <= NROOTS; i++) - b[i] = - (lambda[i] == 0) ? A0 : MODNN(INDEX_OF[lambda[i]] - discr_r + NN); - } - else { - /* 2 lines below: B(x) <-- x*B(x) */ - memmove(&b[1], b, NROOTS * sizeof(b[0])); - b[0] = A0; - } - memcpy(lambda, t, (NROOTS + 1) * sizeof(t[0])); - } - } - - /* Convert lambda to index form and compute deg(lambda(x)) */ - deg_lambda = 0; - for (i = 0; (unsigned int)i < NROOTS + 1; i++) { - lambda[i] = INDEX_OF[lambda[i]]; - if (lambda[i] != A0) - deg_lambda = i; - } - /* Find roots of the error+erasure locator polynomial by Chien search */ - memcpy(®[1], &lambda[1], NROOTS * sizeof(reg[0])); - count = 0; /* Number of roots of lambda(x) */ - for (i = 1, k = IPRIM - 1; (unsigned int)i <= NN; i++, k = MODNN(k + IPRIM)) { - q = 1; /* lambda[0] is always 0 */ - for (j = deg_lambda; j > 0; j--) { - if (reg[j] != A0) { - reg[j] = MODNN(reg[j] + j); - q ^= ALPHA_TO[reg[j]]; - } - } - if (q != 0) - continue; /* Not a root */ - /* store root (index-form) and error location number */ -#if DEBUG >= 2 - printf("count %d root %d loc %d\n", count, i, k); -#endif - root[count] = i; - loc[count] = k; - /* If we've already found max possible roots, - * abort the search to save time - */ - if (++count == deg_lambda) - break; - } - if (deg_lambda != count) { - /* - * deg(lambda) unequal to number of roots => uncorrectable - * error detected - */ - count = -1; - goto finish; - } - /* - * Compute err+eras evaluator poly omega(x) = s(x)*lambda(x) (modulo - * x**NROOTS). in index form. Also find deg(omega). - */ - deg_omega = 0; - for (i = 0; (unsigned int)i < NROOTS; i++) { - tmp = 0; - j = (deg_lambda < i) ? deg_lambda : i; - for (; j >= 0; j--) { - if ((s[i - j] != A0) && (lambda[j] != A0)) - tmp ^= ALPHA_TO[MODNN(s[i - j] + lambda[j])]; - } - if (tmp != 0) - deg_omega = i; - omega[i] = INDEX_OF[tmp]; - } - omega[NROOTS] = A0; - - /* - * Compute error values in poly-form. num1 = omega(inv(X(l))), num2 = - * inv(X(l))**(FCR-1) and den = lambda_pr(inv(X(l))) all in poly-form - */ - for (j = count - 1; j >= 0; j--) { - num1 = 0; - for (i = deg_omega; i >= 0; i--) { - if (omega[i] != A0) - num1 ^= ALPHA_TO[MODNN(omega[i] + i * root[j])]; - } - num2 = ALPHA_TO[MODNN(root[j] * (FCR - 1) + NN)]; - den = 0; - - /* lambda[i+1] for i even is the formal derivative lambda_pr of lambda[i] */ - for (i = (int)min((unsigned int)deg_lambda, NROOTS - 1) & ~1; i >= 0; i -= 2) { - if (lambda[i + 1] != A0) - den ^= ALPHA_TO[MODNN(lambda[i + 1] + i * root[j])]; - } - if (den == 0) { -#if DEBUG >= 1 - printf("\n ERROR: denominator = 0\n"); -#endif - count = -1; - goto finish; - } - /* Apply error to data */ - if (num1 != 0) { - data[loc[j]] ^= - ALPHA_TO[MODNN(INDEX_OF[num1] + INDEX_OF[num2] + NN - INDEX_OF[den])]; - } - } -finish: - if (eras_pos != NULL) { - for (i = 0; i < count; i++) - eras_pos[i] = loc[i]; - } - return count; -} diff --git a/blocklib/fec/lib/reed-solomon/decode_rs_ccsds.c b/blocklib/fec/lib/reed-solomon/decode_rs_ccsds.c deleted file mode 100644 index be6e2018e..000000000 --- a/blocklib/fec/lib/reed-solomon/decode_rs_ccsds.c +++ /dev/null @@ -1,28 +0,0 @@ -/* This function wraps around the fixed 8-bit decoder, performing the - * basis transformations necessary to meet the CCSDS standard - * - * Copyright 2002, Phil Karn, KA9Q - * May be used under the terms of the GNU General Public License (GPL) - */ -#define FIXED 1 -#include "ccsds.h" -#include "fixed.h" - -int decode_rs_ccsds(unsigned char* data, int* eras_pos, int no_eras) -{ - int i, r; - unsigned char cdata[NN]; - - /* Convert data from dual basis to conventional */ - for (i = 0; i < NN; i++) - cdata[i] = Tal1tab[data[i]]; - - r = decode_rs_8(cdata, eras_pos, no_eras); - - if (r > 0) { - /* Convert from conventional to dual basis */ - for (i = 0; i < NN; i++) - data[i] = Taltab[cdata[i]]; - } - return r; -} diff --git a/blocklib/fec/lib/reed-solomon/encode_rs.h b/blocklib/fec/lib/reed-solomon/encode_rs.h deleted file mode 100644 index 45e1ab720..000000000 --- a/blocklib/fec/lib/reed-solomon/encode_rs.h +++ /dev/null @@ -1,56 +0,0 @@ -/* Reed-Solomon encoder - * Copyright 2002, Phil Karn, KA9Q - * May be used under the terms of the GNU General Public License (GPL) - */ - -#include <string.h> - -void ENCODE_RS( -#ifndef FIXED - void* p, -#endif - DTYPE* data, - DTYPE* bb) -{ -#ifndef FIXED - struct rs* rs = (struct rs*)p; -#endif - unsigned int i, j; - DTYPE feedback; - - memset(bb, 0, NROOTS * sizeof(DTYPE)); - - for (i = 0; i < NN - NROOTS; i++) { - feedback = INDEX_OF[data[i] ^ bb[0]]; - if (feedback != A0) { /* feedback term is non-zero */ -#ifdef UNNORMALIZED - /* This line is unnecessary when GENPOLY[NROOTS] is unity, as it must - * always be for the polynomials constructed by init_rs() - */ - feedback = MODNN(NN - GENPOLY[NROOTS] + feedback); -#endif - for (j = 1; j < NROOTS; j++) -#ifdef FIXED - bb[j] ^= ALPHA_TO[MODNN(feedback + GENPOLY[NROOTS - j])]; -#elif defined(BIGSYM) - // Same as above; keeping as a separate line in case these change. - bb[j] ^= ALPHA_TO[MODNN(feedback + GENPOLY[NROOTS - j])]; -#else - bb[j] ^= ALPHA_TO[rs->modnn_table[feedback + GENPOLY[NROOTS - j]]]; -#endif - } - /* Shift */ - memmove(&bb[0], &bb[1], sizeof(DTYPE) * (NROOTS - 1)); - if (feedback != A0) -#ifdef FIXED - bb[NROOTS - 1] = ALPHA_TO[MODNN(feedback + GENPOLY[0])]; -#elif defined(BIGSYM) - // Same as above; keeping as a separate line in case these change. - bb[NROOTS - 1] = ALPHA_TO[MODNN(feedback + GENPOLY[0])]; -#else - bb[NROOTS - 1] = ALPHA_TO[rs->modnn_table[feedback + GENPOLY[0]]]; -#endif - else - bb[NROOTS - 1] = 0; - } -} diff --git a/blocklib/fec/lib/reed-solomon/encode_rs_ccsds.c b/blocklib/fec/lib/reed-solomon/encode_rs_ccsds.c deleted file mode 100644 index 7080b3f41..000000000 --- a/blocklib/fec/lib/reed-solomon/encode_rs_ccsds.c +++ /dev/null @@ -1,25 +0,0 @@ -/* This function wraps around the fixed 8-bit encoder, performing the - * basis transformations necessary to meet the CCSDS standard - * - * Copyright 2002, Phil Karn, KA9Q - * May be used under the terms of the GNU General Public License (GPL) - */ -#define FIXED -#include "ccsds.h" -#include "fixed.h" - -void encode_rs_ccsds(unsigned char* data, unsigned char* parity) -{ - int i; - unsigned char cdata[NN - NROOTS]; - - /* Convert data from dual basis to conventional */ - for (i = 0; i < NN - NROOTS; i++) - cdata[i] = Tal1tab[data[i]]; - - encode_rs_8(cdata, parity); - - /* Convert parity from conventional to dual basis */ - for (i = 0; i < NN - NROOTS; i++) - parity[i] = Taltab[parity[i]]; -} diff --git a/blocklib/fec/lib/reed-solomon/exercise.c b/blocklib/fec/lib/reed-solomon/exercise.c deleted file mode 100644 index 598f485fe..000000000 --- a/blocklib/fec/lib/reed-solomon/exercise.c +++ /dev/null @@ -1,136 +0,0 @@ -/* Exercise an RS codec a specified number of times using random - * data and error patterns - * - * Copyright 2002 Phil Karn, KA9Q - * May be used under the terms of the GNU General Public License (GPL) - */ -#define FLAG_ERASURE 1 /* Randomly flag 50% of errors as erasures */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -#ifdef FIXED -#include "fixed.h" -#define EXERCISE exercise_8 -#elif defined(CCSDS) -#include "ccsds.h" -#include "fixed.h" -#define EXERCISE exercise_ccsds -#elif defined(BIGSYM) -#include "int.h" -#define EXERCISE exercise_int -#else -#include "char.h" -#define EXERCISE exercise_char -#endif - -#ifdef FIXED -#define PRINTPARM printf("(255,223):"); -#elif defined(CCSDS) -#define PRINTPARM printf("CCSDS (255,223):"); -#else -#define PRINTPARM printf("(%d,%d):", rs->nn, rs->nn - rs->nroots); -#endif - -/* Exercise the RS codec passed as an argument */ -int EXERCISE( -#if !defined(CCSDS) && !defined(FIXED) - void* p, -#endif - int trials) -{ -#if !defined(CCSDS) && !defined(FIXED) - struct rs* rs = (struct rs*)p; -#endif -#if MAX_ARRAY - DTYPE block[MAX_ARRAY], tblock[MAX_ARRAY]; - unsigned int i; - int errors; - int errlocs[MAX_ARRAY]; - int derrlocs[MAX_ARRAY]; -#else - DTYPE block[NN], tblock[NN]; - unsigned int i; - int errors; - int errlocs[NN]; - int derrlocs[NROOTS]; -#endif - int derrors; - int errval, errloc; - int erasures; - int decoder_errors = 0; - - while (trials-- != 0) { - /* Test up to the error correction capacity of the code */ - for (errors = 0; (unsigned int)errors <= NROOTS / 2; errors++) { - - /* Load block with random data and encode */ - for (i = 0; i < NN - NROOTS; i++) - block[i] = rand() & NN; - -#if defined(CCSDS) || defined(FIXED) - ENCODE_RS(&block[0], &block[NN - NROOTS]); -#else - ENCODE_RS(rs, &block[0], &block[NN - NROOTS]); -#endif - - /* Make temp copy, seed with errors */ - memcpy(tblock, block, sizeof(tblock)); - memset(errlocs, 0, sizeof(errlocs)); - memset(derrlocs, 0, sizeof(derrlocs)); - erasures = 0; - for (i = 0; i < (unsigned int)errors; i++) { - do { - errval = rand() & NN; - } while (errval == 0); /* Error value must be nonzero */ - - do { - errloc = rand() % NN; - } while (errlocs[errloc] != - 0); /* Must not choose the same location twice */ - - errlocs[errloc] = 1; - -#if FLAG_ERASURE - if (rand() & 1) /* 50-50 chance */ - derrlocs[erasures++] = errloc; -#endif - tblock[errloc] ^= errval; - } - - /* Decode the errored block */ -#if defined(CCSDS) || defined(FIXED) - derrors = DECODE_RS(tblock, derrlocs, erasures); -#else - derrors = DECODE_RS(rs, tblock, derrlocs, erasures); -#endif - - if (derrors != errors) { - PRINTPARM - printf(" decoder says %d errors, true number is %d\n", derrors, errors); - decoder_errors++; - } - for (i = 0; i < (unsigned int)derrors; i++) { - if (errlocs[derrlocs[i]] == 0) { - PRINTPARM - printf(" decoder indicates error in location %d without error\n", i); - decoder_errors++; - } - } - if (memcmp(tblock, block, sizeof(tblock)) != 0) { - PRINTPARM - printf(" uncorrected errors! output ^ input:"); - decoder_errors++; - for (i = 0; i < NN; i++) - printf(" %02x", tblock[i] ^ block[i]); - printf("\n"); - } - } - } - return decoder_errors; -} diff --git a/blocklib/fec/lib/reed-solomon/fixed.h b/blocklib/fec/lib/reed-solomon/fixed.h deleted file mode 100644 index feb3105b0..000000000 --- a/blocklib/fec/lib/reed-solomon/fixed.h +++ /dev/null @@ -1,41 +0,0 @@ -/* Configure the RS codec with fixed parameters for CCSDS standard - * (255,223) code over GF(256). Note: the conventional basis is still - * used; the dual-basis mappings are performed in [en|de]code_rs_ccsds.c - * - * Copyright 2002 Phil Karn, KA9Q - * May be used under the terms of the GNU General Public License (GPL) - */ -#define DTYPE unsigned char - -#include <gnuradio/fec/api.h> - -static inline int mod255(int x) -{ - while (x >= 255) { - x -= 255; - x = (x >> 8) + (x & 255); - } - return x; -} -#define MODNN(x) mod255(x) - -extern unsigned char CCSDS_alpha_to[]; -extern unsigned char CCSDS_index_of[]; -extern unsigned char CCSDS_poly[]; - -#define MM 8 -#define NN 255 -#define ALPHA_TO CCSDS_alpha_to -#define INDEX_OF CCSDS_index_of -#define GENPOLY CCSDS_poly -#define NROOTS 32 -#define FCR 112 -#define PRIM 11 -#define IPRIM 116 -#define A0 (NN) - -#define ENCODE_RS encode_rs_8 -#define DECODE_RS decode_rs_8 - -FEC_API void ENCODE_RS(DTYPE* data, DTYPE* parity); -FEC_API int DECODE_RS(DTYPE* data, int* eras_pos, int no_eras);
\ No newline at end of file diff --git a/blocklib/fec/lib/reed-solomon/gen_ccsds.c b/blocklib/fec/lib/reed-solomon/gen_ccsds.c deleted file mode 100644 index 8073278d8..000000000 --- a/blocklib/fec/lib/reed-solomon/gen_ccsds.c +++ /dev/null @@ -1,35 +0,0 @@ -/* Generate tables for CCSDS code - * Copyright 2002 Phil Karn, KA9Q - * May be used under the terms of the GNU General Public License (GPL) - */ -#include "char.h" -#include <stdio.h> - -int main() -{ - struct rs* rs; - int i; - - rs = init_rs_char(8, 0x187, 112, 11, 32); /* CCSDS standard */ - printf("unsigned char CCSDS_alpha_to[] = {"); - for (i = 0; i < 256; i++) { - if ((i % 16) == 0) - printf("\n"); - printf("0x%02x,", rs->alpha_to[i]); - } - printf("\n};\n\nunsigned char CCSDS_index_of[] = {"); - for (i = 0; i < 256; i++) { - if ((i % 16) == 0) - printf("\n"); - printf("%3d,", rs->index_of[i]); - } - printf("\n};\n\nunsigned char CCSDS_poly[] = {"); - for (i = 0; i < 33; i++) { - if ((i % 16) == 0) - printf("\n"); - - printf("%3d,", rs->genpoly[i]); - } - printf("\n};\n"); - exit(0); -} diff --git a/blocklib/fec/lib/reed-solomon/gen_ccsds_tal.c b/blocklib/fec/lib/reed-solomon/gen_ccsds_tal.c deleted file mode 100644 index 9db195d79..000000000 --- a/blocklib/fec/lib/reed-solomon/gen_ccsds_tal.c +++ /dev/null @@ -1,50 +0,0 @@ -/* Conversion lookup tables from conventional alpha to Berlekamp's - * dual-basis representation. Used in the CCSDS version only. - * taltab[] -- convert conventional to dual basis - * tal1tab[] -- convert dual basis to conventional - - * Note: the actual RS encoder/decoder works with the conventional basis. - * So data is converted from dual to conventional basis before either - * encoding or decoding and then converted back. - * - * Copyright 2002 Phil Karn, KA9Q - * May be used under the terms of the GNU General Public License (GPL) - */ -#include <stdio.h> -unsigned char Taltab[256], Tal1tab[256]; - -static unsigned char tal[] = { 0x8d, 0xef, 0xec, 0x86, 0xfa, 0x99, 0xaf, 0x7b }; - -/* Generate conversion lookup tables between conventional alpha representation - * (@**7, @**6, ...@**0) - * and Berlekamp's dual basis representation - * (l0, l1, ...l7) - */ -int main() -{ - int i, j, k; - - for (i = 0; i < 256; i++) { /* For each value of input */ - Taltab[i] = 0; - for (j = 0; j < 8; j++) /* for each column of matrix */ - for (k = 0; k < 8; k++) { /* for each row of matrix */ - if (i & (1 << k)) - Taltab[i] ^= tal[7 - k] & (1 << j); - } - Tal1tab[Taltab[i]] = i; - } - printf("unsigned char Taltab[] = {\n"); - for (i = 0; i < 256; i++) { - if ((i % 16) == 0) - printf("\n"); - printf("0x%02x,", Taltab[i]); - } - printf("\n};\n\nunsigned char Tal1tab[] = {"); - for (i = 0; i < 256; i++) { - if ((i % 16) == 0) - printf("\n"); - printf("0x%02x,", Tal1tab[i]); - } - printf("\n};\n"); - exit(0); -} diff --git a/blocklib/fec/lib/reed-solomon/init_rs.c b/blocklib/fec/lib/reed-solomon/init_rs.c deleted file mode 100644 index 11a89d1be..000000000 --- a/blocklib/fec/lib/reed-solomon/init_rs.c +++ /dev/null @@ -1,163 +0,0 @@ -/* Initialize a RS codec - * - * Copyright 2002 Phil Karn, KA9Q - * May be used under the terms of the GNU General Public License (GPL) - */ -#include <stdlib.h> - -#ifdef CCSDS -#include "ccsds.h" -#elif defined(BIGSYM) -#include "int.h" -#else -#include "char.h" -#endif - -#ifndef NULL -#define NULL ((void*)0) -#endif - -void FREE_RS(void* p) -{ - struct rs* rs = (struct rs*)p; - - free(rs->alpha_to); - free(rs->index_of); - free(rs->genpoly); -#ifdef FIXED -#elif defined(BIGSYM) -#else - free(rs->modnn_table); -#endif - free(rs); -} - -/* Initialize a Reed-Solomon codec - * symsize = symbol size, bits (1-8) - * gfpoly = Field generator polynomial coefficients - * fcr = first root of RS code generator polynomial, index form - * prim = primitive element to generate polynomial roots - * nroots = RS code generator polynomial degree (number of roots) - */ -void* INIT_RS(unsigned int symsize, - unsigned int gfpoly, - unsigned fcr, - unsigned prim, - unsigned int nroots) -{ - struct rs* rs; - int sr, root, iprim; - unsigned int i, j; - - if (symsize > 8 * sizeof(DTYPE)) - return NULL; /* Need version with ints rather than chars */ - - if (fcr >= (1u << symsize)) - return NULL; - if (prim == 0 || prim >= (1u << symsize)) - return NULL; - if (nroots >= (1u << symsize)) - return NULL; /* Can't have more roots than symbol values! */ - - rs = (struct rs*)calloc(1, sizeof(struct rs)); - if (rs == NULL) - return NULL; - rs->mm = symsize; - rs->nn = (1 << symsize) - 1; - - rs->alpha_to = (DTYPE*)malloc(sizeof(DTYPE) * (rs->nn + 1)); - if (rs->alpha_to == NULL) { - free(rs); - return NULL; - } - rs->index_of = (DTYPE*)malloc(sizeof(DTYPE) * (rs->nn + 1)); - if (rs->index_of == NULL) { - free(rs->alpha_to); - free(rs); - return NULL; - } - - /* Generate Galois field lookup tables */ - rs->index_of[0] = A0; /* log(zero) = -inf */ - rs->alpha_to[A0] = 0; /* alpha**-inf = 0 */ - sr = 1; - for (i = 0; i < rs->nn; i++) { - rs->index_of[sr] = i; - rs->alpha_to[i] = sr; - sr <<= 1; - if (sr & (1 << symsize)) - sr ^= gfpoly; - sr &= rs->nn; - } - if (sr != 1) { - /* field generator polynomial is not primitive! */ - free(rs->alpha_to); - free(rs->index_of); - free(rs); - return NULL; - } - - /* Form RS code generator polynomial from its roots */ - rs->genpoly = (DTYPE*)malloc(sizeof(DTYPE) * (nroots + 1)); - if (rs->genpoly == NULL) { - free(rs->alpha_to); - free(rs->index_of); - free(rs); - return NULL; - } - rs->fcr = fcr; - rs->prim = prim; - rs->nroots = nroots; - - /* Find prim-th root of 1, used in decoding */ - for (iprim = 1; (iprim % prim) != 0; iprim += rs->nn) - ; - rs->iprim = iprim / prim; - - rs->genpoly[0] = 1; - for (i = 0, root = fcr * prim; i < nroots; i++, root += prim) { - rs->genpoly[i + 1] = 1; - - /* Multiply rs->genpoly[] by @**(root + x) */ - for (j = i; j > 0; j--) { - if (rs->genpoly[j] != 0) - rs->genpoly[j] = - rs->genpoly[j - 1] ^ - rs->alpha_to[modnn(rs, rs->index_of[rs->genpoly[j]] + root)]; - else - rs->genpoly[j] = rs->genpoly[j - 1]; - } - /* rs->genpoly[0] can never be zero */ - rs->genpoly[0] = rs->alpha_to[modnn(rs, rs->index_of[rs->genpoly[0]] + root)]; - } - /* convert rs->genpoly[] to index form for quicker encoding */ - for (i = 0; i <= nroots; i++) - rs->genpoly[i] = rs->index_of[rs->genpoly[i]]; - -#ifdef FIXED -#elif defined(BIGSYM) -#else - /* Form modnn lookup table */ - rs->modnn_table = (int*)malloc(sizeof(int) * (2 << ((sizeof(unsigned char)) * 8))); - if (rs->modnn_table == NULL) { - free(rs->genpoly); - free(rs->alpha_to); - free(rs->index_of); - free(rs); - return NULL; - } - for (i = 0; i < (2 << ((sizeof(unsigned char)) * 8)); i++) { - j = i; - rs->modnn_table[i] = modnn(rs, j); - } -#endif - -#if 0 - printf ("genpoly:\n"); - for (i = nroots; i >= 0; i--){ - printf (" %3d*X^%d\n", rs->alpha_to[rs->genpoly[i]], i); - } -#endif - - return rs; -} diff --git a/blocklib/fec/lib/reed-solomon/int.h b/blocklib/fec/lib/reed-solomon/int.h deleted file mode 100644 index 80dd50d3f..000000000 --- a/blocklib/fec/lib/reed-solomon/int.h +++ /dev/null @@ -1,56 +0,0 @@ -/* Include file to configure the RS codec for integer symbols - * - * Copyright 2002, Phil Karn, KA9Q - * May be used under the terms of the GNU General Public License (GPL) - */ -#define DTYPE int - -#include <gnuradio/fec/api.h> - -/* Reed-Solomon codec control block */ -struct FEC_API rs { - unsigned int mm; /* Bits per symbol */ - unsigned int nn; /* Symbols per block (= (1<<mm)-1) */ - int* alpha_to; /* log lookup table */ - int* index_of; /* Antilog lookup table */ - int* genpoly; /* Generator polynomial */ - unsigned int nroots; /* Number of generator roots = number of parity symbols */ - unsigned int fcr; /* First consecutive root, index form */ - unsigned int prim; /* Primitive element, index form */ - unsigned int iprim; /* prim-th root of 1, index form */ -}; - -static inline int modnn(struct rs* rs, int x) -{ - while (x >= rs->nn) { - x -= rs->nn; - x = (x >> rs->mm) + (x & rs->nn); - } - return x; -} -#define MODNN(x) modnn(rs, x) - -#define MM (rs->mm) -#define NN (rs->nn) -#define ALPHA_TO (rs->alpha_to) -#define INDEX_OF (rs->index_of) -#define GENPOLY (rs->genpoly) -#define NROOTS (rs->nroots) -#define FCR (rs->fcr) -#define PRIM (rs->prim) -#define IPRIM (rs->iprim) -#define A0 (NN) - -#define ENCODE_RS encode_rs_int -#define DECODE_RS decode_rs_int -#define INIT_RS init_rs_int -#define FREE_RS free_rs_int - -FEC_API void ENCODE_RS(void* p, DTYPE* data, DTYPE* parity); -FEC_API int DECODE_RS(void* p, DTYPE* data, int* eras_pos, int no_eras); -void* INIT_RS(unsigned int symsize, - unsigned int gfpoly, - unsigned int fcr, - unsigned int prim, - unsigned int nroots); -FEC_API void FREE_RS(void* p); diff --git a/blocklib/fec/lib/reed-solomon/meson.build b/blocklib/fec/lib/reed-solomon/meson.build deleted file mode 100644 index c5d99a910..000000000 --- a/blocklib/fec/lib/reed-solomon/meson.build +++ /dev/null @@ -1,71 +0,0 @@ -# Copyright 2010-2012 Free Software Foundation, Inc. -# -# This file is part of GNU Radio -# -# SPDX-License-Identifier: GPL-3.0-or-later -# - -# ######################################################################## -# # This file included, use CMake directory variables -# ######################################################################## -# #MSVC workaround: we can't have dynamically sized arrays. -# #So ifdef a max array bounds that is larger than NN and NROOTS -# #Its a bit of a hack, but if you look at the code, its so full of ifdefs, -# #and lacks optimization where it should be pre-allocating these arrays. -# if(MSVC) -# set_source_files_properties( -# ${CMAKE_CURRENT_SOURCE_DIR}/exercise.c -# ${CMAKE_CURRENT_SOURCE_DIR}/char.c -# PROPERTIES COMPILE_DEFINITIONS "MAX_ARRAY=256;" -# ) -# endif(MSVC) - -# add_library(gr_fec_rs OBJECT -# ${CMAKE_CURRENT_SOURCE_DIR}/ccsds.c -# ${CMAKE_CURRENT_SOURCE_DIR}/ccsds_tab.c -# ${CMAKE_CURRENT_SOURCE_DIR}/ccsds_tal.c -# ${CMAKE_CURRENT_SOURCE_DIR}/char.c -# ${CMAKE_CURRENT_SOURCE_DIR}/decode_rs_ccsds.c -# ${CMAKE_CURRENT_SOURCE_DIR}/encode_rs_ccsds.c -# ${CMAKE_CURRENT_SOURCE_DIR}/init_rs.c -# ) -# target_include_directories(gr_fec_rs -# PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/../../include> -# PRIVATE $<TARGET_PROPERTY:gnuradio-runtime,INCLUDE_DIRECTORIES> -# ) -# set_target_properties(gr_fec_rs PROPERTIES POSITION_INDEPENDENT_CODE ON) - -sources = [ - 'ccsds.c','ccsds_tab.c','ccsds_tal.c','char.c','decode_rs_ccsds.c','encode_rs_ccsds.c','init_rs.c' -] - -incdir = include_directories(['../../include/gnuradio/fec','../../include']) - -gnuradio_blocklib_fec_lib = library('gnuradio-blocklib-fec', - sources, - include_directories : incdir, - install : true, - dependencies : [gnuradio_gr_dep], - pic : true) - -gnuradio_blocklib_fec_dep = declare_dependency(include_directories : incdir, - link_with : gnuradio_blocklib_fec_lib) - - -# target_sources(gnuradio-fec PRIVATE $<TARGET_OBJECTS:gr_fec_rs>) - -# ######################################################################## -# # Register unit tests -# ######################################################################## -# if(ENABLE_TESTING) -# add_executable(gr_fec_rstest -# ${CMAKE_CURRENT_SOURCE_DIR}/exercise.c -# ${CMAKE_CURRENT_SOURCE_DIR}/rstest.c -# $<TARGET_OBJECTS:gr_fec_rs> -# ) -# target_link_libraries(gr_fec_rstest gnuradio-runtime) -# target_include_directories(gr_fec_rstest -# PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../../include -# ) -# add_test(test_rs gr_fec_rstest) -# endif(ENABLE_TESTING) diff --git a/blocklib/fec/lib/reed-solomon/rs.3 b/blocklib/fec/lib/reed-solomon/rs.3 deleted file mode 100644 index c3953ce57..000000000 --- a/blocklib/fec/lib/reed-solomon/rs.3 +++ /dev/null @@ -1,170 +0,0 @@ -.TH REED-SOLOMON 3 -.SH NAME -init_rs_int, encode_rs_int, decode_rs_int, free_rs_int, -init_rs_char, encode_rs_char, decode_rs_char, free_rs_char, -encode_rs_8, decode_rs_8, encode_rs_ccsds, decode_rs_ccsds -.SH SYNOPSIS -.nf -.ft B -#include "rs.h" - -void *init_rs_int(unsigned int symsize,unsigned int gfpoly,unsigned fcr, -unsigned prim,unsigned int nroots); -void encode_rs_int(void *rs,int *data,int *parity); -int decode_rs_int(void *rs,int *data,int *eras_pos,int no_eras); -void free_rs_int(void *rs); - -void *init_rs_char(unsigned int symsize,unsigned int gfpoly,unsigned fcr, -unsigned prim,unsigned int nroots); -void encode_rs_char(void *rs,unsigned char *data,unsigned char *parity); -int decode_rs_char(void *rs,unsigned char *data,int *eras_pos,int no_eras); -void free_rs_char(void *rs); - -void encode_rs_8(unsigned char *data,unsigned char *parity); -int decode_rs_8(unsigned char *data,int *eras_pos,int no_eras); - -void encode_rs_ccsds(unsigned char *data,unsigned char *parity); -int decode_rs_ccsds(unsigned char *data,int *eras_pos,int no_eras); - -unsigned char Taltab[256]; -unsigned char Tal1tab[256]; - -.fi - -.SH DESCRIPTION -These functions implement Reed-Solomon error control encoding and -decoding. For optimal performance in a variety of applications, three -sets of functions are supplied. To access these functions, add "-lrs" -to your linker command line. - -The functions with names ending in "_int" handle data in integer arrays, -permitting arbitrarily large codewords limited only by machine -resources. - -The functions with names ending in "_char" take unsigned char arrays and can -handle codes with symbols of 8 bits or less (i.e., with codewords of -255 symbols or less). - -\fBencode_rs_8\fR and \fBdecode_rs_8\fR implement a specific -(255,223) code with 8-bit symbols specified by the CCSDS: -a field generator of 1 + X + X^2 + X^7 + X^8 and a code -generator with first consecutive root = 112 and a primitive element of -11. These functions use the conventional -polynomial form, \fBnot\fR the dual-basis specified in -the CCSDS standard, to represent symbols. - -For full CCSDS compatibility, \fBencode_rs_ccsds\fR and -\fBdecode_rs_ccsds\fR are provided. These functions use two lookup -tables, \fBTaltab\fR to convert from conventional to dual-basis, and -\fBTal1tab\fR to perform the inverse mapping from dual-basis to -conventional form, before and after calls to \fBencode_rs_8\fR -and \fBdecode_rs_8\fR. - -The _8 and _ccsds functions do not require initialization. -To use the general purpose RS encoder or decoder (i.e., -the _char or _int versions), the user must first -call \fBinit_rs_int\fR or \fBinit_rs_char\fR as appropriate. The -arguments are as follows: - -\fBsymsize\fR gives the symbol size in bits, up to 8 for \fBinit_rs_char\fR -or 32 for \fBinit_rs_int\fR on a machine with 32-bit ints (though such a -huge code would exhaust memory limits on a 32-bit machine). The resulting -Reed-Solomon code word will have 2^\fBsymsize\fR - 1 symbols, -each containing \fBsymsize\fR bits. - -\fBgfpoly\fR gives the extended Galois field generator polynomial coefficients, -with the 0th coefficient in the low order bit. The polynomial -\fImust\fR be primitive; if not, the call will fail and NULL will be -returned. - -\fBfcr\fR gives, in index form, the first consecutive root of the -Reed Solomon code generator polynomial. - -\fBprim\fR gives, in index form, the primitive element in the Galois field -used to generate the Reed Solomon code generator polynomial. - -\fBnroots\fR gives the number of roots in the Reed Solomon code -generator polynomial. This equals the number of parity symbols -per code block. - -The resulting Reed-Solomon code has parameters (N,K), where -N = 2^\fBsymsize\fR-1 and K = N-\fBnroots\fR. - -The \fBencode_rs_char\fR and \fBencode_rs_int\fR functions accept -the pointer returned by \fBinit_rs_char\fR or -\fBinit_rs_int\fR, respectively, to -encode a block of data using the specified code. -The input data array is expected to -contain K symbols (of \fBsymsize\fR bits each, right justified -in each char or int) and \fBnroots\fR parity symbols will be placed -into the \fBparity\fR array, right justified. - -The \fBdecode_rs_char\fR and \fBdecode_rs_int\fR functions correct -the errors in a Reed-Solomon codeword up to the capability of the code. -An optional list of "erased" symbol indices may be given in the \fBeras_pos\fR -array to assist the decoder; this parameter may be NULL if no erasures -are given. The number of erased symbols must be given in the \fBno_eras\fR -parameter. - -To maximize performance, the encode and decode functions perform no -"sanity checking" of their inputs. Decoder failure may result if -\fBeras_pos\fR contains duplicate entries, and both encoder and -decoder will fail if an input symbol exceeds its allowable range. -(Symbol range overflow cannot occur with the _8 or _ccsds functions, -or with the _char functions when 8-bit symbols are specified.) - -The decoder corrects the symbols "in place", returning the number -of symbols in error. If the codeword is uncorrectable, -1 is returned -and the data block is unchanged. If \fBeras_pos\fR is non-null, it is -used to return a list of corrected symbol positions, in no particular -order. This means that the -array passed through this parameter \fImust\fR have at least \fBnroots\fR -elements to prevent a possible buffer overflow. - -The \fBfree_rs_int\fR and \fBfree_rs_char\fR functions free the internal -space allocated by the \fBinit_rs_int\fR and \fBinit_rs_char\fR functions, -respecitively. - -The functions \fBencode_rs_8\fR and \fBdecode_rs_8\fR do not have -corresponding \fBinit\fR and \fBfree\fR, nor do they take the -\fBrs\fR argument accepted by the other functions as their parameters -are statically compiled. These functions implement a code -equivalent to calling - -\fBinit_rs_char\fR(8,0x187,112,11,32); - -and using the resulting pointer with \fBencode_rs_char\fR and -\fBdecode_rs_char\fR. - -.SH RETURN VALUES -\fBinit_rs_int\fR and \fBinit_rs_char\fR return a pointer to an internal -control structure that must be passed to the corresponding encode, decode -and free functions. These functions return NULL on error. - -The decode functions return a count of corrected -symbols, or -1 if the block was uncorrectible. - -.SH AUTHOR -Phil Karn, KA9Q (karn@ka9q.net), based heavily on earlier work by Robert -Morelos-Zaragoza (rober@spectra.eng.hawaii.edu) and Hari Thirumoorthy -(harit@spectra.eng.hawaii.edu). - -.SH COPYRIGHT -Copyright 2002, Phil Karn, KA9Q. May be used under the terms of the -GNU General Public License (GPL). - -.SH SEE ALSO -CCSDS 101.0-B-5: Telemetry Channel Coding. -http://www.ccsds.org/documents/pdf/CCSDS-101.0-B-5.pdf - -.SH NOTE -CCSDS chose the "dual basis" symbol representation because it -simplified the implementation of a Reed-Solomon encoder in dedicated -hardware. However, this approach holds no advantages for a software -implementation on a general purpose computer, so use of the dual basis -is recommended only if compatibility with the CCSDS standard is needed, -e.g., to decode data from an existing spacecraft using the CCSDS -standard. If you just want a fast (255,223) RS codec without needing -to interoperate with a CCSDS standard code, use \fBencode_rs_8\fR -and \fBdecode_rs_8\fR. - diff --git a/blocklib/fec/lib/reed-solomon/rstest.c b/blocklib/fec/lib/reed-solomon/rstest.c deleted file mode 100644 index cfc2d62bc..000000000 --- a/blocklib/fec/lib/reed-solomon/rstest.c +++ /dev/null @@ -1,123 +0,0 @@ -/* Test the Reed-Solomon codecs - * for various block sizes and with random data and random error patterns - * - * Copyright 2002 Phil Karn, KA9Q - * May be used under the terms of the GNU General Public License (GPL) - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <gnuradio/fec/rs.h> -#include <stdio.h> -#include <stdlib.h> -#include <time.h> - -int exercise_char(void*, int); - -#ifdef ALL_VERSIONS -int exercise_int(void*, int); -int exercise_8(int); -int exercise_ccsds(int); -#endif - -struct { - int symsize; - int genpoly; - int fcs; - int prim; - int nroots; - int ntrials; -} Tab[] = { - { 2, 0x7, 1, 1, 1, 10 }, - { 3, 0xb, 1, 1, 2, 10 }, - { 4, 0x13, 1, 1, 4, 10 }, - { 5, 0x25, 1, 1, 6, 10 }, - { 6, 0x43, 1, 1, 8, 10 }, - { 7, 0x89, 1, 1, 10, 10 }, - { 8, 0x11d, 1, 1, 32, 10 }, - { 8, 0x187, 112, 11, 32, 10 }, /* Duplicates CCSDS codec */ -#ifdef ALL_VESIONS - { 9, 0x211, 1, 1, 32, 10 }, - { 10, 0x409, 1, 1, 32, 10 }, - { 11, 0x805, 1, 1, 32, 10 }, - { 12, 0x1053, 1, 1, 32, 5 }, - { 13, 0x201b, 1, 1, 32, 2 }, - { 14, 0x4443, 1, 1, 32, 1 }, - { 15, 0x8003, 1, 1, 32, 1 }, - { 16, 0x1100b, 1, 1, 32, 1 }, -#endif - { 0, 0, 0, 0, 0 }, -}; - -int main() -{ - void* handle; - int errs, terrs; - int i; - - terrs = 0; - srand(time(NULL)); - -#ifdef ALL_VERSIONS - printf("Testing fixed (255,223) RS codec..."); - fflush(stdout); - errs = exercise_8(10); - terrs += errs; - if (errs == 0) { - printf("OK\n"); - } - printf("Testing CCSDS standard (255,223) RS codec..."); - fflush(stdout); - errs = exercise_ccsds(10); - terrs += errs; - if (errs == 0) { - printf("OK\n"); - } -#endif - - for (i = 0; Tab[i].symsize != 0; i++) { - int nn, kk; - - nn = (1 << Tab[i].symsize) - 1; - kk = nn - Tab[i].nroots; - printf("Testing (%d,%d) RS codec...", nn, kk); - fflush(stdout); - if (Tab[i].symsize <= 8) { - if ((handle = init_rs_char(Tab[i].symsize, - Tab[i].genpoly, - Tab[i].fcs, - Tab[i].prim, - Tab[i].nroots)) == NULL) { - printf("init_rs_char failed!\n"); - continue; - } - errs = exercise_char(handle, Tab[i].ntrials); - } else { -#ifdef ALL_VERSIONS - if ((handle = init_rs_int(Tab[i].symsize, - Tab[i].genpoly, - Tab[i].fcs, - Tab[i].prim, - Tab[i].nroots)) == NULL) { - printf("init_rs_int failed!\n"); - continue; - } - errs = exercise_int(handle, Tab[i].ntrials); -#else - printf("init_rs_init support is not enabled\n"); - exit(1); -#endif - } - terrs += errs; - if (errs == 0) { - printf("OK\n"); - } - free_rs_char(handle); - } - if (terrs == 0) - printf("All codec tests passed!\n"); - - exit(0); -} diff --git a/blocklib/fec/meson.build b/blocklib/fec/meson.build deleted file mode 100644 index 0aa86b5b9..000000000 --- a/blocklib/fec/meson.build +++ /dev/null @@ -1,19 +0,0 @@ -subdir('include/gnuradio/fec') - -fec_sources = [] -fec_cu_sources = [] -fec_pybind_sources = [] -fec_pybind_names = [] -fec_deps = [] - -# Individual block subdirectories - - -subdir('lib') -# if (get_option('enable_python')) -# subdir('python/fec') -# endif - -# if (get_option('enable_testing')) -# subdir('test') -# endif
\ No newline at end of file diff --git a/blocklib/fec/python/gnuradio/fec/meson.build b/blocklib/fec/python/gnuradio/fec/meson.build deleted file mode 100644 index e69de29bb..000000000 --- a/blocklib/fec/python/gnuradio/fec/meson.build +++ /dev/null diff --git a/blocklib/fft/.gitignore b/blocklib/fft/.gitignore deleted file mode 100644 index 25d053a52..000000000 --- a/blocklib/fft/.gitignore +++ /dev/null @@ -1 +0,0 @@ -meson.build
\ No newline at end of file diff --git a/blocklib/fft/bench/bm_fft.py b/blocklib/fft/bench/bm_fft.py deleted file mode 100644 index a6c13659c..000000000 --- a/blocklib/fft/bench/bm_fft.py +++ /dev/null @@ -1,118 +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.schedulers import nbt -import sys -import signal -from argparse import ArgumentParser -from gnuradio.fft import window -import time -from gnuradio import filter - - -class benchmark_cuda_fft(gr.flowgraph): - - def __init__(self, args): - gr.flowgraph.__init__(self) - - ################################################## - # Variables - ################################################## - nsamples = args.samples - nblocks = args.nblocks - fftsize = args.fft_size - bufsize = args.buffer_size - - ################################################## - # Blocks - ################################################## - self.nsrc = blocks.null_source(gr.sizeof_gr_complex*fftsize) - self.nsnk = blocks.null_sink(gr.sizeof_gr_complex*fftsize) - self.hd = streamops.head(gr.sizeof_gr_complex * - fftsize, int(nsamples) // fftsize) - - blks = [] - if not args.cuda: - for ii in range(nblocks): - if ii % 2 == 0: - blks.append(fft.fft_cc_fwd(fftsize, [], False)) - else: - blks.append(fft.fft_cc_rev(fftsize, [], False)) - if (ii > 0): - self.connect(blks[ii-1], 0, blks[ii], 0) - - self.connect(self.hd, 0, blks[0], 0) - self.connect(self.nsrc, 0, self.hd, 0) - self.connect(blks[nblocks-1], 0, self.nsnk, 0) - else: - for ii in range(nblocks): - if ii % 2 == 0: - blks.append(fft.fft_cc_fwd(fftsize, [], False)) - else: - blks.append(fft.fft_cc_rev(fftsize, [], False)) - if (ii > 0): - self.connect(blks[ii-1], 0, blks[ii], 0).set_custom_buffer( - gr.buffer_cuda_properties.make(gr.buffer_cuda_type.D2D).set_buffer_size(bufsize)) - - self.connect(self.hd, 0, self.blks[0], 0) .set_custom_buffer( - gr.buffer_cuda_properties.make(gr.buffer_cuda_type.D2H).set_buffer_size(bufsize)) - self.connect(self.nsrc, 0, self.hd, 0).set_custom_buffer( - gr.buffer_cuda_properties.make(gr.buffer_cuda_type.H2D).set_buffer_size(bufsize)) - self.connect(blks[nblocks-1], 0, self.nsnk).set_custom_buffer( - gr.buffer_cuda_properties.make(gr.buffer_cuda_type.H2D).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_cuda_fft, 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('--nblocks', type=int, default=4) - parser.add_argument('--fft_size', type=int, default=1024) - 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/fft/fft/fft.yml b/blocklib/fft/fft/fft.yml deleted file mode 100644 index 03aac8424..000000000 --- a/blocklib/fft/fft/fft.yml +++ /dev/null @@ -1,54 +0,0 @@ -module: fft -block: fft -label: FFT -blocktype: sync_block -category: '[Core]/Fourier Analysis' - -typekeys: - - id: T - type: class - options: - - cf32 - - rf32 - - id: direction - type: bool - label: Direction - options: - - ['true','_fwd'] - - ['false','_rev'] - - -parameters: -- id: fft_size - label: FFT Size - dtype: size - settable: false -- id: window - label: Window - dtype: rf32 - container: vector - settable: false -- id: shift - label: Shift - dtype: bool - default: 'false' - settable: false - -ports: -- domain: stream - id: in - direction: input - type: typekeys/T - shape: parameters/fft_size - -- domain: stream - id: out - direction: output - type: typekeys/T - shape: parameters/fft_size - -implementations: -- id: cpu -- id: cuda - -file_format: 1 diff --git a/blocklib/fft/fft/fft_cpu.cc b/blocklib/fft/fft/fft_cpu.cc deleted file mode 100644 index 9f51276bf..000000000 --- a/blocklib/fft/fft/fft_cpu.cc +++ /dev/null @@ -1,198 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2004,2007,2008,2010,2012,2020 Free Software Foundation, Inc. - * Copyright 2021 Josh Morman - * - * This file is part of GNU Radio - * - * SPDX-License-Identifier: GPL-3.0-or-later - * - */ - -#include "fft_cpu.h" -#include "fft_cpu_gen.h" - -namespace gr { -namespace fft { - -template <class T, bool forward> -fft_cpu<T, forward>::fft_cpu(const typename fft<T, forward>::block_args& args) - : INHERITED_CONSTRUCTORS(T, forward), - d_fft_size(args.fft_size), - d_shift(args.shift), - d_fft(args.fft_size) -{ - if (args.window.empty() || args.window.size() == d_fft_size) { - d_window = args.window; - } - else { - throw std::runtime_error("fft: window not the same length as fft_size"); - } -} - -template <class T, bool forward> -void fft_cpu<T, forward>::set_nthreads(int n) -{ - d_fft.set_nthreads(n); -} - -template <class T, bool forward> -int fft_cpu<T, forward>::nthreads() const -{ - return d_fft.nthreads(); -} - -template <> -void fft_cpu<gr_complex, true>::fft_and_shift(const gr_complex* in, gr_complex* out) -{ - if (!d_window.empty()) { - gr_complex* dst = d_fft.get_inbuf(); - volk_32fc_32f_multiply_32fc(&dst[0], in, &d_window[0], d_fft_size); - } - else { - memcpy(d_fft.get_inbuf(), in, sizeof(gr_complex) * d_fft_size); - } - d_fft.execute(); - if (d_shift) { - unsigned int len = (unsigned int)(ceil(d_fft_size / 2.0)); - memcpy( - &out[0], &d_fft.get_outbuf()[len], sizeof(gr_complex) * (d_fft_size - len)); - memcpy(&out[d_fft_size - len], &d_fft.get_outbuf()[0], sizeof(gr_complex) * len); - } - else { - - memcpy(out, d_fft.get_outbuf(), sizeof(gr_complex) * d_fft_size); - } -} - -template <> -void fft_cpu<gr_complex, false>::fft_and_shift(const gr_complex* in, gr_complex* out) -{ - if (!d_window.empty()) { - gr_complex* dst = d_fft.get_inbuf(); - if (d_shift) { - unsigned int offset = d_fft_size / 2; - int fft_m_offset = d_fft_size - offset; - volk_32fc_32f_multiply_32fc(&dst[fft_m_offset], &in[0], &d_window[0], offset); - volk_32fc_32f_multiply_32fc( - &dst[0], &in[offset], &d_window[offset], d_fft_size - offset); - } - else { - volk_32fc_32f_multiply_32fc(&dst[0], in, &d_window[0], d_fft_size); - } - } - else { - if (d_shift) { // apply an ifft shift on the data - gr_complex* dst = d_fft.get_inbuf(); - unsigned int len = - (unsigned int)(floor(d_fft_size / 2.0)); // half length of complex array - memcpy(&dst[0], &in[len], sizeof(gr_complex) * (d_fft_size - len)); - memcpy(&dst[d_fft_size - len], &in[0], sizeof(gr_complex) * len); - } - else { - memcpy(d_fft.get_inbuf(), in, sizeof(gr_complex) * d_fft_size); - } - } - d_fft.execute(); - memcpy(out, d_fft.get_outbuf(), sizeof(gr_complex) * d_fft_size); -} - -template <> -void fft_cpu<float, true>::fft_and_shift(const float* in, gr_complex* out) -{ - // copy input into optimally aligned buffer - if (!d_window.empty()) { - gr_complex* dst = d_fft.get_inbuf(); - for (unsigned int i = 0; i < d_fft_size; i++) // apply window - dst[i] = in[i] * d_window[i]; - } - else { - gr_complex* dst = d_fft.get_inbuf(); - for (unsigned int i = 0; i < d_fft_size; i++) // float to complex conversion - dst[i] = in[i]; - } - - d_fft.execute(); - if (d_shift) { - unsigned int len = (unsigned int)(ceil(d_fft_size / 2.0)); - memcpy( - &out[0], &d_fft.get_outbuf()[len], sizeof(gr_complex) * (d_fft_size - len)); - memcpy(&out[d_fft_size - len], &d_fft.get_outbuf()[0], sizeof(gr_complex) * len); - } - else { - - memcpy(out, d_fft.get_outbuf(), sizeof(gr_complex) * d_fft_size); - } -} - -template <> -void fft_cpu<float, false>::fft_and_shift(const float* in, gr_complex* out) -{ - // copy input into optimally aligned buffer - if (!d_window.empty()) { - gr_complex* dst = d_fft.get_inbuf(); - if (d_shift) { - unsigned int len = - (unsigned int)(floor(d_fft_size / 2.0)); // half length of complex array - for (unsigned int i = 0; i < len; i++) { - dst[i] = in[len + i] * d_window[len + i]; - } - for (unsigned int i = len; i < d_fft_size; i++) { - dst[i] = in[i - len] * d_window[i - len]; - } - } - else { - for (unsigned int i = 0; i < d_fft_size; i++) // apply window - dst[i] = in[i] * d_window[i]; - } - } - else { - gr_complex* dst = d_fft.get_inbuf(); - if (d_shift) { - unsigned int len = - (unsigned int)(floor(d_fft_size / 2.0)); // half length of complex array - for (unsigned int i = 0; i < len; i++) { - dst[i] = in[len + i]; - } - for (unsigned int i = len; i < d_fft_size; i++) { - dst[i] = in[i - len]; - } - } - else { - for (unsigned int i = 0; i < d_fft_size; i++) // float to complex conversion - dst[i] = in[i]; - } - } - - // compute the fft - d_fft.execute(); - - // copy result to output stream - memcpy(out, d_fft.get_outbuf(), sizeof(gr_complex) * d_fft_size); -} - -template <class T, bool forward> -work_return_t fft_cpu<T, forward>::work(work_io& wio) -{ - auto in = wio.inputs()[0].items<T>(); - auto out = wio.outputs()[0].items<gr_complex>(); - auto noutput_items = wio.outputs()[0].n_items; - - size_t count = 0; - - while (count++ < noutput_items) { - - fft_and_shift(in, out); - - in += d_fft_size; - out += d_fft_size; - } - - - wio.produce_each(noutput_items); - return work_return_t::OK; -} - - -} // namespace fft -} // namespace gr
\ No newline at end of file diff --git a/blocklib/fft/fft/fft_cpu.h b/blocklib/fft/fft/fft_cpu.h deleted file mode 100644 index 186eb33ee..000000000 --- a/blocklib/fft/fft/fft_cpu.h +++ /dev/null @@ -1,41 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2004,2007,2008,2012,2020 Free Software Foundation, Inc. - * Copyright 2021 Josh Morman - * - * This file is part of GNU Radio - * - * SPDX-License-Identifier: GPL-3.0-or-later - * - */ - -#pragma once - -#include <gnuradio/fft/fft.h> -#include <gnuradio/kernel/fft/fftw_fft.h> - -namespace gr { -namespace fft { - -template <class T, bool forward> -class fft_cpu : public fft<T, forward> -{ -public: - fft_cpu(const typename fft<T, forward>::block_args& args); - work_return_t work(work_io&) override; - - void set_nthreads(int n); - int nthreads() const; - -protected: - size_t d_fft_size; - std::vector<float> d_window; - bool d_shift; - - kernel::fft::fftw_fft<gr_complex, forward> d_fft; - - void fft_and_shift(const T* in, gr_complex* out); -}; - -} // namespace fft -} // namespace gr
\ No newline at end of file diff --git a/blocklib/fft/fft/fft_cuda.cc b/blocklib/fft/fft/fft_cuda.cc deleted file mode 100644 index 5b4eeebad..000000000 --- a/blocklib/fft/fft/fft_cuda.cc +++ /dev/null @@ -1,102 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2021 Josh Morman - * - * This file is part of GNU Radio - * - * SPDX-License-Identifier: GPL-3.0-or-later - * - */ - -#include "fft_cuda.h" -#include "fft_cuda_gen.h" - - -extern void exec_fft_shift(const cuFloatComplex* in, - cuFloatComplex* out, - int n, - int grid_size, - int block_size, - cudaStream_t stream); - -namespace gr { -namespace fft { - -template <class T, bool forward> -fft_cuda<T, forward>::fft_cuda(const typename fft<T, forward>::block_args& args) - : INHERITED_CONSTRUCTORS(T, forward), - d_fft_size(args.fft_size), - d_shift(args.shift), - d_fft(args.fft_size) -{ - if (args.window.empty() || args.window.size() == d_fft_size) { - d_window = args.window; - } - else { - throw std::runtime_error("fft: window not the same length as fft_size"); - } - - cudaStreamCreate(&d_stream); -} - - -template <> -void fft_cuda<gr_complex, true>::fft_and_shift(const gr_complex* in, - gr_complex* out, - int batch) -{ - int blockSize = 1024; - int gridSize = (batch * d_fft_size + blockSize - 1) / blockSize; - if (d_shift) - exec_fft_shift((cuFloatComplex*)in, - (cuFloatComplex*)in, - batch * d_fft_size, - gridSize, - blockSize, - d_stream); - d_fft.launch(in, out, batch, d_stream); -} - -template <> -void fft_cuda<gr_complex, false>::fft_and_shift(const gr_complex* in, - gr_complex* out, - int batch) -{ - int blockSize = 1024; - int gridSize = (batch * d_fft_size + blockSize - 1) / blockSize; - if (d_shift) - exec_fft_shift((cuFloatComplex*)in, - (cuFloatComplex*)in, - batch * d_fft_size, - gridSize, - blockSize, - d_stream); - d_fft.launch(in, out, batch, d_stream); -} - -template <> -void fft_cuda<float, true>::fft_and_shift(const float* in, gr_complex* out, int batch) -{ -} - -template <> -void fft_cuda<float, false>::fft_and_shift(const float* in, gr_complex* out, int batch) -{ -} - -template <class T, bool forward> -work_return_t fft_cuda<T, forward>::work(work_io& wio) -{ - - auto in = wio.inputs()[0].items<T>(); - auto out = wio.outputs()[0].items<gr_complex>(); - auto noutput_items = wio.outputs()[0].n_items; - - fft_and_shift(in, out, noutput_items); - cudaStreamSynchronize(d_stream); - wio.produce_each(noutput_items); - return work_return_t::OK; -} - -} // namespace fft -} // namespace gr diff --git a/blocklib/fft/fft/fft_cuda.h b/blocklib/fft/fft/fft_cuda.h deleted file mode 100644 index afeea0138..000000000 --- a/blocklib/fft/fft/fft_cuda.h +++ /dev/null @@ -1,39 +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/fft/fft.h> -#include <cusp/fft.cuh> - -namespace gr { -namespace fft { - -template <class T, bool forward> -class fft_cuda : public fft<T, forward> -{ -public: - fft_cuda(const typename fft<T, forward>::block_args& args); - work_return_t work(work_io&) override; - -protected: - size_t d_fft_size; - std::vector<float> d_window; - bool d_shift; - cudaStream_t d_stream; - - // std::shared_ptr<cusp::fft<T,forward>> d_fft; - cusp::fft<T, forward> d_fft; - - void fft_and_shift(const T* in, gr_complex* out, int batch); -}; - -} // namespace fft -} // namespace gr
\ No newline at end of file diff --git a/blocklib/fft/fft/fft_shift.cu b/blocklib/fft/fft/fft_shift.cu deleted file mode 100644 index 235f7005c..000000000 --- a/blocklib/fft/fft/fft_shift.cu +++ /dev/null @@ -1,39 +0,0 @@ -#include <cuComplex.h> - -template <typename T> -__global__ void kernel_fft_shift(const T* in, T* out, int n); - -template <> -__global__ void kernel_fft_shift(const cuFloatComplex* in, cuFloatComplex* out, int n) -{ - int i = blockIdx.x * blockDim.x + threadIdx.x; - - if (i < n) { - float a = 1 - 2 * (i & 1); - out[i].x = in[i].x * a; - out[i].y = in[i].y * a; - } -} - -template <> -__global__ void kernel_fft_shift(const cuDoubleComplex* in, cuDoubleComplex* out, int n) -{ - int i = blockIdx.x * blockDim.x + threadIdx.x; - - if (i < n) { - double a = 1 - 2 * (i & 1); - out[i].x = in[i].x * a; - out[i].y = in[i].y * a; - } -} - - -void exec_fft_shift(const cuFloatComplex* in, - cuFloatComplex* out, - int n, - int grid_size, - int block_size, - cudaStream_t stream) -{ - kernel_fft_shift<<<grid_size, block_size, 0, stream>>>(in, out, n); -} diff --git a/blocklib/fft/include/gnuradio/fft/.gitignore b/blocklib/fft/include/gnuradio/fft/.gitignore deleted file mode 100644 index d53050d7d..000000000 --- a/blocklib/fft/include/gnuradio/fft/.gitignore +++ /dev/null @@ -1 +0,0 @@ -!meson.build diff --git a/blocklib/fft/include/gnuradio/fft/api.h b/blocklib/fft/include/gnuradio/fft/api.h deleted file mode 100644 index 492d3e899..000000000 --- a/blocklib/fft/include/gnuradio/fft/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_fft_EXPORTS -#define FFT_API __GR_ATTR_EXPORT -#else -#define FFT_API __GR_ATTR_IMPORT -#endif diff --git a/blocklib/fft/include/gnuradio/fft/meson.build b/blocklib/fft/include/gnuradio/fft/meson.build deleted file mode 100644 index b7dfa1e07..000000000 --- a/blocklib/fft/include/gnuradio/fft/meson.build +++ /dev/null @@ -1,7 +0,0 @@ -headers = [ - 'api.h', - # 'fftw_fft.h', - # 'window.h' -] - -install_headers(headers, subdir : 'gnuradio/fft') diff --git a/blocklib/fft/lib/.gitignore b/blocklib/fft/lib/.gitignore deleted file mode 100644 index 01ecb66ff..000000000 --- a/blocklib/fft/lib/.gitignore +++ /dev/null @@ -1 +0,0 @@ -!meson.build
\ No newline at end of file diff --git a/blocklib/fft/lib/meson.build b/blocklib/fft/lib/meson.build deleted file mode 100644 index b79654039..000000000 --- a/blocklib/fft/lib/meson.build +++ /dev/null @@ -1,60 +0,0 @@ -fft_deps += [gnuradio_gr_dep, volk_dep, fmt_dep, pmtf_dep, gr_kernel_fft_lib_dep] - -# fft_sources += ['fftw_fft.cc','window.cc'] - -if IMPLEMENT_CUDA - fft_deps += cuda_dep - fft_deps += cusp_dep -endif - -block_cpp_args = ['-DHAVE_CPU'] -if IMPLEMENT_CUDA - block_cpp_args += '-DHAVE_CUDA' - - gnuradio_blocklib_fft_cu = library('gnuradio-blocklib-fft-cu', - fft_cu_sources, - include_directories : incdir, - install : true, - dependencies : [cuda_dep]) - - gnuradio_blocklib_fft_cu_dep = declare_dependency(include_directories : incdir, - link_with : gnuradio_blocklib_fft_cu, - dependencies : cuda_dep) - - fft_deps += [gnuradio_blocklib_fft_cu_dep, cuda_dep] - # fft_deps += [cuda_dep] - -endif - -incdir = include_directories(['../include/gnuradio/fft','../include']) -gnuradio_blocklib_fft_lib = library('gnuradio-blocklib-fft', - fft_sources, - include_directories : incdir, - install : true, - link_language: 'cpp', - dependencies : fft_deps, - cpp_args : block_cpp_args) - -gnuradio_blocklib_fft_dep = declare_dependency(include_directories : incdir, - link_with : gnuradio_blocklib_fft_lib, - dependencies : fft_deps) - -cmake_conf = configuration_data() -cmake_conf.set('libdir', join_paths(prefix,get_option('libdir'))) -cmake_conf.set('module', 'fft') -cmake.configure_package_config_file( - name : 'gnuradio-fft', - 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_fft_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-fft', - filebase : 'gnuradio-fft', - description : 'GNU Radio FFT Module') diff --git a/blocklib/fft/python/gnuradio/fft/.gitignore b/blocklib/fft/python/gnuradio/fft/.gitignore deleted file mode 100644 index 87a129428..000000000 --- a/blocklib/fft/python/gnuradio/fft/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -./meson.build -!bindings/meson.build
\ No newline at end of file diff --git a/blocklib/fft/python/gnuradio/fft/__init__.py b/blocklib/fft/python/gnuradio/fft/__init__.py deleted file mode 100644 index 22e856a99..000000000 --- a/blocklib/fft/python/gnuradio/fft/__init__.py +++ /dev/null @@ -1,9 +0,0 @@ - -import os - -try: - from .fft_python import * -except ImportError: - dirname, filename = os.path.split(os.path.abspath(__file__)) - __path__.append(os.path.join(dirname, "bindings")) - from .fft_python import * diff --git a/blocklib/fft/python/gnuradio/fft/bindings/meson.build b/blocklib/fft/python/gnuradio/fft/bindings/meson.build deleted file mode 100644 index 82b25a1f2..000000000 --- a/blocklib/fft/python/gnuradio/fft/bindings/meson.build +++ /dev/null @@ -1,2 +0,0 @@ -# fft_pybind_sources = [files('window_pybind.cc')] + fft_pybind_sources -# fft_pybind_names = ['window'] + fft_pybind_names
\ No newline at end of file diff --git a/blocklib/fft/python/gnuradio/fft/bindings/window_pybind.cc b/blocklib/fft/python/gnuradio/fft/bindings/window_pybind.cc deleted file mode 100644 index f60e55669..000000000 --- a/blocklib/fft/python/gnuradio/fft/bindings/window_pybind.cc +++ /dev/null @@ -1,174 +0,0 @@ -/* - * Copyright 2020,2021 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(window.h) */ -/* BINDTOOL_HEADER_FILE_HASH(872e1911444c9a5982f4d00af81a2def) */ -/***********************************************************************************/ - -#include <pybind11/complex.h> -#include <pybind11/pybind11.h> -#include <pybind11/stl.h> - -namespace py = pybind11; - -#include <gnuradio/kernel/fft/window.h> - -void bind_window(py::module& m) -{ - using window = gr::kernel::fft::window; - - py::class_<window, std::shared_ptr<window>> window_class(m, "window"); - - py::enum_<gr::kernel::fft::window::window_t>(window_class, "window_t") - .value("HAMMING", gr::kernel::fft::window::HAMMING) // 0 - .value("HANN", gr::kernel::fft::window::HANN) // 1 - .value("HANNING", gr::kernel::fft::window::HANNING) // 1 - .value("BLACKMAN", gr::kernel::fft::window::BLACKMAN) // 2 - .value("RECTANGULAR", gr::kernel::fft::window::RECTANGULAR) // 3 - .value("KAISER", gr::kernel::fft::window::KAISER) // 4 - .value("BLACKMAN_hARRIS", gr::kernel::fft::window::BLACKMAN_hARRIS) // 5 - .value("BLACKMAN_HARRIS", gr::kernel::fft::window::BLACKMAN_HARRIS) // 5 - .value("BARTLETT", gr::kernel::fft::window::BARTLETT) // 6 - .value("FLATTOP", gr::kernel::fft::window::FLATTOP) // 7 - .value("NUTTALL", gr::kernel::fft::window::NUTTALL) // 8 - .value("BLACKMAN_NUTTALL", gr::kernel::fft::window::BLACKMAN_NUTTALL) // 8 - .value("NUTTALL_CFD", gr::kernel::fft::window::NUTTALL_CFD) // 9 - .value("WELCH", gr::kernel::fft::window::WELCH) // 10 - .value("PARZEN", gr::kernel::fft::window::PARZEN) // 11 - .value("EXPONENTIAL", gr::kernel::fft::window::EXPONENTIAL) // 12 - .value("RIEMANN", gr::kernel::fft::window::RIEMANN) // 13 - .value("GAUSSIAN", gr::kernel::fft::window::GAUSSIAN) // 14 - .value("TUKEY", gr::kernel::fft::window::TUKEY) // 15 - .export_values(); - - py::implicitly_convertible<int, gr::kernel::fft::window::window_t>(); - - window_class - .def_static("max_attenuation", - &window::max_attenuation, - py::arg("type"), - py::arg("param") = 6.7599999999999998) - - - .def_static("coswindow", - (std::vector<float>(*)(int, float, float, float)) & window::coswindow, - py::arg("ntaps"), - py::arg("c0"), - py::arg("c1"), - py::arg("c2")) - - - .def_static("coswindow", - (std::vector<float>(*)(int, float, float, float, float)) & - window::coswindow, - py::arg("ntaps"), - py::arg("c0"), - py::arg("c1"), - py::arg("c2"), - py::arg("c3")) - - - .def_static("coswindow", - (std::vector<float>(*)(int, float, float, float, float, float)) & - window::coswindow, - py::arg("ntaps"), - py::arg("c0"), - py::arg("c1"), - py::arg("c2"), - py::arg("c3"), - py::arg("c4")) - - - .def_static("rectangular", &window::rectangular, py::arg("ntaps")) - - - .def_static("hamming", &window::hamming, py::arg("ntaps")) - - - .def_static("hann", &window::hann, py::arg("ntaps")) - - - .def_static("hanning", &window::hanning, py::arg("ntaps")) - - - .def_static("blackman", &window::blackman, py::arg("ntaps")) - - - .def_static("blackman2", &window::blackman2, py::arg("ntaps")) - - - .def_static("blackman3", &window::blackman3, py::arg("ntaps")) - - - .def_static("blackman4", &window::blackman4, py::arg("ntaps")) - - - .def_static("blackman_harris", - &window::blackman_harris, - py::arg("ntaps"), - py::arg("atten") = 92) - - - .def_static("blackmanharris", - &window::blackmanharris, - py::arg("ntaps"), - py::arg("atten") = 92) - - - .def_static("nuttall", &window::nuttall, py::arg("ntaps")) - - - .def_static("blackman_nuttall", &window::blackman_nuttall, py::arg("ntaps")) - - - .def_static("nuttall_cfd", &window::nuttall_cfd, py::arg("ntaps")) - - - .def_static("flattop", &window::flattop, py::arg("ntaps")) - - - .def_static("kaiser", &window::kaiser, py::arg("ntaps"), py::arg("beta")) - - - .def_static("bartlett", &window::bartlett, py::arg("ntaps")) - - - .def_static("welch", &window::welch, py::arg("ntaps")) - - - .def_static("parzen", &window::parzen, py::arg("ntaps")) - - - .def_static("exponential", &window::exponential, py::arg("ntaps"), py::arg("d")) - - - .def_static("riemann", &window::riemann, py::arg("ntaps")) - - - .def_static("tukey", &window::tukey, py::arg("ntaps"), py::arg("alpha")) - - - .def_static("gaussian", &window::gaussian, py::arg("ntaps"), py::arg("sigma")) - - - .def_static("build", - &window::build, - py::arg("type"), - py::arg("ntaps"), - py::arg("param") = 6.76, - py::arg("normalize") = false) - - ; -} diff --git a/blocklib/fft/test/.gitignore b/blocklib/fft/test/.gitignore deleted file mode 100644 index 01ecb66ff..000000000 --- a/blocklib/fft/test/.gitignore +++ /dev/null @@ -1 +0,0 @@ -!meson.build
\ No newline at end of file diff --git a/blocklib/fft/test/meson.build b/blocklib/fft/test/meson.build deleted file mode 100644 index 6f6fcb4f3..000000000 --- a/blocklib/fft/test/meson.build +++ /dev/null @@ -1,11 +0,0 @@ -################################################### -# QA -################################################### - -if GR_ENABLE_PYTHON - test('qa_fft', py3, args : files('qa_fft.py'), env: TEST_ENV) - if (IMPLEMENT_CUDA) - test('qa_cufft', py3, args : files('qa_cufft.py'), env: TEST_ENV) - endif - -endif diff --git a/blocklib/fft/test/qa_cufft.py b/blocklib/fft/test/qa_cufft.py deleted file mode 100644 index d5e670c12..000000000 --- a/blocklib/fft/test/qa_cufft.py +++ /dev/null @@ -1,280 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright 2008,2010,2012 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, blocks - -# Note: Octave code to verify these results: -# primes = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, -# 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311] -# src_data = primes(1:2:end) + primes(2:2:end)*i -# forward = fft(src_data(:)) -# reverse = ifft(forward(:)) -# windowed = fft(src_data(:).*hamming(32)) -# reverse_window_shift = ifft(fftshift(forward.*hamming(32))) - -primes = ( - 2, - 3, - 5, - 7, - 11, - 13, - 17, - 19, - 23, - 29, - 31, - 37, - 41, - 43, - 47, - 53, - 59, - 61, - 67, - 71, - 73, - 79, - 83, - 89, - 97, - 101, - 103, - 107, - 109, - 113, - 127, - 131, - 137, - 139, - 149, - 151, - 157, - 163, - 167, - 173, - 179, - 181, - 191, - 193, - 197, - 199, - 211, - 223, - 227, - 229, - 233, - 239, - 241, - 251, - 257, - 263, - 269, - 271, - 277, - 281, - 283, - 293, - 307, - 311) - -primes_transformed = ((4377 + 4516j), - (-1706.1268310546875 + 1638.4256591796875j), - (-915.2083740234375 + 660.69427490234375j), - (-660.370361328125 + 381.59600830078125j), - (-499.96044921875 + 238.41630554199219j), - (-462.26748657226562 + 152.88948059082031j), - (-377.98440551757812 + 77.5928955078125j), - (-346.85821533203125 + 47.152004241943359j), - (-295 + 20j), - (-286.33609008789062 - 22.257017135620117j), - (-271.52999877929688 - 33.081821441650391j), - (-224.6358642578125 - 67.019538879394531j), - (-244.24473571777344 - 91.524826049804688j), - (-203.09068298339844 - 108.54627227783203j), - (-198.45195007324219 - 115.90768432617188j), - (-182.97744750976562 - 128.12318420410156j), - (-167 - 180j), - (-130.33688354492188 - 173.83778381347656j), - (-141.19784545898438 - 190.28807067871094j), - (-111.09677124023438 - 214.48896789550781j), - (-70.039543151855469 - 242.41630554199219j), - (-68.960540771484375 - 228.30015563964844j), - (-53.049201965332031 - 291.47097778320312j), - (-28.695289611816406 - 317.64553833007812j), - (57 - 300j), - (45.301143646240234 - 335.69509887695312j), - (91.936195373535156 - 373.32437133789062j), - (172.09465026855469 - 439.275146484375j), - (242.24473571777344 - 504.47515869140625j), - (387.81732177734375 - 666.6788330078125j), - (689.48553466796875 - 918.2142333984375j), - (1646.539306640625 - 1694.1956787109375j)) - - -class test_fft(gr_unittest.TestCase): - def setUp(self): - self.tb = gr.flowgraph() - self.rt = gr.runtime() - self.fft_size = 32 - - def tearDown(self): - pass - - def assert_fft_ok2(self, expected_result, result_data): - expected_result = expected_result[:len(result_data)] - self.assertComplexTuplesAlmostEqual2(expected_result, result_data, - abs_eps=1e-9, rel_eps=4e-4) - - def test_forward(self): - src_data = tuple([complex(primes[2 * i], primes[2 * i + 1]) - for i in range(self.fft_size)]) - expected_result = primes_transformed - - src = blocks.vector_source_c(src_data, False, self.fft_size) - op = fft.fft_cc_fwd(self.fft_size, [], False, fft.fft_cc_fwd.cuda) - dst = blocks.vector_sink_c(self.fft_size) - self.tb.connect(src, 0, op, 0).set_custom_buffer(gr.buffer_cuda_properties.make(gr.buffer_cuda_type.H2D)) - self.tb.connect(op, 0, dst, 0).set_custom_buffer(gr.buffer_cuda_properties.make(gr.buffer_cuda_type.D2H)) - self.rt.initialize(self.tb) - self.rt.run() - result_data = dst.data() - self.assert_fft_ok2(expected_result, result_data) - - def test_reverse(self): - src_data = tuple([x / self.fft_size for x in primes_transformed]) - expected_result = tuple( - [complex(primes[2 * i], primes[2 * i + 1]) for i in range(self.fft_size)]) - - src = blocks.vector_source_c(src_data, False, self.fft_size) - op = fft.fft_cc_rev(self.fft_size, [], False, fft.fft_cc_rev.cuda) - dst = blocks.vector_sink_c(self.fft_size) - self.tb.connect(src, 0, op, 0).set_custom_buffer(gr.buffer_cuda_properties.make(gr.buffer_cuda_type.H2D)) - self.tb.connect(op, 0, dst, 0).set_custom_buffer(gr.buffer_cuda_properties.make(gr.buffer_cuda_type.D2H)) - self.rt.initialize(self.tb) - self.rt.run() - result_data = dst.data() - self.assert_fft_ok2(expected_result, result_data) - - # def test_multithreaded(self): - # # Same test as above, only use 2 threads - # src_data = tuple([x / self.fft_size for x in primes_transformed]) - # expected_result = tuple( - # [complex(primes[2 * i], primes[2 * i + 1]) for i in range(self.fft_size)]) - # nthreads = 2 - - # src = blocks.vector_source_c(src_data) - # s2v = blocks.stream_to_vector(gr.sizeof_gr_complex, self.fft_size) - # op = fft.fft_vcc(self.fft_size, False, [], False, nthreads) - # v2s = blocks.vector_to_stream(gr.sizeof_gr_complex, self.fft_size) - # dst = blocks.vector_sink_c() - # self.tb.connect(src, s2v, op, v2s, dst) - # self.tb.run() - # result_data = dst.data() - # self.assert_fft_ok2(expected_result, result_data) - - # def test_window(self): - # src_data = tuple([complex(primes[2 * i], primes[2 * i + 1]) - # for i in range(self.fft_size)]) - # expected_result = ((2238.9174 + 2310.4750j), - # (-1603.7416 - 466.7420j), - # (116.7449 - 70.8553j), - # (-13.9157 + 19.0855j), - # (-4.8283 + 16.7025j), - # (-43.7425 + 16.9871j), - # (-16.1904 + 1.7494j), - # (-32.3797 + 6.9964j), - # (-13.5283 + 7.7721j), - # (-24.3276 - 7.5378j), - # (-29.2711 + 4.5709j), - # (-2.7124 - 6.6307j), - # (-33.5486 - 8.3485j), - # (-8.3016 - 9.9534j), - # (-18.8590 - 8.3501j), - # (-13.9092 - 1.1396j), - # (-17.7626 - 26.9281j), - # (0.0182 - 8.9000j), - # (-19.9143 - 14.1320j), - # (-10.3073 - 15.5759j), - # (3.5800 - 29.1835j), - # (-7.5263 - 1.5900j), - # (-3.0392 - 31.7445j), - # (-15.1355 - 33.6158j), - # (28.2345 - 11.4373j), - # (-6.0055 - 27.0418j), - # (5.2074 - 21.2431j), - # (23.1617 - 31.8610j), - # (13.6494 - 11.1982j), - # (14.7145 - 14.4113j), - # (-60.0053 + 114.7418j), - # (-440.1561 - 1632.9807j)) - # window = fft.window.hamming(ntaps=self.fft_size) - - # src = blocks.vector_source_c(src_data) - # s2v = blocks.stream_to_vector(gr.sizeof_gr_complex, self.fft_size) - # op = fft.fft_vcc(self.fft_size, True, window, False) - # v2s = blocks.vector_to_stream(gr.sizeof_gr_complex, self.fft_size) - # dst = blocks.vector_sink_c() - # self.tb.connect(src, s2v, op, v2s, dst) - # self.tb.run() - # result_data = dst.data() - # self.assert_fft_ok2(expected_result, result_data) - - # def test_reverse_window_shift(self): - # src_data = tuple([x / self.fft_size for x in primes_transformed]) - # expected_result = ((-74.8629 - 63.2502j), - # (-3.5446 - 2.0365j), - # (2.9231 + 1.6827j), - # (-2.7852 - 0.8613j), - # (2.4763 + 2.7881j), - # (-2.7457 - 3.2602j), - # (4.7748 + 2.4145j), - # (-2.8807 - 4.5313j), - # (5.9949 + 4.1976j), - # (-6.1095 - 6.0681j), - # (5.2248 + 5.7743j), - # (-6.0436 - 6.3773j), - # (9.7184 + 9.2482j), - # (-8.2791 - 8.6507j), - # (6.3273 + 6.1560j), - # (-12.2841 - 12.4692j), - # (10.5816 + 10.0241j), - # (-13.0312 - 11.9451j), - # (12.2983 + 13.3644j), - # (-13.0372 - 14.0795j), - # (14.4682 + 13.3079j), - # (-16.7673 - 16.7287j), - # (14.3946 + 11.5916j), - # (-16.8368 - 21.3156j), - # (20.4528 + 16.8499j), - # (-18.4075 - 18.2446j), - # (17.7507 + 19.2109j), - # (-21.5207 - 20.7159j), - # (22.2183 + 19.8012j), - # (-22.2144 - 20.0343j), - # (17.0359 + 17.6910j), - # (-91.8955 - 103.1093j)) - # window = fft.window.hamming(ntaps=self.fft_size) - - # src = blocks.vector_source_c(src_data) - # s2v = blocks.stream_to_vector(gr.sizeof_gr_complex, self.fft_size) - # op = fft.fft_vcc(self.fft_size, False, window, True) - # v2s = blocks.vector_to_stream(gr.sizeof_gr_complex, self.fft_size) - # dst = blocks.vector_sink_c() - # self.tb.connect(src, s2v, op, v2s, dst) - # self.tb.run() - # result_data = dst.data() - # self.assert_fft_ok2(expected_result, result_data) - - -if __name__ == '__main__': - gr_unittest.run(test_fft) - diff --git a/blocklib/fft/test/qa_fft.py b/blocklib/fft/test/qa_fft.py deleted file mode 100644 index c38e5840a..000000000 --- a/blocklib/fft/test/qa_fft.py +++ /dev/null @@ -1,280 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright 2008,2010,2012 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, blocks - -# Note: Octave code to verify these results: -# primes = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, -# 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311] -# src_data = primes(1:2:end) + primes(2:2:end)*i -# forward = fft(src_data(:)) -# reverse = ifft(forward(:)) -# windowed = fft(src_data(:).*hamming(32)) -# reverse_window_shift = ifft(fftshift(forward.*hamming(32))) - -primes = ( - 2, - 3, - 5, - 7, - 11, - 13, - 17, - 19, - 23, - 29, - 31, - 37, - 41, - 43, - 47, - 53, - 59, - 61, - 67, - 71, - 73, - 79, - 83, - 89, - 97, - 101, - 103, - 107, - 109, - 113, - 127, - 131, - 137, - 139, - 149, - 151, - 157, - 163, - 167, - 173, - 179, - 181, - 191, - 193, - 197, - 199, - 211, - 223, - 227, - 229, - 233, - 239, - 241, - 251, - 257, - 263, - 269, - 271, - 277, - 281, - 283, - 293, - 307, - 311) - -primes_transformed = ((4377 + 4516j), - (-1706.1268310546875 + 1638.4256591796875j), - (-915.2083740234375 + 660.69427490234375j), - (-660.370361328125 + 381.59600830078125j), - (-499.96044921875 + 238.41630554199219j), - (-462.26748657226562 + 152.88948059082031j), - (-377.98440551757812 + 77.5928955078125j), - (-346.85821533203125 + 47.152004241943359j), - (-295 + 20j), - (-286.33609008789062 - 22.257017135620117j), - (-271.52999877929688 - 33.081821441650391j), - (-224.6358642578125 - 67.019538879394531j), - (-244.24473571777344 - 91.524826049804688j), - (-203.09068298339844 - 108.54627227783203j), - (-198.45195007324219 - 115.90768432617188j), - (-182.97744750976562 - 128.12318420410156j), - (-167 - 180j), - (-130.33688354492188 - 173.83778381347656j), - (-141.19784545898438 - 190.28807067871094j), - (-111.09677124023438 - 214.48896789550781j), - (-70.039543151855469 - 242.41630554199219j), - (-68.960540771484375 - 228.30015563964844j), - (-53.049201965332031 - 291.47097778320312j), - (-28.695289611816406 - 317.64553833007812j), - (57 - 300j), - (45.301143646240234 - 335.69509887695312j), - (91.936195373535156 - 373.32437133789062j), - (172.09465026855469 - 439.275146484375j), - (242.24473571777344 - 504.47515869140625j), - (387.81732177734375 - 666.6788330078125j), - (689.48553466796875 - 918.2142333984375j), - (1646.539306640625 - 1694.1956787109375j)) - - -class test_fft(gr_unittest.TestCase): - def setUp(self): - self.tb = gr.flowgraph() - self.rt = gr.runtime() - self.fft_size = 32 - - def tearDown(self): - pass - - def assert_fft_ok2(self, expected_result, result_data): - expected_result = expected_result[:len(result_data)] - self.assertComplexTuplesAlmostEqual2(expected_result, result_data, - abs_eps=1e-9, rel_eps=4e-4) - - def test_forward(self): - src_data = tuple([complex(primes[2 * i], primes[2 * i + 1]) - for i in range(self.fft_size)]) - expected_result = primes_transformed - - src = blocks.vector_source_c(src_data, False, self.fft_size) - op = fft.fft_cc_fwd(self.fft_size, [], False) - dst = blocks.vector_sink_c(self.fft_size) - self.tb.connect(src, 0, op, 0) - self.tb.connect(op, 0, dst, 0) - self.rt.initialize(self.tb) - self.rt.run() - result_data = dst.data() - self.assert_fft_ok2(expected_result, result_data) - - def test_reverse(self): - src_data = tuple([x / self.fft_size for x in primes_transformed]) - expected_result = tuple( - [complex(primes[2 * i], primes[2 * i + 1]) for i in range(self.fft_size)]) - - src = blocks.vector_source_c(src_data, False, self.fft_size) - op = fft.fft_cc_rev(self.fft_size, [], False) - dst = blocks.vector_sink_c(self.fft_size) - self.tb.connect(src, 0, op, 0) - self.tb.connect(op, 0, dst, 0) - self.rt.initialize(self.tb) - self.rt.run() - result_data = dst.data() - self.assert_fft_ok2(expected_result, result_data) - - # def test_multithreaded(self): - # # Same test as above, only use 2 threads - # src_data = tuple([x / self.fft_size for x in primes_transformed]) - # expected_result = tuple( - # [complex(primes[2 * i], primes[2 * i + 1]) for i in range(self.fft_size)]) - # nthreads = 2 - - # src = blocks.vector_source_c(src_data) - # s2v = blocks.stream_to_vector(gr.sizeof_gr_complex, self.fft_size) - # op = fft.fft_vcc(self.fft_size, False, [], False, nthreads) - # v2s = blocks.vector_to_stream(gr.sizeof_gr_complex, self.fft_size) - # dst = blocks.vector_sink_c() - # self.tb.connect(src, s2v, op, v2s, dst) - # self.tb.run() - # result_data = dst.data() - # self.assert_fft_ok2(expected_result, result_data) - - # def test_window(self): - # src_data = tuple([complex(primes[2 * i], primes[2 * i + 1]) - # for i in range(self.fft_size)]) - # expected_result = ((2238.9174 + 2310.4750j), - # (-1603.7416 - 466.7420j), - # (116.7449 - 70.8553j), - # (-13.9157 + 19.0855j), - # (-4.8283 + 16.7025j), - # (-43.7425 + 16.9871j), - # (-16.1904 + 1.7494j), - # (-32.3797 + 6.9964j), - # (-13.5283 + 7.7721j), - # (-24.3276 - 7.5378j), - # (-29.2711 + 4.5709j), - # (-2.7124 - 6.6307j), - # (-33.5486 - 8.3485j), - # (-8.3016 - 9.9534j), - # (-18.8590 - 8.3501j), - # (-13.9092 - 1.1396j), - # (-17.7626 - 26.9281j), - # (0.0182 - 8.9000j), - # (-19.9143 - 14.1320j), - # (-10.3073 - 15.5759j), - # (3.5800 - 29.1835j), - # (-7.5263 - 1.5900j), - # (-3.0392 - 31.7445j), - # (-15.1355 - 33.6158j), - # (28.2345 - 11.4373j), - # (-6.0055 - 27.0418j), - # (5.2074 - 21.2431j), - # (23.1617 - 31.8610j), - # (13.6494 - 11.1982j), - # (14.7145 - 14.4113j), - # (-60.0053 + 114.7418j), - # (-440.1561 - 1632.9807j)) - # window = fft.window.hamming(ntaps=self.fft_size) - - # src = blocks.vector_source_c(src_data) - # s2v = blocks.stream_to_vector(gr.sizeof_gr_complex, self.fft_size) - # op = fft.fft_vcc(self.fft_size, True, window, False) - # v2s = blocks.vector_to_stream(gr.sizeof_gr_complex, self.fft_size) - # dst = blocks.vector_sink_c() - # self.tb.connect(src, s2v, op, v2s, dst) - # self.tb.run() - # result_data = dst.data() - # self.assert_fft_ok2(expected_result, result_data) - - # def test_reverse_window_shift(self): - # src_data = tuple([x / self.fft_size for x in primes_transformed]) - # expected_result = ((-74.8629 - 63.2502j), - # (-3.5446 - 2.0365j), - # (2.9231 + 1.6827j), - # (-2.7852 - 0.8613j), - # (2.4763 + 2.7881j), - # (-2.7457 - 3.2602j), - # (4.7748 + 2.4145j), - # (-2.8807 - 4.5313j), - # (5.9949 + 4.1976j), - # (-6.1095 - 6.0681j), - # (5.2248 + 5.7743j), - # (-6.0436 - 6.3773j), - # (9.7184 + 9.2482j), - # (-8.2791 - 8.6507j), - # (6.3273 + 6.1560j), - # (-12.2841 - 12.4692j), - # (10.5816 + 10.0241j), - # (-13.0312 - 11.9451j), - # (12.2983 + 13.3644j), - # (-13.0372 - 14.0795j), - # (14.4682 + 13.3079j), - # (-16.7673 - 16.7287j), - # (14.3946 + 11.5916j), - # (-16.8368 - 21.3156j), - # (20.4528 + 16.8499j), - # (-18.4075 - 18.2446j), - # (17.7507 + 19.2109j), - # (-21.5207 - 20.7159j), - # (22.2183 + 19.8012j), - # (-22.2144 - 20.0343j), - # (17.0359 + 17.6910j), - # (-91.8955 - 103.1093j)) - # window = fft.window.hamming(ntaps=self.fft_size) - - # src = blocks.vector_source_c(src_data) - # s2v = blocks.stream_to_vector(gr.sizeof_gr_complex, self.fft_size) - # op = fft.fft_vcc(self.fft_size, False, window, True) - # v2s = blocks.vector_to_stream(gr.sizeof_gr_complex, self.fft_size) - # dst = blocks.vector_sink_c() - # self.tb.connect(src, s2v, op, v2s, dst) - # self.tb.run() - # result_data = dst.data() - # self.assert_fft_ok2(expected_result, result_data) - - -if __name__ == '__main__': - gr_unittest.run(test_fft) - diff --git a/blocklib/fileio/.gitignore b/blocklib/fileio/.gitignore deleted file mode 100644 index 25d053a52..000000000 --- a/blocklib/fileio/.gitignore +++ /dev/null @@ -1 +0,0 @@ -meson.build
\ No newline at end of file diff --git a/blocklib/fileio/file_sink/file_sink.yml b/blocklib/fileio/file_sink/file_sink.yml deleted file mode 100644 index f3058e5d2..000000000 --- a/blocklib/fileio/file_sink/file_sink.yml +++ /dev/null @@ -1,40 +0,0 @@ -module: fileio -block: file_sink -label: File Sink -blocktype: sync_block -category: '[Core]/File Operators' - -parameters: -- id: filename - label: Filename - dtype: string - settable: false -- id: itemsize - label: Item Size - dtype: size - settable: false - default: 0 -- id: append - label: Append - dtype: bool - settable: false - default: 'false' - -ports: -- domain: stream - id: in - direction: input - type: untyped - size: parameters/itemsize - -callbacks: -- id: set_unbuffered - return: void - args: - - id: unbuffered - dtype: bool - -implementations: -- id: cpu - -file_format: 1 diff --git a/blocklib/fileio/file_sink/file_sink_cpu.cc b/blocklib/fileio/file_sink/file_sink_cpu.cc deleted file mode 100644 index 5412a9097..000000000 --- a/blocklib/fileio/file_sink/file_sink_cpu.cc +++ /dev/null @@ -1,76 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2004,2006,2007,2010,2013 Free Software Foundation, Inc. - * - * This file is part of GNU Radio - * - * SPDX-License-Identifier: GPL-3.0-or-later - * - */ - -#include "file_sink_cpu.h" -#include "file_sink_cpu_gen.h" - -namespace gr { -namespace fileio { - -file_sink_cpu::file_sink_cpu(const block_args& args) - : INHERITED_CONSTRUCTORS, - file_sink_base(args.filename, true, args.append), - d_itemsize(args.itemsize) - -{ -} - -file_sink_cpu::~file_sink_cpu() {} - -work_return_t file_sink_cpu::work(work_io& wio) -{ - auto inbuf = wio.inputs()[0].items<uint8_t>(); - auto noutput_items = wio.inputs()[0].n_items; - - if (d_itemsize == 0) { - d_itemsize = wio.inputs()[0].buf().item_size(); - } - - size_t nwritten = 0; - - do_update(); // update d_fp is reqd - - if (!d_fp) { - wio.inputs()[0].n_consumed = noutput_items; // drop output on the floor - return work_return_t::OK; - } - - while (nwritten < noutput_items) { - const int count = fwrite(inbuf, d_itemsize, noutput_items - nwritten, d_fp); - if (count == 0) { - if (ferror(d_fp)) { - std::stringstream s; - s << "file_sink write failed with error " << fileno(d_fp) << std::endl; - throw std::runtime_error(s.str()); - } - else { // is EOF - break; - } - } - nwritten += count; - inbuf += count * d_itemsize; - } - - if (d_unbuffered) - fflush(d_fp); - - wio.consume_each(nwritten); - return work_return_t::OK; -} - -bool file_sink_cpu::stop() -{ - do_update(); - fflush(d_fp); - return true; -} - -} // namespace fileio -} // namespace gr
\ No newline at end of file diff --git a/blocklib/fileio/file_sink/file_sink_cpu.h b/blocklib/fileio/file_sink/file_sink_cpu.h deleted file mode 100644 index e2e84f805..000000000 --- a/blocklib/fileio/file_sink/file_sink_cpu.h +++ /dev/null @@ -1,40 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2004,2007,2013 Free Software Foundation, Inc. - * - * This file is part of GNU Radio - * - * SPDX-License-Identifier: GPL-3.0-or-later - * - */ - -#pragma once - -#include <gnuradio/fileio/file_sink.h> -#include <gnuradio/fileio/file_sink_base.h> - -namespace gr { -namespace fileio { - -class file_sink_cpu : public file_sink, public file_sink_base -{ -public: - file_sink_cpu(const block_args& args); - ~file_sink_cpu() override; - - bool stop() override; - - work_return_t work(work_io&) override; - - void set_unbuffered(bool unbuffered) override - { - file_sink_base::set_unbuffered(unbuffered); - } - - -private: - size_t d_itemsize; -}; - -} // namespace fileio -} // namespace gr
\ No newline at end of file diff --git a/blocklib/fileio/file_source/file_source.yml b/blocklib/fileio/file_source/file_source.yml deleted file mode 100644 index 0845c0343..000000000 --- a/blocklib/fileio/file_source/file_source.yml +++ /dev/null @@ -1,52 +0,0 @@ -module: fileio -block: file_source -label: File Source -blocktype: sync_block -category: '[Core]/File Operators' - -parameters: -- id: filename - label: File Name - dtype: string - settable: false -- id: repeat - label: Repeat - dtype: bool - settable: false - default: 'false' -- id: itemsize - label: Item Size - dtype: size - settable: false - default: 0 -- id: offset - label: Offset - dtype: ru64 - settable: false - default: 0 -- id: len - label: Length - dtype: ru64 - settable: false - default: 0 - -ports: -- domain: stream - id: out - direction: output - type: untyped - size: parameters/itemsize - -callbacks: -- id: seek - return: bool - args: - - id: seek_point - dtype: ri64 - - id: whence - dtype: int - -implementations: -- id: cpu - -file_format: 1 diff --git a/blocklib/fileio/file_source/file_source_cpu.cc b/blocklib/fileio/file_source/file_source_cpu.cc deleted file mode 100644 index 0a01efdd8..000000000 --- a/blocklib/fileio/file_source/file_source_cpu.cc +++ /dev/null @@ -1,335 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2012, 2018 Free Software Foundation, Inc. - * - * This file is part of GNU Radio - * - * SPDX-License-Identifier: GPL-3.0-or-later - * - */ - -#include "file_source_cpu.h" -#include "file_source_cpu_gen.h" - -#include <fcntl.h> -#include <sys/stat.h> -#include <sys/types.h> -#include <cstdio> -#include <filesystem> -#include <stdexcept> - -#include <pmtf/scalar.hpp> -#include <pmtf/string.hpp> - -#ifdef _MSC_VER -#define GR_FSEEK _fseeki64 -#define GR_FTELL _ftelli64 -#define GR_FSTAT _fstati64 -#define GR_FILENO _fileno -#define GR_STAT _stati64 -#define S_ISREG(m) (((m)&S_IFMT) == S_IFREG) -#else -#define GR_FSEEK fseeko -#define GR_FTELL ftello -#define GR_FSTAT fstat -#define GR_FILENO fileno -#define GR_STAT stat -#endif - -namespace fs = std::filesystem; - -namespace gr { -namespace fileio { - -file_source_cpu::file_source_cpu(const file_source::block_args& args) - : INHERITED_CONSTRUCTORS, - - d_start_offset_items(args.offset), - d_length_items(args.len), - d_repeat(args.repeat), - d_itemsize(args.itemsize), - d_filename(args.filename), - d_offset(args.offset) -{ - - if (args.itemsize > 0) { - open(d_filename, d_repeat, d_offset, d_length_items); - do_update(); - } - else { - fs::path f{ d_filename }; - if (!fs::exists(f)) { - throw new std::runtime_error( - fmt::format("file_source: the file {} does not exist", d_filename)); - } - } - - std::stringstream str; - str << name() << id(); - _id = pmtf::string(str.str()); -} - - -file_source_cpu::~file_source_cpu() -{ - if (d_fp) - fclose((FILE*)d_fp); - if (d_new_fp) - fclose((FILE*)d_new_fp); -} - -bool file_source_cpu::seek(int64_t seek_point, int whence) -{ - if (d_seekable) { - seek_point += d_start_offset_items; - - switch (whence) { - case SEEK_SET: - break; - case SEEK_CUR: - seek_point += (d_length_items - d_items_remaining); - break; - case SEEK_END: - seek_point = d_length_items - seek_point; - break; - default: - d_logger->warn("bad seek mode"); - return 0; - } - - if ((seek_point < (int64_t)d_start_offset_items) || - (seek_point > (int64_t)(d_start_offset_items + d_length_items - 1))) { - d_logger->warn("bad seek point"); - return 0; - } - return GR_FSEEK((FILE*)d_fp, seek_point * d_itemsize, SEEK_SET) == 0; - } - else { - d_logger->warn("file not seekable"); - return 0; - } -} - - -void file_source_cpu::open(const std::string& filename, - bool repeat, - uint64_t start_offset_items, - uint64_t length_items) -{ - // obtain exclusive access for duration of this function - std::scoped_lock lock(fp_mutex); - - if (d_new_fp) { - fclose(d_new_fp); - d_new_fp = 0; - } - - if ((d_new_fp = fopen(filename.c_str(), "rb")) == NULL) { - d_logger->error("{}:{}", filename, strerror(errno)); - throw std::runtime_error("can't open file"); - } - - struct GR_STAT st; - - if (GR_FSTAT(GR_FILENO(d_new_fp), &st)) { - d_logger->error("{}:{}", filename, strerror(errno)); - throw std::runtime_error("can't fstat file"); - } - if (S_ISREG(st.st_mode)) { - d_seekable = true; - } - else { - d_seekable = false; - } - - uint64_t file_size; - - if (d_seekable) { - // Check to ensure the file will be consumed according to item size - if (GR_FSEEK(d_new_fp, 0, SEEK_END) == -1) { - throw std::runtime_error("can't fseek()"); - } - file_size = GR_FTELL(d_new_fp); - - // Make sure there will be at least one item available - if ((file_size / d_itemsize) < (start_offset_items + 1)) { - if (start_offset_items) { - d_logger->warn("file is too small for start offset"); - } - else { - d_logger->warn("file is too small"); - } - fclose(d_new_fp); - throw std::runtime_error("file is too small"); - } - } - else { - file_size = INT64_MAX; - } - - uint64_t items_available = (file_size / d_itemsize - start_offset_items); - - // If length is not specified, use the remainder of the file. Check alignment at end. - if (length_items == 0) { - length_items = items_available; - if (file_size % d_itemsize) { - d_logger->warn("file size is not a multiple of item size"); - } - } - - // Check specified length. Warn and use available items instead of throwing an - // exception. - if (length_items > items_available) { - length_items = items_available; - d_logger->warn("file too short, will read fewer than requested items"); - } - - // Rewind to start offset - if (d_seekable) { - auto start_offset = start_offset_items * d_itemsize; -#ifdef _POSIX_C_SOURCE -#if _POSIX_C_SOURCE >= 200112L - // If supported, tell the OS that we'll be accessing the file sequentially - // and that it would be a good idea to start prefetching it - auto fd = fileno(d_new_fp); - static const std::map<int, const std::string> fadv_errstrings = { - { EBADF, "bad file descriptor" }, - { EINVAL, "invalid advise" }, - { ESPIPE, "tried to act as if a pipe or similar was a file" } - }; - if (file_size && file_size != INT64_MAX) { - if (auto ret = posix_fadvise( - fd, start_offset, file_size - start_offset, POSIX_FADV_SEQUENTIAL)) { - d_logger->warn("failed to advise to read sequentially, {}", - fadv_errstrings.at(ret)); - } - if (auto ret = posix_fadvise( - fd, start_offset, file_size - start_offset, POSIX_FADV_WILLNEED)) { - d_logger->warn("failed to advise we'll need file contents soon, {}", - fadv_errstrings.at(ret)); - } - } -#endif -#endif - if (GR_FSEEK(d_new_fp, start_offset, SEEK_SET) == -1) { - throw std::runtime_error("can't fseek()"); - } - } - - d_updated = true; - d_repeat = repeat; - d_start_offset_items = start_offset_items; - d_length_items = length_items; - d_items_remaining = length_items; -} - -void file_source_cpu::close() -{ - // obtain exclusive access for duration of this function - std::scoped_lock lock(fp_mutex); - - if (d_new_fp != NULL) { - fclose(d_new_fp); - d_new_fp = NULL; - } - d_updated = true; -} - -void file_source_cpu::do_update() -{ - if (d_updated) { - std::scoped_lock lock(fp_mutex); // hold while in scope - - if (d_fp) - fclose(d_fp); - - d_fp = d_new_fp; // install new file pointer - d_new_fp = 0; - d_updated = false; - d_file_begin = true; - } -} - -void file_source_cpu::set_begin_tag(const std::string& val) { d_add_begin_tag = val; } - -work_return_t file_source_cpu::work(work_io& wio) -{ - auto out = wio.outputs()[0].items<uint8_t>(); - auto noutput_items = wio.outputs()[0].n_items; - uint64_t size = noutput_items; - - if (d_itemsize == 0) { - d_itemsize = wio.outputs()[0].buf().item_size(); - open(d_filename, d_repeat, d_offset, d_length_items); - } - - do_update(); // update d_fp is reqd - if (d_fp == NULL) - throw std::runtime_error("work with file not open"); - - std::scoped_lock lock(fp_mutex); // hold for the rest of this function - - // No items remaining - all done - if (d_items_remaining == 0) { - wio.outputs()[0].n_produced = 0; - return work_return_t::DONE; - } - - while (size) { - - // Add stream tag whenever the file starts again - if (d_file_begin && !d_add_begin_tag.empty()) { - wio.outputs()[0].buf().add_tag( - wio.outputs()[0].buf().total_written() + noutput_items - size, - pmtf::map{ { d_add_begin_tag, pmtf::scalar<int64_t>(d_repeat_cnt) }, - { "srcid", _id } }); - - d_file_begin = false; - } - - uint64_t nitems_to_read = std::min(size, d_items_remaining); - - size_t nitems_read = fread(out, d_itemsize, nitems_to_read, (FILE*)d_fp); - if (nitems_to_read != nitems_read) { - // Size of non-seekable files is unknown. EOF is normal. - if (!d_seekable && feof((FILE*)d_fp)) { - size -= nitems_read; - d_items_remaining = 0; - break; - } - - throw std::runtime_error("fread error"); - } - - size -= nitems_read; - d_items_remaining -= nitems_read; - out += nitems_read * d_itemsize; - - // Ran out of items ("EOF") - if (d_items_remaining == 0) { - // Repeat: rewind and request tag - if (d_repeat && d_seekable) { - if (GR_FSEEK(d_fp, d_start_offset_items * d_itemsize, SEEK_SET) == -1) { - throw std::runtime_error("can't fseek()"); - } - d_items_remaining = d_length_items; - if (!d_add_begin_tag.empty()) { - d_file_begin = true; - d_repeat_cnt++; - } - } - - // No repeat: return - else { - break; - } - } - } - - wio.produce_each(noutput_items - size); - return work_return_t::OK; -} - - -} // namespace fileio -} // namespace gr diff --git a/blocklib/fileio/file_source/file_source_cpu.h b/blocklib/fileio/file_source/file_source_cpu.h deleted file mode 100644 index 52930fe35..000000000 --- a/blocklib/fileio/file_source/file_source_cpu.h +++ /dev/null @@ -1,77 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2012, 2018 Free Software Foundation, Inc. - * - * This file is part of GNU Radio - * - * SPDX-License-Identifier: GPL-3.0-or-later - * - */ - -#pragma once - -#include <gnuradio/fileio/file_source.h> - -namespace gr { -namespace fileio { - -class file_source_cpu : public file_source -{ -public: - file_source_cpu(const block_args& args); - ~file_source_cpu() override; - work_return_t work(work_io&) override; - - /*! - * \brief seek file to \p seek_point relative to \p whence - * - * \param seek_point sample offset in file - * \param whence one of SEEK_SET, SEEK_CUR, SEEK_END (man fseek) - */ - bool seek(int64_t seek_point, int whence) override; - - /*! - * \brief Opens a new file. - * - * \param filename name of the file to source from - * \param repeat repeat file from start - * \param offset begin this many items into file - * \param len produce only items [offset, offset+len) - */ - void - open(const std::string& filename, bool repeat, uint64_t offset = 0, uint64_t len = 0); - - /*! - * \brief Close the file handle. - */ - void close(); - - /*! - * \brief Add a stream tag to the first sample of the file if true - */ - void set_begin_tag(const std::string& val); - -private: - uint64_t d_start_offset_items; - uint64_t d_length_items; - uint64_t d_items_remaining; - FILE* d_fp = nullptr; - FILE* d_new_fp = nullptr; - bool d_repeat; - size_t d_itemsize; - std::string d_filename; - size_t d_offset; - bool d_updated = false; - bool d_file_begin = true; - bool d_seekable; - long d_repeat_cnt = 0; - std::string d_add_begin_tag; - - std::mutex fp_mutex; - pmtf::pmt _id; - - void do_update(); -}; - -} // namespace fileio -} // namespace gr diff --git a/blocklib/fileio/include/gnuradio/fileio/.gitignore b/blocklib/fileio/include/gnuradio/fileio/.gitignore deleted file mode 100644 index d53050d7d..000000000 --- a/blocklib/fileio/include/gnuradio/fileio/.gitignore +++ /dev/null @@ -1 +0,0 @@ -!meson.build diff --git a/blocklib/fileio/include/gnuradio/fileio/file_sink_base.h b/blocklib/fileio/include/gnuradio/fileio/file_sink_base.h deleted file mode 100644 index 8c9a21c3c..000000000 --- a/blocklib/fileio/include/gnuradio/fileio/file_sink_base.h +++ /dev/null @@ -1,67 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2004,2007,2008,2013 Free Software Foundation, Inc. - * - * This file is part of GNU Radio - * - * SPDX-License-Identifier: GPL-3.0-or-later - * - */ - -#pragma once - -#include <gnuradio/logger.h> -#include <cstdio> -#include <mutex> - -namespace gr { -namespace fileio { - -/*! - * \brief Common base class for file sinks - */ -class file_sink_base -{ -protected: - FILE* d_fp; // current FILE pointer - FILE* d_new_fp; // new FILE pointer - bool d_updated; // is there a new FILE pointer? - bool d_is_binary; - std::mutex d_mutex; - bool d_unbuffered; - bool d_append; - gr::logger_ptr d_logger, d_debug_logger; - -protected: - file_sink_base(const std::string& filename, bool is_binary, bool append); - -public: - file_sink_base() {} - ~file_sink_base(); - - /*! - * \brief Open filename and begin output to it. - */ - bool open(const char* filename); - - /*! - * \brief Close current output file. - * - * Closes current output file and ignores any output until - * open is called to connect to another file. - */ - void close(); - - /*! - * \brief if we've had an update, do it now. - */ - void do_update(); - - /*! - * \brief turn on unbuffered writes for slower outputs - */ - void set_unbuffered(bool unbuffered); -}; - -} // namespace fileio -} // namespace gr diff --git a/blocklib/fileio/include/gnuradio/fileio/meson.build b/blocklib/fileio/include/gnuradio/fileio/meson.build deleted file mode 100644 index e69de29bb..000000000 --- a/blocklib/fileio/include/gnuradio/fileio/meson.build +++ /dev/null diff --git a/blocklib/fileio/lib/.gitignore b/blocklib/fileio/lib/.gitignore deleted file mode 100644 index 01ecb66ff..000000000 --- a/blocklib/fileio/lib/.gitignore +++ /dev/null @@ -1 +0,0 @@ -!meson.build
\ No newline at end of file diff --git a/blocklib/fileio/lib/file_sink_base.cc b/blocklib/fileio/lib/file_sink_base.cc deleted file mode 100644 index 0328b0729..000000000 --- a/blocklib/fileio/lib/file_sink_base.cc +++ /dev/null @@ -1,120 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2004,2006,2007,2009,2013 Free Software Foundation, Inc. - * - * This file is part of GNU Radio - * - * SPDX-License-Identifier: GPL-3.0-or-later - * - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include <gnuradio/fileio/file_sink_base.h> - -#include <fcntl.h> -#include <sys/stat.h> -#include <sys/types.h> -#include <unistd.h> -#include <cstdio> -#include <stdexcept> - -// win32 (mingw/msvc) specific -#ifdef HAVE_IO_H -#include <io.h> -#endif -#ifdef O_BINARY -#define OUR_O_BINARY O_BINARY -#else -#define OUR_O_BINARY 0 -#endif - -// should be handled via configure -#ifdef O_LARGEFILE -#define OUR_O_LARGEFILE O_LARGEFILE -#else -#define OUR_O_LARGEFILE 0 -#endif - -namespace gr { -namespace fileio { - -file_sink_base::file_sink_base(const std::string& filename, bool is_binary, bool append) - : d_fp(0), d_new_fp(0), d_updated(false), d_is_binary(is_binary), d_append(append) -{ - if (!open(filename.c_str())) - throw std::runtime_error("can't open file"); - - gr::configure_default_loggers(d_logger, d_debug_logger, "file_sink_base"); -} - -file_sink_base::~file_sink_base() -{ - close(); - if (d_fp) { - fclose(d_fp); - d_fp = 0; - } -} - -bool file_sink_base::open(const char* filename) -{ - std::scoped_lock guard(d_mutex); // hold mutex for duration of this function - - // we use the open system call to get access to the O_LARGEFILE flag. - int fd; - int flags; - - if (d_append) { - flags = O_WRONLY | O_CREAT | O_APPEND | OUR_O_LARGEFILE | OUR_O_BINARY; - } - else { - flags = O_WRONLY | O_CREAT | O_TRUNC | OUR_O_LARGEFILE | OUR_O_BINARY; - } - if ((fd = ::open(filename, flags, 0664)) < 0) { - d_logger->error("{}: {}", filename, strerror(errno)); - return false; - } - if (d_new_fp) { // if we've already got a new one open, close it - fclose(d_new_fp); - d_new_fp = 0; - } - - if ((d_new_fp = fdopen(fd, d_is_binary ? "wb" : "w")) == NULL) { - d_logger->error("{}: {}", filename, strerror(errno)); - ::close(fd); // don't leak file descriptor if fdopen fails. - } - - d_updated = true; - return d_new_fp != 0; -} - -void file_sink_base::close() -{ - std::scoped_lock guard(d_mutex); // hold mutex for duration of this function - - if (d_new_fp) { - fclose(d_new_fp); - d_new_fp = 0; - } - d_updated = true; -} - -void file_sink_base::do_update() -{ - if (d_updated) { - std::scoped_lock guard(d_mutex); // hold mutex for duration of this block - if (d_fp) - fclose(d_fp); - d_fp = d_new_fp; // install new file pointer - d_new_fp = 0; - d_updated = false; - } -} - -void file_sink_base::set_unbuffered(bool unbuffered) { d_unbuffered = unbuffered; } - -} // namespace fileio -} /* namespace gr */ diff --git a/blocklib/fileio/lib/meson.build b/blocklib/fileio/lib/meson.build deleted file mode 100644 index ff7f2b12e..000000000 --- a/blocklib/fileio/lib/meson.build +++ /dev/null @@ -1,52 +0,0 @@ -fileio_deps += [gnuradio_gr_dep, volk_dep, fmt_dep, pmtf_dep] -fileio_sources += 'file_sink_base.cc' -block_cpp_args = ['-DHAVE_CPU'] -# if IMPLEMENT_CUDA -# block_cpp_args += '-DHAVE_CUDA' - -# gnuradio_blocklib_fileio_cu = library('gnuradio-blocklib-fileio-cu', -# fileio_cu_sources, -# include_directories : incdir, -# install : true, -# dependencies : [cuda_dep]) - -# gnuradio_blocklib_fileio_cu_dep = declare_dependency(include_directories : incdir, -# link_with : gnuradio_blocklib_fileio_cu, -# dependencies : cuda_dep) - -# fileio_deps += [gnuradio_blocklib_fileio_cu_dep, cuda_dep] - -# endif - -incdir = include_directories(['../include/gnuradio/fileio','../include']) -gnuradio_blocklib_fileio_lib = library('gnuradio-blocklib-fileio', - fileio_sources, - include_directories : incdir, - install : true, - link_language: 'cpp', - dependencies : fileio_deps, - cpp_args : block_cpp_args) - -gnuradio_blocklib_fileio_dep = declare_dependency(include_directories : incdir, - link_with : gnuradio_blocklib_fileio_lib, - dependencies : fileio_deps) - -cmake_conf = configuration_data() -cmake_conf.set('libdir', join_paths(prefix,get_option('libdir'))) -cmake_conf.set('module', 'fileio') -cmake.configure_package_config_file( - name : 'gnuradio-fileio', - 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_fileio_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-fileio', - filebase : 'gnuradio-fileio', - description : 'GNU Radio FileIO Module') diff --git a/blocklib/fileio/python/gnuradio/fileio/.gitignore b/blocklib/fileio/python/gnuradio/fileio/.gitignore deleted file mode 100644 index 25d053a52..000000000 --- a/blocklib/fileio/python/gnuradio/fileio/.gitignore +++ /dev/null @@ -1 +0,0 @@ -meson.build
\ No newline at end of file diff --git a/blocklib/fileio/python/gnuradio/fileio/__init__.py b/blocklib/fileio/python/gnuradio/fileio/__init__.py deleted file mode 100644 index 4d381cca2..000000000 --- a/blocklib/fileio/python/gnuradio/fileio/__init__.py +++ /dev/null @@ -1,9 +0,0 @@ - -import os - -try: - from .fileio_python import * -except ImportError: - dirname, filename = os.path.split(os.path.abspath(__file__)) - __path__.append(os.path.join(dirname, "bindings")) - from .fileio_python import * diff --git a/blocklib/fileio/python/gnuradio/fileio/bindings/file_sink_base_pybind.cc b/blocklib/fileio/python/gnuradio/fileio/bindings/file_sink_base_pybind.cc deleted file mode 100644 index 71720e966..000000000 --- a/blocklib/fileio/python/gnuradio/fileio/bindings/file_sink_base_pybind.cc +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright 2020 Free Software Foundation, Inc. - * - * This file is part of GNU Radio - * - * SPDX-License-Identifier: GPL-3.0-or-later - * - */ - -#include <pybind11/complex.h> -#include <pybind11/pybind11.h> -#include <pybind11/stl.h> - -namespace py = pybind11; - -#include <gnuradio/fileio/file_sink_base.h> -// pydoc.h is automatically generated in the build directory -// #include <block_pydoc.h> - -void bind_file_sink_base(py::module& m) -{ - using file_sink_base = ::gr::fileio::file_sink_base; - - py::class_<file_sink_base, std::shared_ptr<file_sink_base>>(m, "file_sink_base") - .def("set_unbuffered", &file_sink_base::set_unbuffered, py::arg("unbuffered")); -} diff --git a/blocklib/fileio/test/.gitignore b/blocklib/fileio/test/.gitignore deleted file mode 100644 index 01ecb66ff..000000000 --- a/blocklib/fileio/test/.gitignore +++ /dev/null @@ -1 +0,0 @@ -!meson.build
\ No newline at end of file diff --git a/blocklib/fileio/test/meson.build b/blocklib/fileio/test/meson.build deleted file mode 100644 index c7dae54cd..000000000 --- a/blocklib/fileio/test/meson.build +++ /dev/null @@ -1,9 +0,0 @@ -################################################### -# QA -################################################### - -if GR_ENABLE_PYTHON - test('qa_file_source', py3, args : files('qa_file_source.py'), env: TEST_ENV) - test('qa_file_sink', py3, args : files('qa_file_sink.py'), env: TEST_ENV) - -endif diff --git a/blocklib/fileio/test/qa_file_sink.py b/blocklib/fileio/test/qa_file_sink.py deleted file mode 100644 index 01128c756..000000000 --- a/blocklib/fileio/test/qa_file_sink.py +++ /dev/null @@ -1,52 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright 2018 Free Software Foundation, Inc. -# -# This file is part of GNU Radio -# -# SPDX-License-Identifier: GPL-3.0-or-later -# -# - -import os -import tempfile -import array -from gnuradio import gr, gr_unittest, blocks, fileio - - -class test_file_sink(gr_unittest.TestCase): - - def setUp(self): - os.environ['GR_CONF_CONTROLPORT_ON'] = 'False' - self.tb = gr.flowgraph() - self.rt = gr.runtime() - - def tearDown(self): - self.tb = None - self.rt = None - - def test_file_sink(self): - data = range(1000) - expected_result = data - - with tempfile.NamedTemporaryFile() as temp: - src = blocks.vector_source_f(data) - snk = fileio.file_sink(temp.name) - snk.set_unbuffered(True) # FIXME: comes from base class no pybind yet - self.tb.connect(src, snk) - self.rt.initialize(self.tb) - self.rt.run() - - # Check file length (float: 4 * nsamples) - file_size = os.stat(temp.name).st_size - self.assertEqual(file_size, 4 * len(data)) - - # Check file contents - with open(temp.name, 'rb') as datafile: - result_data = array.array('f') - result_data.fromfile(datafile, len(data)) - self.assertFloatTuplesAlmostEqual(expected_result, result_data) - - -if __name__ == '__main__': - gr_unittest.run(test_file_sink) diff --git a/blocklib/fileio/test/qa_file_source.py b/blocklib/fileio/test/qa_file_source.py deleted file mode 100644 index a2fa53524..000000000 --- a/blocklib/fileio/test/qa_file_source.py +++ /dev/null @@ -1,152 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright 2018 Free Software Foundation, Inc. -# -# This file is part of GNU Radio -# -# SPDX-License-Identifier: GPL-3.0-or-later -# -# - -import os -import tempfile -import array -# import pmt -from gnuradio import gr, gr_unittest, blocks, fileio - - -class test_file_source(gr_unittest.TestCase): - - @classmethod - def setUpClass(cls): - os.environ['GR_CONF_CONTROLPORT_ON'] = 'False' - cls._datafile = tempfile.NamedTemporaryFile() - cls._datafilename = cls._datafile.name - cls._vector = [x for x in range(1000)] - with open(cls._datafilename, 'wb') as f: - array.array('f', cls._vector).tofile(f) - - @classmethod - def tearDownClass(cls): - del cls._vector - del cls._datafilename - del cls._datafile - - def setUp(self): - self.tb = gr.flowgraph() - self.rt = gr.runtime() - - def tearDown(self): - self.tb = None - self.rt = None - - def test_file_source(self): - src = fileio.file_source(self._datafilename) - snk = blocks.vector_sink_f() - self.tb.connect(src, snk) - self.rt.initialize(self.tb) - self.rt.run() - - result_data = snk.data() - self.assertFloatTuplesAlmostEqual(self._vector, result_data) - # self.assertEqual(len(snk.tags()), 0) - - def test_file_source_no_such_file(self): - """ - Try to open a non-existent file and verify exception is thrown. - """ - try: - _ = fileio.file_source("___no_such_file___") - self.assertTrue(False) - except RuntimeError: - self.assertTrue(True) - - def test_file_source_with_offset(self): - expected_result = self._vector[100:] - - src = fileio.file_source( - self._datafilename, - offset=100) - snk = blocks.vector_sink_f() - - self.tb.connect(src, snk) - self.rt.initialize(self.tb) - self.rt.run() - - result_data = snk.data() - self.assertFloatTuplesAlmostEqual(expected_result, result_data) - # self.assertEqual(len(snk.tags()), 0) - - def test_source_with_offset_and_len(self): - expected_result = self._vector[100:100 + 600] - - src = fileio.file_source( - self._datafilename, - offset=100, - len=600) - snk = blocks.vector_sink_f() - self.tb.connect(src, snk) - self.rt.initialize(self.tb) - self.rt.run() - - result_data = snk.data() - self.assertFloatTuplesAlmostEqual(expected_result, result_data) - # self.assertEqual(len(snk.tags()), 0) - - def test_file_source_can_seek_after_open(self): - - src = fileio.file_source(self._datafilename, itemsize=gr.sizeof_float) - self.assertTrue(src.seek(0, os.SEEK_SET)) - self.assertTrue(src.seek(len(self._vector) - 1, os.SEEK_SET)) - # Seek past end of file - this will also log a warning - self.assertFalse(src.seek(len(self._vector), os.SEEK_SET)) - # Negative seek - this will also log a warning - self.assertFalse(src.seek(-1, os.SEEK_SET)) - - self.assertTrue(src.seek(1, os.SEEK_END)) - self.assertTrue(src.seek(len(self._vector), os.SEEK_END)) - # Seek past end of file - this will also log a warning - self.assertFalse(src.seek(0, os.SEEK_END)) - - self.assertTrue(src.seek(0, os.SEEK_SET)) - self.assertTrue(src.seek(1, os.SEEK_CUR)) - # Seek past end of file - this will also log a warning - self.assertFalse(src.seek(len(self._vector), os.SEEK_CUR)) - - # def test_begin_tag(self): - # expected_result = self._vector - - # src = blocks.file_source(gr.sizeof_float, self._datafilename) - # src.set_begin_tag(pmt.string_to_symbol("file_begin")) - # snk = blocks.vector_sink_f() - # self.tb.connect(src, snk) - # self.tb.run() - - # result_data = snk.data() - # self.assertFloatTuplesAlmostEqual(expected_result, result_data) - # self.assertEqual(len(snk.tags()), 1) - - # def test_begin_tag_repeat(self): - # expected_result = self._vector + self._vector - - # src = blocks.file_source(gr.sizeof_float, self._datafilename, True) - # src.set_begin_tag(pmt.string_to_symbol("file_begin")) - # head = streamops.head(gr.sizeof_float, 2 * len(self._vector)) - # snk = blocks.vector_sink_f() - # self.tb.connect(src, head, snk) - # self.tb.run() - - # result_data = snk.data() - # self.assertFloatTuplesAlmostEqual(expected_result, result_data) - # tags = snk.tags() - # self.assertEqual(len(tags), 2) - # self.assertEqual(str(tags[0].key), "file_begin") - # self.assertEqual(str(tags[0].value), "0") - # self.assertEqual(tags[0].offset, 0) - # self.assertEqual(str(tags[1].key), "file_begin") - # self.assertEqual(str(tags[1].value), "1") - # self.assertEqual(tags[1].offset, 1000) - - -if __name__ == '__main__': - gr_unittest.run(test_file_source) 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) diff --git a/blocklib/math/complex_to_mag/complex_to_mag.yml b/blocklib/math/complex_to_mag/complex_to_mag.yml deleted file mode 100644 index e67842ddf..000000000 --- a/blocklib/math/complex_to_mag/complex_to_mag.yml +++ /dev/null @@ -1,31 +0,0 @@ -module: math -block: complex_to_mag -label: Complex to Magnitude -blocktype: sync_block -category: '[Core]/Math Operators' - -parameters: -- id: vlen - label: Vector Length - dtype: size - settable: false - default: 1 - -ports: -- domain: stream - id: in - direction: input - type: cf32 - shape: parameters/vlen - -- domain: stream - id: out - direction: output - type: rf32 - shape: parameters/vlen - -implementations: -- id: cpu -# - id: cuda - -file_format: 1 diff --git a/blocklib/math/complex_to_mag/complex_to_mag_cpu.cc b/blocklib/math/complex_to_mag/complex_to_mag_cpu.cc deleted file mode 100644 index 3d3d0eed4..000000000 --- a/blocklib/math/complex_to_mag/complex_to_mag_cpu.cc +++ /dev/null @@ -1,41 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2012 Free Software Foundation, Inc. - * - * This file is part of GNU Radio - * - * SPDX-License-Identifier: GPL-3.0-or-later - * - */ - -#include "complex_to_mag_cpu.h" -#include "complex_to_mag_cpu_gen.h" -#include <volk/volk.h> - -namespace gr { -namespace math { - -complex_to_mag_cpu::complex_to_mag_cpu(const block_args& args) - : INHERITED_CONSTRUCTORS, d_vlen(args.vlen) -{ - // const int alignment_multiple = volk_get_alignment() / sizeof(float); - // set_output_multiple(std::max(1, alignment_multiple)); -} - -work_return_t complex_to_mag_cpu::work(work_io& wio) -{ - auto noutput_items = wio.outputs()[0].n_items; - int noi = noutput_items * d_vlen; - - auto iptr = wio.inputs()[0].items<gr_complex>(); - auto optr = wio.outputs()[0].items<float>(); - - volk_32fc_magnitude_32f_u(optr, iptr, noi); - - wio.produce_each(noutput_items); - return work_return_t::OK; -} - - -} // namespace math -} // namespace gr diff --git a/blocklib/math/complex_to_mag/complex_to_mag_cpu.h b/blocklib/math/complex_to_mag/complex_to_mag_cpu.h deleted file mode 100644 index 4d6455fa2..000000000 --- a/blocklib/math/complex_to_mag/complex_to_mag_cpu.h +++ /dev/null @@ -1,29 +0,0 @@ -/* -*- c++ -*- */ -/* - * 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/math/complex_to_mag.h> -#include <volk/volk.h> -namespace gr { -namespace math { - -class complex_to_mag_cpu : public complex_to_mag -{ -public: - complex_to_mag_cpu(const block_args& args); - work_return_t work(work_io&) override; - -private: - size_t d_vlen; -}; - -} // namespace math -} // namespace gr
\ No newline at end of file diff --git a/blocklib/math/complex_to_mag_squared/complex_to_mag_squared.yml b/blocklib/math/complex_to_mag_squared/complex_to_mag_squared.yml deleted file mode 100644 index 03ea8a448..000000000 --- a/blocklib/math/complex_to_mag_squared/complex_to_mag_squared.yml +++ /dev/null @@ -1,31 +0,0 @@ -module: math -block: complex_to_mag_squared -label: Complex to Magnitude Squared -blocktype: sync_block -category: '[Core]/Math Operators' - -parameters: -- id: vlen - label: Vector Length - dtype: size - settable: false - default: 1 - -ports: -- domain: stream - id: in - direction: input - type: cf32 - shape: parameters/vlen - -- domain: stream - id: out - direction: output - type: rf32 - shape: parameters/vlen - -implementations: -- id: cpu -# - id: cuda - -file_format: 1 diff --git a/blocklib/math/complex_to_mag_squared/complex_to_mag_squared_cpu.cc b/blocklib/math/complex_to_mag_squared/complex_to_mag_squared_cpu.cc deleted file mode 100644 index 826a53679..000000000 --- a/blocklib/math/complex_to_mag_squared/complex_to_mag_squared_cpu.cc +++ /dev/null @@ -1,40 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2012 Free Software Foundation, Inc. - * - * This file is part of GNU Radio - * - * SPDX-License-Identifier: GPL-3.0-or-later - * - */ - -#include "complex_to_mag_squared_cpu.h" -#include "complex_to_mag_squared_cpu_gen.h" -#include <volk/volk.h> - -namespace gr { -namespace math { -complex_to_mag_squared_cpu::complex_to_mag_squared_cpu(const block_args& args) - : INHERITED_CONSTRUCTORS, d_vlen(args.vlen) -{ - // const int alignment_multiple = volk_get_alignment() / sizeof(float); - // set_output_multiple(std::max(1, alignment_multiple)); -} - -work_return_t complex_to_mag_squared_cpu::work(work_io& wio) -{ - auto noutput_items = wio.outputs()[0].n_items; - int noi = noutput_items * d_vlen; - - auto iptr = wio.inputs()[0].items<gr_complex>(); - auto optr = wio.outputs()[0].items<float>(); - - volk_32fc_magnitude_squared_32f(optr, iptr, noi); - - wio.produce_each(noutput_items); - return work_return_t::OK; -} - - -} // namespace math -} // namespace gr diff --git a/blocklib/math/complex_to_mag_squared/complex_to_mag_squared_cpu.h b/blocklib/math/complex_to_mag_squared/complex_to_mag_squared_cpu.h deleted file mode 100644 index b50bbd544..000000000 --- a/blocklib/math/complex_to_mag_squared/complex_to_mag_squared_cpu.h +++ /dev/null @@ -1,31 +0,0 @@ -/* -*- c++ -*- */ -/* - * 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/math/complex_to_mag_squared.h> -#include <volk/volk.h> - -namespace gr { -namespace math { - -class complex_to_mag_squared_cpu : public complex_to_mag_squared -{ -public: - complex_to_mag_squared_cpu(const block_args& args); - - work_return_t work(work_io&) override; - -private: - size_t d_vlen; -}; - -} // namespace math -} // namespace gr
\ No newline at end of file diff --git a/blocklib/math/divide/divide.yml b/blocklib/math/divide/divide.yml deleted file mode 100644 index 5939755ba..000000000 --- a/blocklib/math/divide/divide.yml +++ /dev/null @@ -1,46 +0,0 @@ -module: math -block: divide -label: Divide -blocktype: sync_block -category: '[Core]/Math Operators' - -typekeys: - - id: T - type: class - options: - - cf32 - - rf32 - - ri32 - - ri16 - -parameters: -- id: num_inputs - label: Number of Inputs - dtype: size - settable: false - default: 2 -- id: vlen - label: Vec. Length - dtype: size - settable: false - default: 1 - -ports: -- domain: stream - id: in - direction: input - type: typekeys/T - shape: parameters/vlen - multiplicity: parameters/num_inputs - -- domain: stream - id: out - direction: output - type: typekeys/T - shape: parameters/vlen - -implementations: -- id: cpu -# - id: cuda - -file_format: 1 diff --git a/blocklib/math/divide/divide_cpu.cc b/blocklib/math/divide/divide_cpu.cc deleted file mode 100644 index e25cfeaa0..000000000 --- a/blocklib/math/divide/divide_cpu.cc +++ /dev/null @@ -1,100 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2004,2009,2010,2012,2018 Free Software Foundation, Inc. - * - * This file is part of GNU Radio - * - * SPDX-License-Identifier: GPL-3.0-or-later - * - */ - -#include "divide_cpu.h" -#include "divide_cpu_gen.h" -#include <volk/volk.h> - -namespace gr { -namespace math { - -template <class T> -divide_cpu<T>::divide_cpu(const typename divide<T>::block_args& args) - : INHERITED_CONSTRUCTORS(T), d_num_inputs(args.num_inputs), d_vlen(args.vlen) -{ -} - -template <> -divide_cpu<float>::divide_cpu(const typename divide<float>::block_args& args) - : INHERITED_CONSTRUCTORS(float), d_num_inputs(args.num_inputs), d_vlen(args.vlen) -{ - // const int alignment_multiple = volk_get_alignment() / sizeof(float); - // set_output_multiple(std::max(1, alignment_multiple)); -} - -template <> -divide_cpu<gr_complex>::divide_cpu(const typename divide<gr_complex>::block_args& args) - : INHERITED_CONSTRUCTORS(gr_complex), d_num_inputs(args.num_inputs), d_vlen(args.vlen) -{ - const int alignment_multiple = volk_get_alignment() / sizeof(gr_complex); - set_output_multiple(std::max(1, alignment_multiple)); -} - - -template <> -work_return_t divide_cpu<float>::work(work_io& wio) -{ - auto optr = wio.outputs()[0].items<float>(); - auto noutput_items = wio.outputs()[0].n_items; - - auto numerator = wio.inputs()[0].items<float>(); - for (size_t inp = 1; inp < d_num_inputs; ++inp) { - volk_32f_x2_divide_32f( - optr, numerator, wio.inputs()[inp].items<float>(), noutput_items * d_vlen); - numerator = optr; - } - - wio.outputs()[0].n_produced = wio.outputs()[0].n_items; - return work_return_t::OK; -} - -template <> -work_return_t divide_cpu<gr_complex>::work(work_io& wio) - -{ - auto optr = wio.outputs()[0].items<gr_complex>(); - auto noutput_items = wio.outputs()[0].n_items; - - auto numerator = wio.inputs()[0].items<gr_complex>(); - for (size_t inp = 1; inp < d_num_inputs; ++inp) { - volk_32fc_x2_divide_32fc(optr, - numerator, - wio.inputs()[inp].items<gr_complex>(), - noutput_items * d_vlen); - numerator = optr; - } - - wio.outputs()[0].n_produced = wio.outputs()[0].n_items; - return work_return_t::OK; -} - -template <class T> -work_return_t divide_cpu<T>::work(work_io& wio) - -{ - auto optr = wio.outputs()[0].items<T>(); - auto noutput_items = wio.outputs()[0].n_items; - - for (size_t i = 0; i < noutput_items * d_vlen; i++) { - T acc = (wio.inputs()[0].items<T>())[i]; - for (size_t j = 1; j < d_num_inputs; j++) { - acc /= (wio.inputs()[j].items<T>())[i]; - } - *optr++ = static_cast<T>(acc); - } - - wio.outputs()[0].n_produced = wio.outputs()[0].n_items; - wio.inputs()[0].n_consumed = wio.inputs()[0].n_items; - return work_return_t::OK; -} - - -} /* namespace math */ -} /* namespace gr */ diff --git a/blocklib/math/divide/divide_cpu.h b/blocklib/math/divide/divide_cpu.h deleted file mode 100644 index bb5f667be..000000000 --- a/blocklib/math/divide/divide_cpu.h +++ /dev/null @@ -1,33 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2004,2009,2010,2012,2018 Free Software Foundation, Inc. - * - * This file is part of GNU Radio - * - * SPDX-License-Identifier: GPL-3.0-or-later - * - */ - -#pragma once - -#include <gnuradio/math/divide.h> - -namespace gr { -namespace math { - -template <class T> -class divide_cpu : public divide<T> -{ -public: - divide_cpu(const typename divide<T>::block_args& args); - - work_return_t work(work_io&) override; - -protected: - size_t d_num_inputs; - size_t d_vlen; -}; - - -} // namespace math -} // namespace gr diff --git a/blocklib/math/multiply/multiply.yml b/blocklib/math/multiply/multiply.yml deleted file mode 100644 index f355a96d4..000000000 --- a/blocklib/math/multiply/multiply.yml +++ /dev/null @@ -1,46 +0,0 @@ -module: math -block: multiply -label: Multiply -blocktype: sync_block -category: '[Core]/Math Operators' - -typekeys: - - id: T - type: class - options: - - cf32 - - rf32 - - ri32 - - ri16 - -parameters: -- id: num_inputs - label: Number of Inputs - dtype: size - settable: false - default: 2 -- id: vlen - label: Vec. Length - dtype: size - settable: false - default: 1 - -ports: -- domain: stream - id: in - direction: input - type: typekeys/T - shape: parameters/vlen - multiplicity: parameters/num_inputs - -- domain: stream - id: out - direction: output - type: typekeys/T - shape: parameters/vlen - -implementations: -- id: cpu -# - id: cuda - -file_format: 1 diff --git a/blocklib/math/multiply/multiply_cpu.cc b/blocklib/math/multiply/multiply_cpu.cc deleted file mode 100644 index f7178dc80..000000000 --- a/blocklib/math/multiply/multiply_cpu.cc +++ /dev/null @@ -1,95 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2004,2009,2010,2012,2018 Free Software Foundation, Inc. - * - * This file is part of GNU Radio - * - * SPDX-License-Identifier: GPL-3.0-or-later - * - */ - -#include "multiply_cpu.h" -#include "multiply_cpu_gen.h" -#include <volk/volk.h> - -namespace gr { -namespace math { - -template <class T> -multiply_cpu<T>::multiply_cpu(const typename multiply<T>::block_args& args) - : INHERITED_CONSTRUCTORS(T), d_num_inputs(args.num_inputs), d_vlen(args.vlen) -{ -} - -template <> -multiply_cpu<float>::multiply_cpu(const typename multiply<float>::block_args& args) - : INHERITED_CONSTRUCTORS(float), d_num_inputs(args.num_inputs), d_vlen(args.vlen) -{ - // const int alignment_multiple = volk_get_alignment() / sizeof(float); - // set_output_multiple(std::max(1, alignment_multiple)); -} - -template <> -multiply_cpu<gr_complex>::multiply_cpu( - const typename multiply<gr_complex>::block_args& args) - : INHERITED_CONSTRUCTORS(gr_complex), d_num_inputs(args.num_inputs), d_vlen(args.vlen) -{ - // const int alignment_multiple = volk_get_alignment() / sizeof(gr_complex); - // set_output_multiple(std::max(1, alignment_multiple)); -} - -template <> -work_return_t multiply_cpu<float>::work(work_io& wio) -{ - auto out = wio.outputs()[0].items<float>(); - auto noutput_items = wio.outputs()[0].n_items; - int noi = d_vlen * noutput_items; - - memcpy(out, wio.inputs()[0].items<float>(), noi * sizeof(float)); - for (size_t i = 1; i < d_num_inputs; i++) { - volk_32f_x2_multiply_32f(out, out, wio.inputs()[i].items<float>(), noi); - } - - wio.outputs()[0].n_produced = wio.outputs()[0].n_items; - return work_return_t::OK; -} - -template <> -work_return_t multiply_cpu<gr_complex>::work(work_io& wio) - -{ - auto out = wio.outputs()[0].items<gr_complex>(); - auto noutput_items = wio.outputs()[0].n_items; - int noi = d_vlen * noutput_items; - - memcpy(out, wio.inputs()[0].items<gr_complex>(), noi * sizeof(gr_complex)); - for (size_t i = 1; i < d_num_inputs; i++) { - volk_32fc_x2_multiply_32fc(out, out, wio.inputs()[i].items<gr_complex>(), noi); - } - - wio.outputs()[0].n_produced = wio.outputs()[0].n_items; - return work_return_t::OK; -} - -template <class T> -work_return_t multiply_cpu<T>::work(work_io& wio) - -{ - auto optr = wio.outputs()[0].items<T>(); - auto noutput_items = wio.outputs()[0].n_items; - - for (size_t i = 0; i < noutput_items * d_vlen; i++) { - T acc = (wio.inputs()[0].items<T>())[i]; - for (size_t j = 1; j < d_num_inputs; j++) { - acc *= (wio.inputs()[j].items<T>())[i]; - } - *optr++ = static_cast<T>(acc); - } - - wio.outputs()[0].n_produced = wio.outputs()[0].n_items; - wio.inputs()[0].n_consumed = wio.inputs()[0].n_items; - return work_return_t::OK; -} - -} /* namespace math */ -} /* namespace gr */ diff --git a/blocklib/math/multiply/multiply_cpu.h b/blocklib/math/multiply/multiply_cpu.h deleted file mode 100644 index 18dfa463a..000000000 --- a/blocklib/math/multiply/multiply_cpu.h +++ /dev/null @@ -1,33 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2004,2009,2010,2012,2018 Free Software Foundation, Inc. - * - * This file is part of GNU Radio - * - * SPDX-License-Identifier: GPL-3.0-or-later - * - */ - -#pragma once - -#include <gnuradio/math/multiply.h> - -namespace gr { -namespace math { - -template <class T> -class multiply_cpu : public multiply<T> -{ -public: - multiply_cpu(const typename multiply<T>::block_args& args); - - work_return_t work(work_io&) override; - -protected: - size_t d_num_inputs; - size_t d_vlen; -}; - - -} // namespace math -} // namespace gr diff --git a/blocklib/math/test/meson.build b/blocklib/math/test/meson.build index 4a525e008..f21368bca 100644 --- a/blocklib/math/test/meson.build +++ b/blocklib/math/test/meson.build @@ -1,7 +1,6 @@ if GR_ENABLE_PYTHON test('qa_conjugate', py3, args : files('qa_conjugate.py'), env: TEST_ENV) - test('qa_type_conversions', py3, args : files('qa_type_conversions.py'), env: TEST_ENV) test('qa_add_mult_div_sub', py3, args : files('qa_add_mult_div_sub.py'), env: TEST_ENV) test('qa_add_numpy', py3, args : files('qa_add_numpy.py'), env: TEST_ENV) if (IMPLEMENT_CUDA) diff --git a/blocklib/math/test/qa_add_mult_div_sub.py b/blocklib/math/test/qa_add_mult_div_sub.py index 728be544f..4edbc6cb6 100644 --- a/blocklib/math/test/qa_add_mult_div_sub.py +++ b/blocklib/math/test/qa_add_mult_div_sub.py @@ -124,37 +124,37 @@ class test_add_mult_div_sub(gr_unittest.TestCase): # multiply_XX - def test_multiply_ss(self): - src1_data = [1, 2, 3, 4, 5] - src2_data = [8, -3, 4, 8, 2] - expected_result = [8, -6, 12, 32, 10] - op = math.multiply_ss(2) - self.help_ss((src1_data, src2_data), - expected_result, op) + # def test_multiply_ss(self): + # src1_data = [1, 2, 3, 4, 5] + # src2_data = [8, -3, 4, 8, 2] + # expected_result = [8, -6, 12, 32, 10] + # op = math.multiply_ss(2) + # self.help_ss((src1_data, src2_data), + # expected_result, op) - def test_multiply_ii(self): - src1_data = [1, 2, 3, 4, 5] - src2_data = [8, -3, 4, 8, 2] - expected_result = [8, -6, 12, 32, 10] - op = math.multiply_ii(2) - self.help_ii((src1_data, src2_data), - expected_result, op) + # def test_multiply_ii(self): + # src1_data = [1, 2, 3, 4, 5] + # src2_data = [8, -3, 4, 8, 2] + # expected_result = [8, -6, 12, 32, 10] + # op = math.multiply_ii(2) + # self.help_ii((src1_data, src2_data), + # expected_result, op) - def test_multiply_ff(self): - src1_data = [1, 2, 3, 4, 5] - src2_data = [8, -3, 4, 8, 2] - expected_result = [8, -6, 12, 32, 10] - op = math.multiply_ff(2) - self.help_ff((src1_data, src2_data), - expected_result, op) + # def test_multiply_ff(self): + # src1_data = [1, 2, 3, 4, 5] + # src2_data = [8, -3, 4, 8, 2] + # expected_result = [8, -6, 12, 32, 10] + # op = math.multiply_ff(2) + # self.help_ff((src1_data, src2_data), + # expected_result, op) - def test_multiply_cc(self): - src1_data = [1 + 1j, 2 + 2j, 3 + 3j, 4 + 4j, 5 + 5j] - src2_data = [8, -3, 4, 8, 2] - expected_result = [8 + 8j, -6 - 6j, 12 + 12j, 32 + 32j, 10 + 10j] - op = math.multiply_cc(2) - self.help_cc((src1_data, src2_data), - expected_result, op) + # def test_multiply_cc(self): + # src1_data = [1 + 1j, 2 + 2j, 3 + 3j, 4 + 4j, 5 + 5j] + # src2_data = [8, -3, 4, 8, 2] + # expected_result = [8 + 8j, -6 - 6j, 12 + 12j, 32 + 32j, 10 + 10j] + # op = math.multiply_cc(2) + # self.help_cc((src1_data, src2_data), + # expected_result, op) # multiply_const_XX @@ -268,12 +268,12 @@ class test_add_mult_div_sub(gr_unittest.TestCase): # result_data = dst.data() # self.assertEqual(expected_result, result_data) - def test_div_ff(self): - src1_data = [5, 9, -15, 1024] - src2_data = [10, 3, -5, 64] - expected_result = [0.5, 3, 3, 16] - op = math.divide_ff() - self.help_ff((src1_data, src2_data), expected_result, op) + # def test_div_ff(self): + # src1_data = [5, 9, -15, 1024] + # src2_data = [10, 3, -5, 64] + # expected_result = [0.5, 3, 3, 16] + # op = math.divide_ff() + # self.help_ff((src1_data, src2_data), expected_result, op) if __name__ == '__main__': diff --git a/blocklib/math/test/qa_type_conversions.py b/blocklib/math/test/qa_type_conversions.py deleted file mode 100644 index 8ef973f53..000000000 --- a/blocklib/math/test/qa_type_conversions.py +++ /dev/null @@ -1,324 +0,0 @@ -#!/usr/bin/env python3 -# -# 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, blocks, math - -from math import sqrt, atan2 - - -class test_type_conversions(gr_unittest.TestCase): - - def setUp(self): - self.tb = gr.flowgraph() - self.rt = gr.runtime() - - def tearDown(self): - self.tb = None - self.rt = None - - # def test_char_to_float_identity(self): - # src_data = (1, 2, 3, 4, 5) - # expected_data = [1.0, 2.0, 3.0, 4.0, 5.0] - # src = blocks.vector_source_b(src_data) - # op = blocks.char_to_float() - # dst = blocks.vector_sink_f() - # self.tb.connect(src, op, dst) - # self.tb.run() - # self.assertFloatTuplesAlmostEqual(expected_data, dst.data()) - - # def test_char_to_float_scale(self): - # src_data = (1, 2, 3, 4, 5) - # expected_data = [0.5, 1.0, 1.5, 2.0, 2.5] - # src = blocks.vector_source_b(src_data) - # op = blocks.char_to_float(scale=2.0) - # dst = blocks.vector_sink_f() - # self.tb.connect(src, op, dst) - # self.tb.run() - # self.assertFloatTuplesAlmostEqual(expected_data, dst.data()) - - # def test_char_to_short(self): - # src_data = (1, 2, 3, 4, 5) - # expected_data = [256, 512, 768, 1024, 1280] - # src = blocks.vector_source_b(src_data) - # op = blocks.char_to_short() - # dst = blocks.vector_sink_s() - # self.tb.connect(src, op, dst) - # self.tb.run() - # self.assertEqual(expected_data, dst.data()) - - # def test_complex_to_interleaved_char(self): - # src_data = (1 + 2j, 3 + 4j, 5 + 6j, 7 + 8j, 9 + 10j) - # expected_data = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] - # src = blocks.vector_source_c(src_data) - # op = blocks.complex_to_interleaved_char() - # dst = blocks.vector_sink_b() - # self.tb.connect(src, op, dst) - # self.tb.run() - # self.assertEqual(expected_data, dst.data()) - - # def test_complex_to_interleaved_short(self): - # src_data = (1 + 2j, 3 + 4j, 5 + 6j, 7 + 8j, 9 + 10j) - # expected_data = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] - # src = blocks.vector_source_c(src_data) - # op = blocks.complex_to_interleaved_short() - # dst = blocks.vector_sink_s() - # self.tb.connect(src, op, dst) - # self.tb.run() - # self.assertEqual(expected_data, dst.data()) - - # def test_complex_to_float_1(self): - # src_data = (1 + 2j, 3 + 4j, 5 + 6j, 7 + 8j, 9 + 10j) - # expected_data = [1.0, 3.0, 5.0, 7.0, 9.0] - # src = blocks.vector_source_c(src_data) - # op = blocks.complex_to_float() - # dst = blocks.vector_sink_f() - # self.tb.connect(src, op, dst) - # self.tb.run() - # self.assertFloatTuplesAlmostEqual(expected_data, dst.data()) - - # def test_complex_to_float_2(self): - # src_data = (1 + 2j, 3 + 4j, 5 + 6j, 7 + 8j, 9 + 10j) - # expected_data1 = [1.0, 3.0, 5.0, 7.0, 9.0] - # expected_data2 = [2.0, 4.0, 6.0, 8.0, 10.0] - # src = blocks.vector_source_c(src_data) - # op = blocks.complex_to_float() - # dst1 = blocks.vector_sink_f() - # dst2 = blocks.vector_sink_f() - # self.tb.connect(src, op) - # self.tb.connect((op, 0), dst1) - # self.tb.connect((op, 1), dst2) - # self.tb.run() - # self.assertFloatTuplesAlmostEqual(expected_data1, dst1.data()) - # self.assertFloatTuplesAlmostEqual(expected_data2, dst2.data()) - - # def test_complex_to_real(self): - # src_data = (1 + 2j, 3 + 4j, 5 + 6j, 7 + 8j, 9 + 10j) - # expected_data = [1.0, 3.0, 5.0, 7.0, 9.0] - # src = blocks.vector_source_c(src_data) - # op = blocks.complex_to_real() - # dst = blocks.vector_sink_f() - # self.tb.connect(src, op, dst) - # self.tb.run() - # self.assertFloatTuplesAlmostEqual(expected_data, dst.data()) - - # def test_complex_to_imag(self): - # src_data = (1 + 2j, 3 + 4j, 5 + 6j, 7 + 8j, 9 + 10j) - # expected_data = [2.0, 4.0, 6.0, 8.0, 10.0] - # src = blocks.vector_source_c(src_data) - # op = blocks.complex_to_imag() - # dst = blocks.vector_sink_f() - # self.tb.connect(src, op, dst) - # self.tb.run() - # self.assertFloatTuplesAlmostEqual(expected_data, dst.data()) - - def test_complex_to_mag(self): - src_data = (1 + 2j, 3 - 4j, 5 + 6j, 7 - 8j, -9 + 10j) - expected_data = [sqrt(5), sqrt(25), sqrt(61), sqrt(113), sqrt(181)] - src = blocks.vector_source_c(src_data) - op = math.complex_to_mag() - dst = blocks.vector_sink_f() - self.tb.connect(src, op) - self.tb.connect(op, dst) - self.rt.initialize(self.tb) - self.rt.run() - self.assertFloatTuplesAlmostEqual(expected_data, dst.data(), 5) - - def test_complex_to_mag_squared(self): - src_data = (1 + 2j, 3 - 4j, 5 + 6j, 7 - 8j, -9 + 10j) - expected_data = [5.0, 25.0, 61.0, 113.0, 181.0] - src = blocks.vector_source_c(src_data) - op = math.complex_to_mag_squared() - dst = blocks.vector_sink_f() - self.tb.connect(src, op) - self.tb.connect(op, dst) - self.rt.initialize(self.tb) - self.rt.run() - self.assertFloatTuplesAlmostEqual(expected_data, dst.data()) - - # def test_complex_to_arg(self): - # src_data = (1 + 2j, 3 - 4j, 5 + 6j, 7 - 8j, -9 + 10j) - # expected_data = [atan2(2, 1), atan2(-4, 3), - # atan2(6, 5), atan2(-8, 7), atan2(10, -9)] - # src = blocks.vector_source_c(src_data) - # op = blocks.complex_to_arg() - # dst = blocks.vector_sink_f() - # self.tb.connect(src, op, dst) - # self.tb.run() - # self.assertFloatTuplesAlmostEqual(expected_data, dst.data(), 2) - - # def test_float_to_char_identity(self): - # src_data = (1.0, 2.0, 3.0, 4.0, 5.0) - # expected_data = [1, 2, 3, 4, 5] - # src = blocks.vector_source_f(src_data) - # op = blocks.float_to_char() - # dst = blocks.vector_sink_b() - # self.tb.connect(src, op, dst) - # self.tb.run() - # self.assertEqual(expected_data, dst.data()) - - # def test_float_to_char_scale(self): - # src_data = (1.0, 2.0, 3.0, 4.0, 5.0) - # expected_data = [5, 10, 15, 20, 25] - # src = blocks.vector_source_f(src_data) - # op = blocks.float_to_char(1, 5) - # dst = blocks.vector_sink_b() - # self.tb.connect(src, op, dst) - # self.tb.run() - # self.assertEqual(expected_data, dst.data()) - - # def test_float_to_complex_1(self): - # src_data = (1.0, 3.0, 5.0, 7.0, 9.0) - # expected_data = [1 + 0j, 3 + 0j, 5 + 0j, 7 + 0j, 9 + 0j] - # src = blocks.vector_source_f(src_data) - # op = blocks.float_to_complex() - # dst = blocks.vector_sink_c() - # self.tb.connect(src, op, dst) - # self.tb.run() - # self.assertFloatTuplesAlmostEqual(expected_data, dst.data()) - - # def test_float_to_complex_2(self): - # src1_data = (1.0, 3.0, 5.0, 7.0, 9.0) - # src2_data = (2.0, 4.0, 6.0, 8.0, 10.0) - # expected_data = [1 + 2j, 3 + 4j, 5 + 6j, 7 + 8j, 9 + 10j] - # src1 = blocks.vector_source_f(src1_data) - # src2 = blocks.vector_source_f(src2_data) - # op = blocks.float_to_complex() - # dst = blocks.vector_sink_c() - # self.tb.connect(src1, (op, 0)) - # self.tb.connect(src2, (op, 1)) - # self.tb.connect(op, dst) - # self.tb.run() - # self.assertFloatTuplesAlmostEqual(expected_data, dst.data()) - - # def test_float_to_int_identity(self): - # src_data = (1.0, 2.0, 3.0, 4.0, 5.0) - # expected_data = [1, 2, 3, 4, 5] - # src = blocks.vector_source_f(src_data) - # op = blocks.float_to_int() - # dst = blocks.vector_sink_i() - # self.tb.connect(src, op, dst) - # self.tb.run() - # self.assertEqual(expected_data, dst.data()) - - # def test_float_to_int_scale(self): - # src_data = (1.0, 2.0, 3.0, 4.0, 5.0) - # expected_data = [5, 10, 15, 20, 25] - # src = blocks.vector_source_f(src_data) - # op = blocks.float_to_int(1, 5) - # dst = blocks.vector_sink_i() - # self.tb.connect(src, op, dst) - # self.tb.run() - # self.assertEqual(expected_data, dst.data()) - - # def test_float_to_short_identity(self): - # src_data = (1.0, 2.0, 3.0, 4.0, 5.0) - # expected_data = [1, 2, 3, 4, 5] - # src = blocks.vector_source_f(src_data) - # op = blocks.float_to_short() - # dst = blocks.vector_sink_s() - # self.tb.connect(src, op, dst) - # self.tb.run() - # self.assertEqual(expected_data, dst.data()) - - # def test_float_to_short_scale(self): - # src_data = (1.0, 2.0, 3.0, 4.0, 5.0) - # expected_data = [5, 10, 15, 20, 25] - # src = blocks.vector_source_f(src_data) - # op = blocks.float_to_short(1, 5) - # dst = blocks.vector_sink_s() - # self.tb.connect(src, op, dst) - # self.tb.run() - # self.assertEqual(expected_data, dst.data()) - - # def test_float_to_uchar(self): - # src_data = (1.0, -2.0, 3.0, -4.0, 256.0) - # expected_data = [1, 0, 3, 0, 255] - # src = blocks.vector_source_f(src_data) - # op = blocks.float_to_uchar() - # dst = blocks.vector_sink_b() - # self.tb.connect(src, op, dst) - # self.tb.run() - # self.assertEqual(expected_data, dst.data()) - - # def test_int_to_float_identity(self): - # src_data = (1, 2, 3, 4, 5) - # expected_data = [1.0, 2.0, 3.0, 4.0, 5.0] - # src = blocks.vector_source_i(src_data) - # op = blocks.int_to_float() - # dst = blocks.vector_sink_f() - # self.tb.connect(src, op, dst) - # self.tb.run() - # self.assertFloatTuplesAlmostEqual(expected_data, dst.data()) - - # def test_int_to_float_scale(self): - # src_data = (1, 2, 3, 4, 5) - # expected_data = [0.2, 0.4, 0.6, 0.8, 1.0] - # src = blocks.vector_source_i(src_data) - # op = blocks.int_to_float(1, 5) - # dst = blocks.vector_sink_f() - # self.tb.connect(src, op, dst) - # self.tb.run() - # self.assertFloatTuplesAlmostEqual(expected_data, dst.data()) - - # def test_interleaved_short_to_complex(self): - # src_data = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10) - # expected_data = [1 + 2j, 3 + 4j, 5 + 6j, 7 + 8j, 9 + 10j] - # src = blocks.vector_source_s(src_data, vlen=2) - # op = streamops.interleaved_short_to_complex() - # dst = blocks.vector_sink_c() - # self.tb.connect(src, op) - # self.tb.connect(op, dst) - # self.tb.run() - # self.assertEqual(expected_data, dst.data()) - - # def test_short_to_char(self): - # src_data = (256, 512, 768, 1024, 1280) - # expected_data = [1, 2, 3, 4, 5] - # src = blocks.vector_source_s(src_data) - # op = blocks.short_to_char() - # dst = blocks.vector_sink_b() - # self.tb.connect(src, op, dst) - # self.tb.run() - # self.assertEqual(expected_data, dst.data()) - - # def test_short_to_float_identity(self): - # src_data = (1, 2, 3, 4, 5) - # expected_data = [1.0, 2.0, 3.0, 4.0, 5.0] - # src = blocks.vector_source_s(src_data) - # op = blocks.short_to_float() - # dst = blocks.vector_sink_f() - # self.tb.connect(src, op, dst) - # self.tb.run() - # self.assertEqual(expected_data, dst.data()) - - # def test_short_to_float_scale(self): - # src_data = (5, 10, 15, 20, 25) - # expected_data = [1.0, 2.0, 3.0, 4.0, 5.0] - # src = blocks.vector_source_s(src_data) - # op = blocks.short_to_float(1, 5) - # dst = blocks.vector_sink_f() - # self.tb.connect(src, op, dst) - # self.tb.run() - # self.assertEqual(expected_data, dst.data()) - - # def test_uchar_to_float(self): - # src_data = (1, 2, 3, 4, 5) - # expected_data = [1.0, 2.0, 3.0, 4.0, 5.0] - # src = blocks.vector_source_b(src_data) - # op = blocks.uchar_to_float() - # dst = blocks.vector_sink_f() - # self.tb.connect(src, op, dst) - # self.tb.run() - # self.assertEqual(expected_data, dst.data()) - - -if __name__ == '__main__': - gr_unittest.run(test_type_conversions) diff --git a/blocklib/meson.build b/blocklib/meson.build index 0e30f3c60..c1655791d 100644 --- a/blocklib/meson.build +++ b/blocklib/meson.build @@ -17,31 +17,6 @@ endif if get_option('enable_gr_blocks') subdir('blocks') endif - -if get_option('enable_gr_fec') -subdir('fec') -endif -if get_option('enable_gr_fft') -subdir('fft') -endif -if get_option('enable_gr_filter') -subdir('filter') -endif -if get_option('enable_gr_analog') -subdir('analog') -endif if get_option('enable_gr_streamops') subdir('streamops') endif -if get_option('enable_gr_fileio') -subdir('fileio') -endif -if get_option('enable_gr_zeromq') -subdir('zeromq') -endif -if get_option('enable_gr_audio') -subdir('audio') -endif -if get_option('enable_gr_soapy') -subdir('soapy') -endif diff --git a/blocklib/soapy/.gitignore b/blocklib/soapy/.gitignore deleted file mode 100644 index 74cf878c2..000000000 --- a/blocklib/soapy/.gitignore +++ /dev/null @@ -1,5 +0,0 @@ -meson.build -!include/gnuradio/soapy/meson.build -!lib/meson.build -!python/gnuradio/soapy/bindings/meson.build -!test/meson.build diff --git a/blocklib/soapy/hackrf_sink/hackrf_sink.yml b/blocklib/soapy/hackrf_sink/hackrf_sink.yml deleted file mode 100644 index 661a44ed8..000000000 --- a/blocklib/soapy/hackrf_sink/hackrf_sink.yml +++ /dev/null @@ -1,92 +0,0 @@ -module: soapy -block: hackrf_sink -label: HackRF Sink -blocktype: grc -category: '[Core]/Soapy' - -typekeys: - - id: T - type: class - options: - - cf32 - # - rf32 - -grc: - flags: [python] - templates: - imports: from gnuradio import soapy - make: |- - dev = 'driver=hackrf' - stream_args = '' - tune_args = [''] - settings = [''] - - self.${id} = soapy.sink_${T.fcn}(dev, 1, ${dev_args}, - stream_args, tune_args, settings) - self.${id}.set_sample_rate(0, ${samp_rate}) - self.${id}.set_bandwidth(0, ${bandwidth}) - self.${id}.set_frequency(0, ${center_freq}) - self.${id}.set_gain(0, 'AMP', ${amp}) - self.${id}.set_gain(0, 'VGA', min(max(${vga}, 0.0), 47.0)) - callbacks: - - set_sample_rate(0, ${samp_rate}) - - set_bandwidth(0, ${bandwidth}) - - set_frequency(0, ${center_freq}) - - set_gain(0, 'AMP', ${amp}) - - set_gain(0, 'VGA', min(max(${vga}, 0.0), 47.0)) - - -parameters: - - id: dev_args - label: Device arguments - dtype: string - grc: - hide: ${'part' if not dev_args else 'none'} - - - id: samp_rate - label: Sample Rate - dtype: rf32 - grc: - default: 'samp_rate' - - - id: bandwidth - label: Bandwidth (0=auto) - dtype: rf32 - grc: - default: '0' - hide: part - category: RF Options - - - id: center_freq - label: 'Center Freq (Hz)' - dtype: rf64 - grc: - category: RF Options - default: 'freq' - - - id: amp - label: 'Amp On (+14 dB)' - dtype: bool - grc: - default: 'False' - hide: part - category: RF Options - - - id: vga - label: 'VGA Gain (0dB - 47dB)' - dtype: rf64 - grc: - default: '16' - hide: part - category: RF Options - -ports: - - domain: stream - id: in - direction: input - type: typekeys/T - -implementations: -- id: cpu - -file_format: 1 diff --git a/blocklib/soapy/hackrf_source/hackrf_source.yml b/blocklib/soapy/hackrf_source/hackrf_source.yml deleted file mode 100644 index c63bdff42..000000000 --- a/blocklib/soapy/hackrf_source/hackrf_source.yml +++ /dev/null @@ -1,104 +0,0 @@ -module: soapy -block: hackrf_source -label: HackRF Source -blocktype: grc -category: '[Core]/Soapy' - -typekeys: - - id: T - type: class - options: - - cf32 - # - rf32 - -grc: - flags: [python] - templates: - imports: |- - from gnuradio import soapy - make: |- - dev = 'driver=hackrf' - stream_args = '' - tune_args = [''] - settings = [''] - - self.${id} = soapy.source_${T.fcn}(dev, 1, ${dev_args}, - stream_args, tune_args, settings) - self.${id}.set_sample_rate(0, ${samp_rate}) - self.${id}.set_bandwidth(0, ${bandwidth}) - self.${id}.set_frequency(0, ${center_freq}) - self.${id}.set_gain(0, 'AMP', ${amp}) - self.${id}.set_gain(0, 'LNA', min(max(${gain}, 0.0), 40.0)) - self.${id}.set_gain(0, 'VGA', min(max(${vga}, 0.0), 62.0)) - callbacks: - - set_sample_rate(0, ${samp_rate}) - - set_bandwidth(0, ${bandwidth}) - - set_frequency(0, ${center_freq}) - - set_gain(0, 'AMP', ${amp}) - - set_gain(0, 'LNA', min(max(${gain}, 0.0), 40.0)) - - set_gain(0, 'VGA', min(max(${vga}, 0.0), 62.0)) - - -parameters: - - id: dev_args - label: Device arguments - dtype: string - grc: - hide: ${'part' if not dev_args else 'none'} - - - id: samp_rate - label: Sample Rate - dtype: rf32 - grc: - default: 'samp_rate' - - - id: bandwidth - label: Bandwidth (0=auto) - dtype: rf32 - grc: - category: RF Options - default: '0' - hide: part - - - id: center_freq - label: 'Center Freq (Hz)' - - dtype: rf32 - grc: - category: RF Options - default: 'freq' - - - id: amp - label: 'Amp On (+14 dB)' - dtype: bool - grc: - category: RF Options - default: 'False' - hide: part - - - id: gain - label: 'IF Gain (0dB - 40dB)' - dtype: rf32 - grc: - category: RF Options - default: '16' - hide: part - - - id: vga - label: 'VGA Gain (0dB - 62dB)' - dtype: rf32 - grc: - category: RF Options - default: '16' - hide: part - -ports: - - domain: stream - id: out - direction: output - type: typekeys/T - -implementations: -- id: cpu - -file_format: 1 diff --git a/blocklib/soapy/include/gnuradio/soapy/api.h b/blocklib/soapy/include/gnuradio/soapy/api.h deleted file mode 100644 index be2073508..000000000 --- a/blocklib/soapy/include/gnuradio/soapy/api.h +++ /dev/null @@ -1,19 +0,0 @@ -/* - * gr-soapy: Soapy SDR Radio Module - * - * Copyright (C) 2018 - * Libre Space Foundation <http://librespacefoundation.org/> - * - * SPDX-License-Identifier: GPL-3.0-or-later - * - */ - -#pragma once - -#include <gnuradio/attributes.h> - -#ifdef gnuradio_soapy_EXPORTS -#define SOAPY_API __GR_ATTR_EXPORT -#else -#define SOAPY_API __GR_ATTR_IMPORT -#endif diff --git a/blocklib/soapy/include/gnuradio/soapy/block.h b/blocklib/soapy/include/gnuradio/soapy/block.h deleted file mode 100644 index 49422881b..000000000 --- a/blocklib/soapy/include/gnuradio/soapy/block.h +++ /dev/null @@ -1,726 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2021 Jeff Long - * Copyright 2018-2021 Libre Space Foundation <http://libre.space/> - * - * SPDX-License-Identifier: GPL-3.0-or-later - */ - -#pragma once - -#include <gnuradio/block.h> -#include <gnuradio/soapy/api.h> -#include <gnuradio/soapy/soapy_types.h> -#include <cstdint> -#include <string> -#include <vector> - -namespace gr { -namespace soapy { - -class SOAPY_API block : virtual public gr::block -{ -public: - /*! - * A key that uniquely identifies the device driver. - * This key identifies the underlying implementation. - * Several variants of a product may share a driver. - */ - virtual std::string get_driver_key() const = 0; - - /*! - * A key that uniquely identifies the hardware. - * This key should be meaningful to the user - * to optimize for the underlying hardware. - */ - virtual std::string get_hardware_key() const = 0; - - /*! - * Query a dictionary of available device information. - * This dictionary can any number of values like - * vendor name, product name, revisions, serials... - * This information can be displayed to the user - * to help identify the instantiated device. - */ - virtual kwargs_t get_hardware_info() const = 0; - - /*! - * Set the frontend mapping of available DSP units to RF frontends. - * This mapping controls channel mapping and channel availability. - * \param frontend_mapping a vendor-specific mapping string - */ - virtual void set_frontend_mapping(const std::string& frontend_mapping) = 0; - - /*! - * Get the frontend mapping of available DSP units to RF frontends. - * This mapping describes channel mapping and channel availability. - * \return a vendor-specific mapping string - */ - virtual std::string get_frontend_mapping() const = 0; - - /*! - * Query a dictionary of available channel information. - * This dictionary can any number of values like - * decoder type, version, available functions... - * This information can be displayed to the user - * to help identify the instantiated channel. - * \param channel an available channel on the device - * \return channel information - */ - virtual kwargs_t get_channel_info(size_t channel) const = 0; - - /*! - * Set sample rate - * \param channel an available channel - * \param sample_rate samples per second - */ - virtual void set_sample_rate(size_t channel, double sample_rate) = 0; - - /*! - * Get the baseband sample rate of the RX chain. - * \param channel an available channel on the device - * \return the sample rate in samples per second - */ - virtual double get_sample_rate(size_t channel) const = 0; - - /*! - * Get the range of possible baseband sample rates. - * \param channel an available channel on the device - * \return a list of sample rate ranges in samples per second - */ - virtual range_list_t get_sample_rate_range(size_t channel) const = 0; - - /*! - * Set device center frequency - * \param channel an available channel - * \param freq frequency in Hz - */ - virtual void set_frequency(size_t channel, double freq) = 0; - - /*! - * Set center frequency of a tunable element - * \param channel an available channel - * \param name an available element name - * \param freq frequency in Hz - */ - virtual void set_frequency(size_t channel, const std::string& name, double freq) = 0; - - /*! - * Get the down conversion frequency of the chain. - * \param channel an available channel on the device - * \return the center frequency in Hz - */ - virtual double get_frequency(size_t channel) const = 0; - - /*! - * Get the frequency of a tunable element in the chain. - * \param channel an available channel on the device - * \param name the name of a tunable element - * \return the tunable element's frequency in Hz - */ - virtual double get_frequency(size_t channel, const std::string& name) const = 0; - - /*! - * List available tunable elements in the chain. - * Elements should be in order RF to baseband. - * \param channel an available channel - * \return a list of tunable elements by name - */ - virtual std::vector<std::string> list_frequencies(size_t channel) const = 0; - - /*! - * Get the range of overall frequency values. - * \param channel an available channel on the device - * \return a list of frequency ranges in Hz - */ - virtual range_list_t get_frequency_range(size_t channel) const = 0; - - /*! - * Get the range of tunable values for the specified element. - * \param channel an available channel on the device - * \param name the name of a tunable element - * \return a list of frequency ranges in Hz - */ - virtual range_list_t get_frequency_range(size_t channel, - const std::string& name) const = 0; - - /*! - * Query the argument info description for stream args. - * \param channel an available channel on the device - * \return a list of argument info structures - */ - virtual arginfo_list_t get_frequency_args_info(size_t channel) const = 0; - - /*! - * Set filter bandwidth - * \param channel an available channel - * \param bandwidth filter width in Hz - */ - virtual void set_bandwidth(size_t channel, double bandwidth) = 0; - - /*! - * Get baseband filter width of the RX chain. - * \param channel an available channel on the device - * \return the baseband filter width in Hz - */ - virtual double get_bandwidth(size_t channel) const = 0; - - /*! - * Get the range of possible baseband filter widths. - * \param channel an available channel on the device - * \return a list of bandwidth ranges in Hz - */ - virtual range_list_t get_bandwidth_range(size_t channel) const = 0; - - /*! - * List available antennas for a channel - * @param channel channel index - * @return available antenna names - */ - virtual std::vector<std::string> list_antennas(int channel) const = 0; - - /*! - * Set antenna for channel - * \param channel an available channel - * \param name an available antenna string name - */ - virtual void set_antenna(size_t channel, const std::string& name) = 0; - - /*! - * Get the selected antenna on RX chain. - * \param channel an available channel on the device - * \return the name of the selected antenna - */ - virtual std::string get_antenna(size_t channel) const = 0; - - /*! - * Return whether automatic gain control (AGC) is supported - * \param channel an available channel - */ - virtual bool has_gain_mode(size_t channel) const = 0; - - /*! - * Set automatic gain control (AGC) - * \param channel an available channel - * \param enable true to enable AGC - */ - virtual void set_gain_mode(size_t channel, bool enable) = 0; - - /*! - * Get the automatic gain mode on the RX chain. - * \param channel an available channel on the device - * \return true for automatic gain setting - */ - virtual bool get_gain_mode(size_t channel) const = 0; - - /*! - * List available amplification elements. - * Elements should be in order RF to baseband. - * \param channel an available channel - * \return a list of gain string names - */ - virtual std::vector<std::string> list_gains(size_t channel) const = 0; - - /*! - * Set overall gain - * The gain will be distributed automatically across available - * elements according to Soapy API. - * \param channel an available channel - * \param gain overall gain value - */ - virtual void set_gain(size_t channel, double gain) = 0; - - /*! - * Set specific gain value - * \param channel an available channel - * \param name gain name to set - * \param gain gain value - */ - virtual void set_gain(size_t channel, const std::string& name, double gain) = 0; - - /*! - * Get the overall value of the gain elements in a chain - * \param channel an available channel on the device - * \return the value of the gain in dB - */ - virtual double get_gain(size_t channel) const = 0; - - /*! - * Get the value of an individual amplification element in a chain. - * \param channel an available channel on the device - * \param name the name of an amplification element - * \return the value of the gain in dB - */ - virtual double get_gain(size_t channel, const std::string& name) const = 0; - - /*! - * Get the overall range of possible gain values. - * \param channel an available channel on the device - * \return a list of gain ranges in dB - */ - virtual range_t get_gain_range(size_t channel) const = 0; - - /*! - * Get the range of possible gain values for a specific element. - * \param channel an available channel on the device - * \param name the name of an amplification element - * \return a list of gain ranges in dB - */ - virtual range_t get_gain_range(size_t channel, const std::string& name) const = 0; - - /*! - * Return whether frequency correction is supported - * \param channel an available channel - */ - virtual bool has_frequency_correction(size_t channel) const = 0; - - /*! - * Set frequency correction - * \param channel an available channel - * \param freq_correction in PPM - */ - virtual void set_frequency_correction(size_t channel, double freq_correction) = 0; - - /*! - * Get the frequency correction value. - * \param channel an available channel on the device - * \return the correction value in PPM - */ - virtual double get_frequency_correction(size_t channel) const = 0; - - /*! - * Return whether DC offset mode can be set - * \param channel an available channel - */ - virtual bool has_dc_offset_mode(size_t channel) const = 0; - - /*! - * Set DC offset mode - * \param channel an available channel - * \param automatic true to set automatic DC removal - */ - virtual void set_dc_offset_mode(size_t channel, bool automatic) = 0; - - /*! - * Get the automatic DC offset correction mode. - * \param channel an available channel on the device - * \return true for automatic offset correction - */ - virtual bool get_dc_offset_mode(size_t channel) const = 0; - - /*! - * Return whether manual dc offset correction is supported - * \param channel an available channel - */ - virtual bool has_dc_offset(size_t channel) const = 0; - - /*! - * Set dc offset correction - * \param channel an available channel - * \param dc_offset complex dc offset correction - */ - virtual void set_dc_offset(size_t channel, const gr_complexd& dc_offset) = 0; - - /*! - * Get the DC offset correction. - * \param channel an available channel on the device - * \return the relative correction (1.0 max) - */ - virtual gr_complexd get_dc_offset(size_t channel) const = 0; - - /*! - * Return whether manual IQ balance correction is supported - * \param channel an available channel - */ - virtual bool has_iq_balance(size_t channel) const = 0; - - /*! - * Set IQ balance correction - * \param channel an available channel - * \param iq_balance complex iq balance correction - */ - virtual void set_iq_balance(size_t channel, const gr_complexd& iq_balance) = 0; - - /*! - * Get the IQ balance correction. - * \param channel an available channel on the device - * \return the relative correction (1.0 max) - */ - virtual gr_complexd get_iq_balance(size_t channel) const = 0; - - /*! - * Does the device support automatic frontend IQ balance correction? - * \param channel an available channel on the device - * \return true if IQ balance corrections are supported - */ - virtual bool has_iq_balance_mode(size_t channel) const = 0; - - /*! - * Set the automatic frontend IQ balance correction. - * \param channel an available channel on the device - * \param automatic true for automatic correction - */ - virtual void set_iq_balance_mode(size_t channel, bool automatic) = 0; - - /*! - * Get the automatic IQ balance corrections mode. - * \param channel an available channel on the device - * \return true for automatic correction - */ - virtual bool get_iq_balance_mode(size_t channel) const = 0; - - /*! - * Set master clock rate - * \param clock_rate clock rate in Hz - */ - virtual void set_master_clock_rate(double clock_rate) = 0; - - /*! - * Get the master clock rate of the device. - * \return the clock rate in Hz - */ - virtual double get_master_clock_rate() const = 0; - - /*! - * Get the range of available master clock rates. - * \return a list of clock rate ranges in Hz - */ - virtual range_list_t get_master_clock_rates() const = 0; - - /*! - * Set the reference clock rate of the device. - * \param rate the clock rate in Hz - */ - virtual void set_reference_clock_rate(double rate) = 0; - - /*! - * Get the reference clock rate of the device. - * \return the clock rate in Hz - */ - virtual double get_reference_clock_rate() const = 0; - - /*! - * Get the range of available reference clock rates. - * \return a list of clock rate ranges in Hz - */ - virtual range_list_t get_reference_clock_rates() const = 0; - - /*! - * Get the list of available clock sources. - * \return a list of clock source names - */ - virtual std::vector<std::string> list_clock_sources() const = 0; - - /*! - * Set the clock source - * \param clock_source an available clock source - */ - virtual void set_clock_source(const std::string& clock_source) = 0; - - /*! - * Get the clock source of the device - * \return the name of the clock source - */ - virtual std::string get_clock_source() const = 0; - - /*! - * Get the list of available time sources. - * \return a list of time source names - */ - virtual std::vector<std::string> list_time_sources() const = 0; - - /*! - * Set the time source on the device - * \param source the name of a time source - */ - virtual void set_time_source(const std::string& source) = 0; - - /*! - * Get the time source of the device - * \return the name of a time source - */ - virtual std::string get_time_source() const = 0; - - /*! - * Does this device have a hardware clock? - * \param what optional argument - * \return true if the hardware clock exists - */ - virtual bool has_hardware_time(const std::string& what = "") const = 0; - - /*! - * Read the time from the hardware clock on the device. - * The what argument can refer to a specific time counter. - * \param what optional argument - * \return the time in nanoseconds - */ - virtual long long get_hardware_time(const std::string& what = "") const = 0; - - /*! - * Write the time to the hardware clock on the device. - * The what argument can refer to a specific time counter. - * \param timeNs time in nanoseconds - * \param what optional argument - */ - virtual void set_hardware_time(long long timeNs, const std::string& what = "") = 0; - - /*! - * List the available global readback sensors. - * A sensor can represent a reference lock, RSSI, temperature. - * \return a list of available sensor string names - */ - virtual std::vector<std::string> list_sensors() const = 0; - - /*! - * Get meta-information about a sensor. - * Example: displayable name, type, range. - * \param key the ID name of an available sensor - * \return meta-information about a sensor - */ - virtual arginfo_t get_sensor_info(const std::string& key) const = 0; - - /*! - * Readback a global sensor given the name. - * The value returned is a string which can represent - * a boolean ("true"/"false"), an integer, or float. - * \param key the ID name of an available sensor - * \return the current value of the sensor - */ - virtual std::string read_sensor(const std::string& key) const = 0; - - /*! - * List the available channel readback sensors. - * A sensor can represent a reference lock, RSSI, temperature. - * \param channel an available channel on the device - * \return a list of available sensor string names - */ - virtual std::vector<std::string> list_sensors(size_t channel) const = 0; - - /*! - * Get meta-information about a channel sensor. - * Example: displayable name, type, range. - * \param channel an available channel on the device - * \param key the ID name of an available sensor - * \return meta-information about a sensor - */ - virtual arginfo_t get_sensor_info(size_t channel, const std::string& key) const = 0; - - /*! - * Readback a channel sensor given the name. - * The value returned is a string which can represent - * a boolean ("true"/"false"), an integer, or float. - * \param channel an available channel on the device - * \param key the ID name of an available sensor - * \return the current value of the sensor - */ - virtual std::string read_sensor(size_t channel, const std::string& key) const = 0; - - /*! - * Get a list of available register interfaces by name. - * \return a list of available register interfaces - */ - virtual std::vector<std::string> list_register_interfaces() const = 0; - - /*! - * Write a register on the device given the interface name. - * This can represent a register on a soft CPU, FPGA, IC; - * the interpretation is up the implementation to decide. - * \param name the name of a available register interface - * \param addr the register address - * \param value the register value - */ - virtual void - write_register(const std::string& name, unsigned addr, unsigned value) = 0; - - /*! - * Read a register on the device given the interface name. - * \param name the name of a available register interface - * \param addr the register address - * \return the register value - */ - virtual unsigned read_register(const std::string& name, unsigned addr) const = 0; - - /*! - * Write a memory block on the device given the interface name. - * This can represent a memory block on a soft CPU, FPGA, IC; - * the interpretation is up the implementation to decide. - * \param name the name of a available memory block interface - * \param addr the memory block start address - * \param value the memory block content - */ - virtual void write_registers(const std::string& name, - unsigned addr, - const std::vector<unsigned>& value) = 0; - - /*! - * Read a memory block on the device given the interface name. - * \param name the name of a available memory block interface - * \param addr the memory block start address - * \param length number of words to be read from memory block - * \return the memory block content - */ - virtual std::vector<unsigned> - read_registers(const std::string& name, unsigned addr, size_t length) const = 0; - - /*! - * Describe the allowed keys and values used for settings. - * \return a list of argument info structures - */ - virtual arginfo_list_t get_setting_info() const = 0; - - /*! - * Write an arbitrary setting on the device. - * The interpretation is up the implementation. - * \param key the setting identifier - * \param value the setting value - */ - virtual void write_setting(const std::string& key, const std::string& value) = 0; - - /*! - * Read an arbitrary setting on the device. - * \param key the setting identifier - * \return the setting value - */ - virtual std::string read_setting(const std::string& key) const = 0; - - /*! - * Describe the allowed keys and values used for channel settings. - * \param channel an available channel on the device - * \return a list of argument info structures - */ - virtual arginfo_list_t get_setting_info(size_t channel) const = 0; - - /*! - * Write an arbitrary channel setting on the device. - * The interpretation is up the implementation. - * \param channel an available channel on the device - * \param key the setting identifier - * \param value the setting value - */ - virtual void - write_setting(size_t channel, const std::string& key, const std::string& value) = 0; - - /*! - * Read an arbitrary channel setting on the device. - * \param channel an available channel on the device - * \param key the setting identifier - * \return the setting value - */ - virtual std::string read_setting(size_t channel, const std::string& key) const = 0; - - /*! - * Get a list of available GPIO banks by name. - */ - virtual std::vector<std::string> list_gpio_banks() const = 0; - - /*! - * Write the value of a GPIO bank. - * \param bank the name of an available bank - * \param value an integer representing GPIO bits - */ - virtual void write_gpio(const std::string& bank, unsigned value) = 0; - - /*! - * Write the value of a GPIO bank with modification mask. - * \param bank the name of an available bank - * \param value an integer representing GPIO bits - * \param mask a modification mask where 1 = modify - */ - virtual void write_gpio(const std::string& bank, unsigned value, unsigned mask) = 0; - - /*! - * Readback the value of a GPIO bank. - * \param bank the name of an available bank - * \return an integer representing GPIO bits - */ - virtual unsigned read_gpio(const std::string& bank) const = 0; - - /*! - * Write the data direction of a GPIO bank. - * 1 bits represent outputs, 0 bits represent inputs. - * \param bank the name of an available bank - * \param dir an integer representing data direction bits - */ - virtual void write_gpio_dir(const std::string& bank, unsigned dir) = 0; - - /*! - * Write the data direction of a GPIO bank with modification mask. - * 1 bits represent outputs, 0 bits represent inputs. - * \param bank the name of an available bank - * \param dir an integer representing data direction bits - * \param mask a modification mask where 1 = modify - */ - virtual void write_gpio_dir(const std::string& bank, unsigned dir, unsigned mask) = 0; - - /*! - * Read the data direction of a GPIO bank. - * 1 bits represent outputs, 0 bits represent inputs. - * \param bank the name of an available bank - * \return an integer representing data direction bits - */ - virtual unsigned read_gpio_dir(const std::string& bank) const = 0; - - /*! - * Write to an available I2C slave. - * If the device contains multiple I2C masters, - * the address bits can encode which master. - * \param addr the address of the slave - * \param data an array of bytes write out - */ - virtual void write_i2c(int addr, const std::string& data) = 0; - - /*! - * Read from an available I2C slave. - * If the device contains multiple I2C masters, - * the address bits can encode which master. - * \param addr the address of the slave - * \param num_bytes the number of bytes to read - * \return an array of bytes read from the slave - */ - virtual std::string read_i2c(int addr, size_t num_bytes) = 0; - - /*! - * Perform a SPI transaction and return the result. - * Its up to the implementation to set the clock rate, - * and read edge, and the write edge of the SPI core. - * SPI slaves without a readback pin will return 0. - * - * If the device contains multiple SPI masters, - * the address bits can encode which master. - * - * \param addr an address of an available SPI slave - * \param data the SPI data, num_bits-1 is first out - * \param num_bits the number of bits to clock out - * \return the readback data, num_bits-1 is first in - */ - virtual unsigned transact_spi(int addr, unsigned data, size_t num_bits) = 0; - - /*! - * Enumerate the available UART devices. - * \return a list of names of available UARTs - */ - virtual std::vector<std::string> list_uarts() const = 0; - - /*! - * Write data to a UART device. - * Its up to the implementation to set the baud rate, - * carriage return settings, flushing on newline. - * \param which the name of an available UART - * \param data an array of bytes to write out - */ - virtual void write_uart(const std::string& which, const std::string& data) = 0; - - /*! - * Read bytes from a UART until timeout or newline. - * Its up to the implementation to set the baud rate, - * carriage return settings, flushing on newline. - * \param which the name of an available UART - * \param timeout_us a timeout in microseconds - * \return an array of bytes read from the UART - */ - virtual std::string read_uart(const std::string& which, - long timeout_us = 100000) const = 0; -}; - -} // namespace soapy -} // namespace gr diff --git a/blocklib/soapy/include/gnuradio/soapy/meson.build b/blocklib/soapy/include/gnuradio/soapy/meson.build deleted file mode 100644 index 415d5a6b1..000000000 --- a/blocklib/soapy/include/gnuradio/soapy/meson.build +++ /dev/null @@ -1,3 +0,0 @@ -headers = [] - -install_headers(headers, subdir : 'gnuradio/soapy')
\ No newline at end of file diff --git a/blocklib/soapy/include/gnuradio/soapy/soapy_types.h b/blocklib/soapy/include/gnuradio/soapy/soapy_types.h deleted file mode 100644 index 1d276db22..000000000 --- a/blocklib/soapy/include/gnuradio/soapy/soapy_types.h +++ /dev/null @@ -1,32 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2021 Free Software Foundation, Inc. - * - * This file is part of GNU Radio - * - * SPDX-License-Identifier: GPL-3.0-or-later - * - */ - -#pragma once - -/* GR-style type aliases for Soapy types exposed in gr-soapy blocks */ - -#include <SoapySDR/Types.hpp> - -namespace gr { -namespace soapy { - -using arginfo_t = SoapySDR::ArgInfo; -using arginfo_list_t = SoapySDR::ArgInfoList; - -using argtype_t = SoapySDR::ArgInfo::Type; - -using kwargs_t = SoapySDR::Kwargs; -using kwargs_list_t = SoapySDR::KwargsList; - -using range_t = SoapySDR::Range; -using range_list_t = SoapySDR::RangeList; - -} // namespace soapy -} // namespace gr diff --git a/blocklib/soapy/lib/block_impl.cc b/blocklib/soapy/lib/block_impl.cc deleted file mode 100644 index 4b920526c..000000000 --- a/blocklib/soapy/lib/block_impl.cc +++ /dev/null @@ -1,1660 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2021 Jeff Long - * Copyright 2018-2021 Libre Space Foundation <http://libre.space> - * - * SPDX-License-Identifier: GPL-3.0-or-later - */ - - -#include "block_impl.h" -#include "setting_string_conversion.h" -#include <SoapySDR/Formats.h> -#include <SoapySDR/Version.hpp> -#include <fmt/core.h> -#include <pmtf/scalar.hpp> -#include <pmtf/string.hpp> -#include <cmath> -#include <numeric> - -namespace gr { -namespace soapy { - -static bool arg_info_has_key(const arginfo_list_t& info_list, const std::string& key) -{ - return std::any_of(info_list.begin(), info_list.end(), [key](const arginfo_t& info) { - return info.key == key; - }); -} - -template <typename T> -static inline bool vector_contains(const std::vector<T>& vec, const std::string& elem) -{ - return (std::find(vec.begin(), vec.end(), elem) != vec.end()); -} - -static inline bool value_in_range(const range_t& range, double value) -{ - return (value >= range.minimum()) && (value <= range.maximum()); -} - -static inline bool value_in_ranges(const range_list_t& ranges, double value) -{ - return std::any_of(ranges.begin(), ranges.end(), [value](const range_t& range) { - return value_in_range(range, value); - }); -} - -static std::string string_vector_to_string(const std::vector<std::string>& vec) -{ - if (vec.empty()) - return "[]"; - - std::string str = "["; - for (const auto& vecStr : vec) { - str += vecStr; - str += ", "; - } - str.erase(str.length() - 2, 2); - - str += "]"; - - return str; -} - -static std::string range_to_string(const range_t& range) -{ - const auto min = range.minimum(); - const auto max = range.maximum(); - - if (min == max) - return std::to_string(min); - else - return "[" + std::to_string(min) + ", " + std::to_string(max) + "]"; -} - -static std::string ranges_to_string(const range_list_t& ranges) -{ - if (ranges.empty()) - return "[]"; - - std::string str; - for (const auto& range : ranges) { - str += range_to_string(range); - str += ", "; - } - str.erase(str.length() - 2, 2); - - return str; -} - -static void check_abi(void) -{ - const std::string buildtime_abi = SOAPY_SDR_ABI_VERSION; - const std::string runtime_abi = SoapySDR::getABIVersion(); - - if (buildtime_abi != runtime_abi) { - throw std::runtime_error(fmt::format( - "\nGR-Soapy detected ABI compatibility mismatch with SoapySDR library.\n" - "GR-Soapy was built against ABI: {},\n" - "but the SoapySDR library reports ABI: {}\n" - "Suggestion: install an ABI compatible version of SoapySDR,\n" - "or rebuild GR-Soapy component against this ABI version.\n", - buildtime_abi, - runtime_abi)); - } -} - -const std::string CMD_CHAN_KEY = "chan"; -const std::string CMD_FREQ_KEY = "freq"; -const std::string CMD_GAIN_KEY = "gain"; -const std::string CMD_ANTENNA_KEY = "antenna"; -const std::string CMD_RATE_KEY = "rate"; -const std::string CMD_BW_KEY = "bandwidth"; -const std::string CMD_GAINMODE_KEY = "gain_mode"; -const std::string CMD_FREQCORR_KEY = "freq_corr"; -const std::string CMD_DCOFFSETMODE_KEY = "dc_offset_mode"; -const std::string CMD_DCOFFSET_KEY = "dc_offset"; -const std::string CMD_IQBAL_KEY = "iq_bal"; -const std::string CMD_IQBALMODE_KEY = "iq_bal_mode"; -const std::string CMD_MCR_KEY = "master_clock_rate"; -const std::string CMD_REFCLOCKRATE_KEY = "ref_clock_rate"; -const std::string CMD_CLOCKSRC_KEY = "clock_src"; -const std::string CMD_TIMESRC_KEY = "time_src"; -const std::string CMD_HWTIME_KEY = "hw_time"; -const std::string CMD_REG_KEY = "reg"; -const std::string CMD_REGS_KEY = "regs"; -const std::string CMD_SETTING_KEY = "setting"; -const std::string CMD_GPIO_KEY = "gpio"; -const std::string CMD_GPIODIR_KEY = "gpio_dir"; -const std::string CMD_I2C_KEY = "i2c"; -const std::string CMD_UART_KEY = "uart"; - -const std::string CMD_NAME_KEY = "name"; -const std::string CMD_KEY_KEY = "key"; -const std::string CMD_VALUE_KEY = "value"; -const std::string CMD_ADDR_KEY = "addr"; -const std::string CMD_MASK_KEY = "mask"; -const std::string CMD_TIME_KEY = "time"; -const std::string CMD_BANK_KEY = "bank"; -const std::string CMD_DATA_KEY = "data"; - -// Common default values for pmt::dict_ref -const pmtf::pmt PMT_EMPTYSTR = pmtf::string(""); -const pmtf::pmt PMT_ZERO = pmtf::scalar<int>(0); - -/* - * The private constructor - */ -block_impl::block_impl(int direction, - const std::string& device, - const std::string& type, - size_t nchan, - const std::string& dev_args, - const std::string& stream_args, - const std::vector<std::string>& tune_args, - const std::vector<std::string>& other_settings) - : gr::block("soapy_block"), - d_direction(direction), - d_nchan(nchan), - d_stream_args(stream_args), - d_channels(nchan) -{ - check_abi(); - - // Channel list - std::iota(std::begin(d_channels), std::end(d_channels), 0); - - // Must be 1 or nchan. - if (nchan != tune_args.size() && tune_args.size() != 1) { - throw std::invalid_argument(name() + - ": Wrong number of channels and tune arguments"); - } - - // Must be 1 or nchan. - if (nchan != other_settings.size() && other_settings.size() != 1) { - throw std::invalid_argument(name() + ": Wrong number of channels and settings"); - } - - // Convert type to Soapy type. - if (type == "fc32" || type == SOAPY_SDR_CF32) { - d_soapy_type = SOAPY_SDR_CF32; - } - else if (type == "sc16" || type == SOAPY_SDR_CS16) { - d_soapy_type = SOAPY_SDR_CS16; - } - else if (type == "sc8" || type == SOAPY_SDR_CS8) { - d_soapy_type = SOAPY_SDR_CS8; - } - else { - throw std::invalid_argument(name() + ": Invalid IO type"); - } - - kwargs_t dev_kwargs = SoapySDR::KwargsFromString(device + ", " + dev_args); - d_device = device_ptr_t(SoapySDR::Device::make(dev_kwargs)); - - /* Some of the arguments maybe device settings, so we need to re-apply them */ - arginfo_list_t supported_settings = d_device->getSettingInfo(); - for (const auto& arg : dev_kwargs) { - for (const auto& supported : supported_settings) { - if (supported.key == arg.first) { - d_device->writeSetting(arg.first, arg.second); - } - } - } - - if (d_nchan > d_device->getNumChannels(d_direction)) { - throw std::invalid_argument( - name() + ": Unsupported number of channels. Only " + - std::to_string(d_device->getNumChannels(d_direction)) + - " channels available."); - } - - /* - * Validate stream arguments for all channels - */ - for (const auto& channel : d_channels) { - arginfo_list_t supported_args = d_device->getStreamArgsInfo(d_direction, channel); - kwargs_t stream_kwargs = SoapySDR::KwargsFromString(stream_args); - - for (const auto& arg : stream_kwargs) { - if (!arg_info_has_key(supported_args, arg.first)) { - throw std::invalid_argument(name() + ": Unsupported stream argument " + - arg.first + " for channel " + - std::to_string(channel)); - } - } - } - - /* Validate tuning arguments for each channel */ - for (const auto& channel : d_channels) { - arginfo_list_t supported_args = - d_device->getFrequencyArgsInfo(d_direction, channel); - - /* If single set of args, apply to all channels */ - const size_t arg_idx = tune_args.size() == 1 ? 0 : channel; - kwargs_t tune_kwargs = SoapySDR::KwargsFromString(tune_args[arg_idx]); - - for (const auto& arg : tune_kwargs) { - if (!arg_info_has_key(supported_args, arg.first)) { - throw std::invalid_argument(name() + ": Unsupported tune argument " + - arg.first + " for channel " + - std::to_string(channel)); - } - } - d_tune_args.push_back(tune_kwargs); - } - - /* Validate and apply other settings to each channel */ - for (const auto& channel : d_channels) { - arginfo_list_t supported_settings = - d_device->getSettingInfo(d_direction, channel); - - /* If single set of args, apply to all channels */ - const size_t arg_idx = other_settings.size() == 1 ? 0 : channel; - kwargs_t settings_kwargs = SoapySDR::KwargsFromString(other_settings[arg_idx]); - - /* - * Before applying the setting, make a last check if the setting - * is a valid gain - */ - std::vector<std::string> gain_names = d_device->listGains(d_direction, channel); - for (const auto& gain_name : gain_names) { - SoapySDR::Kwargs::iterator iter = settings_kwargs.find(gain_name); - if (iter != settings_kwargs.end()) { - d_device->setGain( - d_direction, channel, gain_name, std::stod(iter->second)); - /* - * As only valid settings are applied, we remove it so it does not - * recognized as an invalid setting - */ - settings_kwargs.erase(iter); - } - } - - for (const auto& arg : settings_kwargs) { - if (!arg_info_has_key(supported_settings, arg.first)) { - throw std::invalid_argument(name() + ": Unsupported setting " + - arg.first + " for channel " + - std::to_string(channel)); - } - d_device->writeSetting(d_direction, channel, arg.first, arg.second); - } - } - - // message_port_register_in(pmtf::string("cmd")); - // set_msg_handler(pmtf::string("cmd"), - // [this](pmtf::pmt pmt) { this->msg_handler_cmd(pmt); }); - // register_msg_cmd_handler(CMD_FREQ_KEY, [this](pmtf::pmt val, size_t channel) { - // this->cmd_handler_frequency(val, channel); - // }); - // register_msg_cmd_handler(CMD_GAIN_KEY, [this](pmtf::pmt val, size_t channel) { - // this->cmd_handler_gain(val, channel); - // }); - - // register_msg_cmd_handler(CMD_RATE_KEY, [this](pmtf::pmt val, size_t channel) { - // this->cmd_handler_samp_rate(val, channel); - // }); - // register_msg_cmd_handler(CMD_BW_KEY, [this](pmtf::pmt val, size_t channel) { - // this->cmd_handler_bw(val, channel); - // }); - // register_msg_cmd_handler(CMD_ANTENNA_KEY, [this](pmtf::pmt val, size_t channel) { - // this->cmd_handler_antenna(val, channel); - // }); - // register_msg_cmd_handler(CMD_GAINMODE_KEY, [this](pmtf::pmt val, size_t channel) { - // this->cmd_handler_gain_mode(val, channel); - // }); - // register_msg_cmd_handler(CMD_FREQCORR_KEY, [this](pmtf::pmt val, size_t channel) { - // this->cmd_handler_frequency_correction(val, channel); - // }); - // register_msg_cmd_handler(CMD_FREQCORR_KEY, [this](pmtf::pmt val, size_t channel) { - // this->cmd_handler_frequency_correction(val, channel); - // }); - // register_msg_cmd_handler(CMD_DCOFFSETMODE_KEY, - // [this](pmtf::pmt val, size_t channel) { - // this->cmd_handler_dc_offset_mode(val, channel); - // }); - // register_msg_cmd_handler(CMD_DCOFFSET_KEY, [this](pmtf::pmt val, size_t channel) { - // this->cmd_handler_dc_offset(val, channel); - // }); - // register_msg_cmd_handler(CMD_IQBAL_KEY, [this](pmtf::pmt val, size_t channel) { - // this->cmd_handler_iq_balance(val, channel); - // }); - // register_msg_cmd_handler(CMD_IQBALMODE_KEY, [this](pmtf::pmt val, size_t channel) - // { - // this->cmd_handler_iq_balance_mode(val, channel); - // }); - // register_msg_cmd_handler(CMD_MCR_KEY, [this](pmtf::pmt val, size_t channel) { - // this->cmd_handler_master_clock_rate(val, channel); - // }); - // register_msg_cmd_handler(CMD_REFCLOCKRATE_KEY, - // [this](pmtf::pmt val, size_t channel) { - // this->cmd_handler_reference_clock_rate(val, channel); - // }); - // register_msg_cmd_handler(CMD_CLOCKSRC_KEY, [this](pmtf::pmt val, size_t channel) { - // this->cmd_handler_clock_source(val, channel); - // }); - // register_msg_cmd_handler(CMD_TIMESRC_KEY, [this](pmtf::pmt val, size_t channel) { - // this->cmd_handler_time_source(val, channel); - // }); - // register_msg_cmd_handler(CMD_HWTIME_KEY, [this](pmtf::pmt val, size_t channel) { - // this->cmd_handler_hardware_time(val, channel); - // }); - // register_msg_cmd_handler(CMD_REG_KEY, [this](pmtf::pmt val, size_t channel) { - // this->cmd_handler_register(val, channel); - // }); - // register_msg_cmd_handler(CMD_REGS_KEY, [this](pmtf::pmt val, size_t channel) { - // this->cmd_handler_registers(val, channel); - // }); - // register_msg_cmd_handler(CMD_SETTING_KEY, [this](pmtf::pmt val, size_t channel) { - // this->cmd_handler_setting(val, channel); - // }); - // register_msg_cmd_handler(CMD_GPIO_KEY, [this](pmtf::pmt val, size_t channel) { - // this->cmd_handler_gpio(val, channel); - // }); - // register_msg_cmd_handler(CMD_GPIODIR_KEY, [this](pmtf::pmt val, size_t channel) { - // this->cmd_handler_gpio_dir(val, channel); - // }); - // register_msg_cmd_handler(CMD_I2C_KEY, [this](pmtf::pmt val, size_t channel) { - // this->cmd_handler_i2c(val, channel); - // }); - // register_msg_cmd_handler(CMD_UART_KEY, [this](pmtf::pmt val, size_t channel) { - // this->cmd_handler_uart(val, channel); - // }); -} - -bool block_impl::start() -{ - std::lock_guard<std::mutex> l(d_device_mutex); - - d_stream = d_device->setupStream( - d_direction, d_soapy_type, d_channels, SoapySDR::KwargsFromString(d_stream_args)); - d_mtu = d_device->getStreamMTU(d_stream); - - // /* This limits each work invocation to MTU transfers */ - // if (d_mtu > 0) { - // set_max_noutput_items(d_mtu); - // } else { - // set_max_noutput_items(1024); - // } - - d_device->activateStream(d_stream); - - return true; -} - -bool block_impl::stop() -{ - if (d_stream) { - std::lock_guard<std::mutex> l(d_device_mutex); - d_device->closeStream(d_stream); - d_stream = nullptr; - } - - return true; -} - -block_impl::~block_impl() {} - -void block_impl::register_msg_cmd_handler(const pmtf::pmt& cmd, cmd_handler_t handler) -{ - // d_cmd_handlers[cmd] = handler; -} - -void block_impl::validate_channel(size_t channel) const -{ - if (channel >= d_nchan) { - throw std::invalid_argument(name() + ": Channel " + std::to_string(channel) + - " is not activated."); - } -} - -std::string block_impl::get_driver_key() const { return d_device->getDriverKey(); } - -std::string block_impl::get_hardware_key() const { return d_device->getHardwareKey(); } - -kwargs_t block_impl::get_hardware_info() const { return d_device->getHardwareInfo(); } - -void block_impl::set_frontend_mapping(const std::string& mapping) -{ - d_device->setFrontendMapping(d_direction, mapping); -} - -std::string block_impl::get_frontend_mapping() const -{ - return d_device->getFrontendMapping(d_direction); -} - -kwargs_t block_impl::get_channel_info(size_t channel) const -{ - validate_channel(channel); - return d_device->getChannelInfo(d_direction, channel); -} - -void block_impl::set_sample_rate(size_t channel, double sample_rate) -{ - validate_channel(channel); - - range_list_t sps_range = d_device->getSampleRateRange(d_direction, channel); - - if (!value_in_ranges(sps_range, sample_rate)) { - std::string msg = name() + ": Unsupported sample rate (" + - std::to_string(sample_rate) + "). Rate must be in the range "; - msg += ranges_to_string(sps_range); - - throw std::invalid_argument(msg); - } - - d_device->setSampleRate(d_direction, channel, sample_rate); -} - -double block_impl::get_sample_rate(size_t channel) const -{ - validate_channel(channel); - return d_device->getSampleRate(d_direction, channel); -} - -range_list_t block_impl::get_sample_rate_range(size_t channel) const -{ - validate_channel(channel); - return d_device->getSampleRateRange(d_direction, channel); -} - -void block_impl::set_frequency(size_t channel, double frequency) -{ - validate_channel(channel); - d_device->setFrequency(d_direction, channel, frequency, d_tune_args[channel]); -} - -void block_impl::set_frequency(size_t channel, const std::string& name, double frequency) -{ - validate_channel(channel); - std::vector<std::string> freqs = d_device->listFrequencies(d_direction, channel); - - // Set frequency for specified element, silently ignoring a non-existant - // element if frequency is zero. - if (vector_contains(freqs, name)) { - d_device->setFrequency(d_direction, channel, name, frequency); - } - else if (std::fpclassify(std::abs(frequency)) != FP_ZERO) { - throw std::invalid_argument( - this->name() + ": Channel " + std::to_string(channel) + - " does not support frequency " + name + - ". Consider setting this frequency to 0 to bypass this error"); - } -} - -double block_impl::get_frequency(size_t channel) const -{ - validate_channel(channel); - return d_device->getFrequency(d_direction, channel); -} - -double block_impl::get_frequency(size_t channel, const std::string& name) const -{ - validate_channel(channel); - return d_device->getFrequency(d_direction, channel, name); -} - -std::vector<std::string> block_impl::list_frequencies(size_t channel) const -{ - validate_channel(channel); - return d_device->listFrequencies(d_direction, channel); -} - -range_list_t block_impl::get_frequency_range(size_t channel) const -{ - validate_channel(channel); - return d_device->getFrequencyRange(d_direction, channel); -} - -range_list_t block_impl::get_frequency_range(size_t channel, - const std::string& name) const -{ - validate_channel(channel); - return d_device->getFrequencyRange(d_direction, channel, name); -} - -arginfo_list_t block_impl::get_frequency_args_info(size_t channel) const -{ - validate_channel(channel); - return d_device->getFrequencyArgsInfo(d_direction, channel); -} - -void block_impl::set_bandwidth(size_t channel, double bandwidth) -{ - validate_channel(channel); - d_device->setBandwidth(d_direction, channel, bandwidth); -} - -double block_impl::get_bandwidth(size_t channel) const -{ - validate_channel(channel); - return d_device->getBandwidth(d_direction, channel); -} - -range_list_t block_impl::get_bandwidth_range(size_t channel) const -{ - validate_channel(channel); - return d_device->getBandwidthRange(d_direction, channel); -} - -std::vector<std::string> block_impl::list_antennas(int channel) const -{ - validate_channel(channel); - return d_device->listAntennas(d_direction, channel); -} - -void block_impl::set_antenna(const size_t channel, const std::string& name) -{ - validate_channel(channel); - std::vector<std::string> antennas = d_device->listAntennas(d_direction, channel); - - // Ignore call if there are no antennas. - if (antennas.empty()) { - return; - } - - if (!vector_contains(antennas, name)) { - std::string msg = this->name() + ": Antenna " + name + " at channel " + - std::to_string(channel) + " is not supported. " + - "Available antennas are: "; - msg += string_vector_to_string(antennas); - - throw std::invalid_argument(msg); - } - - d_device->setAntenna(d_direction, channel, name); -} - -std::string block_impl::get_antenna(size_t channel) const -{ - validate_channel(channel); - return d_device->getAntenna(d_direction, channel); -} - -bool block_impl::has_gain_mode(size_t channel) const -{ - validate_channel(channel); - return d_device->hasGainMode(d_direction, channel); -} - -void block_impl::set_gain_mode(size_t channel, bool enable) -{ - validate_channel(channel); - // TODO: ignoring error if disabling AGC ... is this a good idea? - if (!has_gain_mode(channel) && enable) { - throw std::invalid_argument(name() + ": Channel " + std::to_string(channel) + - " does not support AGC"); - } - d_device->setGainMode(d_direction, channel, enable); -} - -bool block_impl::get_gain_mode(size_t channel) const -{ - validate_channel(channel); - return d_device->getGainMode(d_direction, channel); -} - -std::vector<std::string> block_impl::list_gains(size_t channel) const -{ - validate_channel(channel); - return d_device->listGains(d_direction, channel); -} - -void block_impl::set_gain(size_t channel, double gain) -{ - validate_channel(channel); - range_t rGain = d_device->getGainRange(d_direction, channel); - - if (!value_in_range(rGain, gain)) { - d_debug_logger->error( - "Gain out of range: {} <= gain <= {}", rGain.minimum(), rGain.maximum()); - return; - } - - d_device->setGain(d_direction, channel, gain); -} - -void block_impl::set_gain(size_t channel, const std::string& name, double gain) -{ - validate_channel(channel); - - /* Validate gain name */ - std::vector<std::string> gains = d_device->listGains(d_direction, channel); - if (!vector_contains(gains, name)) { - throw std::invalid_argument(this->name() + ": Unknown gain " + name + - " for channel " + std::to_string(channel)); - } - - /* Validate gain value */ - range_t rGain = d_device->getGainRange(d_direction, channel, name); - if (!value_in_range(rGain, gain)) { - d_debug_logger->error("Gain {} out of range: {} <= gain <= {}", - name, - rGain.minimum(), - rGain.maximum()); - } - - d_device->setGain(d_direction, channel, name, gain); -} - -double block_impl::get_gain(size_t channel) const -{ - validate_channel(channel); - return d_device->getGain(d_direction, channel); -} - -double block_impl::get_gain(size_t channel, const std::string& name) const -{ - validate_channel(channel); - return d_device->getGain(d_direction, channel, name); -} - -range_t block_impl::get_gain_range(size_t channel) const -{ - validate_channel(channel); - return d_device->getGainRange(d_direction, channel); -} - -range_t block_impl::get_gain_range(size_t channel, const std::string& name) const -{ - validate_channel(channel); - return d_device->getGainRange(d_direction, channel, name); -} - -bool block_impl::has_frequency_correction(size_t channel) const -{ - validate_channel(channel); - return d_device->hasFrequencyCorrection(d_direction, channel); -} - -void block_impl::set_frequency_correction(size_t channel, double freq_correction) -{ - validate_channel(channel); - - // Set frequency correction, ignoring missing functionality if correction - // is zero. - if (has_frequency_correction(channel)) { - d_device->setFrequencyCorrection(d_direction, channel, freq_correction); - } - else if (std::fpclassify(std::abs(freq_correction)) != FP_ZERO) { - throw std::invalid_argument(this->name() + ": Channel " + - std::to_string(channel) + - " does not support frequency correction setting"); - } -} - -double block_impl::get_frequency_correction(size_t channel) const -{ - validate_channel(channel); - return d_device->getFrequencyCorrection(d_direction, channel); -} - -bool block_impl::has_dc_offset_mode(size_t channel) const -{ - validate_channel(channel); - return d_device->hasDCOffsetMode(d_direction, channel); -} - -void block_impl::set_dc_offset_mode(size_t channel, bool automatic) -{ - validate_channel(channel); - - // TODO: ignoring error if disabling automatic ... is this a good idea? - if (!has_dc_offset_mode(channel) && automatic) { - throw std::invalid_argument(this->name() + ": Channel " + - std::to_string(channel) + - " does not support automatic DC removal setting"); - } - d_device->setDCOffsetMode(d_direction, channel, automatic); -} - -bool block_impl::get_dc_offset_mode(size_t channel) const -{ - validate_channel(channel); - return d_device->getDCOffsetMode(d_direction, channel); -} - -bool block_impl::has_dc_offset(size_t channel) const -{ - validate_channel(channel); - return d_device->hasDCOffset(d_direction, channel); -} - -void block_impl::set_dc_offset(size_t channel, const gr_complexd& dc_offset) -{ - validate_channel(channel); - - const bool supported = has_dc_offset(channel); - /* - * In case of 0 DC offset, the method exits to avoid failing in case of the - * device does not supports DC offset - */ - if (std::fpclassify(std::norm(dc_offset)) == FP_ZERO) { - if (supported && !d_device->getDCOffsetMode(d_direction, channel)) { - d_device->setDCOffset(d_direction, channel, dc_offset); - } - return; - } - - if (!supported) { - throw std::invalid_argument(this->name() + ": Channel " + - std::to_string(channel) + - " does not support DC offset setting"); - } - d_device->setDCOffset(d_direction, channel, dc_offset); -} - -gr_complexd block_impl::get_dc_offset(size_t channel) const -{ - validate_channel(channel); - return d_device->getDCOffset(d_direction, channel); -} - -bool block_impl::has_iq_balance(size_t channel) const -{ - validate_channel(channel); - return d_device->hasIQBalance(d_direction, channel); -} - -void block_impl::set_iq_balance(size_t channel, const gr_complexd& iq_balance) -{ - validate_channel(channel); - - const bool supported = has_iq_balance(channel); - /* - * In case of 0 frequency correction, the method exits to avoid failing - * in case of the device does not supports DC offset - */ - if (std::fpclassify(std::norm(iq_balance)) == FP_ZERO) { - if (supported) { - d_device->setIQBalance(d_direction, channel, iq_balance); - } - return; - } - - if (!supported) { - throw std::invalid_argument(this->name() + ": Channel " + - std::to_string(channel) + - " does not support IQ imbalance correction setting"); - } - d_device->setIQBalance(d_direction, channel, iq_balance); -} - -gr_complexd block_impl::get_iq_balance(size_t channel) const -{ - validate_channel(channel); - return d_device->getIQBalance(d_direction, channel); -} - -bool block_impl::has_iq_balance_mode(size_t channel) const -{ - validate_channel(channel); - -#ifdef SOAPY_SDR_API_HAS_IQ_BALANCE_MODE - return d_device->hasIQBalanceMode(d_direction, channel); -#else - (void)channel; - throw std::runtime_error( - "Automatic IQ imbalance correction API not implemented in this version"); -#endif -} - -void block_impl::set_iq_balance_mode(size_t channel, bool automatic) -{ - validate_channel(channel); - -#ifdef SOAPY_SDR_API_HAS_IQ_BALANCE_MODE - if (!has_iq_balance_mode(channel)) { - throw std::invalid_argument( - this->name() + ": Channel " + std::to_string(channel) + - " does not support automatic IQ imbalance correction"); - } - d_device->setIQBalanceMode(d_direction, channel, automatic); -#else - (void)channel; - (void)automatic; - throw std::runtime_error( - "Automatic IQ imbalance correction API not implemented in this version"); -#endif -} - -bool block_impl::get_iq_balance_mode(size_t channel) const -{ - validate_channel(channel); - -#ifdef SOAPY_SDR_API_HAS_IQ_BALANCE_MODE - if (!has_iq_balance_mode(channel)) { - throw std::invalid_argument( - this->name() + ": Channel " + std::to_string(channel) + - " does not support automatic IQ imbalance correction"); - } - return d_device->getIQBalanceMode(d_direction, channel); -#else - (void)channel; - throw std::runtime_error( - "Automatic IQ imbalance correction API not implemented in this version"); -#endif -} - -void block_impl::set_master_clock_rate(double clock_rate) -{ - const auto clock_rates = d_device->getMasterClockRates(); - - if (!value_in_ranges(clock_rates, clock_rate)) { - std::string msg = "Unsupported clock rate ("; - msg += std::to_string(clock_rate); - msg += "). Clock rate must be in the range "; - msg += ranges_to_string(clock_rates); - - throw std::invalid_argument(msg); - } - d_device->setMasterClockRate(clock_rate); -} - -double block_impl::get_master_clock_rate() const -{ - return d_device->getMasterClockRate(); -} - -range_list_t block_impl::get_master_clock_rates() const -{ - return d_device->getMasterClockRates(); -} - -void block_impl::set_reference_clock_rate(double clock_rate) -{ -#ifdef SOAPY_SDR_API_HAS_REF_CLOCK_RATE_API - const auto clock_rates = d_device->getReferenceClockRates(); - - if (!value_in_ranges(clock_rates, clock_rate)) { - std::string msg = "Unsupported clock rate ("; - msg += std::to_string(clock_rate); - msg += "). Clock rate must be in the range "; - msg += ranges_to_string(clock_rates); - - throw std::invalid_argument(msg); - } - d_device->setReferenceClockRate(clock_rate); -#else - (void)clock_rate; - throw std::runtime_error("Reference clock API not implemented in this version"); -#endif -} - -double block_impl::get_reference_clock_rate() const -{ -#ifdef SOAPY_SDR_API_HAS_REF_CLOCK_RATE_API - return d_device->getReferenceClockRate(); -#else - throw std::runtime_error("Reference clock API not implemented in this version"); -#endif -} - -range_list_t block_impl::get_reference_clock_rates() const -{ -#ifdef SOAPY_SDR_API_HAS_REF_CLOCK_RATE_API - return d_device->getReferenceClockRates(); -#else - throw std::runtime_error("Reference clock API not implemented in this version"); -#endif -} - -std::vector<std::string> block_impl::list_time_sources() const -{ - return d_device->listTimeSources(); -} - -void block_impl::set_time_source(const std::string& time_source) -{ - const auto time_sources = d_device->listTimeSources(); - - if (!vector_contains(time_sources, time_source)) { - std::string msg = "Invalid time source (" + time_source + ")."; - msg += "Valid time sources: "; - msg += string_vector_to_string(time_sources); - - throw std::invalid_argument(msg); - } - - d_device->setTimeSource(time_source); -} - -std::string block_impl::get_time_source() const { return d_device->getTimeSource(); } - -std::vector<std::string> block_impl::list_clock_sources() const -{ - return d_device->listClockSources(); -} - -void block_impl::set_clock_source(const std::string& clock_source) -{ - const auto clock_sources = d_device->listClockSources(); - - if (!vector_contains(clock_sources, clock_source)) { - std::string msg = "Invalid clock source (" + clock_source + ")."; - msg += "Valid clock sources: "; - msg += string_vector_to_string(clock_sources); - - throw std::invalid_argument(msg); - } - - d_device->setClockSource(clock_source); -} - -std::string block_impl::get_clock_source() const { return d_device->getClockSource(); } - -bool block_impl::has_hardware_time(const std::string& what) const -{ - return d_device->hasHardwareTime(what); -} - -long long block_impl::get_hardware_time(const std::string& what) const -{ - if (!has_hardware_time(what)) { - std::string msg = - this->name() + ": device does not support querying hardware time"; - if (!what.empty()) { - msg += " ("; - msg += what; - msg += ")"; - } - - throw std::invalid_argument(msg); - } - return d_device->getHardwareTime(what); -} - -void block_impl::set_hardware_time(long long timeNs, const std::string& what) -{ - if (!has_hardware_time(what)) { - std::string msg = - this->name() + ": device does not support querying hardware time"; - if (!what.empty()) { - msg += " (" + what + ")"; - } - - throw std::invalid_argument(msg); - } - d_device->setHardwareTime(timeNs, what); -} - -std::vector<std::string> block_impl::list_sensors() const -{ - return d_device->listSensors(); -} - -arginfo_t block_impl::get_sensor_info(const std::string& key) const -{ - const auto sensors = d_device->listSensors(); - - if (vector_contains(sensors, key)) { - return d_device->getSensorInfo(key); - } - else { - throw std::invalid_argument("Invalid sensor: " + key); - } -} - -std::string block_impl::read_sensor(const std::string& key) const -{ - const auto sensors = d_device->listSensors(); - - if (vector_contains(sensors, key)) { - return d_device->readSensor(key); - } - else { - throw std::invalid_argument("Invalid sensor: " + key); - } -} - -std::vector<std::string> block_impl::list_sensors(size_t channel) const -{ - validate_channel(channel); - return d_device->listSensors(d_direction, channel); -} - -arginfo_t block_impl::get_sensor_info(size_t channel, const std::string& key) const -{ - validate_channel(channel); - const auto sensors = d_device->listSensors(d_direction, channel); - - if (vector_contains(sensors, key)) { - return d_device->getSensorInfo(d_direction, channel, key); - } - else { - throw std::invalid_argument("Invalid sensor: " + key); - } -} - -std::string block_impl::read_sensor(size_t channel, const std::string& key) const -{ - validate_channel(channel); - const auto sensors = d_device->listSensors(d_direction, channel); - - if (vector_contains(sensors, key)) { - return d_device->readSensor(d_direction, channel, key); - } - else { - throw std::invalid_argument("Invalid sensor: " + key); - } -} - -std::vector<std::string> block_impl::list_register_interfaces() const -{ - return d_device->listRegisterInterfaces(); -} - -void block_impl::write_register(const std::string& name, unsigned addr, unsigned value) -{ - const auto register_interfaces = list_register_interfaces(); - if (!vector_contains(register_interfaces, name)) { - throw std::invalid_argument(this->name() + ": invalid register interface (" + - name + ")"); - } - d_device->writeRegister(name, addr, value); -} - -unsigned block_impl::read_register(const std::string& name, unsigned addr) const -{ - const auto register_interfaces = list_register_interfaces(); - if (!vector_contains(register_interfaces, name)) { - throw std::invalid_argument(this->name() + ": invalid register interface (" + - name + ")"); - } - return d_device->readRegister(name, addr); -} - -void block_impl::write_registers(const std::string& name, - unsigned addr, - const std::vector<unsigned>& value) -{ - const auto register_interfaces = list_register_interfaces(); - if (!vector_contains(register_interfaces, name)) { - throw std::invalid_argument(this->name() + ": invalid register interface (" + - name + ")"); - } - d_device->writeRegisters(name, addr, value); -} - -std::vector<unsigned> -block_impl::read_registers(const std::string& name, unsigned addr, size_t length) const -{ - const auto register_interfaces = list_register_interfaces(); - if (!vector_contains(register_interfaces, name)) { - throw std::invalid_argument(this->name() + ": invalid register interface (" + - name + ")"); - } - return d_device->readRegisters(name, addr, length); -} - -arginfo_list_t block_impl::get_setting_info() const { return d_device->getSettingInfo(); } - -void block_impl::write_setting(const std::string& key, const std::string& value) -{ - const auto setting_info = d_device->getSettingInfo(); - - if (arg_info_has_key(setting_info, key)) { - d_device->writeSetting(key, value); - } - else { - throw std::invalid_argument("Invalid setting: " + key); - } -} - -std::string block_impl::read_setting(const std::string& key) const -{ - const auto setting_info = d_device->getSettingInfo(); - - if (arg_info_has_key(setting_info, key)) { - return d_device->readSetting(key); - } - else { - throw std::invalid_argument("Invalid setting: " + key); - } -} - -arginfo_list_t block_impl::get_setting_info(size_t channel) const -{ - validate_channel(channel); - return d_device->getSettingInfo(d_direction, channel); -} - -void block_impl::write_setting(size_t channel, - const std::string& key, - const std::string& value) -{ - validate_channel(channel); - const auto setting_info = d_device->getSettingInfo(d_direction, channel); - - if (arg_info_has_key(setting_info, key)) { - d_device->writeSetting(d_direction, channel, key, value); - } - else { - throw std::invalid_argument("Invalid setting: " + key); - } -} - -std::string block_impl::read_setting(size_t channel, const std::string& key) const -{ - validate_channel(channel); - const auto setting_info = d_device->getSettingInfo(d_direction, channel); - - if (arg_info_has_key(setting_info, key)) { - return d_device->readSetting(d_direction, channel, key); - } - else { - throw std::invalid_argument("Invalid setting: " + key); - } -} - -std::vector<std::string> block_impl::list_gpio_banks() const -{ - return d_device->listGPIOBanks(); -} - -void block_impl::write_gpio(const std::string& bank, unsigned value) -{ - const auto gpio_banks = list_gpio_banks(); - if (!vector_contains(gpio_banks, bank)) { - throw std::invalid_argument(this->name() + ": invalid GPIO bank (" + bank + ")"); - } - d_device->writeGPIO(bank, value); -} - -void block_impl::write_gpio(const std::string& bank, unsigned value, unsigned mask) -{ - const auto gpio_banks = list_gpio_banks(); - if (!vector_contains(gpio_banks, bank)) { - throw std::invalid_argument(this->name() + ": invalid GPIO bank (" + bank + ")"); - } - d_device->writeGPIO(bank, value, mask); -} - -unsigned block_impl::read_gpio(const std::string& bank) const -{ - const auto gpio_banks = list_gpio_banks(); - - if (!vector_contains(gpio_banks, bank)) { - throw std::invalid_argument(this->name() + ": invalid GPIO bank (" + bank + ")"); - } - return d_device->readGPIO(bank); -} - -void block_impl::write_gpio_dir(const std::string& bank, unsigned dir) -{ - const auto gpio_banks = list_gpio_banks(); - if (!vector_contains(gpio_banks, bank)) { - throw std::invalid_argument(this->name() + ": invalid GPIO bank (" + bank + ")"); - } - d_device->writeGPIODir(bank, dir); -} - -void block_impl::write_gpio_dir(const std::string& bank, unsigned dir, unsigned mask) -{ - const auto gpio_banks = list_gpio_banks(); - if (!vector_contains(gpio_banks, bank)) { - throw std::invalid_argument(this->name() + ": invalid GPIO bank (" + bank + ")"); - } - d_device->writeGPIODir(bank, dir, mask); -} - -unsigned block_impl::read_gpio_dir(const std::string& bank) const -{ - const auto gpio_banks = list_gpio_banks(); - - if (!vector_contains(gpio_banks, bank)) { - throw std::invalid_argument(this->name() + ": invalid GPIO bank (" + bank + ")"); - } - return d_device->readGPIODir(bank); -} - -void block_impl::write_i2c(int addr, const std::string& data) -{ - d_device->writeI2C(addr, data); -} - -std::string block_impl::read_i2c(int addr, size_t num_bytes) -{ - return d_device->readI2C(addr, num_bytes); -} - -unsigned block_impl::transact_spi(int addr, unsigned data, size_t num_bits) -{ - return d_device->transactSPI(addr, data, num_bits); -} - -std::vector<std::string> block_impl::list_uarts() const { return d_device->listUARTs(); } - -void block_impl::write_uart(const std::string& which, const std::string& data) -{ - const auto uarts = list_uarts(); - - if (!vector_contains(uarts, which)) { - std::string msg = "Invalid UART (" + which + ")."; - msg += "Valid UARTs: "; - msg += string_vector_to_string(uarts); - - throw std::invalid_argument(msg); - } - d_device->writeUART(which, data); -} - -std::string block_impl::read_uart(const std::string& which, long timeout_us) const -{ - const auto uarts = list_uarts(); - - if (!vector_contains(uarts, which)) { - std::string msg = "Invalid UART (" + which + ")."; - msg += "Valid UARTs: "; - msg += string_vector_to_string(uarts); - - throw std::invalid_argument(msg); - } - return d_device->readUART(which, timeout_us); -} - -/* End public API implementation */ - -// void block_impl::cmd_handler_frequency(pmtf::pmt val, size_t channel) -// { -// if (!(val->is_number() && !val->is_complex())) { -// GR_LOG_ERROR(d_debug_logger, "soapy: freq must be float/int"); -// return; -// } -// set_frequency(channel, pmtf::scalar<double>(val)); -// } - -// void block_impl::cmd_handler_gain(pmtf::pmt val, size_t channel) -// { -// // For compatibility, accept either a numeric value for setting the -// // overall gain or a dict with a gain element and element-specific -// // value. -// if (!(val->is_number() && !val->is_complex()) && !val->is_dict()) { -// GR_LOG_ERROR(d_debug_logger, "soapy: gain must be float/int or a dict"); -// return; -// } - -// if (val->is_dict()) { -// if (!pmt::dict_has_key(val, CMD_GAIN_KEY)) { -// GR_LOG_ERROR(d_debug_logger, "soapy: gain dict must contain key \"gain\""); -// return; -// } - -// // Accept no name, falls back to default argument "" -// const auto name = -// pmt::symbol_to_string(pmt::dict_ref(val, CMD_NAME_KEY, PMT_EMPTYSTR)); -// const auto gain = pmtf::scalar<double>(pmt::dict_ref(val, CMD_GAIN_KEY, -// PMT_ZERO)); - -// set_gain(channel, name, gain); -// } else { -// set_gain(channel, pmtf::scalar<double>(val)); -// } -// } - -// void block_impl::cmd_handler_samp_rate(pmtf::pmt val, size_t channel) -// { -// if (!(val->is_number() && !val->is_complex())) { -// GR_LOG_ERROR(d_debug_logger, "soapy: rate must be float/int"); -// return; -// } -// set_sample_rate(channel, pmtf::scalar<double>(val)); -// } - -// void block_impl::cmd_handler_bw(pmtf::pmt val, size_t channel) -// { -// if (!(val->is_number() && !val->is_complex())) { -// GR_LOG_ERROR(d_debug_logger, "soapy: bw must be float/int"); -// return; -// } -// set_bandwidth(channel, pmtf::scalar<double>(val)); -// } - -// void block_impl::cmd_handler_antenna(pmtf::pmt val, size_t channel) -// { -// if (!val->is_symbol()) { -// GR_LOG_ERROR(d_debug_logger, "soapy: ant must be string"); -// return; -// } -// set_antenna(channel, pmt::symbol_to_string(val)); -// } - -// void block_impl::cmd_handler_gain_mode(pmtf::pmt val, size_t channel) -// { -// if (!val->is_bool()) { -// GR_LOG_ERROR(d_debug_logger, "soapy: gain mode must be bool"); -// return; -// } -// set_gain_mode(channel, pmt::to_bool(val)); -// } - -// void block_impl::cmd_handler_frequency_correction(pmtf::pmt val, size_t channel) -// { -// if (!(val->is_number() && !val->is_complex())) { -// GR_LOG_ERROR(d_debug_logger, "soapy: frequency correction must be float/int"); -// return; -// } -// set_frequency_correction(channel, pmtf::scalar<double>(val)); -// } - -// void block_impl::cmd_handler_dc_offset_mode(pmtf::pmt val, size_t channel) -// { -// if (!val->is_bool()) { -// GR_LOG_ERROR(d_debug_logger, "soapy: DC offset mode must be bool"); -// return; -// } -// set_dc_offset_mode(channel, pmt::to_bool(val)); -// } - -// void block_impl::cmd_handler_dc_offset(pmtf::pmt val, size_t channel) -// { -// if (!val->is_number()) { -// GR_LOG_ERROR(d_debug_logger, "soapy: DC offset must be numeric"); -// return; -// } -// set_dc_offset(channel, pmt::to_complex(val)); -// } - -// void block_impl::cmd_handler_iq_balance(pmtf::pmt val, size_t channel) -// { -// if (!val->is_number()) { -// GR_LOG_ERROR(d_debug_logger, "soapy: IQ balance must be numeric"); -// return; -// } -// set_iq_balance(channel, pmt::to_complex(val)); -// } - -// void block_impl::cmd_handler_iq_balance_mode(pmtf::pmt val, size_t channel) -// { -// if (!val->is_bool()) { -// GR_LOG_ERROR(d_debug_logger, "soapy: IQ balance mode must be bool"); -// return; -// } -// set_iq_balance_mode(channel, pmt::to_bool(val)); -// } - -// void block_impl::cmd_handler_master_clock_rate(pmtf::pmt val, size_t) -// { -// if (!(val->is_number() && !val->is_complex())) { -// GR_LOG_ERROR(d_debug_logger, "soapy: master clock rate must be float/int"); -// return; -// } -// set_master_clock_rate(pmtf::scalar<double>(val)); -// } - -// void block_impl::cmd_handler_reference_clock_rate(pmtf::pmt val, size_t) -// { -// if (!(val->is_number() && !val->is_complex())) { -// GR_LOG_ERROR(d_debug_logger, "soapy: reference clock rate must be float/int"); -// return; -// } -// set_reference_clock_rate(pmtf::scalar<double>(val)); -// } - -// void block_impl::cmd_handler_clock_source(pmtf::pmt val, size_t) -// { -// if (!val->is_symbol()) { -// GR_LOG_ERROR(d_debug_logger, "soapy: clock source must be string"); -// return; -// } -// set_clock_source(pmt::symbol_to_string(val)); -// } - -// void block_impl::cmd_handler_time_source(pmtf::pmt val, size_t) -// { -// if (!val->is_symbol()) { -// GR_LOG_ERROR(d_debug_logger, "soapy: time source must be string"); -// return; -// } -// set_time_source(pmt::symbol_to_string(val)); -// } - -// void block_impl::cmd_handler_hardware_time(pmtf::pmt val, size_t) -// { -// if (!val->is_dict()) { -// GR_LOG_ERROR(d_debug_logger, "soapy: hardware time must be a dict"); -// return; -// } - -// if (!pmt::dict_has_key(val, CMD_TIME_KEY)) { -// GR_LOG_ERROR(d_debug_logger, -// "soapy: hardware time dict must contain key \"time\""); -// return; -// } - -// // Accept no name, falls back to default argument "" -// const auto name = -// pmt::symbol_to_string(pmt::dict_ref(val, CMD_NAME_KEY, PMT_EMPTYSTR)); -// const auto time = pmt::to_long(pmt::dict_ref(val, CMD_TIME_KEY, PMT_ZERO)); - -// set_hardware_time(static_cast<long long>(time), name); -// } - -// void block_impl::cmd_handler_register(pmtf::pmt val, size_t) -// { -// if (!val->is_dict()) { -// GR_LOG_ERROR(d_debug_logger, "soapy: register write param must be a dict"); -// return; -// } - -// if (!pmt::dict_has_key(val, CMD_NAME_KEY) || !pmt::dict_has_key(val, CMD_ADDR_KEY) -// || -// !pmt::dict_has_key(val, CMD_VALUE_KEY)) { -// GR_LOG_ERROR( -// d_debug_logger, -// "soapy: register write dict must contain keys \"name\", \"addr\", -// \"value\""); -// return; -// } - -// const auto name = -// pmt::symbol_to_string(pmt::dict_ref(val, CMD_NAME_KEY, PMT_EMPTYSTR)); -// const auto addr = pmt::to_uint64(pmt::dict_ref(val, CMD_ADDR_KEY, PMT_ZERO)); -// const auto value = pmt::to_uint64(pmt::dict_ref(val, CMD_VALUE_KEY, PMT_ZERO)); - -// write_register(name, static_cast<unsigned>(addr), static_cast<unsigned>(value)); -// } - -// void block_impl::cmd_handler_registers(pmtf::pmt val, size_t) -// { -// if (!val->is_dict()) { -// GR_LOG_ERROR(d_debug_logger, "soapy: multi-register write param must be a -// dict"); return; -// } - -// if (!pmt::dict_has_key(val, CMD_NAME_KEY) || !pmt::dict_has_key(val, CMD_ADDR_KEY) -// || -// !pmt::dict_has_key(val, CMD_VALUE_KEY)) { -// GR_LOG_ERROR(d_debug_logger, -// "soapy: multi-register write dict must contain keys \"name\", " -// "\"addr\", \"value\""); -// return; -// } - -// const auto name = -// pmt::symbol_to_string(pmt::dict_ref(val, CMD_NAME_KEY, PMT_EMPTYSTR)); -// const auto addr = pmt::to_uint64(pmt::dict_ref(val, CMD_ADDR_KEY, PMT_ZERO)); -// const auto value = pmt::u32vector_elements( -// pmt::dict_ref(val, CMD_VALUE_KEY, pmt::make_u32vector(0, 0))); - -// write_registers(name, static_cast<unsigned>(addr), value); -// } - -// // TODO: any way to call channel-less version? -// void block_impl::cmd_handler_setting(pmtf::pmt val, size_t channel) -// { -// if (!val->is_dict()) { -// GR_LOG_ERROR(d_debug_logger, "soapy: GPIO must be a dict"); -// return; -// } - -// if (!pmt::dict_has_key(val, CMD_KEY_KEY) || !pmt::dict_has_key(val, CMD_VALUE_KEY)) -// { -// GR_LOG_ERROR(d_debug_logger, "soapy: GPIO must contain keys \"key\", -// \"value\""); return; -// } - -// const auto key = pmt::symbol_to_string(pmt::dict_ref(val, CMD_KEY_KEY, -// PMT_EMPTYSTR)); const auto value_pmt = pmt::dict_ref(val, CMD_VALUE_KEY, -// PMT_EMPTYSTR); - -// std::string value; -// if (pmt::is_bool(val)) { -// write_setting(channel, key, setting_to_string(pmt::to_bool(value_pmt))); -// } else if (pmt::is_number(val)) { -// write_setting(channel, key, -// setting_to_string(pmtf::scalar<double>(value_pmt))); -// } else { -// write_setting(channel, key, pmt::symbol_to_string(value_pmt)); -// } -// } - -// void block_impl::cmd_handler_gpio(pmtf::pmt val, size_t) -// { -// if (!val->is_dict()) { -// GR_LOG_ERROR(d_debug_logger, "soapy: setting must be a dict"); -// return; -// } - -// if (!pmt::dict_has_key(val, CMD_BANK_KEY) || !pmt::dict_has_key(val, -// CMD_VALUE_KEY)) { -// GR_LOG_ERROR(d_debug_logger, "soapy: GPIO must contain keys \"bank\", -// \"value\""); return; -// } - -// const auto bank = -// pmt::symbol_to_string(pmt::dict_ref(val, CMD_BANK_KEY, PMT_EMPTYSTR)); -// const auto value = pmt::to_uint64(pmt::dict_ref(val, CMD_VALUE_KEY, PMT_ZERO)); - -// if (pmt::dict_has_key(val, CMD_MASK_KEY)) { -// const auto mask = pmt::to_uint64(pmt::dict_ref(val, CMD_MASK_KEY, PMT_ZERO)); - -// write_gpio(bank, static_cast<unsigned>(value), static_cast<unsigned>(mask)); -// } else { -// write_gpio(bank, static_cast<unsigned>(value)); -// } -// } - -// void block_impl::cmd_handler_gpio_dir(pmtf::pmt val, size_t) -// { -// static const pmtf::pmt CMD_DIR_KEY = pmtf::string("dir"); - -// if (!val->is_dict()) { -// GR_LOG_ERROR(d_debug_logger, "soapy: GPIO dir must be a dict"); -// return; -// } - -// if (!pmt::dict_has_key(val, CMD_BANK_KEY) || !pmt::dict_has_key(val, CMD_DIR_KEY)) -// { -// GR_LOG_ERROR(d_debug_logger, -// "soapy: GPIO dir must contain keys \"bank\", \"dir\""); -// return; -// } - -// const auto bank = -// pmt::symbol_to_string(pmt::dict_ref(val, CMD_BANK_KEY, PMT_EMPTYSTR)); -// const auto dir = pmt::to_uint64(pmt::dict_ref(val, CMD_DIR_KEY, PMT_ZERO)); - -// if (pmt::dict_has_key(val, CMD_MASK_KEY)) { -// const auto mask = pmt::to_uint64(pmt::dict_ref(val, CMD_MASK_KEY, PMT_ZERO)); - -// write_gpio_dir(bank, static_cast<unsigned>(dir), static_cast<unsigned>(mask)); -// } else { -// write_gpio_dir(bank, static_cast<unsigned>(dir)); -// } -// } - -// void block_impl::cmd_handler_i2c(pmtf::pmt val, size_t) -// { -// if (!val->is_dict()) { -// GR_LOG_ERROR(d_debug_logger, "soapy: I2C must be a dict"); -// return; -// } - -// if (!pmt::dict_has_key(val, CMD_ADDR_KEY) || !pmt::dict_has_key(val, CMD_DATA_KEY)) -// { -// GR_LOG_ERROR(d_debug_logger, "soapy: I2C must contain keys \"addr\", -// \"data\""); return; -// } - -// const auto addr = pmt::to_long(pmt::dict_ref(val, CMD_ADDR_KEY, PMT_ZERO)); -// const auto data = -// pmt::symbol_to_string(pmt::dict_ref(val, CMD_DATA_KEY, PMT_EMPTYSTR)); - -// write_i2c(static_cast<int>(addr), data); -// } - -// void block_impl::cmd_handler_uart(pmtf::pmt val, size_t) -// { -// if (!val->is_dict()) { -// GR_LOG_ERROR(d_debug_logger, "soapy: UART must be a dict"); -// return; -// } - -// if (!pmt::dict_has_key(val, CMD_NAME_KEY) || !pmt::dict_has_key(val, CMD_DATA_KEY)) -// { -// GR_LOG_ERROR(d_debug_logger, "soapy: UART must contain keys \"name\", -// \"data\""); return; -// } - -// const auto name = -// pmt::symbol_to_string(pmt::dict_ref(val, CMD_NAME_KEY, PMT_EMPTYSTR)); -// const auto data = -// pmt::symbol_to_string(pmt::dict_ref(val, CMD_DATA_KEY, PMT_EMPTYSTR)); - -// write_uart(name, data); -// } - -// void block_impl::msg_handler_cmd(pmtf::pmt msg) -// { -// const long CHANNEL_ALL = 0x12345678; // arbitrary - -// if (!pmt::is_dict(msg)) { -// GR_LOG_ERROR(d_debug_logger, "soapy: commands must be pmt::dict"); -// return; -// } - -// // Channel not specified means apply to all -// const pmtf::pmt channel_all_pmt = pmt::from_long(CHANNEL_ALL); -// size_t channel = pmt::to_long(pmt::dict_ref(msg, CMD_CHAN_KEY, channel_all_pmt)); - -// if (channel != CHANNEL_ALL && channel >= d_nchan) { -// GR_LOG_ERROR(d_debug_logger, -// "soapy: ignoring command for invalid channel {}", -// channel); -// return; -// } - -// for (size_t i = 0; i < pmt::length(msg); i++) { -// const pmtf::pmt item = pmt::nth(i, msg); -// const pmtf::pmt key = pmt::car(item); -// const pmtf::pmt val = pmt::cdr(item); -// if (key == CMD_CHAN_KEY) { -// continue; -// } - -// // Find command handler -// auto it = d_cmd_handlers.find(key); -// if (it == d_cmd_handlers.end()) { -// GR_LOG_ERROR(d_debug_logger, -// "soapy: ignoring unknown command key '{}'", -// pmt::symbol_to_string(key)); -// continue; -// } -// cmd_handler_t handler = it->second; - -// if (channel != CHANNEL_ALL) { -// std::lock_guard<std::mutex> l(d_device_mutex); -// handler(val, channel); -// } else { -// for (size_t c = 0; c < d_nchan; c++) { -// std::lock_guard<std::mutex> l(d_device_mutex); -// handler(val, c); -// } -// } -// } -// } -} /* namespace soapy */ -} /* namespace gr */ diff --git a/blocklib/soapy/lib/block_impl.h b/blocklib/soapy/lib/block_impl.h deleted file mode 100644 index 8ccd878ad..000000000 --- a/blocklib/soapy/lib/block_impl.h +++ /dev/null @@ -1,294 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2021 Jeff Long - * Copyright 2018-2021 Libre Space Foundation <http://libre.space> - * - * SPDX-License-Identifier: GPL-3.0-or-later - */ - -#pragma once - -#include <mutex> - -#include <gnuradio/soapy/block.h> - -#include <SoapySDR/Device.hpp> -#include <SoapySDR/Modules.hpp> -#include <SoapySDR/Registry.hpp> -#include <SoapySDR/Version.hpp> - -namespace gr { -namespace soapy { - -using cmd_handler_t = std::function<void(pmtf::pmt, size_t)>; -struct device_deleter { - void operator()(SoapySDR::Device* d) { SoapySDR::Device::unmake(d); } -}; -using device_ptr_t = std::unique_ptr<SoapySDR::Device, device_deleter>; - -/*! - * \brief Base block implementation for SDR devices. - */ - -class block_impl : virtual public block -{ -private: - const int d_direction; - const std::string d_dev_str; - const std::string d_args; - - size_t d_nchan; - std::string d_stream_args; - std::vector<size_t> d_channels; - std::string d_soapy_type; - std::map<pmtf::pmt, cmd_handler_t> d_cmd_handlers; - kwargs_list_t d_tune_args; - - void register_msg_cmd_handler(const pmtf::pmt& cmd, cmd_handler_t handler); - - /*! - * \brief Raise std::invalid_argument if channel is invalid - */ - void validate_channel(size_t channel) const; - -protected: - size_t d_mtu = 0; - - block_impl(int direction, - const std::string& device, - const std::string& type, - size_t nchan, - const std::string& dev_args, - const std::string& stream_args, - const std::vector<std::string>& tune_args, - const std::vector<std::string>& other_settings); - block_impl(const block_impl&) = delete; - block_impl(block_impl&&) = delete; - block_impl& operator=(const block_impl&) = delete; - block_impl& operator=(block_impl&&) = delete; - ~block_impl() override; - - std::mutex d_device_mutex; - device_ptr_t d_device; - SoapySDR::Stream* d_stream = nullptr; - - // static io_signature::sptr args_to_io_sig(const std::string& type, size_t nchan) - // { - // size_t size = 0; - // if (type == "fc32") { - // size = 8; - // } else if (type == "sc16") { - // size = 4; - // } else if (type == "sc8") { - // size = 2; - // } else { - // size = 1; /* TODO: this is an error */ - // } - // return io_signature::make(nchan, nchan, size); - // } - -public: - bool start() override; - bool stop() override; - - /*** Begin public API implementation ***/ - - std::string get_driver_key() const override; - std::string get_hardware_key() const override; - kwargs_t get_hardware_info() const override; - - void set_frontend_mapping(const std::string& frontend_mapping) override; - std::string get_frontend_mapping() const override; - - kwargs_t get_channel_info(size_t channel) const override; - - void set_sample_rate(size_t channel, double sample_rate) override; - double get_sample_rate(size_t channel) const override; - range_list_t get_sample_rate_range(size_t channel) const override; - - void set_frequency(size_t channel, double frequency) override; - void - set_frequency(size_t channel, const std::string& name, double frequency) override; - double get_frequency(size_t channel) const override; - double get_frequency(size_t channel, const std::string& name) const override; - std::vector<std::string> list_frequencies(size_t channel) const override; - range_list_t get_frequency_range(size_t channel) const override; - range_list_t get_frequency_range(size_t channel, - const std::string& name) const override; - arginfo_list_t get_frequency_args_info(size_t channel) const override; - - void set_bandwidth(size_t channel, double bandwidth) override; - double get_bandwidth(size_t channel) const override; - range_list_t get_bandwidth_range(size_t channel) const override; - - std::vector<std::string> list_antennas(int channel) const override; - void set_antenna(size_t channel, const std::string& name) override; - std::string get_antenna(size_t channel) const override; - - bool has_gain_mode(size_t channel) const override; - void set_gain_mode(size_t channel, bool enable) override; - bool get_gain_mode(size_t channel) const override; - - std::vector<std::string> list_gains(size_t channel) const override; - void set_gain(size_t channel, double gain) override; - void set_gain(size_t channel, const std::string& name, double gain) override; - double get_gain(size_t channel) const override; - double get_gain(size_t channel, const std::string& name) const override; - range_t get_gain_range(size_t channel) const override; - range_t get_gain_range(size_t channel, const std::string& name) const override; - - bool has_frequency_correction(size_t channel) const override; - void set_frequency_correction(size_t channel, double freq_correction) override; - double get_frequency_correction(size_t channel) const override; - - bool has_dc_offset_mode(size_t channel) const override; - void set_dc_offset_mode(size_t channel, bool automatic) override; - bool get_dc_offset_mode(size_t channel) const override; - - bool has_dc_offset(size_t channel) const override; - void set_dc_offset(size_t channel, const gr_complexd& dc_offset) override; - gr_complexd get_dc_offset(size_t channel) const override; - - bool has_iq_balance(size_t channel) const override; - void set_iq_balance(size_t channel, const gr_complexd& iq_balance) override; - gr_complexd get_iq_balance(size_t channel) const override; - - bool has_iq_balance_mode(size_t channel) const override; - void set_iq_balance_mode(size_t channel, bool automatic) override; - bool get_iq_balance_mode(size_t channel) const override; - - void set_master_clock_rate(double clock_rate) override; - double get_master_clock_rate() const override; - range_list_t get_master_clock_rates() const override; - - void set_reference_clock_rate(double rate) override; - double get_reference_clock_rate() const override; - range_list_t get_reference_clock_rates() const override; - - std::vector<std::string> list_clock_sources() const override; - void set_clock_source(const std::string& clock_source) override; - std::string get_clock_source() const override; - - std::vector<std::string> list_time_sources() const override; - void set_time_source(const std::string& source) override; - std::string get_time_source() const override; - bool has_hardware_time(const std::string& what) const override; - long long get_hardware_time(const std::string& what) const override; - void set_hardware_time(long long timeNs, const std::string& what) override; - - std::vector<std::string> list_sensors() const override; - arginfo_t get_sensor_info(const std::string& key) const override; - std::string read_sensor(const std::string& key) const override; - std::vector<std::string> list_sensors(size_t channel) const override; - arginfo_t get_sensor_info(size_t channel, const std::string& key) const override; - std::string read_sensor(size_t channel, const std::string& key) const override; - - std::vector<std::string> list_register_interfaces() const override; - void write_register(const std::string& name, unsigned addr, unsigned value) override; - unsigned read_register(const std::string& name, unsigned addr) const override; - void write_registers(const std::string& name, - unsigned addr, - const std::vector<unsigned>& value) override; - std::vector<unsigned> - read_registers(const std::string& name, unsigned addr, size_t length) const override; - - arginfo_list_t get_setting_info() const override; - void write_setting(const std::string& key, const std::string& value) override; - std::string read_setting(const std::string& key) const override; - arginfo_list_t get_setting_info(size_t channel) const override; - void write_setting(size_t channel, - const std::string& key, - const std::string& value) override; - std::string read_setting(size_t channel, const std::string& key) const override; - - std::vector<std::string> list_gpio_banks() const override; - void write_gpio(const std::string& bank, unsigned value) override; - void write_gpio(const std::string& bank, unsigned value, unsigned mask) override; - unsigned read_gpio(const std::string& bank) const override; - void write_gpio_dir(const std::string& bank, unsigned dir) override; - void write_gpio_dir(const std::string& bank, unsigned dir, unsigned mask) override; - unsigned read_gpio_dir(const std::string& bank) const override; - - void write_i2c(int addr, const std::string& data) override; - std::string read_i2c(int addr, size_t num_bytes) override; - - unsigned transact_spi(int addr, unsigned data, size_t num_bits) override; - - std::vector<std::string> list_uarts() const override; - void write_uart(const std::string& which, const std::string& data) override; - std::string read_uart(const std::string& which, long timeout_us) const override; - - /*** End public API implementation ***/ - -protected: - /*** Begin message handlers ***/ - - // /*! - // * Calls the correct message handler according to the received message symbol. - // * A dictionary with key the handler name is used in order to call the - // * corresponding handler. - // * \param msg a PMT dictionary - // */ - // void msg_handler_cmd(pmtf::pmt msg); - - // /*! - // * Set the center frequency of the RX chain. - // * @param val center frequency in Hz - // * @param channel an available channel on the device - // */ - // void cmd_handler_frequency(pmtf::pmt val, size_t channel); - - // /*! - // * Set the overall gain for the specified chain. - // * The gain will be distributed automatically across available - // * elements according to Soapy API. - // * @param val the new amplification value in dB - // * @param channel an avalaible channel on the device - // */ - // void cmd_handler_gain(pmtf::pmt val, size_t channel); - - // /*! - // * Set the baseband sample rate for the RX chain. - // * @param val the sample rate samples per second - // * @param channel an available channel on the device - // */ - // void cmd_handler_samp_rate(pmtf::pmt val, size_t channel); - - // /*! - // * Set the baseband filter width for the RX chain. - // * @param val baseband filter width in Hz - // * @param channel an available channel on the device - // */ - // void cmd_handler_bw(pmtf::pmt val, size_t channel); - - // /*! - // * Set the anntena element for the RX chain. - // * @param val name of the anntena - // * @param channel an available channel on the device - // */ - // void cmd_handler_antenna(pmtf::pmt val, size_t channel); - - // void cmd_handler_gain_mode(pmtf::pmt val, size_t channel); - // void cmd_handler_frequency_correction(pmtf::pmt val, size_t channel); - // void cmd_handler_dc_offset_mode(pmtf::pmt val, size_t channel); - // void cmd_handler_dc_offset(pmtf::pmt val, size_t channel); - // void cmd_handler_iq_balance(pmtf::pmt val, size_t channel); - // void cmd_handler_iq_balance_mode(pmtf::pmt val, size_t channel); - // void cmd_handler_master_clock_rate(pmtf::pmt val, size_t); - // void cmd_handler_reference_clock_rate(pmtf::pmt val, size_t); - // void cmd_handler_clock_source(pmtf::pmt val, size_t); - // void cmd_handler_time_source(pmtf::pmt val, size_t); - // void cmd_handler_hardware_time(pmtf::pmt val, size_t); - // void cmd_handler_register(pmtf::pmt val, size_t); - // void cmd_handler_registers(pmtf::pmt val, size_t); - // void cmd_handler_setting(pmtf::pmt val, size_t channel); - // void cmd_handler_gpio(pmtf::pmt val, size_t); - // void cmd_handler_gpio_dir(pmtf::pmt val, size_t); - // void cmd_handler_i2c(pmtf::pmt val, size_t); - // void cmd_handler_uart(pmtf::pmt val, size_t); - - /*** End message handlers ***/ -}; - -} // namespace soapy -} // namespace gr diff --git a/blocklib/soapy/lib/meson.build b/blocklib/soapy/lib/meson.build deleted file mode 100644 index 1888e6cb0..000000000 --- a/blocklib/soapy/lib/meson.build +++ /dev/null @@ -1,40 +0,0 @@ -soapy_sources += ['block_impl.cc'] - -soapysdr_dep = dependency('SoapySDR', version : '>=0.7', required : true) - -soapy_deps += [gnuradio_gr_dep, soapysdr_dep, volk_dep, fmt_dep, pmtf_dep] - -block_cpp_args = ['-DHAVE_CPU'] - -incdir = include_directories(['../include/gnuradio/soapy','../include']) -gnuradio_blocklib_soapy_lib = library('gnuradio-blocklib-soapy', - soapy_sources, - include_directories : incdir, - install : true, - link_language: 'cpp', - dependencies : soapy_deps, - cpp_args : block_cpp_args) - -gnuradio_blocklib_soapy_dep = declare_dependency(include_directories : incdir, - link_with : gnuradio_blocklib_soapy_lib, - dependencies : soapy_deps) - -cmake_conf = configuration_data() -cmake_conf.set('libdir', join_paths(prefix,get_option('libdir'))) -cmake_conf.set('module', 'soapy') -cmake.configure_package_config_file( - name : 'gnuradio-soapy', - 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_soapy_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-soapy', - filebase : 'gnuradio-soapy', - description : 'GNU Radio Soapy Module') diff --git a/blocklib/soapy/lib/setting_string_conversion.h b/blocklib/soapy/lib/setting_string_conversion.h deleted file mode 100644 index 8b000aa11..000000000 --- a/blocklib/soapy/lib/setting_string_conversion.h +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright 2021 Nicholas Corgan - * SPDX-License-Identifier: GPL-3.0-or-later - */ - -#pragma once - -#include <SoapySDR/Types.hpp> -#include <SoapySDR/Version.h> - -#include <sstream> - -namespace gr { -namespace soapy { - -// SoapySDR doesn't have an API define for SettingToString, so we need -// to check the version. 0.8 is the first tagged version to have this -// functionality. -#if SOAPY_SDR_API_VERSION >= 0x080000 - -template <typename T> -static inline T string_to_setting(const std::string& str) -{ - return SoapySDR::StringToSetting<T>(str); -} - -template <typename T> -static inline std::string setting_to_string(const T& setting) -{ - return SoapySDR::SettingToString<T>(setting); -} - -#else - -// Copied from SoapySDR 0.8 -#define SOAPY_SDR_TRUE "true" -#define SOAPY_SDR_FALSE "false" - -template <typename T> -static inline T string_to_setting(const std::string& str) -{ - std::stringstream sstream(str); - T setting; - - sstream >> setting; - - return setting; -} - -// Copied from SoapySDR 0.8 -//! convert empty and "false" strings to false, integers to their truthness -template <> -inline bool string_to_setting<bool>(const std::string& str) -{ - if (str.empty() || str == SOAPY_SDR_FALSE) { - return false; - } - if (str == SOAPY_SDR_TRUE) { - return true; - } - try { - return static_cast<bool>(std::stod(str)); - } catch (std::invalid_argument& e) { - } - // other values are true - return true; -} - -template <typename T> -static inline std::string setting_to_string(const T& setting) -{ - return std::to_string(setting); -} - -template <> -inline std::string setting_to_string<bool>(const bool& setting) -{ - return setting ? SOAPY_SDR_TRUE : SOAPY_SDR_FALSE; -} - -#endif - -} // namespace soapy -} // namespace gr diff --git a/blocklib/soapy/limesdr_source/limesdr_source.yml b/blocklib/soapy/limesdr_source/limesdr_source.yml deleted file mode 100644 index 3e96a4089..000000000 --- a/blocklib/soapy/limesdr_source/limesdr_source.yml +++ /dev/null @@ -1,92 +0,0 @@ -module: soapy -block: limesdr_source -label: LimeSDR Source -blocktype: grc -category: '[Core]/Soapy' - -typekeys: - - id: T - type: class - options: - - cf32 - # - rf32 - -grc: - flags: [python] - templates: - imports: from gnuradio import soapy - make: | - dev = 'driver=lime' - stream_args = '' - tune_args = [''] - settings = [''] - - self.${id} = soapy.source_${T.fcn}(dev, 1, ${dev_args}, - stream_args, tune_args, settings) - self.${id}.set_sample_rate(0, ${samp_rate}) - self.${id}.set_bandwidth(0, ${bandwidth}) - self.${id}.set_frequency(0, ${center_freq}) - self.${id}.set_frequency_correction(0, ${freq_correction}) - self.${id}.set_gain(0, min(max(${gain}, -12.0), 61.0)) - callbacks: - - set_sample_rate(0, ${samp_rate}) - - set_bandwidth(0, ${bandwidth}) - - set_frequency(0, ${center_freq}) - - set_frequency_correction(0, ${freq_correction}) - - set_gain(0, min(max(${gain}, -12.0), 61.0)) - - -parameters: - - id: dev_args - label: Device arguments - dtype: string - grc: - hide: ${'part' if not dev_args else 'none'} - - - id: samp_rate - label: Sample Rate - dtype: rf32 - grc: - default: 'samp_rate' - - - id: bandwidth - label: Bandwidth - dtype: rf32 - grc: - category: RF Options - default: '0.0' - hide: part - - - id: center_freq - label: 'Center Freq (Hz)' - dtype: rf32 - grc: - category: RF Options - default: 'freq' - - - id: freq_correction - label: 'Frequency Correction (PPM)' - dtype: rf32 - grc: - category: RF Options - default: '0' - hide: 'part' - - - id: gain - label: 'RF Gain (-12dB - 61dB)' - dtype: rf32 - grc: - category: RF Options - default: '20.0' - hide: 'part' - -ports: - - domain: stream - id: out - direction: output - type: typekeys/T - -implementations: -- id: cpu - -file_format: 1 diff --git a/blocklib/soapy/python/gnuradio/soapy/__init__.py b/blocklib/soapy/python/gnuradio/soapy/__init__.py deleted file mode 100644 index b155fe72b..000000000 --- a/blocklib/soapy/python/gnuradio/soapy/__init__.py +++ /dev/null @@ -1,9 +0,0 @@ - -import os - -try: - from .soapy_python import * -except ImportError: - dirname, filename = os.path.split(os.path.abspath(__file__)) - __path__.append(os.path.join(dirname, "bindings")) - from .soapy_python import * diff --git a/blocklib/soapy/python/gnuradio/soapy/bindings/block_pybind.cc b/blocklib/soapy/python/gnuradio/soapy/bindings/block_pybind.cc deleted file mode 100644 index da6b1c82e..000000000 --- a/blocklib/soapy/python/gnuradio/soapy/bindings/block_pybind.cc +++ /dev/null @@ -1,657 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2020-2021 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(block.h) */ -/* BINDTOOL_HEADER_FILE_HASH(6326cce2f22e30ab332ef966343f4a50) */ -/***********************************************************************************/ - -#include "soapy_common.h" - -#include <pybind11/complex.h> -#include <pybind11/pybind11.h> -#include <pybind11/stl.h> - -namespace py = pybind11; - -#include <gnuradio/soapy/block.h> -// pydoc.h is automatically generated in the build directory -// #include <block_pydoc.h> - -#include <algorithm> -#include <cassert> - -#define __EXPAND(x) x -#define __COUNT(_1, _2, _3, _4, _5, _6, _7, COUNT, ...) COUNT -#define __VA_SIZE(...) __EXPAND(__COUNT(__VA_ARGS__, 7, 6, 5, 4, 3, 2, 1)) -#define __CAT1(a, b) a##b -#define __CAT2(a, b) __CAT1(a, b) -#define __DOC1(n1) "" -#define __DOC2(n1, n2) "" -#define __DOC3(n1, n2, n3) "" -#define __DOC4(n1, n2, n3, n4) "" -#define __DOC5(n1, n2, n3, n4, n5) "" -#define __DOC6(n1, n2, n3, n4, n5, n6) "" -#define __DOC7(n1, n2, n3, n4, n5, n6, n7) "" -#define DOC(...) __EXPAND(__EXPAND(__CAT2(__DOC, __VA_SIZE(__VA_ARGS__)))(__VA_ARGS__)) -#define D(...) DOC(gr, soapy, __VA_ARGS__) - -// Assumption: we've validated that this key exists, -// probably through get_setting_info. -static gr::soapy::arginfo_t -get_specific_arginfo(const gr::soapy::arginfo_list_t& arginfo_list, - const std::string& key) -{ - auto iter = std::find_if( - arginfo_list.begin(), - arginfo_list.end(), - [&key](const gr::soapy::arginfo_t& arginfo) { return (arginfo.key == key); }); - assert(iter != arginfo_list.end()); - - return (*iter); -} - -void bind_block(py::module& m) -{ - - using block = ::gr::soapy::block; - - - py::class_<block, gr::block, gr::node, std::shared_ptr<block>>(m, "block", D(block)) - - - .def("set_frontend_mapping", - &block::set_frontend_mapping, - py::arg("frontend_mapping"), - D(block, set_frontend_mapping)) - - - .def("get_frontend_mapping", - &block::get_frontend_mapping, - D(block, get_frontend_mapping)) - - - .def("get_channel_info", - &block::get_channel_info, - py::arg("channel"), - D(block, get_channel_info)) - - - .def("set_sample_rate", - &block::set_sample_rate, - py::arg("channel"), - py::arg("sample_rate"), - D(block, set_sample_rate)) - - - .def("get_sample_rate", - &block::get_sample_rate, - py::arg("channel"), - D(block, get_sample_rate)) - - - .def("get_sample_rate_range", - &block::get_sample_rate_range, - py::arg("channel"), - D(block, get_sample_rate_range)) - - - .def("set_frequency", - (void(block::*)(size_t, double)) & block::set_frequency, - py::arg("channel"), - py::arg("freq"), - D(block, set_frequency, 0)) - - - .def("set_frequency", - (void(block::*)(size_t, const std::string&, double)) & block::set_frequency, - py::arg("channel"), - py::arg("name"), - py::arg("freq"), - D(block, set_frequency, 1)) - - - .def("get_frequency", - (double(block::*)(size_t) const) & block::get_frequency, - py::arg("channel"), - D(block, get_frequency, 0)) - - - .def("get_frequency", - (double(block::*)(size_t, const std::string&) const) & block::get_frequency, - py::arg("channel"), - py::arg("name"), - D(block, get_frequency, 1)) - - - .def("list_frequencies", - &block::list_frequencies, - py::arg("channel"), - D(block, list_frequencies)) - - - .def("get_frequency_range", - (gr::soapy::range_list_t(block::*)(size_t) const) & - block::get_frequency_range, - py::arg("channel"), - D(block, get_frequency_range, 0)) - - - .def("get_frequency_range", - (gr::soapy::range_list_t(block::*)(size_t, const std::string&) const) & - block::get_frequency_range, - py::arg("channel"), - py::arg("name"), - D(block, get_frequency_range, 1)) - - - .def("get_frequency_args_info", - &block::get_frequency_args_info, - py::arg("channel"), - D(block, get_frequency_args_info)) - - - .def("set_bandwidth", - &block::set_bandwidth, - py::arg("channel"), - py::arg("bandwidth"), - D(block, set_bandwidth)) - - - .def("get_bandwidth", - &block::get_bandwidth, - py::arg("channel"), - D(block, get_bandwidth)) - - - .def("get_bandwidth_range", - &block::get_bandwidth_range, - py::arg("channel"), - D(block, get_bandwidth_range)) - - - .def("list_antennas", - &block::list_antennas, - py::arg("channel"), - D(block, list_antennas)) - - - .def("set_antenna", - &block::set_antenna, - py::arg("channel"), - py::arg("name"), - D(block, set_antenna)) - - - .def( - "get_antenna", &block::get_antenna, py::arg("channel"), D(block, get_antenna)) - - - .def("has_gain_mode", - &block::has_gain_mode, - py::arg("channel"), - D(block, has_gain_mode)) - - - .def("set_gain_mode", - &block::set_gain_mode, - py::arg("channel"), - py::arg("automatic"), - D(block, set_gain_mode)) - - - .def("get_gain_mode", - &block::get_gain_mode, - py::arg("channel"), - D(block, get_gain_mode)) - - - .def("list_gains", &block::list_gains, py::arg("channel"), D(block, list_gains)) - - - .def("set_gain", - (void(block::*)(size_t, double)) & block::set_gain, - py::arg("channel"), - py::arg("gain"), - D(block, set_gain, 0)) - - - .def("set_gain", - (void(block::*)(size_t, const std::string&, double)) & block::set_gain, - py::arg("channel"), - py::arg("name"), - py::arg("gain"), - D(block, set_gain, 1)) - - - .def("get_gain", - (double(block::*)(size_t) const) & block::get_gain, - py::arg("channel"), - D(block, get_gain, 0)) - - - .def("get_gain", - (double(block::*)(size_t, const std::string&) const) & block::get_gain, - py::arg("channel"), - py::arg("name"), - D(block, get_gain, 1)) - - - .def("get_gain_range", - (gr::soapy::range_t(block::*)(size_t) const) & block::get_gain_range, - py::arg("channel"), - D(block, get_gain_range, 0)) - - - .def("get_gain_range", - (gr::soapy::range_t(block::*)(size_t, const std::string&) const) & - block::get_gain_range, - py::arg("channel"), - py::arg("name"), - D(block, get_gain_range, 1)) - - - .def("has_frequency_correction", - &block::has_frequency_correction, - py::arg("channel"), - D(block, has_frequency_correction)) - - - .def("set_frequency_correction", - &block::set_frequency_correction, - py::arg("channel"), - py::arg("freq_correction"), - D(block, set_frequency_correction)) - - - .def("get_frequency_correction", - &block::get_frequency_correction, - py::arg("channel"), - D(block, get_frequency_correction)) - - - .def("has_dc_offset_mode", - &block::has_dc_offset_mode, - py::arg("channel"), - D(block, has_dc_offset_mode)) - - - .def("set_dc_offset_mode", - &block::set_dc_offset_mode, - py::arg("channel"), - py::arg("automatic"), - D(block, set_dc_offset_mode)) - - - .def("get_dc_offset_mode", - &block::get_dc_offset_mode, - py::arg("channel"), - D(block, get_dc_offset_mode)) - - - .def("has_dc_offset", - &block::has_dc_offset, - py::arg("channel"), - D(block, has_dc_offset)) - - - .def("set_dc_offset", - &block::set_dc_offset, - py::arg("channel"), - py::arg("dc_offset"), - D(block, set_dc_offset)) - - - .def("get_dc_offset", - &block::get_dc_offset, - py::arg("channel"), - D(block, get_dc_offset)) - - - .def("has_iq_balance", - &block::has_iq_balance, - py::arg("channel"), - D(block, has_iq_balance)) - - - .def("set_iq_balance", - &block::set_iq_balance, - py::arg("channel"), - py::arg("iq_balance"), - D(block, set_iq_balance)) - - - .def("get_iq_balance", - &block::get_iq_balance, - py::arg("channel"), - D(block, get_iq_balance)) - - - .def("has_iq_balance_mode", - &block::has_iq_balance_mode, - py::arg("channel"), - D(block, has_iq_balance_mode)) - - - .def("set_iq_balance_mode", - &block::set_iq_balance_mode, - py::arg("channel"), - py::arg("automatic"), - D(block, set_iq_balance_mode)) - - - .def("get_iq_balance_mode", - &block::get_iq_balance_mode, - py::arg("channel"), - D(block, get_iq_balance_mode)) - - - .def("set_master_clock_rate", - &block::set_master_clock_rate, - py::arg("clock_rate"), - D(block, set_master_clock_rate)) - - - .def("get_master_clock_rate", - &block::get_master_clock_rate, - D(block, get_master_clock_rate)) - - - .def("get_master_clock_rates", - &block::get_master_clock_rates, - D(block, get_master_clock_rate)) - - - .def("set_reference_clock_rate", - &block::set_reference_clock_rate, - py::arg("clock_rate"), - D(block, set_reference_clock_rate)) - - - .def("get_reference_clock_rate", - &block::get_reference_clock_rate, - D(block, get_reference_clock_rate)) - - - .def("get_reference_clock_rates", - &block::get_reference_clock_rates, - D(block, get_reference_clock_rate)) - - - .def("list_clock_sources", - &block::list_clock_sources, - D(block, list_clock_sources)) - - - .def("set_clock_source", - &block::set_clock_source, - py::arg("clock_source"), - D(block, set_clock_source)) - - - .def("get_clock_source", &block::get_clock_source, D(block, get_clock_source)) - - - .def("list_time_sources", &block::list_time_sources, D(block, list_time_sources)) - - - .def("set_time_source", - &block::set_time_source, - py::arg("time_source"), - D(block, set_time_source)) - - - .def("get_time_source", &block::get_time_source, D(block, get_time_source)) - - - .def("has_hardware_time", - &block::has_hardware_time, - py::arg("what") = "", - D(block, has_hardware_time)) - - - .def("set_hardware_time", - &block::set_hardware_time, - py::arg("what") = "", - py::arg("time_ns"), - D(block, set_hardware_time)) - - - .def("get_hardware_time", - &block::get_hardware_time, - py::arg("what") = "", - D(block, get_hardware_time)) - - - .def("list_sensors", - (std::vector<std::string>(block::*)() const) & block::list_sensors, - D(block, list_sensors, 0)) - - .def("get_sensor_info", - (gr::soapy::arginfo_t(block::*)(const std::string&) const) & - block::get_sensor_info, - py::arg("key"), - D(block, get_sensor_info, 0)) - - .def( - "read_sensor", - [](const block& self, const std::string& key) -> py::object { - const auto arginfo = self.get_sensor_info(key); - - return cast_string_to_arginfo_type(arginfo.type, arginfo.value); - }, - py::arg("key"), - D(block, read_sensor, 0)) - - .def("list_sensors", - (std::vector<std::string>(block::*)(size_t) const) & block::list_sensors, - py::arg("channel"), - D(block, list_sensors, 1)) - - .def("get_sensor_info", - (gr::soapy::arginfo_t(block::*)(size_t, const std::string&) const) & - block::get_sensor_info, - py::arg("channel"), - py::arg("key"), - D(block, get_sensor_info, 1)) - - .def( - "read_sensor", - [](const block& self, size_t channel, const std::string& key) -> py::object { - const auto arginfo = self.get_sensor_info(channel, key); - - return cast_string_to_arginfo_type(arginfo.type, arginfo.value); - }, - py::arg("channel"), - py::arg("key"), - D(block, read_sensor, 1)) - - - .def("list_register_interfaces", - &block::list_register_interfaces, - D(block, list_register_interfaces)) - - - .def("write_register", - &block::write_register, - py::arg("name"), - py::arg("addr"), - py::arg("value"), - D(block, write_register)) - - - .def("read_register", - &block::read_register, - py::arg("name"), - py::arg("addr"), - D(block, read_register)) - - - .def("write_registers", - &block::write_registers, - py::arg("name"), - py::arg("addr"), - py::arg("value"), - D(block, write_registers)) - - - .def("read_registers", - &block::read_registers, - py::arg("name"), - py::arg("addr"), - py::arg("length"), - D(block, read_registers)) - - .def("get_setting_info", - (gr::soapy::arginfo_list_t(block::*)() const) & block::get_setting_info, - D(block, get_setting_info, 0)) - - .def( - "write_setting", - [](block& self, const std::string& key, py::object value) -> void { - auto setting_info = cast_pyobject_to_arginfo_string(value); - - self.write_setting(key, setting_info.value); - }, - py::arg("key"), - py::arg("value"), - D(block, write_setting, 0)) - - .def( - "read_setting", - [](const block& self, const std::string& key) -> py::object { - const auto setting_info = - get_specific_arginfo(self.get_setting_info(), key); - - return cast_string_to_arginfo_type(setting_info.type, setting_info.value); - }, - py::arg("key"), - D(block, read_setting, 0)) - - .def("get_setting_info", - (gr::soapy::arginfo_list_t(block::*)(size_t) const) & - block::get_setting_info, - py::arg("channel"), - D(block, get_setting_info, 0)) - - .def( - "write_setting", - [](block& self, size_t channel, const std::string& key, py::object value) - -> void { - auto setting_info = cast_pyobject_to_arginfo_string(value); - - self.write_setting(channel, key, setting_info.value); - }, - py::arg("channel"), - py::arg("key"), - py::arg("value"), - D(block, write_setting, 0)) - - .def( - "read_setting", - [](const block& self, size_t channel, const std::string& key) -> py::object { - const auto setting_info = - get_specific_arginfo(self.get_setting_info(channel), key); - - return cast_string_to_arginfo_type(setting_info.type, setting_info.value); - }, - py::arg("channel"), - py::arg("key"), - D(block, read_setting, 0)) - - - .def("list_gpio_banks", &block::list_gpio_banks, D(block, list_gpio_banks)) - - - .def("write_gpio", - (void(block::*)(const std::string&, unsigned)) & block::write_gpio, - py::arg("bank"), - py::arg("value"), - D(block, write_gpio, 0)) - - - .def("write_gpio", - (void(block::*)(const std::string&, unsigned, unsigned)) & block::write_gpio, - py::arg("bank"), - py::arg("value"), - py::arg("mask"), - D(block, write_gpio, 1)) - - - .def("read_gpio", &block::read_gpio, py::arg("bank"), D(block, read_gpio)) - - - .def("write_gpio_dir", - (void(block::*)(const std::string&, unsigned)) & block::write_gpio_dir, - py::arg("bank"), - py::arg("value"), - D(block, write_gpio_dir, 0)) - - - .def("write_gpio_dir", - (void(block::*)(const std::string&, unsigned, unsigned)) & - block::write_gpio_dir, - py::arg("bank"), - py::arg("value"), - py::arg("mask"), - D(block, write_gpio_dir, 1)) - - - .def("read_gpio_dir", - &block::read_gpio_dir, - py::arg("bank"), - D(block, read_gpio_dir)) - - - .def("write_i2c", - &block::write_i2c, - py::arg("addr"), - py::arg("data"), - D(block, write_i2c)) - - - .def("read_i2c", - &block::read_i2c, - py::arg("addr"), - py::arg("length"), - D(block, read_i2c)) - - - .def("transact_spi", - &block::transact_spi, - py::arg("addr"), - py::arg("data"), - py::arg("num_bits"), - D(block, transact_spi)) - - - .def("list_uarts", &block::list_uarts, D(block, list_uarts)) - - - .def("write_uart", - &block::write_uart, - py::arg("which"), - py::arg("data"), - D(block, write_uart)) - - - .def("read_uart", - &block::read_uart, - py::arg("which"), - py::arg("timeout_us") = 100000, - D(block, read_uart)) - - ; -} diff --git a/blocklib/soapy/python/gnuradio/soapy/bindings/meson.build b/blocklib/soapy/python/gnuradio/soapy/bindings/meson.build deleted file mode 100644 index 9bd9af38b..000000000 --- a/blocklib/soapy/python/gnuradio/soapy/bindings/meson.build +++ /dev/null @@ -1,2 +0,0 @@ -soapy_pybind_sources = [files('soapy_types_pybind.cc', 'soapy_common.cc', 'block_pybind.cc')] + soapy_pybind_sources -soapy_pybind_names = ['soapy_types', 'block'] + soapy_pybind_names
\ No newline at end of file diff --git a/blocklib/soapy/python/gnuradio/soapy/bindings/soapy_common.cc b/blocklib/soapy/python/gnuradio/soapy/bindings/soapy_common.cc deleted file mode 100644 index 5f1fc70ab..000000000 --- a/blocklib/soapy/python/gnuradio/soapy/bindings/soapy_common.cc +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright 2021 Free Software Foundation, Inc. - * - * This file is part of GNU Radio - * - * SPDX-License-Identifier: GPL-3.0-or-later - * - */ - -#include "setting_string_conversion.h" -#include "soapy_common.h" - -#include <SoapySDR/Types.hpp> -#include <SoapySDR/Version.h> -#include <string> - -py::object cast_string_to_arginfo_type(gr::soapy::argtype_t argtype, - const std::string& str) -{ - py::object ret; - switch (argtype) { - case SoapySDR::ArgInfo::BOOL: - ret = py::bool_(gr::soapy::string_to_setting<bool>(str)); - break; - - case SoapySDR::ArgInfo::INT: - ret = py::int_(gr::soapy::string_to_setting<int>(str)); - break; - - case SoapySDR::ArgInfo::FLOAT: - ret = py::float_(gr::soapy::string_to_setting<double>(str)); - break; - - default: - ret = py::str(str); - break; - } - - return ret; -} - -setting_info cast_pyobject_to_arginfo_string(py::object obj) -{ - setting_info info; - - if (py::isinstance<py::bool_>(obj)) { - info.value = gr::soapy::setting_to_string(bool(py::cast<py::bool_>(obj))); - info.type = SoapySDR::ArgInfo::BOOL; - } - else if (py::isinstance<py::int_>(obj)) { - info.value = gr::soapy::setting_to_string(int(py::cast<py::int_>(obj))); - info.type = SoapySDR::ArgInfo::INT; - } - else if (py::isinstance<py::float_>(obj)) { - info.value = gr::soapy::setting_to_string(double(py::cast<py::float_>(obj))); - info.type = SoapySDR::ArgInfo::FLOAT; - } - else { - info.value = py::str(obj); - info.type = SoapySDR::ArgInfo::STRING; - } - - return info; -} diff --git a/blocklib/soapy/python/gnuradio/soapy/bindings/soapy_common.h b/blocklib/soapy/python/gnuradio/soapy/bindings/soapy_common.h deleted file mode 100644 index 90d5b9035..000000000 --- a/blocklib/soapy/python/gnuradio/soapy/bindings/soapy_common.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright 2021 Free Software Foundation, Inc. - * - * This file is part of GNU Radio - * - * SPDX-License-Identifier: GPL-3.0-or-later - * - */ - -#pragma once - -#include <pybind11/complex.h> -#include <pybind11/operators.h> -#include <pybind11/pybind11.h> -#include <pybind11/stl.h> - -namespace py = pybind11; - -#include <gnuradio/soapy/soapy_types.h> - -py::object cast_string_to_arginfo_type(gr::soapy::argtype_t argtype, - const std::string& str); - -struct setting_info { - std::string value; - gr::soapy::argtype_t type; -}; - -setting_info cast_pyobject_to_arginfo_string(py::object obj); diff --git a/blocklib/soapy/python/gnuradio/soapy/bindings/soapy_types_pybind.cc b/blocklib/soapy/python/gnuradio/soapy/bindings/soapy_types_pybind.cc deleted file mode 100644 index f91e03f61..000000000 --- a/blocklib/soapy/python/gnuradio/soapy/bindings/soapy_types_pybind.cc +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright 2021 Free Software Foundation, Inc. - * - * This file is part of GNU Radio - * - * SPDX-License-Identifier: GPL-3.0-or-later - * - */ - -#include "soapy_common.h" - -#include <pybind11/complex.h> -#include <pybind11/operators.h> -#include <pybind11/pybind11.h> -#include <pybind11/stl.h> - -namespace py = pybind11; - -#include <gnuradio/soapy/soapy_types.h> - -void bind_soapy_types(py::module& m) -{ - py::class_<gr::soapy::range_t>(m, "range_t") - // Constructors - .def(py::init<>()) - .def(py::init<double, double>()) - .def(py::init<double, double, double>()) - - // Methods - .def("minimum", &gr::soapy::range_t::minimum) - .def("maximum", &gr::soapy::range_t::maximum) - .def("step", &gr::soapy::range_t::step) - - .def("__str__", [](const gr::soapy::range_t& range) -> std::string { - std::string ret = "(minimum: "; - ret += std::to_string(range.minimum()); - ret += ", maximum: "; - ret += std::to_string(range.maximum()); - ret += ", step: "; - ret += std::to_string(range.step()); - ret += ")"; - - return ret; - }); - - py::enum_<gr::soapy::argtype_t>(m, "argtype_t") - .value("BOOL", gr::soapy::arginfo_t::BOOL) - .value("INT", gr::soapy::arginfo_t::INT) - .value("FLOAT", gr::soapy::arginfo_t::FLOAT) - .value("STRING", gr::soapy::arginfo_t::STRING) - .export_values(); - - py::class_<gr::soapy::arginfo_t>(m, "arginfo_t") - // Constructors - .def(py::init<>()) - - // Properties - .def_readwrite("key", &gr::soapy::arginfo_t::key) - .def_property( - "value", - [](const gr::soapy::arginfo_t& arginfo) -> py::object { - return cast_string_to_arginfo_type(arginfo.type, arginfo.value); - }, - // So we can implicitly convert to Soapy's convention - [](gr::soapy::arginfo_t& arginfo, py::object obj) -> void { - const auto info = cast_pyobject_to_arginfo_string(obj); - - arginfo.value = info.value; - arginfo.type = info.type; - }) - - .def_readwrite("name", &gr::soapy::arginfo_t::name) - .def_readwrite("description", &gr::soapy::arginfo_t::description) - .def_readwrite("units", &gr::soapy::arginfo_t::units) - .def_readwrite("type", &gr::soapy::arginfo_t::type) - .def_readwrite("range", &gr::soapy::arginfo_t::range) - .def_readwrite("options", &gr::soapy::arginfo_t::options) - .def_readwrite("option_names", &gr::soapy::arginfo_t::optionNames) - - .def("__str__", [](const gr::soapy::arginfo_t& arginfo) -> std::string { - return (arginfo.key + "=" + arginfo.value); - }); -} diff --git a/blocklib/soapy/rtlsdr_source/rtlsdr_source.yml b/blocklib/soapy/rtlsdr_source/rtlsdr_source.yml deleted file mode 100644 index 0a6f42597..000000000 --- a/blocklib/soapy/rtlsdr_source/rtlsdr_source.yml +++ /dev/null @@ -1,92 +0,0 @@ -module: soapy -block: rtlsdr_source -label: RTL SDR Source -blocktype: grc -category: '[Core]/Soapy' - -typekeys: - - id: T - type: class - options: - - cf32 - # - rf32 - -grc: - flags: [python] - templates: - imports: |- - from gnuradio import soapy - make: |- - dev = 'driver=rtlsdr' - stream_args = '' - tune_args = [''] - settings = [''] - - self.${id} = soapy.source_${T.fcn}(dev, 1, ${dev_args}, - stream_args, tune_args, settings) - self.${id}.set_sample_rate(0, ${samp_rate}) - self.${id}.set_gain_mode(0, ${agc}) - self.${id}.set_frequency(0, ${center_freq}) - self.${id}.set_frequency_correction(0, ${freq_correction}) - self.${id}.set_gain(0, 'TUNER', ${gain}) - - callbacks: - - set_sample_rate(0, ${samp_rate}) - - set_gain_mode(0, ${agc}) - - set_frequency(0, ${center_freq}) - - set_frequency_correction(0, ${freq_correction}) - - set_gain(0, 'TUNER', ${gain}) - - -parameters: - - id: dev_args - label: Device arguments - dtype: string - grc: - hide: ${'part' if not dev_args else 'none'} - - id: samp_rate - label: Sample Rate - dtype: rf32 - grc: - default: "samp_rate" - settable: true - - id: center_freq - label: "Center Freq (Hz)" - dtype: rf32 - grc: - category: RF Options - default: "freq" - settable: true - - id: gain - label: "RF Gain" - dtype: rf32 - grc: - category: RF Options - default: "20" - hide: ${'all' if agc else 'part'} - settable: true - - id: freq_correction - label: "Frequency Correction (PPM)" - dtype: rf32 - default: 0 - grc: - category: RF Options - hide: "part" - - id: agc - label: "AGC" - dtype: bool - default: 'false' - grc: - category: RF Options - hide: "part" - -ports: - - domain: stream - id: out - direction: output - type: typekeys/T - -implementations: -- id: cpu - -file_format: 1 diff --git a/blocklib/soapy/sink/sink.yml b/blocklib/soapy/sink/sink.yml deleted file mode 100644 index d91a9f45a..000000000 --- a/blocklib/soapy/sink/sink.yml +++ /dev/null @@ -1,84 +0,0 @@ -module: soapy -block: sink -label: Sink -blocktype: gr::soapy::block -# inherits: gr::soapy::block -category: '[Core]/Soapy' - -typekeys: - - id: T - type: class - options: - - cf32 - # - rf32 - -includes: - - gnuradio/soapy/block.h - -parameters: -- id: device - label: Device - dtype: string - settable: false - grc: - hide: 'all' -- id: nchan - label: Number of Channels - dtype: size_t - settable: false - grc: - hide: 'all' -- id: dev_args - label: Device Args - dtype: string - settable: false - default: '""' -- id: stream_args - label: Stream Args - dtype: string - settable: false - default: '""' - grc: - hide: 'all' -- id: tune_args - label: Tune Args - dtype: string - container: vector - settable: false - serializable: false # pmtf library doesn't support vectors of strings yet - default: std::vector<std::string>{""} - grc: - default: '[]' - hide: 'all' -- id: other_settings - label: Other Settings - dtype: string - container: vector - settable: false - serializable: false # pmtf library doesn't support vectors of strings yet - default: std::vector<std::string>{""} - grc: - default: '[]' - hide: 'all' - -- id: length_tag_name - label: Length Tag Name - dtype: string - cotr: false - settable: true - default: '""' - grc: - hide: 'part' - -ports: -- domain: stream - id: in - direction: input - type: typekeys/T - multiplicity: parameters/nchan - -implementations: -- id: cpu -# - id: cuda - -file_format: 1 diff --git a/blocklib/soapy/sink/sink_cpu.cc b/blocklib/soapy/sink/sink_cpu.cc deleted file mode 100644 index cf6299fb7..000000000 --- a/blocklib/soapy/sink/sink_cpu.cc +++ /dev/null @@ -1,77 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2004,2009,2010,2012,2018 Free Software Foundation, Inc. - * - * This file is part of GNU Radio - * - * SPDX-License-Identifier: GPL-3.0-or-later - * - */ - -#include "sink_cpu.h" -#include "sink_cpu_gen.h" -#include <SoapySDR/Errors.hpp> -#include <SoapySDR/Formats.h> -#include <volk/volk.h> - -namespace gr { -namespace soapy { - -template <> -sink_cpu<gr_complex>::sink_cpu(const typename sink<gr_complex>::block_args& args) - : gr::block("soapy_sink"), - sink<gr_complex>(args), - block_impl(SOAPY_SDR_TX, - args.device, - SOAPY_SDR_CF32, - args.nchan, - args.dev_args, - args.stream_args, - args.tune_args, - args.other_settings) -{ -} - -template <class T> -work_return_t sink_cpu<T>::work(work_io& wio) -{ - int nin = wio.inputs()[0].n_items; - long long int time_ns = 0; - int nconsumed = 0; - - int nwrite = nin; - int flags = 0; - - // TODO: optimization: add loop to handle portions of more than one burst - // per call. - - // FIXME: Add back burst tag handling. Requires some changes to tag/pmt - - int result = 0; - if (nwrite != 0) { - // No command handlers while writing - std::lock_guard<std::mutex> l(d_device_mutex); - result = d_device->writeStream( - d_stream, wio.all_input_ptrs().data(), nwrite, flags, time_ns); - } - - if (result >= 0) { - nconsumed += result; - // if (d_burst_remaining > 0) { - // d_burst_remaining -= result; - // } - } - else if (result == SOAPY_SDR_UNDERFLOW) { - std::cerr << "sU" << std::flush; - } - else { - d_logger->warn("Soapy sink error: {:s}", SoapySDR::errToStr(result)); - } - - wio.consume_each(nconsumed); - return work_return_t::OK; -} - - -} /* namespace soapy */ -} /* namespace gr */ diff --git a/blocklib/soapy/sink/sink_cpu.h b/blocklib/soapy/sink/sink_cpu.h deleted file mode 100644 index 0d8be80ab..000000000 --- a/blocklib/soapy/sink/sink_cpu.h +++ /dev/null @@ -1,22 +0,0 @@ -#pragma once - -#include "block_impl.h" -#include <gnuradio/soapy/sink.h> -namespace gr { -namespace soapy { - -template <class T> -class sink_cpu : public sink<T>, public block_impl -{ -public: - sink_cpu(const typename sink<T>::block_args& args); - - work_return_t work(work_io&) override; - -private: - size_t d_burst_remaining = 0; -}; - - -} // namespace soapy -} // namespace gr diff --git a/blocklib/soapy/source/source.yml b/blocklib/soapy/source/source.yml deleted file mode 100644 index 07624cb28..000000000 --- a/blocklib/soapy/source/source.yml +++ /dev/null @@ -1,75 +0,0 @@ -module: soapy -block: source -label: Source -blocktype: gr::soapy::block -# inherits: gr::soapy::block -category: '[Core]/Soapy' - -typekeys: - - id: T - type: class - options: - - cf32 - # - rf32 - -includes: - - gnuradio/soapy/block.h - -parameters: -- id: device - label: Device - dtype: string - settable: false - grc: - hide: 'all' -- id: nchan - label: Number of Channels - dtype: size_t - settable: false - grc: - hide: 'all' -- id: dev_args - label: Device Args - dtype: string - settable: false - default: '""' -- id: stream_args - label: Stream Args - dtype: string - settable: false - default: '""' - grc: - hide: 'all' -- id: tune_args - label: Tune Args - dtype: string - container: vector - settable: false - serializable: false # pmtf library doesn't support vectors of strings yet - default: std::vector<std::string>{""} - grc: - default: '[]' - hide: 'all' -- id: other_settings - label: Other Settings - dtype: std::string - container: vector - settable: false - serializable: false # pmtf library doesn't support vectors of strings yet - default: std::vector<std::string>{""} - grc: - default: '[]' - hide: 'all' - -ports: -- domain: stream - id: out - direction: output - type: typekeys/T - multiplicity: parameters/nchan - -implementations: -- id: cpu -# - id: cuda - -file_format: 1 diff --git a/blocklib/soapy/source/source_cpu.cc b/blocklib/soapy/source/source_cpu.cc deleted file mode 100644 index de838506f..000000000 --- a/blocklib/soapy/source/source_cpu.cc +++ /dev/null @@ -1,102 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2004,2009,2010,2012,2018 Free Software Foundation, Inc. - * - * This file is part of GNU Radio - * - * SPDX-License-Identifier: GPL-3.0-or-later - * - */ - -#include "source_cpu.h" -#include "source_cpu_gen.h" -#include <SoapySDR/Errors.hpp> -#include <SoapySDR/Formats.h> -#include <volk/volk.h> - -namespace gr { -namespace soapy { - -template <> -source_cpu<gr_complex>::source_cpu(const typename source<gr_complex>::block_args& args) - : gr::block("soapy_source"), - source<gr_complex>(args), - block_impl(SOAPY_SDR_RX, - args.device, - SOAPY_SDR_CF32, - args.nchan, - args.dev_args, - args.stream_args, - args.tune_args, - args.other_settings) -{ -} - -template <class T> -work_return_t source_cpu<T>::work(work_io& wio) -{ - auto noutput_items = wio.outputs()[0].n_items; - /* This limits each work invocation to MTU transfers */ - if (d_mtu > 0) { - noutput_items = std::min(noutput_items, d_mtu); - } - else { - noutput_items = std::min(noutput_items, size_t{ 1024 }); - } - - long long int time_ns = 0; - int flags = 0; - const long timeout_us = 500000; // 0.5 sec - int nout = 0; - - auto output_items = wio.all_output_ptrs(); - for (;;) { - - // No command handlers while reading - int result; - { - std::lock_guard<std::mutex> l(d_device_mutex); - result = d_device->readStream( - d_stream, output_items.data(), noutput_items, flags, time_ns, timeout_us); - } - - if (result >= 0) { - nout = result; - break; - } - - switch (result) { - - // Retry on overflow. Data has been lost. - case SOAPY_SDR_OVERFLOW: - std::cerr << "sO" << std::flush; - continue; - - // Yield back to scheduler on timeout. - case SOAPY_SDR_TIMEOUT: - break; - - // Report and yield back to scheduler on other errors. - default: - logger()->warn("Soapy source error: {}", SoapySDR::errToStr(result)); - break; - } - - break; - }; - - wio.produce_each(nout); - - // if we didn't produce anything, need to kick the scheduler - // This emulates GR 3.x scheduler behavior but also allows for - // a non-blocking implementation above - if (!nout) { - this->come_back_later(100); - } - - return work_return_t::OK; -} - - -} /* namespace soapy */ -} /* namespace gr */ diff --git a/blocklib/soapy/source/source_cpu.h b/blocklib/soapy/source/source_cpu.h deleted file mode 100644 index 2cfe37022..000000000 --- a/blocklib/soapy/source/source_cpu.h +++ /dev/null @@ -1,21 +0,0 @@ -#pragma once - -#include "block_impl.h" -#include <gnuradio/soapy/source.h> -namespace gr { -namespace soapy { - -template <class T> -class source_cpu : public source<T>, public block_impl -{ -public: - source_cpu(const typename source<T>::block_args& args); - - work_return_t work(work_io&) override; - -private: -}; - - -} // namespace soapy -} // namespace gr diff --git a/blocklib/soapy/test/meson.build b/blocklib/soapy/test/meson.build deleted file mode 100644 index e69de29bb..000000000 --- a/blocklib/soapy/test/meson.build +++ /dev/null diff --git a/blocklib/soapy/test/test_soapy.py b/blocklib/soapy/test/test_soapy.py deleted file mode 100644 index 15b9d8404..000000000 --- a/blocklib/soapy/test/test_soapy.py +++ /dev/null @@ -1,27 +0,0 @@ -from gnuradio import gr, soapy, blocks, streamops - -samp_rate = 250000 - -src = soapy.source_c('driver=rtlsdr',1) -src.set_sample_rate(0, samp_rate) -src.set_gain_mode(0, False) -src.set_frequency(0, 90500000) -src.set_frequency_correction(0, 0) -src.set_gain(0, 'TUNER', 40) - -hd = streamops.head(100000) -snk = blocks.vector_sink_c() - -fg = gr.flowgraph() - -fg.connect(src,0,hd,0) -fg.connect(hd,0,snk,0) - -fg.start() -fg.wait() - -from matplotlib import pyplot as plt -import numpy as np -plt.plot(np.real(snk.data())) -plt.plot(np.imag(snk.data())) -plt.show()
\ No newline at end of file diff --git a/blocklib/streamops/annotator/annotator.yml b/blocklib/streamops/annotator/annotator.yml deleted file mode 100644 index 2b9802f89..000000000 --- a/blocklib/streamops/annotator/annotator.yml +++ /dev/null @@ -1,61 +0,0 @@ -# This YAML is currently not used because ports need to support multiplicity -## As it is currently implemented, the ports are added in the _cpu constructor -## which we need to be in the top level constructor, but requires extra logic - -module: streamops -block: annotator -label: Annotator -blocktype: sync_block -category: '[Core]/Debug Tools' - -parameters: -- id: when - label: When - dtype: ru64 - settable: false -- id: num_inputs - label: Num Inputs - dtype: size - settable: false -- id: num_outputs - label: Num Outputs - dtype: size - settable: false -- id: tpp - label: Tag Propagation Policy - dtype: gr::tag_propagation_policy_t - settable: false - serializable: false -- id: itemsize - label: Item Size - dtype: size - settable: false - default: 0 - grc: - hide: part - -ports: -- domain: stream - id: in - direction: input - type: untyped - size: parameters/itemsize - multiplicity: parameters/num_inputs - -- domain: stream - id: out - direction: output - type: untyped - size: parameters/itemsize - multiplicity: parameters/num_outputs - -callbacks: -- id: data - return: std::vector<tag_t> - const: true - -implementations: -- id: cpu -# - id: cuda - -file_format: 1 diff --git a/blocklib/streamops/annotator/annotator_cpu.cc b/blocklib/streamops/annotator/annotator_cpu.cc deleted file mode 100644 index 01923b4ca..000000000 --- a/blocklib/streamops/annotator/annotator_cpu.cc +++ /dev/null @@ -1,82 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2010,2013 Free Software Foundation, Inc. - * Copyright 2021 Josh Morman - * - * This file is part of GNU Radio - * - * SPDX-License-Identifier: GPL-3.0-or-later - * - */ - -#include "annotator_cpu.h" -#include "annotator_cpu_gen.h" -#include <pmtf/scalar.hpp> -#include <pmtf/string.hpp> -#include <cstring> -#include <iomanip> -#include <iostream> - -namespace gr { -namespace streamops { - -annotator_cpu::annotator_cpu(const block_args& args) - : INHERITED_CONSTRUCTORS, - d_when(args.when), - d_num_inputs(args.num_inputs), - d_num_outputs(args.num_outputs), - d_tpp(args.tpp) -{ - - set_tag_propagation_policy(args.tpp); - - d_tag_counter = 0; - // set_relative_rate(1, 1); -} - -work_return_t annotator_cpu::work(work_io& wio) - -{ - auto noutput_items = wio.outputs()[0].n_items; - - uint64_t abs_N = 0; - - for (unsigned i = 0; i < d_num_inputs; i++) { - abs_N = wio.inputs()[i].nitems_read(); - - auto tags = wio.inputs()[i].tags_in_window(0, noutput_items); - d_stored_tags.insert(d_stored_tags.end(), tags.begin(), tags.end()); - } - - // Storing the current noutput_items as the value to the "noutput_items" key - auto srcid = pmtf::string(alias()); - auto key = "seq"; - - // Work does nothing to the data stream; just copy all inputs to outputs - // Adds a new tag when the number of items read is a multiple of d_when - abs_N = wio.outputs()[0].buf().total_written(); - - for (size_t j = 0; j < noutput_items; j++) { - // the min() is a hack to make sure this doesn't segfault if - // there are a different number of ins and outs. This is - // specifically designed to test the 1-to-1 propagation policy. - // for (unsigned i = 0; i < std::min(d_num_outputs, d_num_inputs); i++) { - for (unsigned i = 0; i < d_num_outputs; i++) { - if (abs_N % d_when == 0) { - auto value = pmtf::scalar<uint64_t>(d_tag_counter++); - // tag_map tm = {{key, value}, {"srcid",srcid}}; - wio.outputs()[i].buf().add_tag( - abs_N, pmtf::map{ { key, value }, { "srcid", srcid } }); - } - } - abs_N++; - } - for (unsigned i = 0; i < d_num_outputs; i++) { - wio.outputs()[i].n_produced = noutput_items; - } - - return work_return_t::OK; -} - -} /* namespace streamops */ -} /* namespace gr */ diff --git a/blocklib/streamops/annotator/annotator_cpu.h b/blocklib/streamops/annotator/annotator_cpu.h deleted file mode 100644 index 61b3d2981..000000000 --- a/blocklib/streamops/annotator/annotator_cpu.h +++ /dev/null @@ -1,36 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2010,2013 Free Software Foundation, Inc. - * Copyright 2021 Josh Morman - * - * This file is part of GNU Radio - * - * SPDX-License-Identifier: GPL-3.0-or-later - * - */ - -#pragma once - -#include <gnuradio/streamops/annotator.h> - -namespace gr { -namespace streamops { - -class annotator_cpu : public annotator -{ -public: - annotator_cpu(const block_args& args); - work_return_t work(work_io&) override; - - std::vector<tag_t> data() const override { return d_stored_tags; }; - -private: - const uint64_t d_when; - uint64_t d_tag_counter; - std::vector<tag_t> d_stored_tags; - size_t d_num_inputs, d_num_outputs; - tag_propagation_policy_t d_tpp; -}; - -} // namespace streamops -} // namespace gr
\ No newline at end of file diff --git a/blocklib/streamops/deinterleave/deinterleave.yml b/blocklib/streamops/deinterleave/deinterleave.yml deleted file mode 100644 index 37599c5d8..000000000 --- a/blocklib/streamops/deinterleave/deinterleave.yml +++ /dev/null @@ -1,70 +0,0 @@ -module: streamops -block: deinterleave -label: deinterleave -blocktype: block -category: '[Core]/Stream Operators' - -doc: - brief: deinterleave an input block of samples into N outputs - detail: |- - This block deinterleaves blocks of samples. For each output - connection, the input stream will be deinterleaved successively - to the output connections. By default, the block deinterleaves - a single input to each output unless blocksize is given in the - constructor. - - \code - blocksize = 1 - connections = 2 - input = [a, b, c, d, e, f, g, h] - output[0] = [a, c, e, g] - output[1] = [b, d, f, h] - \endcode - - \code - blocksize = 2 - connections = 2 - input = [a, b, c, d, e, f, g, h] - output[0] = [a, b, e, f] - output[1] = [c, d, g, h] - \endcode - -parameters: -- id: nstreams - label: Num Streams - dtype: size - settable: false - grc: - default: 2 -- id: blocksize - label: Block Size - dtype: size - settable: false - default: 1 -- id: itemsize - label: Item Size - dtype: size - settable: false - default: 0 - grc: - hide: part - -ports: -- domain: stream - id: in - direction: input - type: untyped - size: parameters/itemsize - -- domain: stream - id: out - direction: output - type: untyped - size: parameters/itemsize - multiplicity: parameters/nstreams - -implementations: -- id: cpu -# - id: cuda - -file_format: 1 diff --git a/blocklib/streamops/deinterleave/deinterleave_cpu.cc b/blocklib/streamops/deinterleave/deinterleave_cpu.cc deleted file mode 100644 index 811dd1921..000000000 --- a/blocklib/streamops/deinterleave/deinterleave_cpu.cc +++ /dev/null @@ -1,83 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2022 Josh Morman - * - * This file is part of GNU Radio - * - * SPDX-License-Identifier: GPL-3.0-or-later - * - */ - -#include "deinterleave_cpu.h" -#include "deinterleave_cpu_gen.h" - -#include <algorithm> - -namespace gr { -namespace streamops { - -deinterleave_cpu::deinterleave_cpu(block_args args) : INHERITED_CONSTRUCTORS -{ - if (args.itemsize > 0) { - d_size_bytes = args.itemsize * args.blocksize; - set_output_multiple(args.blocksize); - } - set_relative_rate(1.0 / args.nstreams); -} - -work_return_t deinterleave_cpu::work(work_io& wio) - -{ - auto blocksize = pmtf::get_as<size_t>(*this->param_blocksize); - auto itemsize = wio.inputs()[0].buf().item_size(); - - // Since itemsize can be set after construction - if (d_size_bytes == 0) { - d_size_bytes = itemsize * blocksize; - set_output_multiple(blocksize); - return work_return_t::OK; - } - - // Forecasting - auto nstreams = pmtf::get_as<size_t>(*this->param_nstreams); - auto noutput_items = wio.min_noutput_items(); - auto ninput_items = wio.inputs()[0].n_items; - auto min_output = blocksize * (ninput_items / (blocksize * nstreams)); - if (min_output < 1) { - return work_return_t::INSUFFICIENT_INPUT_ITEMS; - } - noutput_items = std::min(noutput_items, min_output); - ninput_items = noutput_items * nstreams; - - auto in = wio.inputs()[0].items<uint8_t>(); - int count = 0, totalcount = noutput_items * nstreams; - unsigned int skip = 0; - unsigned int acc = 0; - while (count < totalcount) { - auto out = wio.outputs()[d_current_output].items<uint8_t>(); - memcpy(out + skip * d_size_bytes, in, d_size_bytes); - in += d_size_bytes; - // produce(d_current_output, blocksize); - wio.outputs()[d_current_output].n_produced += blocksize; - d_current_output = (d_current_output + 1) % nstreams; - - // accumulate times through the loop; increment skip after a - // full pass over the output streams. - // This is separate than d_current_output since we could be in - // the middle of a loop when we exit. - acc++; - if (acc >= nstreams) { - skip++; - acc = 0; - } - - // Keep track of our loop counter - count += blocksize; - } - wio.consume_each(totalcount); - return work_return_t::OK; -} - - -} // namespace streamops -} // namespace gr
\ No newline at end of file diff --git a/blocklib/streamops/deinterleave/deinterleave_cpu.h b/blocklib/streamops/deinterleave/deinterleave_cpu.h deleted file mode 100644 index 61630ddf4..000000000 --- a/blocklib/streamops/deinterleave/deinterleave_cpu.h +++ /dev/null @@ -1,30 +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/streamops/deinterleave.h> - -namespace gr { -namespace streamops { - -class deinterleave_cpu : public virtual deinterleave -{ -public: - deinterleave_cpu(block_args args); - work_return_t work(work_io&) override; - -private: - size_t d_current_output = 0; - size_t d_size_bytes = 0; // block size in bytes -}; - -} // namespace streamops -} // namespace gr
\ No newline at end of file diff --git a/blocklib/streamops/interleave/interleave.yml b/blocklib/streamops/interleave/interleave.yml deleted file mode 100644 index 0ece776a6..000000000 --- a/blocklib/streamops/interleave/interleave.yml +++ /dev/null @@ -1,72 +0,0 @@ -module: streamops -block: interleave -label: interleave -blocktype: block -category: '[Core]/Stream Operators' - -doc: - brief: interleave N inputs into a single output - detail: |- - This block interleaves blocks of samples. For each input - connection, the samples are interleaved successively to the - output connection. By default, the block interleaves a single - sample from each input to the output unless blocksize is given - in the constructor. - - \code - blocksize = 1 - connections = 2 - input[0] = [a, c, e, g] - input[1] = [b, d, f, h] - output = [a, b, c, d, e, f, g, h] - \endcode - - \code - blocksize = 2 - connections = 2 - input[0] = [a, b, e, f] - input[1] = [c, d, g, h] - output = [a, b, c, d, e, f, g, h] - \endcode - - -parameters: -- id: nstreams - label: Num Streams - dtype: size - settable: false - grc: - default: 2 -- id: blocksize - label: Block Size - dtype: size - settable: false - default: 1 -- id: itemsize - label: Item Size - dtype: size - settable: false - default: 0 - grc: - hide: part - -ports: -- domain: stream - id: in - direction: input - type: untyped - size: parameters/itemsize - multiplicity: parameters/nstreams - -- domain: stream - id: out - direction: output - type: untyped - size: parameters/itemsize - - -implementations: -- id: cpu -# - id: cuda - -file_format: 1 diff --git a/blocklib/streamops/interleave/interleave_cpu.cc b/blocklib/streamops/interleave/interleave_cpu.cc deleted file mode 100644 index f9d003e2c..000000000 --- a/blocklib/streamops/interleave/interleave_cpu.cc +++ /dev/null @@ -1,65 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2022 Josh Morman - * - * This file is part of GNU Radio - * - * SPDX-License-Identifier: GPL-3.0-or-later - * - */ - -#include "interleave_cpu.h" -#include "interleave_cpu_gen.h" - -namespace gr { -namespace streamops { - -interleave_cpu::interleave_cpu(block_args args) - : INHERITED_CONSTRUCTORS, - d_ninputs(args.nstreams), - d_blocksize(args.blocksize), - d_itemsize(args.itemsize) - -{ - set_relative_rate(d_ninputs); - set_output_multiple(d_blocksize * d_ninputs); -} - -work_return_t interleave_cpu::work(work_io& wio) - -{ - - // Since itemsize can be set after construction - if (d_itemsize == 0) { - d_itemsize = wio.inputs()[0].buf().item_size(); - return work_return_t::OK; - } - - // Forecasting - auto ninput_items = wio.min_ninput_items(); - auto noutput_items = wio.outputs()[0].n_items; - auto noutput_blocks = - std::min(ninput_items / d_blocksize, noutput_items / (d_blocksize * d_ninputs)); - - if (noutput_blocks < 1) { - return work_return_t::INSUFFICIENT_OUTPUT_ITEMS; - } - - auto out = wio.outputs()[0].items<uint8_t>(); - - for (unsigned int i = 0; i < noutput_blocks; i++) { - for (auto& in : wio.inputs()) { - memcpy(out, - in.items<uint8_t>() + d_itemsize * d_blocksize * i, - d_itemsize * d_blocksize); - out += d_itemsize * d_blocksize; - } - } - wio.consume_each(noutput_blocks * d_blocksize); - wio.produce_each(noutput_blocks * d_blocksize * d_ninputs); - return work_return_t::OK; -} - - -} // namespace streamops -} // namespace gr
\ No newline at end of file diff --git a/blocklib/streamops/interleave/interleave_cpu.h b/blocklib/streamops/interleave/interleave_cpu.h deleted file mode 100644 index 20d39d84c..000000000 --- a/blocklib/streamops/interleave/interleave_cpu.h +++ /dev/null @@ -1,31 +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/streamops/interleave.h> - -namespace gr { -namespace streamops { - -class interleave_cpu : public virtual interleave -{ -public: - interleave_cpu(block_args args); - work_return_t work(work_io&) override; - -private: - const unsigned int d_ninputs; - const unsigned int d_blocksize; - size_t d_itemsize; -}; - -} // namespace streamops -} // namespace gr
\ No newline at end of file diff --git a/blocklib/streamops/interleaved_short_to_complex/interleaved_short_to_complex.yml b/blocklib/streamops/interleaved_short_to_complex/interleaved_short_to_complex.yml deleted file mode 100644 index d53f5cd7d..000000000 --- a/blocklib/streamops/interleaved_short_to_complex/interleaved_short_to_complex.yml +++ /dev/null @@ -1,35 +0,0 @@ -module: streamops -block: interleaved_short_to_complex -label: Interleaved Short to Complex -blocktype: sync_block -category: '[Core]/Stream Operators' - -parameters: -- id: swap - label: Swap I and Q - dtype: bool - settable: false - default: 'false' -- id: scale_factor - label: Scale Factor - dtype: rf32 - settable: true - default: 1.0 - -ports: -- domain: stream - id: in - direction: input - type: int16_t - shape: '2' - -- domain: stream - id: out - direction: output - type: cf32 - -implementations: -- id: cpu -# - id: cuda - -file_format: 1 diff --git a/blocklib/streamops/interleaved_short_to_complex/interleaved_short_to_complex_cpu.cc b/blocklib/streamops/interleaved_short_to_complex/interleaved_short_to_complex_cpu.cc deleted file mode 100644 index 5020819b2..000000000 --- a/blocklib/streamops/interleaved_short_to_complex/interleaved_short_to_complex_cpu.cc +++ /dev/null @@ -1,54 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2012 Free Software Foundation, Inc. - * - * This file is part of GNU Radio - * - * SPDX-License-Identifier: GPL-3.0-or-later - * - */ - -#include "interleaved_short_to_complex_cpu.h" -#include "interleaved_short_to_complex_cpu_gen.h" -#include <volk/volk.h> - -namespace gr { -namespace streamops { - -interleaved_short_to_complex_cpu::interleaved_short_to_complex_cpu(const block_args& args) - : INHERITED_CONSTRUCTORS, d_scalar(args.scale_factor), d_swap(args.swap) -{ -} - -void interleaved_short_to_complex_cpu::set_swap(bool swap) { d_swap = swap; } -void interleaved_short_to_complex_cpu::set_scale_factor(float new_value) -{ - d_scalar = new_value; -} - -work_return_t interleaved_short_to_complex_cpu::work(work_io& wio) - -{ - auto in = wio.inputs()[0].items<short>(); - auto out = wio.outputs()[0].items<float>(); - - auto noutput_items = wio.outputs()[0].n_items; - - // This calculates in[] * 1.0 / d_scalar - volk_16i_s32f_convert_32f(out, in, d_scalar, 2 * noutput_items); - - if (d_swap) { - for (size_t i = 0; i < noutput_items; ++i) { - float f = out[2 * i + 1]; - out[2 * i + 1] = out[2 * i]; - out[2 * i] = f; - } - } - - wio.outputs()[0].n_produced = noutput_items; - return work_return_t::OK; -} - - -} /* namespace streamops */ -} /* namespace gr */ diff --git a/blocklib/streamops/interleaved_short_to_complex/interleaved_short_to_complex_cpu.h b/blocklib/streamops/interleaved_short_to_complex/interleaved_short_to_complex_cpu.h deleted file mode 100644 index b4ec50fe1..000000000 --- a/blocklib/streamops/interleaved_short_to_complex/interleaved_short_to_complex_cpu.h +++ /dev/null @@ -1,36 +0,0 @@ -/* -*- c++ -*- */ -/* - * 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/streamops/interleaved_short_to_complex.h> - -namespace gr { -namespace streamops { - -class interleaved_short_to_complex_cpu : public interleaved_short_to_complex -{ -public: - interleaved_short_to_complex_cpu(const block_args& args); - - work_return_t work(work_io&) override; - - - void set_swap(bool swap); - void set_scale_factor(float new_value) override; - -private: - float d_scalar; - bool d_swap; -}; - - -} // namespace streamops -} // namespace gr diff --git a/blocklib/streamops/keep_m_in_n/keep_m_in_n.yml b/blocklib/streamops/keep_m_in_n/keep_m_in_n.yml deleted file mode 100644 index 913c8a55f..000000000 --- a/blocklib/streamops/keep_m_in_n/keep_m_in_n.yml +++ /dev/null @@ -1,52 +0,0 @@ -module: streamops -block: keep_m_in_n -label: Keep M in N -blocktype: block -category: '[Core]/Stream Operators' - -# Example Parameters -parameters: -- id: m - label: M - dtype: size - settable: true - grc: - default: 1 -- id: n - label: N - dtype: size - settable: true - grc: - default: 2 -- id: offset - label: offset - dtype: size - settable: true - grc: - default: 0 -- id: itemsize - label: Item Size - dtype: size - settable: false - default: 0 - grc: - hide: part - -ports: -- domain: stream - id: in - direction: input - type: untyped - size: parameters/itemsize - -- domain: stream - id: out - direction: output - type: untyped - size: parameters/itemsize - -implementations: -- id: cpu -- id: cuda - -file_format: 1 diff --git a/blocklib/streamops/keep_m_in_n/keep_m_in_n_cpu.cc b/blocklib/streamops/keep_m_in_n/keep_m_in_n_cpu.cc deleted file mode 100644 index 6b297546c..000000000 --- a/blocklib/streamops/keep_m_in_n/keep_m_in_n_cpu.cc +++ /dev/null @@ -1,102 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2012,2018,2022 Free Software Foundation, Inc. - * Copyright 2022 Josh Morman - * - * This file is part of GNU Radio - * - * SPDX-License-Identifier: GPL-3.0-or-later - * - */ - -#include "keep_m_in_n_cpu.h" -#include "keep_m_in_n_cpu_gen.h" - -namespace gr { -namespace streamops { - -keep_m_in_n_cpu::keep_m_in_n_cpu(block_args args) : INHERITED_CONSTRUCTORS -{ - // sanity checking - if (args.m <= 0) { - throw std::runtime_error(fmt::format("m={:d} but must be > 0", args.m)); - } - if (args.n <= 0) { - throw std::runtime_error(fmt::format("n={:d} but must be > 0", args.n)); - } - if (args.m > args.n) { - throw std::runtime_error(fmt::format("m = {:d} ≤ {:d} = n", args.m, args.n)); - } - if (args.offset < 0) { - throw std::runtime_error( - fmt::format("offset {:d} but must be >= 0", args.offset)); - } - if (args.offset >= args.n) { - throw std::runtime_error( - fmt::format("offset = {:d} < {:d} = n", args.offset, args.n)); - } - - set_output_multiple(args.m); - - // TODO: integer ratio relative rate - // set_relative_rate(static_cast<uint64_t>(m), static_cast<uint64_t>(n)); - set_relative_rate((double)args.m / args.n); -} - -work_return_t keep_m_in_n_cpu::work(work_io& wio) - -{ - auto out = wio.outputs()[0].items<uint8_t>(); - auto in = wio.inputs()[0].items<uint8_t>(); - auto noutput_items = wio.outputs()[0].n_items; - auto ninput_items = wio.inputs()[0].n_items; - - // Grab our parameters - auto itemsize = wio.outputs()[0].buf().item_size(); - auto m = pmtf::get_as<size_t>(*this->param_m); - auto n = pmtf::get_as<size_t>(*this->param_n); - auto offset = pmtf::get_as<size_t>(*this->param_offset); - - // iterate over data blocks of size {n, input : m, output} - int blks = std::min(noutput_items / m, ninput_items / n); - int excess = (offset + m - n) * itemsize; - - for (int i = 0; i < blks; i++) { - // set up copy pointers - const uint8_t* iptr = &in[(i * n + offset) * itemsize]; - uint8_t* optr = &out[i * m * itemsize]; - // perform copy - if (excess <= 0) { - memcpy(optr, iptr, m * itemsize); - } - else { - memcpy(optr, &in[i * n * itemsize], excess); - memcpy(optr + excess, iptr, m * itemsize - excess); - } - } - - wio.consume_each(blks * n); - wio.produce_each(blks * m); - return work_return_t::OK; -} - -void keep_m_in_n_cpu::on_parameter_change(param_action_sptr action) -{ - // This will set the underlying PMT - block::on_parameter_change(action); - - auto m = pmtf::get_as<size_t>(*this->param_m); - auto n = pmtf::get_as<size_t>(*this->param_n); - - // Do more updating for certain parameters - if (action->id() == keep_m_in_n::id_m) { - - set_output_multiple(m); - set_relative_rate((double)m / n); - } - else if (action->id() == keep_m_in_n::id_n) { - set_relative_rate((double)m / n); - } -} -} // namespace streamops -} // namespace gr
\ No newline at end of file diff --git a/blocklib/streamops/keep_m_in_n/keep_m_in_n_cpu.h b/blocklib/streamops/keep_m_in_n/keep_m_in_n_cpu.h deleted file mode 100644 index 9f1ad5e76..000000000 --- a/blocklib/streamops/keep_m_in_n/keep_m_in_n_cpu.h +++ /dev/null @@ -1,29 +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/streamops/keep_m_in_n.h> - -namespace gr { -namespace streamops { - -class keep_m_in_n_cpu : public virtual keep_m_in_n -{ -public: - keep_m_in_n_cpu(block_args args); - work_return_t work(work_io&) override; - -private: - void on_parameter_change(param_action_sptr action) override; -}; - -} // namespace streamops -} // namespace gr
\ No newline at end of file diff --git a/blocklib/streamops/keep_m_in_n/keep_m_in_n_cuda.cc b/blocklib/streamops/keep_m_in_n/keep_m_in_n_cuda.cc deleted file mode 100644 index 0765af585..000000000 --- a/blocklib/streamops/keep_m_in_n/keep_m_in_n_cuda.cc +++ /dev/null @@ -1,111 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2022 Josh Morman - * - * This file is part of GNU Radio - * - * SPDX-License-Identifier: GPL-3.0-or-later - * - */ - -#include "keep_m_in_n_cuda.h" -#include "keep_m_in_n_cuda_gen.h" - -#include <gnuradio/helper_cuda.h> - -#include <cuComplex.h> -#include <cuda.h> -#include <cuda_runtime.h> - - -namespace gr { -namespace streamops { - -keep_m_in_n_cuda::keep_m_in_n_cuda(block_args args) : INHERITED_CONSTRUCTORS - -{ - // sanity checking - if (args.m <= 0) { - throw std::runtime_error(fmt::format("m={:d} but must be > 0", args.m)); - } - if (args.n <= 0) { - throw std::runtime_error(fmt::format("n={:d} but must be > 0", args.n)); - } - if (args.m > args.n) { - throw std::runtime_error(fmt::format("m = {:d} ≤ {:d} = n", args.m, args.n)); - } - if (args.offset >= args.n) { - throw std::runtime_error( - fmt::format("offset = {:d} < {:d} = n", args.offset, args.n)); - } - - - // can change this to uint64_t by restricting the output multiple - p_kernel = std::make_shared<cusp::keep_m_in_n<uint8_t>>(args.m, args.n, 4); - p_kernel->occupancy(&d_min_block, &d_min_grid); - - cudaStreamCreate(&d_stream); - p_kernel->set_stream(d_stream); - - set_output_multiple(args.m); - set_relative_rate((double)args.m / args.n); -} - -work_return_t keep_m_in_n_cuda::work(work_io& wio) - -{ - auto out = wio.outputs()[0].items<uint8_t>(); - auto in = wio.inputs()[0].items<uint8_t>(); - auto noutput_items = wio.outputs()[0].n_items; - auto ninput_items = wio.inputs()[0].n_items; - auto itemsize = wio.outputs()[0].buf().item_size(); - auto m = pmtf::get_as<size_t>(*this->param_m); - auto n = pmtf::get_as<size_t>(*this->param_n); - auto offset = pmtf::get_as<size_t>(*this->param_offset); - - // iterate over data blocks of size {n, input : m, output} - int blks = std::min(noutput_items / m, ninput_items / n); - - if (blks == 0) { - wio.consume_each(0); - wio.produce_each(0); - return work_return_t::OK; - } - - int gridSize = (blks * m * itemsize + d_min_block - 1) / d_min_block; - checkCudaErrors(p_kernel->launch(in, - out, - m, - n, - itemsize, - offset, - gridSize, - d_min_block, - blks * m * itemsize, - d_stream)); - - wio.consume_each(blks * n); - wio.produce_each(blks * m); - return work_return_t::OK; -} - -void keep_m_in_n_cuda::on_parameter_change(param_action_sptr action) -{ - // This will set the underlying PMT - block::on_parameter_change(action); - - auto m = pmtf::get_as<size_t>(*this->param_m); - auto n = pmtf::get_as<size_t>(*this->param_n); - - // Do more updating for certain parameters - if (action->id() == keep_m_in_n::id_m) { - - set_output_multiple(m); - set_relative_rate((double)m / n); - } - else if (action->id() == keep_m_in_n::id_n) { - set_relative_rate((double)m / n); - } -} -} // namespace streamops -} // namespace gr diff --git a/blocklib/streamops/keep_m_in_n/keep_m_in_n_cuda.h b/blocklib/streamops/keep_m_in_n/keep_m_in_n_cuda.h deleted file mode 100644 index ed2fec555..000000000 --- a/blocklib/streamops/keep_m_in_n/keep_m_in_n_cuda.h +++ /dev/null @@ -1,35 +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/streamops/keep_m_in_n.h> - -#include <cusp/keep_m_in_n.cuh> - -namespace gr { -namespace streamops { - -class keep_m_in_n_cuda : public keep_m_in_n -{ -public: - keep_m_in_n_cuda(block_args args); - work_return_t work(work_io&) override; - -private: - int d_min_block; - int d_min_grid; - cudaStream_t d_stream; - std::shared_ptr<cusp::keep_m_in_n<uint8_t>> p_kernel; - void on_parameter_change(param_action_sptr action) override; -}; - -} // namespace streamops -} // namespace gr
\ No newline at end of file diff --git a/blocklib/streamops/nop/nop.yml b/blocklib/streamops/nop/nop.yml deleted file mode 100644 index ef1379d15..000000000 --- a/blocklib/streamops/nop/nop.yml +++ /dev/null @@ -1,33 +0,0 @@ -module: streamops -block: nop -label: Nop -blocktype: sync_block -category: '[Core]/Debug Tools' - -parameters: -- id: itemsize - label: Item Size - dtype: size - settable: false - default: 0 - grc: - hide: part - -ports: -- domain: stream - id: in - direction: input - type: untyped - size: parameters/itemsize - -- domain: stream - id: out - direction: output - type: untyped - size: parameters/itemsize - -implementations: -- id: cpu -# - id: cuda - -file_format: 1 diff --git a/blocklib/streamops/nop/nop_cpu.cc b/blocklib/streamops/nop/nop_cpu.cc deleted file mode 100644 index 7f4880744..000000000 --- a/blocklib/streamops/nop/nop_cpu.cc +++ /dev/null @@ -1,26 +0,0 @@ -/* -*- c++ -*- */ -/* - * This file is part of GNU Radio - * - * SPDX-License-Identifier: GPL-3.0-or-later - * - */ - -#include "nop_cpu.h" -#include "nop_cpu_gen.h" - -namespace gr { -namespace streamops { - -nop_cpu::nop_cpu(block_args args) : INHERITED_CONSTRUCTORS {} - -work_return_t nop_cpu::work(work_io& wio) - -{ - wio.produce_each(wio.outputs()[0].n_items); - return work_return_t::OK; -} - - -} // namespace streamops -} // namespace gr
\ No newline at end of file diff --git a/blocklib/streamops/nop/nop_cpu.h b/blocklib/streamops/nop/nop_cpu.h deleted file mode 100644 index 9e78ec776..000000000 --- a/blocklib/streamops/nop/nop_cpu.h +++ /dev/null @@ -1,24 +0,0 @@ -/* -*- c++ -*- */ -/* - * This file is part of GNU Radio - * - * SPDX-License-Identifier: GPL-3.0-or-later - * - */ - -#pragma once - -#include <gnuradio/streamops/nop.h> - -namespace gr { -namespace streamops { - -class nop_cpu : public nop -{ -public: - nop_cpu(block_args args); - work_return_t work(work_io&) override; -}; - -} // namespace streamops -} // namespace gr
\ No newline at end of file diff --git a/blocklib/streamops/nop_head/nop_head.yml b/blocklib/streamops/nop_head/nop_head.yml deleted file mode 100644 index 14a6c3387..000000000 --- a/blocklib/streamops/nop_head/nop_head.yml +++ /dev/null @@ -1,36 +0,0 @@ -module: streamops -block: nop_head -label: Nop Head -blocktype: sync_block -category: '[Core]/Debug Tools' - -parameters: -- id: nitems - label: Num. Items - dtype: size - settable: false -- id: itemsize - label: Item Size - dtype: size - settable: false - default: 0 - grc: - hide: part -ports: -- domain: stream - id: in - direction: input - type: untyped - size: parameters/itemsize - -- domain: stream - id: out - direction: output - type: untyped - size: parameters/itemsize - -implementations: -- id: cpu -# - id: cuda - -file_format: 1 diff --git a/blocklib/streamops/nop_head/nop_head_cpu.cc b/blocklib/streamops/nop_head/nop_head_cpu.cc deleted file mode 100644 index bc9571e3d..000000000 --- a/blocklib/streamops/nop_head/nop_head_cpu.cc +++ /dev/null @@ -1,45 +0,0 @@ -/* -*- c++ -*- */ -/* - * This file is part of GNU Radio - * - * SPDX-License-Identifier: GPL-3.0-or-later - * - */ - -#include "nop_head_cpu.h" -#include "nop_head_cpu_gen.h" - -namespace gr { -namespace streamops { - -nop_head_cpu::nop_head_cpu(const block_args& args) - : INHERITED_CONSTRUCTORS, d_nitems(args.nitems) -{ -} - -work_return_t nop_head_cpu::work(work_io& wio) - -{ - - if (d_ncopied_items >= d_nitems) { - wio.outputs()[0].n_produced = 0; - return work_return_t::DONE; // Done! - } - - unsigned n = std::min(d_nitems - d_ncopied_items, (uint64_t)wio.outputs()[0].n_items); - - if (n == 0) { - wio.outputs()[0].n_produced = 0; - return work_return_t::OK; - } - - // Do Nothing - - d_ncopied_items += n; - wio.outputs()[0].n_produced = n; - - return work_return_t::OK; -} - -} /* namespace streamops */ -} /* namespace gr */ diff --git a/blocklib/streamops/nop_head/nop_head_cpu.h b/blocklib/streamops/nop_head/nop_head_cpu.h deleted file mode 100644 index 3b167c0bf..000000000 --- a/blocklib/streamops/nop_head/nop_head_cpu.h +++ /dev/null @@ -1,28 +0,0 @@ -/* -*- c++ -*- */ -/* - * This file is part of GNU Radio - * - * SPDX-License-Identifier: GPL-3.0-or-later - * - */ - -#pragma once - -#include <gnuradio/streamops/nop_head.h> - -namespace gr { -namespace streamops { - -class nop_head_cpu : public nop_head -{ -public: - nop_head_cpu(const block_args& args); - work_return_t work(work_io&) override; - -private: - size_t d_nitems; - size_t d_ncopied_items = 0; -}; - -} // namespace streamops -} // namespace gr
\ No newline at end of file diff --git a/blocklib/streamops/probe_signal/probe_signal.yml b/blocklib/streamops/probe_signal/probe_signal.yml deleted file mode 100644 index 909f5748b..000000000 --- a/blocklib/streamops/probe_signal/probe_signal.yml +++ /dev/null @@ -1,34 +0,0 @@ -module: streamops -block: probe_signal -label: Probe Signal -blocktype: sync_block -category: '[Core]/Measurement Tools' - -typekeys: - - id: T - type: class - options: - - cf32 - - rf32 - - ri32 - - ri16 - - ri8 - -parameters: -- id: level - label: Probe Level - dtype: T - gettable: true - cotr: false - -ports: -- domain: stream - id: in - direction: input - type: typekeys/T - -implementations: -- id: cpu -# - id: cuda - -file_format: 1
\ No newline at end of file diff --git a/blocklib/streamops/probe_signal/probe_signal_cpu.cc b/blocklib/streamops/probe_signal/probe_signal_cpu.cc deleted file mode 100644 index 5514ca6b6..000000000 --- a/blocklib/streamops/probe_signal/probe_signal_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 "probe_signal_cpu.h" -#include "probe_signal_cpu_gen.h" - -namespace gr { -namespace streamops { - -template <class T> -probe_signal_cpu<T>::probe_signal_cpu(const typename probe_signal<T>::block_args& args) - : INHERITED_CONSTRUCTORS(T) -{ -} - -template <class T> -work_return_t probe_signal_cpu<T>::work(work_io& wio) - -{ - auto in = wio.inputs()[0].items<T>(); - auto ninput_items = wio.inputs()[0].n_items; - - if (ninput_items > 0) - *this->param_level = in[ninput_items - 1]; - - wio.consume_each(ninput_items); - return work_return_t::OK; -} - -} /* namespace streamops */ -} /* namespace gr */ diff --git a/blocklib/streamops/probe_signal/probe_signal_cpu.h b/blocklib/streamops/probe_signal/probe_signal_cpu.h deleted file mode 100644 index 7d1a9d68b..000000000 --- a/blocklib/streamops/probe_signal/probe_signal_cpu.h +++ /dev/null @@ -1,32 +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/streamops/probe_signal.h> - -namespace gr { -namespace streamops { - -template <class T> -class probe_signal_cpu : public probe_signal<T> -{ -public: - probe_signal_cpu(const typename probe_signal<T>::block_args& args); - - work_return_t work(work_io&) override; - -private: - // Declare private variables here -}; - - -} // namespace streamops -} // namespace gr diff --git a/blocklib/streamops/probe_signal_v/probe_signal_v.yml b/blocklib/streamops/probe_signal_v/probe_signal_v.yml deleted file mode 100644 index 0a42b5ebb..000000000 --- a/blocklib/streamops/probe_signal_v/probe_signal_v.yml +++ /dev/null @@ -1,45 +0,0 @@ -module: streamops -block: probe_signal_v -label: Probe Signal Vector -blocktype: sync_block -category: '[Core]/Measurement Tools' - -doc: - brief: Sink that allows a vector of samples to be grabbed from Python. - -typekeys: - - id: T - type: class - options: - - cf32 - - rf32 - - ri32 - - ri16 - - ri8 - -parameters: -- id: vlen - label: Vec. Length - dtype: size - settable: false -- id: level - label: Constant - dtype: T - gettable: true - container: vector - cotr: false - grc: - hide: all - -ports: -- domain: stream - id: in - direction: input - type: typekeys/T - shape: parameters/vlen - -implementations: -- id: cpu -# - id: cuda - -file_format: 1
\ No newline at end of file diff --git a/blocklib/streamops/probe_signal_v/probe_signal_v_cpu.cc b/blocklib/streamops/probe_signal_v/probe_signal_v_cpu.cc deleted file mode 100644 index b200ada10..000000000 --- a/blocklib/streamops/probe_signal_v/probe_signal_v_cpu.cc +++ /dev/null @@ -1,39 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2005,2010,2012-2013,2018 Free Software Foundation, Inc. - * Copyright 2022 Josh Morman - * - * This file is part of GNU Radio - * - * SPDX-License-Identifier: GPL-3.0-or-later - * - */ - -#include "probe_signal_v_cpu.h" -#include "probe_signal_v_cpu_gen.h" - -namespace gr { -namespace streamops { - -template <class T> -probe_signal_v_cpu<T>::probe_signal_v_cpu( - const typename probe_signal_v<T>::block_args& args) - : INHERITED_CONSTRUCTORS(T), d_vlen(args.vlen), d_level(args.vlen) -{ -} - -template <class T> -work_return_t probe_signal_v_cpu<T>::work(work_io& wio) - -{ - auto in = wio.inputs()[0].items<T>(); - auto ninput_items = wio.inputs()[0].n_items; - - memcpy(d_level.data(), &in[(ninput_items - 1) * d_vlen], d_vlen * sizeof(T)); - - wio.consume_each(ninput_items); - return work_return_t::OK; -} - -} /* namespace streamops */ -} /* namespace gr */ diff --git a/blocklib/streamops/probe_signal_v/probe_signal_v_cpu.h b/blocklib/streamops/probe_signal_v/probe_signal_v_cpu.h deleted file mode 100644 index 28f4beddc..000000000 --- a/blocklib/streamops/probe_signal_v/probe_signal_v_cpu.h +++ /dev/null @@ -1,40 +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/streamops/probe_signal_v.h> - -namespace gr { -namespace streamops { - -template <class T> -class probe_signal_v_cpu : public probe_signal_v<T> -{ -public: - probe_signal_v_cpu(const typename probe_signal_v<T>::block_args& args); - - work_return_t work(work_io&) override; - -private: - // Just work with the private member variable, and pass it out as pmt when queried - void on_parameter_query(param_action_sptr action) override - { - pmtf::pmt param = d_level; - action->set_pmt_value(param); - } - - size_t d_vlen; - std::vector<T> d_level; -}; - - -} // namespace streamops -} // namespace gr diff --git a/blocklib/streamops/selector/selector.yml b/blocklib/streamops/selector/selector.yml deleted file mode 100644 index a179afb3f..000000000 --- a/blocklib/streamops/selector/selector.yml +++ /dev/null @@ -1,67 +0,0 @@ -module: streamops -block: selector -label: Selector -blocktype: block -category: '[Core]/Misc' - -parameters: -- id: num_inputs - label: Num Inputs - dtype: size - settable: false - grc: - hide: part - default: 2 -- id: num_outputs - label: Num Outputs - dtype: size - settable: false - grc: - hide: part - default: 2 -- id: input_index - label: Input Index - dtype: size - settable: true - grc: - default: 0 -- id: output_index - label: Output Index - dtype: size - settable: true - grc: - default: 0 -- id: itemsize - label: Item Size - dtype: size - settable: false - default: 0 - grc: - hide: part -- id: enabled - label: Enabled - dtype: bool - cotr: false - settable: true - default: true - -ports: -- domain: stream - id: in - direction: input - type: untyped - size: parameters/itemsize - multiplicity: parameters/num_inputs - -- domain: stream - id: out - direction: output - type: untyped - size: parameters/itemsize - multiplicity: parameters/num_outputs - -implementations: -- id: cpu -# - id: cuda - -file_format: 1 diff --git a/blocklib/streamops/selector/selector_cpu.cc b/blocklib/streamops/selector/selector_cpu.cc deleted file mode 100644 index 3d4d3522c..000000000 --- a/blocklib/streamops/selector/selector_cpu.cc +++ /dev/null @@ -1,63 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2022 Josh Morman - * - * This file is part of GNU Radio - * - * SPDX-License-Identifier: GPL-3.0-or-later - * - */ - -#include "selector_cpu.h" -#include "selector_cpu_gen.h" - -namespace gr { -namespace streamops { - -selector_cpu::selector_cpu(block_args args) - : INHERITED_CONSTRUCTORS, - d_itemsize(args.itemsize), - d_num_inputs(args.num_inputs), - d_num_outputs(args.num_outputs) -{ - set_tag_propagation_policy(gr::tag_propagation_policy_t::TPP_CUSTOM); -} - -work_return_t selector_cpu::work(work_io& wio) - -{ - auto input_index = pmtf::get_as<size_t>(*this->param_input_index); - auto output_index = pmtf::get_as<size_t>(*this->param_output_index); - auto enabled = pmtf::get_as<bool>(*this->param_enabled); - auto in = wio.inputs()[input_index].items<uint8_t>(); - auto out = wio.outputs()[output_index].items<uint8_t>(); - auto noutput_items = - std::min(wio.inputs()[input_index].n_items, wio.outputs()[output_index].n_items); - - if (d_itemsize == 0) { - d_itemsize = wio.outputs()[output_index].buf().item_size(); - } - - if (enabled) { - auto nread = wio.inputs()[input_index].nitems_read(); - auto nwritten = wio.outputs()[output_index].nitems_written(); - - auto tags = - wio.inputs()[input_index].tags_in_window(nread, nread + noutput_items); - - for (auto tag : tags) { - tag.set_offset(tag.offset() - (nread - nwritten)); - wio.outputs()[output_index].add_tag(tag); - } - - std::copy(in, in + noutput_items * d_itemsize, out); - wio.outputs()[output_index].n_produced = noutput_items; - } - - wio.consume_each(noutput_items); - return work_return_t::OK; -} - - -} // namespace streamops -} // namespace gr
\ No newline at end of file diff --git a/blocklib/streamops/selector/selector_cpu.h b/blocklib/streamops/selector/selector_cpu.h deleted file mode 100644 index 6065512a4..000000000 --- a/blocklib/streamops/selector/selector_cpu.h +++ /dev/null @@ -1,30 +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/streamops/selector.h> - -namespace gr { -namespace streamops { - -class selector_cpu : public virtual selector -{ -public: - selector_cpu(block_args args); - work_return_t work(work_io&) override; - -private: - size_t d_itemsize = 0; - size_t d_num_inputs, d_num_outputs; -}; - -} // namespace streamops -} // namespace gr
\ No newline at end of file diff --git a/blocklib/streamops/stream_to_streams/stream_to_streams.yml b/blocklib/streamops/stream_to_streams/stream_to_streams.yml deleted file mode 100644 index 496a8c762..000000000 --- a/blocklib/streamops/stream_to_streams/stream_to_streams.yml +++ /dev/null @@ -1,38 +0,0 @@ -module: streamops -block: stream_to_streams -label: Stream To Streams -blocktype: block -category: '[Core]/Stream Operators' - -parameters: -- id: nstreams - label: Number of Streams - dtype: size - settable: false -- id: itemsize - label: Item Size - dtype: size - settable: false - default: 0 - grc: - hide: part - -ports: -- domain: stream - id: in - direction: input - type: untyped - size: parameters/itemsize - -- domain: stream - id: out - direction: output - type: untyped - size: parameters/itemsize - multiplicity: parameters/nstreams - -implementations: -- id: cpu -- id: cuda - -file_format: 1 diff --git a/blocklib/streamops/stream_to_streams/stream_to_streams_cpu.cc b/blocklib/streamops/stream_to_streams/stream_to_streams_cpu.cc deleted file mode 100644 index 591fb67dd..000000000 --- a/blocklib/streamops/stream_to_streams/stream_to_streams_cpu.cc +++ /dev/null @@ -1,49 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2012 Free Software Foundation, Inc. - * - * This file is part of GNU Radio - * - * SPDX-License-Identifier: GPL-3.0-or-later - * - */ - -#include "stream_to_streams_cpu.h" -#include "stream_to_streams_cpu_gen.h" -#include <volk/volk.h> - -namespace gr { -namespace streamops { - -stream_to_streams_cpu::stream_to_streams_cpu(const block_args& args) - : INHERITED_CONSTRUCTORS -{ -} - -work_return_t stream_to_streams_cpu::work(work_io& wio) -{ - auto in = wio.inputs()[0].items<uint8_t>(); - - uint8_t* in_ptr = const_cast<uint8_t*>(in); - auto noutput_items = wio.outputs()[0].n_items; - auto ninput_items = wio.inputs()[0].n_items; - size_t nstreams = wio.outputs().size(); - - auto total_items = std::min(ninput_items / nstreams, (size_t)noutput_items); - auto itemsize = wio.outputs()[0].buf().item_size(); - - for (size_t i = 0; i < total_items; i++) { - for (size_t j = 0; j < nstreams; j++) { - memcpy(wio.outputs()[j].items<uint8_t>() + i * itemsize, in_ptr, itemsize); - in_ptr += itemsize; - } - } - - wio.produce_each(total_items); - wio.consume_each(total_items * nstreams); - return work_return_t::OK; -} - - -} /* namespace streamops */ -} /* namespace gr */ diff --git a/blocklib/streamops/stream_to_streams/stream_to_streams_cpu.h b/blocklib/streamops/stream_to_streams/stream_to_streams_cpu.h deleted file mode 100644 index bc601044d..000000000 --- a/blocklib/streamops/stream_to_streams/stream_to_streams_cpu.h +++ /dev/null @@ -1,28 +0,0 @@ -/* -*- c++ -*- */ -/* - * 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/streamops/stream_to_streams.h> - -namespace gr { -namespace streamops { - -class stream_to_streams_cpu : public stream_to_streams -{ -public: - stream_to_streams_cpu(const block_args& args); - - work_return_t work(work_io&) override; -}; - - -} // namespace streamops -} // namespace gr diff --git a/blocklib/streamops/stream_to_streams/stream_to_streams_cuda.cc b/blocklib/streamops/stream_to_streams/stream_to_streams_cuda.cc deleted file mode 100644 index d5b7d418f..000000000 --- a/blocklib/streamops/stream_to_streams/stream_to_streams_cuda.cc +++ /dev/null @@ -1,57 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2021 Josh Morman - * - * This file is part of GNU Radio - * - * SPDX-License-Identifier: GPL-3.0-or-later - * - */ - -#include "stream_to_streams_cuda.h" -#include "stream_to_streams_cuda_gen.h" -#include <gnuradio/helper_cuda.h> -#include <volk/volk.h> - -namespace gr { -namespace streamops { - -stream_to_streams_cuda::stream_to_streams_cuda(const block_args& args) - : INHERITED_CONSTRUCTORS, d_nstreams(args.nstreams) -{ - d_out_items.resize(args.nstreams); - cudaStreamCreate(&d_stream); -} - -work_return_t stream_to_streams_cuda::work(work_io& wio) - -{ - auto noutput_items = wio.outputs()[0].n_items; - auto ninput_items = wio.inputs()[0].n_items; - size_t nstreams = wio.outputs().size(); - auto itemsize = wio.outputs()[0].buf().item_size(); - - if (!p_kernel) { - p_kernel = - std::make_shared<cusp::deinterleave>((int)d_nstreams, 1, (int)itemsize); - p_kernel->set_stream(d_stream); - } - - - auto total_items = std::min(ninput_items / nstreams, (size_t)noutput_items); - - d_out_items = wio.all_output_ptrs(); - - p_kernel->launch_default_occupancy({ wio.inputs()[0].items<uint8_t>() }, - d_out_items, - itemsize * total_items * nstreams); - cudaStreamSynchronize(d_stream); - - wio.produce_each(total_items); - wio.consume_each(total_items * nstreams); - return work_return_t::OK; -} - - -} /* namespace streamops */ -} /* namespace gr */ diff --git a/blocklib/streamops/stream_to_streams/stream_to_streams_cuda.h b/blocklib/streamops/stream_to_streams/stream_to_streams_cuda.h deleted file mode 100644 index 8d7608d05..000000000 --- a/blocklib/streamops/stream_to_streams/stream_to_streams_cuda.h +++ /dev/null @@ -1,37 +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/streamops/stream_to_streams.h> -#include <cusp/deinterleave.cuh> - -namespace gr { -namespace streamops { - -class stream_to_streams_cuda : public stream_to_streams -{ -public: - stream_to_streams_cuda(const block_args& args); - - work_return_t work(work_io&) override; - -private: - size_t d_nstreams; - - std::vector<void*> d_out_items; - - std::shared_ptr<cusp::deinterleave> p_kernel; - cudaStream_t d_stream; -}; - - -} // namespace streamops -} // namespace gr diff --git a/blocklib/streamops/test/meson.build b/blocklib/streamops/test/meson.build index a301e1ad7..71b2b5f3b 100644 --- a/blocklib/streamops/test/meson.build +++ b/blocklib/streamops/test/meson.build @@ -4,9 +4,4 @@ if GR_ENABLE_PYTHON test('qa_delay', py3, args : files('qa_delay.py'), env: TEST_ENV) - test('qa_type_conversions', py3, args : files('qa_type_conversions.py'), env: TEST_ENV) - test('qa_keep_m_in_n', py3, args : files('qa_keep_m_in_n.py'), env: TEST_ENV) - test('qa_probe_signal', py3, args : files('qa_probe_signal.py'), env: TEST_ENV) - test('qa_interleave', py3, args : files('qa_interleave.py'), env: TEST_ENV) - test('qa_selector', py3, args : files('qa_selector.py'), env: TEST_ENV) endif diff --git a/blocklib/streamops/test/qa_interleave.py b/blocklib/streamops/test/qa_interleave.py deleted file mode 100644 index 08eabdfcb..000000000 --- a/blocklib/streamops/test/qa_interleave.py +++ /dev/null @@ -1,138 +0,0 @@ -#!/usr/bin/env python -# -# Copyright 2004,2007,2010,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, blocks, streamops - - -class test_interleave (gr_unittest.TestCase): - - def setUp(self): - self.tb = gr.top_block() - - def tearDown(self): - self.tb = None - - def test_int_001(self): - lenx = 64 - src0 = blocks.vector_source_f(list(range(0, lenx, 4))) - src1 = blocks.vector_source_f(list(range(1, lenx, 4))) - src2 = blocks.vector_source_f(list(range(2, lenx, 4))) - src3 = blocks.vector_source_f(list(range(3, lenx, 4))) - op = streamops.interleave(gr.sizeof_float) - dst = blocks.vector_sink_f() - - self.tb.connect((src0, 0), (op, 0)) - self.tb.connect((src1, 0), (op, 1)) - self.tb.connect((src2, 0), (op, 2)) - self.tb.connect((src3, 0), (op, 3)) - self.tb.connect(op, dst) - self.tb.run() - expected_result = tuple(range(lenx)) - result_data = dst.data() - self.assertFloatTuplesAlmostEqual(expected_result, result_data) - - def test_int_002(self): - blksize = 4 - lenx = 64 - def plusup_big(a): return a + (blksize * 4) - def plusup_little(a): return a + blksize - a_vec = list(range(0, blksize)) - for i in range(0, (lenx // (4 * blksize)) - 1): - a_vec += list(map(plusup_big, a_vec[len(a_vec) - blksize:])) - - b_vec = list(map(plusup_little, a_vec)) - c_vec = list(map(plusup_little, b_vec)) - d_vec = list(map(plusup_little, c_vec)) - - src0 = blocks.vector_source_f(a_vec) - src1 = blocks.vector_source_f(b_vec) - src2 = blocks.vector_source_f(c_vec) - src3 = blocks.vector_source_f(d_vec) - op = streamops.interleave(gr.sizeof_float, blksize) - dst = blocks.vector_sink_f() - - self.tb.connect((src0, 0), (op, 0)) - self.tb.connect((src1, 0), (op, 1)) - self.tb.connect((src2, 0), (op, 2)) - self.tb.connect((src3, 0), (op, 3)) - self.tb.connect(op, dst) - self.tb.run() - expected_result = tuple(range(lenx)) - result_data = dst.data() - - self.assertFloatTuplesAlmostEqual(expected_result, result_data) - - def test_deint_001(self): - lenx = 64 - src = blocks.vector_source_f(list(range(lenx))) - op = streamops.deinterleave(gr.sizeof_float) - dst0 = blocks.vector_sink_f() - dst1 = blocks.vector_sink_f() - dst2 = blocks.vector_sink_f() - dst3 = blocks.vector_sink_f() - - self.tb.connect(src, op) - self.tb.connect((op, 0), (dst0, 0)) - self.tb.connect((op, 1), (dst1, 0)) - self.tb.connect((op, 2), (dst2, 0)) - self.tb.connect((op, 3), (dst3, 0)) - self.tb.run() - - expected_result0 = tuple(range(0, lenx, 4)) - expected_result1 = tuple(range(1, lenx, 4)) - expected_result2 = tuple(range(2, lenx, 4)) - expected_result3 = tuple(range(3, lenx, 4)) - - self.assertFloatTuplesAlmostEqual(expected_result0, dst0.data()) - self.assertFloatTuplesAlmostEqual(expected_result1, dst1.data()) - self.assertFloatTuplesAlmostEqual(expected_result2, dst2.data()) - self.assertFloatTuplesAlmostEqual(expected_result3, dst3.data()) - - def test_deint_002(self): - blksize = 4 - lenx = 64 - src = blocks.vector_source_f(list(range(lenx))) - op = streamops.deinterleave(gr.sizeof_float, blksize) - dst0 = blocks.vector_sink_f() - dst1 = blocks.vector_sink_f() - dst2 = blocks.vector_sink_f() - dst3 = blocks.vector_sink_f() - - self.tb.connect(src, op) - self.tb.connect((op, 0), (dst0, 0)) - self.tb.connect((op, 1), (dst1, 0)) - self.tb.connect((op, 2), (dst2, 0)) - self.tb.connect((op, 3), (dst3, 0)) - self.tb.run() - - def plusup_big(a): return a + (blksize * 4) - def plusup_little(a): return a + blksize - a_vec = list(range(0, blksize)) - for i in range(0, (lenx // (4 * blksize)) - 1): - a_vec += list(map(plusup_big, a_vec[len(a_vec) - blksize:])) - - b_vec = list(map(plusup_little, a_vec)) - c_vec = list(map(plusup_little, b_vec)) - d_vec = list(map(plusup_little, c_vec)) - - expected_result0 = tuple(a_vec) - expected_result1 = tuple(b_vec) - expected_result2 = tuple(c_vec) - expected_result3 = tuple(d_vec) - - self.assertFloatTuplesAlmostEqual(expected_result0, dst0.data()) - self.assertFloatTuplesAlmostEqual(expected_result1, dst1.data()) - self.assertFloatTuplesAlmostEqual(expected_result2, dst2.data()) - self.assertFloatTuplesAlmostEqual(expected_result3, dst3.data()) - - -if __name__ == '__main__': - gr_unittest.run(test_interleave) diff --git a/blocklib/streamops/test/qa_keep_m_in_n.py b/blocklib/streamops/test/qa_keep_m_in_n.py deleted file mode 100644 index a3f4fdc17..000000000 --- a/blocklib/streamops/test/qa_keep_m_in_n.py +++ /dev/null @@ -1,94 +0,0 @@ -#!/usr/bin/env python -# -# Copyright 2008,2010,2012,2013,2018,2022 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, blocks, streamops - -import sys -import random - - -class test_keep_m_in_n(gr_unittest.TestCase): - - def setUp(self): - random.seed(0) - - def tearDown(self): - pass - - def test_001(self): - self.maxDiff = None - tb = gr.top_block() - src = blocks.vector_source_c(list(range(0, 100))) - - # itemsize, M, N, offset - km2 = streamops.keep_m_in_n(1, 2, 0) - km3 = streamops.keep_m_in_n(1, 3, 1) - km7 = streamops.keep_m_in_n(1, 7, 2) - snk2 = blocks.vector_sink_c() - snk3 = blocks.vector_sink_c() - snk7 = blocks.vector_sink_c() - tb.connect((src, km2, snk2)) - tb.connect((src, km3, snk3)) - tb.connect((src, km7, snk7)) - tb.run() - - self.assertEqual(list(range(0, 100, 2)), list(snk2.data())) - self.assertEqual(list(range(1, 100, 3)), list(snk3.data())) - self.assertEqual(list(range(2, 100, 7)), list(snk7.data())) - - def test_002(self): - self.maxDiff = None - tb = gr.top_block() - src = blocks.vector_source_f(list(range(0, 100))) - - km = [] - snk = [] - for i in range(5): - km.append(streamops.keep_m_in_n(3, 5, i)) - snk.append(blocks.vector_sink_f()) - tb.connect((src, km[i], snk[i])) - tb.run() - - for i in range(5): - self.assertEqual( - sorted( - list(range(i, 100, 5)) + - list(range((i + 1) % 5, 100, 5)) + - list(range((i + 2) % 5, 100, 5)) - ), - list(snk[i].data()) - ) - - def test_003(self): - with self.assertRaises(RuntimeError) as cm: - streamops.keep_m_in_n(0, 5, 0) - self.assertEqual(str(cm.exception), 'm=0 but must be > 0') - - with self.assertRaises(RuntimeError) as cm: - streamops.keep_m_in_n(5, 0, 0) - self.assertEqual(str(cm.exception), 'n=0 but must be > 0') - - with self.assertRaises(RuntimeError) as cm: - streamops.keep_m_in_n(6, 5, 0) - self.assertEqual(str(cm.exception), 'm = 6 ≤ 5 = n') - - # with self.assertRaises(RuntimeError) as cm: - # streamops.keep_m_in_n(2, 5, -1) - # self.assertEqual(str(cm.exception), - # 'offset -1 but must be >= 0') - - with self.assertRaises(RuntimeError) as cm: - streamops.keep_m_in_n(2, 5, 5) - self.assertEqual(str(cm.exception), 'offset = 5 < 5 = n') - - -if __name__ == '__main__': - gr_unittest.run(test_keep_m_in_n) diff --git a/blocklib/streamops/test/qa_probe_signal.py b/blocklib/streamops/test/qa_probe_signal.py deleted file mode 100644 index 85293bf9b..000000000 --- a/blocklib/streamops/test/qa_probe_signal.py +++ /dev/null @@ -1,92 +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, blocks, streamops - - -class test_probe_signal(gr_unittest.TestCase): - - def setUp(self): - self.tb = gr.top_block() - - def tearDown(self): - self.tb = None - - def test_001(self): - value = 12.3 - repeats = 100 - src_data = [value] * repeats - - src = blocks.vector_source_f(src_data) - dst = streamops.probe_signal_f() - - self.tb.connect(src, dst) - self.tb.run() - output = dst.level() - self.assertAlmostEqual(value, output, places=6) - - def test_002(self): - vector_length = 10 - repeats = 10 - value = [0.5 + i for i in range(0, vector_length)] - src_data = value * repeats - - src = blocks.vector_source_f(src_data, vlen=vector_length) - dst = streamops.probe_signal_v_f(vector_length) - - self.tb.connect(src, dst) - self.tb.run() - output = dst.level() - self.assertEqual(len(output), vector_length) - self.assertAlmostEqual(value[3], output[3], places=6) - - def test_003_race_condition_regression_test(self): - src = blocks.vector_source_c([1 + 2j, 3 + 4j], True) - dst = streamops.probe_signal_c() - - self.tb.connect(src, dst) - self.tb.start() - - while dst.level() == 0.0: - continue - - for _ in range(100000): - output = dst.level() - self.assertIn(output, [1 + 2j, 3 + 4j]) - - self.tb.stop() - self.tb.wait() - - def test_004_race_condition_regression_test_vector(self): - vector_length = 10 - src_data = [1.0] * vector_length + [2.0] * vector_length - - src = blocks.vector_source_f(src_data, True, vector_length) - dst = streamops.probe_signal_v_f(vector_length) - - self.tb.connect(src, dst) - self.tb.start() - - while dst.level()[0] == 0.0: - continue - - for _ in range(10000): - output = dst.level() - self.assertIn(output[0], [1.0, 2.0]) - for i in range(1, vector_length): - self.assertEqual(output[0], output[i]) - - self.tb.stop() - self.tb.wait() - - -if __name__ == '__main__': - gr_unittest.run(test_probe_signal) diff --git a/blocklib/streamops/test/qa_selector.py b/blocklib/streamops/test/qa_selector.py deleted file mode 100644 index 5a18655c2..000000000 --- a/blocklib/streamops/test/qa_selector.py +++ /dev/null @@ -1,221 +0,0 @@ -#!/usr/bin/env python -# -# Copyright 2019 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, blocks, streamops - - -class test_selector(gr_unittest.TestCase): - - def setUp(self): - self.tb = gr.top_block() - - def tearDown(self): - self.tb = None - - def test_select_same(self): - src_data = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] - expected_result = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] - expected_drop = () - - num_inputs = 4 - num_outputs = 4 - input_index = 1 - output_index = 2 - - op = streamops.selector(num_inputs, num_outputs, input_index, output_index) - - src = [] - dst = [] - for ii in range(num_inputs): - src.append(blocks.vector_source_b(src_data)) - self.tb.connect((src[ii], 0), (op, ii)) - for jj in range(num_outputs): - dst.append(blocks.vector_sink_b()) - self.tb.connect((op, jj), (dst[jj], 0)) - - self.tb.run() - - dst_data = dst[output_index].data() - - self.assertEqual(expected_result, dst_data) - - def test_select_input(self): - - num_inputs = 4 - num_outputs = 4 - input_index = 1 - output_index = 2 - - op = streamops.selector(num_inputs, num_outputs, input_index, output_index) - - src = [] - dst = [] - for ii in range(num_inputs): - src_data = [ii + 1] * 10 - src.append(blocks.vector_source_b(src_data)) - self.tb.connect((src[ii], 0), (op, ii)) - for jj in range(num_outputs): - dst.append(blocks.vector_sink_b()) - self.tb.connect((op, jj), (dst[jj], 0)) - - self.tb.run() - - expected_result = [input_index + 1] * 10 - dst_data = list(dst[output_index].data()) - - self.assertEqual(expected_result, dst_data) - - def test_dump(self): - - num_inputs = 4 - num_outputs = 4 - input_index = 1 - output_index = 2 - output_not_selected = 3 - - op = streamops.selector(num_inputs, num_outputs, input_index, output_index) - - src = [] - dst = [] - for ii in range(num_inputs): - src_data = [ii + 1] * 10 - src.append(blocks.vector_source_b(src_data)) - self.tb.connect((src[ii], 0), (op, ii)) - for jj in range(num_outputs): - dst.append(blocks.vector_sink_b()) - self.tb.connect((op, jj), (dst[jj],0)) - - self.tb.run() - - expected_result = [] - dst_data = list(dst[output_not_selected].data()) - - self.assertEqual(expected_result, dst_data) - - def test_not_enabled(self): - src_data = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] - expected_result = [] - - num_inputs = 4 - num_outputs = 4 - input_index = 1 - output_index = 2 - - op = streamops.selector(num_inputs, num_outputs, input_index, output_index) - op.set_enabled(False) - - src = [] - dst = [] - for ii in range(num_inputs): - src.append(blocks.vector_source_b(src_data)) - self.tb.connect((src[ii], 0), (op, ii)) - for jj in range(num_outputs): - dst.append(blocks.vector_sink_b()) - self.tb.connect((op, jj), (dst[jj], 0)) - - self.tb.run() - - dst_data = dst[output_index].data() - self.assertEqual(expected_result, dst_data) - - # These tests cannot be run as set_index can only be called after check_topology is called - def test_set_indices(self): - - num_inputs = 4; num_outputs = 4 - input_index = 1; output_index = 2 - - op = streamops.selector(num_inputs, num_outputs, 0, 0) - - src = [] - dst = [] - for ii in range(num_inputs): - src_data = [ii+1]*10 - src.append( blocks.vector_source_b(src_data)) - self.tb.connect((src[ii], 0), (op,ii)) - for jj in range(num_outputs): - dst.append(blocks.vector_sink_b()) - self.tb.connect((op,jj),(dst[jj], 0)) - - op.set_input_index(input_index) - op.set_output_index(output_index) - - self.tb.run() - - expected_result = [input_index+1]*10 - dst_data = list(dst[output_index].data()) - - self.assertEqual(expected_result, dst_data) - - def test_dont_set_indices(self): - - num_inputs = 4; num_outputs = 4 - input_index = 1; output_index = 2 - - op = streamops.selector(num_inputs, num_outputs, 0, 0) - #op.set_input_index(input_index) - #op.set_output_index(output_index) - - src = [] - dst = [] - for ii in range(num_inputs): - src_data = [ii+1]*10 - src.append( blocks.vector_source_b(src_data)) - self.tb.connect((src[ii], 0), (op,ii)) - for jj in range(num_outputs): - dst.append(blocks.vector_sink_b()) - self.tb.connect((op,jj),(dst[jj], 0)) - - self.tb.run() - - expected_result = [input_index+1]*10 - dst_data = list(dst[output_index].data()) - - self.assertNotEqual(expected_result, dst_data) - - def test_float_vector(self): - - num_inputs = 4 - num_outputs = 4 - input_index = 1 - output_index = 2 - - veclen = 3 - - op = streamops.selector( - num_inputs, - num_outputs, - input_index, - output_index) - - src = [] - dst = [] - for ii in range(num_inputs): - src_data = [float(ii) + 1] * 10 * veclen - src.append( - blocks.vector_source_f( - src_data, - repeat=False, - vlen=veclen)) - self.tb.connect((src[ii], 0), (op, ii)) - for jj in range(num_outputs): - dst.append(blocks.vector_sink_f(vlen=veclen)) - self.tb.connect((op, jj), (dst[jj], 0)) - - self.tb.run() - - expected_result = [float(input_index) + 1] * 10 * veclen - dst_data = list(dst[output_index].data()) - - self.assertEqual(expected_result, dst_data) - - -if __name__ == '__main__': - gr_unittest.run(test_selector) diff --git a/blocklib/streamops/test/qa_type_conversions.py b/blocklib/streamops/test/qa_type_conversions.py deleted file mode 100644 index ac50f870f..000000000 --- a/blocklib/streamops/test/qa_type_conversions.py +++ /dev/null @@ -1,321 +0,0 @@ -#!/usr/bin/env python3 -# -# 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, blocks, streamops - -# from math import sqrt, atan2 - - -class test_type_conversions(gr_unittest.TestCase): - - def setUp(self): - self.tb = gr.flowgraph() - self.rt = gr.runtime() - - def tearDown(self): - self.tb = None - self.rt = None - - # def test_char_to_float_identity(self): - # src_data = (1, 2, 3, 4, 5) - # expected_data = [1.0, 2.0, 3.0, 4.0, 5.0] - # src = blocks.vector_source_b(src_data) - # op = blocks.char_to_float() - # dst = blocks.vector_sink_f() - # self.tb.connect(src, op, dst) - # self.tb.run() - # self.assertFloatTuplesAlmostEqual(expected_data, dst.data()) - - # def test_char_to_float_scale(self): - # src_data = (1, 2, 3, 4, 5) - # expected_data = [0.5, 1.0, 1.5, 2.0, 2.5] - # src = blocks.vector_source_b(src_data) - # op = blocks.char_to_float(scale=2.0) - # dst = blocks.vector_sink_f() - # self.tb.connect(src, op, dst) - # self.tb.run() - # self.assertFloatTuplesAlmostEqual(expected_data, dst.data()) - - # def test_char_to_short(self): - # src_data = (1, 2, 3, 4, 5) - # expected_data = [256, 512, 768, 1024, 1280] - # src = blocks.vector_source_b(src_data) - # op = blocks.char_to_short() - # dst = blocks.vector_sink_s() - # self.tb.connect(src, op, dst) - # self.tb.run() - # self.assertEqual(expected_data, dst.data()) - - # def test_complex_to_interleaved_char(self): - # src_data = (1 + 2j, 3 + 4j, 5 + 6j, 7 + 8j, 9 + 10j) - # expected_data = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] - # src = blocks.vector_source_c(src_data) - # op = blocks.complex_to_interleaved_char() - # dst = blocks.vector_sink_b() - # self.tb.connect(src, op, dst) - # self.tb.run() - # self.assertEqual(expected_data, dst.data()) - - # def test_complex_to_interleaved_short(self): - # src_data = (1 + 2j, 3 + 4j, 5 + 6j, 7 + 8j, 9 + 10j) - # expected_data = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] - # src = blocks.vector_source_c(src_data) - # op = blocks.complex_to_interleaved_short() - # dst = blocks.vector_sink_s() - # self.tb.connect(src, op, dst) - # self.tb.run() - # self.assertEqual(expected_data, dst.data()) - - # def test_complex_to_float_1(self): - # src_data = (1 + 2j, 3 + 4j, 5 + 6j, 7 + 8j, 9 + 10j) - # expected_data = [1.0, 3.0, 5.0, 7.0, 9.0] - # src = blocks.vector_source_c(src_data) - # op = blocks.complex_to_float() - # dst = blocks.vector_sink_f() - # self.tb.connect(src, op, dst) - # self.tb.run() - # self.assertFloatTuplesAlmostEqual(expected_data, dst.data()) - - # def test_complex_to_float_2(self): - # src_data = (1 + 2j, 3 + 4j, 5 + 6j, 7 + 8j, 9 + 10j) - # expected_data1 = [1.0, 3.0, 5.0, 7.0, 9.0] - # expected_data2 = [2.0, 4.0, 6.0, 8.0, 10.0] - # src = blocks.vector_source_c(src_data) - # op = blocks.complex_to_float() - # dst1 = blocks.vector_sink_f() - # dst2 = blocks.vector_sink_f() - # self.tb.connect(src, op) - # self.tb.connect((op, 0), dst1) - # self.tb.connect((op, 1), dst2) - # self.tb.run() - # self.assertFloatTuplesAlmostEqual(expected_data1, dst1.data()) - # self.assertFloatTuplesAlmostEqual(expected_data2, dst2.data()) - - # def test_complex_to_real(self): - # src_data = (1 + 2j, 3 + 4j, 5 + 6j, 7 + 8j, 9 + 10j) - # expected_data = [1.0, 3.0, 5.0, 7.0, 9.0] - # src = blocks.vector_source_c(src_data) - # op = blocks.complex_to_real() - # dst = blocks.vector_sink_f() - # self.tb.connect(src, op, dst) - # self.tb.run() - # self.assertFloatTuplesAlmostEqual(expected_data, dst.data()) - - # def test_complex_to_imag(self): - # src_data = (1 + 2j, 3 + 4j, 5 + 6j, 7 + 8j, 9 + 10j) - # expected_data = [2.0, 4.0, 6.0, 8.0, 10.0] - # src = blocks.vector_source_c(src_data) - # op = blocks.complex_to_imag() - # dst = blocks.vector_sink_f() - # self.tb.connect(src, op, dst) - # self.tb.run() - # self.assertFloatTuplesAlmostEqual(expected_data, dst.data()) - - # def test_complex_to_mag(self): - # src_data = (1 + 2j, 3 - 4j, 5 + 6j, 7 - 8j, -9 + 10j) - # expected_data = [sqrt(5), sqrt(25), sqrt(61), sqrt(113), sqrt(181)] - # src = blocks.vector_source_c(src_data) - # op = blocks.complex_to_mag() - # dst = blocks.vector_sink_f() - # self.tb.connect(src, op, dst) - # self.tb.run() - # self.assertFloatTuplesAlmostEqual(expected_data, dst.data(), 5) - - # def test_complex_to_mag_squared(self): - # src_data = (1 + 2j, 3 - 4j, 5 + 6j, 7 - 8j, -9 + 10j) - # expected_data = [5.0, 25.0, 61.0, 113.0, 181.0] - # src = blocks.vector_source_c(src_data) - # op = blocks.complex_to_mag_squared() - # dst = blocks.vector_sink_f() - # self.tb.connect(src, op, dst) - # self.tb.run() - # self.assertFloatTuplesAlmostEqual(expected_data, dst.data()) - - # def test_complex_to_arg(self): - # src_data = (1 + 2j, 3 - 4j, 5 + 6j, 7 - 8j, -9 + 10j) - # expected_data = [atan2(2, 1), atan2(-4, 3), - # atan2(6, 5), atan2(-8, 7), atan2(10, -9)] - # src = blocks.vector_source_c(src_data) - # op = blocks.complex_to_arg() - # dst = blocks.vector_sink_f() - # self.tb.connect(src, op, dst) - # self.tb.run() - # self.assertFloatTuplesAlmostEqual(expected_data, dst.data(), 2) - - # def test_float_to_char_identity(self): - # src_data = (1.0, 2.0, 3.0, 4.0, 5.0) - # expected_data = [1, 2, 3, 4, 5] - # src = blocks.vector_source_f(src_data) - # op = blocks.float_to_char() - # dst = blocks.vector_sink_b() - # self.tb.connect(src, op, dst) - # self.tb.run() - # self.assertEqual(expected_data, dst.data()) - - # def test_float_to_char_scale(self): - # src_data = (1.0, 2.0, 3.0, 4.0, 5.0) - # expected_data = [5, 10, 15, 20, 25] - # src = blocks.vector_source_f(src_data) - # op = blocks.float_to_char(1, 5) - # dst = blocks.vector_sink_b() - # self.tb.connect(src, op, dst) - # self.tb.run() - # self.assertEqual(expected_data, dst.data()) - - # def test_float_to_complex_1(self): - # src_data = (1.0, 3.0, 5.0, 7.0, 9.0) - # expected_data = [1 + 0j, 3 + 0j, 5 + 0j, 7 + 0j, 9 + 0j] - # src = blocks.vector_source_f(src_data) - # op = blocks.float_to_complex() - # dst = blocks.vector_sink_c() - # self.tb.connect(src, op, dst) - # self.tb.run() - # self.assertFloatTuplesAlmostEqual(expected_data, dst.data()) - - # def test_float_to_complex_2(self): - # src1_data = (1.0, 3.0, 5.0, 7.0, 9.0) - # src2_data = (2.0, 4.0, 6.0, 8.0, 10.0) - # expected_data = [1 + 2j, 3 + 4j, 5 + 6j, 7 + 8j, 9 + 10j] - # src1 = blocks.vector_source_f(src1_data) - # src2 = blocks.vector_source_f(src2_data) - # op = blocks.float_to_complex() - # dst = blocks.vector_sink_c() - # self.tb.connect(src1, (op, 0)) - # self.tb.connect(src2, (op, 1)) - # self.tb.connect(op, dst) - # self.tb.run() - # self.assertFloatTuplesAlmostEqual(expected_data, dst.data()) - - # def test_float_to_int_identity(self): - # src_data = (1.0, 2.0, 3.0, 4.0, 5.0) - # expected_data = [1, 2, 3, 4, 5] - # src = blocks.vector_source_f(src_data) - # op = blocks.float_to_int() - # dst = blocks.vector_sink_i() - # self.tb.connect(src, op, dst) - # self.tb.run() - # self.assertEqual(expected_data, dst.data()) - - # def test_float_to_int_scale(self): - # src_data = (1.0, 2.0, 3.0, 4.0, 5.0) - # expected_data = [5, 10, 15, 20, 25] - # src = blocks.vector_source_f(src_data) - # op = blocks.float_to_int(1, 5) - # dst = blocks.vector_sink_i() - # self.tb.connect(src, op, dst) - # self.tb.run() - # self.assertEqual(expected_data, dst.data()) - - # def test_float_to_short_identity(self): - # src_data = (1.0, 2.0, 3.0, 4.0, 5.0) - # expected_data = [1, 2, 3, 4, 5] - # src = blocks.vector_source_f(src_data) - # op = blocks.float_to_short() - # dst = blocks.vector_sink_s() - # self.tb.connect(src, op, dst) - # self.tb.run() - # self.assertEqual(expected_data, dst.data()) - - # def test_float_to_short_scale(self): - # src_data = (1.0, 2.0, 3.0, 4.0, 5.0) - # expected_data = [5, 10, 15, 20, 25] - # src = blocks.vector_source_f(src_data) - # op = blocks.float_to_short(1, 5) - # dst = blocks.vector_sink_s() - # self.tb.connect(src, op, dst) - # self.tb.run() - # self.assertEqual(expected_data, dst.data()) - - # def test_float_to_uchar(self): - # src_data = (1.0, -2.0, 3.0, -4.0, 256.0) - # expected_data = [1, 0, 3, 0, 255] - # src = blocks.vector_source_f(src_data) - # op = blocks.float_to_uchar() - # dst = blocks.vector_sink_b() - # self.tb.connect(src, op, dst) - # self.tb.run() - # self.assertEqual(expected_data, dst.data()) - - # def test_int_to_float_identity(self): - # src_data = (1, 2, 3, 4, 5) - # expected_data = [1.0, 2.0, 3.0, 4.0, 5.0] - # src = blocks.vector_source_i(src_data) - # op = blocks.int_to_float() - # dst = blocks.vector_sink_f() - # self.tb.connect(src, op, dst) - # self.tb.run() - # self.assertFloatTuplesAlmostEqual(expected_data, dst.data()) - - # def test_int_to_float_scale(self): - # src_data = (1, 2, 3, 4, 5) - # expected_data = [0.2, 0.4, 0.6, 0.8, 1.0] - # src = blocks.vector_source_i(src_data) - # op = blocks.int_to_float(1, 5) - # dst = blocks.vector_sink_f() - # self.tb.connect(src, op, dst) - # self.tb.run() - # self.assertFloatTuplesAlmostEqual(expected_data, dst.data()) - - def test_interleaved_short_to_complex(self): - src_data = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10) - expected_data = [1 + 2j, 3 + 4j, 5 + 6j, 7 + 8j, 9 + 10j] - src = blocks.vector_source_s(src_data, vlen=2) - op = streamops.interleaved_short_to_complex() - dst = blocks.vector_sink_c() - self.tb.connect(src, op) - self.tb.connect(op, dst) - self.rt.initialize(self.tb) - self.rt.run() - self.assertEqual(expected_data, dst.data()) - - # def test_short_to_char(self): - # src_data = (256, 512, 768, 1024, 1280) - # expected_data = [1, 2, 3, 4, 5] - # src = blocks.vector_source_s(src_data) - # op = blocks.short_to_char() - # dst = blocks.vector_sink_b() - # self.tb.connect(src, op, dst) - # self.tb.run() - # self.assertEqual(expected_data, dst.data()) - - # def test_short_to_float_identity(self): - # src_data = (1, 2, 3, 4, 5) - # expected_data = [1.0, 2.0, 3.0, 4.0, 5.0] - # src = blocks.vector_source_s(src_data) - # op = blocks.short_to_float() - # dst = blocks.vector_sink_f() - # self.tb.connect(src, op, dst) - # self.tb.run() - # self.assertEqual(expected_data, dst.data()) - - # def test_short_to_float_scale(self): - # src_data = (5, 10, 15, 20, 25) - # expected_data = [1.0, 2.0, 3.0, 4.0, 5.0] - # src = blocks.vector_source_s(src_data) - # op = blocks.short_to_float(1, 5) - # dst = blocks.vector_sink_f() - # self.tb.connect(src, op, dst) - # self.tb.run() - # self.assertEqual(expected_data, dst.data()) - - # def test_uchar_to_float(self): - # src_data = (1, 2, 3, 4, 5) - # expected_data = [1.0, 2.0, 3.0, 4.0, 5.0] - # src = blocks.vector_source_b(src_data) - # op = blocks.uchar_to_float() - # dst = blocks.vector_sink_f() - # self.tb.connect(src, op, dst) - # self.tb.run() - # self.assertEqual(expected_data, dst.data()) - - -if __name__ == '__main__': - gr_unittest.run(test_type_conversions) diff --git a/blocklib/zeromq/.gitignore b/blocklib/zeromq/.gitignore deleted file mode 100644 index 25d053a52..000000000 --- a/blocklib/zeromq/.gitignore +++ /dev/null @@ -1 +0,0 @@ -meson.build
\ No newline at end of file diff --git a/blocklib/zeromq/include/gnuradio/zeromq/.gitignore b/blocklib/zeromq/include/gnuradio/zeromq/.gitignore deleted file mode 100644 index d53050d7d..000000000 --- a/blocklib/zeromq/include/gnuradio/zeromq/.gitignore +++ /dev/null @@ -1 +0,0 @@ -!meson.build diff --git a/blocklib/zeromq/include/gnuradio/zeromq/api.h b/blocklib/zeromq/include/gnuradio/zeromq/api.h deleted file mode 100644 index 29941d0f4..000000000 --- a/blocklib/zeromq/include/gnuradio/zeromq/api.h +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Copyright 2011 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_blocks_EXPORTS -#define ZEROMQ_API __GR_ATTR_EXPORT -#else -#define ZEROMQ_API __GR_ATTR_IMPORT -#endif diff --git a/blocklib/zeromq/include/gnuradio/zeromq/meson.build b/blocklib/zeromq/include/gnuradio/zeromq/meson.build deleted file mode 100644 index 9bb4be16a..000000000 --- a/blocklib/zeromq/include/gnuradio/zeromq/meson.build +++ /dev/null @@ -1,25 +0,0 @@ -zeromq_headers = [ - 'api.h' -] - -install_headers(zeromq_headers, subdir : 'gnuradio/zeromq') - -cmake_conf = configuration_data() -cmake_conf.set('libdir', join_paths(prefix,get_option('libdir'))) -cmake_conf.set('module', 'zeromq') -cmake.configure_package_config_file( - name : 'gnuradio-zeromq', - 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 = [] # 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-zeromq', - filebase : 'gnuradio-zeromq', - description : 'GNU Radio ZeroMQ Blocks') diff --git a/blocklib/zeromq/lib/.gitignore b/blocklib/zeromq/lib/.gitignore deleted file mode 100644 index 01ecb66ff..000000000 --- a/blocklib/zeromq/lib/.gitignore +++ /dev/null @@ -1 +0,0 @@ -!meson.build
\ No newline at end of file diff --git a/blocklib/zeromq/lib/base.cc b/blocklib/zeromq/lib/base.cc deleted file mode 100644 index 10a07cfa3..000000000 --- a/blocklib/zeromq/lib/base.cc +++ /dev/null @@ -1,236 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2016,2019 Free Software Foundation, Inc. - * - * This file is part of GNU Radio. - * - * SPDX-License-Identifier: GPL-3.0-or-later - * - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "base.h" -#include "tag_headers.h" - -namespace { -constexpr int LINGER_DEFAULT = 1000; // 1 second. -} - -namespace gr { -namespace zeromq { - -base::base(int type, size_t itemsize, int timeout, bool pass_tags, const std::string& key) - : d_context(1), - d_socket(d_context, type), - d_vsize(itemsize), - d_timeout(timeout), - d_pass_tags(pass_tags), - d_key(key) -{ - /* "Fix" timeout value (ms for new API, us for old API) */ - int major, minor, patch; - zmq::version(&major, &minor, &patch); - - if (major < 3) { - d_timeout *= 1000; - } -} - -std::string base::last_endpoint() const -{ - return d_socket.get(zmq::sockopt::last_endpoint); -} - - -base_sink::base_sink(int type, - size_t itemsize, - const std::string& address, - int timeout, - bool pass_tags, - int hwm, - const std::string& key) - : base(type, itemsize, timeout, pass_tags, key) -{ - gr::configure_default_loggers(d_base_logger, d_base_debug_logger, "zmq_base_source"); - - /* Set high watermark */ - if (hwm >= 0) { - d_socket.set(zmq::sockopt::sndhwm, hwm); - } - - /* Set ZMQ_LINGER so socket won't infinitely block during teardown */ - d_socket.set(zmq::sockopt::linger, LINGER_DEFAULT); - - /* Bind */ - d_socket.bind(address); -} - -int base_sink::send_message(const void* in_buf, - const int in_nitems, - const uint64_t in_offset, - const std::vector<tag_t>& tags) -{ - /* Send key if it exists */ - if (!d_key.empty()) { - zmq::message_t key_message(d_key.size()); - memcpy(key_message.data(), d_key.data(), d_key.size()); - d_socket.send(key_message, zmq::send_flags::sndmore); - } - /* Meta-data header */ - std::string header(""); - if (d_pass_tags) { - // std::vector<gr::tag_t> tags; - // get_tags_in_range(tags, 0, in_offset, in_offset + in_nitems); - header = gen_tag_header(in_offset, tags); - } - - /* Create message */ - size_t payload_len = in_nitems * d_vsize; - size_t msg_len = d_pass_tags ? payload_len + header.length() : payload_len; - zmq::message_t msg(msg_len); - - if (d_pass_tags) { - memcpy(msg.data(), header.c_str(), header.length()); - memcpy((uint8_t*)msg.data() + header.length(), in_buf, payload_len); - } - else { - memcpy(msg.data(), in_buf, payload_len); - } - - /* Send */ - d_socket.send(msg, zmq::send_flags::none); - - /* Report back */ - return in_nitems; -} - -base_source::base_source(int type, - size_t itemsize, - const std::string& address, - int timeout, - bool pass_tags, - int hwm, - const std::string& key) - : base(type, itemsize, timeout, pass_tags, key), - d_consumed_bytes(0), - d_consumed_items(0) -{ - /* Set high watermark */ - if (hwm >= 0) { - d_socket.set(zmq::sockopt::rcvhwm, hwm); - } - - /* Set ZMQ_LINGER so socket won't infinitely block during teardown */ - d_socket.set(zmq::sockopt::linger, LINGER_DEFAULT); - - /* Connect */ - d_socket.connect(address); -} - -bool base_source::has_pending() { return d_msg.size() > d_consumed_bytes; } - -int base_source::flush_pending(block_work_output& work_output, - const int out_nitems, - const uint64_t out_offset) -{ - /* How much to copy in this call */ - int to_copy_items = - std::min(out_nitems, (int)((d_msg.size() - d_consumed_bytes) / d_vsize)); - int to_copy_bytes = d_vsize * to_copy_items; - auto nw = work_output.nitems_written(); - - /* Copy actual data */ - memcpy(work_output.items<uint8_t>() + out_offset * d_vsize, - (uint8_t*)d_msg.data() + d_consumed_bytes, - to_copy_bytes); - - /* Add tags matching this segment of samples */ - for (unsigned int i = 0; i < d_tags.size(); i++) { - if ((d_tags[i].offset() >= (uint64_t)d_consumed_items) && - (d_tags[i].offset() < (uint64_t)d_consumed_items + to_copy_items)) { - gr::tag_t nt = d_tags[i]; - nt.set_offset(nt.offset() + nw + out_offset - d_consumed_items); - work_output.add_tag(nt); - } - } - - /* Update pointer */ - d_consumed_items += to_copy_items; - d_consumed_bytes += to_copy_bytes; - - return to_copy_items; -} - -bool base_source::load_message(bool wait) -{ - /* Poll for input */ - zmq::pollitem_t items[] = { { static_cast<void*>(d_socket), 0, ZMQ_POLLIN, 0 } }; - zmq::poll(&items[0], 1, std::chrono::milliseconds{ wait ? d_timeout : 0 }); - - if (!(items[0].revents & ZMQ_POLLIN)) - return false; - - /* Is this the start or continuation of a multi-part message? */ - auto more = d_socket.get(zmq::sockopt::rcvmore); - - /* Reset */ - d_msg.rebuild(); - d_tags.clear(); - d_consumed_items = 0; - d_consumed_bytes = 0; - - /* Get the message */ - const bool ok = bool(d_socket.recv(d_msg)); - - if (!ok) { - // This shouldn't happen since we polled POLLIN, but ZMQ wants us to check - // the return value. - d_base_logger->warn("Failed to recv() message."); - return false; - } - - /* Throw away key and get the first message. Avoid blocking if a multi-part - * message is not sent */ - if (!d_key.empty() && !more) { - auto is_multipart = d_socket.get(zmq::sockopt::rcvmore); - - d_msg.rebuild(); - if (is_multipart) { - const bool multi_ok = bool(d_socket.recv(d_msg)); - - if (!multi_ok) { - d_base_logger->error("Failure to receive multi-part message."); - } - } - else { - return false; - } - } - /* Parse header from the first (or only) message of a multi-part message */ - if (d_pass_tags && !more) { - uint64_t rcv_offset; - - /* Parse header */ - d_consumed_bytes = parse_tag_header(d_msg, rcv_offset, d_tags); - - /* Fixup the tags offset to be relative to the start of this message */ - for (unsigned int i = 0; i < d_tags.size(); i++) { - d_tags[i].set_offset(d_tags[i].offset() - rcv_offset); - } - } - - /* Each message must contain an integer multiple of data vectors */ - if ((d_msg.size() - d_consumed_bytes) % d_vsize != 0) { - throw std::runtime_error("Incompatible vector sizes: need a multiple of " + - std::to_string(d_vsize) + " bytes per message"); - } - - /* We got one ! */ - return true; -} - -} /* namespace zeromq */ -} /* namespace gr */ diff --git a/blocklib/zeromq/lib/base.h b/blocklib/zeromq/lib/base.h deleted file mode 100644 index 7fb6d2ccb..000000000 --- a/blocklib/zeromq/lib/base.h +++ /dev/null @@ -1,89 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2016,2019 Free Software Foundation, Inc. - * Copyright 2022 Josh Morman - * - * This file is part of GNU Radio. - * - * SPDX-License-Identifier: GPL-3.0-or-later - * - */ - -#pragma once - -#include "zmq_common_impl.h" -#include <gnuradio/block_work_io.h> -#include <gnuradio/logger.h> -#include <gnuradio/tag.h> - -namespace gr { -namespace zeromq { - -class base -{ -public: - base(int type, - size_t itemsize, - int timeout, - bool pass_tags, - const std::string& key = ""); - - void set_vsize(size_t vsize) { d_vsize = vsize; } - -protected: - std::string last_endpoint() const; - zmq::context_t d_context; - zmq::socket_t d_socket; - size_t d_vsize; - int d_timeout; - bool d_pass_tags; - const std::string d_key; - - logger_ptr d_base_logger; - logger_ptr d_base_debug_logger; -}; - -class base_sink : public base -{ -public: - base_sink(int type, - size_t itemsize, - const std::string& address, - int timeout, - bool pass_tags, - int hwm, - const std::string& key = ""); - -protected: - int send_message(const void* in_buf, - const int in_nitems, - const uint64_t in_offset, - const std::vector<tag_t>& tags); -}; - -class base_source : public base -{ -public: - base_source(int type, - size_t itemsize, - const std::string& address, - int timeout, - bool pass_tags, - int hwm, - const std::string& key = ""); - -protected: - zmq::message_t d_msg; - std::vector<gr::tag_t> d_tags; - size_t d_consumed_bytes; - int d_consumed_items; - - bool has_pending(); - int flush_pending(block_work_output& work_output, - const int out_nitems, - const uint64_t out_offset); - bool load_message(bool wait); -}; - -} // namespace zeromq -} // namespace gr diff --git a/blocklib/zeromq/lib/meson.build b/blocklib/zeromq/lib/meson.build deleted file mode 100644 index c3f036763..000000000 --- a/blocklib/zeromq/lib/meson.build +++ /dev/null @@ -1,36 +0,0 @@ -zeromq_deps += [gnuradio_gr_dep, volk_dep, fmt_dep, pmtf_dep, cppzmq_dep] -zeromq_sources += ['base.cc', 'tag_headers.cc'] -block_cpp_args = ['-DHAVE_CPU'] - -incdir = include_directories(['../include/gnuradio/zeromq','../include']) -gnuradio_blocklib_zeromq_lib = library('gnuradio-blocklib-zeromq', - zeromq_sources, - include_directories : incdir, - install : true, - link_language: 'cpp', - dependencies : zeromq_deps, - cpp_args : block_cpp_args) - -gnuradio_blocklib_zeromq_dep = declare_dependency(include_directories : incdir, - link_with : gnuradio_blocklib_zeromq_lib, - dependencies : zeromq_deps) - -cmake_conf = configuration_data() -cmake_conf.set('libdir', join_paths(prefix,get_option('libdir'))) -cmake_conf.set('module', 'zeromq') -cmake.configure_package_config_file( - name : 'gnuradio-zeromq', - 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_zeromq_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-zeromq', - filebase : 'gnuradio-zeromq', - description : 'GNU Radio ZeroMQ Module') diff --git a/blocklib/zeromq/lib/tag_headers.cc b/blocklib/zeromq/lib/tag_headers.cc deleted file mode 100644 index fd814bead..000000000 --- a/blocklib/zeromq/lib/tag_headers.cc +++ /dev/null @@ -1,89 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2014 Free Software Foundation, Inc. - * - * This file is part of GNU Radio. - * - * SPDX-License-Identifier: GPL-3.0-or-later - * - */ - -#include "zmq_common_impl.h" -#include <gnuradio/tag.h> -#include <cstring> -#include <sstream> - -#define GR_HEADER_MAGIC 0x5FF0 -#define GR_HEADER_VERSION 0x02 - -namespace gr { -namespace zeromq { - -struct membuf : std::streambuf { - membuf(void* b, size_t len) - { - char* bc = static_cast<char*>(b); - this->setg(bc, bc, bc + len); - } -}; - -std::string gen_tag_header(uint64_t offset, const std::vector<gr::tag_t>& tags) -{ - std::stringbuf sb(""); - std::ostream ss(&sb); - - uint16_t header_magic = GR_HEADER_MAGIC; - uint8_t header_version = GR_HEADER_VERSION; - uint64_t ntags = (uint64_t)tags.size(); - - ss.write((const char*)&header_magic, sizeof(uint16_t)); - ss.write((const char*)&header_version, sizeof(uint8_t)); - ss.write((const char*)&offset, sizeof(uint64_t)); - ss.write((const char*)&ntags, sizeof(uint64_t)); - - for (auto& tag : tags) { - tag.serialize(sb); - } - - return sb.str(); -} - -size_t parse_tag_header(zmq::message_t& msg, - uint64_t& offset_out, - std::vector<gr::tag_t>& tags_out) -{ - membuf sb(msg.data(), msg.size()); - std::istream iss(&sb); - - size_t min_len = - sizeof(uint16_t) + sizeof(uint8_t) + sizeof(uint64_t) + sizeof(uint64_t); - if (msg.size() < min_len) - throw std::runtime_error("incoming zmq msg too small to hold gr tag header!"); - - uint16_t header_magic; - uint8_t header_version; - uint64_t rcv_ntags; - - iss.read((char*)&header_magic, sizeof(uint16_t)); - iss.read((char*)&header_version, sizeof(uint8_t)); - - if (header_magic != GR_HEADER_MAGIC) - throw std::runtime_error("gr header magic does not match!"); - - if (header_version != GR_HEADER_VERSION) - throw std::runtime_error("gr header version does not match!"); - - iss.read((char*)&offset_out, sizeof(uint64_t)); - iss.read((char*)&rcv_ntags, sizeof(uint64_t)); - - for (size_t i = 0; i < rcv_ntags; i++) { - gr::tag_t newtag = tag_t::deserialize(sb); - tags_out.push_back(newtag); - } - - return msg.size() - sb.in_avail(); -} -} /* namespace zeromq */ -} /* namespace gr */ - -// vim: ts=2 sw=2 expandtab diff --git a/blocklib/zeromq/lib/tag_headers.h b/blocklib/zeromq/lib/tag_headers.h deleted file mode 100644 index b8b7a09b1..000000000 --- a/blocklib/zeromq/lib/tag_headers.h +++ /dev/null @@ -1,28 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2014 Free Software Foundation, Inc. - * - * This file is part of GNU Radio. - * - * SPDX-License-Identifier: GPL-3.0-or-later - * - */ - -#ifndef ZEROMQ_TAG_HEADERS_H -#define ZEROMQ_TAG_HEADERS_H - -#include "zmq_common_impl.h" -#include <gnuradio/tag.h> - -namespace gr { -namespace zeromq { - -std::string gen_tag_header(uint64_t offset, const std::vector<gr::tag_t>& tags); -size_t parse_tag_header(zmq::message_t& msg, - uint64_t& offset_out, - std::vector<gr::tag_t>& tags_out); - -} /* namespace zeromq */ -} /* namespace gr */ - -#endif /* ZEROMQ_TAG_HEADERS_H */ diff --git a/blocklib/zeromq/lib/zmq_common_impl.h b/blocklib/zeromq/lib/zmq_common_impl.h deleted file mode 100644 index fc08ef301..000000000 --- a/blocklib/zeromq/lib/zmq_common_impl.h +++ /dev/null @@ -1,13 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2019 Free Software Foundation, Inc. - * Copyright 2022 Josh Morman - * - * This file is part of GNU Radio. - * - * SPDX-License-Identifier: GPL-3.0-or-later - * - */ -#pragma once - -#include <zmq.hpp> diff --git a/blocklib/zeromq/pub_sink/pub_sink.yml b/blocklib/zeromq/pub_sink/pub_sink.yml deleted file mode 100644 index f65b4a70f..000000000 --- a/blocklib/zeromq/pub_sink/pub_sink.yml +++ /dev/null @@ -1,55 +0,0 @@ -module: zeromq -block: pub_sink -label: PUB Sink -blocktype: sync_block -category: '[Core]/ZeroMQ Interfaces' - -# Example Parameters -parameters: - - id: address - label: IP Address - dtype: string - settable: false - - id: timeout - label: Timeout - dtype: int - settable: false - default: 100 - - id: pass_tags - label: Pass Tags - dtype: bool - settable: false - default: "false" - - id: hwm - label: HWM - dtype: int - settable: false - default: -1 - - id: key - label: Key - dtype: string - settable: false - default: "\"\"" - - id: itemsize - label: Item Size - dtype: size - settable: false - default: 0 - -callbacks: -- id: last_endpoint - return: std::string - const: true - # inherited: true - -ports: - - domain: stream - id: in - direction: input - type: untyped - size: parameters/itemsize - -implementations: -- id: cpu - -file_format: 1 diff --git a/blocklib/zeromq/pub_sink/pub_sink_cpu.cc b/blocklib/zeromq/pub_sink/pub_sink_cpu.cc deleted file mode 100644 index 2a5d9d3f5..000000000 --- a/blocklib/zeromq/pub_sink/pub_sink_cpu.cc +++ /dev/null @@ -1,33 +0,0 @@ -#include "pub_sink_cpu.h" -#include "pub_sink_cpu_gen.h" - -namespace gr { -namespace zeromq { - -pub_sink_cpu::pub_sink_cpu(block_args args) - : INHERITED_CONSTRUCTORS, - base_sink(ZMQ_PUB, - args.itemsize, - args.address, - args.timeout, - args.pass_tags, - args.hwm, - args.key) -{ -} - -work_return_t pub_sink_cpu::work(work_io& wio) -{ - auto noutput_items = wio.inputs()[0].n_items; - auto nread = wio.inputs()[0].nitems_read(); - auto nsent = send_message(wio.inputs()[0].raw_items(), - noutput_items, - nread, - wio.inputs()[0].tags_in_window(0, noutput_items)); - wio.consume_each(nsent); - return work_return_t::OK; -} - - -} // namespace zeromq -} // namespace gr diff --git a/blocklib/zeromq/pub_sink/pub_sink_cpu.h b/blocklib/zeromq/pub_sink/pub_sink_cpu.h deleted file mode 100644 index e55d125e7..000000000 --- a/blocklib/zeromq/pub_sink/pub_sink_cpu.h +++ /dev/null @@ -1,28 +0,0 @@ -#pragma once - -#include "base.h" -#include <gnuradio/zeromq/pub_sink.h> - -namespace gr { -namespace zeromq { - -class pub_sink_cpu : public virtual pub_sink, public virtual base_sink -{ -public: - pub_sink_cpu(block_args args); - work_return_t work(work_io&) override; - std::string last_endpoint() const override { return base_sink::last_endpoint(); } - - // Since vsize can be set as 0, then inferred on flowgraph init, set it during start() - bool start() override - { - set_vsize(this->input_stream_ports()[0]->itemsize()); - return pub_sink::start(); - } - -private: - // private variables here -}; - -} // namespace zeromq -} // namespace gr
\ No newline at end of file diff --git a/blocklib/zeromq/pull_msg_source/pull_msg_source.yml b/blocklib/zeromq/pull_msg_source/pull_msg_source.yml deleted file mode 100644 index 3cde228af..000000000 --- a/blocklib/zeromq/pull_msg_source/pull_msg_source.yml +++ /dev/null @@ -1,37 +0,0 @@ -module: zeromq -block: pull_msg_source -label: Pull Msg Source -blocktype: sync_block -category: '[Core]/ZeroMQ Interfaces' - -parameters: - - id: address - label: IP Address - dtype: string - settable: false - - id: timeout - label: Timeout - dtype: int - settable: false - default: 100 - - id: bind - label: Bind - dtype: bool - settable: false - default: "false" - -callbacks: -- id: last_endpoint - return: std::string - const: true - -ports: -- domain: message - id: out - direction: output - -implementations: -- id: cpu -# - id: cuda - -file_format: 1
\ No newline at end of file diff --git a/blocklib/zeromq/pull_msg_source/pull_msg_source_cpu.cc b/blocklib/zeromq/pull_msg_source/pull_msg_source_cpu.cc deleted file mode 100644 index 94c81afb6..000000000 --- a/blocklib/zeromq/pull_msg_source/pull_msg_source_cpu.cc +++ /dev/null @@ -1,96 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2013,2014,2019 Free Software Foundation, Inc. - * Copyright 2022 Josh Morman - * - * This file is part of GNU Radio - * - * SPDX-License-Identifier: GPL-3.0-or-later - * - */ - -#include "pull_msg_source_cpu.h" -#include "pull_msg_source_cpu_gen.h" - -#include <chrono> - -namespace { -constexpr int LINGER_DEFAULT = 1000; // 1 second. -} - -namespace gr { -namespace zeromq { - -pull_msg_source_cpu::pull_msg_source_cpu(block_args args) - : INHERITED_CONSTRUCTORS, - d_timeout(args.timeout), - d_context(1), - d_socket(d_context, ZMQ_PULL) -{ - - d_socket.set(zmq::sockopt::linger, LINGER_DEFAULT); - - if (args.bind) { - d_socket.bind(args.address); - } - else { - d_socket.connect(args.address); - } -} - -bool pull_msg_source_cpu::start() -{ - d_finished = false; - d_thread = std::thread([this] { readloop(); }); - return block::start(); -} - -bool pull_msg_source_cpu::stop() -{ - d_finished = true; - if (d_thread.joinable()) { - d_thread.join(); - } - return block::stop(); -} - -void pull_msg_source_cpu::readloop() -{ - using namespace std::chrono_literals; - while (!d_finished) { - - zmq::pollitem_t items[] = { { static_cast<void*>(d_socket), 0, ZMQ_POLLIN, 0 } }; - zmq::poll(&items[0], 1, std::chrono::milliseconds{ d_timeout }); - - // If we got a reply, process - if (items[0].revents & ZMQ_POLLIN) { - - // Receive data - zmq::message_t msg; - const bool ok = bool(d_socket.recv(msg)); - - if (!ok) { - // Should not happen, we've checked POLLIN. - d_logger->error("Failed to receive message."); - std::this_thread::sleep_for(100us); - continue; - } - - std::string buf(static_cast<char*>(msg.data()), msg.size()); - std::stringbuf sb(buf); - try { - auto m = pmtf::pmt::deserialize(sb); - d_msg_out->post(m); - } catch (...) { // Take out PMT specific exception for now - d_logger->error("Invalid PMT message"); - } - } - else { - std::this_thread::sleep_for(100us); - } - } -} - - -} // namespace zeromq -} // namespace gr diff --git a/blocklib/zeromq/pull_msg_source/pull_msg_source_cpu.h b/blocklib/zeromq/pull_msg_source/pull_msg_source_cpu.h deleted file mode 100644 index a31704ffd..000000000 --- a/blocklib/zeromq/pull_msg_source/pull_msg_source_cpu.h +++ /dev/null @@ -1,45 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2013,2014,2019 Free Software Foundation, Inc. - * Copyright 2022 Josh Morman - * - * This file is part of GNU Radio - * - * SPDX-License-Identifier: GPL-3.0-or-later - * - */ - -#pragma once - -#include <gnuradio/zeromq/pull_msg_source.h> - -#include <zmq.hpp> -#include <thread> - -namespace gr { -namespace zeromq { - -class pull_msg_source_cpu : public virtual pull_msg_source -{ -public: - pull_msg_source_cpu(block_args args); - bool start() override; - bool stop() override; - std::string last_endpoint() const override - { - return d_socket.get(zmq::sockopt::last_endpoint); - } - -private: - bool d_finished; - int d_timeout; // microseconds, -1 is blocking - zmq::context_t d_context; - zmq::socket_t d_socket; - std::thread d_thread; - - - void readloop(); -}; - -} // namespace zeromq -} // namespace gr
\ No newline at end of file diff --git a/blocklib/zeromq/pull_source/pull_source.yml b/blocklib/zeromq/pull_source/pull_source.yml deleted file mode 100644 index 491211407..000000000 --- a/blocklib/zeromq/pull_source/pull_source.yml +++ /dev/null @@ -1,43 +0,0 @@ -module: zeromq -block: pull_source -label: PULL Source -blocktype: sync_block -category: '[Core]/ZeroMQ Interfaces' -# inherits: base - -parameters: - - id: address - label: IP Address - dtype: string - settable: false - - id: timeout - label: Timeout - dtype: int - settable: false - default: 100 - - id: pass_tags - label: Pass Tags - dtype: bool - settable: false - default: "false" - - id: hwm - label: HWM - dtype: int - settable: false - default: -1 - - id: itemsize - label: Item Size - dtype: size - settable: false - default: 0 -ports: - - domain: stream - id: out - direction: output - type: untyped - size: parameters/itemsize - -implementations: - - id: cpu - -file_format: 1 diff --git a/blocklib/zeromq/pull_source/pull_source_cpu.cc b/blocklib/zeromq/pull_source/pull_source_cpu.cc deleted file mode 100644 index 6331db2cc..000000000 --- a/blocklib/zeromq/pull_source/pull_source_cpu.cc +++ /dev/null @@ -1,53 +0,0 @@ -#include "pull_source_cpu.h" -#include "pull_source_cpu_gen.h" - -#include <chrono> -#include <thread> - -namespace gr { -namespace zeromq { - -pull_source_cpu::pull_source_cpu(block_args args) - : INHERITED_CONSTRUCTORS, - base_source( - ZMQ_PULL, args.itemsize, args.address, args.timeout, args.pass_tags, args.hwm) -{ -} - -work_return_t pull_source_cpu::work(work_io& wio) -{ - - auto noutput_items = wio.outputs()[0].n_items; - bool first = true; - size_t done = 0; - - /* Process as much as we can */ - while (1) { - if (has_pending()) { - /* Flush anything pending */ - done += flush_pending(wio.outputs()[0], noutput_items - done, done); - - /* No more space ? */ - if (done == noutput_items) - break; - } - else { - /* Try to get the next message */ - if (!load_message(first)) { - // Launch a thread to come back and try again some time later - come_back_later(100); - break; /* No message, we're done for now */ - } - - /* Not the first anymore */ - first = false; - } - } - - wio.outputs()[0].n_produced = done; - return work_return_t::OK; -} - - -} // namespace zeromq -} // namespace gr diff --git a/blocklib/zeromq/pull_source/pull_source_cpu.h b/blocklib/zeromq/pull_source/pull_source_cpu.h deleted file mode 100644 index 157a9ba45..000000000 --- a/blocklib/zeromq/pull_source/pull_source_cpu.h +++ /dev/null @@ -1,24 +0,0 @@ -#pragma once - -#include "base.h" -#include <gnuradio/zeromq/pull_source.h> - -namespace gr { -namespace zeromq { - -class pull_source_cpu : public virtual pull_source, public virtual base_source -{ -public: - pull_source_cpu(block_args args); - work_return_t work(work_io&) override; - - // Since vsize can be set as 0, then inferred on flowgraph init, set it during start() - bool start() override - { - set_vsize(this->output_stream_ports()[0]->itemsize()); - return pull_source::start(); - } -}; - -} // namespace zeromq -} // namespace gr
\ No newline at end of file diff --git a/blocklib/zeromq/push_msg_sink/push_msg_sink.yml b/blocklib/zeromq/push_msg_sink/push_msg_sink.yml deleted file mode 100644 index 172631951..000000000 --- a/blocklib/zeromq/push_msg_sink/push_msg_sink.yml +++ /dev/null @@ -1,38 +0,0 @@ -module: zeromq -block: push_msg_sink -label: Push Msg Sink -blocktype: block -category: '[Core]/ZeroMQ Interfaces' - -# Example Parameters -parameters: - - id: address - label: IP Address - dtype: string - settable: false - - id: timeout - label: Timeout - dtype: int - settable: false - default: 100 - - id: bind - label: Bind - dtype: bool - settable: false - default: "true" - -callbacks: -- id: last_endpoint - return: std::string - const: true - -ports: -- domain: message - id: in - direction: input - -implementations: -- id: cpu -# - id: cuda - -file_format: 1 diff --git a/blocklib/zeromq/push_msg_sink/push_msg_sink_cpu.cc b/blocklib/zeromq/push_msg_sink/push_msg_sink_cpu.cc deleted file mode 100644 index dd044868d..000000000 --- a/blocklib/zeromq/push_msg_sink/push_msg_sink_cpu.cc +++ /dev/null @@ -1,50 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2013,2014 Free Software Foundation, Inc. - * Copyright 2022 Josh Morman - * - * This file is part of GNU Radio - * - * SPDX-License-Identifier: GPL-3.0-or-later - * - */ - -#include "push_msg_sink_cpu.h" -#include "push_msg_sink_cpu_gen.h" - -namespace { -constexpr int LINGER_DEFAULT = 1000; // 1 second. -} - -namespace gr { -namespace zeromq { - -push_msg_sink_cpu::push_msg_sink_cpu(block_args args) - : INHERITED_CONSTRUCTORS, - d_timeout(args.timeout), - d_context(1), - d_socket(d_context, ZMQ_PUSH) -{ - - d_socket.set(zmq::sockopt::linger, LINGER_DEFAULT); - - if (args.bind) { - d_socket.bind(args.address); - } - else { - d_socket.connect(args.address); - } -} - -void push_msg_sink_cpu::handle_msg_in(pmtf::pmt msg) -{ - std::stringbuf sb(""); - msg.serialize(sb); - std::string s = sb.str(); - zmq::message_t zmsg(s.size()); - memcpy(zmsg.data(), s.c_str(), s.size()); - d_socket.send(zmsg, zmq::send_flags::none); -} - -} // namespace zeromq -} // namespace gr
\ No newline at end of file diff --git a/blocklib/zeromq/push_msg_sink/push_msg_sink_cpu.h b/blocklib/zeromq/push_msg_sink/push_msg_sink_cpu.h deleted file mode 100644 index ad8e01d4e..000000000 --- a/blocklib/zeromq/push_msg_sink/push_msg_sink_cpu.h +++ /dev/null @@ -1,40 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2013,2014 Free Software Foundation, Inc. - * Copyright 2022 Josh Morman - * - * This file is part of GNU Radio - * - * SPDX-License-Identifier: GPL-3.0-or-later - * - */ - -#pragma once - -#include <gnuradio/zeromq/push_msg_sink.h> - -#include <zmq.hpp> - -namespace gr { -namespace zeromq { - -class push_msg_sink_cpu : public virtual push_msg_sink -{ -public: - push_msg_sink_cpu(block_args args); - - std::string last_endpoint() const override - { - return d_socket.get(zmq::sockopt::last_endpoint); - } - -private: - int d_timeout; // microseconds, -1 is blocking - zmq::context_t d_context; - zmq::socket_t d_socket; - - void handle_msg_in(pmtf::pmt msg) override; -}; - -} // namespace zeromq -} // namespace gr
\ No newline at end of file diff --git a/blocklib/zeromq/push_sink/push_sink.yml b/blocklib/zeromq/push_sink/push_sink.yml deleted file mode 100644 index 9e45debb1..000000000 --- a/blocklib/zeromq/push_sink/push_sink.yml +++ /dev/null @@ -1,51 +0,0 @@ -module: zeromq -block: push_sink -label: PUSH Sink -blocktype: sync_block -category: '[Core]/ZeroMQ Interfaces' -# inherits: gr::zeromq::base -# includes: -# - gnuradio/zeromq/base.h - -parameters: - - id: address - label: IP Address - dtype: string - settable: false - - id: timeout - label: Timeout - dtype: int - settable: false - default: 100 - - id: pass_tags - label: Pass Tags - dtype: bool - settable: false - default: "false" - - id: hwm - label: HWM - dtype: int - settable: false - default: -1 - - id: itemsize - label: Item Size - dtype: size - settable: false - default: 0 -callbacks: -- id: last_endpoint - return: std::string - const: true - # inherited: true - -ports: - - domain: stream - id: in - direction: input - type: untyped - size: parameters/itemsize - -implementations: - - id: cpu - -file_format: 1 diff --git a/blocklib/zeromq/push_sink/push_sink_cpu.cc b/blocklib/zeromq/push_sink/push_sink_cpu.cc deleted file mode 100644 index 85de05df0..000000000 --- a/blocklib/zeromq/push_sink/push_sink_cpu.cc +++ /dev/null @@ -1,34 +0,0 @@ -#include "push_sink_cpu.h" -#include "push_sink_cpu_gen.h" - -namespace gr { -namespace zeromq { - -push_sink_cpu::push_sink_cpu(block_args args) - : INHERITED_CONSTRUCTORS, - base_sink( - ZMQ_PUSH, args.itemsize, args.address, args.timeout, args.pass_tags, args.hwm) -{ -} -work_return_t push_sink_cpu::work(work_io& wio) - -{ - // Poll with a timeout (FIXME: scheduler can't wait for us) - zmq::pollitem_t itemsout[] = { { static_cast<void*>(d_socket), 0, ZMQ_POLLOUT, 0 } }; - zmq::poll(&itemsout[0], 1, std::chrono::milliseconds{ d_timeout }); - - // If we can send something, do it - if (itemsout[0].revents & ZMQ_POLLOUT) { - wio.inputs()[0].n_consumed = - send_message(wio.inputs()[0].raw_items(), - wio.inputs()[0].n_items, - wio.inputs()[0].nitems_read(), - wio.inputs()[0].tags_in_window(0, wio.inputs()[0].n_items)); - } - - return work_return_t::OK; -} - - -} // namespace zeromq -} // namespace gr
\ No newline at end of file diff --git a/blocklib/zeromq/push_sink/push_sink_cpu.h b/blocklib/zeromq/push_sink/push_sink_cpu.h deleted file mode 100644 index f58102cfa..000000000 --- a/blocklib/zeromq/push_sink/push_sink_cpu.h +++ /dev/null @@ -1,25 +0,0 @@ -#pragma once - -#include "base.h" -#include <gnuradio/zeromq/push_sink.h> - -namespace gr { -namespace zeromq { - -class push_sink_cpu : public virtual push_sink, public virtual base_sink -{ -public: - push_sink_cpu(block_args args); - work_return_t work(work_io&) override; - std::string last_endpoint() const override { return base_sink::last_endpoint(); } - - // Since vsize can be set as 0, then inferred on flowgraph init, set it during start() - bool start() override - { - set_vsize(this->input_stream_ports()[0]->itemsize()); - return push_sink::start(); - } -}; - -} // namespace zeromq -} // namespace gr
\ No newline at end of file diff --git a/blocklib/zeromq/python/gnuradio/zeromq/.gitignore b/blocklib/zeromq/python/gnuradio/zeromq/.gitignore deleted file mode 100644 index 25d053a52..000000000 --- a/blocklib/zeromq/python/gnuradio/zeromq/.gitignore +++ /dev/null @@ -1 +0,0 @@ -meson.build
\ No newline at end of file diff --git a/blocklib/zeromq/python/gnuradio/zeromq/__init__.py b/blocklib/zeromq/python/gnuradio/zeromq/__init__.py deleted file mode 100644 index ee01dd5ab..000000000 --- a/blocklib/zeromq/python/gnuradio/zeromq/__init__.py +++ /dev/null @@ -1,9 +0,0 @@ - -import os - -try: - from .zeromq_python import * -except ImportError: - dirname, filename = os.path.split(os.path.abspath(__file__)) - __path__.append(os.path.join(dirname, "bindings")) - from .zeromq_python import * diff --git a/blocklib/zeromq/python/gnuradio/zeromq/bindings/.gitignore b/blocklib/zeromq/python/gnuradio/zeromq/bindings/.gitignore deleted file mode 100644 index 01ecb66ff..000000000 --- a/blocklib/zeromq/python/gnuradio/zeromq/bindings/.gitignore +++ /dev/null @@ -1 +0,0 @@ -!meson.build
\ No newline at end of file diff --git a/blocklib/zeromq/python/gnuradio/zeromq/bindings/base_pybind.cc b/blocklib/zeromq/python/gnuradio/zeromq/bindings/base_pybind.cc deleted file mode 100644 index 59d6b86a8..000000000 --- a/blocklib/zeromq/python/gnuradio/zeromq/bindings/base_pybind.cc +++ /dev/null @@ -1,39 +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/zeromq/base.h> - -void bind_base(py::module& m) -{ - using base = gr::zeromq::base; - using base_source = gr::zeromq::base_source; - using base_sink = gr::zeromq::base_sink; - - py::class_<base, std::shared_ptr<base>> base_class(m, "base"); - py::class_<base_source, std::shared_ptr<base_source>> base_class(m, "base_source"); - py::class_<base_sink, std::shared_ptr<base_sink>> base_class(m, "base_sink"); - - base.def("last_endpoint", &base::last_endpoint) -} diff --git a/blocklib/zeromq/python/gnuradio/zeromq/bindings/meson.build b/blocklib/zeromq/python/gnuradio/zeromq/bindings/meson.build deleted file mode 100644 index 8a830aaec..000000000 --- a/blocklib/zeromq/python/gnuradio/zeromq/bindings/meson.build +++ /dev/null @@ -1,2 +0,0 @@ -# zeromq_pybind_sources = [files('base_pybind.cc')] + zeromq_pybind_sources -# zeromq_pybind_names = ['base'] + zeromq_pybind_names
\ No newline at end of file diff --git a/blocklib/zeromq/rep_sink/rep_sink.yml b/blocklib/zeromq/rep_sink/rep_sink.yml deleted file mode 100644 index 2d6a7647e..000000000 --- a/blocklib/zeromq/rep_sink/rep_sink.yml +++ /dev/null @@ -1,51 +0,0 @@ -module: zeromq -block: rep_sink -label: REP Sink -blocktype: sync_block -category: '[Core]/ZeroMQ Interfaces' -# inherits: gr::zeromq::base -# includes: -# - gnuradio/zeromq/base.h - -parameters: - - id: address - label: IP Address - dtype: string - settable: false - - id: timeout - label: Timeout - dtype: int - settable: false - default: 100 - - id: pass_tags - label: Pass Tags - dtype: bool - settable: false - default: "false" - - id: hwm - label: HWM - dtype: int - settable: false - default: -1 - - id: itemsize - label: Item Size - dtype: size - settable: false - default: 0 -callbacks: -- id: last_endpoint - return: std::string - const: true - # inherited: true - -ports: - - domain: stream - id: in - direction: input - type: untyped - size: parameters/itemsize - -implementations: - - id: cpu - -file_format: 1 diff --git a/blocklib/zeromq/rep_sink/rep_sink_cpu.cc b/blocklib/zeromq/rep_sink/rep_sink_cpu.cc deleted file mode 100644 index 7ad80d471..000000000 --- a/blocklib/zeromq/rep_sink/rep_sink_cpu.cc +++ /dev/null @@ -1,74 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2013,2014,2019 Free Software Foundation, Inc. - * - * This file is part of GNU Radio. - * - * SPDX-License-Identifier: GPL-3.0-or-later - * - */ - -#include "rep_sink_cpu.h" -#include "rep_sink_cpu_gen.h" - -namespace gr { -namespace zeromq { - -rep_sink_cpu::rep_sink_cpu(block_args args) - : INHERITED_CONSTRUCTORS, - base_sink( - ZMQ_REP, args.itemsize, args.address, args.timeout, args.pass_tags, args.hwm) -{ -} -work_return_t rep_sink_cpu::work(work_io& wio) -{ - auto in = wio.inputs()[0].items<uint8_t>(); - auto noutput_items = wio.inputs()[0].n_items; - bool first = true; - int done = 0; - - /* Process as much as we can */ - while (1) { - /* Wait for a small time (FIXME: scheduler can't wait for us) */ - /* We only wait if its the first iteration, for the others we'll - * let the scheduler retry */ - zmq::pollitem_t items[] = { { static_cast<void*>(d_socket), 0, ZMQ_POLLIN, 0 } }; - zmq::poll(&items[0], 1, std::chrono::milliseconds{ (first ? d_timeout : 0) }); - - /* If we don't have anything, we're done */ - if (!(items[0].revents & ZMQ_POLLIN)) - break; - - /* Get and parse the request */ - zmq::message_t request; - bool ok = bool(d_socket.recv(request)); - - if (!ok) { - // Should not happen, we've checked POLLIN. - d_logger->error("Failed to receive message."); - break; - } - - int nitems_send = noutput_items - done; - if (request.size() >= sizeof(uint32_t)) { - int req = (int)*(static_cast<uint32_t*>(request.data())); - nitems_send = std::min(nitems_send, req); - } - - /* Delegate the actual send */ - done += send_message(in + (done * d_vsize), - nitems_send, - wio.inputs()[0].nitems_read() + done, - wio.inputs()[0].tags_in_window(0, noutput_items)); - - /* Not the first anymore */ - first = false; - } - - wio.inputs()[0].n_consumed = done; - return work_return_t::OK; -} - - -} // namespace zeromq -} // namespace gr diff --git a/blocklib/zeromq/rep_sink/rep_sink_cpu.h b/blocklib/zeromq/rep_sink/rep_sink_cpu.h deleted file mode 100644 index 98d106c4a..000000000 --- a/blocklib/zeromq/rep_sink/rep_sink_cpu.h +++ /dev/null @@ -1,35 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2013,2014,2019 Free Software Foundation, Inc. - * - * This file is part of GNU Radio. - * - * SPDX-License-Identifier: GPL-3.0-or-later - * - */ - -#pragma once - -#include "base.h" -#include <gnuradio/zeromq/rep_sink.h> - -namespace gr { -namespace zeromq { - -class rep_sink_cpu : public virtual rep_sink, public virtual base_sink -{ -public: - rep_sink_cpu(block_args args); - work_return_t work(work_io&) override; - std::string last_endpoint() const override { return base_sink::last_endpoint(); } - - // Since vsize can be set as 0, then inferred on flowgraph init, set it during start() - bool start() override - { - set_vsize(this->input_stream_ports()[0]->itemsize()); - return rep_sink::start(); - } -}; - -} // namespace zeromq -} // namespace gr
\ No newline at end of file diff --git a/blocklib/zeromq/req_source/req_source.yml b/blocklib/zeromq/req_source/req_source.yml deleted file mode 100644 index 8980ec8f3..000000000 --- a/blocklib/zeromq/req_source/req_source.yml +++ /dev/null @@ -1,43 +0,0 @@ -module: zeromq -block: req_source -label: REQ Source -blocktype: sync_block -category: '[Core]/ZeroMQ Interfaces' -# inherits: base - -parameters: - - id: address - label: IP Address - dtype: string - settable: false - - id: timeout - label: Timeout - dtype: int - settable: false - default: 100 - - id: pass_tags - label: Pass Tags - dtype: bool - settable: false - default: "false" - - id: hwm - label: HWM - dtype: int - settable: false - default: -1 - - id: itemsize - label: Item Size - dtype: size - settable: false - default: 0 -ports: - - domain: stream - id: out - direction: output - type: untyped - size: parameters/itemsize - -implementations: - - id: cpu - -file_format: 1 diff --git a/blocklib/zeromq/req_source/req_source_cpu.cc b/blocklib/zeromq/req_source/req_source_cpu.cc deleted file mode 100644 index 2fc6f86b1..000000000 --- a/blocklib/zeromq/req_source/req_source_cpu.cc +++ /dev/null @@ -1,78 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2013,2014 Free Software Foundation, Inc. - * - * This file is part of GNU Radio. - * - * SPDX-License-Identifier: GPL-3.0-or-later - * - */ - -#include "req_source_cpu.h" -#include "req_source_cpu_gen.h" - -#include <chrono> -#include <thread> - -namespace gr { -namespace zeromq { - -req_source_cpu::req_source_cpu(block_args args) - : INHERITED_CONSTRUCTORS, - base_source( - ZMQ_REQ, args.itemsize, args.address, args.timeout, args.pass_tags, args.hwm) -{ -} - -work_return_t req_source_cpu::work(work_io& wio) -{ - - auto noutput_items = wio.outputs()[0].n_items; - bool first = true; - size_t done = 0; - - /* Process as much as we can */ - while (1) { - if (has_pending()) { - /* Flush anything pending */ - done += flush_pending(wio.outputs()[0], noutput_items - done, done); - - /* No more space ? */ - if (done == noutput_items) - break; - } - else { - - /* Send request if needed */ - if (!d_req_pending) { - /* The REP/REQ pattern state machine guarantees we can send at this point - */ - uint32_t req_len = noutput_items - done; - zmq::message_t request(sizeof(uint32_t)); - memcpy((void*)request.data(), &req_len, sizeof(uint32_t)); - d_socket.send(request, zmq::send_flags::none); - d_req_pending = true; - } - - /* Try to get the next message */ - if (!load_message(first)) { - // Launch a thread to come back and try again some time later - come_back_later(100); - break; /* No message, we're done for now */ - } - - /* Got response */ - d_req_pending = false; - - /* Not the first anymore */ - first = false; - } - } - - wio.outputs()[0].n_produced = done; - return work_return_t::OK; -} - - -} // namespace zeromq -} // namespace gr diff --git a/blocklib/zeromq/req_source/req_source_cpu.h b/blocklib/zeromq/req_source/req_source_cpu.h deleted file mode 100644 index 05cd2b6b8..000000000 --- a/blocklib/zeromq/req_source/req_source_cpu.h +++ /dev/null @@ -1,37 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2013,2014 Free Software Foundation, Inc. - * - * This file is part of GNU Radio. - * - * SPDX-License-Identifier: GPL-3.0-or-later - * - */ - -#pragma once - -#include "base.h" -#include <gnuradio/zeromq/req_source.h> - -namespace gr { -namespace zeromq { - -class req_source_cpu : public virtual req_source, public virtual base_source -{ -public: - req_source_cpu(block_args args); - work_return_t work(work_io&) override; - - // Since vsize can be set as 0, then inferred on flowgraph init, set it during start() - bool start() override - { - set_vsize(this->output_stream_ports()[0]->itemsize()); - return req_source::start(); - } - -private: - bool d_req_pending = false; -}; - -} // namespace zeromq -} // namespace gr
\ No newline at end of file diff --git a/blocklib/zeromq/sub_source/sub_source.yml b/blocklib/zeromq/sub_source/sub_source.yml deleted file mode 100644 index b461962c6..000000000 --- a/blocklib/zeromq/sub_source/sub_source.yml +++ /dev/null @@ -1,49 +0,0 @@ -module: zeromq -block: sub_source -label: SUB Source -blocktype: sync_block -category: '[Core]/ZeroMQ Interfaces' - -# Example Parameters -parameters: - - id: address - label: IP Address - dtype: string - settable: false - - id: timeout - label: Timeout - dtype: int - settable: false - default: 100 - - id: pass_tags - label: Pass Tags - dtype: bool - settable: false - default: "false" - - id: hwm - label: HWM - dtype: int - settable: false - default: -1 - - id: key - label: Key - dtype: string - settable: false - default: "\"\"" - - id: itemsize - label: Item Size - dtype: size - settable: false - default: 0 - -ports: - - domain: stream - id: out - direction: output - type: untyped - size: parameters/itemsize - -implementations: - - id: cpu - -file_format: 1
\ No newline at end of file diff --git a/blocklib/zeromq/sub_source/sub_source_cpu.cc b/blocklib/zeromq/sub_source/sub_source_cpu.cc deleted file mode 100644 index 47e8a05b4..000000000 --- a/blocklib/zeromq/sub_source/sub_source_cpu.cc +++ /dev/null @@ -1,60 +0,0 @@ -#include "sub_source_cpu.h" -#include "sub_source_cpu_gen.h" - -#include <chrono> -#include <thread> - -namespace gr { -namespace zeromq { - -sub_source_cpu::sub_source_cpu(block_args args) - : INHERITED_CONSTRUCTORS, - base_source(ZMQ_SUB, - args.itemsize, - args.address, - args.timeout, - args.pass_tags, - args.hwm, - args.key) -{ - - /* Subscribe */ - d_socket.set(zmq::sockopt::subscribe, args.key); -} - -work_return_t sub_source_cpu::work(work_io& wio) -{ - auto noutput_items = wio.outputs()[0].n_items; - bool first = true; - size_t done = 0; - - /* Process as much as we can */ - while (1) { - if (has_pending()) { - /* Flush anything pending */ - done += flush_pending(wio.outputs()[0], noutput_items - done, done); - - /* No more space ? */ - if (done == noutput_items) - break; - } - else { - /* Try to get the next message */ - if (!load_message(first)) { - // Launch a thread to come back and try again some time later - come_back_later(100); - break; /* No message, we're done for now */ - } - - /* Not the first anymore */ - first = false; - } - } - - wio.produce_each(done); - return work_return_t::OK; -} - - -} // namespace zeromq -} // namespace gr diff --git a/blocklib/zeromq/sub_source/sub_source_cpu.h b/blocklib/zeromq/sub_source/sub_source_cpu.h deleted file mode 100644 index 85ec087ac..000000000 --- a/blocklib/zeromq/sub_source/sub_source_cpu.h +++ /dev/null @@ -1,27 +0,0 @@ -#pragma once - -#include "base.h" -#include <gnuradio/zeromq/sub_source.h> - -namespace gr { -namespace zeromq { - -class sub_source_cpu : public virtual sub_source, public virtual base_source -{ -public: - sub_source_cpu(block_args args); - work_return_t work(work_io&) override; - - // Since vsize can be set as 0, then inferred on flowgraph init, set it during start() - bool start() override - { - set_vsize(this->output_stream_ports()[0]->itemsize()); - return sub_source::start(); - } - -private: - // private variables here -}; - -} // namespace zeromq -} // namespace gr
\ No newline at end of file diff --git a/blocklib/zeromq/test/.gitignore b/blocklib/zeromq/test/.gitignore deleted file mode 100644 index 01ecb66ff..000000000 --- a/blocklib/zeromq/test/.gitignore +++ /dev/null @@ -1 +0,0 @@ -!meson.build
\ No newline at end of file diff --git a/blocklib/zeromq/test/meson.build b/blocklib/zeromq/test/meson.build deleted file mode 100644 index f271695c2..000000000 --- a/blocklib/zeromq/test/meson.build +++ /dev/null @@ -1,10 +0,0 @@ -################################################### -# QA -################################################### - -if GR_ENABLE_PYTHON - test('qa_zeromq_pushpull', py3, args : files('qa_zeromq_pushpull.py'), env: TEST_ENV) - test('qa_zeromq_pull_msg_source', py3, args : files('qa_zeromq_pull_msg_source.py'), env: TEST_ENV) - test('qa_zeromq_pubsub', py3, args : files('qa_zeromq_pubsub.py'), env: TEST_ENV) - test('qa_zeromq_reqrep', py3, args : files('qa_zeromq_reqrep.py'), env: TEST_ENV) -endif diff --git a/blocklib/zeromq/test/qa_zeromq_pubsub.py b/blocklib/zeromq/test/qa_zeromq_pubsub.py deleted file mode 100644 index 4334794d8..000000000 --- a/blocklib/zeromq/test/qa_zeromq_pubsub.py +++ /dev/null @@ -1,110 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- -# -# Copyright 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 -from gnuradio import blocks, zeromq -import pmtf -import time - - -def make_tag(key, value, offset, srcid=None): - - if srcid is None: - tag = gr.tag_t(offset, {key: pmtf.pmt(value)}) - else: - tag = gr.tag_t(offset, {key: pmtf.pmt(value), "srcid": pmtf.pmt(srcid)}) - return tag - - -# def compare_tags(a, b): -# return a.offset == b.offset and pmt.equal(a.key, b.key) and \ -# pmt.equal(a.value, b.value) and pmt.equal(a.srcid, b.srcid) - - -class qa_zeromq_pubsub (gr_unittest.TestCase): - - def setUp(self): - self.send_tb = gr.top_block() - self.recv_tb = gr.top_block() - - def tearDown(self): - self.send_tb = None - self.recv_tb = None - - def test_001(self): - vlen = 10 - src_data = list(range(vlen)) * 100 - src = blocks.vector_source_f(src_data, False, vlen) - zeromq_pub_sink = zeromq.pub_sink("tcp://127.0.0.1:0", 0) - address = zeromq_pub_sink.last_endpoint() - zeromq_sub_source = zeromq.sub_source(address, 0) - sink = blocks.vector_sink_f(vlen) - self.send_tb.connect(src, zeromq_pub_sink) - self.recv_tb.connect(zeromq_sub_source, sink) - self.recv_tb.start() - time.sleep(0.5) - self.send_tb.start() - time.sleep(0.5) - self.recv_tb.stop() - self.send_tb.stop() - # self.recv_tb.wait() - # self.send_tb.wait() - self.assertFloatTuplesAlmostEqual(sink.data(), src_data) - - def test_002(self): - # same as test_001, but insert a tag and set key filter - vlen = 10 - src_data = list(range(vlen)) * 100 - - src_tags = tuple([make_tag('key', 'val', 0, 'src'), - make_tag('key', 'val', 1, 'src')]) - - src = blocks.vector_source_f(src_data, False, vlen, tags=src_tags) - zeromq_pub_sink = zeromq.pub_sink( - "tcp://127.0.0.1:0", - 0, - pass_tags=True, - key="filter_key") - address = zeromq_pub_sink.last_endpoint() - zeromq_sub_source = zeromq.sub_source(address, 0, pass_tags=True, key="filter_key") - sink = blocks.vector_sink_f(vlen) - self.send_tb.connect(src, zeromq_pub_sink) - self.recv_tb.connect(zeromq_sub_source, sink) - - # start both flowgraphs - self.recv_tb.start() - time.sleep(0.5) - self.send_tb.start() - time.sleep(0.5) - self.recv_tb.stop() - self.send_tb.stop() - self.recv_tb.wait() - self.send_tb.wait() - - # compare data - self.assertFloatTuplesAlmostEqual(sink.data(), src_data) - - # compare all tags - rx_tags = sink.tags() - self.assertEqual(len(src_tags), len(rx_tags)) - - idx = 0 - for in_tag, out_tag in zip(src_tags, rx_tags): - print(idx) - print(in_tag) - print(out_tag) - self.assertTrue(in_tag == out_tag) - idx += 1 - - -if __name__ == '__main__': - gr_unittest.run(qa_zeromq_pubsub) diff --git a/blocklib/zeromq/test/qa_zeromq_pull_msg_source.py b/blocklib/zeromq/test/qa_zeromq_pull_msg_source.py deleted file mode 100644 index ff161b9c7..000000000 --- a/blocklib/zeromq/test/qa_zeromq_pull_msg_source.py +++ /dev/null @@ -1,66 +0,0 @@ -#!/usr/bin/env python -# -# Copyright 2020 Free Software Foundation, Inc. -# -# This file is part of GNU Radio -# -# SPDX-License-Identifier: GPL-3.0-or-later -# -# -"""Unit tests for ZMQ PULL Message Source block""" - -import time -import zmq - -from gnuradio import gr, gr_unittest, blocks, zeromq -import pmtf - - -class qa_zeromq_pull_msg_source(gr_unittest.TestCase): - """Unit tests for ZMQ PULL Message Source block""" - - def setUp(self): - addr = 'tcp://127.0.0.1' - self.context = zmq.Context() - self.zmq_sock = self.context.socket(zmq.PUSH) - port = self.zmq_sock.bind_to_random_port(addr) - - self.zeromq_pull_msg_source = zeromq.pull_msg_source( - ('%s:%s' % (addr, port)), 100) - self.message_debug = blocks.message_debug() - self.tb = gr.top_block() - self.tb.connect( - (self.zeromq_pull_msg_source, 'out'), (self.message_debug, 'store')) - - self.tb.start() - time.sleep(0.1) - - def tearDown(self): - self.tb.stop() - self.tb.wait() - self.zeromq_pull_msg_source = None - self.message_debug = None - self.tb = None - self.zmq_sock.close() - self.context.term() - - def test_valid_pmt(self): - """Test receiving of valid PMT messages""" - msg = pmtf.pmt('test_valid_pmt') - self.zmq_sock.send(bytes(msg.serialize())) - for _ in range(10): - if self.message_debug.num_messages() > 0: - break - time.sleep(0.2) - self.assertEqual(1, self.message_debug.num_messages()) - self.assertEqual(msg(), self.message_debug.get_message(0)()) - - # def test_invalid_pmt(self): - # """Test receiving of invalid PMT messages""" - # self.zmq_sock.send_string('test_invalid_pmt') - # time.sleep(0.1) - # self.assertEqual(0, self.message_debug.num_messages()()) - - -if __name__ == '__main__': - gr_unittest.run(qa_zeromq_pull_msg_source) diff --git a/blocklib/zeromq/test/qa_zeromq_pushpull.py b/blocklib/zeromq/test/qa_zeromq_pushpull.py deleted file mode 100644 index ea18ed7b1..000000000 --- a/blocklib/zeromq/test/qa_zeromq_pushpull.py +++ /dev/null @@ -1,46 +0,0 @@ -#!/usr/bin/env python -# -# Copyright 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, blocks, zeromq -import time - - -class qa_zeromq_pushpull (gr_unittest.TestCase): - - def setUp(self): - self.send_tb = gr.top_block() - self.recv_tb = gr.top_block() - - def tearDown(self): - self.send_tb = None - self.recv_tb = None - - def test_001(self): - vlen = 10 - src_data = list(range(vlen)) * 100 - src = blocks.vector_source_f(src_data, False, vlen) - zeromq_push_sink = zeromq.push_sink("tcp://127.0.0.1:0") - address = zeromq_push_sink.last_endpoint() - zeromq_pull_source = zeromq.pull_source(address, 0) - sink = blocks.vector_sink_f(vlen) - self.send_tb.connect(src, zeromq_push_sink) - self.recv_tb.connect(zeromq_pull_source, sink) - self.recv_tb.start() - # time.sleep(0.5) - self.send_tb.start() - time.sleep(0.5) - self.recv_tb.stop() - self.send_tb.stop() - self.assertFloatTuplesAlmostEqual(sink.data(), src_data) - - -if __name__ == '__main__': - gr_unittest.run(qa_zeromq_pushpull) diff --git a/blocklib/zeromq/test/qa_zeromq_reqrep.py b/blocklib/zeromq/test/qa_zeromq_reqrep.py deleted file mode 100644 index 733bf2f03..000000000 --- a/blocklib/zeromq/test/qa_zeromq_reqrep.py +++ /dev/null @@ -1,50 +0,0 @@ -#!/usr/bin/env python3 -# -*- coding: utf-8 -*- -# -# Copyright 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 -from gnuradio import blocks, zeromq -import time - - -class qa_zeromq_reqrep (gr_unittest.TestCase): - - def setUp(self): - self.send_tb = gr.top_block() - self.recv_tb = gr.top_block() - - def tearDown(self): - self.send_tb = None - self.recv_tb = None - - def test_001(self): - vlen = 10 - src_data = list(range(vlen)) * 100 - src = blocks.vector_source_f(src_data, False, vlen) - zeromq_rep_sink = zeromq.rep_sink("tcp://127.0.0.1:0", 0) - address = zeromq_rep_sink.last_endpoint() - zeromq_req_source = zeromq.req_source(address, 0) - sink = blocks.vector_sink_f(vlen) - self.send_tb.connect(src, zeromq_rep_sink) - self.recv_tb.connect(zeromq_req_source, sink) - self.recv_tb.start() - time.sleep(0.5) - self.send_tb.start() - time.sleep(0.5) - self.recv_tb.stop() - self.send_tb.stop() - self.recv_tb.wait() - self.send_tb.wait() - self.assertFloatTuplesAlmostEqual(sink.data(), src_data) - - -if __name__ == '__main__': - gr_unittest.run(qa_zeromq_reqrep) |