aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJosh Morman <jmorman@gnuradio.org>2022-11-10 11:44:53 -0500
committerJosh Morman <jmorman@gnuradio.org>2022-11-10 11:44:55 -0500
commitb5b05f7c2a5e708db525fa8c3ef7ff2f1f7816d3 (patch)
tree5e202f5275b199dee99d37221c0690c63e748935
parentfilter: pfb_arb_resampler updated to new block api and use optfir (diff)
downloadgnuradio-dev-4.0-minimal.tar.xz
gnuradio-dev-4.0-minimal.zip
global: strip down to minimal filesetdev-4.0-minimal
As a separate branch to start incorporating broader refactoring changes Signed-off-by: Josh Morman <jmorman@gnuradio.org>
-rw-r--r--bench/bm_nop.cc123
-rw-r--r--bench/meson.build12
-rw-r--r--blocklib/analog/.gitignore1
-rw-r--r--blocklib/analog/agc/agc.yml43
-rw-r--r--blocklib/analog/agc/agc_cpu.cc27
-rw-r--r--blocklib/analog/agc/agc_cpu.h20
-rw-r--r--blocklib/analog/enums.yml24
-rw-r--r--blocklib/analog/examples/fm_rx.grc207
-rwxr-xr-xblocklib/analog/examples/fm_rx.py185
-rw-r--r--blocklib/analog/fm_deemph/fm_deemph.yml116
-rw-r--r--blocklib/analog/fm_deemph/fm_deemph_cpu.cc47
-rw-r--r--blocklib/analog/fm_deemph/fm_deemph_cpu.h29
-rw-r--r--blocklib/analog/include/gnuradio/analog/.gitignore1
-rw-r--r--blocklib/analog/include/gnuradio/analog/meson.build0
-rw-r--r--blocklib/analog/lib/.gitignore1
-rw-r--r--blocklib/analog/lib/meson.build54
-rw-r--r--blocklib/analog/noise_source/noise_source.yml45
-rw-r--r--blocklib/analog/noise_source/noise_source_cpu.cc77
-rw-r--r--blocklib/analog/noise_source/noise_source_cpu.h33
-rw-r--r--blocklib/analog/python/gnuradio/analog/.gitignore1
-rw-r--r--blocklib/analog/python/gnuradio/analog/__init__.py12
-rw-r--r--blocklib/analog/python/gnuradio/analog/fm_deemph_hier.py36
-rw-r--r--blocklib/analog/quadrature_demod/quadrature_demod.yml57
-rw-r--r--blocklib/analog/quadrature_demod/quadrature_demod_cpu.cc50
-rw-r--r--blocklib/analog/quadrature_demod/quadrature_demod_cpu.h30
-rw-r--r--blocklib/analog/random_source/random_source.yml59
-rw-r--r--blocklib/analog/sig_source/.gitignore1
-rw-r--r--blocklib/analog/sig_source/sig_source.yml67
-rw-r--r--blocklib/analog/sig_source/sig_source_cpu.cc215
-rw-r--r--blocklib/analog/sig_source/sig_source_cpu.h58
-rw-r--r--blocklib/analog/test/.gitignore1
-rw-r--r--blocklib/analog/test/meson.build9
-rw-r--r--blocklib/analog/test/qa_agc.py497
-rw-r--r--blocklib/analog/test/qa_noise.py40
-rw-r--r--blocklib/analog/test/qa_quadrature_demod.py55
-rw-r--r--blocklib/analog/test/qa_sig_source.py224
-rw-r--r--blocklib/audio/.gitignore1
-rw-r--r--blocklib/audio/alsa_sink/alsa_sink.yml49
-rw-r--r--blocklib/audio/alsa_sink/alsa_sink_cpu.cc521
-rw-r--r--blocklib/audio/alsa_sink/alsa_sink_cpu.h68
-rw-r--r--blocklib/audio/examples/.gitignore1
-rw-r--r--blocklib/audio/examples/alsa_tones.grc154
-rw-r--r--blocklib/audio/include/gnuradio/audio/.gitignore1
-rw-r--r--blocklib/audio/include/gnuradio/audio/meson.build3
-rw-r--r--blocklib/audio/lib/.gitignore1
-rw-r--r--blocklib/audio/lib/alsa_internal.cc172
-rw-r--r--blocklib/audio/lib/alsa_internal.h89
-rw-r--r--blocklib/audio/lib/meson.build42
-rw-r--r--blocklib/audio/python/gnuradio/audio/.gitignore1
-rw-r--r--blocklib/audio/python/gnuradio/audio/__init__.py9
-rw-r--r--blocklib/audio/test/.gitignore1
-rw-r--r--blocklib/audio/test/meson.build3
-rw-r--r--blocklib/blocks/nop_source/nop_source.yml33
-rw-r--r--blocklib/blocks/nop_source/nop_source_cpu.cc29
-rw-r--r--blocklib/blocks/nop_source/nop_source_cpu.h27
-rw-r--r--blocklib/fec/include/gnuradio/fec/.gitignore1
-rw-r--r--blocklib/fec/include/gnuradio/fec/api.h18
-rw-r--r--blocklib/fec/include/gnuradio/fec/meson.build6
-rw-r--r--blocklib/fec/include/gnuradio/fec/rs.h41
-rw-r--r--blocklib/fec/lib/.gitignore1
-rw-r--r--blocklib/fec/lib/meson.build21
-rw-r--r--blocklib/fec/lib/reed-solomon/Makefile.in.karn99
-rw-r--r--blocklib/fec/lib/reed-solomon/README2
-rw-r--r--blocklib/fec/lib/reed-solomon/README.karn22
-rw-r--r--blocklib/fec/lib/reed-solomon/ccsds.c10
-rw-r--r--blocklib/fec/lib/reed-solomon/ccsds.h1
-rw-r--r--blocklib/fec/lib/reed-solomon/ccsds_tab.c45
-rw-r--r--blocklib/fec/lib/reed-solomon/ccsds_tal.c40
-rw-r--r--blocklib/fec/lib/reed-solomon/char.c9
-rw-r--r--blocklib/fec/lib/reed-solomon/char.h58
-rw-r--r--blocklib/fec/lib/reed-solomon/decode_rs.h273
-rw-r--r--blocklib/fec/lib/reed-solomon/decode_rs_ccsds.c28
-rw-r--r--blocklib/fec/lib/reed-solomon/encode_rs.h56
-rw-r--r--blocklib/fec/lib/reed-solomon/encode_rs_ccsds.c25
-rw-r--r--blocklib/fec/lib/reed-solomon/exercise.c136
-rw-r--r--blocklib/fec/lib/reed-solomon/fixed.h41
-rw-r--r--blocklib/fec/lib/reed-solomon/gen_ccsds.c35
-rw-r--r--blocklib/fec/lib/reed-solomon/gen_ccsds_tal.c50
-rw-r--r--blocklib/fec/lib/reed-solomon/init_rs.c163
-rw-r--r--blocklib/fec/lib/reed-solomon/int.h56
-rw-r--r--blocklib/fec/lib/reed-solomon/meson.build71
-rw-r--r--blocklib/fec/lib/reed-solomon/rs.3170
-rw-r--r--blocklib/fec/lib/reed-solomon/rstest.c123
-rw-r--r--blocklib/fec/meson.build19
-rw-r--r--blocklib/fec/python/gnuradio/fec/meson.build0
-rw-r--r--blocklib/fft/.gitignore1
-rw-r--r--blocklib/fft/bench/bm_fft.py118
-rw-r--r--blocklib/fft/fft/fft.yml54
-rw-r--r--blocklib/fft/fft/fft_cpu.cc198
-rw-r--r--blocklib/fft/fft/fft_cpu.h41
-rw-r--r--blocklib/fft/fft/fft_cuda.cc102
-rw-r--r--blocklib/fft/fft/fft_cuda.h39
-rw-r--r--blocklib/fft/fft/fft_shift.cu39
-rw-r--r--blocklib/fft/include/gnuradio/fft/.gitignore1
-rw-r--r--blocklib/fft/include/gnuradio/fft/api.h18
-rw-r--r--blocklib/fft/include/gnuradio/fft/meson.build7
-rw-r--r--blocklib/fft/lib/.gitignore1
-rw-r--r--blocklib/fft/lib/meson.build60
-rw-r--r--blocklib/fft/python/gnuradio/fft/.gitignore2
-rw-r--r--blocklib/fft/python/gnuradio/fft/__init__.py9
-rw-r--r--blocklib/fft/python/gnuradio/fft/bindings/meson.build2
-rw-r--r--blocklib/fft/python/gnuradio/fft/bindings/window_pybind.cc174
-rw-r--r--blocklib/fft/test/.gitignore1
-rw-r--r--blocklib/fft/test/meson.build11
-rw-r--r--blocklib/fft/test/qa_cufft.py280
-rw-r--r--blocklib/fft/test/qa_fft.py280
-rw-r--r--blocklib/fileio/.gitignore1
-rw-r--r--blocklib/fileio/file_sink/file_sink.yml40
-rw-r--r--blocklib/fileio/file_sink/file_sink_cpu.cc76
-rw-r--r--blocklib/fileio/file_sink/file_sink_cpu.h40
-rw-r--r--blocklib/fileio/file_source/file_source.yml52
-rw-r--r--blocklib/fileio/file_source/file_source_cpu.cc335
-rw-r--r--blocklib/fileio/file_source/file_source_cpu.h77
-rw-r--r--blocklib/fileio/include/gnuradio/fileio/.gitignore1
-rw-r--r--blocklib/fileio/include/gnuradio/fileio/file_sink_base.h67
-rw-r--r--blocklib/fileio/include/gnuradio/fileio/meson.build0
-rw-r--r--blocklib/fileio/lib/.gitignore1
-rw-r--r--blocklib/fileio/lib/file_sink_base.cc120
-rw-r--r--blocklib/fileio/lib/meson.build52
-rw-r--r--blocklib/fileio/python/gnuradio/fileio/.gitignore1
-rw-r--r--blocklib/fileio/python/gnuradio/fileio/__init__.py9
-rw-r--r--blocklib/fileio/python/gnuradio/fileio/bindings/file_sink_base_pybind.cc26
-rw-r--r--blocklib/fileio/test/.gitignore1
-rw-r--r--blocklib/fileio/test/meson.build9
-rw-r--r--blocklib/fileio/test/qa_file_sink.py52
-rw-r--r--blocklib/fileio/test/qa_file_source.py152
-rw-r--r--blocklib/filter/.gitignore1
-rw-r--r--blocklib/filter/bench/bm_pfb_channelizer.py130
-rw-r--r--blocklib/filter/dc_blocker/dc_blocker.yml40
-rw-r--r--blocklib/filter/dc_blocker/dc_blocker_cpu.cc79
-rw-r--r--blocklib/filter/dc_blocker/dc_blocker_cpu.h41
-rw-r--r--blocklib/filter/examples/.gitignore1
-rw-r--r--blocklib/filter/examples/pfb_channelizer_example.grc263
-rw-r--r--blocklib/filter/fir_filter/fir_filter.yml70
-rw-r--r--blocklib/filter/fir_filter/fir_filter_cpu.cc90
-rw-r--r--blocklib/filter/fir_filter/fir_filter_cpu.h38
-rw-r--r--blocklib/filter/fir_filter/qa_fir_filter.py194
-rw-r--r--blocklib/filter/iir_filter/iir_filter.yml69
-rw-r--r--blocklib/filter/iir_filter/iir_filter_cpu.cc38
-rw-r--r--blocklib/filter/iir_filter/iir_filter_cpu.h49
-rw-r--r--blocklib/filter/include/gnuradio/filter/.gitignore1
-rw-r--r--blocklib/filter/include/gnuradio/filter/api.h18
-rw-r--r--blocklib/filter/include/gnuradio/filter/meson.build11
-rw-r--r--blocklib/filter/lib/.gitignore1
-rw-r--r--blocklib/filter/lib/meson.build60
-rw-r--r--blocklib/filter/moving_average/moving_average.yml50
-rw-r--r--blocklib/filter/moving_average/moving_average_cpu.cc89
-rw-r--r--blocklib/filter/moving_average/moving_average_cpu.h47
-rw-r--r--blocklib/filter/moving_average/moving_average_cuda.cc72
-rw-r--r--blocklib/filter/moving_average/moving_average_cuda.h48
-rw-r--r--blocklib/filter/pfb_arb_resampler/pfb_arb_resampler.yml79
-rw-r--r--blocklib/filter/pfb_arb_resampler/pfb_arb_resampler_cpu.cc138
-rw-r--r--blocklib/filter/pfb_arb_resampler/pfb_arb_resampler_cpu.h130
-rw-r--r--blocklib/filter/pfb_arb_resampler/qa_pfb_arb_resampler.py305
-rw-r--r--blocklib/filter/pfb_channelizer/pfb_channelizer.yml47
-rw-r--r--blocklib/filter/pfb_channelizer/pfb_channelizer_cpu.cc180
-rw-r--r--blocklib/filter/pfb_channelizer/pfb_channelizer_cpu.h51
-rw-r--r--blocklib/filter/pfb_channelizer/pfb_channelizer_cuda.cc81
-rw-r--r--blocklib/filter/pfb_channelizer/pfb_channelizer_cuda.h47
-rw-r--r--blocklib/filter/python/gnuradio/filter/.gitignore2
-rw-r--r--blocklib/filter/python/gnuradio/filter/__init__.py9
-rw-r--r--blocklib/filter/python/gnuradio/filter/bindings/firdes_pybind.cc203
-rw-r--r--blocklib/filter/python/gnuradio/filter/bindings/meson.build2
-rw-r--r--blocklib/filter/python/gnuradio/filter/meson.build54
-rw-r--r--blocklib/filter/test/.gitignore1
-rw-r--r--blocklib/filter/test/cuda/qa_moving_average_cuda.py232
-rw-r--r--blocklib/filter/test/meson.build10
-rw-r--r--blocklib/filter/test/qa_fir_filter.py196
-rw-r--r--blocklib/filter/test/qa_iir_filter.py403
-rw-r--r--blocklib/filter/test/qa_moving_average.py232
-rw-r--r--blocklib/filter/test/qa_pfb_arb_resampler.py305
-rw-r--r--blocklib/filter/test/qa_pfb_channelizer.py149
-rw-r--r--blocklib/math/complex_to_mag/complex_to_mag.yml31
-rw-r--r--blocklib/math/complex_to_mag/complex_to_mag_cpu.cc41
-rw-r--r--blocklib/math/complex_to_mag/complex_to_mag_cpu.h29
-rw-r--r--blocklib/math/complex_to_mag_squared/complex_to_mag_squared.yml31
-rw-r--r--blocklib/math/complex_to_mag_squared/complex_to_mag_squared_cpu.cc40
-rw-r--r--blocklib/math/complex_to_mag_squared/complex_to_mag_squared_cpu.h31
-rw-r--r--blocklib/math/divide/divide.yml46
-rw-r--r--blocklib/math/divide/divide_cpu.cc100
-rw-r--r--blocklib/math/divide/divide_cpu.h33
-rw-r--r--blocklib/math/multiply/multiply.yml46
-rw-r--r--blocklib/math/multiply/multiply_cpu.cc95
-rw-r--r--blocklib/math/multiply/multiply_cpu.h33
-rw-r--r--blocklib/math/test/meson.build1
-rw-r--r--blocklib/math/test/qa_add_mult_div_sub.py68
-rw-r--r--blocklib/math/test/qa_type_conversions.py324
-rw-r--r--blocklib/meson.build25
-rw-r--r--blocklib/soapy/.gitignore5
-rw-r--r--blocklib/soapy/hackrf_sink/hackrf_sink.yml92
-rw-r--r--blocklib/soapy/hackrf_source/hackrf_source.yml104
-rw-r--r--blocklib/soapy/include/gnuradio/soapy/api.h19
-rw-r--r--blocklib/soapy/include/gnuradio/soapy/block.h726
-rw-r--r--blocklib/soapy/include/gnuradio/soapy/meson.build3
-rw-r--r--blocklib/soapy/include/gnuradio/soapy/soapy_types.h32
-rw-r--r--blocklib/soapy/lib/block_impl.cc1660
-rw-r--r--blocklib/soapy/lib/block_impl.h294
-rw-r--r--blocklib/soapy/lib/meson.build40
-rw-r--r--blocklib/soapy/lib/setting_string_conversion.h84
-rw-r--r--blocklib/soapy/limesdr_source/limesdr_source.yml92
-rw-r--r--blocklib/soapy/python/gnuradio/soapy/__init__.py9
-rw-r--r--blocklib/soapy/python/gnuradio/soapy/bindings/block_pybind.cc657
-rw-r--r--blocklib/soapy/python/gnuradio/soapy/bindings/meson.build2
-rw-r--r--blocklib/soapy/python/gnuradio/soapy/bindings/soapy_common.cc64
-rw-r--r--blocklib/soapy/python/gnuradio/soapy/bindings/soapy_common.h29
-rw-r--r--blocklib/soapy/python/gnuradio/soapy/bindings/soapy_types_pybind.cc83
-rw-r--r--blocklib/soapy/rtlsdr_source/rtlsdr_source.yml92
-rw-r--r--blocklib/soapy/sink/sink.yml84
-rw-r--r--blocklib/soapy/sink/sink_cpu.cc77
-rw-r--r--blocklib/soapy/sink/sink_cpu.h22
-rw-r--r--blocklib/soapy/source/source.yml75
-rw-r--r--blocklib/soapy/source/source_cpu.cc102
-rw-r--r--blocklib/soapy/source/source_cpu.h21
-rw-r--r--blocklib/soapy/test/meson.build0
-rw-r--r--blocklib/soapy/test/test_soapy.py27
-rw-r--r--blocklib/streamops/annotator/annotator.yml61
-rw-r--r--blocklib/streamops/annotator/annotator_cpu.cc82
-rw-r--r--blocklib/streamops/annotator/annotator_cpu.h36
-rw-r--r--blocklib/streamops/deinterleave/deinterleave.yml70
-rw-r--r--blocklib/streamops/deinterleave/deinterleave_cpu.cc83
-rw-r--r--blocklib/streamops/deinterleave/deinterleave_cpu.h30
-rw-r--r--blocklib/streamops/interleave/interleave.yml72
-rw-r--r--blocklib/streamops/interleave/interleave_cpu.cc65
-rw-r--r--blocklib/streamops/interleave/interleave_cpu.h31
-rw-r--r--blocklib/streamops/interleaved_short_to_complex/interleaved_short_to_complex.yml35
-rw-r--r--blocklib/streamops/interleaved_short_to_complex/interleaved_short_to_complex_cpu.cc54
-rw-r--r--blocklib/streamops/interleaved_short_to_complex/interleaved_short_to_complex_cpu.h36
-rw-r--r--blocklib/streamops/keep_m_in_n/keep_m_in_n.yml52
-rw-r--r--blocklib/streamops/keep_m_in_n/keep_m_in_n_cpu.cc102
-rw-r--r--blocklib/streamops/keep_m_in_n/keep_m_in_n_cpu.h29
-rw-r--r--blocklib/streamops/keep_m_in_n/keep_m_in_n_cuda.cc111
-rw-r--r--blocklib/streamops/keep_m_in_n/keep_m_in_n_cuda.h35
-rw-r--r--blocklib/streamops/nop/nop.yml33
-rw-r--r--blocklib/streamops/nop/nop_cpu.cc26
-rw-r--r--blocklib/streamops/nop/nop_cpu.h24
-rw-r--r--blocklib/streamops/nop_head/nop_head.yml36
-rw-r--r--blocklib/streamops/nop_head/nop_head_cpu.cc45
-rw-r--r--blocklib/streamops/nop_head/nop_head_cpu.h28
-rw-r--r--blocklib/streamops/probe_signal/probe_signal.yml34
-rw-r--r--blocklib/streamops/probe_signal/probe_signal_cpu.cc38
-rw-r--r--blocklib/streamops/probe_signal/probe_signal_cpu.h32
-rw-r--r--blocklib/streamops/probe_signal_v/probe_signal_v.yml45
-rw-r--r--blocklib/streamops/probe_signal_v/probe_signal_v_cpu.cc39
-rw-r--r--blocklib/streamops/probe_signal_v/probe_signal_v_cpu.h40
-rw-r--r--blocklib/streamops/selector/selector.yml67
-rw-r--r--blocklib/streamops/selector/selector_cpu.cc63
-rw-r--r--blocklib/streamops/selector/selector_cpu.h30
-rw-r--r--blocklib/streamops/stream_to_streams/stream_to_streams.yml38
-rw-r--r--blocklib/streamops/stream_to_streams/stream_to_streams_cpu.cc49
-rw-r--r--blocklib/streamops/stream_to_streams/stream_to_streams_cpu.h28
-rw-r--r--blocklib/streamops/stream_to_streams/stream_to_streams_cuda.cc57
-rw-r--r--blocklib/streamops/stream_to_streams/stream_to_streams_cuda.h37
-rw-r--r--blocklib/streamops/test/meson.build5
-rw-r--r--blocklib/streamops/test/qa_interleave.py138
-rw-r--r--blocklib/streamops/test/qa_keep_m_in_n.py94
-rw-r--r--blocklib/streamops/test/qa_probe_signal.py92
-rw-r--r--blocklib/streamops/test/qa_selector.py221
-rw-r--r--blocklib/streamops/test/qa_type_conversions.py321
-rw-r--r--blocklib/zeromq/.gitignore1
-rw-r--r--blocklib/zeromq/include/gnuradio/zeromq/.gitignore1
-rw-r--r--blocklib/zeromq/include/gnuradio/zeromq/api.h18
-rw-r--r--blocklib/zeromq/include/gnuradio/zeromq/meson.build25
-rw-r--r--blocklib/zeromq/lib/.gitignore1
-rw-r--r--blocklib/zeromq/lib/base.cc236
-rw-r--r--blocklib/zeromq/lib/base.h89
-rw-r--r--blocklib/zeromq/lib/meson.build36
-rw-r--r--blocklib/zeromq/lib/tag_headers.cc89
-rw-r--r--blocklib/zeromq/lib/tag_headers.h28
-rw-r--r--blocklib/zeromq/lib/zmq_common_impl.h13
-rw-r--r--blocklib/zeromq/pub_sink/pub_sink.yml55
-rw-r--r--blocklib/zeromq/pub_sink/pub_sink_cpu.cc33
-rw-r--r--blocklib/zeromq/pub_sink/pub_sink_cpu.h28
-rw-r--r--blocklib/zeromq/pull_msg_source/pull_msg_source.yml37
-rw-r--r--blocklib/zeromq/pull_msg_source/pull_msg_source_cpu.cc96
-rw-r--r--blocklib/zeromq/pull_msg_source/pull_msg_source_cpu.h45
-rw-r--r--blocklib/zeromq/pull_source/pull_source.yml43
-rw-r--r--blocklib/zeromq/pull_source/pull_source_cpu.cc53
-rw-r--r--blocklib/zeromq/pull_source/pull_source_cpu.h24
-rw-r--r--blocklib/zeromq/push_msg_sink/push_msg_sink.yml38
-rw-r--r--blocklib/zeromq/push_msg_sink/push_msg_sink_cpu.cc50
-rw-r--r--blocklib/zeromq/push_msg_sink/push_msg_sink_cpu.h40
-rw-r--r--blocklib/zeromq/push_sink/push_sink.yml51
-rw-r--r--blocklib/zeromq/push_sink/push_sink_cpu.cc34
-rw-r--r--blocklib/zeromq/push_sink/push_sink_cpu.h25
-rw-r--r--blocklib/zeromq/python/gnuradio/zeromq/.gitignore1
-rw-r--r--blocklib/zeromq/python/gnuradio/zeromq/__init__.py9
-rw-r--r--blocklib/zeromq/python/gnuradio/zeromq/bindings/.gitignore1
-rw-r--r--blocklib/zeromq/python/gnuradio/zeromq/bindings/base_pybind.cc39
-rw-r--r--blocklib/zeromq/python/gnuradio/zeromq/bindings/meson.build2
-rw-r--r--blocklib/zeromq/rep_sink/rep_sink.yml51
-rw-r--r--blocklib/zeromq/rep_sink/rep_sink_cpu.cc74
-rw-r--r--blocklib/zeromq/rep_sink/rep_sink_cpu.h35
-rw-r--r--blocklib/zeromq/req_source/req_source.yml43
-rw-r--r--blocklib/zeromq/req_source/req_source_cpu.cc78
-rw-r--r--blocklib/zeromq/req_source/req_source_cpu.h37
-rw-r--r--blocklib/zeromq/sub_source/sub_source.yml49
-rw-r--r--blocklib/zeromq/sub_source/sub_source_cpu.cc60
-rw-r--r--blocklib/zeromq/sub_source/sub_source_cpu.h27
-rw-r--r--blocklib/zeromq/test/.gitignore1
-rw-r--r--blocklib/zeromq/test/meson.build10
-rw-r--r--blocklib/zeromq/test/qa_zeromq_pubsub.py110
-rw-r--r--blocklib/zeromq/test/qa_zeromq_pull_msg_source.py66
-rw-r--r--blocklib/zeromq/test/qa_zeromq_pushpull.py46
-rw-r--r--blocklib/zeromq/test/qa_zeromq_reqrep.py50
-rw-r--r--gr/include/gnuradio/buffer_cpu_host.h142
-rw-r--r--gr/include/gnuradio/buffer_cuda.h84
-rw-r--r--gr/include/gnuradio/buffer_cuda_pinned.h67
-rw-r--r--gr/include/gnuradio/buffer_cuda_sm.h151
-rw-r--r--gr/include/gnuradio/buffer_net_zmq.h137
-rw-r--r--gr/include/gnuradio/buffer_sm.h107
-rw-r--r--gr/include/gnuradio/meson.build4
-rw-r--r--gr/include/moodycamel/LICENSE.md62
-rw-r--r--gr/include/moodycamel/blockingconcurrentqueue.h615
-rw-r--r--gr/include/moodycamel/concurrentqueue.h4506
-rw-r--r--gr/include/moodycamel/lightweightsemaphore.h415
-rw-r--r--gr/include/moodycamel/meson.build5
-rw-r--r--gr/lib/buffer_cpu_host.cc96
-rw-r--r--gr/lib/buffer_cuda.cc162
-rw-r--r--gr/lib/buffer_cuda_pinned.cc80
-rw-r--r--gr/lib/buffer_cuda_sm.cc164
-rw-r--r--gr/lib/buffer_net_zmq.cc175
-rw-r--r--gr/lib/buffer_sm.cc374
-rw-r--r--gr/lib/meson.build3
-rw-r--r--gr/meson.build1
-rw-r--r--gr/python/gnuradio/gr/bindings/buffer_net_zmq_pybind.cc37
-rw-r--r--gr/python/gnuradio/gr/bindings/gr_pybind.cc2
-rw-r--r--gr/python/gnuradio/gr/bindings/meson.build1
-rw-r--r--gr/test/meson.build18
-rw-r--r--gr/test/qa_host_buffer.cc281
-rw-r--r--meson.build6
-rw-r--r--schedulers/nbt/include/gnuradio/schedulers/nbt/scheduler_nbt.h11
-rw-r--r--test/meson.build3
-rw-r--r--test/qa_single_mapped_buffers.cc139
-rw-r--r--test/qa_tags.cc251
-rw-r--r--test/qa_zmq_buffers.cc54
335 files changed, 45 insertions, 30387 deletions
diff --git a/bench/bm_nop.cc b/bench/bm_nop.cc
deleted file mode 100644
index 8ed44379d..000000000
--- a/bench/bm_nop.cc
+++ /dev/null
@@ -1,123 +0,0 @@
-#include <chrono>
-#include <iostream>
-#include <thread>
-
-#include <gnuradio/blocks/nop_source.h>
-#include <gnuradio/blocks/null_sink.h>
-#include <gnuradio/buffer_cpu_simple.h>
-#include <gnuradio/buffer_cpu_vmcirc.h>
-#include <gnuradio/flowgraph.h>
-#include <gnuradio/realtime.h>
-#include <gnuradio/runtime.h>
-#include <gnuradio/schedulers/nbt/scheduler_nbt.h>
-#include <gnuradio/streamops/nop.h>
-#include <gnuradio/streamops/nop_head.h>
-
-#include <iostream>
-
-#include "CLI/App.hpp"
-#include "CLI/Config.hpp"
-#include "CLI/Formatter.hpp"
-
-using namespace gr;
-
-int main(int argc, char* argv[])
-{
- uint64_t samples = 15000000;
- int nblocks = 1;
- int nthreads = 0;
- int veclen = 1;
- int buffer_type = 0;
- bool rt_prio = false;
-
- CLI::App app{ "App description" };
-
- app.add_option("--samples", samples, "Number of Samples");
- app.add_option("--veclen", veclen, "Vector Length");
- app.add_option("--nblocks", nblocks, "Number of copy blocks");
- app.add_option("--nthreads", nthreads, "Number of threads (0:tpb)");
- app.add_option("--buffer_type",
- buffer_type,
- "Buffer Type (0:simple, 1:vmcirc, 2:cuda, 3:cuda_pinned");
- app.add_flag("--rt_prio", rt_prio, "Enable Real-time priority");
-
- if (rt_prio && gr::enable_realtime_scheduling() != rt_status_t::OK) {
- std::cout << "Error: failed to enable real-time scheduling." << std::endl;
- }
-
- {
- auto src = blocks::nop_source::make({ 1, sizeof(gr_complex) * veclen });
- auto head =
- streamops::nop_head::make({ samples / veclen, sizeof(gr_complex) * veclen });
- auto snk = blocks::null_sink::make({ 1, sizeof(gr_complex) * veclen });
- std::vector<streamops::nop::sptr> blks(nblocks);
- for (int i = 0; i < nblocks; i++) {
- blks[i] = streamops::nop::make({ sizeof(gr_complex) * veclen });
- }
- flowgraph_sptr fg(new flowgraph());
-
- if (buffer_type == 0) {
- fg->connect(src, 0, head, 0);
- fg->connect(head, 0, blks[0], 0);
- for (int i = 0; i < nblocks - 1; i++) {
- fg->connect(blks[i], 0, blks[i + 1], 0);
- }
- fg->connect(blks[nblocks - 1], 0, snk, 0);
- }
- else {
- fg->connect(src, 0, head, 0)->set_custom_buffer(BUFFER_CPU_VMCIRC_ARGS);
- fg->connect(head, 0, blks[0], 0)->set_custom_buffer(BUFFER_CPU_VMCIRC_ARGS);
- for (int i = 0; i < nblocks - 1; i++) {
- fg->connect(blks[i], 0, blks[i + 1], 0)
- ->set_custom_buffer(BUFFER_CPU_VMCIRC_ARGS);
- }
- fg->connect(blks[nblocks - 1], 0, snk, 0)
- ->set_custom_buffer(BUFFER_CPU_VMCIRC_ARGS);
- }
-
- auto sched = schedulers::scheduler_nbt::make();
- if (buffer_type == 1) {
- sched->set_default_buffer_factory(BUFFER_CPU_VMCIRC_ARGS);
- }
-
- if (nthreads > 0) {
- int blks_per_thread = nblocks / nthreads;
-
- for (int i = 0; i < nthreads; i++) {
- std::vector<block_sptr> block_group;
- if (i == 0) {
- block_group.push_back(src);
- block_group.push_back(head);
- }
-
- for (int j = 0; j < blks_per_thread; j++) {
- block_group.push_back(blks[i * blks_per_thread + j]);
- }
-
- if (i == nthreads - 1) {
- for (int j = 0; j < (nblocks - nthreads * blks_per_thread); j++) {
- block_group.push_back(blks[(i + 1) * blks_per_thread + j]);
- }
- block_group.push_back(snk);
- }
- sched->add_block_group(block_group);
- }
- }
-
- fg->validate();
-
- auto rt = runtime::make();
- rt->add_scheduler(sched);
- rt->initialize(fg);
- auto t1 = std::chrono::steady_clock::now();
- rt->start();
- rt->wait();
-
-
- auto t2 = std::chrono::steady_clock::now();
- auto time =
- std::chrono::duration_cast<std::chrono::nanoseconds>(t2 - t1).count() / 1e9;
-
- std::cout << "[PROFILE_TIME]" << time << "[PROFILE_TIME]" << std::endl;
- }
-}
diff --git a/bench/meson.build b/bench/meson.build
index 581596a94..1619841fa 100644
--- a/bench/meson.build
+++ b/bench/meson.build
@@ -25,18 +25,6 @@ executable('bm_nbt_fanout',
CLI11_dep],
install : true)
-srcs = ['bm_nop.cc']
-executable('bm_nbt_nop',
- srcs,
- # include_directories : incdir,
- link_language : 'cpp',
- dependencies: [gnuradio_gr_dep,
- gnuradio_blocklib_blocks_dep,
- gnuradio_blocklib_streamops_dep,
- gnuradio_scheduler_nbt_dep,
- CLI11_dep],
- install : true)
-
srcs = ['bm_msg_forward.cc']
executable('bm_msg_forward',
srcs,
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(&reg[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)
diff --git a/gr/include/gnuradio/buffer_cpu_host.h b/gr/include/gnuradio/buffer_cpu_host.h
deleted file mode 100644
index fbc9a8429..000000000
--- a/gr/include/gnuradio/buffer_cpu_host.h
+++ /dev/null
@@ -1,142 +0,0 @@
-#pragma once
-
-#include <algorithm>
-#include <cstdint>
-#include <cstring>
-#include <memory>
-#include <vector>
-
-#include <gnuradio/buffer_sm.h>
-
-namespace gr {
-enum class buffer_cpu_host_type { H2H, D2D, H2D, D2H, UNKNOWN };
-class buffer_cpu_host_reader;
-class buffer_cpu_host : public buffer_sm
-{
-private:
- std::vector<uint8_t> _host_buffer;
- std::vector<uint8_t> _device_buffer;
- buffer_cpu_host_type _transfer_type = buffer_cpu_host_type::H2H;
-
-public:
- buffer_cpu_host(size_t num_items,
- size_t item_size,
- buffer_cpu_host_type type,
- std::shared_ptr<buffer_properties> buf_properties);
-
- static buffer_uptr make(size_t num_items,
- size_t item_size,
- std::shared_ptr<buffer_properties> buffer_properties);
-
- void* read_ptr(size_t index) override;
- void* write_ptr() override;
-
- void post_write(int num_items) override;
-
- buffer_cpu_host_type transfer_type() { return _transfer_type; }
-
- buffer_reader_uptr add_reader(std::shared_ptr<buffer_properties> buf_props,
- size_t itemsize) override;
-
- virtual bool output_blocked_callback(bool force = false) override
- {
- switch (_transfer_type) {
- case buffer_cpu_host_type::H2H:
- case buffer_cpu_host_type::H2D:
- case buffer_cpu_host_type::D2D:
- case buffer_cpu_host_type::D2H:
- return output_blocked_callback_logic(force, std::memmove);
- default:
- return false;
- }
- }
-};
-
-class buffer_cpu_host_reader : public buffer_sm_reader
-{
-private:
- buffer_cpu_host* _buffer_cpu_host;
-
-public:
- buffer_cpu_host_reader(buffer_cpu_host* bufp,
- std::shared_ptr<buffer_properties> buf_props,
- size_t itemsize,
- size_t read_index = 0)
- : buffer_sm_reader(bufp, itemsize, buf_props, read_index), _buffer_cpu_host(bufp)
- {
- }
-
- virtual bool input_blocked_callback(size_t items_required) override
- {
- // Only singly mapped buffers need to do anything with this callback
- // std::scoped_lock guard(*(_buffer->mutex()));
- std::lock_guard<std::mutex> guard(*(_buffer->mutex()));
-
- auto items_avail = items_available();
-
- // GR_LOG_DEBUG(d_debug_logger,
- // "input_blocked_callback: items_avail {}, _read_index {}, "
- // "_write_index {}, items_required {}",
- // items_avail,
- // _read_index,
- // _buffer->write_index(),
- // items_required);
-
- // GR_LOG_DEBUG(d_debug_logger,
- // "input_blocked_callback: total_written {}, total_read {}",
- // _buffer->total_written(),
- // total_read());
-
-
- // Maybe adjust read pointers from min read index?
- // This would mean that *all* readers must be > (passed) the write index
- if (items_avail < items_required && _buffer->write_index() < read_index()) {
- // GR_LOG_DEBUG(d_debug_logger, "Calling adjust_buffer_data ");
-
- switch (_buffer_cpu_host->transfer_type()) {
- case buffer_cpu_host_type::H2H:
- case buffer_cpu_host_type::H2D:
- case buffer_cpu_host_type::D2D:
- case buffer_cpu_host_type::D2H:
- return _buffer_cpu_host->adjust_buffer_data(std::memcpy, std::memmove);
- default:
- return false;
- }
- }
-
- return false;
- }
-};
-
-class buffer_cpu_host_properties : public buffer_properties
-{
-public:
- // using std::shared_ptr<buffer_properties> = sptr;
- buffer_cpu_host_properties(buffer_cpu_host_type buffer_type_)
- : buffer_properties(), _buffer_type(buffer_type_)
- {
- _bff = buffer_cpu_host::make;
- }
- buffer_cpu_host_type buffer_type() { return _buffer_type; }
- static std::shared_ptr<buffer_properties>
- make(buffer_cpu_host_type buffer_type_ = buffer_cpu_host_type::H2H)
- {
- return std::static_pointer_cast<buffer_properties>(
- std::make_shared<buffer_cpu_host_properties>(buffer_type_));
- }
-
-private:
- buffer_cpu_host_type _buffer_type;
-};
-
-#define BUFFER_CPU_HOST_ARGS_H2H \
- buffer_cpu_host_properties::make(buffer_cpu_host_type::H2H)
-#define BUFFER_CPU_HOST_ARGS_H2D \
- buffer_cpu_host_properties::make(buffer_cpu_host_type::H2D)
-#define BUFFER_CPU_HOST_ARGS_D2H \
- buffer_cpu_host_properties::make(buffer_cpu_host_type::D2H)
-#define BUFFER_CPU_HOST_ARGS_D2D \
- buffer_cpu_host_properties::make(buffer_cpu_host_type::D2D)
-
-
-} // namespace gr
diff --git a/gr/include/gnuradio/buffer_cuda.h b/gr/include/gnuradio/buffer_cuda.h
deleted file mode 100644
index 7874716bd..000000000
--- a/gr/include/gnuradio/buffer_cuda.h
+++ /dev/null
@@ -1,84 +0,0 @@
-#include <string.h>
-#include <algorithm>
-#include <cstdint>
-#include <memory>
-#include <mutex>
-#include <vector>
-
-#include <gnuradio/buffer.h>
-#include <cuda.h>
-#include <cuda_runtime.h>
-
-namespace gr {
-enum class buffer_cuda_type { D2D, H2D, D2H, UNKNOWN };
-
-class buffer_cuda : public buffer
-{
-private:
- uint8_t* _host_buffer;
- uint8_t* _device_buffer;
- buffer_cuda_type _type = buffer_cuda_type::UNKNOWN;
- cudaStream_t stream;
-
-public:
- using sptr = std::shared_ptr<buffer_cuda>;
- buffer_cuda(size_t num_items,
- size_t item_size,
- buffer_cuda_type type,
- std::shared_ptr<buffer_properties> buf_properties);
- ~buffer_cuda();
-
- static buffer_uptr make(size_t num_items,
- size_t item_size,
- std::shared_ptr<buffer_properties> buffer_properties);
-
- void* read_ptr(size_t read_index);
- void* write_ptr();
-
- virtual void post_write(int num_items);
-
- virtual buffer_reader_uptr add_reader(std::shared_ptr<buffer_properties> buf_props,
- size_t itemsize);
-};
-
-class buffer_cuda_reader : public buffer_reader
-{
-public:
- buffer_cuda_reader(buffer* bufp,
- std::shared_ptr<buffer_properties> buf_props,
- size_t itemsize,
- size_t read_index)
- : buffer_reader(bufp, buf_props, itemsize, read_index)
- {
- }
-
- virtual void post_read(int num_items);
-};
-
-class buffer_cuda_properties : public buffer_properties
-{
-public:
- // using std::shared_ptr<buffer_properties> = sptr;
- buffer_cuda_properties(buffer_cuda_type buffer_type_)
- : buffer_properties(), _buffer_type(buffer_type_)
- {
- _bff = buffer_cuda::make;
- }
- buffer_cuda_type buffer_type() { return _buffer_type; }
- static std::shared_ptr<buffer_properties>
- make(buffer_cuda_type buffer_type_ = buffer_cuda_type::D2D)
- {
- return std::static_pointer_cast<buffer_properties>(
- std::make_shared<buffer_cuda_properties>(buffer_type_));
- }
-
-private:
- buffer_cuda_type _buffer_type;
-};
-
-
-} // namespace gr
-
-#define CUDA_BUFFER_ARGS_H2D buffer_cuda_properties::make(buffer_cuda_type::H2D)
-#define CUDA_BUFFER_ARGS_D2H buffer_cuda_properties::make(buffer_cuda_type::D2H)
-#define CUDA_BUFFER_ARGS_D2D buffer_cuda_properties::make(buffer_cuda_type::D2D)
diff --git a/gr/include/gnuradio/buffer_cuda_pinned.h b/gr/include/gnuradio/buffer_cuda_pinned.h
deleted file mode 100644
index 809902b06..000000000
--- a/gr/include/gnuradio/buffer_cuda_pinned.h
+++ /dev/null
@@ -1,67 +0,0 @@
-#include <string.h>
-#include <algorithm>
-#include <cstdint>
-#include <memory>
-#include <mutex>
-#include <vector>
-
-#include <gnuradio/buffer.h>
-
-namespace gr {
-
-
-class buffer_cuda_pinned : public buffer
-{
-private:
- uint8_t* _pinned_buffer;
-
-public:
- using sptr = std::shared_ptr<buffer_cuda_pinned>;
- buffer_cuda_pinned(size_t num_items,
- size_t item_size,
- std::shared_ptr<buffer_properties> buf_properties);
- ~buffer_cuda_pinned();
-
- static buffer_uptr make(size_t num_items,
- size_t item_size,
- std::shared_ptr<buffer_properties> buffer_properties);
- void* read_ptr(size_t index);
- void* write_ptr();
- virtual void post_write(int num_items);
-
- virtual buffer_reader_uptr add_reader(std::shared_ptr<buffer_properties> buf_props,
- size_t itemsize);
-};
-class buffer_cuda_pinned_reader : public buffer_reader
-{
-public:
- buffer_cuda_pinned_reader(buffer* bufp,
- std::shared_ptr<buffer_properties> buf_props,
- size_t itemsize,
- size_t read_index)
- : buffer_reader(bufp, buf_props, itemsize, read_index)
- {
- }
-
- virtual void post_read(int num_items);
-};
-
-class buffer_cuda_pinned_properties : public buffer_properties
-{
-public:
- // using std::shared_ptr<buffer_properties> = sptr;
- buffer_cuda_pinned_properties() : buffer_properties()
- {
- _bff = buffer_cuda_pinned::make;
- }
- static std::shared_ptr<buffer_properties> make()
- {
- return std::dynamic_pointer_cast<buffer_properties>(
- std::make_shared<buffer_cuda_pinned_properties>());
- }
-};
-
-
-} // namespace gr
-
-#define CUDA_BUFFER_PINNED_ARGS buffer_cuda_pinned_properties::make()
diff --git a/gr/include/gnuradio/buffer_cuda_sm.h b/gr/include/gnuradio/buffer_cuda_sm.h
deleted file mode 100644
index e8a38b7f0..000000000
--- a/gr/include/gnuradio/buffer_cuda_sm.h
+++ /dev/null
@@ -1,151 +0,0 @@
-#include <string.h>
-#include <algorithm>
-#include <cstdint>
-#include <memory>
-#include <mutex>
-#include <vector>
-
-#include <gnuradio/buffer_sm.h>
-#include <cuda.h>
-#include <cuda_runtime.h>
-
-namespace gr {
-enum class buffer_cuda_sm_type { D2D, H2D, D2H, UNKNOWN };
-
-class buffer_cuda_sm : public buffer_sm
-{
-private:
- uint8_t* _host_buffer;
- uint8_t* _device_buffer;
- buffer_cuda_sm_type _type = buffer_cuda_sm_type::UNKNOWN;
- cudaStream_t stream;
-
-public:
- using sptr = std::shared_ptr<buffer_cuda_sm>;
- buffer_cuda_sm(size_t num_items,
- size_t item_size,
- buffer_cuda_sm_type type,
- std::shared_ptr<buffer_properties> buf_properties);
- ~buffer_cuda_sm();
-
- static buffer_uptr make(size_t num_items,
- size_t item_size,
- std::shared_ptr<buffer_properties> buffer_properties);
-
- void* read_ptr(size_t read_index);
- void* write_ptr();
- buffer_cuda_sm_type type() { return _type; }
-
- virtual void post_write(int num_items);
-
- virtual buffer_reader_uptr add_reader(std::shared_ptr<buffer_properties> buf_props,
- size_t itemsize);
-
- static void* cuda_memcpy(void* dest, const void* src, std::size_t count);
- static void* cuda_memmove(void* dest, const void* src, std::size_t count);
-
- virtual bool output_blocked_callback(bool force = false) override
- {
- switch (_type) {
- case buffer_cuda_sm_type::H2D:
- return output_blocked_callback_logic(force, std::memmove);
- case buffer_cuda_sm_type::D2D:
- case buffer_cuda_sm_type::D2H:
- return output_blocked_callback_logic(force, cuda_memmove);
- default:
- return false;
- }
- }
-};
-
-class buffer_cuda_sm_reader : public buffer_sm_reader
-{
-private:
- // logger_ptr d_logger;
- // logger_ptr d_debug_logger;
-
- buffer_cuda_sm* _buffer_cuda_sm;
-
-public:
- buffer_cuda_sm_reader(buffer_cuda_sm* buffer,
- std::shared_ptr<buffer_properties> buf_props,
- size_t itemsize,
- size_t read_index)
- : buffer_sm_reader(buffer, itemsize, buf_props, read_index)
- {
- _buffer_cuda_sm = buffer;
- // gr::configure_default_loggers(d_logger, d_debug_logger, "buffer_cuda_sm");
- }
-
- // virtual void post_read(int num_items);
-
- virtual bool input_blocked_callback(size_t items_required) override
- {
- // Only singly mapped buffers need to do anything with this callback
- // std::scoped_lock guard(*(_buffer->mutex()));
- std::lock_guard<std::mutex> guard(*(_buffer->mutex()));
-
- auto items_avail = items_available();
-
- // GR_LOG_DEBUG(d_debug_logger,
- // "input_blocked_callback: items_avail {}, _read_index {}, "
- // "_write_index {}, items_required {}",
- // items_avail,
- // _read_index,
- // _buffer->write_index(),
- // items_required);
-
- // GR_LOG_DEBUG(d_debug_logger,
- // "input_blocked_callback: total_written {}, total_read {}",
- // _buffer->total_written(),
- // total_read());
-
-
- // Maybe adjust read pointers from min read index?
- // This would mean that *all* readers must be > (passed) the write index
- if (items_avail < items_required && _buffer->write_index() < read_index()) {
- // GR_LOG_DEBUG(d_debug_logger, "Calling adjust_buffer_data ");
-
- switch (_buffer_cuda_sm->type()) {
- case buffer_cuda_sm_type::H2D:
- case buffer_cuda_sm_type::D2D:
- return _buffer_sm->adjust_buffer_data(buffer_cuda_sm::cuda_memcpy,
- buffer_cuda_sm::cuda_memmove);
- case buffer_cuda_sm_type::D2H:
- return _buffer_sm->adjust_buffer_data(std::memcpy, std::memmove);
- default:
- return false;
- }
- }
-
- return false;
- }
-};
-
-class buffer_cuda_sm_properties : public buffer_properties
-{
-public:
- // using std::shared_ptr<buffer_properties> = sptr;
- buffer_cuda_sm_properties(buffer_cuda_sm_type buffer_type_)
- : buffer_properties(), _buffer_type(buffer_type_)
- {
- _bff = buffer_cuda_sm::make;
- }
- buffer_cuda_sm_type buffer_type() { return _buffer_type; }
- static std::shared_ptr<buffer_properties>
- make(buffer_cuda_sm_type buffer_type_ = buffer_cuda_sm_type::D2D)
- {
- return std::static_pointer_cast<buffer_properties>(
- std::make_shared<buffer_cuda_sm_properties>(buffer_type_));
- }
-
-private:
- buffer_cuda_sm_type _buffer_type;
-};
-
-
-} // namespace gr
-
-#define CUDA_BUFFER_SM_ARGS_H2D buffer_cuda_sm_properties::make(buffer_cuda_sm_type::H2D)
-#define CUDA_BUFFER_SM_ARGS_D2H buffer_cuda_sm_properties::make(buffer_cuda_sm_type::D2H)
-#define CUDA_BUFFER_SM_ARGS_D2D buffer_cuda_sm_properties::make(buffer_cuda_sm_type::D2D)
diff --git a/gr/include/gnuradio/buffer_net_zmq.h b/gr/include/gnuradio/buffer_net_zmq.h
deleted file mode 100644
index af31c6110..000000000
--- a/gr/include/gnuradio/buffer_net_zmq.h
+++ /dev/null
@@ -1,137 +0,0 @@
-#pragma once
-
-#include <algorithm>
-#include <cstdint>
-#include <cstring>
-#include <memory>
-#include <vector>
-
-#include <zmq.hpp>
-
-#include <gnuradio/buffer.h>
-
-namespace gr {
-
-
-class buffer_net_zmq_reader;
-
-class buffer_net_zmq : public buffer
-{
-private:
- std::vector<uint8_t> _buffer;
-
- zmq::context_t _context;
- zmq::socket_t _socket;
-
-
-public:
- using sptr = std::shared_ptr<buffer_net_zmq>;
- buffer_net_zmq(size_t num_items,
- size_t item_size,
- std::shared_ptr<buffer_properties> buffer_properties,
- int port);
- ~buffer_net_zmq() override{};
- static buffer_uptr make(size_t num_items,
- size_t item_size,
- std::shared_ptr<buffer_properties> buffer_properties);
-
- void* read_ptr(size_t index) override { return nullptr; }
- size_t space_available() override { return _num_items; }
- void* write_ptr() override { return _buffer.data(); }
-
- void post_write(int num_items) override
- {
- // send the data from buffer over the socket
- d_debug_logger->debug("sending {} items", num_items);
- auto res = _socket.send(zmq::buffer(write_ptr(), num_items * _item_size),
- zmq::send_flags::none);
- d_debug_logger->debug("send returned code {}", *res);
- }
-
- buffer_reader_uptr add_reader(std::shared_ptr<buffer_properties> buf_props,
- size_t itemsize) override
- {
- // do nothing because readers will be added on zmq connect
- return nullptr;
- }
-};
-
-class buffer_net_zmq_reader : public buffer_reader
-{
-private:
- zmq::context_t _context;
- zmq::socket_t _socket;
- zmq::message_t _msg;
- size_t _msg_idx = 0;
- size_t _msg_size = 0;
-
- // Circular buffer for zmq to write into
- gr::buffer_uptr _circbuf;
- gr::buffer_reader_uptr _circbuf_rdr;
-
- logger_ptr d_logger;
- logger_ptr d_debug_logger;
-
-public:
- bool _recv_done = false;
- static buffer_reader_uptr make(size_t itemsize,
- std::shared_ptr<buffer_properties> buf_props);
- buffer_net_zmq_reader(std::shared_ptr<buffer_properties> buf_props,
- size_t itemsize,
- const std::string& ipaddr,
- int port);
-
- ~buffer_net_zmq_reader() override{};
-
- bool read_info(buffer_info_t& info) override
- {
- auto ret = _circbuf_rdr->read_info(info);
- return ret;
- }
- void* read_ptr() override { return _circbuf_rdr->read_ptr(); }
-
- // Tags not supported yet
- const std::vector<tag_t>& tags() const override { return _circbuf->tags(); }
- std::vector<tag_t> get_tags(size_t num_items) override { return {}; }
- void post_read(int num_items) override
- {
- d_debug_logger->debug("post_read: {}", num_items);
- _circbuf_rdr->post_read(num_items);
- }
-};
-
-
-class buffer_net_zmq_properties : public buffer_properties
-{
-public:
- // using std::shared_ptr<buffer_properties> = sptr;
- buffer_net_zmq_properties(const std::string& ipaddr, int port)
- : buffer_properties(), _ipaddr(ipaddr), _port(port)
- {
- _bff = buffer_net_zmq::make;
- _brff = buffer_net_zmq_reader::make;
- }
- ~buffer_net_zmq_properties() override{};
-
- static std::shared_ptr<buffer_properties> make(const std::string& ipaddr,
- int port = 0)
- {
- return std::dynamic_pointer_cast<buffer_properties>(
- std::make_shared<buffer_net_zmq_properties>(ipaddr, port));
- }
-
- static std::shared_ptr<buffer_properties>
- make_from_params(const std::string& json_str);
-
- void set_port(int port) { _port = port; }
- auto port() { return _port; }
- auto ipaddr() { return _ipaddr; }
-
- std::string to_json() override;
-
-private:
- std::string _ipaddr;
- int _port;
-};
-
-} // namespace gr
diff --git a/gr/include/gnuradio/buffer_sm.h b/gr/include/gnuradio/buffer_sm.h
deleted file mode 100644
index 73a850eca..000000000
--- a/gr/include/gnuradio/buffer_sm.h
+++ /dev/null
@@ -1,107 +0,0 @@
-#pragma once
-
-#include <algorithm>
-#include <cstdint>
-#include <cstring>
-#include <memory>
-#include <vector>
-
-#include <gnuradio/buffer.h>
-// #include <gnuradio/logger.h>
-
-namespace gr {
-
-typedef void* (*memcpy_func_t)(void* dest, const void* src, std::size_t count);
-typedef void* (*memmove_func_t)(void* dest, const void* src, std::size_t count);
-
-class buffer_sm_reader;
-class buffer_sm : public buffer
-{
-private:
- std::vector<uint8_t> _buffer;
- uint8_t* _raw_buffer;
-
- // logger_ptr d_logger;
- // logger_ptr d_debug_logger;
-
-public:
- using sptr = std::shared_ptr<buffer_sm>;
- buffer_sm(size_t num_items,
- size_t item_size,
- std::shared_ptr<buffer_properties> buf_properties);
-
- static buffer_uptr
- make(size_t num_items,
- size_t item_size,
- std::shared_ptr<buffer_properties> buffer_properties = nullptr);
-
- void* read_ptr(size_t index) override;
- void* write_ptr() override;
-
- void post_write(int num_items) override;
-
- virtual bool
- output_blocked_callback_logic(bool force = false,
- memmove_func_t memmove_func = std::memmove);
-
- /*!
- * \brief Return true if thread is ready to call the callback, false otherwise
- */
- bool output_blkd_cb_ready(int output_multiple) override;
- bool output_blocked_callback(bool force = false) override;
- size_t space_available() override;
-
- bool write_info(buffer_info_t& info) override;
- buffer_reader_uptr add_reader(std::shared_ptr<buffer_properties> buf_props,
- size_t itemsize) override;
-
- bool adjust_buffer_data(memcpy_func_t memcpy_func, memmove_func_t memmove_func);
-
- // Wipes away the default single mapped buffer and replaces it with something
- // defined externally in the derived class
- void set_bufp(uint8_t* ptr)
- {
- _raw_buffer = ptr;
- _buffer.resize(0);
- }
-};
-
-class buffer_sm_reader : public buffer_reader
-{
-private:
- logger_ptr d_logger;
- logger_ptr d_debug_logger;
-
-protected:
- buffer_sm* _buffer_sm;
-
-public:
- buffer_sm_reader(buffer_sm* buffer,
- size_t itemsize,
- std::shared_ptr<buffer_properties> buf_props = nullptr,
- size_t read_index = 0);
-
- void post_read(int num_items) override;
-
- /*!
- * \brief Return true if thread is ready to call input_blocked_callback,
- * false otherwise
- */
- bool input_blkd_cb_ready(int items_required) override;
- bool input_blocked_callback(size_t items_required) override;
- size_t bytes_available() override;
-};
-
-
-class buffer_sm_properties : public buffer_properties
-{
-public:
- buffer_sm_properties();
-
- static std::shared_ptr<buffer_properties> make();
-};
-
-
-#define SM_BUFFER_ARGS buffer_sm_properties::make()
-
-} // namespace gr
diff --git a/gr/include/gnuradio/meson.build b/gr/include/gnuradio/meson.build
index 4c5e9d51f..64d995b5d 100644
--- a/gr/include/gnuradio/meson.build
+++ b/gr/include/gnuradio/meson.build
@@ -8,8 +8,6 @@ runtime_headers = [
'block_group_properties.h',
'clonable_block.h',
'concurrent_queue.h',
- 'buffer_cuda.h',
- 'buffer_cuda_pinned.h',
'edge.h',
'flat_graph.h',
'flowgraph.h',
@@ -43,12 +41,10 @@ runtime_headers = [
'sptr_magic.h',
'realtime.h',
'runtime.h',
- 'buffer_sm.h',
'executor.h',
'constants.h',
'registry.h',
'high_res_timer.h',
- 'custom_lock.h'
]
install_headers(runtime_headers, subdir : 'gnuradio')
diff --git a/gr/include/moodycamel/LICENSE.md b/gr/include/moodycamel/LICENSE.md
deleted file mode 100644
index 519338976..000000000
--- a/gr/include/moodycamel/LICENSE.md
+++ /dev/null
@@ -1,62 +0,0 @@
-This license file applies to everything in this repository except that which
-is explicitly annotated as being written by other authors, i.e. the Boost
-queue (included in the benchmarks for comparison), Intel's TBB library (ditto),
-dlib::pipe (ditto),
-the CDSChecker tool (used for verification), the Relacy model checker (ditto),
-and Jeff Preshing's semaphore implementation (used in the blocking queue) which
-has a zlib license (embedded in lightweightsempahore.h).
-
----
-
-Simplified BSD License:
-
-Copyright (c) 2013-2016, Cameron Desrochers.
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without modification,
-are permitted provided that the following conditions are met:
-
-- Redistributions of source code must retain the above copyright notice, this list of
-conditions and the following disclaimer.
-- Redistributions in binary form must reproduce the above copyright notice, this list of
-conditions and the following disclaimer in the documentation and/or other materials
-provided with the distribution.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
-EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
-THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
-OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
-TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
-EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
----
-
-I have also chosen to dual-license under the Boost Software License as an alternative to
-the Simplified BSD license above:
-
-Boost Software License - Version 1.0 - August 17th, 2003
-
-Permission is hereby granted, free of charge, to any person or organization
-obtaining a copy of the software and accompanying documentation covered by
-this license (the "Software") to use, reproduce, display, distribute,
-execute, and transmit the Software, and to prepare derivative works of the
-Software, and to permit third-parties to whom the Software is furnished to
-do so, all subject to the following:
-
-The copyright notices in the Software and this entire statement, including
-the above license grant, this restriction and the following disclaimer,
-must be included in all copies of the Software, in whole or in part, and
-all derivative works of the Software, unless such copies or derivative
-works are solely in the form of machine-executable object code generated by
-a source language processor.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
-SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
-FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
-ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
-DEALINGS IN THE SOFTWARE.
diff --git a/gr/include/moodycamel/blockingconcurrentqueue.h b/gr/include/moodycamel/blockingconcurrentqueue.h
deleted file mode 100644
index 7db0ef364..000000000
--- a/gr/include/moodycamel/blockingconcurrentqueue.h
+++ /dev/null
@@ -1,615 +0,0 @@
-// Provides an efficient blocking version of moodycamel::ConcurrentQueue.
-// ©2015-2020 Cameron Desrochers. Distributed under the terms of the simplified
-// BSD license, available at the top of concurrentqueue.h.
-// Also dual-licensed under the Boost Software License (see LICENSE.md)
-// Uses Jeff Preshing's semaphore implementation (under the terms of its
-// separate zlib license, see lightweightsemaphore.h).
-
-#pragma once
-
-#include "concurrentqueue.h"
-#include "lightweightsemaphore.h"
-
-#include <type_traits>
-#include <cerrno>
-#include <chrono>
-#include <ctime>
-#include <memory>
-
-namespace moodycamel {
-// This is a blocking version of the queue. It has an almost identical interface to
-// the normal non-blocking version, with the addition of various wait_dequeue() methods
-// and the removal of producer-specific dequeue methods.
-template <typename T, typename Traits = ConcurrentQueueDefaultTraits>
-class BlockingConcurrentQueue
-{
-private:
- typedef ::moodycamel::ConcurrentQueue<T, Traits> ConcurrentQueue;
- typedef ::moodycamel::LightweightSemaphore LightweightSemaphore;
-
-public:
- typedef typename ConcurrentQueue::producer_token_t producer_token_t;
- typedef typename ConcurrentQueue::consumer_token_t consumer_token_t;
-
- typedef typename ConcurrentQueue::index_t index_t;
- typedef typename ConcurrentQueue::size_t size_t;
- typedef typename std::make_signed<size_t>::type ssize_t;
-
- static const size_t BLOCK_SIZE = ConcurrentQueue::BLOCK_SIZE;
- static const size_t EXPLICIT_BLOCK_EMPTY_COUNTER_THRESHOLD =
- ConcurrentQueue::EXPLICIT_BLOCK_EMPTY_COUNTER_THRESHOLD;
- static const size_t EXPLICIT_INITIAL_INDEX_SIZE =
- ConcurrentQueue::EXPLICIT_INITIAL_INDEX_SIZE;
- static const size_t IMPLICIT_INITIAL_INDEX_SIZE =
- ConcurrentQueue::IMPLICIT_INITIAL_INDEX_SIZE;
- static const size_t INITIAL_IMPLICIT_PRODUCER_HASH_SIZE =
- ConcurrentQueue::INITIAL_IMPLICIT_PRODUCER_HASH_SIZE;
- static const std::uint32_t EXPLICIT_CONSUMER_CONSUMPTION_QUOTA_BEFORE_ROTATE =
- ConcurrentQueue::EXPLICIT_CONSUMER_CONSUMPTION_QUOTA_BEFORE_ROTATE;
- static const size_t MAX_SUBQUEUE_SIZE = ConcurrentQueue::MAX_SUBQUEUE_SIZE;
-
-public:
- // Creates a queue with at least `capacity` element slots; note that the
- // actual number of elements that can be inserted without additional memory
- // allocation depends on the number of producers and the block size (e.g. if
- // the block size is equal to `capacity`, only a single block will be allocated
- // up-front, which means only a single producer will be able to enqueue elements
- // without an extra allocation -- blocks aren't shared between producers).
- // This method is not thread safe -- it is up to the user to ensure that the
- // queue is fully constructed before it starts being used by other threads (this
- // includes making the memory effects of construction visible, possibly with a
- // memory barrier).
- explicit BlockingConcurrentQueue(size_t capacity = 6 * BLOCK_SIZE)
- : inner(capacity),
- sema(create<LightweightSemaphore, ssize_t, int>(0, (int)Traits::MAX_SEMA_SPINS),
- &BlockingConcurrentQueue::template destroy<LightweightSemaphore>)
- {
- assert(reinterpret_cast<ConcurrentQueue*>((BlockingConcurrentQueue*)1) ==
- &((BlockingConcurrentQueue*)1)->inner &&
- "BlockingConcurrentQueue must have ConcurrentQueue as its first member");
- if (!sema) {
- MOODYCAMEL_THROW(std::bad_alloc());
- }
- }
-
- BlockingConcurrentQueue(size_t minCapacity,
- size_t maxExplicitProducers,
- size_t maxImplicitProducers)
- : inner(minCapacity, maxExplicitProducers, maxImplicitProducers),
- sema(create<LightweightSemaphore, ssize_t, int>(0, (int)Traits::MAX_SEMA_SPINS),
- &BlockingConcurrentQueue::template destroy<LightweightSemaphore>)
- {
- assert(reinterpret_cast<ConcurrentQueue*>((BlockingConcurrentQueue*)1) ==
- &((BlockingConcurrentQueue*)1)->inner &&
- "BlockingConcurrentQueue must have ConcurrentQueue as its first member");
- if (!sema) {
- MOODYCAMEL_THROW(std::bad_alloc());
- }
- }
-
- // Disable copying and copy assignment
- BlockingConcurrentQueue(BlockingConcurrentQueue const&) MOODYCAMEL_DELETE_FUNCTION;
- BlockingConcurrentQueue&
- operator=(BlockingConcurrentQueue const&) MOODYCAMEL_DELETE_FUNCTION;
-
- // Moving is supported, but note that it is *not* a thread-safe operation.
- // Nobody can use the queue while it's being moved, and the memory effects
- // of that move must be propagated to other threads before they can use it.
- // Note: When a queue is moved, its tokens are still valid but can only be
- // used with the destination queue (i.e. semantically they are moved along
- // with the queue itself).
- BlockingConcurrentQueue(BlockingConcurrentQueue&& other) MOODYCAMEL_NOEXCEPT
- : inner(std::move(other.inner)),
- sema(std::move(other.sema))
- {
- }
-
- inline BlockingConcurrentQueue&
- operator=(BlockingConcurrentQueue&& other) MOODYCAMEL_NOEXCEPT
- {
- return swap_internal(other);
- }
-
- // Swaps this queue's state with the other's. Not thread-safe.
- // Swapping two queues does not invalidate their tokens, however
- // the tokens that were created for one queue must be used with
- // only the swapped queue (i.e. the tokens are tied to the
- // queue's movable state, not the object itself).
- inline void swap(BlockingConcurrentQueue& other) MOODYCAMEL_NOEXCEPT
- {
- swap_internal(other);
- }
-
-private:
- BlockingConcurrentQueue& swap_internal(BlockingConcurrentQueue& other)
- {
- if (this == &other) {
- return *this;
- }
-
- inner.swap(other.inner);
- sema.swap(other.sema);
- return *this;
- }
-
-public:
- // Enqueues a single item (by copying it).
- // Allocates memory if required. Only fails if memory allocation fails (or implicit
- // production is disabled because Traits::INITIAL_IMPLICIT_PRODUCER_HASH_SIZE is 0,
- // or Traits::MAX_SUBQUEUE_SIZE has been defined and would be surpassed).
- // Thread-safe.
- inline bool enqueue(T const& item)
- {
- if ((details::likely)(inner.enqueue(item))) {
- sema->signal();
- return true;
- }
- return false;
- }
-
- // Enqueues a single item (by moving it, if possible).
- // Allocates memory if required. Only fails if memory allocation fails (or implicit
- // production is disabled because Traits::INITIAL_IMPLICIT_PRODUCER_HASH_SIZE is 0,
- // or Traits::MAX_SUBQUEUE_SIZE has been defined and would be surpassed).
- // Thread-safe.
- inline bool enqueue(T&& item)
- {
- if ((details::likely)(inner.enqueue(std::move(item)))) {
- sema->signal();
- return true;
- }
- return false;
- }
-
- // Enqueues a single item (by copying it) using an explicit producer token.
- // Allocates memory if required. Only fails if memory allocation fails (or
- // Traits::MAX_SUBQUEUE_SIZE has been defined and would be surpassed).
- // Thread-safe.
- inline bool enqueue(producer_token_t const& token, T const& item)
- {
- if ((details::likely)(inner.enqueue(token, item))) {
- sema->signal();
- return true;
- }
- return false;
- }
-
- // Enqueues a single item (by moving it, if possible) using an explicit producer
- // token. Allocates memory if required. Only fails if memory allocation fails (or
- // Traits::MAX_SUBQUEUE_SIZE has been defined and would be surpassed).
- // Thread-safe.
- inline bool enqueue(producer_token_t const& token, T&& item)
- {
- if ((details::likely)(inner.enqueue(token, std::move(item)))) {
- sema->signal();
- return true;
- }
- return false;
- }
-
- // Enqueues several items.
- // Allocates memory if required. Only fails if memory allocation fails (or
- // implicit production is disabled because Traits::INITIAL_IMPLICIT_PRODUCER_HASH_SIZE
- // is 0, or Traits::MAX_SUBQUEUE_SIZE has been defined and would be surpassed).
- // Note: Use std::make_move_iterator if the elements should be moved instead of
- // copied. Thread-safe.
- template <typename It>
- inline bool enqueue_bulk(It itemFirst, size_t count)
- {
- if ((details::likely)(inner.enqueue_bulk(std::forward<It>(itemFirst), count))) {
- sema->signal((LightweightSemaphore::ssize_t)(ssize_t)count);
- return true;
- }
- return false;
- }
-
- // Enqueues several items using an explicit producer token.
- // Allocates memory if required. Only fails if memory allocation fails
- // (or Traits::MAX_SUBQUEUE_SIZE has been defined and would be surpassed).
- // Note: Use std::make_move_iterator if the elements should be moved
- // instead of copied.
- // Thread-safe.
- template <typename It>
- inline bool enqueue_bulk(producer_token_t const& token, It itemFirst, size_t count)
- {
- if ((details::likely)(
- inner.enqueue_bulk(token, std::forward<It>(itemFirst), count))) {
- sema->signal((LightweightSemaphore::ssize_t)(ssize_t)count);
- return true;
- }
- return false;
- }
-
- // Enqueues a single item (by copying it).
- // Does not allocate memory. Fails if not enough room to enqueue (or implicit
- // production is disabled because Traits::INITIAL_IMPLICIT_PRODUCER_HASH_SIZE
- // is 0).
- // Thread-safe.
- inline bool try_enqueue(T const& item)
- {
- if (inner.try_enqueue(item)) {
- sema->signal();
- return true;
- }
- return false;
- }
-
- // Enqueues a single item (by moving it, if possible).
- // Does not allocate memory (except for one-time implicit producer).
- // Fails if not enough room to enqueue (or implicit production is
- // disabled because Traits::INITIAL_IMPLICIT_PRODUCER_HASH_SIZE is 0).
- // Thread-safe.
- inline bool try_enqueue(T&& item)
- {
- if (inner.try_enqueue(std::move(item))) {
- sema->signal();
- return true;
- }
- return false;
- }
-
- // Enqueues a single item (by copying it) using an explicit producer token.
- // Does not allocate memory. Fails if not enough room to enqueue.
- // Thread-safe.
- inline bool try_enqueue(producer_token_t const& token, T const& item)
- {
- if (inner.try_enqueue(token, item)) {
- sema->signal();
- return true;
- }
- return false;
- }
-
- // Enqueues a single item (by moving it, if possible) using an explicit producer
- // token. Does not allocate memory. Fails if not enough room to enqueue. Thread-safe.
- inline bool try_enqueue(producer_token_t const& token, T&& item)
- {
- if (inner.try_enqueue(token, std::move(item))) {
- sema->signal();
- return true;
- }
- return false;
- }
-
- // Enqueues several items.
- // Does not allocate memory (except for one-time implicit producer).
- // Fails if not enough room to enqueue (or implicit production is
- // disabled because Traits::INITIAL_IMPLICIT_PRODUCER_HASH_SIZE is 0).
- // Note: Use std::make_move_iterator if the elements should be moved
- // instead of copied.
- // Thread-safe.
- template <typename It>
- inline bool try_enqueue_bulk(It itemFirst, size_t count)
- {
- if (inner.try_enqueue_bulk(std::forward<It>(itemFirst), count)) {
- sema->signal((LightweightSemaphore::ssize_t)(ssize_t)count);
- return true;
- }
- return false;
- }
-
- // Enqueues several items using an explicit producer token.
- // Does not allocate memory. Fails if not enough room to enqueue.
- // Note: Use std::make_move_iterator if the elements should be moved
- // instead of copied.
- // Thread-safe.
- template <typename It>
- inline bool
- try_enqueue_bulk(producer_token_t const& token, It itemFirst, size_t count)
- {
- if (inner.try_enqueue_bulk(token, std::forward<It>(itemFirst), count)) {
- sema->signal((LightweightSemaphore::ssize_t)(ssize_t)count);
- return true;
- }
- return false;
- }
-
-
- // Attempts to dequeue from the queue.
- // Returns false if all producer streams appeared empty at the time they
- // were checked (so, the queue is likely but not guaranteed to be empty).
- // Never allocates. Thread-safe.
- template <typename U>
- inline bool try_dequeue(U& item)
- {
- if (sema->tryWait()) {
- while (!inner.try_dequeue(item)) {
- continue;
- }
- return true;
- }
- return false;
- }
-
- // Attempts to dequeue from the queue using an explicit consumer token.
- // Returns false if all producer streams appeared empty at the time they
- // were checked (so, the queue is likely but not guaranteed to be empty).
- // Never allocates. Thread-safe.
- template <typename U>
- inline bool try_dequeue(consumer_token_t& token, U& item)
- {
- if (sema->tryWait()) {
- while (!inner.try_dequeue(token, item)) {
- continue;
- }
- return true;
- }
- return false;
- }
-
- // Attempts to dequeue several elements from the queue.
- // Returns the number of items actually dequeued.
- // Returns 0 if all producer streams appeared empty at the time they
- // were checked (so, the queue is likely but not guaranteed to be empty).
- // Never allocates. Thread-safe.
- template <typename It>
- inline size_t try_dequeue_bulk(It itemFirst, size_t max)
- {
- size_t count = 0;
- max = (size_t)sema->tryWaitMany((LightweightSemaphore::ssize_t)(ssize_t)max);
- while (count != max) {
- count += inner.template try_dequeue_bulk<It&>(itemFirst, max - count);
- }
- return count;
- }
-
- // Attempts to dequeue several elements from the queue using an explicit consumer
- // token. Returns the number of items actually dequeued. Returns 0 if all producer
- // streams appeared empty at the time they were checked (so, the queue is likely but
- // not guaranteed to be empty). Never allocates. Thread-safe.
- template <typename It>
- inline size_t try_dequeue_bulk(consumer_token_t& token, It itemFirst, size_t max)
- {
- size_t count = 0;
- max = (size_t)sema->tryWaitMany((LightweightSemaphore::ssize_t)(ssize_t)max);
- while (count != max) {
- count += inner.template try_dequeue_bulk<It&>(token, itemFirst, max - count);
- }
- return count;
- }
-
-
- // Blocks the current thread until there's something to dequeue, then
- // dequeues it.
- // Never allocates. Thread-safe.
- template <typename U>
- inline void wait_dequeue(U& item)
- {
- while (!sema->wait()) {
- continue;
- }
- while (!inner.try_dequeue(item)) {
- continue;
- }
- }
-
- // Blocks the current thread until either there's something to dequeue
- // or the timeout (specified in microseconds) expires. Returns false
- // without setting `item` if the timeout expires, otherwise assigns
- // to `item` and returns true.
- // Using a negative timeout indicates an indefinite timeout,
- // and is thus functionally equivalent to calling wait_dequeue.
- // Never allocates. Thread-safe.
- template <typename U>
- inline bool wait_dequeue_timed(U& item, std::int64_t timeout_usecs)
- {
- if (!sema->wait(timeout_usecs)) {
- return false;
- }
- while (!inner.try_dequeue(item)) {
- continue;
- }
- return true;
- }
-
- // Blocks the current thread until either there's something to dequeue
- // or the timeout expires. Returns false without setting `item` if the
- // timeout expires, otherwise assigns to `item` and returns true.
- // Never allocates. Thread-safe.
- template <typename U, typename Rep, typename Period>
- inline bool wait_dequeue_timed(U& item,
- std::chrono::duration<Rep, Period> const& timeout)
- {
- return wait_dequeue_timed(
- item, std::chrono::duration_cast<std::chrono::microseconds>(timeout).count());
- }
-
- // Blocks the current thread until there's something to dequeue, then
- // dequeues it using an explicit consumer token.
- // Never allocates. Thread-safe.
- template <typename U>
- inline void wait_dequeue(consumer_token_t& token, U& item)
- {
- while (!sema->wait()) {
- continue;
- }
- while (!inner.try_dequeue(token, item)) {
- continue;
- }
- }
-
- // Blocks the current thread until either there's something to dequeue
- // or the timeout (specified in microseconds) expires. Returns false
- // without setting `item` if the timeout expires, otherwise assigns
- // to `item` and returns true.
- // Using a negative timeout indicates an indefinite timeout,
- // and is thus functionally equivalent to calling wait_dequeue.
- // Never allocates. Thread-safe.
- template <typename U>
- inline bool
- wait_dequeue_timed(consumer_token_t& token, U& item, std::int64_t timeout_usecs)
- {
- if (!sema->wait(timeout_usecs)) {
- return false;
- }
- while (!inner.try_dequeue(token, item)) {
- continue;
- }
- return true;
- }
-
- // Blocks the current thread until either there's something to dequeue
- // or the timeout expires. Returns false without setting `item` if the
- // timeout expires, otherwise assigns to `item` and returns true.
- // Never allocates. Thread-safe.
- template <typename U, typename Rep, typename Period>
- inline bool wait_dequeue_timed(consumer_token_t& token,
- U& item,
- std::chrono::duration<Rep, Period> const& timeout)
- {
- return wait_dequeue_timed(
- token,
- item,
- std::chrono::duration_cast<std::chrono::microseconds>(timeout).count());
- }
-
- // Attempts to dequeue several elements from the queue.
- // Returns the number of items actually dequeued, which will
- // always be at least one (this method blocks until the queue
- // is non-empty) and at most max.
- // Never allocates. Thread-safe.
- template <typename It>
- inline size_t wait_dequeue_bulk(It itemFirst, size_t max)
- {
- size_t count = 0;
- max = (size_t)sema->waitMany((LightweightSemaphore::ssize_t)(ssize_t)max);
- while (count != max) {
- count += inner.template try_dequeue_bulk<It&>(itemFirst, max - count);
- }
- return count;
- }
-
- // Attempts to dequeue several elements from the queue.
- // Returns the number of items actually dequeued, which can
- // be 0 if the timeout expires while waiting for elements,
- // and at most max.
- // Using a negative timeout indicates an indefinite timeout,
- // and is thus functionally equivalent to calling wait_dequeue_bulk.
- // Never allocates. Thread-safe.
- template <typename It>
- inline size_t
- wait_dequeue_bulk_timed(It itemFirst, size_t max, std::int64_t timeout_usecs)
- {
- size_t count = 0;
- max = (size_t)sema->waitMany((LightweightSemaphore::ssize_t)(ssize_t)max,
- timeout_usecs);
- while (count != max) {
- count += inner.template try_dequeue_bulk<It&>(itemFirst, max - count);
- }
- return count;
- }
-
- // Attempts to dequeue several elements from the queue.
- // Returns the number of items actually dequeued, which can
- // be 0 if the timeout expires while waiting for elements,
- // and at most max.
- // Never allocates. Thread-safe.
- template <typename It, typename Rep, typename Period>
- inline size_t wait_dequeue_bulk_timed(
- It itemFirst, size_t max, std::chrono::duration<Rep, Period> const& timeout)
- {
- return wait_dequeue_bulk_timed<It&>(
- itemFirst,
- max,
- std::chrono::duration_cast<std::chrono::microseconds>(timeout).count());
- }
-
- // Attempts to dequeue several elements from the queue using an explicit consumer
- // token. Returns the number of items actually dequeued, which will always be at least
- // one (this method blocks until the queue is non-empty) and at most max. Never
- // allocates. Thread-safe.
- template <typename It>
- inline size_t wait_dequeue_bulk(consumer_token_t& token, It itemFirst, size_t max)
- {
- size_t count = 0;
- max = (size_t)sema->waitMany((LightweightSemaphore::ssize_t)(ssize_t)max);
- while (count != max) {
- count += inner.template try_dequeue_bulk<It&>(token, itemFirst, max - count);
- }
- return count;
- }
-
- // Attempts to dequeue several elements from the queue using an explicit consumer
- // token. Returns the number of items actually dequeued, which can be 0 if the timeout
- // expires while waiting for elements, and at most max. Using a negative timeout
- // indicates an indefinite timeout, and is thus functionally equivalent to calling
- // wait_dequeue_bulk. Never allocates. Thread-safe.
- template <typename It>
- inline size_t wait_dequeue_bulk_timed(consumer_token_t& token,
- It itemFirst,
- size_t max,
- std::int64_t timeout_usecs)
- {
- size_t count = 0;
- max = (size_t)sema->waitMany((LightweightSemaphore::ssize_t)(ssize_t)max,
- timeout_usecs);
- while (count != max) {
- count += inner.template try_dequeue_bulk<It&>(token, itemFirst, max - count);
- }
- return count;
- }
-
- // Attempts to dequeue several elements from the queue using an explicit consumer
- // token. Returns the number of items actually dequeued, which can be 0 if the timeout
- // expires while waiting for elements, and at most max. Never allocates. Thread-safe.
- template <typename It, typename Rep, typename Period>
- inline size_t
- wait_dequeue_bulk_timed(consumer_token_t& token,
- It itemFirst,
- size_t max,
- std::chrono::duration<Rep, Period> const& timeout)
- {
- return wait_dequeue_bulk_timed<It&>(
- token,
- itemFirst,
- max,
- std::chrono::duration_cast<std::chrono::microseconds>(timeout).count());
- }
-
-
- // Returns an estimate of the total number of elements currently in the queue. This
- // estimate is only accurate if the queue has completely stabilized before it is
- // called (i.e. all enqueue and dequeue operations have completed and their memory
- // effects are visible on the calling thread, and no further operations start while
- // this method is being called). Thread-safe.
- inline size_t size_approx() const { return (size_t)sema->availableApprox(); }
-
-
- // Returns true if the underlying atomic variables used by
- // the queue are lock-free (they should be on most platforms).
- // Thread-safe.
- static bool is_lock_free() { return ConcurrentQueue::is_lock_free(); }
-
-
-private:
- template <typename U, typename A1, typename A2>
- static inline U* create(A1&& a1, A2&& a2)
- {
- void* p = (Traits::malloc)(sizeof(U));
- return p != nullptr ? new (p) U(std::forward<A1>(a1), std::forward<A2>(a2))
- : nullptr;
- }
-
- template <typename U>
- static inline void destroy(U* p)
- {
- if (p != nullptr) {
- p->~U();
- }
- (Traits::free)(p);
- }
-
-private:
- ConcurrentQueue inner;
- std::unique_ptr<LightweightSemaphore, void (*)(LightweightSemaphore*)> sema;
-};
-
-
-template <typename T, typename Traits>
-inline void swap(BlockingConcurrentQueue<T, Traits>& a,
- BlockingConcurrentQueue<T, Traits>& b) MOODYCAMEL_NOEXCEPT
-{
- a.swap(b);
-}
-
-} // end namespace moodycamel
diff --git a/gr/include/moodycamel/concurrentqueue.h b/gr/include/moodycamel/concurrentqueue.h
deleted file mode 100644
index 2a5bbcd82..000000000
--- a/gr/include/moodycamel/concurrentqueue.h
+++ /dev/null
@@ -1,4506 +0,0 @@
-// Provides a C++11 implementation of a multi-producer, multi-consumer lock-free queue.
-// An overview, including benchmark results, is provided here:
-// http://moodycamel.com/blog/2014/a-fast-general-purpose-lock-free-queue-for-c++
-// The full design is also described in excruciating detail at:
-// http://moodycamel.com/blog/2014/detailed-design-of-a-lock-free-queue
-
-// Simplified BSD license:
-// Copyright (c) 2013-2020, Cameron Desrochers.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without modification,
-// are permitted provided that the following conditions are met:
-//
-// - Redistributions of source code must retain the above copyright notice, this list of
-// conditions and the following disclaimer.
-// - Redistributions in binary form must reproduce the above copyright notice, this list
-// of conditions and the following disclaimer in the documentation and/or other materials
-// provided with the distribution.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
-// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
-// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
-// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
-// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// Also dual-licensed under the Boost Software License (see LICENSE.md)
-
-#pragma once
-
-#if defined(__GNUC__)
-// Disable -Wconversion warnings (spuriously triggered when Traits::size_t and
-// Traits::index_t are set to < 32 bits, causing integer promotion, causing warnings
-// upon assigning any computed values)
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wconversion"
-
-#ifdef MCDBGQ_USE_RELACY
-#pragma GCC diagnostic ignored "-Wint-to-pointer-cast"
-#endif
-#endif
-
-#if defined(_MSC_VER) && (!defined(_HAS_CXX17) || !_HAS_CXX17)
-// VS2019 with /W4 warns about constant conditional expressions but unless /std=c++17 or
-// higher does not support `if constexpr`, so we have no choice but to simply disable the
-// warning
-#pragma warning(push)
-#pragma warning(disable : 4127) // conditional expression is constant
-#endif
-
-#if defined(__APPLE__)
-#include "TargetConditionals.h"
-#endif
-
-#ifdef MCDBGQ_USE_RELACY
-#include "relacy/relacy_std.hpp"
-#include "relacy_shims.h"
-// We only use malloc/free anyway, and the delete macro messes up `= delete` method
-// declarations. We'll override the default trait malloc ourselves without a macro.
-#undef new
-#undef delete
-#undef malloc
-#undef free
-#else
-#include <atomic> // Requires C++11. Sorry VS2010.
-#include <cassert>
-#endif
-#include <type_traits>
-#include <algorithm>
-#include <array>
-#include <climits> // for CHAR_BIT
-#include <cstddef> // for max_align_t
-#include <cstdint>
-#include <cstdlib>
-#include <limits>
-#include <thread> // partly for __WINPTHREADS_VERSION if on MinGW-w64 w/ POSIX threading
-#include <utility>
-
-// Platform-specific definitions of a numeric thread ID type and an invalid value
-namespace moodycamel {
-namespace details {
-template <typename thread_id_t>
-struct thread_id_converter {
- typedef thread_id_t thread_id_numeric_size_t;
- typedef thread_id_t thread_id_hash_t;
- static thread_id_hash_t prehash(thread_id_t const& x) { return x; }
-};
-} // namespace details
-} // namespace moodycamel
-#if defined(MCDBGQ_USE_RELACY)
-namespace moodycamel {
-namespace details {
-typedef std::uint32_t thread_id_t;
-static const thread_id_t invalid_thread_id = 0xFFFFFFFFU;
-static const thread_id_t invalid_thread_id2 = 0xFFFFFFFEU;
-static inline thread_id_t thread_id() { return rl::thread_index(); }
-} // namespace details
-} // namespace moodycamel
-#elif defined(_WIN32) || defined(__WINDOWS__) || defined(__WIN32__)
-// No sense pulling in windows.h in a header, we'll manually declare the function
-// we use and rely on backwards-compatibility for this not to break
-extern "C" __declspec(dllimport) unsigned long __stdcall GetCurrentThreadId(void);
-namespace moodycamel {
-namespace details {
-static_assert(sizeof(unsigned long) == sizeof(std::uint32_t),
- "Expected size of unsigned long to be 32 bits on Windows");
-typedef std::uint32_t thread_id_t;
-static const thread_id_t invalid_thread_id =
- 0; // See http://blogs.msdn.com/b/oldnewthing/archive/2004/02/23/78395.aspx
-static const thread_id_t invalid_thread_id2 =
- 0xFFFFFFFFU; // Not technically guaranteed to be invalid, but is never used in
- // practice. Note that all Win32 thread IDs are presently multiples of 4.
-static inline thread_id_t thread_id()
-{
- return static_cast<thread_id_t>(::GetCurrentThreadId());
-}
-} // namespace details
-} // namespace moodycamel
-#elif defined(__arm__) || defined(_M_ARM) || defined(__aarch64__) || \
- (defined(__APPLE__) && TARGET_OS_IPHONE)
-namespace moodycamel {
-namespace details {
-static_assert(sizeof(std::thread::id) == 4 || sizeof(std::thread::id) == 8,
- "std::thread::id is expected to be either 4 or 8 bytes");
-
-typedef std::thread::id thread_id_t;
-static const thread_id_t invalid_thread_id; // Default ctor creates invalid ID
-
-// Note we don't define a invalid_thread_id2 since std::thread::id doesn't have one; it's
-// only used if MOODYCAMEL_CPP11_THREAD_LOCAL_SUPPORTED is defined anyway, which it won't
-// be.
-static inline thread_id_t thread_id() { return std::this_thread::get_id(); }
-
-template <std::size_t>
-struct thread_id_size {
-};
-template <>
-struct thread_id_size<4> {
- typedef std::uint32_t numeric_t;
-};
-template <>
-struct thread_id_size<8> {
- typedef std::uint64_t numeric_t;
-};
-
-template <>
-struct thread_id_converter<thread_id_t> {
- typedef thread_id_size<sizeof(thread_id_t)>::numeric_t thread_id_numeric_size_t;
-#ifndef __APPLE__
- typedef std::size_t thread_id_hash_t;
-#else
- typedef thread_id_numeric_size_t thread_id_hash_t;
-#endif
-
- static thread_id_hash_t prehash(thread_id_t const& x)
- {
-#ifndef __APPLE__
- return std::hash<std::thread::id>()(x);
-#else
- return *reinterpret_cast<thread_id_hash_t const*>(&x);
-#endif
- }
-};
-} // namespace details
-} // namespace moodycamel
-#else
-// Use a nice trick from this answer: http://stackoverflow.com/a/8438730/21475
-// In order to get a numeric thread ID in a platform-independent way, we use a
-// thread-local static variable's address as a thread identifier :-)
-#if defined(__GNUC__) || defined(__INTEL_COMPILER)
-#define MOODYCAMEL_THREADLOCAL __thread
-#elif defined(_MSC_VER)
-#define MOODYCAMEL_THREADLOCAL __declspec(thread)
-#else
-// Assume C++11 compliant compiler
-#define MOODYCAMEL_THREADLOCAL thread_local
-#endif
-namespace moodycamel {
-namespace details {
-typedef std::uintptr_t thread_id_t;
-static const thread_id_t invalid_thread_id = 0; // Address can't be nullptr
-static const thread_id_t invalid_thread_id2 =
- 1; // Member accesses off a null pointer are also generally invalid. Plus it's not
- // aligned.
-inline thread_id_t thread_id()
-{
- static MOODYCAMEL_THREADLOCAL int x;
- return reinterpret_cast<thread_id_t>(&x);
-}
-} // namespace details
-} // namespace moodycamel
-#endif
-
-// Constexpr if
-#ifndef MOODYCAMEL_CONSTEXPR_IF
-#if (defined(_MSC_VER) && defined(_HAS_CXX17) && _HAS_CXX17) || __cplusplus > 201402L
-#define MOODYCAMEL_CONSTEXPR_IF if constexpr
-#define MOODYCAMEL_MAYBE_UNUSED [[maybe_unused]]
-#else
-#define MOODYCAMEL_CONSTEXPR_IF if
-#define MOODYCAMEL_MAYBE_UNUSED
-#endif
-#endif
-
-// Exceptions
-#ifndef MOODYCAMEL_EXCEPTIONS_ENABLED
-#if (defined(_MSC_VER) && defined(_CPPUNWIND)) || \
- (defined(__GNUC__) && defined(__EXCEPTIONS)) || \
- (!defined(_MSC_VER) && !defined(__GNUC__))
-#define MOODYCAMEL_EXCEPTIONS_ENABLED
-#endif
-#endif
-#ifdef MOODYCAMEL_EXCEPTIONS_ENABLED
-#define MOODYCAMEL_TRY try
-#define MOODYCAMEL_CATCH(...) catch (__VA_ARGS__)
-#define MOODYCAMEL_RETHROW throw
-#define MOODYCAMEL_THROW(expr) throw(expr)
-#else
-#define MOODYCAMEL_TRY MOODYCAMEL_CONSTEXPR_IF(true)
-#define MOODYCAMEL_CATCH(...) else MOODYCAMEL_CONSTEXPR_IF(false)
-#define MOODYCAMEL_RETHROW
-#define MOODYCAMEL_THROW(expr)
-#endif
-
-#ifndef MOODYCAMEL_NOEXCEPT
-#if !defined(MOODYCAMEL_EXCEPTIONS_ENABLED)
-#define MOODYCAMEL_NOEXCEPT
-#define MOODYCAMEL_NOEXCEPT_CTOR(type, valueType, expr) true
-#define MOODYCAMEL_NOEXCEPT_ASSIGN(type, valueType, expr) true
-#elif defined(_MSC_VER) && defined(_NOEXCEPT) && _MSC_VER < 1800
-// VS2012's std::is_nothrow_[move_]constructible is broken and returns true when it
-// shouldn't :-( We have to assume *all* non-trivial constructors may throw on VS2012!
-#define MOODYCAMEL_NOEXCEPT _NOEXCEPT
-#define MOODYCAMEL_NOEXCEPT_CTOR(type, valueType, expr) \
- (std::is_rvalue_reference<valueType>::value && \
- std::is_move_constructible<type>::value \
- ? std::is_trivially_move_constructible<type>::value \
- : std::is_trivially_copy_constructible<type>::value)
-#define MOODYCAMEL_NOEXCEPT_ASSIGN(type, valueType, expr) \
- ((std::is_rvalue_reference<valueType>::value && std::is_move_assignable<type>::value \
- ? std::is_trivially_move_assignable<type>::value || \
- std::is_nothrow_move_assignable<type>::value \
- : std::is_trivially_copy_assignable<type>::value || \
- std::is_nothrow_copy_assignable<type>::value) && \
- MOODYCAMEL_NOEXCEPT_CTOR(type, valueType, expr))
-#elif defined(_MSC_VER) && defined(_NOEXCEPT) && _MSC_VER < 1900
-#define MOODYCAMEL_NOEXCEPT _NOEXCEPT
-#define MOODYCAMEL_NOEXCEPT_CTOR(type, valueType, expr) \
- (std::is_rvalue_reference<valueType>::value && \
- std::is_move_constructible<type>::value \
- ? std::is_trivially_move_constructible<type>::value || \
- std::is_nothrow_move_constructible<type>::value \
- : std::is_trivially_copy_constructible<type>::value || \
- std::is_nothrow_copy_constructible<type>::value)
-#define MOODYCAMEL_NOEXCEPT_ASSIGN(type, valueType, expr) \
- ((std::is_rvalue_reference<valueType>::value && std::is_move_assignable<type>::value \
- ? std::is_trivially_move_assignable<type>::value || \
- std::is_nothrow_move_assignable<type>::value \
- : std::is_trivially_copy_assignable<type>::value || \
- std::is_nothrow_copy_assignable<type>::value) && \
- MOODYCAMEL_NOEXCEPT_CTOR(type, valueType, expr))
-#else
-#define MOODYCAMEL_NOEXCEPT noexcept
-#define MOODYCAMEL_NOEXCEPT_CTOR(type, valueType, expr) noexcept(expr)
-#define MOODYCAMEL_NOEXCEPT_ASSIGN(type, valueType, expr) noexcept(expr)
-#endif
-#endif
-
-#ifndef MOODYCAMEL_CPP11_THREAD_LOCAL_SUPPORTED
-#ifdef MCDBGQ_USE_RELACY
-#define MOODYCAMEL_CPP11_THREAD_LOCAL_SUPPORTED
-#else
-// VS2013 doesn't support `thread_local`, and MinGW-w64 w/ POSIX threading has a crippling
-// bug: http://sourceforge.net/p/mingw-w64/bugs/445 g++ <=4.7 doesn't support thread_local
-// either. Finally, iOS/ARM doesn't have support for it either, and g++/ARM allows it to
-// compile but it's unconfirmed to actually work
-#if (!defined(_MSC_VER) || _MSC_VER >= 1900) && \
- (!defined(__MINGW32__) && !defined(__MINGW64__) || \
- !defined(__WINPTHREADS_VERSION)) && \
- (!defined(__GNUC__) || __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)) && \
- (!defined(__APPLE__) || !TARGET_OS_IPHONE) && !defined(__arm__) && \
- !defined(_M_ARM) && !defined(__aarch64__)
-// Assume `thread_local` is fully supported in all other C++11 compilers/platforms
-//#define MOODYCAMEL_CPP11_THREAD_LOCAL_SUPPORTED // always disabled for now since
-// several users report having problems with it on
-#endif
-#endif
-#endif
-
-// VS2012 doesn't support deleted functions.
-// In this case, we declare the function normally but don't define it. A link error will
-// be generated if the function is called.
-#ifndef MOODYCAMEL_DELETE_FUNCTION
-#if defined(_MSC_VER) && _MSC_VER < 1800
-#define MOODYCAMEL_DELETE_FUNCTION
-#else
-#define MOODYCAMEL_DELETE_FUNCTION = delete
-#endif
-#endif
-
-namespace moodycamel {
-namespace details {
-#ifndef MOODYCAMEL_ALIGNAS
-// VS2013 doesn't support alignas or alignof, and align() requires a constant literal
-#if defined(_MSC_VER) && _MSC_VER <= 1800
-#define MOODYCAMEL_ALIGNAS(alignment) __declspec(align(alignment))
-#define MOODYCAMEL_ALIGNOF(obj) __alignof(obj)
-#define MOODYCAMEL_ALIGNED_TYPE_LIKE(T, obj) \
- typename details::Vs2013Aligned<std::alignment_of<obj>::value, T>::type
-template <int Align, typename T>
-struct Vs2013Aligned {
-}; // default, unsupported alignment
-template <typename T>
-struct Vs2013Aligned<1, T> {
- typedef __declspec(align(1)) T type;
-};
-template <typename T>
-struct Vs2013Aligned<2, T> {
- typedef __declspec(align(2)) T type;
-};
-template <typename T>
-struct Vs2013Aligned<4, T> {
- typedef __declspec(align(4)) T type;
-};
-template <typename T>
-struct Vs2013Aligned<8, T> {
- typedef __declspec(align(8)) T type;
-};
-template <typename T>
-struct Vs2013Aligned<16, T> {
- typedef __declspec(align(16)) T type;
-};
-template <typename T>
-struct Vs2013Aligned<32, T> {
- typedef __declspec(align(32)) T type;
-};
-template <typename T>
-struct Vs2013Aligned<64, T> {
- typedef __declspec(align(64)) T type;
-};
-template <typename T>
-struct Vs2013Aligned<128, T> {
- typedef __declspec(align(128)) T type;
-};
-template <typename T>
-struct Vs2013Aligned<256, T> {
- typedef __declspec(align(256)) T type;
-};
-#else
-template <typename T>
-struct identity {
- typedef T type;
-};
-#define MOODYCAMEL_ALIGNAS(alignment) alignas(alignment)
-#define MOODYCAMEL_ALIGNOF(obj) alignof(obj)
-#define MOODYCAMEL_ALIGNED_TYPE_LIKE(T, obj) \
- alignas(alignof(obj)) typename details::identity<T>::type
-#endif
-#endif
-} // namespace details
-} // namespace moodycamel
-
-
-// TSAN can false report races in lock-free code. To enable TSAN to be used from projects
-// that use this one, we can apply per-function compile-time suppression. See
-// https://clang.llvm.org/docs/ThreadSanitizer.html#has-feature-thread-sanitizer
-#define MOODYCAMEL_NO_TSAN
-#if defined(__has_feature)
-#if __has_feature(thread_sanitizer)
-#undef MOODYCAMEL_NO_TSAN
-#define MOODYCAMEL_NO_TSAN __attribute__((no_sanitize("thread")))
-#endif // TSAN
-#endif // TSAN
-
-// Compiler-specific likely/unlikely hints
-namespace moodycamel {
-namespace details {
-#if defined(__GNUC__)
-static inline bool(likely)(bool x) { return __builtin_expect((x), true); }
-static inline bool(unlikely)(bool x) { return __builtin_expect((x), false); }
-#else
-static inline bool(likely)(bool x) { return x; }
-static inline bool(unlikely)(bool x) { return x; }
-#endif
-} // namespace details
-} // namespace moodycamel
-
-#ifdef MOODYCAMEL_QUEUE_INTERNAL_DEBUG
-#include "internal/concurrentqueue_internal_debug.h"
-#endif
-
-namespace moodycamel {
-namespace details {
-template <typename T>
-struct const_numeric_max {
- static_assert(std::is_integral<T>::value,
- "const_numeric_max can only be used with integers");
- static const T value =
- std::numeric_limits<T>::is_signed
- ? (static_cast<T>(1) << (sizeof(T) * CHAR_BIT - 1)) - static_cast<T>(1)
- : static_cast<T>(-1);
-};
-
-#if defined(__GLIBCXX__)
-typedef ::max_align_t std_max_align_t; // libstdc++ forgot to add it to std:: for a while
-#else
-typedef std::max_align_t
- std_max_align_t; // Others (e.g. MSVC) insist it can *only* be accessed via std::
-#endif
-
-// Some platforms have incorrectly set max_align_t to a type with <8 bytes alignment even
-// while supporting 8-byte aligned scalar values (*cough* 32-bit iOS). Work around this
-// with our own union. See issue #64.
-typedef union {
- std_max_align_t x;
- long long y;
- void* z;
-} max_align_t;
-} // namespace details
-
-// Default traits for the ConcurrentQueue. To change some of the
-// traits without re-implementing all of them, inherit from this
-// struct and shadow the declarations you wish to be different;
-// since the traits are used as a template type parameter, the
-// shadowed declarations will be used where defined, and the defaults
-// otherwise.
-struct ConcurrentQueueDefaultTraits {
- // General-purpose size type. std::size_t is strongly recommended.
- typedef std::size_t size_t;
-
- // The type used for the enqueue and dequeue indices. Must be at least as
- // large as size_t. Should be significantly larger than the number of elements
- // you expect to hold at once, especially if you have a high turnover rate;
- // for example, on 32-bit x86, if you expect to have over a hundred million
- // elements or pump several million elements through your queue in a very
- // short space of time, using a 32-bit type *may* trigger a race condition.
- // A 64-bit int type is recommended in that case, and in practice will
- // prevent a race condition no matter the usage of the queue. Note that
- // whether the queue is lock-free with a 64-int type depends on the whether
- // std::atomic<std::uint64_t> is lock-free, which is platform-specific.
- typedef std::size_t index_t;
-
- // Internally, all elements are enqueued and dequeued from multi-element
- // blocks; this is the smallest controllable unit. If you expect few elements
- // but many producers, a smaller block size should be favoured. For few producers
- // and/or many elements, a larger block size is preferred. A sane default
- // is provided. Must be a power of 2.
- static const size_t BLOCK_SIZE = 32;
-
- // For explicit producers (i.e. when using a producer token), the block is
- // checked for being empty by iterating through a list of flags, one per element.
- // For large block sizes, this is too inefficient, and switching to an atomic
- // counter-based approach is faster. The switch is made for block sizes strictly
- // larger than this threshold.
- static const size_t EXPLICIT_BLOCK_EMPTY_COUNTER_THRESHOLD = 32;
-
- // How many full blocks can be expected for a single explicit producer? This should
- // reflect that number's maximum for optimal performance. Must be a power of 2.
- static const size_t EXPLICIT_INITIAL_INDEX_SIZE = 32;
-
- // How many full blocks can be expected for a single implicit producer? This should
- // reflect that number's maximum for optimal performance. Must be a power of 2.
- static const size_t IMPLICIT_INITIAL_INDEX_SIZE = 32;
-
- // The initial size of the hash table mapping thread IDs to implicit producers.
- // Note that the hash is resized every time it becomes half full.
- // Must be a power of two, and either 0 or at least 1. If 0, implicit production
- // (using the enqueue methods without an explicit producer token) is disabled.
- static const size_t INITIAL_IMPLICIT_PRODUCER_HASH_SIZE = 32;
-
- // Controls the number of items that an explicit consumer (i.e. one with a token)
- // must consume before it causes all consumers to rotate and move on to the next
- // internal queue.
- static const std::uint32_t EXPLICIT_CONSUMER_CONSUMPTION_QUOTA_BEFORE_ROTATE = 256;
-
- // The maximum number of elements (inclusive) that can be enqueued to a sub-queue.
- // Enqueue operations that would cause this limit to be surpassed will fail. Note
- // that this limit is enforced at the block level (for performance reasons), i.e.
- // it's rounded up to the nearest block size.
- static const size_t MAX_SUBQUEUE_SIZE = details::const_numeric_max<size_t>::value;
-
- // The number of times to spin before sleeping when waiting on a semaphore.
- // Recommended values are on the order of 1000-10000 unless the number of
- // consumer threads exceeds the number of idle cores (in which case try 0-100).
- // Only affects instances of the BlockingConcurrentQueue.
- static const int MAX_SEMA_SPINS = 10000;
-
-
-#ifndef MCDBGQ_USE_RELACY
- // Memory allocation can be customized if needed.
- // malloc should return nullptr on failure, and handle alignment like std::malloc.
-#if defined(malloc) || defined(free)
- // Gah, this is 2015, stop defining macros that break standard code already!
- // Work around malloc/free being special macros:
- static inline void* WORKAROUND_malloc(size_t size) { return malloc(size); }
- static inline void WORKAROUND_free(void* ptr) { return free(ptr); }
- static inline void*(malloc)(size_t size) { return WORKAROUND_malloc(size); }
- static inline void(free)(void* ptr) { return WORKAROUND_free(ptr); }
-#else
- static inline void* malloc(size_t size) { return std::malloc(size); }
- static inline void free(void* ptr) { return std::free(ptr); }
-#endif
-#else
- // Debug versions when running under the Relacy race detector (ignore
- // these in user code)
- static inline void* malloc(size_t size) { return rl::rl_malloc(size, $); }
- static inline void free(void* ptr) { return rl::rl_free(ptr, $); }
-#endif
-};
-
-
-// When producing or consuming many elements, the most efficient way is to:
-// 1) Use one of the bulk-operation methods of the queue with a token
-// 2) Failing that, use the bulk-operation methods without a token
-// 3) Failing that, create a token and use that with the single-item methods
-// 4) Failing that, use the single-parameter methods of the queue
-// Having said that, don't create tokens willy-nilly -- ideally there should be
-// a maximum of one token per thread (of each kind).
-struct ProducerToken;
-struct ConsumerToken;
-
-template <typename T, typename Traits>
-class ConcurrentQueue;
-template <typename T, typename Traits>
-class BlockingConcurrentQueue;
-class ConcurrentQueueTests;
-
-
-namespace details {
-struct ConcurrentQueueProducerTypelessBase {
- ConcurrentQueueProducerTypelessBase* next;
- std::atomic<bool> inactive;
- ProducerToken* token;
-
- ConcurrentQueueProducerTypelessBase() : next(nullptr), inactive(false), token(nullptr)
- {
- }
-};
-
-template <bool use32>
-struct _hash_32_or_64 {
- static inline std::uint32_t hash(std::uint32_t h)
- {
- // MurmurHash3 finalizer -- see
- // https://code.google.com/p/smhasher/source/browse/trunk/MurmurHash3.cpp Since
- // the thread ID is already unique, all we really want to do is propagate that
- // uniqueness evenly across all the bits, so that we can use a subset of the bits
- // while reducing collisions significantly
- h ^= h >> 16;
- h *= 0x85ebca6b;
- h ^= h >> 13;
- h *= 0xc2b2ae35;
- return h ^ (h >> 16);
- }
-};
-template <>
-struct _hash_32_or_64<1> {
- static inline std::uint64_t hash(std::uint64_t h)
- {
- h ^= h >> 33;
- h *= 0xff51afd7ed558ccd;
- h ^= h >> 33;
- h *= 0xc4ceb9fe1a85ec53;
- return h ^ (h >> 33);
- }
-};
-template <std::size_t size>
-struct hash_32_or_64 : public _hash_32_or_64<(size > 4)> {
-};
-
-static inline size_t hash_thread_id(thread_id_t id)
-{
- static_assert(sizeof(thread_id_t) <= 8,
- "Expected a platform where thread IDs are at most 64-bit values");
- return static_cast<size_t>(
- hash_32_or_64<sizeof(thread_id_converter<thread_id_t>::thread_id_hash_t)>::hash(
- thread_id_converter<thread_id_t>::prehash(id)));
-}
-
-template <typename T>
-static inline bool circular_less_than(T a, T b)
-{
-#ifdef _MSC_VER
-#pragma warning(push)
-#pragma warning(disable : 4554)
-#endif
- static_assert(
- std::is_integral<T>::value && !std::numeric_limits<T>::is_signed,
- "circular_less_than is intended to be used only with unsigned integer types");
- return static_cast<T>(a - b) >
- static_cast<T>(static_cast<T>(1) << static_cast<T>(sizeof(T) * CHAR_BIT - 1));
-#ifdef _MSC_VER
-#pragma warning(pop)
-#endif
-}
-
-template <typename U>
-static inline char* align_for(char* ptr)
-{
- const std::size_t alignment = std::alignment_of<U>::value;
- return ptr +
- (alignment - (reinterpret_cast<std::uintptr_t>(ptr) % alignment)) % alignment;
-}
-
-template <typename T>
-static inline T ceil_to_pow_2(T x)
-{
- static_assert(
- std::is_integral<T>::value && !std::numeric_limits<T>::is_signed,
- "ceil_to_pow_2 is intended to be used only with unsigned integer types");
-
- // Adapted from http://graphics.stanford.edu/~seander/bithacks.html#RoundUpPowerOf2
- --x;
- x |= x >> 1;
- x |= x >> 2;
- x |= x >> 4;
- for (std::size_t i = 1; i < sizeof(T); i <<= 1) {
- x |= x >> (i << 3);
- }
- ++x;
- return x;
-}
-
-template <typename T>
-static inline void swap_relaxed(std::atomic<T>& left, std::atomic<T>& right)
-{
- T temp = std::move(left.load(std::memory_order_relaxed));
- left.store(std::move(right.load(std::memory_order_relaxed)),
- std::memory_order_relaxed);
- right.store(std::move(temp), std::memory_order_relaxed);
-}
-
-template <typename T>
-static inline T const& nomove(T const& x)
-{
- return x;
-}
-
-template <bool Enable>
-struct nomove_if {
- template <typename T>
- static inline T const& eval(T const& x)
- {
- return x;
- }
-};
-
-template <>
-struct nomove_if<false> {
- template <typename U>
- static inline auto eval(U&& x) -> decltype(std::forward<U>(x))
- {
- return std::forward<U>(x);
- }
-};
-
-template <typename It>
-static inline auto deref_noexcept(It& it) MOODYCAMEL_NOEXCEPT -> decltype(*it)
-{
- return *it;
-}
-
-#if defined(__clang__) || !defined(__GNUC__) || __GNUC__ > 4 || \
- (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)
-template <typename T>
-struct is_trivially_destructible : std::is_trivially_destructible<T> {
-};
-#else
-template <typename T>
-struct is_trivially_destructible : std::has_trivial_destructor<T> {
-};
-#endif
-
-#ifdef MOODYCAMEL_CPP11_THREAD_LOCAL_SUPPORTED
-#ifdef MCDBGQ_USE_RELACY
-typedef RelacyThreadExitListener ThreadExitListener;
-typedef RelacyThreadExitNotifier ThreadExitNotifier;
-#else
-struct ThreadExitListener {
- typedef void (*callback_t)(void*);
- callback_t callback;
- void* userData;
-
- ThreadExitListener* next; // reserved for use by the ThreadExitNotifier
-};
-
-
-class ThreadExitNotifier
-{
-public:
- static void subscribe(ThreadExitListener* listener)
- {
- auto& tlsInst = instance();
- listener->next = tlsInst.tail;
- tlsInst.tail = listener;
- }
-
- static void unsubscribe(ThreadExitListener* listener)
- {
- auto& tlsInst = instance();
- ThreadExitListener** prev = &tlsInst.tail;
- for (auto ptr = tlsInst.tail; ptr != nullptr; ptr = ptr->next) {
- if (ptr == listener) {
- *prev = ptr->next;
- break;
- }
- prev = &ptr->next;
- }
- }
-
-private:
- ThreadExitNotifier() : tail(nullptr) {}
- ThreadExitNotifier(ThreadExitNotifier const&) MOODYCAMEL_DELETE_FUNCTION;
- ThreadExitNotifier& operator=(ThreadExitNotifier const&) MOODYCAMEL_DELETE_FUNCTION;
-
- ~ThreadExitNotifier()
- {
- // This thread is about to exit, let everyone know!
- assert(this == &instance() &&
- "If this assert fails, you likely have a buggy compiler! Change the "
- "preprocessor conditions such that "
- "MOODYCAMEL_CPP11_THREAD_LOCAL_SUPPORTED is no longer defined.");
- for (auto ptr = tail; ptr != nullptr; ptr = ptr->next) {
- ptr->callback(ptr->userData);
- }
- }
-
- // Thread-local
- static inline ThreadExitNotifier& instance()
- {
- static thread_local ThreadExitNotifier notifier;
- return notifier;
- }
-
-private:
- ThreadExitListener* tail;
-};
-#endif
-#endif
-
-template <typename T>
-struct static_is_lock_free_num {
- enum { value = 0 };
-};
-template <>
-struct static_is_lock_free_num<signed char> {
- enum { value = ATOMIC_CHAR_LOCK_FREE };
-};
-template <>
-struct static_is_lock_free_num<short> {
- enum { value = ATOMIC_SHORT_LOCK_FREE };
-};
-template <>
-struct static_is_lock_free_num<int> {
- enum { value = ATOMIC_INT_LOCK_FREE };
-};
-template <>
-struct static_is_lock_free_num<long> {
- enum { value = ATOMIC_LONG_LOCK_FREE };
-};
-template <>
-struct static_is_lock_free_num<long long> {
- enum { value = ATOMIC_LLONG_LOCK_FREE };
-};
-template <typename T>
-struct static_is_lock_free : static_is_lock_free_num<typename std::make_signed<T>::type> {
-};
-template <>
-struct static_is_lock_free<bool> {
- enum { value = ATOMIC_BOOL_LOCK_FREE };
-};
-template <typename U>
-struct static_is_lock_free<U*> {
- enum { value = ATOMIC_POINTER_LOCK_FREE };
-};
-} // namespace details
-
-
-struct ProducerToken {
- template <typename T, typename Traits>
- explicit ProducerToken(ConcurrentQueue<T, Traits>& queue);
-
- template <typename T, typename Traits>
- explicit ProducerToken(BlockingConcurrentQueue<T, Traits>& queue);
-
- ProducerToken(ProducerToken&& other) MOODYCAMEL_NOEXCEPT : producer(other.producer)
- {
- other.producer = nullptr;
- if (producer != nullptr) {
- producer->token = this;
- }
- }
-
- inline ProducerToken& operator=(ProducerToken&& other) MOODYCAMEL_NOEXCEPT
- {
- swap(other);
- return *this;
- }
-
- void swap(ProducerToken& other) MOODYCAMEL_NOEXCEPT
- {
- std::swap(producer, other.producer);
- if (producer != nullptr) {
- producer->token = this;
- }
- if (other.producer != nullptr) {
- other.producer->token = &other;
- }
- }
-
- // A token is always valid unless:
- // 1) Memory allocation failed during construction
- // 2) It was moved via the move constructor
- // (Note: assignment does a swap, leaving both potentially valid)
- // 3) The associated queue was destroyed
- // Note that if valid() returns true, that only indicates
- // that the token is valid for use with a specific queue,
- // but not which one; that's up to the user to track.
- inline bool valid() const { return producer != nullptr; }
-
- ~ProducerToken()
- {
- if (producer != nullptr) {
- producer->token = nullptr;
- producer->inactive.store(true, std::memory_order_release);
- }
- }
-
- // Disable copying and assignment
- ProducerToken(ProducerToken const&) MOODYCAMEL_DELETE_FUNCTION;
- ProducerToken& operator=(ProducerToken const&) MOODYCAMEL_DELETE_FUNCTION;
-
-private:
- template <typename T, typename Traits>
- friend class ConcurrentQueue;
- friend class ConcurrentQueueTests;
-
-protected:
- details::ConcurrentQueueProducerTypelessBase* producer;
-};
-
-
-struct ConsumerToken {
- template <typename T, typename Traits>
- explicit ConsumerToken(ConcurrentQueue<T, Traits>& q);
-
- template <typename T, typename Traits>
- explicit ConsumerToken(BlockingConcurrentQueue<T, Traits>& q);
-
- ConsumerToken(ConsumerToken&& other) MOODYCAMEL_NOEXCEPT
- : initialOffset(other.initialOffset),
- lastKnownGlobalOffset(other.lastKnownGlobalOffset),
- itemsConsumedFromCurrent(other.itemsConsumedFromCurrent),
- currentProducer(other.currentProducer),
- desiredProducer(other.desiredProducer)
- {
- }
-
- inline ConsumerToken& operator=(ConsumerToken&& other) MOODYCAMEL_NOEXCEPT
- {
- swap(other);
- return *this;
- }
-
- void swap(ConsumerToken& other) MOODYCAMEL_NOEXCEPT
- {
- std::swap(initialOffset, other.initialOffset);
- std::swap(lastKnownGlobalOffset, other.lastKnownGlobalOffset);
- std::swap(itemsConsumedFromCurrent, other.itemsConsumedFromCurrent);
- std::swap(currentProducer, other.currentProducer);
- std::swap(desiredProducer, other.desiredProducer);
- }
-
- // Disable copying and assignment
- ConsumerToken(ConsumerToken const&) MOODYCAMEL_DELETE_FUNCTION;
- ConsumerToken& operator=(ConsumerToken const&) MOODYCAMEL_DELETE_FUNCTION;
-
-private:
- template <typename T, typename Traits>
- friend class ConcurrentQueue;
- friend class ConcurrentQueueTests;
-
-private: // but shared with ConcurrentQueue
- std::uint32_t initialOffset;
- std::uint32_t lastKnownGlobalOffset;
- std::uint32_t itemsConsumedFromCurrent;
- details::ConcurrentQueueProducerTypelessBase* currentProducer;
- details::ConcurrentQueueProducerTypelessBase* desiredProducer;
-};
-
-// Need to forward-declare this swap because it's in a namespace.
-// See
-// http://stackoverflow.com/questions/4492062/why-does-a-c-friend-class-need-a-forward-declaration-only-in-other-namespaces
-template <typename T, typename Traits>
-inline void
-swap(typename ConcurrentQueue<T, Traits>::ImplicitProducerKVP& a,
- typename ConcurrentQueue<T, Traits>::ImplicitProducerKVP& b) MOODYCAMEL_NOEXCEPT;
-
-
-template <typename T, typename Traits = ConcurrentQueueDefaultTraits>
-class ConcurrentQueue
-{
-public:
- typedef ::moodycamel::ProducerToken producer_token_t;
- typedef ::moodycamel::ConsumerToken consumer_token_t;
-
- typedef typename Traits::index_t index_t;
- typedef typename Traits::size_t size_t;
-
- static const size_t BLOCK_SIZE = static_cast<size_t>(Traits::BLOCK_SIZE);
- static const size_t EXPLICIT_BLOCK_EMPTY_COUNTER_THRESHOLD =
- static_cast<size_t>(Traits::EXPLICIT_BLOCK_EMPTY_COUNTER_THRESHOLD);
- static const size_t EXPLICIT_INITIAL_INDEX_SIZE =
- static_cast<size_t>(Traits::EXPLICIT_INITIAL_INDEX_SIZE);
- static const size_t IMPLICIT_INITIAL_INDEX_SIZE =
- static_cast<size_t>(Traits::IMPLICIT_INITIAL_INDEX_SIZE);
- static const size_t INITIAL_IMPLICIT_PRODUCER_HASH_SIZE =
- static_cast<size_t>(Traits::INITIAL_IMPLICIT_PRODUCER_HASH_SIZE);
- static const std::uint32_t EXPLICIT_CONSUMER_CONSUMPTION_QUOTA_BEFORE_ROTATE =
- static_cast<std::uint32_t>(
- Traits::EXPLICIT_CONSUMER_CONSUMPTION_QUOTA_BEFORE_ROTATE);
-#ifdef _MSC_VER
-#pragma warning(push)
-#pragma warning(disable : 4307) // + integral constant overflow (that's what the ternary
- // expression is for!)
-#pragma warning(disable : 4309) // static_cast: Truncation of constant value
-#endif
- static const size_t MAX_SUBQUEUE_SIZE =
- (details::const_numeric_max<size_t>::value -
- static_cast<size_t>(Traits::MAX_SUBQUEUE_SIZE) <
- BLOCK_SIZE)
- ? details::const_numeric_max<size_t>::value
- : ((static_cast<size_t>(Traits::MAX_SUBQUEUE_SIZE) + (BLOCK_SIZE - 1)) /
- BLOCK_SIZE * BLOCK_SIZE);
-#ifdef _MSC_VER
-#pragma warning(pop)
-#endif
-
- static_assert(!std::numeric_limits<size_t>::is_signed &&
- std::is_integral<size_t>::value,
- "Traits::size_t must be an unsigned integral type");
- static_assert(!std::numeric_limits<index_t>::is_signed &&
- std::is_integral<index_t>::value,
- "Traits::index_t must be an unsigned integral type");
- static_assert(sizeof(index_t) >= sizeof(size_t),
- "Traits::index_t must be at least as wide as Traits::size_t");
- static_assert((BLOCK_SIZE > 1) && !(BLOCK_SIZE & (BLOCK_SIZE - 1)),
- "Traits::BLOCK_SIZE must be a power of 2 (and at least 2)");
- static_assert((EXPLICIT_BLOCK_EMPTY_COUNTER_THRESHOLD > 1) &&
- !(EXPLICIT_BLOCK_EMPTY_COUNTER_THRESHOLD &
- (EXPLICIT_BLOCK_EMPTY_COUNTER_THRESHOLD - 1)),
- "Traits::EXPLICIT_BLOCK_EMPTY_COUNTER_THRESHOLD must be a power of 2 "
- "(and greater than 1)");
- static_assert(
- (EXPLICIT_INITIAL_INDEX_SIZE > 1) &&
- !(EXPLICIT_INITIAL_INDEX_SIZE & (EXPLICIT_INITIAL_INDEX_SIZE - 1)),
- "Traits::EXPLICIT_INITIAL_INDEX_SIZE must be a power of 2 (and greater than 1)");
- static_assert(
- (IMPLICIT_INITIAL_INDEX_SIZE > 1) &&
- !(IMPLICIT_INITIAL_INDEX_SIZE & (IMPLICIT_INITIAL_INDEX_SIZE - 1)),
- "Traits::IMPLICIT_INITIAL_INDEX_SIZE must be a power of 2 (and greater than 1)");
- static_assert((INITIAL_IMPLICIT_PRODUCER_HASH_SIZE == 0) ||
- !(INITIAL_IMPLICIT_PRODUCER_HASH_SIZE &
- (INITIAL_IMPLICIT_PRODUCER_HASH_SIZE - 1)),
- "Traits::INITIAL_IMPLICIT_PRODUCER_HASH_SIZE must be a power of 2");
- static_assert(INITIAL_IMPLICIT_PRODUCER_HASH_SIZE == 0 ||
- INITIAL_IMPLICIT_PRODUCER_HASH_SIZE >= 1,
- "Traits::INITIAL_IMPLICIT_PRODUCER_HASH_SIZE must be at least 1 (or 0 "
- "to disable implicit enqueueing)");
-
-public:
- // Creates a queue with at least `capacity` element slots; note that the
- // actual number of elements that can be inserted without additional memory
- // allocation depends on the number of producers and the block size (e.g. if
- // the block size is equal to `capacity`, only a single block will be allocated
- // up-front, which means only a single producer will be able to enqueue elements
- // without an extra allocation -- blocks aren't shared between producers).
- // This method is not thread safe -- it is up to the user to ensure that the
- // queue is fully constructed before it starts being used by other threads (this
- // includes making the memory effects of construction visible, possibly with a
- // memory barrier).
- explicit ConcurrentQueue(size_t capacity = 6 * BLOCK_SIZE)
- : producerListTail(nullptr),
- producerCount(0),
- initialBlockPoolIndex(0),
- nextExplicitConsumerId(0),
- globalExplicitConsumerOffset(0)
- {
- implicitProducerHashResizeInProgress.clear(std::memory_order_relaxed);
- populate_initial_implicit_producer_hash();
- populate_initial_block_list(capacity / BLOCK_SIZE +
- ((capacity & (BLOCK_SIZE - 1)) == 0 ? 0 : 1));
-
-#ifdef MOODYCAMEL_QUEUE_INTERNAL_DEBUG
- // Track all the producers using a fully-resolved typed list for
- // each kind; this makes it possible to debug them starting from
- // the root queue object (otherwise wacky casts are needed that
- // don't compile in the debugger's expression evaluator).
- explicitProducers.store(nullptr, std::memory_order_relaxed);
- implicitProducers.store(nullptr, std::memory_order_relaxed);
-#endif
- }
-
- // Computes the correct amount of pre-allocated blocks for you based
- // on the minimum number of elements you want available at any given
- // time, and the maximum concurrent number of each type of producer.
- ConcurrentQueue(size_t minCapacity,
- size_t maxExplicitProducers,
- size_t maxImplicitProducers)
- : producerListTail(nullptr),
- producerCount(0),
- initialBlockPoolIndex(0),
- nextExplicitConsumerId(0),
- globalExplicitConsumerOffset(0)
- {
- implicitProducerHashResizeInProgress.clear(std::memory_order_relaxed);
- populate_initial_implicit_producer_hash();
- size_t blocks = (((minCapacity + BLOCK_SIZE - 1) / BLOCK_SIZE) - 1) *
- (maxExplicitProducers + 1) +
- 2 * (maxExplicitProducers + maxImplicitProducers);
- populate_initial_block_list(blocks);
-
-#ifdef MOODYCAMEL_QUEUE_INTERNAL_DEBUG
- explicitProducers.store(nullptr, std::memory_order_relaxed);
- implicitProducers.store(nullptr, std::memory_order_relaxed);
-#endif
- }
-
- // Note: The queue should not be accessed concurrently while it's
- // being deleted. It's up to the user to synchronize this.
- // This method is not thread safe.
- ~ConcurrentQueue()
- {
- // Destroy producers
- auto ptr = producerListTail.load(std::memory_order_relaxed);
- while (ptr != nullptr) {
- auto next = ptr->next_prod();
- if (ptr->token != nullptr) {
- ptr->token->producer = nullptr;
- }
- destroy(ptr);
- ptr = next;
- }
-
- // Destroy implicit producer hash tables
- MOODYCAMEL_CONSTEXPR_IF(INITIAL_IMPLICIT_PRODUCER_HASH_SIZE != 0)
- {
- auto hash = implicitProducerHash.load(std::memory_order_relaxed);
- while (hash != nullptr) {
- auto prev = hash->prev;
- if (prev != nullptr) { // The last hash is part of this object and was not
- // allocated dynamically
- for (size_t i = 0; i != hash->capacity; ++i) {
- hash->entries[i].~ImplicitProducerKVP();
- }
- hash->~ImplicitProducerHash();
- (Traits::free)(hash);
- }
- hash = prev;
- }
- }
-
- // Destroy global free list
- auto block = freeList.head_unsafe();
- while (block != nullptr) {
- auto next = block->freeListNext.load(std::memory_order_relaxed);
- if (block->dynamicallyAllocated) {
- destroy(block);
- }
- block = next;
- }
-
- // Destroy initial free list
- destroy_array(initialBlockPool, initialBlockPoolSize);
- }
-
- // Disable copying and copy assignment
- ConcurrentQueue(ConcurrentQueue const&) MOODYCAMEL_DELETE_FUNCTION;
- ConcurrentQueue& operator=(ConcurrentQueue const&) MOODYCAMEL_DELETE_FUNCTION;
-
- // Moving is supported, but note that it is *not* a thread-safe operation.
- // Nobody can use the queue while it's being moved, and the memory effects
- // of that move must be propagated to other threads before they can use it.
- // Note: When a queue is moved, its tokens are still valid but can only be
- // used with the destination queue (i.e. semantically they are moved along
- // with the queue itself).
- ConcurrentQueue(ConcurrentQueue&& other) MOODYCAMEL_NOEXCEPT
- : producerListTail(other.producerListTail.load(std::memory_order_relaxed)),
- producerCount(other.producerCount.load(std::memory_order_relaxed)),
- initialBlockPoolIndex(
- other.initialBlockPoolIndex.load(std::memory_order_relaxed)),
- initialBlockPool(other.initialBlockPool),
- initialBlockPoolSize(other.initialBlockPoolSize),
- freeList(std::move(other.freeList)),
- nextExplicitConsumerId(
- other.nextExplicitConsumerId.load(std::memory_order_relaxed)),
- globalExplicitConsumerOffset(
- other.globalExplicitConsumerOffset.load(std::memory_order_relaxed))
- {
- // Move the other one into this, and leave the other one as an empty queue
- implicitProducerHashResizeInProgress.clear(std::memory_order_relaxed);
- populate_initial_implicit_producer_hash();
- swap_implicit_producer_hashes(other);
-
- other.producerListTail.store(nullptr, std::memory_order_relaxed);
- other.producerCount.store(0, std::memory_order_relaxed);
- other.nextExplicitConsumerId.store(0, std::memory_order_relaxed);
- other.globalExplicitConsumerOffset.store(0, std::memory_order_relaxed);
-
-#ifdef MOODYCAMEL_QUEUE_INTERNAL_DEBUG
- explicitProducers.store(other.explicitProducers.load(std::memory_order_relaxed),
- std::memory_order_relaxed);
- other.explicitProducers.store(nullptr, std::memory_order_relaxed);
- implicitProducers.store(other.implicitProducers.load(std::memory_order_relaxed),
- std::memory_order_relaxed);
- other.implicitProducers.store(nullptr, std::memory_order_relaxed);
-#endif
-
- other.initialBlockPoolIndex.store(0, std::memory_order_relaxed);
- other.initialBlockPoolSize = 0;
- other.initialBlockPool = nullptr;
-
- reown_producers();
- }
-
- inline ConcurrentQueue& operator=(ConcurrentQueue&& other) MOODYCAMEL_NOEXCEPT
- {
- return swap_internal(other);
- }
-
- // Swaps this queue's state with the other's. Not thread-safe.
- // Swapping two queues does not invalidate their tokens, however
- // the tokens that were created for one queue must be used with
- // only the swapped queue (i.e. the tokens are tied to the
- // queue's movable state, not the object itself).
- inline void swap(ConcurrentQueue& other) MOODYCAMEL_NOEXCEPT { swap_internal(other); }
-
-private:
- ConcurrentQueue& swap_internal(ConcurrentQueue& other)
- {
- if (this == &other) {
- return *this;
- }
-
- details::swap_relaxed(producerListTail, other.producerListTail);
- details::swap_relaxed(producerCount, other.producerCount);
- details::swap_relaxed(initialBlockPoolIndex, other.initialBlockPoolIndex);
- std::swap(initialBlockPool, other.initialBlockPool);
- std::swap(initialBlockPoolSize, other.initialBlockPoolSize);
- freeList.swap(other.freeList);
- details::swap_relaxed(nextExplicitConsumerId, other.nextExplicitConsumerId);
- details::swap_relaxed(globalExplicitConsumerOffset,
- other.globalExplicitConsumerOffset);
-
- swap_implicit_producer_hashes(other);
-
- reown_producers();
- other.reown_producers();
-
-#ifdef MOODYCAMEL_QUEUE_INTERNAL_DEBUG
- details::swap_relaxed(explicitProducers, other.explicitProducers);
- details::swap_relaxed(implicitProducers, other.implicitProducers);
-#endif
-
- return *this;
- }
-
-public:
- // Enqueues a single item (by copying it).
- // Allocates memory if required. Only fails if memory allocation fails (or implicit
- // production is disabled because Traits::INITIAL_IMPLICIT_PRODUCER_HASH_SIZE is 0,
- // or Traits::MAX_SUBQUEUE_SIZE has been defined and would be surpassed).
- // Thread-safe.
- inline bool enqueue(T const& item)
- {
- MOODYCAMEL_CONSTEXPR_IF(INITIAL_IMPLICIT_PRODUCER_HASH_SIZE == 0) return false;
- else return inner_enqueue<CanAlloc>(item);
- }
-
- // Enqueues a single item (by moving it, if possible).
- // Allocates memory if required. Only fails if memory allocation fails (or implicit
- // production is disabled because Traits::INITIAL_IMPLICIT_PRODUCER_HASH_SIZE is 0,
- // or Traits::MAX_SUBQUEUE_SIZE has been defined and would be surpassed).
- // Thread-safe.
- inline bool enqueue(T&& item)
- {
- MOODYCAMEL_CONSTEXPR_IF(INITIAL_IMPLICIT_PRODUCER_HASH_SIZE == 0) return false;
- else return inner_enqueue<CanAlloc>(std::move(item));
- }
-
- // Enqueues a single item (by copying it) using an explicit producer token.
- // Allocates memory if required. Only fails if memory allocation fails (or
- // Traits::MAX_SUBQUEUE_SIZE has been defined and would be surpassed).
- // Thread-safe.
- inline bool enqueue(producer_token_t const& token, T const& item)
- {
- return inner_enqueue<CanAlloc>(token, item);
- }
-
- // Enqueues a single item (by moving it, if possible) using an explicit producer
- // token. Allocates memory if required. Only fails if memory allocation fails (or
- // Traits::MAX_SUBQUEUE_SIZE has been defined and would be surpassed).
- // Thread-safe.
- inline bool enqueue(producer_token_t const& token, T&& item)
- {
- return inner_enqueue<CanAlloc>(token, std::move(item));
- }
-
- // Enqueues several items.
- // Allocates memory if required. Only fails if memory allocation fails (or
- // implicit production is disabled because Traits::INITIAL_IMPLICIT_PRODUCER_HASH_SIZE
- // is 0, or Traits::MAX_SUBQUEUE_SIZE has been defined and would be surpassed).
- // Note: Use std::make_move_iterator if the elements should be moved instead of
- // copied. Thread-safe.
- template <typename It>
- bool enqueue_bulk(It itemFirst, size_t count)
- {
- MOODYCAMEL_CONSTEXPR_IF(INITIAL_IMPLICIT_PRODUCER_HASH_SIZE == 0) return false;
- else return inner_enqueue_bulk<CanAlloc>(itemFirst, count);
- }
-
- // Enqueues several items using an explicit producer token.
- // Allocates memory if required. Only fails if memory allocation fails
- // (or Traits::MAX_SUBQUEUE_SIZE has been defined and would be surpassed).
- // Note: Use std::make_move_iterator if the elements should be moved
- // instead of copied.
- // Thread-safe.
- template <typename It>
- bool enqueue_bulk(producer_token_t const& token, It itemFirst, size_t count)
- {
- return inner_enqueue_bulk<CanAlloc>(token, itemFirst, count);
- }
-
- // Enqueues a single item (by copying it).
- // Does not allocate memory. Fails if not enough room to enqueue (or implicit
- // production is disabled because Traits::INITIAL_IMPLICIT_PRODUCER_HASH_SIZE
- // is 0).
- // Thread-safe.
- inline bool try_enqueue(T const& item)
- {
- MOODYCAMEL_CONSTEXPR_IF(INITIAL_IMPLICIT_PRODUCER_HASH_SIZE == 0) return false;
- else return inner_enqueue<CannotAlloc>(item);
- }
-
- // Enqueues a single item (by moving it, if possible).
- // Does not allocate memory (except for one-time implicit producer).
- // Fails if not enough room to enqueue (or implicit production is
- // disabled because Traits::INITIAL_IMPLICIT_PRODUCER_HASH_SIZE is 0).
- // Thread-safe.
- inline bool try_enqueue(T&& item)
- {
- MOODYCAMEL_CONSTEXPR_IF(INITIAL_IMPLICIT_PRODUCER_HASH_SIZE == 0) return false;
- else return inner_enqueue<CannotAlloc>(std::move(item));
- }
-
- // Enqueues a single item (by copying it) using an explicit producer token.
- // Does not allocate memory. Fails if not enough room to enqueue.
- // Thread-safe.
- inline bool try_enqueue(producer_token_t const& token, T const& item)
- {
- return inner_enqueue<CannotAlloc>(token, item);
- }
-
- // Enqueues a single item (by moving it, if possible) using an explicit producer
- // token. Does not allocate memory. Fails if not enough room to enqueue. Thread-safe.
- inline bool try_enqueue(producer_token_t const& token, T&& item)
- {
- return inner_enqueue<CannotAlloc>(token, std::move(item));
- }
-
- // Enqueues several items.
- // Does not allocate memory (except for one-time implicit producer).
- // Fails if not enough room to enqueue (or implicit production is
- // disabled because Traits::INITIAL_IMPLICIT_PRODUCER_HASH_SIZE is 0).
- // Note: Use std::make_move_iterator if the elements should be moved
- // instead of copied.
- // Thread-safe.
- template <typename It>
- bool try_enqueue_bulk(It itemFirst, size_t count)
- {
- MOODYCAMEL_CONSTEXPR_IF(INITIAL_IMPLICIT_PRODUCER_HASH_SIZE == 0) return false;
- else return inner_enqueue_bulk<CannotAlloc>(itemFirst, count);
- }
-
- // Enqueues several items using an explicit producer token.
- // Does not allocate memory. Fails if not enough room to enqueue.
- // Note: Use std::make_move_iterator if the elements should be moved
- // instead of copied.
- // Thread-safe.
- template <typename It>
- bool try_enqueue_bulk(producer_token_t const& token, It itemFirst, size_t count)
- {
- return inner_enqueue_bulk<CannotAlloc>(token, itemFirst, count);
- }
-
-
- // Attempts to dequeue from the queue.
- // Returns false if all producer streams appeared empty at the time they
- // were checked (so, the queue is likely but not guaranteed to be empty).
- // Never allocates. Thread-safe.
- template <typename U>
- bool try_dequeue(U& item)
- {
- // Instead of simply trying each producer in turn (which could cause needless
- // contention on the first producer), we score them heuristically.
- size_t nonEmptyCount = 0;
- ProducerBase* best = nullptr;
- size_t bestSize = 0;
- for (auto ptr = producerListTail.load(std::memory_order_acquire);
- nonEmptyCount < 3 && ptr != nullptr;
- ptr = ptr->next_prod()) {
- auto size = ptr->size_approx();
- if (size > 0) {
- if (size > bestSize) {
- bestSize = size;
- best = ptr;
- }
- ++nonEmptyCount;
- }
- }
-
- // If there was at least one non-empty queue but it appears empty at the time
- // we try to dequeue from it, we need to make sure every queue's been tried
- if (nonEmptyCount > 0) {
- if ((details::likely)(best->dequeue(item))) {
- return true;
- }
- for (auto ptr = producerListTail.load(std::memory_order_acquire);
- ptr != nullptr;
- ptr = ptr->next_prod()) {
- if (ptr != best && ptr->dequeue(item)) {
- return true;
- }
- }
- }
- return false;
- }
-
- // Attempts to dequeue from the queue.
- // Returns false if all producer streams appeared empty at the time they
- // were checked (so, the queue is likely but not guaranteed to be empty).
- // This differs from the try_dequeue(item) method in that this one does
- // not attempt to reduce contention by interleaving the order that producer
- // streams are dequeued from. So, using this method can reduce overall throughput
- // under contention, but will give more predictable results in single-threaded
- // consumer scenarios. This is mostly only useful for internal unit tests.
- // Never allocates. Thread-safe.
- template <typename U>
- bool try_dequeue_non_interleaved(U& item)
- {
- for (auto ptr = producerListTail.load(std::memory_order_acquire); ptr != nullptr;
- ptr = ptr->next_prod()) {
- if (ptr->dequeue(item)) {
- return true;
- }
- }
- return false;
- }
-
- // Attempts to dequeue from the queue using an explicit consumer token.
- // Returns false if all producer streams appeared empty at the time they
- // were checked (so, the queue is likely but not guaranteed to be empty).
- // Never allocates. Thread-safe.
- template <typename U>
- bool try_dequeue(consumer_token_t& token, U& item)
- {
- // The idea is roughly as follows:
- // Every 256 items from one producer, make everyone rotate (increase the global
- // offset) -> this means the highest efficiency consumer dictates the rotation
- // speed of everyone else, more or less If you see that the global offset has
- // changed, you must reset your consumption counter and move to your designated
- // place If there's no items where you're supposed to be, keep moving until you
- // find a producer with some items If the global offset has not changed but you've
- // run out of items to consume, move over from your current position until you
- // find an producer with something in it
-
- if (token.desiredProducer == nullptr ||
- token.lastKnownGlobalOffset !=
- globalExplicitConsumerOffset.load(std::memory_order_relaxed)) {
- if (!update_current_producer_after_rotation(token)) {
- return false;
- }
- }
-
- // If there was at least one non-empty queue but it appears empty at the time
- // we try to dequeue from it, we need to make sure every queue's been tried
- if (static_cast<ProducerBase*>(token.currentProducer)->dequeue(item)) {
- if (++token.itemsConsumedFromCurrent ==
- EXPLICIT_CONSUMER_CONSUMPTION_QUOTA_BEFORE_ROTATE) {
- globalExplicitConsumerOffset.fetch_add(1, std::memory_order_relaxed);
- }
- return true;
- }
-
- auto tail = producerListTail.load(std::memory_order_acquire);
- auto ptr = static_cast<ProducerBase*>(token.currentProducer)->next_prod();
- if (ptr == nullptr) {
- ptr = tail;
- }
- while (ptr != static_cast<ProducerBase*>(token.currentProducer)) {
- if (ptr->dequeue(item)) {
- token.currentProducer = ptr;
- token.itemsConsumedFromCurrent = 1;
- return true;
- }
- ptr = ptr->next_prod();
- if (ptr == nullptr) {
- ptr = tail;
- }
- }
- return false;
- }
-
- // Attempts to dequeue several elements from the queue.
- // Returns the number of items actually dequeued.
- // Returns 0 if all producer streams appeared empty at the time they
- // were checked (so, the queue is likely but not guaranteed to be empty).
- // Never allocates. Thread-safe.
- template <typename It>
- size_t try_dequeue_bulk(It itemFirst, size_t max)
- {
- size_t count = 0;
- for (auto ptr = producerListTail.load(std::memory_order_acquire); ptr != nullptr;
- ptr = ptr->next_prod()) {
- count += ptr->dequeue_bulk(itemFirst, max - count);
- if (count == max) {
- break;
- }
- }
- return count;
- }
-
- // Attempts to dequeue several elements from the queue using an explicit consumer
- // token. Returns the number of items actually dequeued. Returns 0 if all producer
- // streams appeared empty at the time they were checked (so, the queue is likely but
- // not guaranteed to be empty). Never allocates. Thread-safe.
- template <typename It>
- size_t try_dequeue_bulk(consumer_token_t& token, It itemFirst, size_t max)
- {
- if (token.desiredProducer == nullptr ||
- token.lastKnownGlobalOffset !=
- globalExplicitConsumerOffset.load(std::memory_order_relaxed)) {
- if (!update_current_producer_after_rotation(token)) {
- return 0;
- }
- }
-
- size_t count = static_cast<ProducerBase*>(token.currentProducer)
- ->dequeue_bulk(itemFirst, max);
- if (count == max) {
- if ((token.itemsConsumedFromCurrent += static_cast<std::uint32_t>(max)) >=
- EXPLICIT_CONSUMER_CONSUMPTION_QUOTA_BEFORE_ROTATE) {
- globalExplicitConsumerOffset.fetch_add(1, std::memory_order_relaxed);
- }
- return max;
- }
- token.itemsConsumedFromCurrent += static_cast<std::uint32_t>(count);
- max -= count;
-
- auto tail = producerListTail.load(std::memory_order_acquire);
- auto ptr = static_cast<ProducerBase*>(token.currentProducer)->next_prod();
- if (ptr == nullptr) {
- ptr = tail;
- }
- while (ptr != static_cast<ProducerBase*>(token.currentProducer)) {
- auto dequeued = ptr->dequeue_bulk(itemFirst, max);
- count += dequeued;
- if (dequeued != 0) {
- token.currentProducer = ptr;
- token.itemsConsumedFromCurrent = static_cast<std::uint32_t>(dequeued);
- }
- if (dequeued == max) {
- break;
- }
- max -= dequeued;
- ptr = ptr->next_prod();
- if (ptr == nullptr) {
- ptr = tail;
- }
- }
- return count;
- }
-
-
- // Attempts to dequeue from a specific producer's inner queue.
- // If you happen to know which producer you want to dequeue from, this
- // is significantly faster than using the general-case try_dequeue methods.
- // Returns false if the producer's queue appeared empty at the time it
- // was checked (so, the queue is likely but not guaranteed to be empty).
- // Never allocates. Thread-safe.
- template <typename U>
- inline bool try_dequeue_from_producer(producer_token_t const& producer, U& item)
- {
- return static_cast<ExplicitProducer*>(producer.producer)->dequeue(item);
- }
-
- // Attempts to dequeue several elements from a specific producer's inner queue.
- // Returns the number of items actually dequeued.
- // If you happen to know which producer you want to dequeue from, this
- // is significantly faster than using the general-case try_dequeue methods.
- // Returns 0 if the producer's queue appeared empty at the time it
- // was checked (so, the queue is likely but not guaranteed to be empty).
- // Never allocates. Thread-safe.
- template <typename It>
- inline size_t try_dequeue_bulk_from_producer(producer_token_t const& producer,
- It itemFirst,
- size_t max)
- {
- return static_cast<ExplicitProducer*>(producer.producer)
- ->dequeue_bulk(itemFirst, max);
- }
-
-
- // Returns an estimate of the total number of elements currently in the queue. This
- // estimate is only accurate if the queue has completely stabilized before it is
- // called (i.e. all enqueue and dequeue operations have completed and their memory
- // effects are visible on the calling thread, and no further operations start while
- // this method is being called). Thread-safe.
- size_t size_approx() const
- {
- size_t size = 0;
- for (auto ptr = producerListTail.load(std::memory_order_acquire); ptr != nullptr;
- ptr = ptr->next_prod()) {
- size += ptr->size_approx();
- }
- return size;
- }
-
-
- // Returns true if the underlying atomic variables used by
- // the queue are lock-free (they should be on most platforms).
- // Thread-safe.
- static bool is_lock_free()
- {
- return details::static_is_lock_free<bool>::value == 2 &&
- details::static_is_lock_free<size_t>::value == 2 &&
- details::static_is_lock_free<std::uint32_t>::value == 2 &&
- details::static_is_lock_free<index_t>::value == 2 &&
- details::static_is_lock_free<void*>::value == 2 &&
- details::static_is_lock_free<typename details::thread_id_converter<
- details::thread_id_t>::thread_id_numeric_size_t>::value == 2;
- }
-
-
-private:
- friend struct ProducerToken;
- friend struct ConsumerToken;
- struct ExplicitProducer;
- friend struct ExplicitProducer;
- struct ImplicitProducer;
- friend struct ImplicitProducer;
- friend class ConcurrentQueueTests;
-
- enum AllocationMode { CanAlloc, CannotAlloc };
-
-
- ///////////////////////////////
- // Queue methods
- ///////////////////////////////
-
- template <AllocationMode canAlloc, typename U>
- inline bool inner_enqueue(producer_token_t const& token, U&& element)
- {
- return static_cast<ExplicitProducer*>(token.producer)
- ->ConcurrentQueue::ExplicitProducer::template enqueue<canAlloc>(
- std::forward<U>(element));
- }
-
- template <AllocationMode canAlloc, typename U>
- inline bool inner_enqueue(U&& element)
- {
- auto producer = get_or_add_implicit_producer();
- return producer == nullptr
- ? false
- : producer
- ->ConcurrentQueue::ImplicitProducer::template enqueue<canAlloc>(
- std::forward<U>(element));
- }
-
- template <AllocationMode canAlloc, typename It>
- inline bool
- inner_enqueue_bulk(producer_token_t const& token, It itemFirst, size_t count)
- {
- return static_cast<ExplicitProducer*>(token.producer)
- ->ConcurrentQueue::ExplicitProducer::template enqueue_bulk<canAlloc>(
- itemFirst, count);
- }
-
- template <AllocationMode canAlloc, typename It>
- inline bool inner_enqueue_bulk(It itemFirst, size_t count)
- {
- auto producer = get_or_add_implicit_producer();
- return producer == nullptr
- ? false
- : producer->ConcurrentQueue::ImplicitProducer::template enqueue_bulk<
- canAlloc>(itemFirst, count);
- }
-
- inline bool update_current_producer_after_rotation(consumer_token_t& token)
- {
- // Ah, there's been a rotation, figure out where we should be!
- auto tail = producerListTail.load(std::memory_order_acquire);
- if (token.desiredProducer == nullptr && tail == nullptr) {
- return false;
- }
- auto prodCount = producerCount.load(std::memory_order_relaxed);
- auto globalOffset = globalExplicitConsumerOffset.load(std::memory_order_relaxed);
- if ((details::unlikely)(token.desiredProducer == nullptr)) {
- // Aha, first time we're dequeueing anything.
- // Figure out our local position
- // Note: offset is from start, not end, but we're traversing from end --
- // subtract from count first
- std::uint32_t offset = prodCount - 1 - (token.initialOffset % prodCount);
- token.desiredProducer = tail;
- for (std::uint32_t i = 0; i != offset; ++i) {
- token.desiredProducer =
- static_cast<ProducerBase*>(token.desiredProducer)->next_prod();
- if (token.desiredProducer == nullptr) {
- token.desiredProducer = tail;
- }
- }
- }
-
- std::uint32_t delta = globalOffset - token.lastKnownGlobalOffset;
- if (delta >= prodCount) {
- delta = delta % prodCount;
- }
- for (std::uint32_t i = 0; i != delta; ++i) {
- token.desiredProducer =
- static_cast<ProducerBase*>(token.desiredProducer)->next_prod();
- if (token.desiredProducer == nullptr) {
- token.desiredProducer = tail;
- }
- }
-
- token.lastKnownGlobalOffset = globalOffset;
- token.currentProducer = token.desiredProducer;
- token.itemsConsumedFromCurrent = 0;
- return true;
- }
-
-
- ///////////////////////////
- // Free list
- ///////////////////////////
-
- template <typename N>
- struct FreeListNode {
- FreeListNode() : freeListRefs(0), freeListNext(nullptr) {}
-
- std::atomic<std::uint32_t> freeListRefs;
- std::atomic<N*> freeListNext;
- };
-
- // A simple CAS-based lock-free free list. Not the fastest thing in the world under
- // heavy contention, but simple and correct (assuming nodes are never freed until
- // after the free list is destroyed), and fairly speedy under low contention.
- template <typename N> // N must inherit FreeListNode or have the same fields (and
- // initialization of them)
- struct FreeList {
- FreeList() : freeListHead(nullptr) {}
- FreeList(FreeList&& other)
- : freeListHead(other.freeListHead.load(std::memory_order_relaxed))
- {
- other.freeListHead.store(nullptr, std::memory_order_relaxed);
- }
- void swap(FreeList& other)
- {
- details::swap_relaxed(freeListHead, other.freeListHead);
- }
-
- FreeList(FreeList const&) MOODYCAMEL_DELETE_FUNCTION;
- FreeList& operator=(FreeList const&) MOODYCAMEL_DELETE_FUNCTION;
-
- inline void add(N* node)
- {
-#ifdef MCDBGQ_NOLOCKFREE_FREELIST
- debug::DebugLock lock(mutex);
-#endif
- // We know that the should-be-on-freelist bit is 0 at this point, so it's safe
- // to set it using a fetch_add
- if (node->freeListRefs.fetch_add(SHOULD_BE_ON_FREELIST,
- std::memory_order_acq_rel) == 0) {
- // Oh look! We were the last ones referencing this node, and we know
- // we want to add it to the free list, so let's do it!
- add_knowing_refcount_is_zero(node);
- }
- }
-
- inline N* try_get()
- {
-#ifdef MCDBGQ_NOLOCKFREE_FREELIST
- debug::DebugLock lock(mutex);
-#endif
- auto head = freeListHead.load(std::memory_order_acquire);
- while (head != nullptr) {
- auto prevHead = head;
- auto refs = head->freeListRefs.load(std::memory_order_relaxed);
- if ((refs & REFS_MASK) == 0 ||
- !head->freeListRefs.compare_exchange_strong(
- refs,
- refs + 1,
- std::memory_order_acquire,
- std::memory_order_relaxed)) {
- head = freeListHead.load(std::memory_order_acquire);
- continue;
- }
-
- // Good, reference count has been incremented (it wasn't at zero), which
- // means we can read the next and not worry about it changing between now
- // and the time we do the CAS
- auto next = head->freeListNext.load(std::memory_order_relaxed);
- if (freeListHead.compare_exchange_strong(head,
- next,
- std::memory_order_acquire,
- std::memory_order_relaxed)) {
- // Yay, got the node. This means it was on the list, which means
- // shouldBeOnFreeList must be false no matter the refcount (because
- // nobody else knows it's been taken off yet, it can't have been put
- // back on).
- assert((head->freeListRefs.load(std::memory_order_relaxed) &
- SHOULD_BE_ON_FREELIST) == 0);
-
- // Decrease refcount twice, once for our ref, and once for the list's
- // ref
- head->freeListRefs.fetch_sub(2, std::memory_order_release);
- return head;
- }
-
- // OK, the head must have changed on us, but we still need to decrease the
- // refcount we increased. Note that we don't need to release any memory
- // effects, but we do need to ensure that the reference count decrement
- // happens-after the CAS on the head.
- refs = prevHead->freeListRefs.fetch_sub(1, std::memory_order_acq_rel);
- if (refs == SHOULD_BE_ON_FREELIST + 1) {
- add_knowing_refcount_is_zero(prevHead);
- }
- }
-
- return nullptr;
- }
-
- // Useful for traversing the list when there's no contention (e.g. to destroy
- // remaining nodes)
- N* head_unsafe() const { return freeListHead.load(std::memory_order_relaxed); }
-
- private:
- inline void add_knowing_refcount_is_zero(N* node)
- {
- // Since the refcount is zero, and nobody can increase it once it's zero
- // (except us, and we run only one copy of this method per node at a time,
- // i.e. the single thread case), then we know we can safely change the next
- // pointer of the node; however, once the refcount is back above zero, then
- // other threads could increase it (happens under heavy contention, when the
- // refcount goes to zero in between a load and a refcount increment of a node
- // in try_get, then back up to something non-zero, then the refcount increment
- // is done by the other thread) -- so, if the CAS to add the node to the
- // actual list fails, decrease the refcount and leave the add operation to the
- // next thread who puts the refcount back at zero (which could be us, hence
- // the loop).
- auto head = freeListHead.load(std::memory_order_relaxed);
- while (true) {
- node->freeListNext.store(head, std::memory_order_relaxed);
- node->freeListRefs.store(1, std::memory_order_release);
- if (!freeListHead.compare_exchange_strong(head,
- node,
- std::memory_order_release,
- std::memory_order_relaxed)) {
- // Hmm, the add failed, but we can only try again when the refcount
- // goes back to zero
- if (node->freeListRefs.fetch_add(SHOULD_BE_ON_FREELIST - 1,
- std::memory_order_release) == 1) {
- continue;
- }
- }
- return;
- }
- }
-
- private:
- // Implemented like a stack, but where node order doesn't matter (nodes are
- // inserted out of order under contention)
- std::atomic<N*> freeListHead;
-
- static const std::uint32_t REFS_MASK = 0x7FFFFFFF;
- static const std::uint32_t SHOULD_BE_ON_FREELIST = 0x80000000;
-
-#ifdef MCDBGQ_NOLOCKFREE_FREELIST
- debug::DebugMutex mutex;
-#endif
- };
-
-
- ///////////////////////////
- // Block
- ///////////////////////////
-
- enum InnerQueueContext { implicit_context = 0, explicit_context = 1 };
-
- struct Block {
- Block()
- : next(nullptr),
- elementsCompletelyDequeued(0),
- freeListRefs(0),
- freeListNext(nullptr),
- shouldBeOnFreeList(false),
- dynamicallyAllocated(true)
- {
-#ifdef MCDBGQ_TRACKMEM
- owner = nullptr;
-#endif
- }
-
- template <InnerQueueContext context>
- inline bool is_empty() const
- {
- MOODYCAMEL_CONSTEXPR_IF(context == explicit_context &&
- BLOCK_SIZE <= EXPLICIT_BLOCK_EMPTY_COUNTER_THRESHOLD)
- {
- // Check flags
- for (size_t i = 0; i < BLOCK_SIZE; ++i) {
- if (!emptyFlags[i].load(std::memory_order_relaxed)) {
- return false;
- }
- }
-
- // Aha, empty; make sure we have all other memory effects that happened
- // before the empty flags were set
- std::atomic_thread_fence(std::memory_order_acquire);
- return true;
- }
- else
- {
- // Check counter
- if (elementsCompletelyDequeued.load(std::memory_order_relaxed) ==
- BLOCK_SIZE) {
- std::atomic_thread_fence(std::memory_order_acquire);
- return true;
- }
- assert(elementsCompletelyDequeued.load(std::memory_order_relaxed) <=
- BLOCK_SIZE);
- return false;
- }
- }
-
- // Returns true if the block is now empty (does not apply in explicit context)
- template <InnerQueueContext context>
- inline bool set_empty(MOODYCAMEL_MAYBE_UNUSED index_t i)
- {
- MOODYCAMEL_CONSTEXPR_IF(context == explicit_context &&
- BLOCK_SIZE <= EXPLICIT_BLOCK_EMPTY_COUNTER_THRESHOLD)
- {
- // Set flag
- assert(!emptyFlags[BLOCK_SIZE - 1 -
- static_cast<size_t>(
- i & static_cast<index_t>(BLOCK_SIZE - 1))]
- .load(std::memory_order_relaxed));
- emptyFlags[BLOCK_SIZE - 1 -
- static_cast<size_t>(i & static_cast<index_t>(BLOCK_SIZE - 1))]
- .store(true, std::memory_order_release);
- return false;
- }
- else
- {
- // Increment counter
- auto prevVal =
- elementsCompletelyDequeued.fetch_add(1, std::memory_order_release);
- assert(prevVal < BLOCK_SIZE);
- return prevVal == BLOCK_SIZE - 1;
- }
- }
-
- // Sets multiple contiguous item statuses to 'empty' (assumes no wrapping and
- // count > 0). Returns true if the block is now empty (does not apply in explicit
- // context).
- template <InnerQueueContext context>
- inline bool set_many_empty(MOODYCAMEL_MAYBE_UNUSED index_t i, size_t count)
- {
- MOODYCAMEL_CONSTEXPR_IF(context == explicit_context &&
- BLOCK_SIZE <= EXPLICIT_BLOCK_EMPTY_COUNTER_THRESHOLD)
- {
- // Set flags
- std::atomic_thread_fence(std::memory_order_release);
- i = BLOCK_SIZE - 1 -
- static_cast<size_t>(i & static_cast<index_t>(BLOCK_SIZE - 1)) -
- count + 1;
- for (size_t j = 0; j != count; ++j) {
- assert(!emptyFlags[i + j].load(std::memory_order_relaxed));
- emptyFlags[i + j].store(true, std::memory_order_relaxed);
- }
- return false;
- }
- else
- {
- // Increment counter
- auto prevVal = elementsCompletelyDequeued.fetch_add(
- count, std::memory_order_release);
- assert(prevVal + count <= BLOCK_SIZE);
- return prevVal + count == BLOCK_SIZE;
- }
- }
-
- template <InnerQueueContext context>
- inline void set_all_empty()
- {
- MOODYCAMEL_CONSTEXPR_IF(context == explicit_context &&
- BLOCK_SIZE <= EXPLICIT_BLOCK_EMPTY_COUNTER_THRESHOLD)
- {
- // Set all flags
- for (size_t i = 0; i != BLOCK_SIZE; ++i) {
- emptyFlags[i].store(true, std::memory_order_relaxed);
- }
- }
- else
- {
- // Reset counter
- elementsCompletelyDequeued.store(BLOCK_SIZE, std::memory_order_relaxed);
- }
- }
-
- template <InnerQueueContext context>
- inline void reset_empty()
- {
- MOODYCAMEL_CONSTEXPR_IF(context == explicit_context &&
- BLOCK_SIZE <= EXPLICIT_BLOCK_EMPTY_COUNTER_THRESHOLD)
- {
- // Reset flags
- for (size_t i = 0; i != BLOCK_SIZE; ++i) {
- emptyFlags[i].store(false, std::memory_order_relaxed);
- }
- }
- else
- {
- // Reset counter
- elementsCompletelyDequeued.store(0, std::memory_order_relaxed);
- }
- }
-
- inline T* operator[](index_t idx) MOODYCAMEL_NOEXCEPT
- {
- return static_cast<T*>(static_cast<void*>(elements)) +
- static_cast<size_t>(idx & static_cast<index_t>(BLOCK_SIZE - 1));
- }
- inline T const* operator[](index_t idx) const MOODYCAMEL_NOEXCEPT
- {
- return static_cast<T const*>(static_cast<void const*>(elements)) +
- static_cast<size_t>(idx & static_cast<index_t>(BLOCK_SIZE - 1));
- }
-
- private:
- static_assert(std::alignment_of<T>::value <= sizeof(T),
- "The queue does not support types with an alignment greater than "
- "their size at this time");
- MOODYCAMEL_ALIGNED_TYPE_LIKE(char[sizeof(T) * BLOCK_SIZE], T) elements;
-
- public:
- Block* next;
- std::atomic<size_t> elementsCompletelyDequeued;
- std::atomic<bool> emptyFlags[BLOCK_SIZE <= EXPLICIT_BLOCK_EMPTY_COUNTER_THRESHOLD
- ? BLOCK_SIZE
- : 1];
-
- public:
- std::atomic<std::uint32_t> freeListRefs;
- std::atomic<Block*> freeListNext;
- std::atomic<bool> shouldBeOnFreeList;
- bool dynamicallyAllocated; // Perhaps a better name for this would be
- // 'isNotPartOfInitialBlockPool'
-
-#ifdef MCDBGQ_TRACKMEM
- void* owner;
-#endif
- };
- static_assert(std::alignment_of<Block>::value >= std::alignment_of<T>::value,
- "Internal error: Blocks must be at least as aligned as the type they "
- "are wrapping");
-
-
-#ifdef MCDBGQ_TRACKMEM
-public:
- struct MemStats;
-
-private:
-#endif
-
- ///////////////////////////
- // Producer base
- ///////////////////////////
-
- struct ProducerBase : public details::ConcurrentQueueProducerTypelessBase {
- ProducerBase(ConcurrentQueue* parent_, bool isExplicit_)
- : tailIndex(0),
- headIndex(0),
- dequeueOptimisticCount(0),
- dequeueOvercommit(0),
- tailBlock(nullptr),
- isExplicit(isExplicit_),
- parent(parent_)
- {
- }
-
- virtual ~ProducerBase() {}
-
- template <typename U>
- inline bool dequeue(U& element)
- {
- if (isExplicit) {
- return static_cast<ExplicitProducer*>(this)->dequeue(element);
- }
- else {
- return static_cast<ImplicitProducer*>(this)->dequeue(element);
- }
- }
-
- template <typename It>
- inline size_t dequeue_bulk(It& itemFirst, size_t max)
- {
- if (isExplicit) {
- return static_cast<ExplicitProducer*>(this)->dequeue_bulk(itemFirst, max);
- }
- else {
- return static_cast<ImplicitProducer*>(this)->dequeue_bulk(itemFirst, max);
- }
- }
-
- inline ProducerBase* next_prod() const
- {
- return static_cast<ProducerBase*>(next);
- }
-
- inline size_t size_approx() const
- {
- auto tail = tailIndex.load(std::memory_order_relaxed);
- auto head = headIndex.load(std::memory_order_relaxed);
- return details::circular_less_than(head, tail)
- ? static_cast<size_t>(tail - head)
- : 0;
- }
-
- inline index_t getTail() const
- {
- return tailIndex.load(std::memory_order_relaxed);
- }
-
- protected:
- std::atomic<index_t> tailIndex; // Where to enqueue to next
- std::atomic<index_t> headIndex; // Where to dequeue from next
-
- std::atomic<index_t> dequeueOptimisticCount;
- std::atomic<index_t> dequeueOvercommit;
-
- Block* tailBlock;
-
- public:
- bool isExplicit;
- ConcurrentQueue* parent;
-
- protected:
-#ifdef MCDBGQ_TRACKMEM
- friend struct MemStats;
-#endif
- };
-
-
- ///////////////////////////
- // Explicit queue
- ///////////////////////////
-
- struct ExplicitProducer : public ProducerBase {
- explicit ExplicitProducer(ConcurrentQueue* parent_)
- : ProducerBase(parent_, true),
- blockIndex(nullptr),
- pr_blockIndexSlotsUsed(0),
- pr_blockIndexSize(EXPLICIT_INITIAL_INDEX_SIZE >> 1),
- pr_blockIndexFront(0),
- pr_blockIndexEntries(nullptr),
- pr_blockIndexRaw(nullptr)
- {
- size_t poolBasedIndexSize =
- details::ceil_to_pow_2(parent_->initialBlockPoolSize) >> 1;
- if (poolBasedIndexSize > pr_blockIndexSize) {
- pr_blockIndexSize = poolBasedIndexSize;
- }
-
- new_block_index(0); // This creates an index with double the number of current
- // entries, i.e. EXPLICIT_INITIAL_INDEX_SIZE
- }
-
- ~ExplicitProducer() override
- {
- // Destruct any elements not yet dequeued.
- // Since we're in the destructor, we can assume all elements
- // are either completely dequeued or completely not (no halfways).
- if (this->tailBlock !=
- nullptr) { // Note this means there must be a block index too
- // First find the block that's partially dequeued, if any
- Block* halfDequeuedBlock = nullptr;
- if ((this->headIndex.load(std::memory_order_relaxed) &
- static_cast<index_t>(BLOCK_SIZE - 1)) != 0) {
- // The head's not on a block boundary, meaning a block somewhere is
- // partially dequeued (or the head block is the tail block and was
- // fully dequeued, but the head/tail are still not on a boundary)
- size_t i = (pr_blockIndexFront - pr_blockIndexSlotsUsed) &
- (pr_blockIndexSize - 1);
- while (details::circular_less_than<index_t>(
- pr_blockIndexEntries[i].base + BLOCK_SIZE,
- this->headIndex.load(std::memory_order_relaxed))) {
- i = (i + 1) & (pr_blockIndexSize - 1);
- }
- assert(details::circular_less_than<index_t>(
- pr_blockIndexEntries[i].base,
- this->headIndex.load(std::memory_order_relaxed)));
- halfDequeuedBlock = pr_blockIndexEntries[i].block;
- }
-
- // Start at the head block (note the first line in the loop gives us the
- // head from the tail on the first iteration)
- auto block = this->tailBlock;
- do {
- block = block->next;
- if (block->ConcurrentQueue::Block::template is_empty<
- explicit_context>()) {
- continue;
- }
-
- size_t i = 0; // Offset into block
- if (block == halfDequeuedBlock) {
- i = static_cast<size_t>(
- this->headIndex.load(std::memory_order_relaxed) &
- static_cast<index_t>(BLOCK_SIZE - 1));
- }
-
- // Walk through all the items in the block; if this is the tail block,
- // we need to stop when we reach the tail index
- auto lastValidIndex =
- (this->tailIndex.load(std::memory_order_relaxed) &
- static_cast<index_t>(BLOCK_SIZE - 1)) == 0
- ? BLOCK_SIZE
- : static_cast<size_t>(
- this->tailIndex.load(std::memory_order_relaxed) &
- static_cast<index_t>(BLOCK_SIZE - 1));
- while (i != BLOCK_SIZE &&
- (block != this->tailBlock || i != lastValidIndex)) {
- (*block)[i++]->~T();
- }
- } while (block != this->tailBlock);
- }
-
- // Destroy all blocks that we own
- if (this->tailBlock != nullptr) {
- auto block = this->tailBlock;
- do {
- auto nextBlock = block->next;
- if (block->dynamicallyAllocated) {
- destroy(block);
- }
- else {
- this->parent->add_block_to_free_list(block);
- }
- block = nextBlock;
- } while (block != this->tailBlock);
- }
-
- // Destroy the block indices
- auto header = static_cast<BlockIndexHeader*>(pr_blockIndexRaw);
- while (header != nullptr) {
- auto prev = static_cast<BlockIndexHeader*>(header->prev);
- header->~BlockIndexHeader();
- (Traits::free)(header);
- header = prev;
- }
- }
-
- template <AllocationMode allocMode, typename U>
- inline bool enqueue(U&& element)
- {
- index_t currentTailIndex = this->tailIndex.load(std::memory_order_relaxed);
- index_t newTailIndex = 1 + currentTailIndex;
- if ((currentTailIndex & static_cast<index_t>(BLOCK_SIZE - 1)) == 0) {
- // We reached the end of a block, start a new one
- auto startBlock = this->tailBlock;
- auto originalBlockIndexSlotsUsed = pr_blockIndexSlotsUsed;
- if (this->tailBlock != nullptr &&
- this->tailBlock->next
- ->ConcurrentQueue::Block::template is_empty<explicit_context>()) {
- // We can re-use the block ahead of us, it's empty!
- this->tailBlock = this->tailBlock->next;
- this->tailBlock->ConcurrentQueue::Block::template reset_empty<
- explicit_context>();
-
- // We'll put the block on the block index (guaranteed to be room since
- // we're conceptually removing the last block from it first -- except
- // instead of removing then adding, we can just overwrite). Note that
- // there must be a valid block index here, since even if allocation
- // failed in the ctor, it would have been re-attempted when adding the
- // first block to the queue; since there is such a block, a block
- // index must have been successfully allocated.
- }
- else {
- // Whatever head value we see here is >= the last value we saw here
- // (relatively), and <= its current value. Since we have the most
- // recent tail, the head must be
- // <= to it.
- auto head = this->headIndex.load(std::memory_order_relaxed);
- assert(!details::circular_less_than<index_t>(currentTailIndex, head));
- if (!details::circular_less_than<index_t>(
- head, currentTailIndex + BLOCK_SIZE) ||
- (MAX_SUBQUEUE_SIZE != details::const_numeric_max<size_t>::value &&
- (MAX_SUBQUEUE_SIZE == 0 ||
- MAX_SUBQUEUE_SIZE - BLOCK_SIZE < currentTailIndex - head))) {
- // We can't enqueue in another block because there's not enough
- // leeway -- the tail could surpass the head by the time the block
- // fills up! (Or we'll exceed the size limit, if the second part
- // of the condition was true.)
- return false;
- }
- // We're going to need a new block; check that the block index has
- // room
- if (pr_blockIndexRaw == nullptr ||
- pr_blockIndexSlotsUsed == pr_blockIndexSize) {
- // Hmm, the circular block index is already full -- we'll need
- // to allocate a new index. Note pr_blockIndexRaw can only be
- // nullptr if the initial allocation failed in the constructor.
-
- MOODYCAMEL_CONSTEXPR_IF(allocMode == CannotAlloc)
- {
- return false;
- }
- else if (!new_block_index(pr_blockIndexSlotsUsed))
- {
- return false;
- }
- }
-
- // Insert a new block in the circular linked list
- auto newBlock =
- this->parent
- ->ConcurrentQueue::template requisition_block<allocMode>();
- if (newBlock == nullptr) {
- return false;
- }
-#ifdef MCDBGQ_TRACKMEM
- newBlock->owner = this;
-#endif
- newBlock->ConcurrentQueue::Block::template reset_empty<
- explicit_context>();
- if (this->tailBlock == nullptr) {
- newBlock->next = newBlock;
- }
- else {
- newBlock->next = this->tailBlock->next;
- this->tailBlock->next = newBlock;
- }
- this->tailBlock = newBlock;
- ++pr_blockIndexSlotsUsed;
- }
-
- MOODYCAMEL_CONSTEXPR_IF(!MOODYCAMEL_NOEXCEPT_CTOR(
- T, U, new (static_cast<T*>(nullptr)) T(std::forward<U>(element))))
- {
- // The constructor may throw. We want the element not to appear in the
- // queue in that case (without corrupting the queue):
- MOODYCAMEL_TRY
- {
- new ((*this->tailBlock)[currentTailIndex])
- T(std::forward<U>(element));
- }
- MOODYCAMEL_CATCH(...)
- {
- // Revert change to the current block, but leave the new block
- // available for next time
- pr_blockIndexSlotsUsed = originalBlockIndexSlotsUsed;
- this->tailBlock =
- startBlock == nullptr ? this->tailBlock : startBlock;
- MOODYCAMEL_RETHROW;
- }
- }
- else
- {
- (void)startBlock;
- (void)originalBlockIndexSlotsUsed;
- }
-
- // Add block to block index
- auto& entry = blockIndex.load(std::memory_order_relaxed)
- ->entries[pr_blockIndexFront];
- entry.base = currentTailIndex;
- entry.block = this->tailBlock;
- blockIndex.load(std::memory_order_relaxed)
- ->front.store(pr_blockIndexFront, std::memory_order_release);
- pr_blockIndexFront = (pr_blockIndexFront + 1) & (pr_blockIndexSize - 1);
-
- MOODYCAMEL_CONSTEXPR_IF(!MOODYCAMEL_NOEXCEPT_CTOR(
- T, U, new (static_cast<T*>(nullptr)) T(std::forward<U>(element))))
- {
- this->tailIndex.store(newTailIndex, std::memory_order_release);
- return true;
- }
- }
-
- // Enqueue
- new ((*this->tailBlock)[currentTailIndex]) T(std::forward<U>(element));
-
- this->tailIndex.store(newTailIndex, std::memory_order_release);
- return true;
- }
-
- template <typename U>
- bool dequeue(U& element)
- {
- auto tail = this->tailIndex.load(std::memory_order_relaxed);
- auto overcommit = this->dequeueOvercommit.load(std::memory_order_relaxed);
- if (details::circular_less_than<index_t>(
- this->dequeueOptimisticCount.load(std::memory_order_relaxed) -
- overcommit,
- tail)) {
- // Might be something to dequeue, let's give it a try
-
- // Note that this if is purely for performance purposes in the common case
- // when the queue is empty and the values are eventually consistent -- we
- // may enter here spuriously.
-
- // Note that whatever the values of overcommit and tail are, they are not
- // going to change (unless we change them) and must be the same value at
- // this point (inside the if) as when the if condition was evaluated.
-
- // We insert an acquire fence here to synchronize-with the release upon
- // incrementing dequeueOvercommit below. This ensures that whatever the
- // value we got loaded into overcommit, the load of dequeueOptisticCount
- // in the fetch_add below will result in a value at least as recent as
- // that (and therefore at least as large). Note that I believe a compiler
- // (signal) fence here would be sufficient due to the nature of fetch_add
- // (all read-modify-write operations are guaranteed to work on the latest
- // value in the modification order), but unfortunately that can't be shown
- // to be correct using only the C++11 standard. See
- // http://stackoverflow.com/questions/18223161/what-are-the-c11-memory-ordering-guarantees-in-this-corner-case
- std::atomic_thread_fence(std::memory_order_acquire);
-
- // Increment optimistic counter, then check if it went over the boundary
- auto myDequeueCount =
- this->dequeueOptimisticCount.fetch_add(1, std::memory_order_relaxed);
-
- // Note that since dequeueOvercommit must be <= dequeueOptimisticCount
- // (because dequeueOvercommit is only ever incremented after
- // dequeueOptimisticCount -- this is enforced in the `else` block below),
- // and since we now have a version of dequeueOptimisticCount that is at
- // least as recent as overcommit (due to the release upon incrementing
- // dequeueOvercommit and the acquire above that synchronizes with it),
- // overcommit <= myDequeueCount. However, we can't assert this since both
- // dequeueOptimisticCount and dequeueOvercommit may (independently)
- // overflow; in such a case, though, the logic still holds since the
- // difference between the two is maintained.
-
- // Note that we reload tail here in case it changed; it will be the same
- // value as before or greater, since this load is sequenced after (happens
- // after) the earlier load above. This is supported by read-read coherency
- // (as defined in the standard), explained here:
- // http://en.cppreference.com/w/cpp/atomic/memory_order
- tail = this->tailIndex.load(std::memory_order_acquire);
- if ((details::likely)(details::circular_less_than<index_t>(
- myDequeueCount - overcommit, tail))) {
- // Guaranteed to be at least one element to dequeue!
-
- // Get the index. Note that since there's guaranteed to be at least
- // one element, this will never exceed tail. We need to do an
- // acquire-release fence here since it's possible that whatever
- // condition got us to this point was for an earlier enqueued element
- // (that we already see the memory effects for), but that by the time
- // we increment somebody else has incremented it, and we need to see
- // the memory effects for *that* element, which is in such a case is
- // necessarily visible on the thread that incremented it in the first
- // place with the more current condition (they must have acquired a
- // tail that is at least as recent).
- auto index = this->headIndex.fetch_add(1, std::memory_order_acq_rel);
-
-
- // Determine which block the element is in
-
- auto localBlockIndex = blockIndex.load(std::memory_order_acquire);
- auto localBlockIndexHead =
- localBlockIndex->front.load(std::memory_order_acquire);
-
- // We need to be careful here about subtracting and dividing because
- // of index wrap-around. When an index wraps, we need to preserve the
- // sign of the offset when dividing it by the block size (in order to
- // get a correct signed block count offset in all cases):
- auto headBase = localBlockIndex->entries[localBlockIndexHead].base;
- auto blockBaseIndex = index & ~static_cast<index_t>(BLOCK_SIZE - 1);
- auto offset = static_cast<size_t>(
- static_cast<typename std::make_signed<index_t>::type>(
- blockBaseIndex - headBase) /
- BLOCK_SIZE);
- auto block = localBlockIndex
- ->entries[(localBlockIndexHead + offset) &
- (localBlockIndex->size - 1)]
- .block;
-
- // Dequeue
- auto& el = *((*block)[index]);
- if (!MOODYCAMEL_NOEXCEPT_ASSIGN(T, T&&, element = std::move(el))) {
- // Make sure the element is still fully dequeued and destroyed
- // even if the assignment throws
- struct Guard {
- Block* block;
- index_t index;
-
- ~Guard()
- {
- (*block)[index]->~T();
- block->ConcurrentQueue::Block::template set_empty<
- explicit_context>(index);
- }
- } guard = { block, index };
-
- element = std::move(el); // NOLINT
- }
- else {
- element = std::move(el); // NOLINT
- el.~T(); // NOLINT
- block->ConcurrentQueue::Block::template set_empty<
- explicit_context>(index);
- }
-
- return true;
- }
- else {
- // Wasn't anything to dequeue after all; make the effective dequeue
- // count eventually consistent
- this->dequeueOvercommit.fetch_add(
- 1, std::memory_order_release); // Release so that the fetch_add on
- // dequeueOptimisticCount is
- // guaranteed to happen before this
- // write
- }
- }
-
- return false;
- }
-
- template <AllocationMode allocMode, typename It>
- bool MOODYCAMEL_NO_TSAN enqueue_bulk(It itemFirst, size_t count)
- {
- // First, we need to make sure we have enough room to enqueue all of the
- // elements; this means pre-allocating blocks and putting them in the block
- // index (but only if all the allocations succeeded).
- index_t startTailIndex = this->tailIndex.load(std::memory_order_relaxed);
- auto startBlock = this->tailBlock;
- auto originalBlockIndexFront = pr_blockIndexFront;
- auto originalBlockIndexSlotsUsed = pr_blockIndexSlotsUsed;
-
- Block* firstAllocatedBlock = nullptr;
-
- // Figure out how many blocks we'll need to allocate, and do so
- size_t blockBaseDiff =
- ((startTailIndex + count - 1) & ~static_cast<index_t>(BLOCK_SIZE - 1)) -
- ((startTailIndex - 1) & ~static_cast<index_t>(BLOCK_SIZE - 1));
- index_t currentTailIndex =
- (startTailIndex - 1) & ~static_cast<index_t>(BLOCK_SIZE - 1);
- if (blockBaseDiff > 0) {
- // Allocate as many blocks as possible from ahead
- while (
- blockBaseDiff > 0 && this->tailBlock != nullptr &&
- this->tailBlock->next != firstAllocatedBlock &&
- this->tailBlock->next
- ->ConcurrentQueue::Block::template is_empty<explicit_context>()) {
- blockBaseDiff -= static_cast<index_t>(BLOCK_SIZE);
- currentTailIndex += static_cast<index_t>(BLOCK_SIZE);
-
- this->tailBlock = this->tailBlock->next;
- firstAllocatedBlock = firstAllocatedBlock == nullptr
- ? this->tailBlock
- : firstAllocatedBlock;
-
- auto& entry = blockIndex.load(std::memory_order_relaxed)
- ->entries[pr_blockIndexFront];
- entry.base = currentTailIndex;
- entry.block = this->tailBlock;
- pr_blockIndexFront =
- (pr_blockIndexFront + 1) & (pr_blockIndexSize - 1);
- }
-
- // Now allocate as many blocks as necessary from the block pool
- while (blockBaseDiff > 0) {
- blockBaseDiff -= static_cast<index_t>(BLOCK_SIZE);
- currentTailIndex += static_cast<index_t>(BLOCK_SIZE);
-
- auto head = this->headIndex.load(std::memory_order_relaxed);
- assert(!details::circular_less_than<index_t>(currentTailIndex, head));
- bool full =
- !details::circular_less_than<index_t>(
- head, currentTailIndex + BLOCK_SIZE) ||
- (MAX_SUBQUEUE_SIZE != details::const_numeric_max<size_t>::value &&
- (MAX_SUBQUEUE_SIZE == 0 ||
- MAX_SUBQUEUE_SIZE - BLOCK_SIZE < currentTailIndex - head));
- if (pr_blockIndexRaw == nullptr ||
- pr_blockIndexSlotsUsed == pr_blockIndexSize || full) {
- MOODYCAMEL_CONSTEXPR_IF(allocMode == CannotAlloc)
- {
- // Failed to allocate, undo changes (but keep injected blocks)
- pr_blockIndexFront = originalBlockIndexFront;
- pr_blockIndexSlotsUsed = originalBlockIndexSlotsUsed;
- this->tailBlock =
- startBlock == nullptr ? firstAllocatedBlock : startBlock;
- return false;
- }
- else if (full || !new_block_index(originalBlockIndexSlotsUsed))
- {
- // Failed to allocate, undo changes (but keep injected blocks)
- pr_blockIndexFront = originalBlockIndexFront;
- pr_blockIndexSlotsUsed = originalBlockIndexSlotsUsed;
- this->tailBlock =
- startBlock == nullptr ? firstAllocatedBlock : startBlock;
- return false;
- }
-
- // pr_blockIndexFront is updated inside new_block_index, so we
- // need to update our fallback value too (since we keep the new
- // index even if we later fail)
- originalBlockIndexFront = originalBlockIndexSlotsUsed;
- }
-
- // Insert a new block in the circular linked list
- auto newBlock =
- this->parent
- ->ConcurrentQueue::template requisition_block<allocMode>();
- if (newBlock == nullptr) {
- pr_blockIndexFront = originalBlockIndexFront;
- pr_blockIndexSlotsUsed = originalBlockIndexSlotsUsed;
- this->tailBlock =
- startBlock == nullptr ? firstAllocatedBlock : startBlock;
- return false;
- }
-
-#ifdef MCDBGQ_TRACKMEM
- newBlock->owner = this;
-#endif
- newBlock->ConcurrentQueue::Block::template set_all_empty<
- explicit_context>();
- if (this->tailBlock == nullptr) {
- newBlock->next = newBlock;
- }
- else {
- newBlock->next = this->tailBlock->next;
- this->tailBlock->next = newBlock;
- }
- this->tailBlock = newBlock;
- firstAllocatedBlock = firstAllocatedBlock == nullptr
- ? this->tailBlock
- : firstAllocatedBlock;
-
- ++pr_blockIndexSlotsUsed;
-
- auto& entry = blockIndex.load(std::memory_order_relaxed)
- ->entries[pr_blockIndexFront];
- entry.base = currentTailIndex;
- entry.block = this->tailBlock;
- pr_blockIndexFront =
- (pr_blockIndexFront + 1) & (pr_blockIndexSize - 1);
- }
-
- // Excellent, all allocations succeeded. Reset each block's emptiness
- // before we fill them up, and publish the new block index front
- auto block = firstAllocatedBlock;
- while (true) {
- block->ConcurrentQueue::Block::template reset_empty<
- explicit_context>();
- if (block == this->tailBlock) {
- break;
- }
- block = block->next;
- }
-
- MOODYCAMEL_CONSTEXPR_IF(MOODYCAMEL_NOEXCEPT_CTOR(
- T,
- decltype(*itemFirst),
- new (static_cast<T*>(nullptr)) T(details::deref_noexcept(itemFirst))))
- {
- blockIndex.load(std::memory_order_relaxed)
- ->front.store((pr_blockIndexFront - 1) & (pr_blockIndexSize - 1),
- std::memory_order_release);
- }
- }
-
- // Enqueue, one block at a time
- index_t newTailIndex = startTailIndex + static_cast<index_t>(count);
- currentTailIndex = startTailIndex;
- auto endBlock = this->tailBlock;
- this->tailBlock = startBlock;
- assert((startTailIndex & static_cast<index_t>(BLOCK_SIZE - 1)) != 0 ||
- firstAllocatedBlock != nullptr || count == 0);
- if ((startTailIndex & static_cast<index_t>(BLOCK_SIZE - 1)) == 0 &&
- firstAllocatedBlock != nullptr) {
- this->tailBlock = firstAllocatedBlock;
- }
- while (true) {
- index_t stopIndex =
- (currentTailIndex & ~static_cast<index_t>(BLOCK_SIZE - 1)) +
- static_cast<index_t>(BLOCK_SIZE);
- if (details::circular_less_than<index_t>(newTailIndex, stopIndex)) {
- stopIndex = newTailIndex;
- }
- MOODYCAMEL_CONSTEXPR_IF(MOODYCAMEL_NOEXCEPT_CTOR(
- T,
- decltype(*itemFirst),
- new (static_cast<T*>(nullptr)) T(details::deref_noexcept(itemFirst))))
- {
- while (currentTailIndex != stopIndex) {
- new ((*this->tailBlock)[currentTailIndex++]) T(*itemFirst++);
- }
- }
- else
- {
- MOODYCAMEL_TRY
- {
- while (currentTailIndex != stopIndex) {
- // Must use copy constructor even if move constructor is
- // available because we may have to revert if there's an
- // exception. Sorry about the horrible templated next line,
- // but it was the only way to disable moving *at compile
- // time*, which is important because a type may only define a
- // (noexcept) move constructor, and so calls to the cctor will
- // not compile, even if they are in an if branch that will
- // never be executed
- new ((*this->tailBlock)[currentTailIndex])
- T(details::nomove_if<!MOODYCAMEL_NOEXCEPT_CTOR(
- T,
- decltype(*itemFirst),
- new (static_cast<T*>(nullptr))
- T(details::deref_noexcept(
- itemFirst)))>::eval(*itemFirst));
- ++currentTailIndex;
- ++itemFirst;
- }
- }
- MOODYCAMEL_CATCH(...)
- {
- // Oh dear, an exception's been thrown -- destroy the elements
- // that were enqueued so far and revert the entire bulk operation
- // (we'll keep any allocated blocks in our linked list for later,
- // though).
- auto constructedStopIndex = currentTailIndex;
- auto lastBlockEnqueued = this->tailBlock;
-
- pr_blockIndexFront = originalBlockIndexFront;
- pr_blockIndexSlotsUsed = originalBlockIndexSlotsUsed;
- this->tailBlock =
- startBlock == nullptr ? firstAllocatedBlock : startBlock;
-
- if (!details::is_trivially_destructible<T>::value) {
- auto block = startBlock;
- if ((startTailIndex & static_cast<index_t>(BLOCK_SIZE - 1)) ==
- 0) {
- block = firstAllocatedBlock;
- }
- currentTailIndex = startTailIndex;
- while (true) {
- stopIndex = (currentTailIndex &
- ~static_cast<index_t>(BLOCK_SIZE - 1)) +
- static_cast<index_t>(BLOCK_SIZE);
- if (details::circular_less_than<index_t>(
- constructedStopIndex, stopIndex)) {
- stopIndex = constructedStopIndex;
- }
- while (currentTailIndex != stopIndex) {
- (*block)[currentTailIndex++]->~T();
- }
- if (block == lastBlockEnqueued) {
- break;
- }
- block = block->next;
- }
- }
- MOODYCAMEL_RETHROW;
- }
- }
-
- if (this->tailBlock == endBlock) {
- assert(currentTailIndex == newTailIndex);
- break;
- }
- this->tailBlock = this->tailBlock->next;
- }
-
- MOODYCAMEL_CONSTEXPR_IF(!MOODYCAMEL_NOEXCEPT_CTOR(
- T,
- decltype(*itemFirst),
- new (static_cast<T*>(nullptr)) T(details::deref_noexcept(itemFirst))))
- {
- if (firstAllocatedBlock != nullptr)
- blockIndex.load(std::memory_order_relaxed)
- ->front.store((pr_blockIndexFront - 1) & (pr_blockIndexSize - 1),
- std::memory_order_release);
- }
-
- this->tailIndex.store(newTailIndex, std::memory_order_release);
- return true;
- }
-
- template <typename It>
- size_t dequeue_bulk(It& itemFirst, size_t max)
- {
- auto tail = this->tailIndex.load(std::memory_order_relaxed);
- auto overcommit = this->dequeueOvercommit.load(std::memory_order_relaxed);
- auto desiredCount = static_cast<size_t>(
- tail - (this->dequeueOptimisticCount.load(std::memory_order_relaxed) -
- overcommit));
- if (details::circular_less_than<size_t>(0, desiredCount)) {
- desiredCount = desiredCount < max ? desiredCount : max;
- std::atomic_thread_fence(std::memory_order_acquire);
-
- auto myDequeueCount = this->dequeueOptimisticCount.fetch_add(
- desiredCount, std::memory_order_relaxed);
-
- tail = this->tailIndex.load(std::memory_order_acquire);
- auto actualCount =
- static_cast<size_t>(tail - (myDequeueCount - overcommit));
- if (details::circular_less_than<size_t>(0, actualCount)) {
- actualCount = desiredCount < actualCount ? desiredCount : actualCount;
- if (actualCount < desiredCount) {
- this->dequeueOvercommit.fetch_add(desiredCount - actualCount,
- std::memory_order_release);
- }
-
- // Get the first index. Note that since there's guaranteed to be at
- // least actualCount elements, this will never exceed tail.
- auto firstIndex =
- this->headIndex.fetch_add(actualCount, std::memory_order_acq_rel);
-
- // Determine which block the first element is in
- auto localBlockIndex = blockIndex.load(std::memory_order_acquire);
- auto localBlockIndexHead =
- localBlockIndex->front.load(std::memory_order_acquire);
-
- auto headBase = localBlockIndex->entries[localBlockIndexHead].base;
- auto firstBlockBaseIndex =
- firstIndex & ~static_cast<index_t>(BLOCK_SIZE - 1);
- auto offset = static_cast<size_t>(
- static_cast<typename std::make_signed<index_t>::type>(
- firstBlockBaseIndex - headBase) /
- BLOCK_SIZE);
- auto indexIndex =
- (localBlockIndexHead + offset) & (localBlockIndex->size - 1);
-
- // Iterate the blocks and dequeue
- auto index = firstIndex;
- do {
- auto firstIndexInBlock = index;
- index_t endIndex =
- (index & ~static_cast<index_t>(BLOCK_SIZE - 1)) +
- static_cast<index_t>(BLOCK_SIZE);
- endIndex =
- details::circular_less_than<index_t>(
- firstIndex + static_cast<index_t>(actualCount), endIndex)
- ? firstIndex + static_cast<index_t>(actualCount)
- : endIndex;
- auto block = localBlockIndex->entries[indexIndex].block;
- if (MOODYCAMEL_NOEXCEPT_ASSIGN(
- T,
- T&&,
- details::deref_noexcept(itemFirst) =
- std::move((*(*block)[index])))) {
- while (index != endIndex) {
- auto& el = *((*block)[index]);
- *itemFirst++ = std::move(el);
- el.~T();
- ++index;
- }
- }
- else {
- MOODYCAMEL_TRY
- {
- while (index != endIndex) {
- auto& el = *((*block)[index]);
- *itemFirst = std::move(el);
- ++itemFirst;
- el.~T();
- ++index;
- }
- }
- MOODYCAMEL_CATCH(...)
- {
- // It's too late to revert the dequeue, but we can make
- // sure that all the dequeued objects are properly
- // destroyed and the block index (and empty count) are
- // properly updated before we propagate the exception
- do {
- block = localBlockIndex->entries[indexIndex].block;
- while (index != endIndex) {
- (*block)[index++]->~T();
- }
- block->ConcurrentQueue::Block::
- template set_many_empty<explicit_context>(
- firstIndexInBlock,
- static_cast<size_t>(endIndex -
- firstIndexInBlock));
- indexIndex =
- (indexIndex + 1) & (localBlockIndex->size - 1);
-
- firstIndexInBlock = index;
- endIndex =
- (index & ~static_cast<index_t>(BLOCK_SIZE - 1)) +
- static_cast<index_t>(BLOCK_SIZE);
- endIndex = details::circular_less_than<index_t>(
- firstIndex +
- static_cast<index_t>(actualCount),
- endIndex)
- ? firstIndex +
- static_cast<index_t>(actualCount)
- : endIndex;
- } while (index != firstIndex + actualCount);
-
- MOODYCAMEL_RETHROW;
- }
- }
- block->ConcurrentQueue::Block::template set_many_empty<
- explicit_context>(
- firstIndexInBlock,
- static_cast<size_t>(endIndex - firstIndexInBlock));
- indexIndex = (indexIndex + 1) & (localBlockIndex->size - 1);
- } while (index != firstIndex + actualCount);
-
- return actualCount;
- }
- else {
- // Wasn't anything to dequeue after all; make the effective dequeue
- // count eventually consistent
- this->dequeueOvercommit.fetch_add(desiredCount,
- std::memory_order_release);
- }
- }
-
- return 0;
- }
-
- private:
- struct BlockIndexEntry {
- index_t base;
- Block* block;
- };
-
- struct BlockIndexHeader {
- size_t size;
- std::atomic<size_t> front; // Current slot (not next, like pr_blockIndexFront)
- BlockIndexEntry* entries;
- void* prev;
- };
-
-
- bool new_block_index(size_t numberOfFilledSlotsToExpose)
- {
- auto prevBlockSizeMask = pr_blockIndexSize - 1;
-
- // Create the new block
- pr_blockIndexSize <<= 1;
- auto newRawPtr = static_cast<char*>((Traits::malloc)(
- sizeof(BlockIndexHeader) + std::alignment_of<BlockIndexEntry>::value - 1 +
- sizeof(BlockIndexEntry) * pr_blockIndexSize));
- if (newRawPtr == nullptr) {
- pr_blockIndexSize >>= 1; // Reset to allow graceful retry
- return false;
- }
-
- auto newBlockIndexEntries =
- reinterpret_cast<BlockIndexEntry*>(details::align_for<BlockIndexEntry>(
- newRawPtr + sizeof(BlockIndexHeader)));
-
- // Copy in all the old indices, if any
- size_t j = 0;
- if (pr_blockIndexSlotsUsed != 0) {
- auto i =
- (pr_blockIndexFront - pr_blockIndexSlotsUsed) & prevBlockSizeMask;
- do {
- newBlockIndexEntries[j++] = pr_blockIndexEntries[i];
- i = (i + 1) & prevBlockSizeMask;
- } while (i != pr_blockIndexFront);
- }
-
- // Update everything
- auto header = new (newRawPtr) BlockIndexHeader;
- header->size = pr_blockIndexSize;
- header->front.store(numberOfFilledSlotsToExpose - 1,
- std::memory_order_relaxed);
- header->entries = newBlockIndexEntries;
- header->prev = pr_blockIndexRaw; // we link the new block to the old one so we
- // can free it later
-
- pr_blockIndexFront = j;
- pr_blockIndexEntries = newBlockIndexEntries;
- pr_blockIndexRaw = newRawPtr;
- blockIndex.store(header, std::memory_order_release);
-
- return true;
- }
-
- private:
- std::atomic<BlockIndexHeader*> blockIndex;
-
- // To be used by producer only -- consumer must use the ones in referenced by
- // blockIndex
- size_t pr_blockIndexSlotsUsed;
- size_t pr_blockIndexSize;
- size_t pr_blockIndexFront; // Next slot (not current)
- BlockIndexEntry* pr_blockIndexEntries;
- void* pr_blockIndexRaw;
-
-#ifdef MOODYCAMEL_QUEUE_INTERNAL_DEBUG
- public:
- ExplicitProducer* nextExplicitProducer;
-
- private:
-#endif
-
-#ifdef MCDBGQ_TRACKMEM
- friend struct MemStats;
-#endif
- };
-
-
- //////////////////////////////////
- // Implicit queue
- //////////////////////////////////
-
- struct ImplicitProducer : public ProducerBase {
- ImplicitProducer(ConcurrentQueue* parent_)
- : ProducerBase(parent_, false),
- nextBlockIndexCapacity(IMPLICIT_INITIAL_INDEX_SIZE),
- blockIndex(nullptr)
- {
- new_block_index();
- }
-
- ~ImplicitProducer() override
- {
- // Note that since we're in the destructor we can assume that all
- // enqueue/dequeue operations completed already; this means that all
- // undequeued elements are placed contiguously across contiguous blocks, and
- // that only the first and last remaining blocks can be only partially empty
- // (all other remaining blocks must be completely full).
-
-#ifdef MOODYCAMEL_CPP11_THREAD_LOCAL_SUPPORTED
- // Unregister ourselves for thread termination notification
- if (!this->inactive.load(std::memory_order_relaxed)) {
- details::ThreadExitNotifier::unsubscribe(&threadExitListener);
- }
-#endif
-
- // Destroy all remaining elements!
- auto tail = this->tailIndex.load(std::memory_order_relaxed);
- auto index = this->headIndex.load(std::memory_order_relaxed);
- Block* block = nullptr;
- assert(index == tail || details::circular_less_than(index, tail));
- bool forceFreeLastBlock =
- index != tail; // If we enter the loop, then the last (tail) block will
- // not be freed
- while (index != tail) {
- if ((index & static_cast<index_t>(BLOCK_SIZE - 1)) == 0 ||
- block == nullptr) {
- if (block != nullptr) {
- // Free the old block
- this->parent->add_block_to_free_list(block);
- }
-
- block = get_block_index_entry_for_index(index)->value.load(
- std::memory_order_relaxed);
- }
-
- ((*block)[index])->~T();
- ++index;
- }
- // Even if the queue is empty, there's still one block that's not on the free
- // list (unless the head index reached the end of it, in which case the tail
- // will be poised to create a new block).
- if (this->tailBlock != nullptr &&
- (forceFreeLastBlock ||
- (tail & static_cast<index_t>(BLOCK_SIZE - 1)) != 0)) {
- this->parent->add_block_to_free_list(this->tailBlock);
- }
-
- // Destroy block index
- auto localBlockIndex = blockIndex.load(std::memory_order_relaxed);
- if (localBlockIndex != nullptr) {
- for (size_t i = 0; i != localBlockIndex->capacity; ++i) {
- localBlockIndex->index[i]->~BlockIndexEntry();
- }
- do {
- auto prev = localBlockIndex->prev;
- localBlockIndex->~BlockIndexHeader();
- (Traits::free)(localBlockIndex);
- localBlockIndex = prev;
- } while (localBlockIndex != nullptr);
- }
- }
-
- template <AllocationMode allocMode, typename U>
- inline bool enqueue(U&& element)
- {
- index_t currentTailIndex = this->tailIndex.load(std::memory_order_relaxed);
- index_t newTailIndex = 1 + currentTailIndex;
- if ((currentTailIndex & static_cast<index_t>(BLOCK_SIZE - 1)) == 0) {
- // We reached the end of a block, start a new one
- auto head = this->headIndex.load(std::memory_order_relaxed);
- assert(!details::circular_less_than<index_t>(currentTailIndex, head));
- if (!details::circular_less_than<index_t>(
- head, currentTailIndex + BLOCK_SIZE) ||
- (MAX_SUBQUEUE_SIZE != details::const_numeric_max<size_t>::value &&
- (MAX_SUBQUEUE_SIZE == 0 ||
- MAX_SUBQUEUE_SIZE - BLOCK_SIZE < currentTailIndex - head))) {
- return false;
- }
-#ifdef MCDBGQ_NOLOCKFREE_IMPLICITPRODBLOCKINDEX
- debug::DebugLock lock(mutex);
-#endif
- // Find out where we'll be inserting this block in the block index
- BlockIndexEntry* idxEntry;
- if (!insert_block_index_entry<allocMode>(idxEntry, currentTailIndex)) {
- return false;
- }
-
- // Get ahold of a new block
- auto newBlock =
- this->parent
- ->ConcurrentQueue::template requisition_block<allocMode>();
- if (newBlock == nullptr) {
- rewind_block_index_tail();
- idxEntry->value.store(nullptr, std::memory_order_relaxed);
- return false;
- }
-#ifdef MCDBGQ_TRACKMEM
- newBlock->owner = this;
-#endif
- newBlock
- ->ConcurrentQueue::Block::template reset_empty<implicit_context>();
-
- MOODYCAMEL_CONSTEXPR_IF(!MOODYCAMEL_NOEXCEPT_CTOR(
- T, U, new (static_cast<T*>(nullptr)) T(std::forward<U>(element))))
- {
- // May throw, try to insert now before we publish the fact that we
- // have this new block
- MOODYCAMEL_TRY
- {
- new ((*newBlock)[currentTailIndex]) T(std::forward<U>(element));
- }
- MOODYCAMEL_CATCH(...)
- {
- rewind_block_index_tail();
- idxEntry->value.store(nullptr, std::memory_order_relaxed);
- this->parent->add_block_to_free_list(newBlock);
- MOODYCAMEL_RETHROW;
- }
- }
-
- // Insert the new block into the index
- idxEntry->value.store(newBlock, std::memory_order_relaxed);
-
- this->tailBlock = newBlock;
-
- MOODYCAMEL_CONSTEXPR_IF(!MOODYCAMEL_NOEXCEPT_CTOR(
- T, U, new (static_cast<T*>(nullptr)) T(std::forward<U>(element))))
- {
- this->tailIndex.store(newTailIndex, std::memory_order_release);
- return true;
- }
- }
-
- // Enqueue
- new ((*this->tailBlock)[currentTailIndex]) T(std::forward<U>(element));
-
- this->tailIndex.store(newTailIndex, std::memory_order_release);
- return true;
- }
-
- template <typename U>
- bool dequeue(U& element)
- {
- // See ExplicitProducer::dequeue for rationale and explanation
- index_t tail = this->tailIndex.load(std::memory_order_relaxed);
- index_t overcommit = this->dequeueOvercommit.load(std::memory_order_relaxed);
- if (details::circular_less_than<index_t>(
- this->dequeueOptimisticCount.load(std::memory_order_relaxed) -
- overcommit,
- tail)) {
- std::atomic_thread_fence(std::memory_order_acquire);
-
- index_t myDequeueCount =
- this->dequeueOptimisticCount.fetch_add(1, std::memory_order_relaxed);
- tail = this->tailIndex.load(std::memory_order_acquire);
- if ((details::likely)(details::circular_less_than<index_t>(
- myDequeueCount - overcommit, tail))) {
- index_t index =
- this->headIndex.fetch_add(1, std::memory_order_acq_rel);
-
- // Determine which block the element is in
- auto entry = get_block_index_entry_for_index(index);
-
- // Dequeue
- auto block = entry->value.load(std::memory_order_relaxed);
- auto& el = *((*block)[index]);
-
- if (!MOODYCAMEL_NOEXCEPT_ASSIGN(T, T&&, element = std::move(el))) {
-#ifdef MCDBGQ_NOLOCKFREE_IMPLICITPRODBLOCKINDEX
- // Note: Acquiring the mutex with every dequeue instead of only
- // when a block is released is very sub-optimal, but it is, after
- // all, purely debug code.
- debug::DebugLock lock(producer->mutex);
-#endif
- struct Guard {
- Block* block;
- index_t index;
- BlockIndexEntry* entry;
- ConcurrentQueue* parent;
-
- ~Guard()
- {
- (*block)[index]->~T();
- if (block->ConcurrentQueue::Block::template set_empty<
- implicit_context>(index)) {
- entry->value.store(nullptr,
- std::memory_order_relaxed);
- parent->add_block_to_free_list(block);
- }
- }
- } guard = { block, index, entry, this->parent };
-
- element = std::move(el); // NOLINT
- }
- else {
- element = std::move(el); // NOLINT
- el.~T(); // NOLINT
-
- if (block->ConcurrentQueue::Block::template set_empty<
- implicit_context>(index)) {
- {
-#ifdef MCDBGQ_NOLOCKFREE_IMPLICITPRODBLOCKINDEX
- debug::DebugLock lock(mutex);
-#endif
- // Add the block back into the global free pool (and
- // remove from block index)
- entry->value.store(nullptr, std::memory_order_relaxed);
- }
- this->parent->add_block_to_free_list(
- block); // releases the above store
- }
- }
-
- return true;
- }
- else {
- this->dequeueOvercommit.fetch_add(1, std::memory_order_release);
- }
- }
-
- return false;
- }
-
-#ifdef _MSC_VER
-#pragma warning(push)
-#pragma warning(disable : 4706) // assignment within conditional expression
-#endif
- template <AllocationMode allocMode, typename It>
- bool enqueue_bulk(It itemFirst, size_t count)
- {
- // First, we need to make sure we have enough room to enqueue all of the
- // elements; this means pre-allocating blocks and putting them in the block
- // index (but only if all the allocations succeeded).
-
- // Note that the tailBlock we start off with may not be owned by us any more;
- // this happens if it was filled up exactly to the top (setting tailIndex to
- // the first index of the next block which is not yet allocated), then
- // dequeued completely (putting it on the free list) before we enqueue again.
-
- index_t startTailIndex = this->tailIndex.load(std::memory_order_relaxed);
- auto startBlock = this->tailBlock;
- Block* firstAllocatedBlock = nullptr;
- auto endBlock = this->tailBlock;
-
- // Figure out how many blocks we'll need to allocate, and do so
- size_t blockBaseDiff =
- ((startTailIndex + count - 1) & ~static_cast<index_t>(BLOCK_SIZE - 1)) -
- ((startTailIndex - 1) & ~static_cast<index_t>(BLOCK_SIZE - 1));
- index_t currentTailIndex =
- (startTailIndex - 1) & ~static_cast<index_t>(BLOCK_SIZE - 1);
- if (blockBaseDiff > 0) {
-#ifdef MCDBGQ_NOLOCKFREE_IMPLICITPRODBLOCKINDEX
- debug::DebugLock lock(mutex);
-#endif
- do {
- blockBaseDiff -= static_cast<index_t>(BLOCK_SIZE);
- currentTailIndex += static_cast<index_t>(BLOCK_SIZE);
-
- // Find out where we'll be inserting this block in the block index
- BlockIndexEntry* idxEntry =
- nullptr; // initialization here unnecessary but compiler can't
- // always tell
- Block* newBlock;
- bool indexInserted = false;
- auto head = this->headIndex.load(std::memory_order_relaxed);
- assert(!details::circular_less_than<index_t>(currentTailIndex, head));
- bool full =
- !details::circular_less_than<index_t>(
- head, currentTailIndex + BLOCK_SIZE) ||
- (MAX_SUBQUEUE_SIZE != details::const_numeric_max<size_t>::value &&
- (MAX_SUBQUEUE_SIZE == 0 ||
- MAX_SUBQUEUE_SIZE - BLOCK_SIZE < currentTailIndex - head));
-
- if (full ||
- !(indexInserted = insert_block_index_entry<allocMode>(
- idxEntry, currentTailIndex)) ||
- (newBlock =
- this->parent->ConcurrentQueue::template requisition_block<
- allocMode>()) == nullptr) {
- // Index allocation or block allocation failed; revert any other
- // allocations and index insertions done so far for this operation
- if (indexInserted) {
- rewind_block_index_tail();
- idxEntry->value.store(nullptr, std::memory_order_relaxed);
- }
- currentTailIndex =
- (startTailIndex - 1) & ~static_cast<index_t>(BLOCK_SIZE - 1);
- for (auto block = firstAllocatedBlock; block != nullptr;
- block = block->next) {
- currentTailIndex += static_cast<index_t>(BLOCK_SIZE);
- idxEntry = get_block_index_entry_for_index(currentTailIndex);
- idxEntry->value.store(nullptr, std::memory_order_relaxed);
- rewind_block_index_tail();
- }
- this->parent->add_blocks_to_free_list(firstAllocatedBlock);
- this->tailBlock = startBlock;
-
- return false;
- }
-
-#ifdef MCDBGQ_TRACKMEM
- newBlock->owner = this;
-#endif
- newBlock->ConcurrentQueue::Block::template reset_empty<
- implicit_context>();
- newBlock->next = nullptr;
-
- // Insert the new block into the index
- idxEntry->value.store(newBlock, std::memory_order_relaxed);
-
- // Store the chain of blocks so that we can undo if later allocations
- // fail, and so that we can find the blocks when we do the actual
- // enqueueing
- if ((startTailIndex & static_cast<index_t>(BLOCK_SIZE - 1)) != 0 ||
- firstAllocatedBlock != nullptr) {
- assert(this->tailBlock != nullptr);
- this->tailBlock->next = newBlock;
- }
- this->tailBlock = newBlock;
- endBlock = newBlock;
- firstAllocatedBlock =
- firstAllocatedBlock == nullptr ? newBlock : firstAllocatedBlock;
- } while (blockBaseDiff > 0);
- }
-
- // Enqueue, one block at a time
- index_t newTailIndex = startTailIndex + static_cast<index_t>(count);
- currentTailIndex = startTailIndex;
- this->tailBlock = startBlock;
- assert((startTailIndex & static_cast<index_t>(BLOCK_SIZE - 1)) != 0 ||
- firstAllocatedBlock != nullptr || count == 0);
- if ((startTailIndex & static_cast<index_t>(BLOCK_SIZE - 1)) == 0 &&
- firstAllocatedBlock != nullptr) {
- this->tailBlock = firstAllocatedBlock;
- }
- while (true) {
- index_t stopIndex =
- (currentTailIndex & ~static_cast<index_t>(BLOCK_SIZE - 1)) +
- static_cast<index_t>(BLOCK_SIZE);
- if (details::circular_less_than<index_t>(newTailIndex, stopIndex)) {
- stopIndex = newTailIndex;
- }
- MOODYCAMEL_CONSTEXPR_IF(MOODYCAMEL_NOEXCEPT_CTOR(
- T,
- decltype(*itemFirst),
- new (static_cast<T*>(nullptr)) T(details::deref_noexcept(itemFirst))))
- {
- while (currentTailIndex != stopIndex) {
- new ((*this->tailBlock)[currentTailIndex++]) T(*itemFirst++);
- }
- }
- else
- {
- MOODYCAMEL_TRY
- {
- while (currentTailIndex != stopIndex) {
- new ((*this->tailBlock)[currentTailIndex])
- T(details::nomove_if<!MOODYCAMEL_NOEXCEPT_CTOR(
- T,
- decltype(*itemFirst),
- new (static_cast<T*>(nullptr))
- T(details::deref_noexcept(
- itemFirst)))>::eval(*itemFirst));
- ++currentTailIndex;
- ++itemFirst;
- }
- }
- MOODYCAMEL_CATCH(...)
- {
- auto constructedStopIndex = currentTailIndex;
- auto lastBlockEnqueued = this->tailBlock;
-
- if (!details::is_trivially_destructible<T>::value) {
- auto block = startBlock;
- if ((startTailIndex & static_cast<index_t>(BLOCK_SIZE - 1)) ==
- 0) {
- block = firstAllocatedBlock;
- }
- currentTailIndex = startTailIndex;
- while (true) {
- stopIndex = (currentTailIndex &
- ~static_cast<index_t>(BLOCK_SIZE - 1)) +
- static_cast<index_t>(BLOCK_SIZE);
- if (details::circular_less_than<index_t>(
- constructedStopIndex, stopIndex)) {
- stopIndex = constructedStopIndex;
- }
- while (currentTailIndex != stopIndex) {
- (*block)[currentTailIndex++]->~T();
- }
- if (block == lastBlockEnqueued) {
- break;
- }
- block = block->next;
- }
- }
-
- currentTailIndex =
- (startTailIndex - 1) & ~static_cast<index_t>(BLOCK_SIZE - 1);
- for (auto block = firstAllocatedBlock; block != nullptr;
- block = block->next) {
- currentTailIndex += static_cast<index_t>(BLOCK_SIZE);
- auto idxEntry =
- get_block_index_entry_for_index(currentTailIndex);
- idxEntry->value.store(nullptr, std::memory_order_relaxed);
- rewind_block_index_tail();
- }
- this->parent->add_blocks_to_free_list(firstAllocatedBlock);
- this->tailBlock = startBlock;
- MOODYCAMEL_RETHROW;
- }
- }
-
- if (this->tailBlock == endBlock) {
- assert(currentTailIndex == newTailIndex);
- break;
- }
- this->tailBlock = this->tailBlock->next;
- }
- this->tailIndex.store(newTailIndex, std::memory_order_release);
- return true;
- }
-#ifdef _MSC_VER
-#pragma warning(pop)
-#endif
-
- template <typename It>
- size_t dequeue_bulk(It& itemFirst, size_t max)
- {
- auto tail = this->tailIndex.load(std::memory_order_relaxed);
- auto overcommit = this->dequeueOvercommit.load(std::memory_order_relaxed);
- auto desiredCount = static_cast<size_t>(
- tail - (this->dequeueOptimisticCount.load(std::memory_order_relaxed) -
- overcommit));
- if (details::circular_less_than<size_t>(0, desiredCount)) {
- desiredCount = desiredCount < max ? desiredCount : max;
- std::atomic_thread_fence(std::memory_order_acquire);
-
- auto myDequeueCount = this->dequeueOptimisticCount.fetch_add(
- desiredCount, std::memory_order_relaxed);
-
- tail = this->tailIndex.load(std::memory_order_acquire);
- auto actualCount =
- static_cast<size_t>(tail - (myDequeueCount - overcommit));
- if (details::circular_less_than<size_t>(0, actualCount)) {
- actualCount = desiredCount < actualCount ? desiredCount : actualCount;
- if (actualCount < desiredCount) {
- this->dequeueOvercommit.fetch_add(desiredCount - actualCount,
- std::memory_order_release);
- }
-
- // Get the first index. Note that since there's guaranteed to be at
- // least actualCount elements, this will never exceed tail.
- auto firstIndex =
- this->headIndex.fetch_add(actualCount, std::memory_order_acq_rel);
-
- // Iterate the blocks and dequeue
- auto index = firstIndex;
- BlockIndexHeader* localBlockIndex;
- auto indexIndex =
- get_block_index_index_for_index(index, localBlockIndex);
- do {
- auto blockStartIndex = index;
- index_t endIndex =
- (index & ~static_cast<index_t>(BLOCK_SIZE - 1)) +
- static_cast<index_t>(BLOCK_SIZE);
- endIndex =
- details::circular_less_than<index_t>(
- firstIndex + static_cast<index_t>(actualCount), endIndex)
- ? firstIndex + static_cast<index_t>(actualCount)
- : endIndex;
-
- auto entry = localBlockIndex->index[indexIndex];
- auto block = entry->value.load(std::memory_order_relaxed);
- if (MOODYCAMEL_NOEXCEPT_ASSIGN(
- T,
- T&&,
- details::deref_noexcept(itemFirst) =
- std::move((*(*block)[index])))) {
- while (index != endIndex) {
- auto& el = *((*block)[index]);
- *itemFirst++ = std::move(el);
- el.~T();
- ++index;
- }
- }
- else {
- MOODYCAMEL_TRY
- {
- while (index != endIndex) {
- auto& el = *((*block)[index]);
- *itemFirst = std::move(el);
- ++itemFirst;
- el.~T();
- ++index;
- }
- }
- MOODYCAMEL_CATCH(...)
- {
- do {
- entry = localBlockIndex->index[indexIndex];
- block = entry->value.load(std::memory_order_relaxed);
- while (index != endIndex) {
- (*block)[index++]->~T();
- }
-
- if (block->ConcurrentQueue::Block::
- template set_many_empty<implicit_context>(
- blockStartIndex,
- static_cast<size_t>(endIndex -
- blockStartIndex))) {
-#ifdef MCDBGQ_NOLOCKFREE_IMPLICITPRODBLOCKINDEX
- debug::DebugLock lock(mutex);
-#endif
- entry->value.store(nullptr,
- std::memory_order_relaxed);
- this->parent->add_block_to_free_list(block);
- }
- indexIndex = (indexIndex + 1) &
- (localBlockIndex->capacity - 1);
-
- blockStartIndex = index;
- endIndex =
- (index & ~static_cast<index_t>(BLOCK_SIZE - 1)) +
- static_cast<index_t>(BLOCK_SIZE);
- endIndex = details::circular_less_than<index_t>(
- firstIndex +
- static_cast<index_t>(actualCount),
- endIndex)
- ? firstIndex +
- static_cast<index_t>(actualCount)
- : endIndex;
- } while (index != firstIndex + actualCount);
-
- MOODYCAMEL_RETHROW;
- }
- }
- if (block->ConcurrentQueue::Block::template set_many_empty<
- implicit_context>(
- blockStartIndex,
- static_cast<size_t>(endIndex - blockStartIndex))) {
- {
-#ifdef MCDBGQ_NOLOCKFREE_IMPLICITPRODBLOCKINDEX
- debug::DebugLock lock(mutex);
-#endif
- // Note that the set_many_empty above did a release,
- // meaning that anybody who acquires the block we're about
- // to free can use it safely since our writes (and reads!)
- // will have happened-before then.
- entry->value.store(nullptr, std::memory_order_relaxed);
- }
- this->parent->add_block_to_free_list(
- block); // releases the above store
- }
- indexIndex = (indexIndex + 1) & (localBlockIndex->capacity - 1);
- } while (index != firstIndex + actualCount);
-
- return actualCount;
- }
- else {
- this->dequeueOvercommit.fetch_add(desiredCount,
- std::memory_order_release);
- }
- }
-
- return 0;
- }
-
- private:
- // The block size must be > 1, so any number with the low bit set is an invalid
- // block base index
- static const index_t INVALID_BLOCK_BASE = 1;
-
- struct BlockIndexEntry {
- std::atomic<index_t> key;
- std::atomic<Block*> value;
- };
-
- struct BlockIndexHeader {
- size_t capacity;
- std::atomic<size_t> tail;
- BlockIndexEntry* entries;
- BlockIndexEntry** index;
- BlockIndexHeader* prev;
- };
-
- template <AllocationMode allocMode>
- inline bool insert_block_index_entry(BlockIndexEntry*& idxEntry,
- index_t blockStartIndex)
- {
- auto localBlockIndex = blockIndex.load(
- std::memory_order_relaxed); // We're the only writer thread, relaxed is OK
- if (localBlockIndex == nullptr) {
- return false; // this can happen if new_block_index failed in the
- // constructor
- }
- size_t newTail = (localBlockIndex->tail.load(std::memory_order_relaxed) + 1) &
- (localBlockIndex->capacity - 1);
- idxEntry = localBlockIndex->index[newTail];
- if (idxEntry->key.load(std::memory_order_relaxed) == INVALID_BLOCK_BASE ||
- idxEntry->value.load(std::memory_order_relaxed) == nullptr) {
-
- idxEntry->key.store(blockStartIndex, std::memory_order_relaxed);
- localBlockIndex->tail.store(newTail, std::memory_order_release);
- return true;
- }
-
- // No room in the old block index, try to allocate another one!
- MOODYCAMEL_CONSTEXPR_IF(allocMode == CannotAlloc) { return false; }
- else if (!new_block_index()) { return false; }
- localBlockIndex = blockIndex.load(std::memory_order_relaxed);
- newTail = (localBlockIndex->tail.load(std::memory_order_relaxed) + 1) &
- (localBlockIndex->capacity - 1);
- idxEntry = localBlockIndex->index[newTail];
- assert(idxEntry->key.load(std::memory_order_relaxed) == INVALID_BLOCK_BASE);
- idxEntry->key.store(blockStartIndex, std::memory_order_relaxed);
- localBlockIndex->tail.store(newTail, std::memory_order_release);
- return true;
- }
-
- inline void rewind_block_index_tail()
- {
- auto localBlockIndex = blockIndex.load(std::memory_order_relaxed);
- localBlockIndex->tail.store(
- (localBlockIndex->tail.load(std::memory_order_relaxed) - 1) &
- (localBlockIndex->capacity - 1),
- std::memory_order_relaxed);
- }
-
- inline BlockIndexEntry* get_block_index_entry_for_index(index_t index) const
- {
- BlockIndexHeader* localBlockIndex;
- auto idx = get_block_index_index_for_index(index, localBlockIndex);
- return localBlockIndex->index[idx];
- }
-
- inline size_t
- get_block_index_index_for_index(index_t index,
- BlockIndexHeader*& localBlockIndex) const
- {
-#ifdef MCDBGQ_NOLOCKFREE_IMPLICITPRODBLOCKINDEX
- debug::DebugLock lock(mutex);
-#endif
- index &= ~static_cast<index_t>(BLOCK_SIZE - 1);
- localBlockIndex = blockIndex.load(std::memory_order_acquire);
- auto tail = localBlockIndex->tail.load(std::memory_order_acquire);
- auto tailBase =
- localBlockIndex->index[tail]->key.load(std::memory_order_relaxed);
- assert(tailBase != INVALID_BLOCK_BASE);
- // Note: Must use division instead of shift because the index may wrap around,
- // causing a negative offset, whose negativity we want to preserve
- auto offset = static_cast<size_t>(
- static_cast<typename std::make_signed<index_t>::type>(index - tailBase) /
- BLOCK_SIZE);
- size_t idx = (tail + offset) & (localBlockIndex->capacity - 1);
- assert(localBlockIndex->index[idx]->key.load(std::memory_order_relaxed) ==
- index &&
- localBlockIndex->index[idx]->value.load(std::memory_order_relaxed) !=
- nullptr);
- return idx;
- }
-
- bool new_block_index()
- {
- auto prev = blockIndex.load(std::memory_order_relaxed);
- size_t prevCapacity = prev == nullptr ? 0 : prev->capacity;
- auto entryCount = prev == nullptr ? nextBlockIndexCapacity : prevCapacity;
- auto raw = static_cast<char*>((Traits::malloc)(
- sizeof(BlockIndexHeader) + std::alignment_of<BlockIndexEntry>::value - 1 +
- sizeof(BlockIndexEntry) * entryCount +
- std::alignment_of<BlockIndexEntry*>::value - 1 +
- sizeof(BlockIndexEntry*) * nextBlockIndexCapacity));
- if (raw == nullptr) {
- return false;
- }
-
- auto header = new (raw) BlockIndexHeader;
- auto entries = reinterpret_cast<BlockIndexEntry*>(
- details::align_for<BlockIndexEntry>(raw + sizeof(BlockIndexHeader)));
- auto index =
- reinterpret_cast<BlockIndexEntry**>(details::align_for<BlockIndexEntry*>(
- reinterpret_cast<char*>(entries) +
- sizeof(BlockIndexEntry) * entryCount));
- if (prev != nullptr) {
- auto prevTail = prev->tail.load(std::memory_order_relaxed);
- auto prevPos = prevTail;
- size_t i = 0;
- do {
- prevPos = (prevPos + 1) & (prev->capacity - 1);
- index[i++] = prev->index[prevPos];
- } while (prevPos != prevTail);
- assert(i == prevCapacity);
- }
- for (size_t i = 0; i != entryCount; ++i) {
- new (entries + i) BlockIndexEntry;
- entries[i].key.store(INVALID_BLOCK_BASE, std::memory_order_relaxed);
- index[prevCapacity + i] = entries + i;
- }
- header->prev = prev;
- header->entries = entries;
- header->index = index;
- header->capacity = nextBlockIndexCapacity;
- header->tail.store((prevCapacity - 1) & (nextBlockIndexCapacity - 1),
- std::memory_order_relaxed);
-
- blockIndex.store(header, std::memory_order_release);
-
- nextBlockIndexCapacity <<= 1;
-
- return true;
- }
-
- private:
- size_t nextBlockIndexCapacity;
- std::atomic<BlockIndexHeader*> blockIndex;
-
-#ifdef MOODYCAMEL_CPP11_THREAD_LOCAL_SUPPORTED
- public:
- details::ThreadExitListener threadExitListener;
-
- private:
-#endif
-
-#ifdef MOODYCAMEL_QUEUE_INTERNAL_DEBUG
- public:
- ImplicitProducer* nextImplicitProducer;
-
- private:
-#endif
-
-#ifdef MCDBGQ_NOLOCKFREE_IMPLICITPRODBLOCKINDEX
- mutable debug::DebugMutex mutex;
-#endif
-#ifdef MCDBGQ_TRACKMEM
- friend struct MemStats;
-#endif
- };
-
-
- //////////////////////////////////
- // Block pool manipulation
- //////////////////////////////////
-
- void populate_initial_block_list(size_t blockCount)
- {
- initialBlockPoolSize = blockCount;
- if (initialBlockPoolSize == 0) {
- initialBlockPool = nullptr;
- return;
- }
-
- initialBlockPool = create_array<Block>(blockCount);
- if (initialBlockPool == nullptr) {
- initialBlockPoolSize = 0;
- }
- for (size_t i = 0; i < initialBlockPoolSize; ++i) {
- initialBlockPool[i].dynamicallyAllocated = false;
- }
- }
-
- inline Block* try_get_block_from_initial_pool()
- {
- if (initialBlockPoolIndex.load(std::memory_order_relaxed) >=
- initialBlockPoolSize) {
- return nullptr;
- }
-
- auto index = initialBlockPoolIndex.fetch_add(1, std::memory_order_relaxed);
-
- return index < initialBlockPoolSize ? (initialBlockPool + index) : nullptr;
- }
-
- inline void add_block_to_free_list(Block* block)
- {
-#ifdef MCDBGQ_TRACKMEM
- block->owner = nullptr;
-#endif
- freeList.add(block);
- }
-
- inline void add_blocks_to_free_list(Block* block)
- {
- while (block != nullptr) {
- auto next = block->next;
- add_block_to_free_list(block);
- block = next;
- }
- }
-
- inline Block* try_get_block_from_free_list() { return freeList.try_get(); }
-
- // Gets a free block from one of the memory pools, or allocates a new one (if
- // applicable)
- template <AllocationMode canAlloc>
- Block* requisition_block()
- {
- auto block = try_get_block_from_initial_pool();
- if (block != nullptr) {
- return block;
- }
-
- block = try_get_block_from_free_list();
- if (block != nullptr) {
- return block;
- }
-
- MOODYCAMEL_CONSTEXPR_IF(canAlloc == CanAlloc) { return create<Block>(); }
- else { return nullptr; }
- }
-
-
-#ifdef MCDBGQ_TRACKMEM
-public:
- struct MemStats {
- size_t allocatedBlocks;
- size_t usedBlocks;
- size_t freeBlocks;
- size_t ownedBlocksExplicit;
- size_t ownedBlocksImplicit;
- size_t implicitProducers;
- size_t explicitProducers;
- size_t elementsEnqueued;
- size_t blockClassBytes;
- size_t queueClassBytes;
- size_t implicitBlockIndexBytes;
- size_t explicitBlockIndexBytes;
-
- friend class ConcurrentQueue;
-
- private:
- static MemStats getFor(ConcurrentQueue* q)
- {
- MemStats stats = { 0 };
-
- stats.elementsEnqueued = q->size_approx();
-
- auto block = q->freeList.head_unsafe();
- while (block != nullptr) {
- ++stats.allocatedBlocks;
- ++stats.freeBlocks;
- block = block->freeListNext.load(std::memory_order_relaxed);
- }
-
- for (auto ptr = q->producerListTail.load(std::memory_order_acquire);
- ptr != nullptr;
- ptr = ptr->next_prod()) {
- bool implicit = dynamic_cast<ImplicitProducer*>(ptr) != nullptr;
- stats.implicitProducers += implicit ? 1 : 0;
- stats.explicitProducers += implicit ? 0 : 1;
-
- if (implicit) {
- auto prod = static_cast<ImplicitProducer*>(ptr);
- stats.queueClassBytes += sizeof(ImplicitProducer);
- auto head = prod->headIndex.load(std::memory_order_relaxed);
- auto tail = prod->tailIndex.load(std::memory_order_relaxed);
- auto hash = prod->blockIndex.load(std::memory_order_relaxed);
- if (hash != nullptr) {
- for (size_t i = 0; i != hash->capacity; ++i) {
- if (hash->index[i]->key.load(std::memory_order_relaxed) !=
- ImplicitProducer::INVALID_BLOCK_BASE &&
- hash->index[i]->value.load(std::memory_order_relaxed) !=
- nullptr) {
- ++stats.allocatedBlocks;
- ++stats.ownedBlocksImplicit;
- }
- }
- stats.implicitBlockIndexBytes +=
- hash->capacity *
- sizeof(typename ImplicitProducer::BlockIndexEntry);
- for (; hash != nullptr; hash = hash->prev) {
- stats.implicitBlockIndexBytes +=
- sizeof(typename ImplicitProducer::BlockIndexHeader) +
- hash->capacity *
- sizeof(typename ImplicitProducer::BlockIndexEntry*);
- }
- }
- for (; details::circular_less_than<index_t>(head, tail);
- head += BLOCK_SIZE) {
- // auto block = prod->get_block_index_entry_for_index(head);
- ++stats.usedBlocks;
- }
- }
- else {
- auto prod = static_cast<ExplicitProducer*>(ptr);
- stats.queueClassBytes += sizeof(ExplicitProducer);
- auto tailBlock = prod->tailBlock;
- bool wasNonEmpty = false;
- if (tailBlock != nullptr) {
- auto block = tailBlock;
- do {
- ++stats.allocatedBlocks;
- if (!block->ConcurrentQueue::Block::template is_empty<
- explicit_context>() ||
- wasNonEmpty) {
- ++stats.usedBlocks;
- wasNonEmpty = wasNonEmpty || block != tailBlock;
- }
- ++stats.ownedBlocksExplicit;
- block = block->next;
- } while (block != tailBlock);
- }
- auto index = prod->blockIndex.load(std::memory_order_relaxed);
- while (index != nullptr) {
- stats.explicitBlockIndexBytes +=
- sizeof(typename ExplicitProducer::BlockIndexHeader) +
- index->size *
- sizeof(typename ExplicitProducer::BlockIndexEntry);
- index = static_cast<typename ExplicitProducer::BlockIndexHeader*>(
- index->prev);
- }
- }
- }
-
- auto freeOnInitialPool =
- q->initialBlockPoolIndex.load(std::memory_order_relaxed) >=
- q->initialBlockPoolSize
- ? 0
- : q->initialBlockPoolSize -
- q->initialBlockPoolIndex.load(std::memory_order_relaxed);
- stats.allocatedBlocks += freeOnInitialPool;
- stats.freeBlocks += freeOnInitialPool;
-
- stats.blockClassBytes = sizeof(Block) * stats.allocatedBlocks;
- stats.queueClassBytes += sizeof(ConcurrentQueue);
-
- return stats;
- }
- };
-
- // For debugging only. Not thread-safe.
- MemStats getMemStats() { return MemStats::getFor(this); }
-
-private:
- friend struct MemStats;
-#endif
-
-
- //////////////////////////////////
- // Producer list manipulation
- //////////////////////////////////
-
- ProducerBase* recycle_or_create_producer(bool isExplicit)
- {
- bool recycled;
- return recycle_or_create_producer(isExplicit, recycled);
- }
-
- ProducerBase* recycle_or_create_producer(bool isExplicit, bool& recycled)
- {
-#ifdef MCDBGQ_NOLOCKFREE_IMPLICITPRODHASH
- debug::DebugLock lock(implicitProdMutex);
-#endif
- // Try to re-use one first
- for (auto ptr = producerListTail.load(std::memory_order_acquire); ptr != nullptr;
- ptr = ptr->next_prod()) {
- if (ptr->inactive.load(std::memory_order_relaxed) &&
- ptr->isExplicit == isExplicit) {
- bool expected = true;
- if (ptr->inactive.compare_exchange_strong(expected,
- /* desired */ false,
- std::memory_order_acquire,
- std::memory_order_relaxed)) {
- // We caught one! It's been marked as activated, the caller can have
- // it
- recycled = true;
- return ptr;
- }
- }
- }
-
- recycled = false;
- return add_producer(
- isExplicit ? static_cast<ProducerBase*>(create<ExplicitProducer>(this))
- : create<ImplicitProducer>(this));
- }
-
- ProducerBase* add_producer(ProducerBase* producer)
- {
- // Handle failed memory allocation
- if (producer == nullptr) {
- return nullptr;
- }
-
- producerCount.fetch_add(1, std::memory_order_relaxed);
-
- // Add it to the lock-free list
- auto prevTail = producerListTail.load(std::memory_order_relaxed);
- do {
- producer->next = prevTail;
- } while (!producerListTail.compare_exchange_weak(
- prevTail, producer, std::memory_order_release, std::memory_order_relaxed));
-
-#ifdef MOODYCAMEL_QUEUE_INTERNAL_DEBUG
- if (producer->isExplicit) {
- auto prevTailExplicit = explicitProducers.load(std::memory_order_relaxed);
- do {
- static_cast<ExplicitProducer*>(producer)->nextExplicitProducer =
- prevTailExplicit;
- } while (!explicitProducers.compare_exchange_weak(
- prevTailExplicit,
- static_cast<ExplicitProducer*>(producer),
- std::memory_order_release,
- std::memory_order_relaxed));
- }
- else {
- auto prevTailImplicit = implicitProducers.load(std::memory_order_relaxed);
- do {
- static_cast<ImplicitProducer*>(producer)->nextImplicitProducer =
- prevTailImplicit;
- } while (!implicitProducers.compare_exchange_weak(
- prevTailImplicit,
- static_cast<ImplicitProducer*>(producer),
- std::memory_order_release,
- std::memory_order_relaxed));
- }
-#endif
-
- return producer;
- }
-
- void reown_producers()
- {
- // After another instance is moved-into/swapped-with this one, all the
- // producers we stole still think their parents are the other queue.
- // So fix them up!
- for (auto ptr = producerListTail.load(std::memory_order_relaxed); ptr != nullptr;
- ptr = ptr->next_prod()) {
- ptr->parent = this;
- }
- }
-
-
- //////////////////////////////////
- // Implicit producer hash
- //////////////////////////////////
-
- struct ImplicitProducerKVP {
- std::atomic<details::thread_id_t> key;
- ImplicitProducer* value; // No need for atomicity since it's only read by the
- // thread that sets it in the first place
-
- ImplicitProducerKVP() : value(nullptr) {}
-
- ImplicitProducerKVP(ImplicitProducerKVP&& other) MOODYCAMEL_NOEXCEPT
- {
- key.store(other.key.load(std::memory_order_relaxed),
- std::memory_order_relaxed);
- value = other.value;
- }
-
- inline ImplicitProducerKVP&
- operator=(ImplicitProducerKVP&& other) MOODYCAMEL_NOEXCEPT
- {
- swap(other);
- return *this;
- }
-
- inline void swap(ImplicitProducerKVP& other) MOODYCAMEL_NOEXCEPT
- {
- if (this != &other) {
- details::swap_relaxed(key, other.key);
- std::swap(value, other.value);
- }
- }
- };
-
- template <typename XT, typename XTraits>
- friend void moodycamel::swap(
- typename ConcurrentQueue<XT, XTraits>::ImplicitProducerKVP&,
- typename ConcurrentQueue<XT, XTraits>::ImplicitProducerKVP&) MOODYCAMEL_NOEXCEPT;
-
- struct ImplicitProducerHash {
- size_t capacity;
- ImplicitProducerKVP* entries;
- ImplicitProducerHash* prev;
- };
-
- inline void populate_initial_implicit_producer_hash()
- {
- MOODYCAMEL_CONSTEXPR_IF(INITIAL_IMPLICIT_PRODUCER_HASH_SIZE == 0) { return; }
- else
- {
- implicitProducerHashCount.store(0, std::memory_order_relaxed);
- auto hash = &initialImplicitProducerHash;
- hash->capacity = INITIAL_IMPLICIT_PRODUCER_HASH_SIZE;
- hash->entries = &initialImplicitProducerHashEntries[0];
- for (size_t i = 0; i != INITIAL_IMPLICIT_PRODUCER_HASH_SIZE; ++i) {
- initialImplicitProducerHashEntries[i].key.store(
- details::invalid_thread_id, std::memory_order_relaxed);
- }
- hash->prev = nullptr;
- implicitProducerHash.store(hash, std::memory_order_relaxed);
- }
- }
-
- void swap_implicit_producer_hashes(ConcurrentQueue& other)
- {
- MOODYCAMEL_CONSTEXPR_IF(INITIAL_IMPLICIT_PRODUCER_HASH_SIZE == 0) { return; }
- else
- {
- // Swap (assumes our implicit producer hash is initialized)
- initialImplicitProducerHashEntries.swap(
- other.initialImplicitProducerHashEntries);
- initialImplicitProducerHash.entries = &initialImplicitProducerHashEntries[0];
- other.initialImplicitProducerHash.entries =
- &other.initialImplicitProducerHashEntries[0];
-
- details::swap_relaxed(implicitProducerHashCount,
- other.implicitProducerHashCount);
-
- details::swap_relaxed(implicitProducerHash, other.implicitProducerHash);
- if (implicitProducerHash.load(std::memory_order_relaxed) ==
- &other.initialImplicitProducerHash) {
- implicitProducerHash.store(&initialImplicitProducerHash,
- std::memory_order_relaxed);
- }
- else {
- ImplicitProducerHash* hash;
- for (hash = implicitProducerHash.load(std::memory_order_relaxed);
- hash->prev != &other.initialImplicitProducerHash;
- hash = hash->prev) {
- continue;
- }
- hash->prev = &initialImplicitProducerHash;
- }
- if (other.implicitProducerHash.load(std::memory_order_relaxed) ==
- &initialImplicitProducerHash) {
- other.implicitProducerHash.store(&other.initialImplicitProducerHash,
- std::memory_order_relaxed);
- }
- else {
- ImplicitProducerHash* hash;
- for (hash = other.implicitProducerHash.load(std::memory_order_relaxed);
- hash->prev != &initialImplicitProducerHash;
- hash = hash->prev) {
- continue;
- }
- hash->prev = &other.initialImplicitProducerHash;
- }
- }
- }
-
- // Only fails (returns nullptr) if memory allocation fails
- ImplicitProducer* get_or_add_implicit_producer()
- {
- // Note that since the data is essentially thread-local (key is thread ID),
- // there's a reduced need for fences (memory ordering is already consistent
- // for any individual thread), except for the current table itself.
-
- // Start by looking for the thread ID in the current and all previous hash tables.
- // If it's not found, it must not be in there yet, since this same thread would
- // have added it previously to one of the tables that we traversed.
-
- // Code and algorithm adapted from
- // http://preshing.com/20130605/the-worlds-simplest-lock-free-hash-table
-
-#ifdef MCDBGQ_NOLOCKFREE_IMPLICITPRODHASH
- debug::DebugLock lock(implicitProdMutex);
-#endif
-
- auto id = details::thread_id();
- auto hashedId = details::hash_thread_id(id);
-
- auto mainHash = implicitProducerHash.load(std::memory_order_acquire);
- assert(mainHash !=
- nullptr); // silence clang-tidy and MSVC warnings (hash cannot be null)
- for (auto hash = mainHash; hash != nullptr; hash = hash->prev) {
- // Look for the id in this hash
- auto index = hashedId;
- while (true) { // Not an infinite loop because at least one slot is free in
- // the hash table
- index &= hash->capacity - 1;
-
- auto probedKey = hash->entries[index].key.load(std::memory_order_relaxed);
- if (probedKey == id) {
- // Found it! If we had to search several hashes deep, though, we
- // should lazily add it to the current main hash table to avoid the
- // extended search next time. Note there's guaranteed to be room in
- // the current hash table since every subsequent table implicitly
- // reserves space for all previous tables (there's only one
- // implicitProducerHashCount).
- auto value = hash->entries[index].value;
- if (hash != mainHash) {
- index = hashedId;
- while (true) {
- index &= mainHash->capacity - 1;
- probedKey = mainHash->entries[index].key.load(
- std::memory_order_relaxed);
- auto empty = details::invalid_thread_id;
-#ifdef MOODYCAMEL_CPP11_THREAD_LOCAL_SUPPORTED
- auto reusable = details::invalid_thread_id2;
- if ((probedKey == empty &&
- mainHash->entries[index].key.compare_exchange_strong(
- empty,
- id,
- std::memory_order_relaxed,
- std::memory_order_relaxed)) ||
- (probedKey == reusable &&
- mainHash->entries[index].key.compare_exchange_strong(
- reusable,
- id,
- std::memory_order_acquire,
- std::memory_order_acquire))) {
-#else
- if ((probedKey == empty &&
- mainHash->entries[index].key.compare_exchange_strong(
- empty,
- id,
- std::memory_order_relaxed,
- std::memory_order_relaxed))) {
-#endif
- mainHash->entries[index].value = value;
- break;
- }
- ++index;
- }
- }
-
- return value;
- }
- if (probedKey == details::invalid_thread_id) {
- break; // Not in this hash table
- }
- ++index;
- }
- }
-
- // Insert!
- auto newCount =
- 1 + implicitProducerHashCount.fetch_add(1, std::memory_order_relaxed);
- while (true) {
- // NOLINTNEXTLINE(clang-analyzer-core.NullDereference)
- if (newCount >= (mainHash->capacity >> 1) &&
- !implicitProducerHashResizeInProgress.test_and_set(
- std::memory_order_acquire)) {
- // We've acquired the resize lock, try to allocate a bigger hash table.
- // Note the acquire fence synchronizes with the release fence at the end
- // of this block, and hence when we reload implicitProducerHash it must be
- // the most recent version (it only gets changed within this locked
- // block).
- mainHash = implicitProducerHash.load(std::memory_order_acquire);
- if (newCount >= (mainHash->capacity >> 1)) {
- auto newCapacity = mainHash->capacity << 1;
- while (newCount >= (newCapacity >> 1)) {
- newCapacity <<= 1;
- }
- auto raw = static_cast<char*>(
- (Traits::malloc)(sizeof(ImplicitProducerHash) +
- std::alignment_of<ImplicitProducerKVP>::value -
- 1 + sizeof(ImplicitProducerKVP) * newCapacity));
- if (raw == nullptr) {
- // Allocation failed
- implicitProducerHashCount.fetch_sub(1, std::memory_order_relaxed);
- implicitProducerHashResizeInProgress.clear(
- std::memory_order_relaxed);
- return nullptr;
- }
-
- auto newHash = new (raw) ImplicitProducerHash;
- newHash->capacity = static_cast<size_t>(newCapacity);
- newHash->entries = reinterpret_cast<ImplicitProducerKVP*>(
- details::align_for<ImplicitProducerKVP>(
- raw + sizeof(ImplicitProducerHash)));
- for (size_t i = 0; i != newCapacity; ++i) {
- new (newHash->entries + i) ImplicitProducerKVP;
- newHash->entries[i].key.store(details::invalid_thread_id,
- std::memory_order_relaxed);
- }
- newHash->prev = mainHash;
- implicitProducerHash.store(newHash, std::memory_order_release);
- implicitProducerHashResizeInProgress.clear(std::memory_order_release);
- mainHash = newHash;
- }
- else {
- implicitProducerHashResizeInProgress.clear(std::memory_order_release);
- }
- }
-
- // If it's < three-quarters full, add to the old one anyway so that we don't
- // have to wait for the next table to finish being allocated by another thread
- // (and if we just finished allocating above, the condition will always be
- // true)
- if (newCount < (mainHash->capacity >> 1) + (mainHash->capacity >> 2)) {
- bool recycled;
- auto producer = static_cast<ImplicitProducer*>(
- recycle_or_create_producer(false, recycled));
- if (producer == nullptr) {
- implicitProducerHashCount.fetch_sub(1, std::memory_order_relaxed);
- return nullptr;
- }
- if (recycled) {
- implicitProducerHashCount.fetch_sub(1, std::memory_order_relaxed);
- }
-
-#ifdef MOODYCAMEL_CPP11_THREAD_LOCAL_SUPPORTED
- producer->threadExitListener.callback =
- &ConcurrentQueue::implicit_producer_thread_exited_callback;
- producer->threadExitListener.userData = producer;
- details::ThreadExitNotifier::subscribe(&producer->threadExitListener);
-#endif
-
- auto index = hashedId;
- while (true) {
- index &= mainHash->capacity - 1;
- auto probedKey =
- mainHash->entries[index].key.load(std::memory_order_relaxed);
-
- auto empty = details::invalid_thread_id;
-#ifdef MOODYCAMEL_CPP11_THREAD_LOCAL_SUPPORTED
- auto reusable = details::invalid_thread_id2;
- if ((probedKey == empty &&
- mainHash->entries[index].key.compare_exchange_strong(
- empty,
- id,
- std::memory_order_relaxed,
- std::memory_order_relaxed)) ||
- (probedKey == reusable &&
- mainHash->entries[index].key.compare_exchange_strong(
- reusable,
- id,
- std::memory_order_acquire,
- std::memory_order_acquire))) {
-#else
- if ((probedKey == empty &&
- mainHash->entries[index].key.compare_exchange_strong(
- empty,
- id,
- std::memory_order_relaxed,
- std::memory_order_relaxed))) {
-#endif
- mainHash->entries[index].value = producer;
- break;
- }
- ++index;
- }
- return producer;
- }
-
- // Hmm, the old hash is quite full and somebody else is busy allocating a new
- // one. We need to wait for the allocating thread to finish (if it succeeds,
- // we add, if not, we try to allocate ourselves).
- mainHash = implicitProducerHash.load(std::memory_order_acquire);
- }
- } // namespace moodycamel
-
-#ifdef MOODYCAMEL_CPP11_THREAD_LOCAL_SUPPORTED
- void implicit_producer_thread_exited(ImplicitProducer* producer)
- {
- // Remove from thread exit listeners
- details::ThreadExitNotifier::unsubscribe(&producer->threadExitListener);
-
- // Remove from hash
-#ifdef MCDBGQ_NOLOCKFREE_IMPLICITPRODHASH
- debug::DebugLock lock(implicitProdMutex);
-#endif
- auto hash = implicitProducerHash.load(std::memory_order_acquire);
- assert(hash != nullptr); // The thread exit listener is only registered if we were
- // added to a hash in the first place
- auto id = details::thread_id();
- auto hashedId = details::hash_thread_id(id);
- details::thread_id_t probedKey;
-
- // We need to traverse all the hashes just in case other threads aren't on the
- // current one yet and are trying to add an entry thinking there's a free slot
- // (because they reused a producer)
- for (; hash != nullptr; hash = hash->prev) {
- auto index = hashedId;
- do {
- index &= hash->capacity - 1;
- probedKey = hash->entries[index].key.load(std::memory_order_relaxed);
- if (probedKey == id) {
- hash->entries[index].key.store(details::invalid_thread_id2,
- std::memory_order_release);
- break;
- }
- ++index;
- } while (probedKey !=
- details::invalid_thread_id); // Can happen if the hash has changed
- // but we weren't put back in it yet, or
- // if we weren't added to this hash in
- // the first place
- }
-
- // Mark the queue as being recyclable
- producer->inactive.store(true, std::memory_order_release);
- }
-
- static void implicit_producer_thread_exited_callback(void* userData)
- {
- auto producer = static_cast<ImplicitProducer*>(userData);
- auto queue = producer->parent;
- queue->implicit_producer_thread_exited(producer);
- }
-#endif
-
- //////////////////////////////////
- // Utility functions
- //////////////////////////////////
-
- template <typename TAlign>
- static inline void* aligned_malloc(size_t size)
- {
- MOODYCAMEL_CONSTEXPR_IF(std::alignment_of<TAlign>::value <=
- std::alignment_of<details::max_align_t>::value)
- return (Traits::malloc)(size);
- else
- {
- size_t alignment = std::alignment_of<TAlign>::value;
- void* raw = (Traits::malloc)(size + alignment - 1 + sizeof(void*));
- if (!raw)
- return nullptr;
- char* ptr =
- details::align_for<TAlign>(reinterpret_cast<char*>(raw) + sizeof(void*));
- *(reinterpret_cast<void**>(ptr) - 1) = raw;
- return ptr;
- }
- }
-
- template <typename TAlign>
- static inline void aligned_free(void* ptr)
- {
- MOODYCAMEL_CONSTEXPR_IF(std::alignment_of<TAlign>::value <=
- std::alignment_of<details::max_align_t>::value)
- return (Traits::free)(ptr);
- else(Traits::free)(ptr ? *(reinterpret_cast<void**>(ptr) - 1) : nullptr);
- }
-
- template <typename U>
- static inline U* create_array(size_t count)
- {
- assert(count > 0);
- U* p = static_cast<U*>(aligned_malloc<U>(sizeof(U) * count));
- if (p == nullptr)
- return nullptr;
-
- for (size_t i = 0; i != count; ++i)
- new (p + i) U();
- return p;
- }
-
- template <typename U>
- static inline void destroy_array(U* p, size_t count)
- {
- if (p != nullptr) {
- assert(count > 0);
- for (size_t i = count; i != 0;)
- (p + --i)->~U();
- }
- aligned_free<U>(p);
- }
-
- template <typename U>
- static inline U* create()
- {
- void* p = aligned_malloc<U>(sizeof(U));
- return p != nullptr ? new (p) U : nullptr;
- }
-
- template <typename U, typename A1>
- static inline U* create(A1&& a1)
- {
- void* p = aligned_malloc<U>(sizeof(U));
- return p != nullptr ? new (p) U(std::forward<A1>(a1)) : nullptr;
- }
-
- template <typename U>
- static inline void destroy(U* p)
- {
- if (p != nullptr)
- p->~U();
- aligned_free<U>(p);
- }
-
-private:
- std::atomic<ProducerBase*> producerListTail;
- std::atomic<std::uint32_t> producerCount;
-
- std::atomic<size_t> initialBlockPoolIndex;
- Block* initialBlockPool;
- size_t initialBlockPoolSize;
-
-#ifndef MCDBGQ_USEDEBUGFREELIST
- FreeList<Block> freeList;
-#else
- debug::DebugFreeList<Block> freeList;
-#endif
-
- std::atomic<ImplicitProducerHash*> implicitProducerHash;
- std::atomic<size_t> implicitProducerHashCount; // Number of slots logically used
- ImplicitProducerHash initialImplicitProducerHash;
- std::array<ImplicitProducerKVP, INITIAL_IMPLICIT_PRODUCER_HASH_SIZE>
- initialImplicitProducerHashEntries;
- std::atomic_flag implicitProducerHashResizeInProgress;
-
- std::atomic<std::uint32_t> nextExplicitConsumerId;
- std::atomic<std::uint32_t> globalExplicitConsumerOffset;
-
-#ifdef MCDBGQ_NOLOCKFREE_IMPLICITPRODHASH
- debug::DebugMutex implicitProdMutex;
-#endif
-
-#ifdef MOODYCAMEL_QUEUE_INTERNAL_DEBUG
- std::atomic<ExplicitProducer*> explicitProducers;
- std::atomic<ImplicitProducer*> implicitProducers;
-#endif
-};
-
-
-template <typename T, typename Traits>
-ProducerToken::ProducerToken(ConcurrentQueue<T, Traits>& queue)
- : producer(queue.recycle_or_create_producer(true))
-{
- if (producer != nullptr) {
- producer->token = this;
- }
-}
-
-template <typename T, typename Traits>
-ProducerToken::ProducerToken(BlockingConcurrentQueue<T, Traits>& queue)
- : producer(reinterpret_cast<ConcurrentQueue<T, Traits>*>(&queue)
- ->recycle_or_create_producer(true))
-{
- if (producer != nullptr) {
- producer->token = this;
- }
-}
-
-template <typename T, typename Traits>
-ConsumerToken::ConsumerToken(ConcurrentQueue<T, Traits>& queue)
- : itemsConsumedFromCurrent(0), currentProducer(nullptr), desiredProducer(nullptr)
-{
- initialOffset = queue.nextExplicitConsumerId.fetch_add(1, std::memory_order_release);
- lastKnownGlobalOffset = static_cast<std::uint32_t>(-1);
-}
-
-template <typename T, typename Traits>
-ConsumerToken::ConsumerToken(BlockingConcurrentQueue<T, Traits>& queue)
- : itemsConsumedFromCurrent(0), currentProducer(nullptr), desiredProducer(nullptr)
-{
- initialOffset = reinterpret_cast<ConcurrentQueue<T, Traits>*>(&queue)
- ->nextExplicitConsumerId.fetch_add(1, std::memory_order_release);
- lastKnownGlobalOffset = static_cast<std::uint32_t>(-1);
-}
-
-template <typename T, typename Traits>
-inline void swap(ConcurrentQueue<T, Traits>& a,
- ConcurrentQueue<T, Traits>& b) MOODYCAMEL_NOEXCEPT
-{
- a.swap(b);
-}
-
-inline void swap(ProducerToken& a, ProducerToken& b) MOODYCAMEL_NOEXCEPT { a.swap(b); }
-
-inline void swap(ConsumerToken& a, ConsumerToken& b) MOODYCAMEL_NOEXCEPT { a.swap(b); }
-
-template <typename T, typename Traits>
-inline void
-swap(typename ConcurrentQueue<T, Traits>::ImplicitProducerKVP& a,
- typename ConcurrentQueue<T, Traits>::ImplicitProducerKVP& b) MOODYCAMEL_NOEXCEPT
-{
- a.swap(b);
-}
-
-} // namespace moodycamel
-
-#if defined(_MSC_VER) && (!defined(_HAS_CXX17) || !_HAS_CXX17)
-#pragma warning(pop)
-#endif
-
-#if defined(__GNUC__)
-#pragma GCC diagnostic pop
-#endif
diff --git a/gr/include/moodycamel/lightweightsemaphore.h b/gr/include/moodycamel/lightweightsemaphore.h
deleted file mode 100644
index 72658b026..000000000
--- a/gr/include/moodycamel/lightweightsemaphore.h
+++ /dev/null
@@ -1,415 +0,0 @@
-// Provides an efficient implementation of a semaphore (LightweightSemaphore).
-// This is an extension of Jeff Preshing's sempahore implementation (licensed
-// under the terms of its separate zlib license) that has been adapted and
-// extended by Cameron Desrochers.
-
-#pragma once
-
-#include <type_traits> // For std::make_signed<T>
-#include <atomic>
-#include <cstddef> // For std::size_t
-
-#if defined(_WIN32)
-// Avoid including windows.h in a header; we only need a handful of
-// items, so we'll redeclare them here (this is relatively safe since
-// the API generally has to remain stable between Windows versions).
-// I know this is an ugly hack but it still beats polluting the global
-// namespace with thousands of generic names or adding a .cpp for nothing.
-extern "C" {
-struct _SECURITY_ATTRIBUTES;
-__declspec(dllimport) void* __stdcall CreateSemaphoreW(
- _SECURITY_ATTRIBUTES* lpSemaphoreAttributes,
- long lInitialCount,
- long lMaximumCount,
- const wchar_t* lpName);
-__declspec(dllimport) int __stdcall CloseHandle(void* hObject);
-__declspec(dllimport) unsigned long __stdcall WaitForSingleObject(
- void* hHandle, unsigned long dwMilliseconds);
-__declspec(dllimport) int __stdcall ReleaseSemaphore(void* hSemaphore,
- long lReleaseCount,
- long* lpPreviousCount);
-}
-#elif defined(__MACH__)
-#include <mach/mach.h>
-#elif defined(__unix__)
-#include <semaphore.h>
-#endif
-
-namespace moodycamel {
-namespace details {
-
-// Code in the mpmc_sema namespace below is an adaptation of Jeff Preshing's
-// portable + lightweight semaphore implementations, originally from
-// https://github.com/preshing/cpp11-on-multicore/blob/master/common/sema.h
-// LICENSE:
-// Copyright (c) 2015 Jeff Preshing
-//
-// This software is provided 'as-is', without any express or implied
-// warranty. In no event will the authors be held liable for any damages
-// arising from the use of this software.
-//
-// Permission is granted to anyone to use this software for any purpose,
-// including commercial applications, and to alter it and redistribute it
-// freely, subject to the following restrictions:
-//
-// 1. The origin of this software must not be misrepresented; you must not
-// claim that you wrote the original software. If you use this software
-// in a product, an acknowledgement in the product documentation would be
-// appreciated but is not required.
-// 2. Altered source versions must be plainly marked as such, and must not be
-// misrepresented as being the original software.
-// 3. This notice may not be removed or altered from any source distribution.
-#if defined(_WIN32)
-class Semaphore
-{
-private:
- void* m_hSema;
-
- Semaphore(const Semaphore& other) MOODYCAMEL_DELETE_FUNCTION;
- Semaphore& operator=(const Semaphore& other) MOODYCAMEL_DELETE_FUNCTION;
-
-public:
- Semaphore(int initialCount = 0)
- {
- assert(initialCount >= 0);
- const long maxLong = 0x7fffffff;
- m_hSema = CreateSemaphoreW(nullptr, initialCount, maxLong, nullptr);
- assert(m_hSema);
- }
-
- ~Semaphore() { CloseHandle(m_hSema); }
-
- bool wait()
- {
- const unsigned long infinite = 0xffffffff;
- return WaitForSingleObject(m_hSema, infinite) == 0;
- }
-
- bool try_wait() { return WaitForSingleObject(m_hSema, 0) == 0; }
-
- bool timed_wait(std::uint64_t usecs)
- {
- return WaitForSingleObject(m_hSema, (unsigned long)(usecs / 1000)) == 0;
- }
-
- void signal(int count = 1)
- {
- while (!ReleaseSemaphore(m_hSema, count, nullptr))
- ;
- }
-};
-#elif defined(__MACH__)
-//---------------------------------------------------------
-// Semaphore (Apple iOS and OSX)
-// Can't use POSIX semaphores due to
-// http://lists.apple.com/archives/darwin-kernel/2009/Apr/msg00010.html
-//---------------------------------------------------------
-class Semaphore
-{
-private:
- semaphore_t m_sema;
-
- Semaphore(const Semaphore& other) MOODYCAMEL_DELETE_FUNCTION;
- Semaphore& operator=(const Semaphore& other) MOODYCAMEL_DELETE_FUNCTION;
-
-public:
- Semaphore(int initialCount = 0)
- {
- assert(initialCount >= 0);
- kern_return_t rc =
- semaphore_create(mach_task_self(), &m_sema, SYNC_POLICY_FIFO, initialCount);
- assert(rc == KERN_SUCCESS);
- (void)rc;
- }
-
- ~Semaphore() { semaphore_destroy(mach_task_self(), m_sema); }
-
- bool wait() { return semaphore_wait(m_sema) == KERN_SUCCESS; }
-
- bool try_wait() { return timed_wait(0); }
-
- bool timed_wait(std::uint64_t timeout_usecs)
- {
- mach_timespec_t ts;
- ts.tv_sec = static_cast<unsigned int>(timeout_usecs / 1000000);
- ts.tv_nsec = static_cast<int>((timeout_usecs % 1000000) * 1000);
-
- // added in OSX 10.10:
- // https://developer.apple.com/library/prerelease/mac/documentation/General/Reference/APIDiffsMacOSX10_10SeedDiff/modules/Darwin.html
- kern_return_t rc = semaphore_timedwait(m_sema, ts);
- return rc == KERN_SUCCESS;
- }
-
- void signal()
- {
- while (semaphore_signal(m_sema) != KERN_SUCCESS)
- ;
- }
-
- void signal(int count)
- {
- while (count-- > 0) {
- while (semaphore_signal(m_sema) != KERN_SUCCESS)
- ;
- }
- }
-};
-#elif defined(__unix__)
-//---------------------------------------------------------
-// Semaphore (POSIX, Linux)
-//---------------------------------------------------------
-class Semaphore
-{
-private:
- sem_t m_sema;
-
- Semaphore(const Semaphore& other) MOODYCAMEL_DELETE_FUNCTION;
- Semaphore& operator=(const Semaphore& other) MOODYCAMEL_DELETE_FUNCTION;
-
-public:
- Semaphore(int initialCount = 0)
- {
- assert(initialCount >= 0);
- int rc = sem_init(&m_sema, 0, static_cast<unsigned int>(initialCount));
- assert(rc == 0);
- (void)rc;
- }
-
- ~Semaphore() { sem_destroy(&m_sema); }
-
- bool wait()
- {
- // http://stackoverflow.com/questions/2013181/gdb-causes-sem-wait-to-fail-with-eintr-error
- int rc;
- do {
- rc = sem_wait(&m_sema);
- } while (rc == -1 && errno == EINTR);
- return rc == 0;
- }
-
- bool try_wait()
- {
- int rc;
- do {
- rc = sem_trywait(&m_sema);
- } while (rc == -1 && errno == EINTR);
- return rc == 0;
- }
-
- bool timed_wait(std::uint64_t usecs)
- {
- struct timespec ts;
- const int usecs_in_1_sec = 1000000;
- const int nsecs_in_1_sec = 1000000000;
- clock_gettime(CLOCK_REALTIME, &ts);
- ts.tv_sec += (time_t)(usecs / usecs_in_1_sec);
- ts.tv_nsec += (long)(usecs % usecs_in_1_sec) * 1000;
- // sem_timedwait bombs if you have more than 1e9 in tv_nsec
- // so we have to clean things up before passing it in
- if (ts.tv_nsec >= nsecs_in_1_sec) {
- ts.tv_nsec -= nsecs_in_1_sec;
- ++ts.tv_sec;
- }
-
- int rc;
- do {
- rc = sem_timedwait(&m_sema, &ts);
- } while (rc == -1 && errno == EINTR);
- return rc == 0;
- }
-
- void signal()
- {
- while (sem_post(&m_sema) == -1)
- ;
- }
-
- void signal(int count)
- {
- while (count-- > 0) {
- while (sem_post(&m_sema) == -1)
- ;
- }
- }
-};
-#else
-#error Unsupported platform! (No semaphore wrapper available)
-#endif
-
-} // end namespace details
-
-
-//---------------------------------------------------------
-// LightweightSemaphore
-//---------------------------------------------------------
-class LightweightSemaphore
-{
-public:
- typedef std::make_signed<std::size_t>::type ssize_t;
-
-private:
- std::atomic<ssize_t> m_count;
- details::Semaphore m_sema;
- int m_maxSpins;
-
- bool waitWithPartialSpinning(std::int64_t timeout_usecs = -1)
- {
- ssize_t oldCount;
- int spin = m_maxSpins;
- while (--spin >= 0) {
- oldCount = m_count.load(std::memory_order_relaxed);
- if ((oldCount > 0) &&
- m_count.compare_exchange_strong(oldCount,
- oldCount - 1,
- std::memory_order_acquire,
- std::memory_order_relaxed))
- return true;
- std::atomic_signal_fence(
- std::memory_order_acquire); // Prevent the compiler from collapsing the
- // loop.
- }
- oldCount = m_count.fetch_sub(1, std::memory_order_acquire);
- if (oldCount > 0)
- return true;
- if (timeout_usecs < 0) {
- if (m_sema.wait())
- return true;
- }
- if (timeout_usecs > 0 && m_sema.timed_wait((std::uint64_t)timeout_usecs))
- return true;
- // At this point, we've timed out waiting for the semaphore, but the
- // count is still decremented indicating we may still be waiting on
- // it. So we have to re-adjust the count, but only if the semaphore
- // wasn't signaled enough times for us too since then. If it was, we
- // need to release the semaphore too.
- while (true) {
- oldCount = m_count.load(std::memory_order_acquire);
- if (oldCount >= 0 && m_sema.try_wait())
- return true;
- if (oldCount < 0 &&
- m_count.compare_exchange_strong(oldCount,
- oldCount + 1,
- std::memory_order_relaxed,
- std::memory_order_relaxed))
- return false;
- }
- }
-
- ssize_t waitManyWithPartialSpinning(ssize_t max, std::int64_t timeout_usecs = -1)
- {
- assert(max > 0);
- ssize_t oldCount;
- int spin = m_maxSpins;
- while (--spin >= 0) {
- oldCount = m_count.load(std::memory_order_relaxed);
- if (oldCount > 0) {
- ssize_t newCount = oldCount > max ? oldCount - max : 0;
- if (m_count.compare_exchange_strong(oldCount,
- newCount,
- std::memory_order_acquire,
- std::memory_order_relaxed))
- return oldCount - newCount;
- }
- std::atomic_signal_fence(std::memory_order_acquire);
- }
- oldCount = m_count.fetch_sub(1, std::memory_order_acquire);
- if (oldCount <= 0) {
- if ((timeout_usecs == 0) || (timeout_usecs < 0 && !m_sema.wait()) ||
- (timeout_usecs > 0 && !m_sema.timed_wait((std::uint64_t)timeout_usecs))) {
- while (true) {
- oldCount = m_count.load(std::memory_order_acquire);
- if (oldCount >= 0 && m_sema.try_wait())
- break;
- if (oldCount < 0 &&
- m_count.compare_exchange_strong(oldCount,
- oldCount + 1,
- std::memory_order_relaxed,
- std::memory_order_relaxed))
- return 0;
- }
- }
- }
- if (max > 1)
- return 1 + tryWaitMany(max - 1);
- return 1;
- }
-
-public:
- LightweightSemaphore(ssize_t initialCount = 0, int maxSpins = 10000)
- : m_count(initialCount), m_maxSpins(maxSpins)
- {
- assert(initialCount >= 0);
- assert(maxSpins >= 0);
- }
-
- bool tryWait()
- {
- ssize_t oldCount = m_count.load(std::memory_order_relaxed);
- while (oldCount > 0) {
- if (m_count.compare_exchange_weak(oldCount,
- oldCount - 1,
- std::memory_order_acquire,
- std::memory_order_relaxed))
- return true;
- }
- return false;
- }
-
- bool wait() { return tryWait() || waitWithPartialSpinning(); }
-
- bool wait(std::int64_t timeout_usecs)
- {
- return tryWait() || waitWithPartialSpinning(timeout_usecs);
- }
-
- // Acquires between 0 and (greedily) max, inclusive
- ssize_t tryWaitMany(ssize_t max)
- {
- assert(max >= 0);
- ssize_t oldCount = m_count.load(std::memory_order_relaxed);
- while (oldCount > 0) {
- ssize_t newCount = oldCount > max ? oldCount - max : 0;
- if (m_count.compare_exchange_weak(oldCount,
- newCount,
- std::memory_order_acquire,
- std::memory_order_relaxed))
- return oldCount - newCount;
- }
- return 0;
- }
-
- // Acquires at least one, and (greedily) at most max
- ssize_t waitMany(ssize_t max, std::int64_t timeout_usecs)
- {
- assert(max >= 0);
- ssize_t result = tryWaitMany(max);
- if (result == 0 && max > 0)
- result = waitManyWithPartialSpinning(max, timeout_usecs);
- return result;
- }
-
- ssize_t waitMany(ssize_t max)
- {
- ssize_t result = waitMany(max, -1);
- assert(result > 0);
- return result;
- }
-
- void signal(ssize_t count = 1)
- {
- assert(count >= 0);
- ssize_t oldCount = m_count.fetch_add(count, std::memory_order_release);
- ssize_t toRelease = -oldCount < count ? -oldCount : count;
- if (toRelease > 0) {
- m_sema.signal((int)toRelease);
- }
- }
-
- std::size_t availableApprox() const
- {
- ssize_t count = m_count.load(std::memory_order_relaxed);
- return count > 0 ? static_cast<std::size_t>(count) : 0;
- }
-};
-
-} // end namespace moodycamel
diff --git a/gr/include/moodycamel/meson.build b/gr/include/moodycamel/meson.build
deleted file mode 100644
index 12a34e6ad..000000000
--- a/gr/include/moodycamel/meson.build
+++ /dev/null
@@ -1,5 +0,0 @@
-install_headers([
- 'blockingconcurrentqueue.h',
- 'concurrentqueue.h',
- 'lightweightsemaphore.h'
-], subdir : 'moodycamel')
diff --git a/gr/lib/buffer_cpu_host.cc b/gr/lib/buffer_cpu_host.cc
deleted file mode 100644
index 0623d166f..000000000
--- a/gr/lib/buffer_cpu_host.cc
+++ /dev/null
@@ -1,96 +0,0 @@
-#include <string.h>
-#include <algorithm>
-#include <cstdint>
-#include <memory>
-#include <mutex>
-#include <vector>
-
-#include <gnuradio/buffer_cpu_host.h>
-
-namespace gr {
-buffer_cpu_host::buffer_cpu_host(size_t num_items,
- size_t item_size,
- buffer_cpu_host_type type,
- std::shared_ptr<buffer_properties> buf_properties)
- : gr::buffer_sm(num_items, item_size, buf_properties), _transfer_type(type)
-{
- _host_buffer.resize(_buf_size);
- _device_buffer.resize(_buf_size);
-
- set_type("buffer_cpu_host_" + std::to_string((int)_transfer_type));
-}
-
-buffer_uptr buffer_cpu_host::make(size_t num_items,
- size_t item_size,
- std::shared_ptr<buffer_properties> buffer_properties)
-{
- auto cbp = std::static_pointer_cast<buffer_cpu_host_properties>(buffer_properties);
- if (cbp != nullptr) {
- return buffer_uptr(new buffer_cpu_host(
- num_items, item_size, cbp->buffer_type(), buffer_properties));
- }
- else {
- throw std::runtime_error(
- "Failed to cast buffer properties to buffer_cpu_host_properties");
- }
-}
-
-void* buffer_cpu_host::read_ptr(size_t index)
-{
- if (_transfer_type == buffer_cpu_host_type::D2H ||
- _transfer_type == buffer_cpu_host_type::H2H) {
- return (void*)&_host_buffer[index];
- }
- else {
- return (void*)&_device_buffer[index];
- }
-}
-void* buffer_cpu_host::write_ptr()
-{
- if (_transfer_type == buffer_cpu_host_type::H2D ||
- _transfer_type == buffer_cpu_host_type::H2H) {
- return (void*)&_host_buffer[_write_index];
- }
- else {
- return (void*)&_device_buffer[_write_index];
- }
-}
-
-void buffer_cpu_host::post_write(int num_items)
-{
- std::lock_guard<std::mutex> guard(_buf_mutex);
-
- size_t bytes_written = num_items * _item_size;
- size_t wi1 = _write_index;
-
- // num_items were written to the buffer
-
- if (_transfer_type == buffer_cpu_host_type::H2D) {
- memcpy(&_device_buffer[wi1], &_host_buffer[wi1], bytes_written);
- }
- else if (_transfer_type == buffer_cpu_host_type::D2H) {
- memcpy(&_host_buffer[wi1], &_device_buffer[wi1], bytes_written);
- }
-
- // advance the write pointer
- _write_index += bytes_written;
- if (_write_index == _buf_size) {
- _write_index = 0;
- }
- if (_write_index > _buf_size) {
- throw std::runtime_error("buffer_sm: Wrote too far into buffer");
- }
- _total_written += num_items;
-}
-
-buffer_reader_uptr
-buffer_cpu_host::add_reader(std::shared_ptr<buffer_properties> buf_props, size_t itemsize)
-{
- auto r =
- std::make_unique<buffer_cpu_host_reader>(this, buf_props, itemsize, _write_index);
- _readers.push_back(r.get());
- return r;
-}
-
-
-} // namespace gr
diff --git a/gr/lib/buffer_cuda.cc b/gr/lib/buffer_cuda.cc
deleted file mode 100644
index 73a1e61f4..000000000
--- a/gr/lib/buffer_cuda.cc
+++ /dev/null
@@ -1,162 +0,0 @@
-#include <cuda.h>
-#include <cuda_runtime.h>
-#include <string.h>
-#include <algorithm>
-#include <cstdint>
-#include <memory>
-#include <mutex>
-#include <vector>
-
-#include <gnuradio/buffer_cuda.h>
-
-
-namespace gr {
-buffer_cuda::buffer_cuda(size_t num_items,
- size_t item_size,
- buffer_cuda_type type,
- std::shared_ptr<buffer_properties> buf_properties)
- : gr::buffer(num_items, item_size, buf_properties), _type(type)
-{
- // _host_buffer.resize(_buf_size * 2); // double circular buffer
- cudaMallocHost(
- &_host_buffer,
- _buf_size *
- 2); // double circular buffer - should do something more intelligent here
- cudaMalloc(
- &_device_buffer,
- _buf_size *
- 2); // double circular buffer - should do something more intelligent here
- set_type("buffer_cuda_" + std::to_string((int)_type));
-
- cudaStreamCreate(&stream);
-}
-buffer_cuda::~buffer_cuda()
-{
- cudaFree(_device_buffer);
- cudaFree(_host_buffer);
-}
-
-buffer_uptr buffer_cuda::make(size_t num_items,
- size_t item_size,
- std::shared_ptr<buffer_properties> buffer_properties)
-{
- auto cbp = std::static_pointer_cast<buffer_cuda_properties>(buffer_properties);
- if (cbp != nullptr) {
- return buffer_uptr(
- new buffer_cuda(num_items, item_size, cbp->buffer_type(), buffer_properties));
- }
- else {
- throw std::runtime_error(
- "Failed to cast buffer properties to buffer_cuda_properties");
- }
-}
-
-void* buffer_cuda::read_ptr(size_t index)
-{
- if (_type == buffer_cuda_type::D2H) {
- return (void*)&_host_buffer[index];
- }
- else {
- return (void*)&_device_buffer[index];
- }
-}
-void* buffer_cuda::write_ptr()
-{
- if (_type == buffer_cuda_type::H2D) {
- return (void*)&_host_buffer[_write_index];
- }
- else {
- return (void*)&_device_buffer[_write_index];
- }
-}
-
-void buffer_cuda_reader::post_read(int num_items)
-{
- std::lock_guard<std::mutex> guard(_rdr_mutex);
- // advance the read pointer
- _read_index += num_items * _itemsize;
- if (_read_index >= _buffer->buf_size()) {
- _read_index -= _buffer->buf_size();
- }
- _total_read += num_items;
-}
-void buffer_cuda::post_write(int num_items)
-{
- std::lock_guard<std::mutex> guard(_buf_mutex);
-
- size_t bytes_written = num_items * _item_size;
- size_t wi1 = _write_index;
- size_t wi2 = _write_index + _buf_size;
- // num_items were written to the buffer
- // copy the data to the second half of the buffer
-
- size_t num_bytes_1 = std::min(_buf_size - wi1, bytes_written);
- size_t num_bytes_2 = bytes_written - num_bytes_1;
-
- if (_type == buffer_cuda_type::H2D) {
- cudaMemcpyAsync(&_device_buffer[wi1],
- &_host_buffer[wi1],
- bytes_written,
- cudaMemcpyHostToDevice,
- stream);
-
- // memcpy(&_host_buffer[wi2], &_host_buffer[wi1], num_bytes_1);
- cudaMemcpyAsync(&_device_buffer[wi2],
- &_device_buffer[wi1],
- num_bytes_1,
- cudaMemcpyDeviceToDevice,
- stream);
- if (num_bytes_2) {
- // memcpy(&_host_buffer[0], &_host_buffer[_buf_size], num_bytes_2);
- cudaMemcpyAsync(&_device_buffer[0],
- &_device_buffer[_buf_size],
- num_bytes_2,
- cudaMemcpyDeviceToDevice,
- stream);
- }
- }
- else if (_type == buffer_cuda_type::D2H) {
- cudaMemcpyAsync(&_host_buffer[wi1],
- &_device_buffer[wi1],
- bytes_written,
- cudaMemcpyDeviceToHost,
- stream);
-
- memcpy(&_host_buffer[wi2], &_host_buffer[wi1], num_bytes_1);
-
- if (num_bytes_2) {
- memcpy(&_host_buffer[0], &_host_buffer[_buf_size], num_bytes_2);
- }
- }
- else // D2D
- {
- cudaMemcpyAsync(&_device_buffer[wi2],
- &_device_buffer[wi1],
- num_bytes_1,
- cudaMemcpyDeviceToDevice);
- if (num_bytes_2)
- cudaMemcpyAsync(&_device_buffer[0],
- &_device_buffer[_buf_size],
- num_bytes_2,
- cudaMemcpyDeviceToDevice,
- stream);
- }
- // advance the write pointer
- _write_index += bytes_written;
- if (_write_index >= _buf_size) {
- _write_index -= _buf_size;
- }
- _total_written += num_items;
- cudaStreamSynchronize(stream);
-}
-
-buffer_reader_uptr buffer_cuda::add_reader(std::shared_ptr<buffer_properties> buf_props,
- size_t itemsize)
-{
- auto r =
- std::make_unique<buffer_cuda_reader>(this, buf_props, itemsize, _write_index);
- _readers.push_back(r.get());
- return r;
-}
-
-} // namespace gr
diff --git a/gr/lib/buffer_cuda_pinned.cc b/gr/lib/buffer_cuda_pinned.cc
deleted file mode 100644
index 3a1de05de..000000000
--- a/gr/lib/buffer_cuda_pinned.cc
+++ /dev/null
@@ -1,80 +0,0 @@
-#include <string.h>
-#include <algorithm>
-#include <cstdint>
-#include <memory>
-#include <mutex>
-#include <vector>
-
-#include <cuda.h>
-#include <cuda_runtime.h>
-
-#include <gnuradio/buffer_cuda_pinned.h>
-
-namespace gr {
-buffer_cuda_pinned::buffer_cuda_pinned(size_t num_items,
- size_t item_size,
- std::shared_ptr<buffer_properties> buf_properties)
- : buffer(num_items, item_size, buf_properties)
-{
- if (!cudaHostAlloc((void**)&_pinned_buffer, _buf_size * 2, 0) == cudaSuccess) {
- throw std::runtime_error("Failed to allocate CUDA pinned memory");
- }
-}
-buffer_cuda_pinned::~buffer_cuda_pinned() { cudaFree(_pinned_buffer); }
-
-buffer_uptr buffer_cuda_pinned::make(size_t num_items,
- size_t item_size,
- std::shared_ptr<buffer_properties> buffer_properties)
-{
- return buffer_uptr(new buffer_cuda_pinned(num_items, item_size, buffer_properties));
-}
-
-void* buffer_cuda_pinned::read_ptr(size_t index) { return (void*)&_pinned_buffer[index]; }
-void* buffer_cuda_pinned::write_ptr() { return (void*)&_pinned_buffer[_write_index]; }
-
-void buffer_cuda_pinned_reader::post_read(int num_items)
-{
- std::lock_guard<std::mutex> guard(_rdr_mutex);
- // advance the read pointer
- _read_index += num_items * _itemsize;
- if (_read_index >= _buffer->buf_size()) {
- _read_index -= _buffer->buf_size();
- }
- _total_read += num_items;
-}
-
-void buffer_cuda_pinned::post_write(int num_items)
-{
- std::lock_guard<std::mutex> guard(_buf_mutex);
-
- size_t bytes_written = num_items * _item_size;
- size_t wi1 = _write_index;
- size_t wi2 = _write_index + _buf_size;
- // num_items were written to the buffer
- // copy the data to the second half of the buffer
-
- size_t num_bytes_1 = std::min(_buf_size - wi1, bytes_written);
- size_t num_bytes_2 = bytes_written - num_bytes_1;
-
- memcpy(&_pinned_buffer[wi2], &_pinned_buffer[wi1], num_bytes_1);
- if (num_bytes_2)
- memcpy(&_pinned_buffer[0], &_pinned_buffer[_buf_size], num_bytes_2);
-
- // advance the write pointer
- _write_index += bytes_written;
- if (_write_index >= _buf_size) {
- _write_index -= _buf_size;
- }
-}
-
-buffer_reader_uptr
-buffer_cuda_pinned::add_reader(std::shared_ptr<buffer_properties> buf_props,
- size_t itemsize)
-{
- auto r = std::make_unique<buffer_cuda_pinned_reader>(
- this, buf_props, itemsize, _write_index);
- _readers.push_back(r.get());
- return r;
-}
-
-} // namespace gr
diff --git a/gr/lib/buffer_cuda_sm.cc b/gr/lib/buffer_cuda_sm.cc
deleted file mode 100644
index 7e8bc88d9..000000000
--- a/gr/lib/buffer_cuda_sm.cc
+++ /dev/null
@@ -1,164 +0,0 @@
-#include <cuda.h>
-#include <cuda_runtime.h>
-#include <string.h>
-#include <algorithm>
-#include <cstdint>
-#include <memory>
-#include <mutex>
-#include <vector>
-
-#include <gnuradio/buffer_cuda_sm.h>
-
-namespace gr {
-buffer_cuda_sm::buffer_cuda_sm(size_t num_items,
- size_t item_size,
- buffer_cuda_sm_type type,
- std::shared_ptr<buffer_properties> buf_properties)
- : gr::buffer_sm(num_items, item_size, buf_properties), _type(type)
-{
- // _host_buffer.resize(_buf_size * 2); // double circular buffer
- cudaMallocHost(&_host_buffer, _buf_size);
- cudaMalloc(&_device_buffer, _buf_size);
- set_type("buffer_cuda_sm_" + std::to_string((int)_type));
-
- cudaStreamCreate(&stream);
-}
-buffer_cuda_sm::~buffer_cuda_sm()
-{
- cudaFree(_device_buffer);
- cudaFree(_host_buffer);
-}
-
-buffer_uptr buffer_cuda_sm::make(size_t num_items,
- size_t item_size,
- std::shared_ptr<buffer_properties> buffer_properties)
-{
- auto cbp = std::static_pointer_cast<buffer_cuda_sm_properties>(buffer_properties);
- if (cbp != nullptr) {
- return buffer_uptr(new buffer_cuda_sm(
- num_items, item_size, cbp->buffer_type(), buffer_properties));
- }
- else {
- throw std::runtime_error(
- "Failed to cast buffer properties to buffer_cuda_sm_properties");
- }
-}
-
-void* buffer_cuda_sm::read_ptr(size_t index)
-{
- if (_type == buffer_cuda_sm_type::D2H) {
- return (void*)&_host_buffer[index];
- }
- else {
- return (void*)&_device_buffer[index];
- }
-}
-void* buffer_cuda_sm::write_ptr()
-{
- if (_type == buffer_cuda_sm_type::H2D) {
- return (void*)&_host_buffer[_write_index];
- }
- else {
- return (void*)&_device_buffer[_write_index];
- }
-}
-
-void buffer_cuda_sm::post_write(int num_items)
-{
- std::lock_guard<std::mutex> guard(_buf_mutex);
-
- size_t bytes_written = num_items * _item_size;
- size_t wi1 = _write_index;
-
- // num_items were written to the buffer
-
- if (_type == buffer_cuda_sm_type::H2D) {
- cudaMemcpyAsync(&_device_buffer[wi1],
- &_host_buffer[wi1],
- bytes_written,
- cudaMemcpyHostToDevice,
- stream);
- }
- else if (_type == buffer_cuda_sm_type::D2H) {
- cudaMemcpyAsync(&_host_buffer[wi1],
- &_device_buffer[wi1],
- bytes_written,
- cudaMemcpyDeviceToHost,
- stream);
- }
-
- // advance the write pointer
- _write_index += bytes_written;
- if (_write_index == _buf_size) {
- _write_index = 0;
- }
- if (_write_index > _buf_size) {
- throw std::runtime_error("buffer_sm: Wrote too far into buffer");
- }
- _total_written += num_items;
- cudaStreamSynchronize(stream);
-}
-
-buffer_reader_uptr
-buffer_cuda_sm::add_reader(std::shared_ptr<buffer_properties> buf_props, size_t itemsize)
-{
- auto r =
- std::make_unique<buffer_cuda_sm_reader>(this, buf_props, itemsize, _write_index);
- _readers.push_back(r.get());
- return r;
-}
-
-void* buffer_cuda_sm::cuda_memcpy(void* dest, const void* src, std::size_t count)
-{
- cudaError_t rc = cudaSuccess;
- rc = cudaMemcpy(dest, src, count, cudaMemcpyDeviceToDevice);
- if (rc) {
- std::ostringstream msg;
- msg << "Error performing cudaMemcpy: " << cudaGetErrorName(rc) << " -- "
- << cudaGetErrorString(rc);
- throw std::runtime_error(msg.str());
- }
-
- return dest;
-}
-
-void* buffer_cuda_sm::cuda_memmove(void* dest, const void* src, std::size_t count)
-{
- // Would a kernel that checks for overlap and then copies front-to-back or
- // back-to-front be faster than using cudaMemcpy with a temp buffer?
-
- // Allocate temp buffer
- void* tempBuffer = nullptr;
- cudaError_t rc = cudaSuccess;
- rc = cudaMalloc((void**)&tempBuffer, count);
- if (rc) {
- std::ostringstream msg;
- msg << "Error allocating device buffer: " << cudaGetErrorName(rc) << " -- "
- << cudaGetErrorString(rc);
- throw std::runtime_error(msg.str());
- }
-
- // First copy data from source to temp buffer
- rc = cudaMemcpy(tempBuffer, src, count, cudaMemcpyDeviceToDevice);
- if (rc) {
- std::ostringstream msg;
- msg << "Error performing cudaMemcpy: " << cudaGetErrorName(rc) << " -- "
- << cudaGetErrorString(rc);
- throw std::runtime_error(msg.str());
- }
-
- // Then copy data from temp buffer to destination to avoid overlap
- rc = cudaMemcpy(dest, tempBuffer, count, cudaMemcpyDeviceToDevice);
- if (rc) {
- std::ostringstream msg;
- msg << "Error performing cudaMemcpy: " << cudaGetErrorName(rc) << " -- "
- << cudaGetErrorString(rc);
- throw std::runtime_error(msg.str());
- }
-
- cudaFree(tempBuffer);
-
- return dest;
-}
-
-} // namespace gr
diff --git a/gr/lib/buffer_net_zmq.cc b/gr/lib/buffer_net_zmq.cc
deleted file mode 100644
index 0236e028a..000000000
--- a/gr/lib/buffer_net_zmq.cc
+++ /dev/null
@@ -1,175 +0,0 @@
-#include <gnuradio/buffer_cpu_vmcirc.h>
-#include <gnuradio/buffer_net_zmq.h>
-#include <nlohmann/json.hpp>
-#include <chrono>
-#include <thread>
-namespace gr {
-
-
-std::shared_ptr<buffer_properties>
-buffer_net_zmq_properties::make_from_params(const std::string& json_str)
-{
- auto json_obj = nlohmann::json::parse(json_str);
- return make(json_obj["ipaddr"], json_obj["port"]);
-}
-
-buffer_uptr buffer_net_zmq::make(size_t num_items,
- size_t item_size,
- std::shared_ptr<buffer_properties> buffer_properties)
-{
-
- auto zbp = std::static_pointer_cast<buffer_net_zmq_properties>(buffer_properties);
- if (zbp != nullptr) {
- return buffer_uptr(
- new buffer_net_zmq(num_items, item_size, buffer_properties, zbp->port()));
- }
- else {
- throw std::runtime_error(
- "Failed to cast buffer properties to buffer_net_zmq_properties");
- }
-}
-
-buffer_net_zmq::buffer_net_zmq(size_t num_items,
- size_t item_size,
- std::shared_ptr<buffer_properties> buf_properties,
- int port)
- : buffer(num_items, item_size, buf_properties),
- _context(1),
- _socket(_context, zmq::socket_type::push)
-{
- gr::configure_default_loggers(d_logger, d_debug_logger, "buffer_net_zmq");
- set_type("buffer_net_zmq");
- _buffer.resize(_buf_size);
- _socket.set(zmq::sockopt::sndhwm, 1);
- _socket.set(zmq::sockopt::rcvhwm, 1);
- std::string endpoint = "tcp://*:" + std::to_string(port);
- std::cout << "snd_endpoint: " << endpoint << std::endl;
- _socket.bind(endpoint);
-}
-
-
-/****************************************************************************/
-/* READER METHODS */
-/****************************************************************************/
-
-
-buffer_reader_uptr
-buffer_net_zmq_reader::make(size_t itemsize, std::shared_ptr<buffer_properties> buf_props)
-{
- auto zbp = std::static_pointer_cast<buffer_net_zmq_properties>(buf_props);
- if (zbp != nullptr) {
- return std::make_unique<buffer_net_zmq_reader>(
- buf_props, itemsize, zbp->ipaddr(), zbp->port());
- }
- else {
- throw std::runtime_error(
- "Failed to cast buffer properties to buffer_net_zmq_properties");
- }
-}
-
-buffer_net_zmq_reader::buffer_net_zmq_reader(std::shared_ptr<buffer_properties> buf_props,
- size_t itemsize,
- const std::string& ipaddr,
- int port)
- : buffer_reader(nullptr, buf_props, itemsize, 0),
- _context(1),
- _socket(_context, zmq::socket_type::pull)
-{
- gr::configure_default_loggers(d_logger, d_debug_logger, "buffer_net_zmq_reader");
- auto bufprops = std::make_shared<buffer_cpu_vmcirc_properties>();
- _circbuf = gr::buffer_cpu_vmcirc::make(
- 8192,
- itemsize,
- bufprops); // FIXME - make nitems a buffer reader factory parameter
- _circbuf_rdr = _circbuf->add_reader(bufprops, itemsize);
-
- // auto b = (float *)_circbuf->write_ptr();
-
- // for (int i=0; i<8192; i++)
- // {
- // b[i] = i;
- // }
- // _circbuf->post_write(8192);
-
- // buffer_info_t info;
- // _circbuf_rdr->read_info(info);
- // auto br = (float *)_circbuf_rdr->read_ptr();
-
-
- // _circbuf_rdr->post_read(4096);
- // br = (float *) _circbuf_rdr->read_ptr();
-
-
- std::string endpoint = "tcp://" + ipaddr + ":" + std::to_string(port);
- d_debug_logger->debug("rcv_endpoint: {}", endpoint);
- _socket.set(zmq::sockopt::sndhwm, 1);
- _socket.set(zmq::sockopt::rcvhwm, 1);
- // _socket.setsockopt(ZMQ_SUBSCRIBE, "", 0);
- _socket.connect(endpoint);
- d_debug_logger->debug(" ... connected");
-
- std::thread t([this]() {
- while (!this->_recv_done) {
- // zmq::message_t msg{};
- // See how much room we have in the circular buffer
- buffer_info_t wi;
- _circbuf->write_info(wi);
-
- auto n_bytes_left_in_msg = _msg.size() - _msg_idx;
- auto n_bytes_in_circbuf = wi.n_items * wi.item_size;
- auto bytes_to_write = std::min(n_bytes_in_circbuf, n_bytes_left_in_msg);
- auto items_to_write = bytes_to_write / wi.item_size;
- bytes_to_write = items_to_write * wi.item_size;
-
- if (n_bytes_in_circbuf <= 0) {
- std::this_thread::sleep_for(std::chrono::milliseconds(1));
- continue;
- }
-
- if (bytes_to_write > 0) {
- memcpy(wi.ptr, (uint8_t*)_msg.data() + _msg_idx, bytes_to_write);
- d_debug_logger->debug("copied {} items", bytes_to_write / wi.item_size);
- _msg_idx += bytes_to_write;
- n_bytes_left_in_msg = _msg.size() - _msg_idx;
- _circbuf->post_write(items_to_write);
- notify_scheduler();
- }
-
- if (n_bytes_left_in_msg == 0) {
- _msg.rebuild();
- d_debug_logger->debug("going into recv");
- auto r = _socket.recv(_msg, zmq::recv_flags::none);
- if (r) {
- d_debug_logger->debug("received msg with size {} items",
- _msg.size() / wi.item_size);
- _msg_idx = 0;
- }
- }
- // GR_LOG_DEBUG(d_debug_logger, "recv: {}", wi.n_items);
- // auto ret = this->_socket.recv(
- // zmq::mutable_buffer(_circbuf->write_ptr(), wi.n_items * wi.item_size),
- // zmq::recv_flags::none);
-
- // _circbuf->post_write(wi.n_items);
- // notify_scheduler();
- // auto recbuf = *ret;
- // assert(recbuf.size == wi.n_items * wi.item_size);
-
- // GR_LOG_DEBUG(d_debug_logger, "nbytesrcv: {}", recbuf.size);
- // std::cout << " ---> msg received " << msg.size() << " bytes" <<
- // std::endl;
- }
- });
-
- t.detach();
-}
-
-std::string buffer_net_zmq_properties::to_json()
-{
- nlohmann::json j = { { "id", "buffer_net_zmq_properties" },
- { "parameters", { { "ipaddr", _ipaddr }, { "port", _port } } } };
-
- return j.dump();
-}
-
-} // namespace gr
diff --git a/gr/lib/buffer_sm.cc b/gr/lib/buffer_sm.cc
deleted file mode 100644
index 6766b1062..000000000
--- a/gr/lib/buffer_sm.cc
+++ /dev/null
@@ -1,374 +0,0 @@
-#include <gnuradio/buffer_sm.h>
-
-#include <gnuradio/logger.h>
-
-namespace gr {
-
-buffer_reader_uptr buffer_sm::add_reader(std::shared_ptr<buffer_properties> buf_props,
- size_t itemsize)
-{
- auto r = std::make_unique<buffer_sm_reader>(this, itemsize, buf_props, _write_index);
- _readers.push_back(r.get());
- return r;
-}
-
-buffer_sm::buffer_sm(size_t num_items,
- size_t item_size,
- std::shared_ptr<buffer_properties> buf_properties)
- : buffer(num_items, item_size, buf_properties)
-{
- _buffer.resize(_buf_size); // singly mapped buffer
- _raw_buffer = _buffer.data();
- _write_index = 0;
-
- set_type("buffer_sm");
-
-
- gr::configure_default_loggers(d_logger, d_debug_logger, _type);
-}
-
-buffer_uptr buffer_sm::make(size_t num_items,
- size_t item_size,
- std::shared_ptr<buffer_properties> buffer_properties)
-{
- return buffer_uptr(new buffer_sm(num_items, item_size, buffer_properties));
-}
-
-void* buffer_sm::read_ptr(size_t index) { return (void*)&_raw_buffer[index]; }
-void* buffer_sm::write_ptr() { return (void*)&_raw_buffer[_write_index]; }
-
-void buffer_sm::post_write(int num_items)
-{
- std::scoped_lock guard(_buf_mutex);
-
- size_t bytes_written = num_items * _item_size;
- // num_items were written to the buffer
-
- // advance the write pointer
- _write_index += bytes_written;
- if (_write_index == _buf_size) {
- _write_index = 0;
- }
- if (_write_index > _buf_size) {
- throw std::runtime_error("buffer_sm: Wrote too far into buffer");
- }
- _total_written += num_items;
-}
-
-bool buffer_sm::output_blkd_cb_ready(int output_multiple)
-{
- uint32_t space_avail = 0;
- {
- std::unique_lock<std::mutex>(*this->mutex());
- space_avail = space_available();
- }
- return ((space_avail > 0) &&
- ((space_avail / output_multiple) * output_multiple == 0));
-}
-
-bool buffer_sm::output_blocked_callback_logic(bool force, memmove_func_t memmove_func)
-{
- auto space_avail = space_available();
-
- // if (((space_avail > 0) && ((space_avail / output_multiple) * output_multiple ==
- // 0)) ||
- if ((space_avail > 0) || force) {
- // Find reader with the smallest read index
- uint32_t min_read_idx = _readers[0]->read_index();
- uint64_t min_read_idx_nitems = _readers[0]->total_read();
- for (size_t idx = 1; idx < _readers.size(); ++idx) {
- // Record index of reader with minimum read-index
- if (_readers[idx]->read_index() < min_read_idx) {
- min_read_idx = _readers[idx]->read_index();
- min_read_idx_nitems = _readers[idx]->total_read();
- }
- }
-
- d_debug_logger->debug("output_blocked_callback, space_avail {}, min_read_idx {}, "
- "_write_index {}",
- space_avail,
- min_read_idx,
- _write_index);
-
- // Make sure we have enough room to start writing back at the beginning
- if ((min_read_idx == 0) || (min_read_idx > _write_index) ||
- (min_read_idx == _write_index && min_read_idx_nitems != total_written())) {
- return false;
- }
-
- // Determine how much "to be read" data needs to be moved
- auto to_move_bytes = _write_index - min_read_idx;
-
- if (to_move_bytes > min_read_idx) {
- return false;
- }
-
-
- d_debug_logger->debug("output_blocked_callback, moving {} bytes", to_move_bytes);
-
- // Shift "to be read" data back to the beginning of the buffer
- std::memmove(_raw_buffer, _raw_buffer + (min_read_idx), to_move_bytes);
-
- // Adjust write index and each reader index
- _write_index -= min_read_idx;
-
- for (size_t idx = 0; idx < _readers.size(); ++idx) {
- d_debug_logger->debug("output_blocked_callback,setting _read_index to {}",
- _readers[idx]->read_index() - min_read_idx);
- _readers[idx]->set_read_index(_readers[idx]->read_index() - min_read_idx);
- }
-
- return true;
- }
-
- return false;
-}
-
-bool buffer_sm::output_blocked_callback(bool force)
-{
- std::scoped_lock guard(_buf_mutex);
-
- return output_blocked_callback_logic(force, std::memmove);
-}
-
-size_t buffer_sm::space_available()
-{
- // Find the max number of items available across readers
-
- uint64_t min_items_read = std::numeric_limits<uint64_t>::max();
- size_t min_read_idx = 0;
- for (size_t idx = 0; idx < _readers.size(); idx++) {
- std::scoped_lock lck{ *(_readers[idx]->mutex()) };
- auto total_read = _readers[idx]->total_read();
- if (total_read < min_items_read) {
- min_items_read = total_read;
- min_read_idx = _readers[idx]->read_index();
- }
- }
-
- size_t space = (_buf_size - _write_index) / _item_size;
-
- if (min_read_idx == _write_index) {
- // If the (min) read index and write index are equal then the buffer
- // is either completely empty or completely full depending on if
- // the number of items read matches the number written
- if (min_items_read != total_written()) {
- space = 0;
- }
- }
- else if (min_read_idx > _write_index) {
- space = (min_read_idx - _write_index) / _item_size;
- }
-
- if (space == 0)
- return space;
- // Only half fill the buffer
- // Leave extra space in case the reader gets stuck and needs realignment
-
- space = std::min(space, _num_items);
-
- return space;
-}
-
-bool buffer_sm::write_info(buffer_info_t& info)
-{
- std::scoped_lock guard(_buf_mutex);
-
- info.ptr = write_ptr();
- info.n_items = space_available();
- if (info.n_items < 0)
- info.n_items = 0;
- info.item_size = _item_size;
- info.total_items = _total_written;
-
- return true;
-}
-
-bool buffer_sm::adjust_buffer_data(memcpy_func_t memcpy_func, memmove_func_t memmove_func)
-{
-
- // Find reader with the smallest read index that is greater than the
- // write index
- // auto min_reader_index = std::numeric_limits<size_t>::max();
- auto min_read_idx = std::numeric_limits<size_t>::max();
- for (size_t idx = 0; idx < _readers.size(); ++idx) {
- if (_readers[idx]->read_index() > write_index()) {
- // Record index of reader with minimum read-index
- // FIXME: What if one of the readers has wrapped back around?
- // -- in that case this should use items_available() callback
- if (_readers[idx]->read_index() < min_read_idx) {
- min_read_idx = _readers[idx]->read_index();
- // min_reader_index = idx;
- }
- }
- }
-
- // Note items_avail might be zero, that's okay.
- auto max_bytes_avail = _buf_size - min_read_idx;
- auto max_items_avail = max_bytes_avail / _item_size;
- auto gap = min_read_idx - _write_index;
- if (_write_index > min_read_idx || max_bytes_avail > gap) {
- return false;
- }
-
- // GR_LOG_DEBUG(d_debug_logger,
- // "adust_buffer_data: max_bytes_avail {}, gap {}",
- // max_bytes_avail,
- // gap);
-
-
- // Shift existing data down to make room for blocked data at end of buffer
- auto move_data_size = _write_index;
- auto dest = _raw_buffer + max_bytes_avail;
- memmove_func(dest, _raw_buffer, move_data_size);
-
- // Next copy the data from the end of the buffer back to the beginning
- auto avail_data_size = max_bytes_avail;
- auto src = _raw_buffer + min_read_idx;
- memcpy_func(_raw_buffer, src, avail_data_size);
-
- // Finally adjust all reader pointers
- for (size_t idx = 0; idx < _readers.size(); ++idx) {
- // GR_LOG_DEBUG(d_debug_logger,
- // "adjust_buffer_data,setting _read_index to {}",
- // _readers[idx]->read_index() - min_read_idx);
- _readers[idx]->set_read_index(max_items_avail - _readers[idx]->items_available());
- }
-
- // Now adjust write pointer
- _write_index += max_items_avail;
-
- return true;
-}
-
-
-buffer_sm_reader::buffer_sm_reader(buffer_sm* bufp,
- size_t itemsize,
- std::shared_ptr<buffer_properties> buf_props,
- size_t read_index)
- : buffer_reader(bufp, buf_props, itemsize, read_index), _buffer_sm(bufp)
-{
- gr::configure_default_loggers(d_logger, d_debug_logger, "buffer_sm_reader");
-}
-
-void buffer_sm_reader::post_read(int num_items)
-{
- std::scoped_lock guard(_rdr_mutex);
-
- // GR_LOG_DEBUG(
- // d_debug_logger, "post_read: _read_index {}, num_items {}", _read_index, num_items);
-
- // advance the read pointer
- _read_index += num_items * _itemsize; //_buffer->item_size();
- _total_read += num_items;
- if (_read_index == _buffer->buf_size()) {
- _read_index = 0;
- }
- if (_read_index > _buffer->buf_size()) {
- // GR_LOG_INFO(d_logger,
- // "too far: num_items {}, prev_index {}, post_index {}",
- // num_items,
- // _read_index - num_items * _buffer->item_size(),
- // _read_index);
-
- // // throw std::runtime_error("buffer_sm_reader: Wrote too far into buffer");
- }
-
- // GR_LOG_DEBUG(d_debug_logger, "post_read: _read_index {}", _read_index);
-}
-
-bool buffer_sm_reader::input_blocked_callback(size_t items_required)
-{
- // Only singly mapped buffers need to do anything with this callback
- std::scoped_lock guard(*(_buffer->mutex()));
-
- auto items_avail = items_available();
-
- // GR_LOG_DEBUG(d_debug_logger,
- // "input_blocked_callback: items_avail {}, _read_index {}, "
- // "_write_index {}, items_required {}",
- // items_avail,
- // _read_index,
- // _buffer->write_index(),
- // items_required);
-
- // GR_LOG_DEBUG(d_debug_logger,
- // "input_blocked_callback: total_written {}, total_read {}",
- // _buffer->total_written(),
- // total_read());
-
-
- // Maybe adjust read pointers from min read index?
- // This would mean that *all* readers must be > (passed) the write index
- if (items_avail < items_required && _buffer->write_index() < read_index()) {
- // GR_LOG_DEBUG(d_debug_logger, "Calling adjust_buffer_data ");
- return _buffer_sm->adjust_buffer_data(std::memcpy, std::memmove);
- }
-
- return false;
-}
-
-size_t buffer_sm_reader::bytes_available()
-{
- // Can only read up to to the write_index, or the end of the buffer
- // there is no wraparound
-
- size_t ret = 0;
-
- size_t w = _buffer->write_index();
- size_t r = _read_index;
-
- if (w < r) {
- ret = (_buffer->buf_size() - r);
- }
- else if (w == r && total_read() < _buffer->total_written()) {
- ret = (_buffer->buf_size() - r);
- }
- else {
- ret = (w - r);
- }
-
- // return ret;
-
- // GR_LOG_DEBUG(d_debug_logger,
- // "items_available: write_index {}, read_index {}, ret {}, total_read "
- // "{}, total_written {}",
- // w,
- // r,
- // ret,
- // total_read(),
- // _buffer->total_written());
-
- // if (_itemsize*(_buffer->total_written() - total_read()) < ret) {
- // d_debug_logger->debug(
- // "check_math {} {} {} {}",
- // _buffer->total_written() - total_read(),
- // ret,
- // total_read(),
- // _buffer->total_written());
- // }
-
- return ret; // in bytes
-}
-
-bool buffer_sm_reader::input_blkd_cb_ready(int items_required)
-{
- std::unique_lock<std::mutex>(*_buffer->mutex());
-
- return (
- ((_buffer->buf_size() * _itemsize - _read_index) < (uint32_t)items_required) &&
- (_buffer->write_index() < _read_index));
-}
-
-buffer_sm_properties::buffer_sm_properties() : buffer_properties()
-{
- _bff = buffer_sm::make;
-}
-
-std::shared_ptr<buffer_properties> buffer_sm_properties::make()
-{
- return std::static_pointer_cast<buffer_properties>(
- std::make_shared<buffer_sm_properties>());
-}
-
-} // namespace gr
diff --git a/gr/lib/meson.build b/gr/lib/meson.build
index a809cea2e..dbee9c491 100644
--- a/gr/lib/meson.build
+++ b/gr/lib/meson.build
@@ -32,7 +32,6 @@ runtime_sources = [
'block.cc',
'port.cc',
'buffer.cc',
- 'buffer_sm.cc',
'buffer_management.cc',
'buffer_cpu_simple.cc',
'realtime.cc',
@@ -56,13 +55,11 @@ runtime_sources = [
'buffer_cpu_vmcirc_sysv_shm.cc',
# mmap requires librt - FIXME - handle this a conditional dependency
'buffer_cpu_vmcirc_mmap_shm_open.cc',
- 'buffer_net_zmq.cc',
'sptr_magic.cc',
'hier_block.cc',
'prefs.cc',
'tag.cc',
'registry.cc',
- 'buffer_cpu_host.cc'
]
if IMPLEMENT_CUDA
diff --git a/gr/meson.build b/gr/meson.build
index 2627dfa6b..62ed6711a 100644
--- a/gr/meson.build
+++ b/gr/meson.build
@@ -1,5 +1,4 @@
subdir('include/gnuradio')
-subdir('include/moodycamel')
subdir('lib')
if (get_option('enable_python'))
diff --git a/gr/python/gnuradio/gr/bindings/buffer_net_zmq_pybind.cc b/gr/python/gnuradio/gr/bindings/buffer_net_zmq_pybind.cc
deleted file mode 100644
index 3effa205c..000000000
--- a/gr/python/gnuradio/gr/bindings/buffer_net_zmq_pybind.cc
+++ /dev/null
@@ -1,37 +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/buffer_net_zmq.h>
-// pydoc.h is automatically generated in the build directory
-// #include <edge_pydoc.h>
-
-void bind_buffer_net_zmq(py::module& m)
-{
- using buffer_net_zmq_properties = ::gr::buffer_net_zmq_properties;
-
- py::class_<buffer_net_zmq_properties,
- gr::buffer_properties,
- std::shared_ptr<buffer_net_zmq_properties>>(m, "buffer_net_zmq_properties")
- // .def(py::init(
- // [](const std::string& ipaddr, int port) {
- // return ::gr::buffer_net_zmq_properties::make(ipaddr, port);
- // }), py::arg("ipaddr"), py::arg("port"))
- .def_static(
- "make", &buffer_net_zmq_properties::make, py::arg("ipaddr"), py::arg("port"))
- .def_static("make_from_params",
- &buffer_net_zmq_properties::make_from_params,
- py::arg("json_str"))
- .def("to_json", &buffer_net_zmq_properties::to_json);
-}
diff --git a/gr/python/gnuradio/gr/bindings/gr_pybind.cc b/gr/python/gnuradio/gr/bindings/gr_pybind.cc
index 1ec5bc33d..8a43a6c1d 100644
--- a/gr/python/gnuradio/gr/bindings/gr_pybind.cc
+++ b/gr/python/gnuradio/gr/bindings/gr_pybind.cc
@@ -35,7 +35,6 @@ void bind_buffer(py::module&);
void bind_vmcircbuf(py::module&);
void bind_constants(py::module&);
void bind_python_block(py::module&);
-void bind_buffer_net_zmq(py::module& m);
void bind_runtime(py::module&);
void bind_runtime_proxy(py::module&);
void bind_graph_utils(py::module&);
@@ -77,7 +76,6 @@ PYBIND11_MODULE(gr_python, m)
bind_flowgraph(m);
bind_scheduler(m);
bind_buffer(m);
- bind_buffer_net_zmq(m);
bind_vmcircbuf(m);
bind_constants(m);
bind_python_block(m);
diff --git a/gr/python/gnuradio/gr/bindings/meson.build b/gr/python/gnuradio/gr/bindings/meson.build
index 23421526b..55ad0ec83 100644
--- a/gr/python/gnuradio/gr/bindings/meson.build
+++ b/gr/python/gnuradio/gr/bindings/meson.build
@@ -13,7 +13,6 @@ runtime_pybind_sources = files([
'scheduler_pybind.cc',
'buffer_pybind.cc',
'buffer_cpu_vmcirc_pybind.cc',
- 'buffer_net_zmq_pybind.cc',
'constants_pybind.cc',
'python_block_pybind.cc',
'runtime_pybind.cc',
diff --git a/gr/test/meson.build b/gr/test/meson.build
index 86be691d4..9c3f5fa78 100644
--- a/gr/test/meson.build
+++ b/gr/test/meson.build
@@ -5,12 +5,12 @@ qa_srcs = ['qa_host_buffer',
deps = [gnuradio_gr_dep,
gtest_dep,]
-foreach qa : qa_srcs
- e = executable(qa,
- qa + '.cc',
- include_directories : incdir,
- link_language : 'cpp',
- dependencies: deps,
- install : false)
- test(qa, e, env: TEST_ENV)
-endforeach \ No newline at end of file
+# foreach qa : qa_srcs
+# e = executable(qa,
+# qa + '.cc',
+# include_directories : incdir,
+# link_language : 'cpp',
+# dependencies: deps,
+# install : false)
+# test(qa, e, env: TEST_ENV)
+# endforeach \ No newline at end of file
diff --git a/gr/test/qa_host_buffer.cc b/gr/test/qa_host_buffer.cc
deleted file mode 100644
index 326611f29..000000000
--- a/gr/test/qa_host_buffer.cc
+++ /dev/null
@@ -1,281 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2021 BlackLynx Inc.
- * Copyright 2022 Josh Morman
- *
- * This file is part of GNU Radio
- *
- * SPDX-License-Identifier: GPL-3.0-or-later
- *
- */
-
-#include <gtest/gtest.h>
-
-#include <gnuradio/block.h>
-#include <gnuradio/buffer_cpu_host.h>
-
-#include <cstdlib>
-#include <iostream>
-
-
-using namespace gr;
-
-// ----------------------------------------------------------------------------
-// Basic checks for buffer_single_mapped using the buffer_cpu_host implementation
-// of the interface for testing.
-// ----------------------------------------------------------------------------
-TEST(HostBuffer, t0)
-{
- size_t nitems = 65536 / sizeof(int);
-
- auto buf_props = BUFFER_CPU_HOST_ARGS_H2D;
- auto buf = buf_props->factory()(nitems, 1, buf_props);
- auto rdr1 = buf->add_reader(buf_props, 1);
-
- EXPECT_TRUE(buf->space_available() == nitems);
- EXPECT_TRUE(rdr1->items_available() == 0);
-
- for (size_t idx = 1; idx <= 16; ++idx) {
- buf->post_write(1000);
- EXPECT_TRUE(buf->space_available() == (nitems - (idx * 1000)));
-
- EXPECT_TRUE(rdr1->items_available() == (idx * 1000));
- }
-
- EXPECT_TRUE(buf->space_available() == 384);
-
- buf->post_write(buf->space_available());
- EXPECT_TRUE(buf->space_available() == 0);
- EXPECT_TRUE(rdr1->items_available() == nitems);
- EXPECT_TRUE(buf->space_available() == 0);
-}
-
-// ----------------------------------------------------------------------------
-// Basic checks for buffer_single_mapped using the buffer_cpu_host implementation
-// of the interface for testing.
-// ----------------------------------------------------------------------------
-TEST(HostBuffer, t1)
-{
- size_t nitems = 65536 / sizeof(int);
-
- auto buf_props = BUFFER_CPU_HOST_ARGS_H2D;
- auto buf = buf_props->factory()(nitems, 1, buf_props);
- auto rdr1 = buf->add_reader(buf_props, 1);
-
- size_t space = buf->space_available();
- EXPECT_TRUE(nitems == space);
-
- EXPECT_TRUE(rdr1->items_available() == 0);
-
- buf->post_write(nitems);
- EXPECT_TRUE(buf->space_available() == 0);
- EXPECT_TRUE(rdr1->items_available() == nitems);
-
- for (size_t idx = 1; idx <= 16; ++idx) {
- rdr1->post_read(1000);
- EXPECT_TRUE(rdr1->items_available() == (nitems - (idx * 1000)));
-
- space = buf->space_available();
- EXPECT_TRUE(space == (idx * 1000));
- }
-
- EXPECT_TRUE(rdr1->items_available() == 384);
- rdr1->post_read(384);
- EXPECT_TRUE(rdr1->items_available() == 0);
-}
-
-// ----------------------------------------------------------------------------
-// Basic check reader/write wrapping of buffer_single_mapped with 1 reader.
-// ----------------------------------------------------------------------------
-TEST(HostBuffer, t2)
-{
- size_t nitems = 65536 / sizeof(int);
-
- auto buf_props = BUFFER_CPU_HOST_ARGS_H2D;
- auto buf = buf_props->factory()(nitems, 1, buf_props);
- auto rdr1 = buf->add_reader(buf_props, 1);
-
- size_t space = buf->space_available();
- EXPECT_TRUE(nitems == space);
- EXPECT_TRUE(rdr1->items_available() == 0);
-
- buf->post_write(nitems);
- EXPECT_TRUE(buf->space_available() == 0);
-
- for (size_t idx = 1; idx <= 16; ++idx) {
- rdr1->post_read(1000);
- EXPECT_TRUE(rdr1->items_available() == (nitems - (idx * 1000)));
-
- space = buf->space_available();
-
- if (idx <= 9)
- EXPECT_TRUE(space == (idx * 1000));
- else
- EXPECT_TRUE(space == ((idx * 1000) - (nitems / 2)));
-
- if (idx == 9) {
- buf->post_write(nitems / 2);
- }
- }
-
- // At this point we can only read up until the end of the buffer even though
- // additional data is available at the beginning of the buffer
- EXPECT_TRUE(rdr1->items_available() == 384);
- rdr1->post_read(384);
-
- // Now the (nitems / 2) at the beginning of the buffer should be available
- EXPECT_TRUE(rdr1->items_available() == (nitems / 2));
-
- for (size_t idx = 0; idx < 4; ++idx)
- rdr1->post_read(1024);
-
- EXPECT_TRUE(buf->space_available() == (nitems / 2));
- EXPECT_TRUE(rdr1->items_available() == (nitems / 4));
-
- for (size_t idx = 0; idx < 4; ++idx)
- rdr1->post_read(1000);
-
- EXPECT_TRUE(buf->space_available() == (nitems / 2));
- EXPECT_TRUE(rdr1->items_available() == 96);
-
- rdr1->post_read(96);
- EXPECT_TRUE(rdr1->items_available() == 0);
-
- EXPECT_TRUE(buf->space_available() == (nitems / 2));
-}
-
-// ----------------------------------------------------------------------------
-// Basic check reader/write wrapping of buffer_single_mapped with 2 readers.
-// ----------------------------------------------------------------------------
-TEST(HostBuffer, t3)
-{
- size_t nitems = 65536 / sizeof(int);
-
- auto buf_props = BUFFER_CPU_HOST_ARGS_H2D;
- auto buf = buf_props->factory()(nitems, 1, buf_props);
- auto rdr1 = buf->add_reader(buf_props, 1);
- auto rdr2 = buf->add_reader(buf_props, 1);
-
- size_t space = buf->space_available();
- EXPECT_TRUE(nitems == space);
- EXPECT_TRUE(rdr1->items_available() == 0);
- EXPECT_TRUE(rdr2->items_available() == 0);
-
- buf->post_write(nitems);
- EXPECT_TRUE(buf->space_available() == 0);
- EXPECT_TRUE(rdr1->items_available() == nitems);
- EXPECT_TRUE(rdr2->items_available() == nitems);
-
- for (size_t idx = 1; idx <= 16; ++idx) {
- rdr1->post_read(1000);
- EXPECT_TRUE(rdr1->items_available() == (nitems - (idx * 1000)));
-
- // Reader 2 hasn't read anything so space available should remain 0
- EXPECT_TRUE(buf->space_available() == 0);
- }
-
- size_t last_rdr1_available = rdr1->items_available();
- size_t increment = last_rdr1_available / 4;
-
- for (size_t idx = 1; idx <= 16; ++idx) {
- rdr2->post_read(1000);
- EXPECT_TRUE(rdr2->items_available() == (nitems - (idx * 1000)));
-
- EXPECT_TRUE(rdr1->items_available() == last_rdr1_available);
- if (idx % 4 == 0) {
- rdr1->post_read(increment);
- EXPECT_TRUE(rdr1->items_available() == (last_rdr1_available - increment));
- last_rdr1_available = rdr1->items_available();
- }
-
- EXPECT_TRUE(buf->space_available() == (idx * 1000));
- }
-}
-
-// ----------------------------------------------------------------------------
-// Basic check of output blocked callback
-// ----------------------------------------------------------------------------
-TEST(HostBuffer, t4)
-{
- size_t nitems = 65536 / sizeof(int);
-
- auto buf_props = BUFFER_CPU_HOST_ARGS_H2D;
- auto buf = buf_props->factory()(nitems, 1, buf_props);
- auto rdr1 = buf->add_reader(buf_props, 1);
-
- EXPECT_TRUE(nitems == buf->space_available());
- EXPECT_TRUE(rdr1->items_available() == 0);
-
- buf->post_write(nitems / 2);
- EXPECT_TRUE(buf->space_available() == (nitems / 2));
- EXPECT_TRUE(rdr1->items_available() == (nitems / 2));
-
- rdr1->post_read(nitems / 2);
- EXPECT_TRUE(buf->space_available() == (nitems / 2));
- EXPECT_TRUE(rdr1->items_available() == 0);
-
- buf->post_write(8000);
- EXPECT_TRUE(buf->space_available() == 192);
-
- bool ready = buf->output_blkd_cb_ready(200);
- EXPECT_TRUE(ready == true);
-
- bool success = buf->output_blocked_callback(200);
- EXPECT_TRUE(success == true);
- EXPECT_TRUE(buf->space_available() == 8384);
- EXPECT_TRUE(rdr1->items_available() == 8000);
-
- rdr1->post_read(4000);
- EXPECT_TRUE(buf->space_available() == 8384);
- EXPECT_TRUE(rdr1->items_available() == 4000);
-
- buf->post_write(4000);
- EXPECT_TRUE(buf->space_available() == 4384);
- EXPECT_TRUE(rdr1->items_available() == 8000);
-
- rdr1->post_read(8000);
- EXPECT_TRUE(buf->space_available() == 4384);
- EXPECT_TRUE(rdr1->items_available() == 0);
-}
-
-// ----------------------------------------------------------------------------
-// Basic check of input blocked callback
-// ----------------------------------------------------------------------------
-TEST(HostBuffer, t5)
-{
- size_t nitems = 65536 / sizeof(int);
-
- auto buf_props = BUFFER_CPU_HOST_ARGS_H2D;
- auto buf = buf_props->factory()(nitems, 1, buf_props);
- auto rdr1 = buf->add_reader(buf_props, 1);
-
- EXPECT_TRUE(nitems == buf->space_available());
- EXPECT_TRUE(rdr1->items_available() == 0);
-
- buf->post_write(16000);
- EXPECT_TRUE(buf->space_available() == 384);
- EXPECT_TRUE(rdr1->items_available() == 16000);
-
- rdr1->post_read(16000);
- EXPECT_TRUE(buf->space_available() == 384);
- EXPECT_TRUE(rdr1->items_available() == 0);
-
- buf->post_write(384);
- EXPECT_TRUE(buf->space_available() == 16000);
- EXPECT_TRUE(rdr1->items_available() == 384);
-
- buf->post_write(116);
- EXPECT_TRUE(buf->space_available() == 15884);
- EXPECT_TRUE(rdr1->items_available() == 384);
-
- bool ready = rdr1->input_blkd_cb_ready(400);
- EXPECT_TRUE(ready == true);
-
- bool success = rdr1->input_blocked_callback(400);
- EXPECT_TRUE(success == true);
- EXPECT_TRUE(rdr1->items_available() == 500);
-
- rdr1->post_read(500);
- EXPECT_TRUE(buf->space_available() == 15884);
- EXPECT_TRUE(rdr1->items_available() == 0);
-}
diff --git a/meson.build b/meson.build
index 01bd5cabc..00f3f9811 100644
--- a/meson.build
+++ b/meson.build
@@ -96,15 +96,9 @@ if (get_option('enable_testing'))
TEST_ENV.prepend('LD_LIBRARY_PATH',
join_paths( meson.build_root(),'schedulers','nbt','lib'),
join_paths( meson.build_root(),'runtime','lib'),
- join_paths( meson.build_root(),'blocklib','analog','lib'),
join_paths( meson.build_root(),'blocklib','blocks','lib'),
- join_paths( meson.build_root(),'blocklib','fec','lib'),
- join_paths( meson.build_root(),'blocklib','fft','lib'),
- join_paths( meson.build_root(),'blocklib','fileio','lib'),
- join_paths( meson.build_root(),'blocklib','filter','lib'),
join_paths( meson.build_root(),'blocklib','math','lib'),
join_paths( meson.build_root(),'blocklib','streamops','lib'),
- join_paths( meson.build_root(),'blocklib','soapy','lib'),
join_paths( meson.build_root(),'kernel','analog','lib'),
join_paths( meson.build_root(),'kernel','digital','lib'),
diff --git a/schedulers/nbt/include/gnuradio/schedulers/nbt/scheduler_nbt.h b/schedulers/nbt/include/gnuradio/schedulers/nbt/scheduler_nbt.h
index d6571c9f7..5122d2b79 100644
--- a/schedulers/nbt/include/gnuradio/schedulers/nbt/scheduler_nbt.h
+++ b/schedulers/nbt/include/gnuradio/schedulers/nbt/scheduler_nbt.h
@@ -1,5 +1,4 @@
#include <gnuradio/block_group_properties.h>
-#include <gnuradio/buffer_cpu_host.h>
#include <gnuradio/buffer_cpu_vmcirc.h>
// #include <gnuradio/buffer_cpu_simple.h>
#include <gnuradio/graph_utils.h>
@@ -26,14 +25,8 @@ public:
}
scheduler_nbt(const scheduler_nbt_options& opts) : scheduler(opts.name), _opts(opts)
{
- if (opts.default_buffer_type == "cpu_host") {
- _default_buf_properties =
- buffer_cpu_host_properties::make(buffer_cpu_host_type::H2H);
- }
- else {
- _default_buf_properties =
- buffer_cpu_vmcirc_properties::make(buffer_cpu_vmcirc_type::AUTO);
- }
+ _default_buf_properties =
+ buffer_cpu_vmcirc_properties::make(buffer_cpu_vmcirc_type::AUTO);
}
~scheduler_nbt() override{};
diff --git a/test/meson.build b/test/meson.build
index 9ef0b73fd..58b8cca11 100644
--- a/test/meson.build
+++ b/test/meson.build
@@ -3,10 +3,7 @@
qa_srcs = ['qa_default_runtime',
'qa_scheduler_nbt',
'qa_block_grouping',
- 'qa_single_mapped_buffers',
'qa_message_ports',
- 'qa_tags',
- 'qa_zmq_buffers',
'qa_hier_block',
'qa_reflection',
]
diff --git a/test/qa_single_mapped_buffers.cc b/test/qa_single_mapped_buffers.cc
deleted file mode 100644
index 1862bcdba..000000000
--- a/test/qa_single_mapped_buffers.cc
+++ /dev/null
@@ -1,139 +0,0 @@
-#include <gtest/gtest.h>
-
-#include <chrono>
-#include <iostream>
-#include <thread>
-
-#include <gnuradio/blocks/vector_sink.h>
-#include <gnuradio/blocks/vector_source.h>
-#include <gnuradio/buffer_sm.h>
-#include <gnuradio/flowgraph.h>
-#include <gnuradio/math/multiply_const.h>
-#include <gnuradio/runtime.h>
-#include <gnuradio/schedulers/nbt/scheduler_nbt.h>
-
-using namespace gr;
-
-
-TEST(SchedulerMTSingleBuffers, SingleMappedSimple)
-{
- int nsamples = 1000000;
- std::vector<gr_complex> input_data(nsamples);
- std::vector<gr_complex> expected_data(nsamples);
-
- float k = 1.0;
- for (int i = 0; i < nsamples; i++) {
- input_data[i] = gr_complex(2 * i, 2 * i + 1);
- }
-
- int nblocks = 2;
- size_t veclen = 1;
- auto src = blocks::vector_source_c::make({ input_data });
- auto snk = blocks::vector_sink_c::make({});
- std::vector<math::multiply_const_cc::sptr> mult_blks(nblocks);
-
- for (int i = 0; i < nblocks; i++) {
- mult_blks[i] = math::multiply_const_cc::make_cpu({ k, veclen });
- }
-
- auto fg = flowgraph::make();
-
- fg->connect(src, 0, mult_blks[0], 0);
- for (int i = 1; i < nblocks; i++) {
- fg->connect(mult_blks[i - 1], 0, mult_blks[i], 0)
- ->set_custom_buffer(SM_BUFFER_ARGS);
- }
- fg->connect(mult_blks[nblocks - 1], 0, snk, 0);
-
- auto rt = runtime::make();
- rt->initialize(fg);
- rt->start();
- rt->wait();
-
-
- for (int i = 0; i < nsamples; i++) {
- expected_data[i] = gr_complex(k * 2 * i, k * (2 * i + 1));
- }
-
-
- auto d = snk->data();
- EXPECT_EQ(d, expected_data);
- EXPECT_EQ(d.size(), expected_data.size());
-
- for (size_t i = 0; i < expected_data.size(); i++) {
- if (d[i] != expected_data[i]) {
- std::cout << i << ": " << d[i] << " " << expected_data[i] << std::endl;
- }
- }
-}
-
-
-#if 1
-// Test the case where we have multiple readers to a single block
-TEST(SchedulerMTSingleBuffers, SingleMappedFanout)
-{
- int nsamples = 1000000;
- std::vector<gr_complex> input_data(nsamples);
- std::vector<gr_complex> expected_data(nsamples);
-
- float k = 1.0;
- for (int i = 0; i < nsamples; i++) {
- input_data[i] = gr_complex(2 * i, 2 * i + 1);
- expected_data[i] = gr_complex(k * 2 * i, k * (2 * i + 1));
- }
-
- auto nblocks = 4;
-
-
- size_t veclen = 1;
- auto src = blocks::vector_source_c::make({ input_data });
- std::vector<blocks::vector_sink_c::sptr> sink_blks(nblocks);
- std::vector<math::multiply_const_cc::sptr> mult_blks(nblocks);
-
- for (int i = 0; i < nblocks; i++) {
- mult_blks[i] = math::multiply_const_cc::make_cpu({ k, veclen });
- sink_blks[i] = blocks::vector_sink_c::make({});
- }
- flowgraph_sptr fg(new flowgraph());
-
- for (int i = 0; i < nblocks; i++) {
- fg->connect(src, 0, mult_blks[i], 0)->set_custom_buffer(SM_BUFFER_ARGS);
- fg->connect(mult_blks[i], 0, sink_blks[i], 0)->set_custom_buffer(SM_BUFFER_ARGS);
- }
-
- auto rt = runtime::make();
- rt->initialize(fg);
- rt->start();
- rt->wait();
-
- for (int n = 0; n < nblocks; n++) {
-
- auto d = sink_blks[n]->data();
- EXPECT_EQ(d.size(), expected_data.size());
- if (d.size() == expected_data.size()) {
- EXPECT_EQ(d, expected_data);
-
- for (size_t i = 0; i < expected_data.size(); i++) {
- if (d[i] != expected_data[i]) {
- std::cout << n << " " << i << ": " << d[i] << " " << expected_data[i]
- << std::endl;
- }
- }
- }
- else {
- if (d.size() < expected_data.size()) {
- auto e = std::vector<gr_complex>(expected_data.begin(),
- expected_data.begin() + d.size());
- EXPECT_EQ(d, e);
-
- for (size_t i = 0; i < e.size(); i++) {
- if (d[i] != e[i]) {
- std::cout << n << " " << i << ": " << d[i] << " " << e[i]
- << std::endl;
- }
- }
- }
- }
- }
-}
-#endif
diff --git a/test/qa_tags.cc b/test/qa_tags.cc
deleted file mode 100644
index 471b5608f..000000000
--- a/test/qa_tags.cc
+++ /dev/null
@@ -1,251 +0,0 @@
-#include <gtest/gtest.h>
-
-#include <chrono>
-#include <iostream>
-#include <thread>
-
-#include <gnuradio/blocks/null_sink.h>
-#include <gnuradio/blocks/null_source.h>
-#include <gnuradio/blocks/vector_sink.h>
-#include <gnuradio/blocks/vector_source.h>
-#include <gnuradio/buffer_cpu_vmcirc.h>
-#include <gnuradio/flowgraph.h>
-#include <gnuradio/runtime.h>
-#include <gnuradio/schedulers/nbt/scheduler_nbt.h>
-#include <gnuradio/streamops/annotator.h>
-#include <gnuradio/streamops/head.h>
-
-using namespace gr;
-
-TEST(SchedulerMTTags, OneToOne)
-{
- size_t N = 40000;
- auto fg = flowgraph::make();
- auto src = gr::blocks::null_source::make({});
- auto head = gr::streamops::head::make_cpu({ N });
- auto ann0 = gr::streamops::annotator::make_cpu(
- { 10000, 1, 2, tag_propagation_policy_t::TPP_ONE_TO_ONE });
- auto ann1 = gr::streamops::annotator::make_cpu(
- { 10000, 1, 1, tag_propagation_policy_t::TPP_ONE_TO_ONE });
- auto ann2 = gr::streamops::annotator::make_cpu(
- { 10000, 1, 1, tag_propagation_policy_t::TPP_ONE_TO_ONE });
- auto snk0 = gr::blocks::null_sink::make({});
- auto snk1 = gr::blocks::null_sink::make({});
-
- // using 1-to-1 tag propagation without having equal number of
- // ins and outs. Make sure this works; will just exit run early.
- fg->connect(src, 0, head, 0);
- fg->connect(head, 0, ann0, 0);
- fg->connect(ann0, 0, ann1, 0);
- fg->connect(ann0, 1, ann2, 0);
- fg->connect(ann1, 0, snk0, 0);
- fg->connect(ann2, 0, snk1, 0);
-
- std::cerr << std::endl
- << "NOTE: This is supposed to produce an error from block_executor"
- << std::endl;
-
- auto rt = runtime::make();
- rt->initialize(fg);
- rt->start();
- rt->wait();
-
- std::vector<gr::tag_t> tags0 = ann0->data();
- std::vector<gr::tag_t> tags1 = ann1->data();
- std::vector<gr::tag_t> tags2 = ann2->data();
-
- // The first annotator does not receive any tags from the null sink upstream
- EXPECT_EQ(tags0.size(), 0);
- EXPECT_EQ(tags1.size(), 4);
- EXPECT_EQ(tags2.size(), 4);
-}
-
-TEST(SchedulerMTTags, t1)
-{
- size_t N = 40000;
- auto fg = flowgraph::make();
- auto src = gr::blocks::null_source::make({});
- auto head = gr::streamops::head::make_cpu({ N });
- auto ann0 = gr::streamops::annotator::make_cpu(
- { 10000, 1, 2, tag_propagation_policy_t::TPP_ALL_TO_ALL });
- auto ann1 = gr::streamops::annotator::make_cpu(
- { 10000, 1, 1, tag_propagation_policy_t::TPP_ALL_TO_ALL });
- auto ann2 = gr::streamops::annotator::make_cpu(
- { 10000, 1, 1, tag_propagation_policy_t::TPP_ALL_TO_ALL });
- auto ann3 = gr::streamops::annotator::make_cpu(
- { 10000, 1, 1, tag_propagation_policy_t::TPP_ALL_TO_ALL });
- auto ann4 = gr::streamops::annotator::make_cpu(
- { 10000, 1, 1, tag_propagation_policy_t::TPP_ALL_TO_ALL });
-
- auto snk0 = gr::blocks::null_sink::make({});
- auto snk1 = gr::blocks::null_sink::make({});
-
- fg->connect(src, 0, head, 0);
- fg->connect(head, 0, ann0, 0);
-
- fg->connect(ann0, 0, ann1, 0);
- fg->connect(ann0, 1, ann2, 0);
- fg->connect(ann1, 0, ann3, 0);
- fg->connect(ann2, 0, ann4, 0);
-
- fg->connect(ann3, 0, snk0, 0);
- fg->connect(ann4, 0, snk1, 0);
-
- auto rt = runtime::make();
- rt->initialize(fg);
- rt->start();
- rt->wait();
-
- std::vector<gr::tag_t> tags0 = ann0->data();
- std::vector<gr::tag_t> tags3 = ann3->data();
- std::vector<gr::tag_t> tags4 = ann4->data();
-
- // The first annotator does not receive any tags from the null sink upstream
- EXPECT_EQ(tags0.size(), (size_t)0);
- EXPECT_EQ(tags3.size(), (size_t)8);
- EXPECT_EQ(tags4.size(), (size_t)8);
-}
-
-TEST(SchedulerMTTags, t2)
-{
- size_t N = 40000;
- auto fg = flowgraph::make();
- auto src = gr::blocks::null_source::make({});
- auto head = gr::streamops::head::make_cpu({ N });
- auto ann0 = gr::streamops::annotator::make_cpu(
- { 10000, 1, 2, tag_propagation_policy_t::TPP_ALL_TO_ALL });
- auto ann1 = gr::streamops::annotator::make_cpu(
- { 10000, 2, 3, tag_propagation_policy_t::TPP_ALL_TO_ALL });
- auto ann2 = gr::streamops::annotator::make_cpu(
- { 10000, 1, 1, tag_propagation_policy_t::TPP_ALL_TO_ALL });
- auto ann3 = gr::streamops::annotator::make_cpu(
- { 10000, 1, 1, tag_propagation_policy_t::TPP_ALL_TO_ALL });
- auto ann4 = gr::streamops::annotator::make_cpu(
- { 10000, 1, 1, tag_propagation_policy_t::TPP_ALL_TO_ALL });
- auto snk0 = gr::blocks::null_sink::make({});
- auto snk1 = gr::blocks::null_sink::make({});
- auto snk2 = gr::blocks::null_sink::make({});
-
- fg->connect(src, 0, head, 0);
- fg->connect(head, 0, ann0, 0);
-
- fg->connect(ann0, 0, ann1, 0);
- fg->connect(ann0, 1, ann1, 1);
- fg->connect(ann1, 0, ann2, 0);
- fg->connect(ann1, 1, ann3, 0);
- fg->connect(ann1, 2, ann4, 0);
-
- fg->connect(ann2, 0, snk0, 0);
- fg->connect(ann3, 0, snk1, 0);
- fg->connect(ann4, 0, snk2, 0);
-
-
- auto rt = runtime::make();
- rt->initialize(fg);
- rt->start();
- rt->wait();
-
- std::vector<gr::tag_t> tags0 = ann0->data();
- std::vector<gr::tag_t> tags1 = ann1->data();
- std::vector<gr::tag_t> tags2 = ann2->data();
- std::vector<gr::tag_t> tags3 = ann4->data();
- std::vector<gr::tag_t> tags4 = ann4->data();
-
- // The first annotator does not receive any tags from the null sink upstream
- EXPECT_EQ(tags0.size(), (size_t)0);
- EXPECT_EQ(tags1.size(), (size_t)8);
-
- // Make sure the rest all have 12 tags
- EXPECT_EQ(tags2.size(), (size_t)12);
- EXPECT_EQ(tags3.size(), (size_t)12);
- EXPECT_EQ(tags4.size(), (size_t)12);
-}
-
-TEST(SchedulerMTTags, t3)
-{
- size_t N = 40000;
- auto fg = flowgraph::make();
- auto src = gr::blocks::null_source::make({});
- auto head = gr::streamops::head::make_cpu({ N });
- auto ann0 = gr::streamops::annotator::make_cpu(
- { 10000, 2, 2, tag_propagation_policy_t::TPP_ONE_TO_ONE });
- auto ann1 = gr::streamops::annotator::make_cpu(
- { 10000, 1, 1, tag_propagation_policy_t::TPP_ALL_TO_ALL });
- auto ann2 = gr::streamops::annotator::make_cpu(
- { 10000, 1, 1, tag_propagation_policy_t::TPP_ALL_TO_ALL });
- auto ann3 = gr::streamops::annotator::make_cpu(
- { 10000, 1, 1, tag_propagation_policy_t::TPP_ONE_TO_ONE });
- auto ann4 = gr::streamops::annotator::make_cpu(
- { 10000, 1, 1, tag_propagation_policy_t::TPP_ONE_TO_ONE });
- auto snk0 = gr::blocks::null_sink::make({});
- auto snk1 = gr::blocks::null_sink::make({});
-
- fg->connect(src, 0, head, 0);
- fg->connect(head, 0, ann0, 0);
- fg->connect(head, 0, ann0, 1);
-
- fg->connect(ann0, 0, ann1, 0);
- fg->connect(ann0, 1, ann2, 0);
- fg->connect(ann1, 0, ann3, 0);
- fg->connect(ann2, 0, ann4, 0);
-
- fg->connect(ann3, 0, snk0, 0);
- fg->connect(ann4, 0, snk1, 0);
-
- auto sched = schedulers::scheduler_nbt::make();
- sched->add_block_group({ src, head, ann0, ann1, ann2, ann3, ann4, snk0, snk1 });
- auto rt = runtime::make();
- rt->add_scheduler(sched);
- rt->initialize(fg);
- rt->start();
- rt->wait();
- auto tags0 = ann0->data();
- auto tags3 = ann3->data();
- auto tags4 = ann4->data();
-
- // The first annotator does not receive any tags from the null sink upstream
- EXPECT_EQ(tags0.size(), (size_t)0);
- EXPECT_EQ(tags3.size(), (size_t)8);
- EXPECT_EQ(tags4.size(), (size_t)8);
-}
-
-
-#if 0 // TODO Rate Change Blocks
-TEST(SchedulerMTTags, t5)
-{
- int N = 40000;
-
- auto fg = flowgraph::make();
- auto src = gr::blocks::null_source::make({sizeof(int)});
- auto head = gr::streamops::head::make_cpu(sizeof(int), N);
- auto ann0 = gr::streamops::annotator::make_cpu(
- 10000, 1, 2, tag_propagation_policy_t::TPP_ALL_TO_ALL);
- auto ann1 = gr::streamops::annotator::make_cpu(
- 10000, 1, 1, tag_propagation_policy_t::TPP_ALL_TO_ALL);
- auto ann2 = gr::streamops::annotator::make_cpu(
- 10000, 1, 1, tag_propagation_policy_t::TPP_ALL_TO_ALL);
- auto snk0 = gr::blocks::null_sink::make(sizeof(int));
-
- // Rate change blocks
- gr::blocks::keep_one_in_n::sptr dec10(
- gr::blocks::keep_one_in_n::make(sizeof(float), 10));
-
- tb->connect(src, 0, head, 0);
- tb->connect(head, 0, ann0, 0);
- tb->connect(ann0, 0, ann1, 0);
- tb->connect(ann1, 0, dec10, 0);
- tb->connect(dec10, 0, ann2, 0);
- tb->connect(ann2, 0, snk0, 0);
-
- tb->run();
-
- std::vector<gr::tag_t> tags0 = ann0->data();
- std::vector<gr::tag_t> tags1 = ann1->data();
- std::vector<gr::tag_t> tags2 = ann2->data();
-
- // The first annotator does not receive any tags from the null sink upstream
- BOOST_REQUIRE_EQUAL(tags0.size(), (size_t)0);
- BOOST_REQUIRE_EQUAL(tags1.size(), (size_t)4);
- BOOST_REQUIRE_EQUAL(tags2.size(), (size_t)8);
-}
-#endif \ No newline at end of file
diff --git a/test/qa_zmq_buffers.cc b/test/qa_zmq_buffers.cc
deleted file mode 100644
index 5a94039bb..000000000
--- a/test/qa_zmq_buffers.cc
+++ /dev/null
@@ -1,54 +0,0 @@
-#include <gtest/gtest.h>
-
-#include <chrono>
-#include <iostream>
-#include <thread>
-
-#include <gnuradio/blocks/vector_sink.h>
-#include <gnuradio/blocks/vector_source.h>
-#include <gnuradio/buffer_cpu_vmcirc.h>
-#include <gnuradio/buffer_net_zmq.h>
-#include <gnuradio/flowgraph.h>
-#include <gnuradio/math/multiply_const.h>
-#include <gnuradio/runtime.h>
-#include <gnuradio/schedulers/nbt/scheduler_nbt.h>
-#include <gnuradio/streamops/copy.h>
-#include <gnuradio/streamops/head.h>
-
-using namespace gr;
-
-TEST(SchedulerMTTest, ZMQBuffers)
-{
- size_t nsamples = 100000;
- std::vector<float> input_data(nsamples);
- for (size_t i = 0; i < nsamples; i++) {
- input_data[i] = i;
- }
- auto src = blocks::vector_source_f::make({ input_data, true });
- // auto copy1 = streamops::copy::make({sizeof(float)});
- auto copy2 = streamops::copy::make({ sizeof(float) });
- auto hd = streamops::head::make({ nsamples, sizeof(float) });
- auto snk1 = blocks::vector_sink_f::make({});
-
- flowgraph_sptr fg(new flowgraph());
- // fg->connect(src, 0, copy1, 0);
- fg->connect(src, 0, copy2, 0)
- ->set_custom_buffer(buffer_net_zmq_properties::make("127.0.0.1", 1234));
- fg->connect(copy2, 0, hd, 0);
- fg->connect(hd, 0, snk1, 0);
-
- auto rt = runtime::make();
- rt->initialize(fg);
- rt->start();
- rt->wait();
-
- EXPECT_EQ(snk1->data().size(), input_data.size());
- EXPECT_EQ(snk1->data(), input_data);
-
- auto data = snk1->data();
- for (size_t i = 0; i < data.size(); i++) {
- if (input_data[i] != data[i]) {
- std::cout << i << ": " << input_data[i] << " " << data[i] << std::endl;
- }
- }
-}