From 51c504ebb1ca21c5f7071826c1af03e45e391a65 Mon Sep 17 00:00:00 2001 From: Daniel Estévez <daniel@destevez.net> Date: Sun, 6 Jun 2021 11:25:57 +0200 Subject: digital: Add NRZI option to differential en/decoder MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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> --- gr-digital/lib/diff_encoder_bb_impl.cc | 37 +++++++++++++++++++++++++++------- 1 file changed, 30 insertions(+), 7 deletions(-) (limited to 'gr-digital/lib/diff_encoder_bb_impl.cc') 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; -- cgit v1.2.3