diff options
-rw-r--r-- | gr-blocks/examples/CMakeLists.txt | 1 | ||||
-rw-r--r-- | gr-blocks/examples/matrix_interleaver.grc | 341 | ||||
-rw-r--r-- | gr-blocks/grc/blocks.tree.yml | 1 | ||||
-rw-r--r-- | gr-blocks/grc/blocks_matrix_interleaver.block.yml | 63 | ||||
-rw-r--r-- | gr-blocks/python/blocks/CMakeLists.txt | 1 | ||||
-rw-r--r-- | gr-blocks/python/blocks/__init__.py | 1 | ||||
-rw-r--r-- | gr-blocks/python/blocks/matrix_interleaver.py | 63 | ||||
-rwxr-xr-x | gr-blocks/python/blocks/qa_matrix_interleaver.py | 62 |
8 files changed, 533 insertions, 0 deletions
diff --git a/gr-blocks/examples/CMakeLists.txt b/gr-blocks/examples/CMakeLists.txt index 4529e7fe62..cf7fd90d24 100644 --- a/gr-blocks/examples/CMakeLists.txt +++ b/gr-blocks/examples/CMakeLists.txt @@ -7,6 +7,7 @@ install( FILES + matrix_interleaver.grc matrix_multiplexer.grc peak_detector2.grc py_snippets_demo.grc diff --git a/gr-blocks/examples/matrix_interleaver.grc b/gr-blocks/examples/matrix_interleaver.grc new file mode 100644 index 0000000000..5358dbe275 --- /dev/null +++ b/gr-blocks/examples/matrix_interleaver.grc @@ -0,0 +1,341 @@ +options: + parameters: + author: Jared Dulmage + category: '[GRC Hier Blocks]' + cmake_opt: '' + comment: '' + copyright: 2020 Caliola Engineering, LLC + description: Matrix interleaver, inputs along rows, outputs along columns + gen_cmake: 'On' + gen_linking: dynamic + generate_options: qt_gui + hier_block_src_path: '.:' + id: matrix_interleaver_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: Block Interleaver Test + window_size: '' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [8, 8] + rotation: 0 + state: enabled + +blocks: +- name: cols + id: variable + parameters: + comment: '' + value: '8' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [8, 215] + rotation: 0 + state: enabled +- name: rows + id: variable + parameters: + comment: '' + value: '4' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [8, 152] + rotation: 0 + state: enabled +- 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: blocks_add_const_vxx_0 + id: blocks_add_const_vxx + parameters: + affinity: '' + alias: '' + comment: Offset for visual + const: '1' + maxoutbuf: '0' + minoutbuf: '0' + type: float + vlen: '1' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [640, 215] + rotation: 0 + state: true +- name: blocks_add_const_vxx_0_0 + id: blocks_add_const_vxx + parameters: + affinity: '' + alias: '' + comment: Offset for visual + const: '1' + maxoutbuf: '0' + minoutbuf: '0' + type: float + vlen: '1' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [640, 318] + rotation: 0 + state: true +- name: blocks_matrix_interleaver_0 + id: blocks_matrix_interleaver + parameters: + affinity: '' + alias: '' + cols: cols + comment: '' + deint: 'False' + maxoutbuf: '0' + minoutbuf: '0' + rows: rows + type: float + vlen: '1' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [447, 199] + rotation: 0 + state: true +- name: blocks_matrix_interleaver_0_0 + id: blocks_matrix_interleaver + parameters: + affinity: '' + alias: '' + cols: cols + comment: '' + deint: 'True' + maxoutbuf: '0' + minoutbuf: '0' + rows: rows + type: float + vlen: '1' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [448, 302] + rotation: 0 + state: true +- name: blocks_stream_to_vector_0 + id: blocks_stream_to_vector + parameters: + affinity: '' + alias: '' + comment: '' + maxoutbuf: '0' + minoutbuf: '0' + num_items: rows * cols + type: float + vlen: '1' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [824, 219] + rotation: 0 + state: true +- name: blocks_stream_to_vector_0_0 + id: blocks_stream_to_vector + parameters: + affinity: '' + alias: '' + comment: '' + maxoutbuf: '0' + minoutbuf: '0' + num_items: rows * cols + type: float + vlen: '1' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [824, 152] + rotation: 0 + state: true +- name: blocks_stream_to_vector_0_1 + id: blocks_stream_to_vector + parameters: + affinity: '' + alias: '' + comment: '' + maxoutbuf: '0' + minoutbuf: '0' + num_items: rows * cols + type: float + vlen: '1' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [824, 283] + rotation: 0 + state: true +- name: blocks_throttle_0 + id: blocks_throttle + parameters: + affinity: '' + alias: '' + comment: '' + ignoretag: 'True' + maxoutbuf: '0' + minoutbuf: '0' + samples_per_second: samp_rate + type: float + vlen: '1' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [452, 148] + rotation: 0 + state: true +- name: blocks_vector_source_x_0 + id: blocks_vector_source_x + parameters: + affinity: '' + alias: '' + comment: '' + maxoutbuf: '0' + minoutbuf: '0' + repeat: 'True' + tags: '[]' + type: float + vector: np.kron(np.ones(cols), np.arange(rows)) + vlen: '1' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [115, 199] + rotation: 0 + state: true +- name: import_0 + id: import + parameters: + alias: '' + comment: '' + imports: import numpy as np + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [300, 15] + rotation: 0 + state: true +- name: qtgui_vector_sink_f_0 + id: qtgui_vector_sink_f + parameters: + affinity: '' + alias: '' + alpha1: '0.4' + alpha10: '1.0' + alpha2: '0.4' + alpha3: '0.4' + alpha4: '1.0' + alpha5: '1.0' + alpha6: '1.0' + alpha7: '1.0' + alpha8: '1.0' + alpha9: '1.0' + autoscale: 'False' + average: '1.0' + color1: '"blue"' + color10: '"dark blue"' + color2: '"red"' + color3: '"green"' + color4: '"black"' + color5: '"cyan"' + color6: '"magenta"' + color7: '"yellow"' + color8: '"dark red"' + color9: '"dark green"' + comment: '' + grid: 'True' + gui_hint: '' + label1: Input + label10: '' + label2: Interleaved + label3: Deinterleaved + label4: '' + label5: '' + label6: '' + label7: '' + label8: '' + label9: '' + maxoutbuf: '0' + minoutbuf: '0' + name: '""' + nconnections: '3' + ref_level: '0' + showports: 'False' + update_time: '0.10' + vlen: rows * cols + width1: '1' + width10: '1' + width2: '1' + width3: '1' + width4: '1' + width5: '1' + width6: '1' + width7: '1' + width8: '1' + width9: '1' + x_axis_label: index + x_start: '0' + x_step: '1.0' + x_units: '""' + y_axis_label: value + y_units: '""' + ymax: max(rows, cols) + 1 + ymin: '-1' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [1040, 159] + rotation: 0 + state: true + +connections: +- [blocks_add_const_vxx_0, '0', blocks_matrix_interleaver_0_0, '0'] +- [blocks_add_const_vxx_0, '0', blocks_stream_to_vector_0, '0'] +- [blocks_add_const_vxx_0_0, '0', blocks_stream_to_vector_0_1, '0'] +- [blocks_matrix_interleaver_0, '0', blocks_add_const_vxx_0, '0'] +- [blocks_matrix_interleaver_0_0, '0', blocks_add_const_vxx_0_0, '0'] +- [blocks_stream_to_vector_0, '0', qtgui_vector_sink_f_0, '1'] +- [blocks_stream_to_vector_0_0, '0', qtgui_vector_sink_f_0, '0'] +- [blocks_stream_to_vector_0_1, '0', qtgui_vector_sink_f_0, '2'] +- [blocks_throttle_0, '0', blocks_stream_to_vector_0_0, '0'] +- [blocks_vector_source_x_0, '0', blocks_matrix_interleaver_0, '0'] +- [blocks_vector_source_x_0, '0', blocks_throttle_0, '0'] + +metadata: + file_format: 1 diff --git a/gr-blocks/grc/blocks.tree.yml b/gr-blocks/grc/blocks.tree.yml index 5fb790efd1..48540f7b72 100644 --- a/gr-blocks/grc/blocks.tree.yml +++ b/gr-blocks/grc/blocks.tree.yml @@ -122,6 +122,7 @@ - blocks_stream_to_vector_decimator - blocks_vector_to_stream - blocks_vector_to_streams + - blocks_matrix_interleaver - blocks_patterned_interleaver - blocks_endian_swap - blocks_vector_insert_x diff --git a/gr-blocks/grc/blocks_matrix_interleaver.block.yml b/gr-blocks/grc/blocks_matrix_interleaver.block.yml new file mode 100644 index 0000000000..d2a664a361 --- /dev/null +++ b/gr-blocks/grc/blocks_matrix_interleaver.block.yml @@ -0,0 +1,63 @@ +id: blocks_matrix_interleaver +label: Matrix Interleaver +flags: [ python ] + +templates: + imports: from gnuradio import blocks + make: |- + blocks.matrix_interleaver( + itemsize=${ type.size } * ${ vlen }, rows=${ rows }, cols=${ cols }, deint=${ deint } + ) + callbacks: + - set_rowsandcols(${ rows }, ${ cols }, ${ deint }) + +parameters: +- id: type + label: IO Type + dtype: enum + options: [complex, float, int, short, byte] + option_attributes: + size: [gr.sizeof_gr_complex, gr.sizeof_float, gr.sizeof_int, gr.sizeof_short, gr.sizeof_char] + hide: part +- id: vlen + label: Vec Length + dtype: int + default: '1' + hide: ${ 'part' if vlen == 1 else 'none' } +- id: rows + label: Rows + dtype: int + default: '1' + hide: none +- id: cols + label: Columns + dtype: int + default: '1' + hide: none +- id: deint + label: Deinterleave + dtype: bool + options: [True, False] + default: False + hide: none + +inputs: +- label: in + dtype: ${ type } + vlen: ${ vlen } + +outputs: +- label: out + dtype: ${ type } + vlen: ${ vlen } + +asserts: +- ${ vlen > 0 } + +documentation: 'Jared Dulmage + + Block interleaver reads inputs into rows and writes outputs by cols + + python/matrix_interleaver.py' + +file_format: 1 diff --git a/gr-blocks/python/blocks/CMakeLists.txt b/gr-blocks/python/blocks/CMakeLists.txt index 25ae7755d5..587c7c7ca2 100644 --- a/gr-blocks/python/blocks/CMakeLists.txt +++ b/gr-blocks/python/blocks/CMakeLists.txt @@ -11,6 +11,7 @@ include(GrPython) GR_PYTHON_INSTALL( FILES __init__.py + matrix_interleaver.py parse_file_metadata.py stream_to_vector_decimator.py msg_pair_to_var.py diff --git a/gr-blocks/python/blocks/__init__.py b/gr-blocks/python/blocks/__init__.py index 4a3bc1ccaf..c9a4b3f756 100644 --- a/gr-blocks/python/blocks/__init__.py +++ b/gr-blocks/python/blocks/__init__.py @@ -25,6 +25,7 @@ from .stream_to_vector_decimator import * from .msg_meta_to_pair import meta_to_pair from .msg_pair_to_var import msg_pair_to_var from .var_to_msg import var_to_msg_pair +from .matrix_interleaver import * #alias old add_vXX and multiply_vXX add_vcc = add_cc diff --git a/gr-blocks/python/blocks/matrix_interleaver.py b/gr-blocks/python/blocks/matrix_interleaver.py new file mode 100644 index 0000000000..26a8e86a6e --- /dev/null +++ b/gr-blocks/python/blocks/matrix_interleaver.py @@ -0,0 +1,63 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# +# Copyright 2021 Caliola Engineering, LLC. +# +# This file is part of GNU Radio +# +# SPDX-License-Identifier: GPL-3.0-or-later +# + +from gnuradio import gr, blocks + +class matrix_interleaver(gr.hier_block2): + """ + Block interleaver writes inputs into conceptual rows of the matrix + and reads outputs by conceptual columns of the matrix. + In deinterleaver mode it writes inputs into conceptual columns + and reads outputs by conceptual rows. + """ + + def __init__(self, itemsize, rows=1, cols=1, deint=False): + gr.hier_block2.__init__( + self, "Matrix Interleaver", + gr.io_signature(1, 1, itemsize), + gr.io_signature(1, 1, itemsize), + ) + + self.itemsize = itemsize + self.set_rowsandcols(rows, cols, deint) + + def set_rowsandcols(self, rows, cols, deint): + self.disconnect_all() + + self.passthrough = None + self.interleaver = None + self.deinterleaver = None + + ################################################## + # Parameters + ################################################## + self.rows = rows + self.cols = cols + self.deint = deint + + ################################################## + # Blocks + ################################################## + # short circuit for unitary rows / columns + if rows == 1 or cols == 1: + self.passthrough = blocks.copy(self.itemsize) + self.connect((self, 0), (self.passthrough, 0), (self, 0)) + return + + self.deinterleaver = blocks.deinterleave(self.itemsize, 1 if deint else cols) + self.interleaver = blocks.interleave(self.itemsize, cols if deint else 1) + + ################################################## + # Connections + ################################################## + self.connect((self, 0), (self.deinterleaver, 0)) + for n in range(rows): + self.connect((self.deinterleaver, n), (self.interleaver, n)) + self.connect((self.interleaver, 0), (self, 0)) diff --git a/gr-blocks/python/blocks/qa_matrix_interleaver.py b/gr-blocks/python/blocks/qa_matrix_interleaver.py new file mode 100755 index 0000000000..d254ef6b55 --- /dev/null +++ b/gr-blocks/python/blocks/qa_matrix_interleaver.py @@ -0,0 +1,62 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# +# Copyright 2021 Caliola Engineering, LLC. +# +# 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 +from matrix_interleaver import matrix_interleaver + +class qa_matrix_interleaver(gr_unittest.TestCase): + + def setUp(self): + self.tb = gr.top_block() + + def tearDown(self): + self.tb = None + + def test_interleave(self): + tb = self.tb + + # set up fg + cols, rows = 4, 10 + vec = sum((cols * [x,] for x in range(rows)), []) + expected = cols * list(range(rows)) + + src = blocks.vector_source_f(vec, False) + itlv = matrix_interleaver(gr.sizeof_float, rows=rows, cols=cols) + snk = blocks.vector_sink_f() + + tb.connect(src, itlv, snk) + tb.run() + result = snk.data() + + # check data + self.assertFloatTuplesAlmostEqual(expected, result) + + def test_deinterleave(self): + tb = self.tb + + # set up fg + cols, rows = 4, 10 + vec = sum((rows * [x,] for x in range(cols)), []) + expected = rows * list(range(cols)) + + src = blocks.vector_source_f(vec, False) + itlv = matrix_interleaver(gr.sizeof_float, rows=rows, cols=cols, deint=True) + snk = blocks.vector_sink_f() + + tb.connect(src, itlv, snk) + tb.run() + result = snk.data() + + # check data + self.assertFloatTuplesAlmostEqual(expected, result) + +if __name__ == '__main__': + gr_unittest.run(qa_matrix_interleaver) |