commit-gnuradio
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Commit-gnuradio] [gnuradio] 01/08: gr-dtv: Replace DVB-T Reed-Solomon w


From: git
Subject: [Commit-gnuradio] [gnuradio] 01/08: gr-dtv: Replace DVB-T Reed-Solomon with existing implementation in gr-fec.
Date: Tue, 16 Aug 2016 16:24:32 +0000 (UTC)

This is an automated email from the git hooks/post-receive script.

jcorgan pushed a commit to branch master
in repository gnuradio.

commit 6ab627b21e030b4707f9547b1b73ad1bb3d96914
Author: Ron Economos <address@hidden>
Date:   Wed Aug 10 16:40:53 2016 -0700

    gr-dtv: Replace DVB-T Reed-Solomon with existing implementation in gr-fec.
---
 gr-dtv/lib/CMakeLists.txt                     |   1 -
 gr-dtv/lib/dvbt/dvbt_reed_solomon.cc          | 475 --------------------------
 gr-dtv/lib/dvbt/dvbt_reed_solomon.h           |  70 ----
 gr-dtv/lib/dvbt/dvbt_reed_solomon_dec_impl.cc |  69 ++--
 gr-dtv/lib/dvbt/dvbt_reed_solomon_dec_impl.h  |  19 +-
 gr-dtv/lib/dvbt/dvbt_reed_solomon_enc_impl.cc |  58 ++--
 gr-dtv/lib/dvbt/dvbt_reed_solomon_enc_impl.h  |  16 +-
 7 files changed, 105 insertions(+), 603 deletions(-)

