summaryrefslogtreecommitdiff
path: root/gr-digital/lib/diff_encoder_bb_impl.cc
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/lib/diff_encoder_bb_impl.cc
parent16d1b0215d59c52009b09867fbfce0b4c3585add (diff)
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/lib/diff_encoder_bb_impl.cc')
-rw-r--r--gr-digital/lib/diff_encoder_bb_impl.cc37
1 files changed, 30 insertions, 7 deletions
diff --git a/gr-digital/lib/diff_encoder_bb_impl.cc b/gr-digital/lib/diff_encoder_bb_impl.cc
index fb14504bc2..d14e7c28e6 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;