2021-03-07 12:46:25 +01:00
|
|
|
/* -*- c++ -*- */
|
|
|
|
|
/*
|
|
|
|
|
* Copyright 2013-2014 Free Software Foundation, Inc.
|
|
|
|
|
*
|
|
|
|
|
* This file is part of GNU Radio
|
|
|
|
|
*
|
|
|
|
|
* SPDX-License-Identifier: GPL-3.0-or-later
|
|
|
|
|
*
|
|
|
|
|
*/
|
|
|
|
|
|
2021-03-31 12:16:38 +02:00
|
|
|
#pragma once
|
2021-03-07 12:46:25 +01:00
|
|
|
|
|
|
|
|
#include <memory>
|
|
|
|
|
#include <string>
|
|
|
|
|
#include <volk/volk_alloc.hh>
|
|
|
|
|
|
2021-03-31 12:16:38 +02:00
|
|
|
namespace fec
|
2021-03-07 12:46:25 +01:00
|
|
|
{
|
|
|
|
|
|
2021-03-31 12:16:38 +02:00
|
|
|
/*!
|
2021-03-07 12:46:25 +01:00
|
|
|
* \brief Parent class for FECAPI objects.
|
|
|
|
|
*
|
|
|
|
|
* \ingroup error_coding_blk
|
|
|
|
|
*
|
|
|
|
|
* \details
|
|
|
|
|
*
|
|
|
|
|
* Parent of a decoder variable class for FECAPI that will fit
|
|
|
|
|
* into the gr::fec::decoder block to handle FEC decoding. This
|
|
|
|
|
* class provides the basic information required to fit into the
|
|
|
|
|
* FECAPI structure. It provides information about input and
|
|
|
|
|
* output data types, potential data conversions, and a few other
|
|
|
|
|
* parameters useful to establish the decoder's behavior.
|
|
|
|
|
*
|
|
|
|
|
* We create objects from FECAPI-derived classes to go into the
|
|
|
|
|
* actual GNU Radio decoder block. Each object contains its own
|
|
|
|
|
* state and so there should be a one-to-one mapping of an FECAPI
|
|
|
|
|
* object and a GR decoder block. Sharing these objects is not
|
|
|
|
|
* guaranteed to be thread-safe.
|
|
|
|
|
*
|
|
|
|
|
* This is a pure virtual class and must be derived from by a
|
|
|
|
|
* child class.
|
|
|
|
|
*
|
|
|
|
|
* \sa gr::fec::code::cc_decoder
|
|
|
|
|
* \sa gr::fec::code::ccsds_decoder
|
|
|
|
|
*/
|
2021-03-31 12:16:38 +02:00
|
|
|
class generic_decoder
|
|
|
|
|
{
|
|
|
|
|
protected:
|
|
|
|
|
//gr::logger_ptr d_logger;
|
|
|
|
|
volk::vector<uint8_t> d_buffer;
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
friend class decoder;
|
|
|
|
|
virtual void generic_work(void *inbuffer, void *outbuffer) = 0;
|
|
|
|
|
int continuous_work(uint8_t *in, int size, uint8_t *out);
|
|
|
|
|
static int base_unique_id;
|
|
|
|
|
int my_id;
|
|
|
|
|
int unique_id();
|
|
|
|
|
std::string d_name;
|
|
|
|
|
//std::string alias() { return (boost::format("%s%d") % d_name % unique_id()).str(); }
|
2021-04-06 18:53:38 +02:00
|
|
|
void clear()
|
|
|
|
|
{
|
|
|
|
|
d_buffer.clear();
|
|
|
|
|
}
|
2021-03-31 12:16:38 +02:00
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
typedef std::shared_ptr<generic_decoder> sptr;
|
|
|
|
|
|
|
|
|
|
generic_decoder(void){};
|
|
|
|
|
generic_decoder(std::string name);
|
|
|
|
|
virtual ~generic_decoder();
|
|
|
|
|
|
|
|
|
|
/*!
|
2021-03-07 12:46:25 +01:00
|
|
|
* Returns the rate of the code. For every r input bits, there
|
|
|
|
|
* is 1 output bit, so the rate is 1/r. Used for setting things
|
|
|
|
|
* like the encoder block's relative rate.
|
|
|
|
|
*
|
|
|
|
|
* This function MUST be reimplemented by the child class.
|
|
|
|
|
*/
|
2021-03-31 12:16:38 +02:00
|
|
|
virtual double rate() = 0;
|
2021-03-07 12:46:25 +01:00
|
|
|
|
2021-03-31 12:16:38 +02:00
|
|
|
/*!
|
2021-03-07 12:46:25 +01:00
|
|
|
* Returns the input size in items that the decoder object uses
|
|
|
|
|
* to decode a full frame. Often, this number is the number of
|
|
|
|
|
* bits per frame if the input format is unpacked. If the block
|
|
|
|
|
* expects packed bytes, then this value should be the number of
|
|
|
|
|
* bytes (number of bits / 8) per input frame.
|
|
|
|
|
*
|
|
|
|
|
* The child class MUST implement this function.
|
|
|
|
|
*/
|
2021-03-31 12:16:38 +02:00
|
|
|
virtual int get_input_size() = 0;
|
2021-03-07 12:46:25 +01:00
|
|
|
|
2021-03-31 12:16:38 +02:00
|
|
|
/*!
|
2021-03-07 12:46:25 +01:00
|
|
|
* Returns the output size in items that the decoder object
|
|
|
|
|
* produces after decoding a full frame. Often, this number is
|
|
|
|
|
* the number of bits in the outputted frame if the input format
|
|
|
|
|
* is unpacked. If the block produces packed bytes, then this
|
|
|
|
|
* value should be the number of bytes (number of bits / 8) per
|
|
|
|
|
* frame produced. This value is generally something like
|
|
|
|
|
* get_input_size()/R for a 1/R rate code.
|
|
|
|
|
*
|
|
|
|
|
* The child class MUST implement this function.
|
|
|
|
|
*/
|
2021-03-31 12:16:38 +02:00
|
|
|
virtual int get_output_size() = 0;
|
2021-03-07 12:46:25 +01:00
|
|
|
|
2021-03-31 12:16:38 +02:00
|
|
|
/*!
|
2021-03-07 12:46:25 +01:00
|
|
|
* Sets up history for the decoder when the decoder is required
|
|
|
|
|
* to look ahead in the data stream in order to finish
|
|
|
|
|
* its processing.
|
|
|
|
|
*
|
|
|
|
|
* The child class MAY implement this function. If not
|
|
|
|
|
* reimplemented, it returns 0.
|
|
|
|
|
*/
|
2021-03-31 12:16:38 +02:00
|
|
|
virtual int get_history();
|
2021-03-07 12:46:25 +01:00
|
|
|
|
2021-03-31 12:16:38 +02:00
|
|
|
/*!
|
2021-03-07 12:46:25 +01:00
|
|
|
* Some decoders require the input items to float around a
|
|
|
|
|
* particular soft value. We can set that floating value by
|
|
|
|
|
* setting this value to return some non-zero number.
|
|
|
|
|
*
|
|
|
|
|
* The fec.extended_decoder block will use this to create an
|
|
|
|
|
* add_const_ff block before the decoder block to adjust all
|
|
|
|
|
* input samples appropriately.
|
|
|
|
|
*
|
|
|
|
|
* The child class MAY implement this function. If not
|
|
|
|
|
* reimplemented, it returns 0.
|
|
|
|
|
*/
|
2021-03-31 12:16:38 +02:00
|
|
|
virtual float get_shift();
|
2021-03-07 12:46:25 +01:00
|
|
|
|
2021-03-31 12:16:38 +02:00
|
|
|
/*!
|
2021-03-07 12:46:25 +01:00
|
|
|
* Sets the size of an input item, as in the size of a char or
|
|
|
|
|
* float item.
|
|
|
|
|
*
|
|
|
|
|
* The child class SHOULD implement this function. If not
|
|
|
|
|
* reimplemented, it returns sizeof(float) as the decoders
|
|
|
|
|
* typically expect floating point input types.
|
|
|
|
|
*/
|
2021-03-31 12:16:38 +02:00
|
|
|
virtual int get_input_item_size();
|
2021-03-07 12:46:25 +01:00
|
|
|
|
2021-03-31 12:16:38 +02:00
|
|
|
/*!
|
2021-03-07 12:46:25 +01:00
|
|
|
* Sets the size of an output item, as in the size of a char or
|
|
|
|
|
* float item.
|
|
|
|
|
*
|
|
|
|
|
* The child class SHOULD implement this function. If not
|
|
|
|
|
* reimplemented, it returns sizeof(char) as the decoders
|
|
|
|
|
* typically expect to produce bits or bytes.
|
|
|
|
|
*/
|
2021-03-31 12:16:38 +02:00
|
|
|
virtual int get_output_item_size();
|
2021-03-07 12:46:25 +01:00
|
|
|
|
2021-03-31 12:16:38 +02:00
|
|
|
/*!
|
2021-03-07 12:46:25 +01:00
|
|
|
* Set up a conversion type required to setup the data properly
|
|
|
|
|
* for this decoder. The decoder itself will not implement the
|
|
|
|
|
* conversion and expects an external wrapper (e.g.,
|
|
|
|
|
* fec.extended_decoder) to read this value and "do the right
|
|
|
|
|
* thing" to format the data.
|
|
|
|
|
*
|
|
|
|
|
* The default behavior is 'none', which means no conversion is
|
|
|
|
|
* required. Whatever the get_input_item_size() value returns,
|
|
|
|
|
* the input is expected to conform directly to this.
|
|
|
|
|
*
|
|
|
|
|
* This may also return 'uchar', which indicates that the
|
|
|
|
|
* wrapper should convert the standard float samples to unsigned
|
|
|
|
|
* characters, either hard sliced or 8-bit soft symbols. See
|
|
|
|
|
* gr::fec::code::cc_decoder as an example decoder that uses
|
|
|
|
|
* this conversion format.
|
|
|
|
|
*
|
|
|
|
|
* If 'packed_bits', the block expects the inputs to be packed
|
|
|
|
|
* hard bits. Each input item is a unsigned char where each of
|
|
|
|
|
* the 8-bits is a hard bit value.
|
|
|
|
|
*
|
|
|
|
|
* The child class SHOULD implement this function. If not
|
|
|
|
|
* reimplemented, it returns "none".
|
|
|
|
|
*/
|
2021-03-31 12:16:38 +02:00
|
|
|
virtual const char *get_input_conversion();
|
2021-03-07 12:46:25 +01:00
|
|
|
|
2021-03-31 12:16:38 +02:00
|
|
|
/*!
|
2021-03-07 12:46:25 +01:00
|
|
|
* Set up a conversion type required to understand the output
|
|
|
|
|
* style of this decoder. Generally, follow-on processing
|
|
|
|
|
* expects unpacked bits, so we specify the conversion type here
|
|
|
|
|
* to indicate what the wrapper (e.g., fec.extended_decoder)
|
|
|
|
|
* should do to convert the output samples from the decoder into
|
|
|
|
|
* unpacked bits.
|
|
|
|
|
*
|
|
|
|
|
* The default behavior is 'none', which means no conversion is
|
|
|
|
|
* required. This should mean that the output data is produced
|
|
|
|
|
* from this decoder as unpacked bit.
|
|
|
|
|
*
|
|
|
|
|
* If 'unpack', the block produces packed bytes that should be
|
|
|
|
|
* unpacked by the wrapper. See gr::fec::code::ccsds_decoder as
|
|
|
|
|
* an example of a decoder that produces packed bytes.
|
|
|
|
|
*
|
|
|
|
|
* The child class SHOULD implement this function. If not
|
|
|
|
|
* reimplemented, it returns "none".
|
|
|
|
|
*/
|
2021-03-31 12:16:38 +02:00
|
|
|
virtual const char *get_output_conversion();
|
2021-03-07 12:46:25 +01:00
|
|
|
|
2021-03-31 12:16:38 +02:00
|
|
|
/*!
|
2021-03-07 12:46:25 +01:00
|
|
|
* Updates the size of a decoded frame.
|
|
|
|
|
*
|
|
|
|
|
* The child class MUST implement this function and interpret
|
|
|
|
|
* how the \p frame_size information affects the block's
|
|
|
|
|
* behavior. It should also provide bounds checks.
|
|
|
|
|
*/
|
2021-03-31 12:16:38 +02:00
|
|
|
virtual bool set_frame_size(unsigned int frame_size) = 0;
|
2021-03-07 12:46:25 +01:00
|
|
|
|
2021-03-31 12:16:38 +02:00
|
|
|
/*!
|
2021-03-07 12:46:25 +01:00
|
|
|
* Get repetitions to decode.
|
|
|
|
|
*
|
|
|
|
|
* The child class should implement this function and return the
|
|
|
|
|
* number of iterations required to decode.
|
|
|
|
|
*/
|
2021-03-31 12:16:38 +02:00
|
|
|
virtual float get_iterations() { return -1; }
|
|
|
|
|
};
|
2021-03-07 12:46:25 +01:00
|
|
|
|
2021-03-31 12:16:38 +02:00
|
|
|
/*! see generic_decoder::get_output_size() */
|
|
|
|
|
int get_decoder_output_size(generic_decoder::sptr my_decoder);
|
2021-03-07 12:46:25 +01:00
|
|
|
|
2021-03-31 12:16:38 +02:00
|
|
|
/*! see generic_decoder::get_input_size() */
|
|
|
|
|
int get_decoder_input_size(generic_decoder::sptr my_decoder);
|
2021-03-07 12:46:25 +01:00
|
|
|
|
2021-03-31 12:16:38 +02:00
|
|
|
/*! see generic_decoder::get_shift() */
|
|
|
|
|
float get_shift(generic_decoder::sptr my_decoder);
|
2021-03-07 12:46:25 +01:00
|
|
|
|
2021-03-31 12:16:38 +02:00
|
|
|
/*! see generic_decoder::get_history() */
|
|
|
|
|
int get_history(generic_decoder::sptr my_decoder);
|
2021-03-07 12:46:25 +01:00
|
|
|
|
2021-03-31 12:16:38 +02:00
|
|
|
/*! see generic_decoder::get_input_item_size() */
|
|
|
|
|
int get_decoder_input_item_size(generic_decoder::sptr my_decoder);
|
2021-03-07 12:46:25 +01:00
|
|
|
|
2021-03-31 12:16:38 +02:00
|
|
|
/*! see generic_decoder::get_output_item_size() */
|
|
|
|
|
int get_decoder_output_item_size(generic_decoder::sptr my_decoder);
|
2021-03-07 12:46:25 +01:00
|
|
|
|
2021-03-31 12:16:38 +02:00
|
|
|
/*! see generic_decoder::get_input_conversion() */
|
|
|
|
|
const char *get_decoder_input_conversion(generic_decoder::sptr my_decoder);
|
2021-03-07 12:46:25 +01:00
|
|
|
|
2021-03-31 12:16:38 +02:00
|
|
|
/*! see generic_decoder::get_output_conversion() */
|
|
|
|
|
const char *get_decoder_output_conversion(generic_decoder::sptr my_decoder);
|
2021-03-07 12:46:25 +01:00
|
|
|
|
2021-03-31 12:16:38 +02:00
|
|
|
} /* namespace fec */
|