aboutsummaryrefslogtreecommitdiffstats
path: root/gr-digital
diff options
context:
space:
mode:
authorDaniel Estévez <daniel@destevez.net>2021-06-06 11:25:57 +0200
committermormj <34754695+mormj@users.noreply.github.com>2021-06-12 12:01:12 -0400
commit51c504ebb1ca21c5f7071826c1af03e45e391a65 (patch)
treedbabf0b0b825f834cff2067248d193fe8d951dd8 /gr-digital
parentsoapy: less surprising bool cast (diff)
downloadgnuradio-51c504ebb1ca21c5f7071826c1af03e45e391a65.tar.xz
gnuradio-51c504ebb1ca21c5f7071826c1af03e45e391a65.zip
digital: Add NRZI option to differential en/decoder
This adds an option to the differential encoder an decoder blocks to perform NRZI encoding and decoding. NRZI only makes sense with a modulus of 2, so the blocks constructors will throw and exception if passed nrzi = true and a modulus different from 2. The GRC blocks handle this by hiding the modulus field if the user selects NRZI encoding. A new unit test for the NRZI version of the blocks is added. Besides checking that encode plus decode gives the original, this test also compares the C++ implementation results against a Numpy implementation. Additionally, a faster implementation of differential encoding/ decoding for modulus 2 is included here. Signed-off-by: Daniel Estévez <daniel@destevez.net>
Diffstat (limited to 'gr-digital')
-rw-r--r--gr-digital/grc/digital_diff_decoder_bb.block.yml16
-rw-r--r--gr-digital/grc/digital_diff_encoder_bb.block.yml16
-rw-r--r--gr-digital/include/gnuradio/digital/CMakeLists.txt1
-rw-r--r--gr-digital/include/gnuradio/digital/diff_coding_type.h26
-rw-r--r--gr-digital/include/gnuradio/digital/diff_decoder_bb.h6
-rw-r--r--gr-digital/include/gnuradio/digital/diff_encoder_bb.h6
-rw-r--r--gr-digital/lib/diff_decoder_bb_impl.cc33
-rw-r--r--gr-digital/lib/diff_decoder_bb_impl.h7
-rw-r--r--gr-digital/lib/diff_encoder_bb_impl.cc37
-rw-r--r--gr-digital/lib/diff_encoder_bb_impl.h5
-rw-r--r--gr-digital/python/digital/bindings/CMakeLists.txt1
-rw-r--r--gr-digital/python/digital/bindings/diff_coding_type_python.cc40
-rw-r--r--gr-digital/python/digital/bindings/diff_decoder_bb_python.cc3
-rw-r--r--gr-digital/python/digital/bindings/diff_encoder_bb_python.cc3
-rw-r--r--gr-digital/python/digital/bindings/docstrings/diff_coding_type_pydoc_template.h15
-rw-r--r--gr-digital/python/digital/bindings/python_bindings.cc2
-rwxr-xr-xgr-digital/python/digital/qa_diff_encoder_nrzi.py72
17 files changed, 265 insertions, 24 deletions
diff --git a/gr-digital/grc/digital_diff_decoder_bb.block.yml b/gr-digital/grc/digital_diff_decoder_bb.block.yml
index 4b94c38b2..ddfbe8192 100644
--- a/gr-digital/grc/digital_diff_decoder_bb.block.yml
+++ b/gr-digital/grc/digital_diff_decoder_bb.block.yml
@@ -3,9 +3,19 @@ label: Differential Decoder
flags: [ python, cpp ]
parameters:
+- id: coding
+ label: Coding
+ dtype: enum
+ default: digital.DIFF_DIFFERENTIAL
+ options: [digital.DIFF_DIFFERENTIAL, digital.DIFF_NRZI]
+ option_labels: [Differential, NRZI]
+ option_attributes:
+ hide_modulus: [none, all]
+ force_modulus: [-1, 2]
- id: modulus
label: Modulus
dtype: int
+ hide: ${ coding.hide_modulus }
inputs:
- domain: stream
@@ -17,13 +27,15 @@ outputs:
templates:
imports: from gnuradio import digital
- make: digital.diff_decoder_bb(${modulus})
+ make: digital.diff_decoder_bb(${modulus if coding.force_modulus == '-1' else coding.force_modulus}, ${coding})
cpp_templates:
includes: ['#include <gnuradio/digital/diff_decoder_bb.h>']
declarations: 'digital::diff_decoder_bb::sptr ${id};'
make: |-
- this->${id} = digital::diff_decoder_bb::make(${modulus});
+ this->${id} = digital::diff_decoder_bb::make(${modulus if coding.force_modulus == '-1' else coding.force_modulus}, ${coding});
link: ['gnuradio-digital']
+ translations:
+ digital.DIFF: 'digital::DIFF'
file_format: 1
diff --git a/gr-digital/grc/digital_diff_encoder_bb.block.yml b/gr-digital/grc/digital_diff_encoder_bb.block.yml
index b9107e84b..02e888dfd 100644
--- a/gr-digital/grc/digital_diff_encoder_bb.block.yml
+++ b/gr-digital/grc/digital_diff_encoder_bb.block.yml
@@ -3,9 +3,19 @@ label: Differential Encoder
flags: [ python, cpp ]
parameters:
+- id: coding
+ label: Coding
+ dtype: enum
+ default: digital.DIFF_DIFFERENTIAL
+ options: [digital.DIFF_DIFFERENTIAL, digital.DIFF_NRZI]
+ option_labels: [Differential, NRZI]
+ option_attributes:
+ hide_modulus: [none, all]
+ force_modulus: [-1, 2]
- id: modulus
label: Modulus
dtype: int
+ hide: ${ coding.hide_modulus }
inputs:
- domain: stream
@@ -17,13 +27,15 @@ outputs:
templates:
imports: from gnuradio import digital
- make: digital.diff_encoder_bb(${modulus})
+ make: digital.diff_encoder_bb(${modulus if coding.force_modulus == '-1' else coding.force_modulus}, ${coding})
cpp_templates:
includes: ['#include <gnuradio/digital/diff_encoder_bb.h>']
declarations: 'digital::diff_encoder_bb::sptr ${id};'
make: |-
- this->${id} = digital::diff_encoder_bb::make(${modulus});
+ this->${id} = digital::diff_encoder_bb::make(${modulus if coding.force_modulus == '-1' else coding.force_modulus}, ${coding});
link: ['gnuradio-digital']
+ translations:
+ digital.DIFF: 'digital::DIFF'
file_format: 1
diff --git a/gr-digital/include/gnuradio/digital/CMakeLists.txt b/gr-digital/include/gnuradio/digital/CMakeLists.txt
index 4d50ecedb..a4c6b914d 100644
--- a/gr-digital/include/gnuradio/digital/CMakeLists.txt
+++ b/gr-digital/include/gnuradio/digital/CMakeLists.txt
@@ -37,6 +37,7 @@ install(FILES
crc32_async_bb.h
decision_feedback_equalizer.h
descrambler_bb.h
+ diff_coding_type.h
diff_decoder_bb.h
diff_encoder_bb.h
diff_phasor_cc.h
diff --git a/gr-digital/include/gnuradio/digital/diff_coding_type.h b/gr-digital/include/gnuradio/digital/diff_coding_type.h
new file mode 100644
index 000000000..9fa93d5ce
--- /dev/null
+++ b/gr-digital/include/gnuradio/digital/diff_coding_type.h
@@ -0,0 +1,26 @@
+/* -*- c++ -*- */
+/*
+ * Copyright (C) 2021 Daniel Estevez <daniel@destevez.net>
+ *
+ * This file is part of GNU Radio
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#ifndef INCLUDED_DIGITAL_DIFF_CODING_TYPE_H
+#define INCLUDED_DIGITAL_DIFF_CODING_TYPE_H
+
+namespace gr {
+namespace digital {
+
+// Differential coding types
+enum diff_coding_type {
+ DIFF_DIFFERENTIAL = 0, // Standard differential coding x[n] - x[n-1] % M
+ DIFF_NRZI = 1, // NRZI coding
+};
+
+} /* namespace digital */
+} /* namespace gr */
+
+#endif /* INCLUDED_DIGITAL_DIFF_CODING_TYPE_H */
diff --git a/gr-digital/include/gnuradio/digital/diff_decoder_bb.h b/gr-digital/include/gnuradio/digital/diff_decoder_bb.h
index e92e001dd..816c0a1c1 100644
--- a/gr-digital/include/gnuradio/digital/diff_decoder_bb.h
+++ b/gr-digital/include/gnuradio/digital/diff_decoder_bb.h
@@ -1,6 +1,7 @@
/* -*- c++ -*- */
/*
* Copyright 2006,2012 Free Software Foundation, Inc.
+ * Copyright 2021 Daniel Estevez <daniel@destevez.net>
*
* This file is part of GNU Radio
*
@@ -12,6 +13,7 @@
#define INCLUDED_GR_DIFF_DECODER_BB_H
#include <gnuradio/digital/api.h>
+#include <gnuradio/digital/diff_coding_type.h>
#include <gnuradio/sync_block.h>
namespace gr {
@@ -35,8 +37,10 @@ public:
* Make a differential decoder block.
*
* \param modulus Modulus of code's alphabet
+ * \param coding Differential coding type
*/
- static sptr make(unsigned int modulus);
+ static sptr make(unsigned int modulus,
+ enum diff_coding_type coding = DIFF_DIFFERENTIAL);
};
} /* namespace digital */
diff --git a/gr-digital/include/gnuradio/digital/diff_encoder_bb.h b/gr-digital/include/gnuradio/digital/diff_encoder_bb.h
index 183be3287..b00445ac2 100644
--- a/gr-digital/include/gnuradio/digital/diff_encoder_bb.h
+++ b/gr-digital/include/gnuradio/digital/diff_encoder_bb.h
@@ -1,6 +1,7 @@
/* -*- c++ -*- */
/*
* Copyright 2006,2012 Free Software Foundation, Inc.
+ * Copyright 2021 Daniel Estevez <daniel@destevez.net>
*
* This file is part of GNU Radio
*
@@ -12,6 +13,7 @@
#define INCLUDED_GR_DIFF_ENCODER_BB_H
#include <gnuradio/digital/api.h>
+#include <gnuradio/digital/diff_coding_type.h>
#include <gnuradio/sync_block.h>
namespace gr {
@@ -35,8 +37,10 @@ public:
* Make a differential encoder block.
*
* \param modulus Modulus of code's alphabet
+ * \param coding Differential coding type
*/
- static sptr make(unsigned int modulus);
+ static sptr make(unsigned int modulus,
+ enum diff_coding_type coding = DIFF_DIFFERENTIAL);
};
} /* namespace digital */
diff --git a/gr-digital/lib/diff_decoder_bb_impl.cc b/gr-digital/lib/diff_decoder_bb_impl.cc
index 95e5c2e9c..f9b093400 100644
--- a/gr-digital/lib/diff_decoder_bb_impl.cc
+++ b/gr-digital/lib/diff_decoder_bb_impl.cc
@@ -1,6 +1,7 @@
/* -*- c++ -*- */
/*
* Copyright 2006,2010,2012 Free Software Foundation, Inc.
+ * Copyright 2021 Daniel Estevez <daniel@destevez.net>
*
* This file is part of GNU Radio
*
@@ -15,19 +16,27 @@
#include "diff_decoder_bb_impl.h"
#include <gnuradio/io_signature.h>
+#include <stdexcept>
+
namespace gr {
namespace digital {
-diff_decoder_bb::sptr diff_decoder_bb::make(unsigned int modulus)
+diff_decoder_bb::sptr diff_decoder_bb::make(unsigned int modulus,
+ enum diff_coding_type coding)
{
- return gnuradio::make_block_sptr<diff_decoder_bb_impl>(modulus);
+ return gnuradio::make_block_sptr<diff_decoder_bb_impl>(modulus, coding);
}
-diff_decoder_bb_impl::diff_decoder_bb_impl(unsigned int modulus)
+diff_decoder_bb_impl::diff_decoder_bb_impl(unsigned int modulus,
+ enum diff_coding_type coding)
: sync_block("diff_decoder_bb",
io_signature::make(1, 1, sizeof(unsigned char)),
io_signature::make(1, 1, sizeof(unsigned char))),
- d_modulus(modulus)
+ d_modulus(modulus),
+ d_coding(coding)
{
+ if (d_coding == DIFF_NRZI && d_modulus != 2) {
+ throw std::runtime_error("diff_decoder: NRZI only supported with modulus 2");
+ }
set_history(2); // need to look at two inputs
}
@@ -43,8 +52,20 @@ int diff_decoder_bb_impl::work(int noutput_items,
unsigned modulus = d_modulus;
- for (int i = 0; i < noutput_items; i++) {
- out[i] = (in[i] - in[i - 1]) % modulus;
+ if (d_coding == DIFF_NRZI) {
+ for (int i = 0; i < noutput_items; i++) {
+ out[i] = ~(in[i] ^ in[i - 1]) & 1;
+ }
+ } else if (modulus == 2) {
+ // optimized implementation for modulus 2
+ for (int i = 0; i < noutput_items; i++) {
+ out[i] = (in[i] ^ in[i - 1]) & 1;
+ }
+ } else {
+ // implementation for modulus != 2
+ for (int i = 0; i < noutput_items; i++) {
+ out[i] = (in[i] - in[i - 1]) % modulus;
+ }
}
return noutput_items;
diff --git a/gr-digital/lib/diff_decoder_bb_impl.h b/gr-digital/lib/diff_decoder_bb_impl.h
index 10688f427..d73a5fe7b 100644
--- a/gr-digital/lib/diff_decoder_bb_impl.h
+++ b/gr-digital/lib/diff_decoder_bb_impl.h
@@ -1,6 +1,7 @@
/* -*- c++ -*- */
/*
* Copyright 2006,2012 Free Software Foundation, Inc.
+ * Copyright 2021 Daniel Estevez <daniel@destevez.net>
*
* This file is part of GNU Radio
*
@@ -20,7 +21,8 @@ namespace digital {
class diff_decoder_bb_impl : public diff_decoder_bb
{
public:
- diff_decoder_bb_impl(unsigned int modulus);
+ diff_decoder_bb_impl(unsigned int modulus,
+ enum diff_coding_type coding = DIFF_DIFFERENTIAL);
~diff_decoder_bb_impl() override;
int work(int noutput_items,
@@ -28,7 +30,8 @@ public:
gr_vector_void_star& output_items) override;
private:
- unsigned int d_modulus;
+ const unsigned int d_modulus;
+ const enum diff_coding_type d_coding;
};
} /* namespace digital */
diff --git a/gr-digital/lib/diff_encoder_bb_impl.cc b/gr-digital/lib/diff_encoder_bb_impl.cc
index fb14504bc..d14e7c28e 100644
--- a/gr-digital/lib/diff_encoder_bb_impl.cc
+++ b/gr-digital/lib/diff_encoder_bb_impl.cc
@@ -1,6 +1,7 @@
/* -*- c++ -*- */
/*
* Copyright 2006,2010,2012 Free Software Foundation, Inc.
+ * Copyright 2021 Daniel Estevez <daniel@destevez.net>
*
* This file is part of GNU Radio
*
@@ -15,21 +16,29 @@
#include "diff_encoder_bb_impl.h"
#include <gnuradio/io_signature.h>
+#include <stdexcept>
+
namespace gr {
namespace digital {
-diff_encoder_bb::sptr diff_encoder_bb::make(unsigned int modulus)
+diff_encoder_bb::sptr diff_encoder_bb::make(unsigned int modulus,
+ enum diff_coding_type coding)
{
- return gnuradio::make_block_sptr<diff_encoder_bb_impl>(modulus);
+ return gnuradio::make_block_sptr<diff_encoder_bb_impl>(modulus, coding);
}
-diff_encoder_bb_impl::diff_encoder_bb_impl(unsigned int modulus)
+diff_encoder_bb_impl::diff_encoder_bb_impl(unsigned int modulus,
+ enum diff_coding_type coding)
: sync_block("diff_encoder_bb",
io_signature::make(1, 1, sizeof(unsigned char)),
io_signature::make(1, 1, sizeof(unsigned char))),
d_last_out(0),
- d_modulus(modulus)
+ d_modulus(modulus),
+ d_coding(coding)
{
+ if (d_coding == DIFF_NRZI && d_modulus != 2) {
+ throw std::runtime_error("diff_encoder: NRZI only supported with modulus 2");
+ }
}
diff_encoder_bb_impl::~diff_encoder_bb_impl() {}
@@ -43,9 +52,23 @@ int diff_encoder_bb_impl::work(int noutput_items,
unsigned last_out = d_last_out;
- for (int i = 0; i < noutput_items; i++) {
- out[i] = (in[i] + last_out) % d_modulus;
- last_out = out[i];
+ if (d_coding == DIFF_NRZI) {
+ for (int i = 0; i < noutput_items; i++) {
+ out[i] = ~(in[i] ^ last_out) & 1;
+ last_out = out[i];
+ }
+ } else if (d_modulus == 2) {
+ // optimized implementation for modulus 2
+ for (int i = 0; i < noutput_items; i++) {
+ out[i] = (in[i] ^ last_out) & 1;
+ last_out = out[i];
+ }
+ } else {
+ // implementation for modulus != 2
+ for (int i = 0; i < noutput_items; i++) {
+ out[i] = (in[i] + last_out) % d_modulus;
+ last_out = out[i];
+ }
}
d_last_out = last_out;
diff --git a/gr-digital/lib/diff_encoder_bb_impl.h b/gr-digital/lib/diff_encoder_bb_impl.h
index ed8ead033..03d3f83a1 100644
--- a/gr-digital/lib/diff_encoder_bb_impl.h
+++ b/gr-digital/lib/diff_encoder_bb_impl.h
@@ -1,6 +1,7 @@
/* -*- c++ -*- */
/*
* Copyright 2006,2012 Free Software Foundation, Inc.
+ * Copyright 2021 Daniel Estevez <daniel@destevez.net>
*
* This file is part of GNU Radio
*
@@ -19,7 +20,8 @@ namespace digital {
class diff_encoder_bb_impl : public diff_encoder_bb
{
public:
- diff_encoder_bb_impl(unsigned int modulus);
+ diff_encoder_bb_impl(unsigned int modulus,
+ enum diff_coding_type coding = DIFF_DIFFERENTIAL);
~diff_encoder_bb_impl() override;
int work(int noutput_items,
@@ -29,6 +31,7 @@ public:
private:
unsigned int d_last_out;
const unsigned int d_modulus;
+ const enum diff_coding_type d_coding;
};
} /* namespace digital */
diff --git a/gr-digital/python/digital/bindings/CMakeLists.txt b/gr-digital/python/digital/bindings/CMakeLists.txt
index 4d24678ec..762769419 100644
--- a/gr-digital/python/digital/bindings/CMakeLists.txt
+++ b/gr-digital/python/digital/bindings/CMakeLists.txt
@@ -32,6 +32,7 @@ list(APPEND digital_python_files
crc32_bb_python.cc
decision_feedback_equalizer_python.cc
descrambler_bb_python.cc
+ diff_coding_type_python.cc
diff_decoder_bb_python.cc
diff_encoder_bb_python.cc
diff_phasor_cc_python.cc
diff --git a/gr-digital/python/digital/bindings/diff_coding_type_python.cc b/gr-digital/python/digital/bindings/diff_coding_type_python.cc
new file mode 100644
index 000000000..5663b2712
--- /dev/null
+++ b/gr-digital/python/digital/bindings/diff_coding_type_python.cc
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2021 Daniel Estevez <daniel@destevez.net>
+ *
+ * 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(diff_coding_type.h) */
+/* BINDTOOL_HEADER_FILE_HASH(d2a67d2eacf4d643b8df9d240a971837) */
+/***********************************************************************************/
+
+#include <pybind11/complex.h>
+#include <pybind11/pybind11.h>
+#include <pybind11/stl.h>
+
+namespace py = pybind11;
+
+#include <gnuradio/digital/diff_coding_type.h>
+// pydoc.h is automatically generated in the build directory
+#include <diff_coding_type_pydoc.h>
+
+void bind_diff_coding_type(py::module& m)
+{
+
+
+ py::enum_<::gr::digital::diff_coding_type>(m, "diff_coding_type")
+ .value("DIFF_DIFFERENTIAL", ::gr::digital::DIFF_DIFFERENTIAL) // 0
+ .value("DIFF_NRZI", ::gr::digital::DIFF_NRZI) // 1
+ .export_values();
+
+ py::implicitly_convertible<int, ::gr::digital::diff_coding_type>();
+}
diff --git a/gr-digital/python/digital/bindings/diff_decoder_bb_python.cc b/gr-digital/python/digital/bindings/diff_decoder_bb_python.cc
index f7fb6b094..a5628fb37 100644
--- a/gr-digital/python/digital/bindings/diff_decoder_bb_python.cc
+++ b/gr-digital/python/digital/bindings/diff_decoder_bb_python.cc
@@ -14,7 +14,7 @@
/* BINDTOOL_GEN_AUTOMATIC(0) */
/* BINDTOOL_USE_PYGCCXML(0) */
/* BINDTOOL_HEADER_FILE(diff_decoder_bb.h) */
-/* BINDTOOL_HEADER_FILE_HASH(3814f3ba5b3a9425eae5611e1a4876ec) */
+/* BINDTOOL_HEADER_FILE_HASH(92f143bcb3f067b3cdf8292a75956d31) */
/***********************************************************************************/
#include <pybind11/complex.h>
@@ -41,6 +41,7 @@ void bind_diff_decoder_bb(py::module& m)
.def(py::init(&diff_decoder_bb::make),
py::arg("modulus"),
+ py::arg("nrzi") = ::gr::digital::DIFF_DIFFERENTIAL,
D(diff_decoder_bb, make))
diff --git a/gr-digital/python/digital/bindings/diff_encoder_bb_python.cc b/gr-digital/python/digital/bindings/diff_encoder_bb_python.cc
index d27c5feec..817b2e3da 100644
--- a/gr-digital/python/digital/bindings/diff_encoder_bb_python.cc
+++ b/gr-digital/python/digital/bindings/diff_encoder_bb_python.cc
@@ -14,7 +14,7 @@
/* BINDTOOL_GEN_AUTOMATIC(0) */
/* BINDTOOL_USE_PYGCCXML(0) */
/* BINDTOOL_HEADER_FILE(diff_encoder_bb.h) */
-/* BINDTOOL_HEADER_FILE_HASH(e817d23aac894b3563101df2958577de) */
+/* BINDTOOL_HEADER_FILE_HASH(866ae99d6fc12353e8d45ba2424bcecd) */
/***********************************************************************************/
#include <pybind11/complex.h>
@@ -41,6 +41,7 @@ void bind_diff_encoder_bb(py::module& m)
.def(py::init(&diff_encoder_bb::make),
py::arg("modulus"),
+ py::arg("coding") = ::gr::digital::DIFF_DIFFERENTIAL,
D(diff_encoder_bb, make))
diff --git a/gr-digital/python/digital/bindings/docstrings/diff_coding_type_pydoc_template.h b/gr-digital/python/digital/bindings/docstrings/diff_coding_type_pydoc_template.h
new file mode 100644
index 000000000..84c1cb810
--- /dev/null
+++ b/gr-digital/python/digital/bindings/docstrings/diff_coding_type_pydoc_template.h
@@ -0,0 +1,15 @@
+/*
+ * Copyright 2020 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+#include "pydoc_macros.h"
+#define D(...) DOC(gr, digital, __VA_ARGS__)
+/*
+ This file contains placeholders for docstrings for the Python bindings.
+ Do not edit! These were automatically extracted during the binding process
+ and will be overwritten during the build process
+ */
diff --git a/gr-digital/python/digital/bindings/python_bindings.cc b/gr-digital/python/digital/bindings/python_bindings.cc
index 830902679..0eabcf63d 100644
--- a/gr-digital/python/digital/bindings/python_bindings.cc
+++ b/gr-digital/python/digital/bindings/python_bindings.cc
@@ -42,6 +42,7 @@ void bind_crc32_async_bb(py::module&);
void bind_crc32_bb(py::module&);
void bind_decision_feedback_equalizer(py::module&);
void bind_descrambler_bb(py::module&);
+void bind_diff_coding_type(py::module&);
void bind_diff_decoder_bb(py::module&);
void bind_diff_encoder_bb(py::module&);
void bind_diff_phasor_cc(py::module&);
@@ -143,6 +144,7 @@ PYBIND11_MODULE(digital_python, m)
bind_crc32_bb(m);
bind_decision_feedback_equalizer(m);
bind_descrambler_bb(m);
+ bind_diff_coding_type(m);
bind_diff_decoder_bb(m);
bind_diff_encoder_bb(m);
bind_diff_phasor_cc(m);
diff --git a/gr-digital/python/digital/qa_diff_encoder_nrzi.py b/gr-digital/python/digital/qa_diff_encoder_nrzi.py
new file mode 100755
index 000000000..179728809
--- /dev/null
+++ b/gr-digital/python/digital/qa_diff_encoder_nrzi.py
@@ -0,0 +1,72 @@
+#!/usr/bin/env python
+#
+# Copyright 2020-2021 Daniel Estevez <daniel@destevez.net>
+#
+# This file is part of GNU Radio
+#
+# SPDX-License-Identifier: GPL-3.0-or-later
+#
+#
+
+from gnuradio import gr, gr_unittest, digital, blocks
+import numpy as np
+
+
+class test_nrzi(gr_unittest.TestCase):
+ def setUp(self):
+ test_size = 256
+ self.data = np.random.randint(0, 2, test_size, dtype='uint8')
+ self.source = blocks.vector_source_b(self.data, False, 1, [])
+ self.sink = blocks.vector_sink_b(1, 0)
+ self.tb = gr.top_block()
+
+ def tearDown(self):
+ self.tb = None
+ del(self.data)
+ del(self.source)
+ del(self.sink)
+
+ def test_encode(self):
+ """Performs NRZI encode and checks the result"""
+ encoder = digital.diff_encoder_bb(2, digital.DIFF_NRZI)
+
+ self.tb.connect(self.source, encoder, self.sink)
+ self.tb.start()
+ self.tb.wait()
+
+ expected = np.cumsum((1 ^ self.data) & 1) & 1
+
+ np.testing.assert_equal(
+ self.sink.data(), expected,
+ 'NRZI encode output does not match expected result')
+
+ def test_decode(self):
+ """Performs NRZI decode and checks the result"""
+ decoder = digital.diff_decoder_bb(2, digital.DIFF_NRZI)
+
+ self.tb.connect(self.source, decoder, self.sink)
+ self.tb.start()
+ self.tb.wait()
+
+ expected = self.data[1:] ^ self.data[:-1] ^ 1
+
+ np.testing.assert_equal(
+ self.sink.data()[1:], expected,
+ 'NRZI decode output does not match expected result')
+
+ def test_encode_decode(self):
+ """Performs NRZI encode and decode and checks the result"""
+ encoder = digital.diff_encoder_bb(2, digital.DIFF_NRZI)
+ decoder = digital.diff_decoder_bb(2, digital.DIFF_NRZI)
+
+ self.tb.connect(self.source, encoder, decoder, self.sink)
+ self.tb.start()
+ self.tb.wait()
+
+ np.testing.assert_equal(
+ self.sink.data(), self.data,
+ 'NRZI encoded and decoded output does not match input')
+
+
+if __name__ == '__main__':
+ gr_unittest.run(test_nrzi)