diff --git a/gr-dtv/lib/CMakeLists.txt b/gr-dtv/lib/CMakeLists.txt
index 67b8a0e..4aa6d49 100644
--- a/gr-dtv/lib/CMakeLists.txt
+++ b/gr-dtv/lib/CMakeLists.txt
@@ -77,7 +77,6 @@ list(APPEND dtv_sources
   dvbs2/dvbs2_modulator_bc_impl.cc
   dvbs2/dvbs2_physical_cc_impl.cc
   dvbt/dvbt_energy_dispersal_impl.cc
-  dvbt/dvbt_reed_solomon.cc
   dvbt/dvbt_reed_solomon_enc_impl.cc
   dvbt/dvbt_convolutional_interleaver_impl.cc
   dvbt/dvbt_configure.cc
diff --git a/gr-dtv/lib/dvbt/dvbt_reed_solomon.cc 
b/gr-dtv/lib/dvbt/dvbt_reed_solomon.cc
deleted file mode 100644
index 7d67a0a..0000000
--- a/gr-dtv/lib/dvbt/dvbt_reed_solomon.cc
+++ /dev/null
@@ -1,475 +0,0 @@
-/* -*- c++ -*- */
-/* 
- * Copyright 2015 Free Software Foundation, Inc.
- * 
- * This is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3, or (at your option)
- * any later version.
- * 
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- * 
- * You should have received a copy of the GNU General Public License
- * along with this software; see the file COPYING.  If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street,
- * Boston, MA 02110-1301, USA.
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <gnuradio/io_signature.h>
-#include "dvbt_reed_solomon.h"
-#include <iostream>
-#include <stdio.h>
-#include <string.h>
-#include <fstream>
-
-using namespace std;
-
-#define min(a,b) ((a) < (b)) ? (a) : (b)
-
-namespace gr {
-  namespace dtv {
-
-    void
-    dvbt_reed_solomon::gf_init(int p, int m, int gfpoly)
-    {
-      d_p = p; d_m = m;
-
-      //maximum number of elements in the GF(p^m)
-      int q = powl(p, m);
-
-      d_gf_exp = new unsigned char[q];
-      if (d_gf_exp == NULL) {
-        std::cout << "Cannot allocate memory for d_gf_exp" << std::endl;
-        return;
-      }
-
-      d_gf_log = new unsigned char[q];
-      if (d_gf_log == NULL) {
-        std::cout << "Cannot allocate memory for d_gf_log" << std::endl;
-        delete [] d_gf_exp;
-        return;
-      }
-
-      int reg_rs = 1;
-
-      d_gf_exp[q - 1] = 0;
-      d_gf_log[0] = q - 1;
-
-      for (int i = 0; i < (q - 1); i++) {
-        d_gf_exp[i] = reg_rs;
-        d_gf_log[reg_rs] = i;
-
-        //This is equvalent with raise to power
-        reg_rs = reg_rs << 1;
-
-        if (reg_rs & (1 << m)) {
-          reg_rs = reg_rs ^ gfpoly;
-        }
-
-        reg_rs = reg_rs & ((1 << m) - 1);
-      }
-    }
-
-    void
-    dvbt_reed_solomon::gf_uninit()
-    {
-      delete [] d_gf_log;
-      delete [] d_gf_exp;
-    }
-
-    int
-    dvbt_reed_solomon::gf_exp(int a)
-    {
-      return d_gf_exp[a % d_n];
-    }
-
-    int
-    dvbt_reed_solomon::gf_log(int a)
-    {
-      return d_gf_log[a % d_n];
-    }
-
-
-    int
-    dvbt_reed_solomon::gf_add(int a, int b)
-    {
-      return (a ^ b);
-    }
-
-    int
-    dvbt_reed_solomon::gf_mul(int a, int b)
-    {
-      if (a == 0 || b == 0) {
-        return 0;
-      }
-      else {
-        return gf_exp(d_gf_log[a] + d_gf_log[b]);
-      }
-    }
-
-    int
-    dvbt_reed_solomon::gf_div(int a, int b)
-    {
-      if (a == 0 || b == 0) {
-        return (0);
-      }
-
-      return (gf_exp(d_n + d_gf_log[a] - d_gf_log[b]));
-    }
-
-    int
-    dvbt_reed_solomon::gf_pow(int a, int power)
-    {
-      if (a == 0) {
-        return (0);
-      }
-
-      return gf_exp(d_n + d_gf_log[a] + power);
-    }
-
-    int
-    dvbt_reed_solomon::gf_lpow(int power)
-    {
-      return d_l[power % d_n];
-    }
-
-    void
-    dvbt_reed_solomon::rs_init(int lambda, int n, int k, int t)
-    {
-      d_n = n; d_k = k; d_t = t;
-      // 2t = n - k, dmin = 2t + 1 = n -k + 1
-
-      d_l = new unsigned char[d_n + 1];
-      if (d_l == NULL) {
-        std::cout << "Cannot allocate memory for d_l" << std::endl;
-        exit(1);
-      }
-
-      d_g = new unsigned char[2 * d_t + 1];
-      if (d_g == NULL) {
-        std::cout << "Cannot allocate memory for d_g" << std::endl;
-        delete [] d_l;
-        exit(1);
-      }
-
-      //Generate roots of lambda
-      d_l[0] = 1;
-
-      for (int i = 1; i <= d_n; i++) {
-        d_l[i] = gf_mul(d_l[i - 1], lambda);
-      }
-
-      //Init Generator polynomial buffer
-      for (int i = 0; i <= (2*t); i++) {
-        d_g[i] = 0;
-      }
-
-      //Start with x+lambda^0
-      d_g[0] = 1;
-
-      //Create generator polynomial
-      for (int i = 1; i <= (2 * t); i++) {
-        for (int j = i; j > 0; j--) {
-          if (d_g[j] != 0) {
-            d_g[j] = gf_add(d_g[j - 1], gf_mul(d_g[j], d_l[i - 1]));
-          }
-          else {
-            d_g[j] = d_g[j - 1];
-          }
-        }
-
-        d_g[0] = gf_mul(d_g[0], d_l[i - 1]);
-      }
-
-      // Init syndrome array
-      d_syn = new unsigned char[2 * d_t + 1];
-      if (d_syn == NULL) {
-        std::cout << "Cannot allocate memory for d_syn" << std::endl;
-        delete [] d_g;
-        delete [] d_l;
-        exit(1);
-      }
-    }
-
-    void
-    dvbt_reed_solomon::rs_uninit()
-    {
-      if (d_syn) {
-        delete [] d_syn;
-      }
-      if (d_g) {
-        delete [] d_g;
-      }
-      if (d_l) {
-        delete [] d_l;
-      }
-    }
-
-    int
-    dvbt_reed_solomon::rs_encode(unsigned char *data_in, unsigned char *parity)
-    {
-      memset(parity, 0, 2 * d_t);
-
-      for (int i = 0; i < d_k; i++) {
-        int feedback = gf_add(data_in[i], parity[0]);
-
-        if (feedback != 0) {
-          for (int j = 1; j < (2 * d_t); j++) {
-            if (d_g[2 * d_t - j] != 0) {
-              parity[j] = gf_add(parity[j], gf_mul(feedback, d_g[2 * d_t - 
j]));
-            }
-          }
-        }
-
-        //Shift the register
-        memmove(&parity[0], &parity[1], (2 * d_t) - 1);
-
-        if (feedback != 0) {
-          parity[2 * d_t - 1] = gf_mul(feedback, d_g[0]);
-        }
-        else {
-          parity[2 * d_t - 1] = 0;
-        }
-      }
-
-      return (0);
-    }
-
-    int
-    dvbt_reed_solomon::rs_decode(unsigned char *data, unsigned char *eras, 
const int no_eras)
-    {
-      __GR_VLA(unsigned char, sigma, 2 * d_t + 1);
-      __GR_VLA(unsigned char, b, 2 * d_t + 1);
-      __GR_VLA(unsigned char, T, 2 * d_t + 1);
-      __GR_VLA(unsigned char, reg, 2 * d_t + 1);
-      __GR_VLA(unsigned char, root, 2 * d_t + 1);
-      __GR_VLA(unsigned char, loc, 2 * d_t + 1);
-      __GR_VLA(unsigned char, omega, 2 * d_t);
-
-      // Compute erasure locator polynomial
-      memset(sigma, 0, 2 * d_t + 1);
-      sigma[0] = 1;
-
-      if (no_eras > 0) {
-        // In this case we know the locations of errors
-        // Init sigma to be the erasure locator polynomial
-        sigma[1] = gf_exp(d_n-1-eras[0]);
-
-        for (int i = 1; i < no_eras; i++) {
-          int u = d_n-1-eras[i];
-
-          for (int j = i+1; j > 0; j--) {
-            sigma[j] = gf_add(sigma[j], gf_pow(sigma[j - 1], u));
-          }
-        }
-      }
-
-      // Calculate syndrome
-
-      for (int j = 0; j < 2 * d_t; j++) {
-        d_syn[j] = data[0];
-      }
-
-      for (int j = 1; j < d_n; j++) {
-        for (int i = 0; i < 2 * d_t; i++) {
-          d_syn[i] = gf_add(data[j], gf_pow(d_syn[i], i));
-        }
-      }
-
-      int syn_error = 0;
-
-      // Verify all syndromes
-      for (int i = 0; i < 2 * d_t; i++) {
-        syn_error |= d_syn[i];
-      }
-
-      if (!syn_error) {
-        // The syndrome is a codeword
-        // Return data unmodified
-        return (0);
-      }
-
-      // Use Modified (errors+erasures) BMA. Algorithm of Berlekamp-Massey
-      // S(i)=r(lambda^i)=e(lambda^i)
-
-      int r = no_eras;
-      int el = no_eras;
-
-      memcpy(b, sigma, 2 * d_t + 1);
-
-      while (++r <= 2 * d_t) {
-        int d_discr = 0;
-
-        for (int i = 0; i < r; i++) {
-          d_discr = gf_add(d_discr, gf_mul(sigma[i], d_syn[r - i - 1]));
-        }
-
-        if (d_discr == 0) {
-          // b(x) = x * b(x)
-          memmove(&b[1], b, 2 * d_t);
-          b[0] = 0;
-        }
-        else {
-          T[0] = sigma[0];
-
-          // T(x) = sigma(x) + d*x*b(x)
-          for (int i = 0; i < 2 * d_t; i++) {
-            T[i + 1] = gf_add(sigma[i + 1], gf_mul(d_discr, b[i]));
-          }
-
-          if (2 * el <= r + no_eras - 1) {
-            el = r + no_eras - el;
-
-            // b(i) = sigma(i) / discr
-            for (int i = 0; i <= 2 * d_t; i++) {
-              b[i] = gf_div(sigma[i], d_discr);
-            }
-          }
-          else {
-            // b(x) = x*b(x)
-            memmove(&b[1], b, 2 * d_t);
-            b[0] = 0;
-          }
-          memcpy(sigma, T, 2 * d_t + 1);
-        }
-      }
-
-      // Compute degree(sigma)
-      int deg_sigma = 0;
-
-      for (int i = 0; i < 2 * d_t + 1; i++) {
-        if (sigma[i] != 0) {
-          deg_sigma = i;
-        }
-      }
-
-      // Find the roots of sigma(x) by Chien search
-      // Test sum(1)=1+sigma(1)*(lambda^1)+...+sigma(nu)*lambda(^nu)
-      // Test sum(2)=1+sigma(1)*(lambda^2)+...+sigma(nu)*lambda(^nu*2)
-      // ...
-      // Test sum(l)=1+sigma(1)*(lambda^l)+...+sigma(nu)*lambda(^nu*l)
-      // in order to see if lambda^(-1) is a root
-      // where nu is degree(sigma)
-
-      int no_roots = 0;
-
-      memcpy(&reg[1], &sigma[1], 2 * d_t);
-
-      for (int i = 1; i <= d_n; i++) {
-        int q = 1;
-
-        for (int j = deg_sigma; j > 0; j--) {
-          reg[j] = gf_pow(reg[j], j);
-          q = gf_add(q, reg[j]);
-        }
-
-        if (q != 0) {
-          continue;
-        }
-
-        // We are here when we found roots of the sigma(x)
-        // Keep roots in index form
-        root[no_roots] = i;
-        loc[no_roots] = i - 1;
-
-        if (++no_roots == deg_sigma) {
-          break;
-        }
-      }
-
-      if (no_roots != deg_sigma) {
-        // Uncorrectable error detected
-        if (eras) {
-          for (int i = 0; i < no_roots; i++)
-            eras[i] = loc[i];
-        }
-
-        return (-1);
-      }
-
-      // Compute erros+erasures evaluator polynomial
-      // omega(x)=sigma(x)S(x) mod (x ^ 2 * t)
-      int deg_omega = 0;
-
-      for (int i = 0; i < 2 * d_t; i++) {
-        int tmp = 0;
-        int j = (deg_sigma < i) ? deg_sigma : i;
-
-        for(;j >= 0; j--) {
-          tmp = gf_add(tmp, gf_mul(d_syn[i - j], sigma[j]));
-        }
-
-        if(tmp != 0) {
-          deg_omega = i;
-        }
-
-        omega[i] = tmp;
-      }
-      omega[2 * d_t] = 0;
-
-      // Compute error values using Forney formula (poly form)
-      // e(j(l))) = (lambda(j(l)) ^ 2) * omega(lambda ^ (-j(l))) / 
sigma_pr(lambda ^ (-j(l)))
-      // where sigma_pr is the formal derivative of sigma
-
-      for (int j = no_roots - 1; j >= 0; j--) {
-        int num1 = 0;
-
-        // roots[] are in index form
-        for (int i = deg_omega; i >= 0; i--) {
-          num1 = gf_add(num1, gf_pow(omega[i], i * root[j]));
-        }
-
-        // root[] is in index form
-        int num2 = gf_exp(root[j] * (-1) + d_n);
-
-        int den = 0;
-
-        // sigma[i+1] for i even is the formal derivative lambda_pr of sigma[i]
-        int deg_max = min(deg_sigma, 2 * d_t - 1);
-
-        for (int i = 1; i <= deg_max; i += 2) {
-          if (sigma[i] != 0)
-            den = gf_add(den, gf_exp(d_gf_log[sigma[i]] + (i - 1) * root[j]));
-        }
-
-        if (den == 0) {
-          if (eras) {
-            for (int i = 0; i < no_roots; i++) {
-              eras[i] = loc[i];
-            }
-          }
-          return (-1);
-        }
-
-        int err = gf_div(gf_mul(num1, num2), den);
-
-        data[loc[j]] = gf_add(data[loc[j]], err);
-      }
-
-      return(no_roots);
-    }
-
-
-    dvbt_reed_solomon::dvbt_reed_solomon(int p, int m, int gfpoly, int n, int 
k, int t, int s, int blocks):
-      d_p(p), d_m(m), d_gfpoly(gfpoly), d_n(n), d_k(k), d_t(t), d_s(s), 
d_blocks(blocks)
-    {
-      gf_init(d_p, d_m, d_gfpoly);
-      rs_init(d_p, d_n, d_k, d_t);
-    }
-
-    dvbt_reed_solomon::~dvbt_reed_solomon()
-    {
-      rs_uninit();
-      gf_uninit();
-    }
-
-  } /* namespace dtv */
-} /* namespace gr */
-
diff --git a/gr-dtv/lib/dvbt/dvbt_reed_solomon.h 
b/gr-dtv/lib/dvbt/dvbt_reed_solomon.h
deleted file mode 100644
index b9286d0..0000000
--- a/gr-dtv/lib/dvbt/dvbt_reed_solomon.h
+++ /dev/null
@@ -1,70 +0,0 @@
-/* -*- c++ -*- */
-/* 
- * Copyright 2015 Free Software Foundation, Inc.
- * 
- * This is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3, or (at your option)
- * any later version.
- * 
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- * 
- * You should have received a copy of the GNU General Public License
- * along with this software; see the file COPYING.  If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street,
- * Boston, MA 02110-1301, USA.
- */
-
-#ifndef INCLUDED_DTV_DVBT_REED_SOLOMON_H
-#define INCLUDED_DTV_DVBT_REED_SOLOMON_H
-
-namespace gr {
-  namespace dtv {
-
-    class dvbt_reed_solomon
-    {
-     private:
-      int d_p;
-      int d_m;
-      int d_gfpoly;
-      int d_n;
-      int d_k;
-      int d_t;
-      int d_s;
-      int d_blocks;
-      unsigned char *d_gf_exp;
-      unsigned char *d_gf_log;
-      unsigned char *d_l;
-      unsigned char *d_g;
-
-      unsigned char *d_syn;
-
-      int gf_add(int a, int b);
-      int gf_mul(int a, int b);
-      int gf_div(int a, int b);
-      int gf_exp(int a);
-      int gf_log(int a);
-      int gf_pow(int a, int power);
-      int gf_lpow(int power);
-
-      void gf_init(int p, int m, int gfpoly);
-      void gf_uninit();
-      void rs_init(int lambda, int n, int k, int t);
-      void rs_uninit();
-
-     public:
-      int rs_encode(unsigned char *data, unsigned char *parity);
-      int rs_decode(unsigned char *data, unsigned char *eras, const int 
no_eras);
-
-      dvbt_reed_solomon(int p, int m, int gfpoly, int n, int k, int t, int s, 
int blocks);
-      ~dvbt_reed_solomon();
-    };
-
-  } // namespace dtv
-} // namespace gr
-
-#endif /* INCLUDED_DTV_DVBT_REED_SOLOMON_H */
-
diff --git a/gr-dtv/lib/dvbt/dvbt_reed_solomon_dec_impl.cc 
b/gr-dtv/lib/dvbt/dvbt_reed_solomon_dec_impl.cc
index 4a5530c..f2e370a 100644
--- a/gr-dtv/lib/dvbt/dvbt_reed_solomon_dec_impl.cc
+++ b/gr-dtv/lib/dvbt/dvbt_reed_solomon_dec_impl.cc
@@ -1,6 +1,6 @@
 /* -*- c++ -*- */
 /* 
- * Copyright 2015 Free Software Foundation, Inc.
+ * Copyright 2015,2016 Free Software Foundation, Inc.
  * 
  * This is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -29,6 +29,11 @@
 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)
+    static const int N = (1 << rs_init_symsize) - 1;   // 255
+
     dvbt_reed_solomon_dec::sptr
     dvbt_reed_solomon_dec::make(int p, int m, int gfpoly, int n, int k, int t, 
int s, int blocks)
     {
@@ -43,15 +48,16 @@ namespace gr {
       : block("dvbt_reed_solomon_dec",
           io_signature::make(1, 1, sizeof(unsigned char) * blocks * (n - s)),
           io_signature::make(1, 1, sizeof(unsigned char) * blocks * (k - s))),
-      d_p(p), d_m(m), d_gfpoly(gfpoly), d_n(n), d_k(k), d_t(t), d_s(s), 
d_blocks(blocks),
-      d_rs(p, m, gfpoly, n, k, t, s, blocks)
+      d_n(n), d_k(k), d_s(s), d_blocks(blocks)
     {
-      d_in = new unsigned char[d_n];
-      if (d_in == NULL) {
-        std::cout << "Cannot allocate memory for d_in" << std::endl;
+      d_rs = init_rs_char(rs_init_symsize, gfpoly, rs_init_fcr, rs_init_prim, 
(n - k));
+      if (d_rs == NULL) {
+        fprintf(stderr, "Reed-Solomon decoder, Out of memory.\n");
         exit(1);
       }
-      memset(&d_in[0], 0, d_n);
+      d_nerrors_corrected_count = 0;
+      d_bad_packet_count = 0;
+      d_total_packets = 0;
     }
 
     /*
@@ -59,7 +65,7 @@ namespace gr {
      */
     dvbt_reed_solomon_dec_impl::~dvbt_reed_solomon_dec_impl()
     {
-      delete [] d_in;
+      free_rs_char(d_rs);
     }
 
     void
