From 9a4494904c77c8516c90f2c2a18518065fe36375 Mon Sep 17 00:00:00 2001
From: Tom Rondeau <tom@trondeau.com>
Date: Sun, 4 May 2014 14:24:50 -0400
Subject: fec: updating puncturing, adding documentation, adding CCSDS encoder.

---
 gr-fec/lib/cc_decoder_impl.cc | 249 ++++++++++++++++++++++--------------------
 1 file changed, 131 insertions(+), 118 deletions(-)

(limited to 'gr-fec/lib/cc_decoder_impl.cc')

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 */
-
-- 
cgit v1.2.3