/* -*- c++ -*- */ /* * Copyright 2015,2016 Free Software Foundation, Inc. * * SPDX-License-Identifier: GPL-3.0-or-later * */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "dvbt_reed_solomon_enc_impl.h" #include <gnuradio/io_signature.h> namespace gr { namespace dtv { static const int rs_init_symsize = 8; static const int rs_init_fcr = 0; // first consecutive root static const int rs_init_prim = 1; // primitive is 1 (alpha) dvbt_reed_solomon_enc::sptr dvbt_reed_solomon_enc::make( int p, int m, int gfpoly, int n, int k, int t, int s, int blocks) { return gnuradio::make_block_sptr<dvbt_reed_solomon_enc_impl>( p, m, gfpoly, n, k, t, s, blocks); } /* * The private constructor */ dvbt_reed_solomon_enc_impl::dvbt_reed_solomon_enc_impl( int p, int m, int gfpoly, int n, int k, int t, int s, int blocks) : block("dvbt_reed_solomon", io_signature::make(1, 1, sizeof(unsigned char) * blocks * (k - s)), io_signature::make(1, 1, sizeof(unsigned char) * blocks * (n - s))), d_n(n), d_k(k), d_s(s), d_blocks(blocks) { d_rs = init_rs_char(rs_init_symsize, gfpoly, rs_init_fcr, rs_init_prim, (n - k)); if (d_rs == NULL) { GR_LOG_FATAL(d_logger, "Reed-Solomon Encoder, cannot allocate memory for d_rs."); throw std::bad_alloc(); } // The full input frame size (d_k) (no need to add in d_s, as the block input is the // pre-shortedned K) d_data = (unsigned char*)malloc(sizeof(unsigned char) * (d_k)); if (d_data == NULL) { GR_LOG_FATAL(d_logger, "Reed-Solomon Encoder, cannot allocate memory for d_data."); free_rs_char(d_rs); throw std::bad_alloc(); } } /* * Our virtual destructor. */ dvbt_reed_solomon_enc_impl::~dvbt_reed_solomon_enc_impl() { free(d_data); free_rs_char(d_rs); } void dvbt_reed_solomon_enc_impl::forecast(int noutput_items, gr_vector_int& ninput_items_required) { ninput_items_required[0] = noutput_items; } void dvbt_reed_solomon_enc_impl::encode(const unsigned char* in, unsigned char* out) { // Shortened Reed-Solomon: prepend zero bytes to message (discarded after encoding) std::memset(d_data, 0, d_s); // This is the number of data bytes we need from the input stream. int shortened_k = d_k - d_s; std::memcpy(&d_data[d_s], in, shortened_k); // Copy input message to output then append Reed-Solomon bits std::memcpy(out, in, shortened_k); encode_rs_char(d_rs, d_data, &out[shortened_k]); } int dvbt_reed_solomon_enc_impl::general_work(int noutput_items, gr_vector_int& ninput_items, gr_vector_const_void_star& input_items, gr_vector_void_star& output_items) { const unsigned char* in = (const unsigned char*)input_items[0]; unsigned char* out = (unsigned char*)output_items[0]; int j = 0; int k = 0; for (int i = 0; i < noutput_items * d_blocks; i++) { encode(in + j, out + k); j += (d_k - d_s); k += (d_n - d_s); } // Tell runtime system how many input items we consumed on // each input stream. consume_each(noutput_items); // Tell runtime system how many output items we produced. return noutput_items; } } /* namespace dtv */ } /* namespace gr */