@@ -69,6 +75,25 @@ namespace gr {
     }
 
     int
+    dvbt_reed_solomon_dec_impl::decode (unsigned char &out, const unsigned 
char &in)
+    {
+      unsigned char tmp[N];
+      int ncorrections;
+
+      // add missing prefix zero padding to message
+      memset(tmp, 0, d_s);
+      memcpy(&tmp[d_s], &in, (d_n - d_s));
+
+      // correct message...
+      ncorrections = decode_rs_char(d_rs, tmp, 0, 0);
+
+      // copy corrected message to output, skipping prefix zero padding
+      memcpy (&out, &tmp[d_s], (d_k - d_s));
+
+      return ncorrections;
+    }
+
+    int
     dvbt_reed_solomon_dec_impl::general_work (int noutput_items,
                        gr_vector_int &ninput_items,
                        gr_vector_const_void_star &input_items,
@@ -76,21 +101,23 @@ namespace gr {
     {
       const unsigned char *in = (const unsigned char *) input_items[0];
       unsigned char *out = (unsigned char *) output_items[0];
-
-      // We receive only nonzero data
-      int in_bsize = d_n - d_s;
-      int out_bsize = d_k - d_s;
+      int j = 0;
+      int k = 0;
 
       for (int i = 0; i < (d_blocks * noutput_items); i++) {
-        //TODO - zero copy?
-        // Set first d_s symbols to zero
-        memset(&d_in[0], 0, d_s);
-        // Then copy actual data
-        memcpy(&d_in[d_s], &in[i * in_bsize], in_bsize);
-
-        d_rs.rs_decode(d_in, NULL, 0);
-
-        memcpy(&out[i * out_bsize], &d_in[d_s], out_bsize);
+        int nerrors_corrected = decode(out[k], in[j]);
+
+        if (nerrors_corrected == -1) {
+          d_bad_packet_count++;
+          d_nerrors_corrected_count += ((d_n - d_s) - (d_k - d_s)) / 2; // 
lower bound estimate; most this RS can fix
+        }
+        else {
+          d_nerrors_corrected_count += nerrors_corrected;
+        }
+
+       d_total_packets++;
+        j += (d_n - d_s);
+        k += (d_k - d_s);
       }
 
       // Tell runtime system how many input items we consumed on
diff --git a/gr-dtv/lib/dvbt/dvbt_reed_solomon_dec_impl.h 
b/gr-dtv/lib/dvbt/dvbt_reed_solomon_dec_impl.h
index 951aa4b..2d9b248 100644
--- a/gr-dtv/lib/dvbt/dvbt_reed_solomon_dec_impl.h
+++ b/gr-dtv/lib/dvbt/dvbt_reed_solomon_dec_impl.h
@@ -1,6 +1,6 @@
 /* -*- c++ -*- */
 /* 
- * Copyright 2015 Free Software Foundation, Inc.
+ * Copyright 2015,2016 Free Software Foundation, Inc.
  * 
  * This is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -22,7 +22,10 @@
 #define INCLUDED_DTV_DVBT_REED_SOLOMON_DEC_IMPL_H
 
 #include <gnuradio/dtv/dvbt_reed_solomon_dec.h>
-#include "dvbt_reed_solomon.h"
+
+extern "C" {
+#include <gnuradio/fec/rs.h>
+}
 
 namespace gr {
   namespace dtv {
@@ -30,18 +33,18 @@ namespace gr {
     class dvbt_reed_solomon_dec_impl : public dvbt_reed_solomon_dec
     {
      private:
-      int d_p;
-      int d_m;
-      int d_gfpoly;
       int d_n;
       int d_k;
-      int d_t;
       int d_s;
       int d_blocks;
 
-      unsigned char * d_in;
+      int d_nerrors_corrected_count;
+      int d_bad_packet_count;
+      int d_total_packets;
+      int d_total_bits;
 
-      dvbt_reed_solomon d_rs;
+      void *d_rs;    /* Reed-Solomon characteristics structure */
+      int decode(unsigned char &out, const unsigned char &in);
 
      public:
       dvbt_reed_solomon_dec_impl(int p, int m, int gfpoly, int n, int k, int 
t, int s, int blocks);
diff --git a/gr-dtv/lib/dvbt/dvbt_reed_solomon_enc_impl.cc 
b/gr-dtv/lib/dvbt/dvbt_reed_solomon_enc_impl.cc
index 561ea08..3bc1860 100644
--- a/gr-dtv/lib/dvbt/dvbt_reed_solomon_enc_impl.cc
+++ b/gr-dtv/lib/dvbt/dvbt_reed_solomon_enc_impl.cc
@@ -1,6 +1,6 @@
 /* -*- c++ -*- */
 /* 
- * Copyright 2015 Free Software Foundation, Inc.
+ * Copyright 2015,2016 Free Software Foundation, Inc.
  * 
  * This is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -26,9 +26,15 @@
 #include "dvbt_reed_solomon_enc_impl.h"
 #include <stdio.h>
 
+#define MPEG_TS_PKT_LENGTH 188
+
 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)
     {
@@ -43,15 +49,19 @@ namespace gr {
       : 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_p(p), d_m(m), d_gfpoly(gfpoly), d_n(n), d_k(k), d_t(t), d_s(s), 
d_blocks(blocks),
-      d_rs(p, m, gfpoly, n, k, t, s, blocks)
+      d_n(n), d_k(k), d_s(s), d_blocks(blocks)
     {
-      d_in = new unsigned char[d_n];
-      if (d_in == NULL) {
-        std::cout << "Cannot allocate memory for d_in" << std::endl;
-        return;
+      d_rs = init_rs_char(rs_init_symsize, gfpoly, rs_init_fcr, rs_init_prim, 
(n - k));
+      if (d_rs == NULL) {
+        fprintf(stderr, "Reed-Solomon encoder, Out of memory.\n");
+        exit(1);
+      }
+      d_data = (unsigned char *) malloc(sizeof(unsigned char) * (d_s + 
MPEG_TS_PKT_LENGTH));
+      if (d_data == NULL) {
+        fprintf(stderr, "Reed-Solomon encoder, Out of memory.\n");
+        free_rs_char(d_rs);
+        exit(1);
       }
-      memset(&d_in[0], 0, d_n);
     }
 
     /*
@@ -59,7 +69,8 @@ namespace gr {
      */
     dvbt_reed_solomon_enc_impl::~dvbt_reed_solomon_enc_impl()
     {
-      delete [] d_in;
+      free(d_data);
+      free_rs_char(d_rs);
     }
 
     void
@@ -68,6 +79,18 @@ namespace gr {
       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);
+      std::memcpy(&d_data[d_s], in, MPEG_TS_PKT_LENGTH);
+
+      // Copy input message to output then append Reed-Solomon bits
+      std::memcpy(out, in, MPEG_TS_PKT_LENGTH);
+      encode_rs_char(d_rs, d_data, &out[MPEG_TS_PKT_LENGTH]);
+    }
+
     int
     dvbt_reed_solomon_enc_impl::general_work (int noutput_items,
                        gr_vector_int &ninput_items,
@@ -76,18 +99,13 @@ namespace gr {
     {
       const unsigned char *in = (const unsigned char *) input_items[0];
       unsigned char *out = (unsigned char *) output_items[0];
+      int j = 0;
+      int k = 0;
 
-      int in_bsize = d_k - d_s;
-      int out_bsize = d_n - d_s;
-
-      // We get a superblock of d_blocks blocks
-      for (int i = 0; i < (d_blocks * noutput_items); i++) {
-        //TODO - zero copy between in/out ?
-        memcpy(&d_in[d_s], &in[i * in_bsize], in_bsize);
-
-        d_rs.rs_encode(&d_in[0], &d_in[d_k]);
-
-        memcpy(&out[i * out_bsize], &d_in[d_s], out_bsize);
+      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
diff --git a/gr-dtv/lib/dvbt/dvbt_reed_solomon_enc_impl.h 
b/gr-dtv/lib/dvbt/dvbt_reed_solomon_enc_impl.h
index 669ee27..47dea87 100644
--- a/gr-dtv/lib/dvbt/dvbt_reed_solomon_enc_impl.h
+++ b/gr-dtv/lib/dvbt/dvbt_reed_solomon_enc_impl.h
@@ -1,6 +1,6 @@
 /* -*- c++ -*- */
 /* 
- * Copyright 2015 Free Software Foundation, Inc.
+ * Copyright 2015,2016 Free Software Foundation, Inc.
  * 
  * This is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -22,7 +22,10 @@
 #define INCLUDED_DTV_DVBT_REED_SOLOMON_ENC_IMPL_H
 
 #include <gnuradio/dtv/dvbt_reed_solomon_enc.h>
-#include "dvbt_reed_solomon.h"
+
+extern "C" {
+#include <gnuradio/fec/rs.h>
+}
 
 namespace gr {
   namespace dtv {
@@ -30,18 +33,15 @@ namespace gr {
     class dvbt_reed_solomon_enc_impl : public dvbt_reed_solomon_enc
     {
      private:
-      int d_p;
-      int d_m;
-      int d_gfpoly;
       int d_n;
       int d_k;
-      int d_t;
       int d_s;
       int d_blocks;
 
-      unsigned char * d_in;
+      unsigned char *d_data;
 
-      dvbt_reed_solomon d_rs;
+      void *d_rs;    /* Reed-Solomon characteristics structure */
+      void encode(const unsigned char *in, unsigned char *out);
 
      public:
       dvbt_reed_solomon_enc_impl(int p, int m, int gfpoly, int n, int k, int 
t, int s, int blocks);



reply via email to

[Prev in Thread] Current Thread [Next in Thread]