diff options
Diffstat (limited to 'gr-fec/lib/ldpc_decoder.cc')
-rw-r--r-- | gr-fec/lib/ldpc_decoder.cc | 187 |
1 files changed, 120 insertions, 67 deletions
diff --git a/gr-fec/lib/ldpc_decoder.cc b/gr-fec/lib/ldpc_decoder.cc index 066024c9e0..55eeac6291 100644 --- a/gr-fec/lib/ldpc_decoder.cc +++ b/gr-fec/lib/ldpc_decoder.cc @@ -36,70 +36,123 @@ namespace gr { namespace fec { -generic_decoder::sptr -ldpc_decoder::make(std::string alist_file, float sigma, int max_iterations) -{ - return generic_decoder::sptr(new ldpc_decoder(alist_file, sigma, max_iterations)); -} - -ldpc_decoder::ldpc_decoder (std::string alist_file, float sigma, int max_iterations) - : generic_decoder("ldpc_decoder") -{ - if(!boost::filesystem::exists( alist_file )) - throw std::runtime_error("Bad AList file name!"); - d_list.read(alist_file.c_str()); - d_code.set_alist(d_list); - d_spa.set_alist_sigma(d_list, sigma); - inputSize = d_code.get_N(); - outputSize = d_code.dimension(); - d_spa.set_K(outputSize); - d_spa.set_max_iterations(max_iterations); -} - -int ldpc_decoder::get_output_size() { - return outputSize; -} - -int ldpc_decoder::get_input_size() { - return inputSize; -} - -void ldpc_decoder::generic_work(void *inBuffer, void *outBuffer) { - const float *inPtr = (const float *) inBuffer; - unsigned char *out = (unsigned char *) outBuffer; - - std::vector<float> rx(inputSize); - for(int i=0; i<inputSize; i++){ rx[i] = inPtr[i] * (-1); } - //memcpy(&rx[0], inPtr, inputSize*sizeof(float)); - int n_iterations = 0; - std::vector<char> estimate( d_spa.decode(rx, &n_iterations) ); - std::vector<char> data( d_code.get_systematic_bits(estimate) ); - memcpy(out, &data[0], outputSize); - d_iterations = n_iterations; -} - -int ldpc_decoder::get_input_item_size() { - return sizeof(INPUT_DATATYPE); -} - -int ldpc_decoder::get_output_item_size() { - return sizeof(OUTPUT_DATATYPE); -} - -int ldpc_decoder::get_history() { - return 0; -} - -float ldpc_decoder::get_shift() { - return 0.0; -} - -const char* ldpc_decoder::get_conversion() { - return "none"; -} - -ldpc_decoder::~ldpc_decoder() { -} - -} -} + generic_decoder::sptr + ldpc_decoder::make(std::string alist_file, float sigma, + int max_iterations) + { + return generic_decoder::sptr + (new ldpc_decoder(alist_file, sigma, max_iterations)); + } + + ldpc_decoder::ldpc_decoder(std::string alist_file, float sigma, + int max_iterations) + : generic_decoder("ldpc_decoder") + { + if(!boost::filesystem::exists( alist_file )) + throw std::runtime_error("Bad AList file name!"); + + d_list.read(alist_file.c_str()); + d_code.set_alist(d_list); + d_spa.set_alist_sigma(d_list, sigma); + + d_rate = static_cast<double>(d_code.dimension())/static_cast<double>(d_code.get_N()); + set_frame_size(d_code.dimension()); + + d_spa.set_K(d_output_size); + d_spa.set_max_iterations(max_iterations); + } + + int + ldpc_decoder::get_output_size() + { + return d_output_size; + } + + int + ldpc_decoder::get_input_size() + { + return d_input_size; + } + + double + ldpc_decoder::rate() + { + return d_rate; + } + + bool + ldpc_decoder::set_frame_size(unsigned int frame_size) + { + if(frame_size % d_code.dimension() != 0) { + GR_LOG_ERROR(d_logger, boost::format("Frame size (%1% bits) must be a " + "multiple of the information word " + "size of the LDPC matrix, %2%") \ + % frame_size % (d_code.dimension())); + throw std::runtime_error("ldpc_decoder: cannot use frame size."); + } + + d_output_size = frame_size; + d_input_size = static_cast<int>(round(frame_size / d_rate)); + + return true; + } + + void + ldpc_decoder::generic_work(void *inBuffer, void *outBuffer) + { + const float *in = (const float *) inBuffer; + unsigned char *out = (unsigned char *) outBuffer; + + int j = 0; + std::vector<float> rx(d_code.get_N()); + for(int i = 0; i < d_input_size; i+=d_code.get_N()) { + for(int k = 0; k < d_code.get_N(); k++) { + rx[k] = in[i+k] * (-1); + } + + int n_iterations = 0; + std::vector<char> estimate( d_spa.decode(rx, &n_iterations) ); + std::vector<char> data( d_code.get_systematic_bits(estimate) ); + memcpy(&out[j], &data[0], d_code.dimension()); + d_iterations = n_iterations; + + j += d_code.dimension(); + } + } + + int + ldpc_decoder::get_input_item_size() + { + return sizeof(INPUT_DATATYPE); + } + + int + ldpc_decoder::get_output_item_size() + { + return sizeof(OUTPUT_DATATYPE); + } + + int + ldpc_decoder::get_history() + { + return 0; + } + + float + ldpc_decoder::get_shift() + { + return 0.0; + } + + const char* + ldpc_decoder::get_conversion() + { + return "none"; + } + + ldpc_decoder::~ldpc_decoder() + { + } + + } // namespace gr +} // namespace fec |