diff options
author | Tom Rondeau <tom@trondeau.com> | 2014-05-04 14:24:50 -0400 |
---|---|---|
committer | Tom Rondeau <tom@trondeau.com> | 2014-05-17 17:45:14 -0400 |
commit | 9a4494904c77c8516c90f2c2a18518065fe36375 (patch) | |
tree | a9981632abad78e00c196e8305105fcaf5019ba4 /gr-fec/lib/cc_decoder_impl.cc | |
parent | fb1d5f822e3a273db88b2087b8d53be67725d232 (diff) |
fec: updating puncturing, adding documentation, adding CCSDS encoder.
Diffstat (limited to 'gr-fec/lib/cc_decoder_impl.cc')
-rw-r--r-- | gr-fec/lib/cc_decoder_impl.cc | 249 |
1 files changed, 131 insertions, 118 deletions
diff --git a/gr-fec/lib/cc_decoder_impl.cc b/gr-fec/lib/cc_decoder_impl.cc index e8d8671e5f..efaf6c002d 100644 --- a/gr-fec/lib/cc_decoder_impl.cc +++ b/gr-fec/lib/cc_decoder_impl.cc @@ -27,7 +27,6 @@ #include "cc_decoder_impl.h" #include <math.h> #include <boost/assign/list_of.hpp> -//#include <volk/volk_typedefs.h> #include <volk/volk.h> #include <sstream> #include <stdio.h> @@ -38,38 +37,35 @@ namespace gr { namespace code { generic_decoder::sptr - cc_decoder::make(int framebits, int k, + cc_decoder::make(int frame_size, int k, int rate, std::vector<int> polys, int start_state, int end_state, - bool tailbiting, bool terminated, - bool truncated, bool streaming) + cc_mode_t mode) { return generic_decoder::sptr - (new cc_decoder_impl(framebits, k, rate, polys, - start_state, end_state, - tailbiting, terminated, - truncated, streaming)); + (new cc_decoder_impl(frame_size, k, rate, polys, + start_state, end_state, mode)); } - cc_decoder_impl::cc_decoder_impl(int framebits, int k, + cc_decoder_impl::cc_decoder_impl(int frame_size, int k, int rate, std::vector<int> polys, int start_state, int end_state, - bool tailbiting, bool terminated, - bool truncated, bool streaming) + cc_mode_t mode) : generic_decoder("cc_decoder"), - d_tailbiting(tailbiting), - d_terminated(terminated), - d_truncated(truncated), - d_streaming(streaming), - d_framebits(framebits), d_k(k), d_rate(rate), d_partial_rate(rate), d_polys(polys), + d_mode(mode), d_start_state_chaining(start_state), d_start_state_nonchaining(start_state), d_end_state_nonchaining(end_state) { + // Set max frame size here; all buffers and settings will be + // based on this value. + d_max_frame_size = frame_size; + set_frame_size(frame_size); + d_vp = new struct v; d_numstates = 1 << (d_k - 1); @@ -77,56 +73,54 @@ namespace gr { d_decision_t_size = d_numstates/8; //packed bit array d_managed_in_size = 0; - if(d_tailbiting) { + switch(d_mode) { + case(CC_TAILBITING): d_end_state = &d_end_state_chaining; - d_veclen = d_framebits + (6 * (d_k - 1)); - d_managed_in = (COMPUTETYPE*)volk_malloc(d_veclen*d_rate*sizeof(COMPUTETYPE), - volk_get_alignment()); + d_managed_in = (unsigned char*)volk_malloc(d_veclen*d_rate*sizeof(unsigned char), + volk_get_alignment()); d_managed_in_size = d_veclen * d_rate; if(d_managed_in == NULL) { - throw std::runtime_error("bad alloc for d_managed_in!\n"); + throw std::runtime_error("cc_decoder: bad alloc for d_managed_in\n"); } - } - - else if(d_truncated) { + break; + + case(CC_TRUNCATED): d_end_state = &d_end_state_chaining; - d_veclen = d_framebits; - } - else if(d_terminated) { + break; + + case(CC_TERMINATED): d_end_state = (end_state == -1) ? &d_end_state_chaining : &d_end_state_nonchaining; - d_veclen = d_framebits + d_k - 1; - } + break; - //streaming - else { + case(CC_STREAMING): d_end_state = &d_end_state_chaining; - d_veclen = d_framebits + d_k - 1; + break; + + default: + throw std::runtime_error("cc_decoder: mode not recognized"); } - d_vp->metrics = (COMPUTETYPE*) volk_malloc(2 * sizeof(COMPUTETYPE) * d_numstates, volk_get_alignment()); + d_vp->metrics = (unsigned char*)volk_malloc(2*sizeof(unsigned char)*d_numstates, + volk_get_alignment()); if(d_vp->metrics == NULL) { throw std::runtime_error("bad alloc for d_vp->metrics!\n"); } - - d_vp->metrics1.t = d_vp->metrics; d_vp->metrics2.t = d_vp->metrics + d_numstates; - d_vp->decisions = (DECISIONTYPE*) volk_malloc(d_veclen*d_decision_t_size, volk_get_alignment()); + d_vp->decisions = (unsigned char*)volk_malloc(d_veclen*d_decision_t_size, + volk_get_alignment()); if(d_vp->decisions == NULL) { throw std::runtime_error("bad alloc for d_vp->decisions!\n"); } - - - Branchtab = (COMPUTETYPE*) volk_malloc(sizeof(COMPUTETYPE) * d_numstates/2*rate, volk_get_alignment()); + Branchtab = (unsigned char*)volk_malloc(sizeof(unsigned char)*d_numstates/2*rate, + volk_get_alignment()); if(Branchtab == NULL) { throw std::runtime_error("bad alloc for d_vp->decisions!\n"); } - - create_viterbi(); if(d_k-1<8) { @@ -164,18 +158,17 @@ namespace gr { cc_decoder_impl::get_output_size() { //unpacked bits - return d_framebits; + return d_frame_size; } int cc_decoder_impl::get_input_size() { - if(d_terminated) { - return d_rate * (d_framebits + d_k - 1); + if(d_mode == CC_TERMINATED) { + return d_rate * (d_frame_size + d_k - 1); } - else { - return d_rate * d_framebits; + return d_rate * d_frame_size; } } @@ -188,7 +181,7 @@ namespace gr { int cc_decoder_impl::get_history() { - if(d_streaming) { + if(d_mode == CC_STREAMING) { return d_rate * (d_k - 1); } else { @@ -196,8 +189,6 @@ namespace gr { } } - - float cc_decoder_impl::get_shift() { @@ -205,7 +196,7 @@ namespace gr { } const char* - cc_decoder_impl::get_conversion() + cc_decoder_impl::get_input_conversion() { return "uchar"; } @@ -222,20 +213,25 @@ namespace gr { } } - if(d_streaming) { - //printf("streaming\n"); + switch(d_mode) { + case(CC_STREAMING): d_start_state = &d_start_state_chaining; init_viterbi_unbiased(d_vp); - } - else if(d_tailbiting) { - //printf("tailbiting\n"); + break; + + case(CC_TAILBITING): d_start_state = &d_start_state_nonchaining; init_viterbi_unbiased(d_vp); - } - else { - //printf("other!\n"); + break; + + case(CC_TRUNCATED): + case(CC_TERMINATED): d_start_state = &d_start_state_nonchaining; init_viterbi(d_vp, *d_start_state); + break; + + default: + throw std::runtime_error("cc_decoder: mode not recognized"); } return; @@ -309,9 +305,9 @@ namespace gr { int cc_decoder_impl::find_endstate() { - COMPUTETYPE* met = ((d_k + d_veclen)%2 == 0)? d_vp->new_metrics.t : d_vp->old_metrics.t; + unsigned char* met = ((d_k + d_veclen)%2 == 0)? d_vp->new_metrics.t : d_vp->old_metrics.t; - COMPUTETYPE min = met[0]; + unsigned char min = met[0]; int state = 0; for(int i = 1; i < d_numstates; ++i) { if(met[i] < min) { @@ -319,35 +315,34 @@ namespace gr { state = i; } - + } //printf("min %d\n", state); return state; } int - cc_decoder_impl::update_viterbi_blk(COMPUTETYPE* syms, int nbits) + cc_decoder_impl::update_viterbi_blk(unsigned char* syms, int nbits) { - DECISIONTYPE *d; + unsigned char *d; d = d_vp->decisions; - memset(d,0,d_decision_t_size * nbits); - - d_kernel( d_vp->new_metrics.t, d_vp->old_metrics.t, syms, d, nbits - (d_k - 1), d_k -1, Branchtab); + d_kernel(d_vp->new_metrics.t, d_vp->old_metrics.t, syms, + d, nbits - (d_k - 1), d_k - 1, Branchtab); return 0; } int - cc_decoder_impl::chainback_viterbi(DECISIONTYPE* data, + cc_decoder_impl::chainback_viterbi(unsigned char* data, unsigned int nbits, unsigned int endstate, unsigned int tailsize) { - DECISIONTYPE *d; + unsigned char *d; /* ADDSHIFT and SUBSHIFT make sure that the thing returned is a byte. */ d = d_vp->decisions; @@ -365,17 +360,17 @@ namespace gr { d += tailsize * d_decision_t_size ; /* Look past tail */ int retval; int dif = tailsize - (d_k - 1); - //printf("break, %d, %d\n", dif, (nbits+dif)%d_framebits); + //printf("break, %d, %d\n", dif, (nbits+dif)%d_frame_size); decision_t dec; - while(nbits-- > d_framebits - (d_k - 1)) { + while(nbits-- > d_frame_size - (d_k - 1)) { int k; dec.t = &d[nbits * d_decision_t_size]; k = (dec.w[(endstate>>d_ADDSHIFT)/32] >> ((endstate>>d_ADDSHIFT)%32)) & 1; endstate = (endstate >> 1) | (k << (d_k-2+d_ADDSHIFT)); //data[((nbits+dif)%nbits)>>3] = endstate>>d_SUBSHIFT; - //printf("%d, %d\n", k, (nbits+dif)%d_framebits); - data[((nbits+dif)%d_framebits)] = k; + //printf("%d, %d\n", k, (nbits+dif)%d_frame_size); + data[((nbits+dif)%d_frame_size)] = k; retval = endstate; } @@ -389,82 +384,100 @@ namespace gr { k = (dec.w[(endstate>>d_ADDSHIFT)/32] >> ((endstate>>d_ADDSHIFT)%32)) & 1; endstate = (endstate >> 1) | (k << (d_k-2+d_ADDSHIFT)); - data[((nbits+dif)%d_framebits)] = k; + data[((nbits+dif)%d_frame_size)] = k; } - //printf("%d, %d, %d, %d, %d, %d, %d, %d\n", data[4095],data[4094],data[4093],data[4092],data[4091],data[4090],data[4089],data[4088]); + return retval >> d_ADDSHIFT; } - void - cc_decoder_impl::set_framebits(int framebits) + bool + cc_decoder_impl::set_frame_size(unsigned int frame_size) { - d_framebits = framebits; - if(d_tailbiting) { - d_veclen = d_framebits + (6 * (d_k - 1)); + bool ret = true; + if(frame_size > d_max_frame_size) { + GR_LOG_INFO(d_logger, boost::format("tried to set frame to %1%; max possible is %2%") \ + % frame_size % d_max_frame_size); + frame_size = d_max_frame_size; + ret = false; + } + + d_frame_size = frame_size; + + switch(d_mode) { + case(CC_TAILBITING): + d_veclen = d_frame_size + (6 * (d_k - 1)); if(d_veclen * d_rate > d_managed_in_size) { throw std::runtime_error("attempt to resize beyond d_managed_in buffer size!\n"); } + break; + + case(CC_TRUNCATED): + d_veclen = d_frame_size; + break; + + case(CC_STREAMING): + case(CC_TERMINATED): + d_veclen = d_frame_size + d_k - 1; + break; + + default: + throw std::runtime_error("cc_decoder: mode not recognized"); } - else if(d_truncated) { - d_veclen = d_framebits; - } - else { - d_veclen = d_framebits + d_k - 1; - } + + return ret; + } + + double + cc_decoder_impl::rate() + { + return 1.0/static_cast<double>(d_rate); } void - cc_decoder_impl::generic_work(void *inBuffer, void *outBuffer) + cc_decoder_impl::generic_work(void *inbuffer, void *outbuffer) { - const COMPUTETYPE *in = (const COMPUTETYPE *) inBuffer; - DECISIONTYPE *out = (DECISIONTYPE *) outBuffer; - - if(d_tailbiting) { - memcpy(d_managed_in, in, d_framebits * d_rate * sizeof(COMPUTETYPE)); - memcpy(d_managed_in + d_framebits * d_rate * sizeof(COMPUTETYPE), in, - (d_veclen - d_framebits) * d_rate * sizeof(COMPUTETYPE)); - /*for(int i = 0; i < d_veclen * d_rate; ++i) { - printf("%u...%d\n", d_managed_in[i], i); - }*/ + const unsigned char *in = (const unsigned char *) inbuffer; + unsigned char *out = (unsigned char *) outbuffer; + + switch(d_mode) { + + case(CC_TAILBITING): + memcpy(d_managed_in, in, d_frame_size * d_rate * sizeof(unsigned char)); + memcpy(d_managed_in + d_frame_size * d_rate * sizeof(unsigned char), in, + (d_veclen - d_frame_size) * d_rate * sizeof(unsigned char)); update_viterbi_blk(d_managed_in, d_veclen); d_end_state_chaining = find_endstate(); - chainback_viterbi(&out[0], d_framebits, *d_end_state, d_veclen - d_framebits); + chainback_viterbi(&out[0], d_frame_size, *d_end_state, d_veclen - d_frame_size); init_viterbi_unbiased(d_vp); - } + break; - - else if(d_truncated) { - update_viterbi_blk((COMPUTETYPE*)(&in[0]), d_veclen); + case(CC_TRUNCATED): + update_viterbi_blk((unsigned char*)(&in[0]), d_veclen); d_end_state_chaining = find_endstate(); - //printf("...end %d\n", d_end_state_chaining); for(unsigned int i = 0; i < d_k-1; ++i) { out[d_veclen - 1 - i] = ((*d_end_state) >> i) & 1; } - d_start_state_chaining = chainback_viterbi(&out[0], d_framebits - (d_k - 1), + d_start_state_chaining = chainback_viterbi(&out[0], d_frame_size - (d_k - 1), *d_end_state, d_k - 1); init_viterbi(d_vp, *d_start_state); - /*for(int i = d_framebits - 25; i < d_framebits; ++i) { - //for(int i = 0; i < 25; ++i) { - printf("%u... : %u\n", out[i], i); - }*/ - } - //terminated or streaming - else { - update_viterbi_blk((COMPUTETYPE*)(&in[0]), d_veclen); + break; + + case(CC_STREAMING): + case(CC_TERMINATED): + update_viterbi_blk((unsigned char*)(&in[0]), d_veclen); d_end_state_chaining = find_endstate(); - //printf("es: %d, %d\n", d_end_state_chaining, *d_end_state); - d_start_state_chaining = chainback_viterbi(&out[0], d_framebits, *d_end_state, - d_veclen - d_framebits); + d_start_state_chaining = chainback_viterbi(&out[0], d_frame_size, *d_end_state, + d_veclen - d_frame_size); init_viterbi(d_vp, *d_start_state); - /*for(int i = d_framebits * d_rate - 25; i < d_framebits * d_rate; ++i) { - printf("%u... : %u\n", in[i], i); - }*/ + break; + + default: + throw std::runtime_error("cc_decoder: mode not recognized"); } } } /* namespace code */ } /* namespace fec */ } /* namespace gr */ - |