commit-gnuradio
[Top][All Lists]
Advanced

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

[Commit-gnuradio] [gnuradio] 26/57: fec: changed puncture block for easi


From: git
Subject: [Commit-gnuradio] [gnuradio] 26/57: fec: changed puncture block for easier to use API.
Date: Wed, 21 May 2014 03:10:27 +0000 (UTC)

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

trondeau pushed a commit to branch master
in repository gnuradio.

commit 4c2cb19a23a0b608617330bba80dd19cbb0c37dc
Author: Tom Rondeau <address@hidden>
Date:   Fri May 2 12:48:34 2014 -0400

    fec: changed puncture block for easier to use API.
    
    Added documentation; added QA code.
---
 gr-blocks/grc/blocks_deinterleave.xml            | 128 ++++++------
 gr-blocks/grc/blocks_interleave.xml              | 128 ++++++------
 gr-blocks/include/gnuradio/blocks/deinterleave.h |  28 ++-
 gr-blocks/include/gnuradio/blocks/interleave.h   |  27 ++-
 gr-blocks/python/blocks/qa_interleave.py         |  43 ++--
 gr-fec/grc/fec_puncture_xx.xml                   |  27 +--
 gr-fec/include/gnuradio/fec/puncture_bb.h        |  63 +++++-
 gr-fec/include/gnuradio/fec/puncture_ff.h        |  62 +++++-
 gr-fec/lib/puncture_bb_impl.cc                   |  38 +++-
 gr-fec/lib/puncture_bb_impl.h                    |   5 +-
 gr-fec/lib/puncture_ff_impl.cc                   |  34 +++-
 gr-fec/lib/puncture_ff_impl.h                    |   5 +-
 gr-fec/python/fec/extended_decoder.py            |   5 +-
 gr-fec/python/fec/extended_encoder.py            |   4 +-
 gr-fec/python/fec/qa_puncture.py                 | 244 +++++++++++++++++++++++
 gr-fec/swig/fec_swig.i                           |   3 +
 16 files changed, 642 insertions(+), 202 deletions(-)

diff --git a/gr-blocks/grc/blocks_deinterleave.xml 
b/gr-blocks/grc/blocks_deinterleave.xml
index 6af6d3c..4ada49d 100644
--- a/gr-blocks/grc/blocks_deinterleave.xml
+++ b/gr-blocks/grc/blocks_deinterleave.xml
@@ -5,70 +5,70 @@
 ###################################################
  -->
 <block>
-       <name>Deinterleave</name>
-       <key>blocks_deinterleave</key>
-       <import>from gnuradio import blocks</import>
-       <make>blocks.deinterleave($type.size*$vlen, $blocksize)</make>
-       <param>
-               <name>IO Type</name>
-               <key>type</key>
-               <type>enum</type>
-               <option>
-                       <name>Complex</name>
-                       <key>complex</key>
-                       <opt>size:gr.sizeof_gr_complex</opt>
-               </option>
-               <option>
-                       <name>Float</name>
-                       <key>float</key>
-                       <opt>size:gr.sizeof_float</opt>
-               </option>
-               <option>
-                       <name>Int</name>
-                       <key>int</key>
-                       <opt>size:gr.sizeof_int</opt>
-               </option>
-               <option>
-                       <name>Short</name>
-                       <key>short</key>
-                       <opt>size:gr.sizeof_short</opt>
-               </option>
-               <option>
-                       <name>Byte</name>
-                       <key>byte</key>
-                       <opt>size:gr.sizeof_char</opt>
-               </option>
-       </param>
-       <param>
-               <name>Num Streams</name>
-               <key>num_streams</key>
-               <value>2</value>
-               <type>int</type>
-       </param>
+  <name>Deinterleave</name>
+  <key>blocks_deinterleave</key>
+  <import>from gnuradio import blocks</import>
+  <make>blocks.deinterleave($type.size*$vlen, $blocksize)</make>
   <param>
-               <name>Block Size</name>
-               <key>blocksize</key>
-               <value>1</value>
-               <type>int</type>
+    <name>IO Type</name>
+    <key>type</key>
+    <type>enum</type>
+    <option>
+      <name>Complex</name>
+      <key>complex</key>
+      <opt>size:gr.sizeof_gr_complex</opt>
+    </option>
+    <option>
+      <name>Float</name>
+      <key>float</key>
+      <opt>size:gr.sizeof_float</opt>
+    </option>
+    <option>
+      <name>Int</name>
+      <key>int</key>
+      <opt>size:gr.sizeof_int</opt>
+    </option>
+    <option>
+      <name>Short</name>
+      <key>short</key>
+      <opt>size:gr.sizeof_short</opt>
+    </option>
+    <option>
+      <name>Byte</name>
+      <key>byte</key>
+      <opt>size:gr.sizeof_char</opt>
+    </option>
+  </param>
+  <param>
+    <name>Num Streams</name>
+    <key>num_streams</key>
+    <value>2</value>
+    <type>int</type>
+  </param>
+  <param>
+    <name>Block Size</name>
+    <key>blocksize</key>
+    <value>1</value>
+    <type>int</type>
     <hide>part</hide>
-       </param>
-       <param>
-               <name>Vec Length</name>
-               <key>vlen</key>
-               <value>1</value>
-               <type>int</type>
-       </param>
-       <check>$num_streams &gt; 0</check>
-       <check>$vlen &gt;= 1</check>
-       <sink>
-               <name>in</name>
-               <type>$type</type>
-               <vlen>$vlen</vlen>
-       </sink>
-       <source>
-               <name>out</name>
-               <type>$type</type>
-               <vlen>$vlen</vlen>
-               <nports>$num_streams</nports>
-       </source>
+  </param>
+  <param>
+    <name>Vec Length</name>
+    <key>vlen</key>
+    <value>1</value>
+    <type>int</type>
+  </param>
+  <check>$num_streams &gt; 0</check>
+  <check>$vlen &gt;= 1</check>
+  <sink>
+    <name>in</name>
+    <type>$type</type>
+    <vlen>$vlen</vlen>
+  </sink>
+  <source>
+    <name>out</name>
+    <type>$type</type>
+    <vlen>$vlen</vlen>
+    <nports>$num_streams</nports>
+  </source>
 </block>
diff --git a/gr-blocks/grc/blocks_interleave.xml 
b/gr-blocks/grc/blocks_interleave.xml
index 675693b..69fb15e 100644
--- a/gr-blocks/grc/blocks_interleave.xml
+++ b/gr-blocks/grc/blocks_interleave.xml
@@ -5,70 +5,70 @@
 ###################################################
  -->
 <block>
-       <name>Interleave</name>
-       <key>blocks_interleave</key>
-       <import>from gnuradio import blocks</import>
-       <make>blocks.interleave($type.size*$vlen, $blocksize)</make>
-       <param>
-               <name>IO Type</name>
-               <key>type</key>
-               <type>enum</type>
-               <option>
-                       <name>Complex</name>
-                       <key>complex</key>
-                       <opt>size:gr.sizeof_gr_complex</opt>
-               </option>
-               <option>
-                       <name>Float</name>
-                       <key>float</key>
-                       <opt>size:gr.sizeof_float</opt>
-               </option>
-               <option>
-                       <name>Int</name>
-                       <key>int</key>
-                       <opt>size:gr.sizeof_int</opt>
-               </option>
-               <option>
-                       <name>Short</name>
-                       <key>short</key>
-                       <opt>size:gr.sizeof_short</opt>
-               </option>
-               <option>
-                       <name>Byte</name>
-                       <key>byte</key>
-                       <opt>size:gr.sizeof_char</opt>
-               </option>
-       </param>
-       <param>
-               <name>Num Streams</name>
-               <key>num_streams</key>
-               <value>2</value>
-               <type>int</type>
-       </param>
+  <name>Interleave</name>
+  <key>blocks_interleave</key>
+  <import>from gnuradio import blocks</import>
+  <make>blocks.interleave($type.size*$vlen, $blocksize)</make>
   <param>
-               <name>Block Size</name>
-               <key>blocksize</key>
-               <value>1</value>
-               <type>int</type>
+    <name>IO Type</name>
+    <key>type</key>
+    <type>enum</type>
+    <option>
+      <name>Complex</name>
+      <key>complex</key>
+      <opt>size:gr.sizeof_gr_complex</opt>
+    </option>
+    <option>
+      <name>Float</name>
+      <key>float</key>
+      <opt>size:gr.sizeof_float</opt>
+    </option>
+    <option>
+      <name>Int</name>
+      <key>int</key>
+      <opt>size:gr.sizeof_int</opt>
+    </option>
+    <option>
+      <name>Short</name>
+      <key>short</key>
+      <opt>size:gr.sizeof_short</opt>
+    </option>
+    <option>
+      <name>Byte</name>
+      <key>byte</key>
+      <opt>size:gr.sizeof_char</opt>
+    </option>
+  </param>
+  <param>
+    <name>Num Streams</name>
+    <key>num_streams</key>
+    <value>2</value>
+    <type>int</type>
+  </param>
+  <param>
+    <name>Block Size</name>
+    <key>blocksize</key>
+    <value>1</value>
+    <type>int</type>
     <hide>part</hide>
-       </param>
-       <param>
-               <name>Vec Length</name>
-               <key>vlen</key>
-               <value>1</value>
-               <type>int</type>
-       </param>
-       <check>$num_streams &gt; 0</check>
-       <check>$vlen &gt;= 1</check>
-       <sink>
-               <name>in</name>
-               <type>$type</type>
-               <vlen>$vlen</vlen>
-               <nports>$num_streams</nports>
-       </sink>
-       <source>
-               <name>out</name>
-               <type>$type</type>
-               <vlen>$vlen</vlen>
-       </source>
+  </param>
+  <param>
+    <name>Vec Length</name>
+    <key>vlen</key>
+    <value>1</value>
+    <type>int</type>
+  </param>
+  <check>$num_streams &gt; 0</check>
+  <check>$vlen &gt;= 1</check>
+  <sink>
+    <name>in</name>
+    <type>$type</type>
+    <vlen>$vlen</vlen>
+    <nports>$num_streams</nports>
+  </sink>
+  <source>
+    <name>out</name>
+    <type>$type</type>
+    <vlen>$vlen</vlen>
+  </source>
 </block>
diff --git a/gr-blocks/include/gnuradio/blocks/deinterleave.h 
b/gr-blocks/include/gnuradio/blocks/deinterleave.h
index a79649f..a3b5480 100644
--- a/gr-blocks/include/gnuradio/blocks/deinterleave.h
+++ b/gr-blocks/include/gnuradio/blocks/deinterleave.h
@@ -1,6 +1,6 @@
 /* -*- c++ -*- */
 /*
- * Copyright 2012 Free Software Foundation, Inc.
+ * Copyright 2012,2014 Free Software Foundation, Inc.
  *
  * This file is part of GNU Radio
  *
@@ -30,8 +30,31 @@ namespace gr {
   namespace blocks {
 
     /*!
-     * \brief deinterleave a single input into N outputs
+     * \brief deinterleave an input block of samples into N outputs.
      * \ingroup stream_operators_blk
+     *
+     * \details
+     * This block deinterleaves blocks of samples. For each output
+     * connection, the input stream will be deinterleaved successively
+     * to the output connections. By default, the block deinterleaves
+     * a single input to each output unless blocksize is given in the
+     * constructor.
+     *
+     * \code
+     *   blocksize = 1
+     *   connections = 2
+     *   input = [a, b, c, d, e, f, g, h]
+     *   output[0] = [a, c, e, g]
+     *   output[1] = [b, d, f, h]
+     * \endcode
+     *
+     * \code
+     *   blocksize = 2
+     *   connections = 2
+     *   input = [a, b, c, d, e, f, g, h]
+     *   output[0] = [a, b, e, f]
+     *   output[1] = [c, d, g, h]
+     * \endcode
      */
     class BLOCKS_API deinterleave : virtual public block
     {
@@ -43,6 +66,7 @@ namespace gr {
        * Make a deinterleave block.
        *
        * \param itemsize stream itemsize
+       * \param blocksize size of block to deinterleave
        */
       static sptr make(size_t itemsize, unsigned int blocksize = 1);
     };
diff --git a/gr-blocks/include/gnuradio/blocks/interleave.h 
b/gr-blocks/include/gnuradio/blocks/interleave.h
index 811c3e3..7f7587d 100644
--- a/gr-blocks/include/gnuradio/blocks/interleave.h
+++ b/gr-blocks/include/gnuradio/blocks/interleave.h
@@ -1,6 +1,6 @@
 /* -*- c++ -*- */
 /*
- * Copyright 2012 Free Software Foundation, Inc.
+ * Copyright 2012,2014 Free Software Foundation, Inc.
  *
  * This file is part of GNU Radio
  *
@@ -32,6 +32,30 @@ namespace gr {
     /*!
      * \brief interleave N inputs into a single output
      * \ingroup stream_operators_blk
+     *
+     * \details
+     *
+     * This block interleaves blocks of samples. For each input
+     * connection, the samples are interleaved successively to the
+     * output connection. By default, the block interleaves a single
+     * sample from eahc input to the output unless blocksize is given
+     * in the constructor.
+     *
+     * \code
+     *   blocksize = 1
+     *   connections = 2
+     *   input[0] = [a, c, e, g]
+     *   input[1] = [b, d, f, h]
+     *   output = [a, b, c, d, e, f, g, h]
+     * \endcode
+     *
+     * \code
+     *   blocksize = 2
+     *   connections = 2
+     *   input[0] = [a, b, e, f]
+     *   input[1] = [c, d, g, h]
+     *   output = [a, b, c, d, e, f, g, h]
+     * \endcode
      */
     class BLOCKS_API interleave : virtual public block
     {
@@ -43,6 +67,7 @@ namespace gr {
        * Make a stream interleave block.
        *
        * \param itemsize stream itemsize
+       * \param blocksize size of block of samples to interleave
        */
       static sptr make(size_t itemsize, unsigned int blocksize = 1);
     };
diff --git a/gr-blocks/python/blocks/qa_interleave.py 
b/gr-blocks/python/blocks/qa_interleave.py
index d2a04cc..526e4a4 100755
--- a/gr-blocks/python/blocks/qa_interleave.py
+++ b/gr-blocks/python/blocks/qa_interleave.py
@@ -1,6 +1,6 @@
 #!/usr/bin/env python
 #
-# Copyright 2004,2007,2010,2012,2013 Free Software Foundation, Inc.
+# Copyright 2004,2007,2010,2012-2014 Free Software Foundation, Inc.
 #
 # This file is part of GNU Radio
 #
@@ -50,17 +50,17 @@ class test_interleave (gr_unittest.TestCase):
         self.assertFloatTuplesAlmostEqual (expected_result, result_data)
 
     def test_int_002 (self):
-        blksize = 4;
-        lenx = 64;
-        plusup_big = lambda a: a + (blksize * 4);
-        plusup_little = lambda a: a + blksize;
-        a_vec = range(0,blksize);
+        blksize = 4
+        lenx = 64
+        plusup_big = lambda a: a + (blksize * 4)
+        plusup_little = lambda a: a + blksize
+        a_vec = range(0,blksize)
         for i in range(0,(lenx/(4 * blksize)) - 1):
-            a_vec += map(plusup_big, a_vec[len(a_vec) - blksize:]);
-        
-        b_vec = map(plusup_little, a_vec);
-        c_vec = map(plusup_little, b_vec);
-        d_vec = map(plusup_little, c_vec);
+            a_vec += map(plusup_big, a_vec[len(a_vec) - blksize:])
+
+        b_vec = map(plusup_little, a_vec)
+        c_vec = map(plusup_little, b_vec)
+        d_vec = map(plusup_little, c_vec)
 
         src0 = blocks.vector_source_f (a_vec)
         src1 = blocks.vector_source_f (b_vec)
@@ -107,8 +107,8 @@ class test_interleave (gr_unittest.TestCase):
         self.assertFloatTuplesAlmostEqual (expected_result3, dst3.data ())
 
     def test_deint_002 (self):
-        blksize = 4;
-        lenx = 64;
+        blksize = 4
+        lenx = 64
         src = blocks.vector_source_f (range (lenx))
         op = blocks.deinterleave (gr.sizeof_float, blksize)
         dst0 = blocks.vector_sink_f ()
@@ -123,15 +123,15 @@ class test_interleave (gr_unittest.TestCase):
         self.tb.connect ((op, 3), dst3)
         self.tb.run ()
 
-        plusup_big = lambda a: a + (blksize * 4);
-        plusup_little = lambda a: a + blksize;
-        a_vec = range(0,blksize);
+        plusup_big = lambda a: a + (blksize * 4)
+        plusup_little = lambda a: a + blksize
+        a_vec = range(0,blksize)
         for i in range(0,(lenx/(4 * blksize)) - 1):
-            a_vec += map(plusup_big, a_vec[len(a_vec) - blksize:]);
-        
-        b_vec = map(plusup_little, a_vec);
-        c_vec = map(plusup_little, b_vec);
-        d_vec = map(plusup_little, c_vec);
+            a_vec += map(plusup_big, a_vec[len(a_vec) - blksize:])
+
+        b_vec = map(plusup_little, a_vec)
+        c_vec = map(plusup_little, b_vec)
+        d_vec = map(plusup_little, c_vec)
 
         expected_result0 = tuple (a_vec)
         expected_result1 = tuple (b_vec)
@@ -145,4 +145,3 @@ class test_interleave (gr_unittest.TestCase):
 
 if __name__ == '__main__':
     gr_unittest.run(test_interleave, "test_interleave.xml")
-
diff --git a/gr-fec/grc/fec_puncture_xx.xml b/gr-fec/grc/fec_puncture_xx.xml
index 0bc5558..8ad9b0c 100644
--- a/gr-fec/grc/fec_puncture_xx.xml
+++ b/gr-fec/grc/fec_puncture_xx.xml
@@ -3,27 +3,27 @@
   <name>Puncture</name>
   <key>fec_puncture_xx</key>
   <import>from gnuradio import fec</import>
-  <make>fec.puncture_$(type.fcn)($delay, $puncpat, $puncholes, 
$puncsize)</make>
+  <make>fec.puncture_$(type.fcn)($puncsize, $puncpat, $puncholes, 
$delay)</make>
 
   <param>
     <name>Type</name>
     <key>type</key>
     <type>enum</type>
     <option>
-      <name>Float</name>
-      <key>float</key>
-      <opt>fcn:ff</opt>
-    </option>
-    <option>
       <name>Byte</name>
       <key>byte</key>
       <opt>fcn:bb</opt>
     </option>
+    <option>
+      <name>Float</name>
+      <key>float</key>
+      <opt>fcn:ff</opt>
+    </option>
   </param>
 
   <param>
-    <name>Delay</name>
-    <key>delay</key>
+    <name>Puncture Size</name>
+    <key>puncsize</key>
     <type>int</type>
   </param>
 
@@ -34,14 +34,9 @@
   </param>
 
   <param>
-    <name>Puncture Holes</name>
-    <key>puncholes</key>
-    <type>int</type>
-  </param>
-
-  <param>
-    <name>Puncture Size</name>
-    <key>puncsize</key>
+    <name>Delay</name>
+    <key>delay</key>
+    <value>0</value>
     <type>int</type>
   </param>
 
diff --git a/gr-fec/include/gnuradio/fec/puncture_bb.h 
b/gr-fec/include/gnuradio/fec/puncture_bb.h
index b3d3db7..b803297 100644
--- a/gr-fec/include/gnuradio/fec/puncture_bb.h
+++ b/gr-fec/include/gnuradio/fec/puncture_bb.h
@@ -29,13 +29,74 @@
 namespace gr {
   namespace fec {
 
+    /*!
+     * \brief Puncture a stream of unpacked bits.
+     * \ingroup error_coding_blk
+     *
+     * \details
+     * For a given block of input samples of \p puncsize, the items
+     * produced is based on \p puncpat. Basically, if:
+     *
+     * \code
+     *    k = 0
+     *    if _puncpat[i] == 1:
+     *       out[k++] = input[i]
+     * \endcode
+     *
+     * This block is designed for unpacked bits - that is, every
+     * input sample is a bit, either a 1 or 0. It's possible to use
+     * packed bits as symbols, but the puncturing will be done on
+     * the symbol level, not the bit level.
+     *
+     * \p puncpat is specified as a 32-bit integer that we can
+     * convert into the vector _puncpat used in the algorithm above:
+     *
+     * \code
+     *    _puncpat = [0,...]
+     *    for i in puncsize:
+     *        _puncpat[i] = puncpat >> (puncsize-1-i)
+     * \endcode
+     *
+     * Example:
+     * \code
+     *    puncsize = 8
+     *    puncpat = 0xEF  -->  [1,1,1,0,1,1,1,1]
+     *    input = [a, b, c, d, e, f, g, h]
+     *    output = [a, b, c, e, f, g, h]
+     * \endcode
+     *
+     * The gr.fec Python module provides a read_bitlist function
+     * that can turn a string of a puncture pattern into the correct
+     * integer form. The pattern of 0xEF could be specified as
+     * fec.readbitlist("11101111"). Also, this allows us to use
+     * puncsize=len("11101111") to make sure that our sizes are set
+     * up correctly for the pattern we want.
+     *
+     * The fec.extended_encoder takes in the puncture pattern
+     * directly as a string and uses the readbitlist inside to do
+     * the conversion.
+     *
+     * The \p delay parameter delays the application of the puncture
+     * pattern. This is equivalent to circularly rotating the \p
+     * puncpat by \p delay. Note that because of the circular shift,
+     * the delay should be between 0 and \p puncsize, but this is
+     * not enforced; the effective delay will simply be \p delay mod
+     * \p puncsize. A negative value here is ignored.
+     */
     class FEC_API puncture_bb : virtual public block
     {
     public:
       // gr::fec::puncture_bb::sptr
       typedef boost::shared_ptr<puncture_bb> sptr;
 
-      static sptr make(int delay, int puncpat, int puncholes, int puncsize);
+      /*!
+       * \brief Constructs a puncture block for unpacked bits.
+       *
+       * \param puncsize Size of block of bits to puncture
+       * \param puncpat The puncturing pattern
+       * \param delay Delayed the puncturing pattern by shifting it
+       */
+      static sptr make(int puncsize, int puncpat, int delay=0);
     };
 
   } /* namespace fec */
diff --git a/gr-fec/include/gnuradio/fec/puncture_ff.h 
b/gr-fec/include/gnuradio/fec/puncture_ff.h
index 927fc0b..8625ab4 100644
--- a/gr-fec/include/gnuradio/fec/puncture_ff.h
+++ b/gr-fec/include/gnuradio/fec/puncture_ff.h
@@ -29,13 +29,73 @@
 namespace gr {
   namespace fec {
 
+    /*!
+     * \brief Puncture a stream of floats.
+     * \ingroup error_coding_blk
+     *
+     * \details
+     * For a given block of input samples of \p puncsize, the items
+     * produced is based on \p puncpat. Basically, if:
+     *
+     * \code
+     *    k = 0
+     *    if _puncpat[i] == 1:
+     *       out[k++] = input[i]
+     * \endcode
+     *
+     * This block is designed for floats, generally 1's and -1's. It's
+     * possible to use other float values as symbols, but this is not
+     * the expected operation.
+     *
+     * \p puncpat is specified as a 32-bit integer that we can
+     * convert into the vector _puncpat used in the algorithm above:
+     *
+     * \code
+     *    _puncpat = [0,...]
+     *    for i in puncsize:
+     *        _puncpat[i] = puncpat >> (puncsize-1-i)
+     * \endcode
+     *
+     * Example:
+     * \code
+     *    puncsize = 8
+     *    puncpat = 0xEF  -->  [1,1,1,0,1,1,1,1]
+     *    input = [a, b, c, d, e, f, g, h]
+     *    output = [a, b, c, e, f, g, h]
+     * \endcode
+     *
+     * The gr.fec Python module provides a read_bitlist function
+     * that can turn a string of a puncture pattern into the correct
+     * integer form. The pattern of 0xEF could be specified as
+     * fec.readbitlist("11101111"). Also, this allows us to use
+     * puncsize=len("11101111") to make sure that our sizes are set
+     * up correctly for the pattern we want.
+     *
+     * The fec.extended_encoder takes in the puncture pattern
+     * directly as a string and uses the readbitlist inside to do
+     * the conversion.
+     *
+     * The \p delay parameter delays the application of the puncture
+     * pattern. This is equivalent to circularly rotating the \p
+     * puncpat by \p delay. Note that because of the circular shift,
+     * the delay should be between 0 and \p puncsize, but this is
+     * not enforced; the effective delay will simply be \p delay mod
+     * \p puncsize. A negative value here is ignored.
+     */
     class FEC_API puncture_ff : virtual public block
     {
     public:
       // gr::fec::puncture_ff::sptr
       typedef boost::shared_ptr<puncture_ff> sptr;
 
-      static sptr make(int delay, int puncpat, int puncholes, int puncsize);
+      /*!
+       * \brief Constructs a puncture block for floats.
+       *
+       * \param puncsize Size of block of bits to puncture
+       * \param puncpat The puncturing pattern
+       * \param delay Delayed the puncturing pattern by shifting it
+       */
+      static sptr make(int puncsize, int puncpat, int delay);
     };
 
   } /* namespace fec */
diff --git a/gr-fec/lib/puncture_bb_impl.cc b/gr-fec/lib/puncture_bb_impl.cc
index 2fedc77..63633b2 100644
--- a/gr-fec/lib/puncture_bb_impl.cc
+++ b/gr-fec/lib/puncture_bb_impl.cc
@@ -26,6 +26,7 @@
 
 #include "puncture_bb_impl.h"
 #include <gnuradio/io_signature.h>
+#include <volk/volk.h>
 #include <boost/bind.hpp>
 #include <pmt/pmt.h>
 #include <string>
@@ -35,25 +36,39 @@ namespace gr {
   namespace fec {
 
     puncture_bb::sptr
-    puncture_bb::make(int delay, int puncpat,
-                      int puncholes, int puncsize)
+    puncture_bb::make(int puncsize, int puncpat, int delay)
     {
       return gnuradio::get_initial_sptr
-        (new puncture_bb_impl(delay, puncpat,
-                              puncholes, puncsize));
+        (new puncture_bb_impl(puncsize, puncpat, delay));
     }
 
-    puncture_bb_impl::puncture_bb_impl(int delay, int puncpat,
-                                       int puncholes, int puncsize)
+    puncture_bb_impl::puncture_bb_impl(int puncsize, int puncpat, int delay)
       : block("puncture_bb",
               io_signature::make(1, 1, sizeof(char)),
               io_signature::make(1, 1, sizeof(char))),
-        d_delay(delay), d_puncholes(puncholes), d_puncsize(puncsize)
+        d_puncsize(puncsize), d_delay(delay)
     {
+      // Create a mask of all 1's of puncsize length
+      int mask = 0;
+      for(int i = 0; i < d_puncsize; i++)
+        mask |= 1 << i;
+
+      // Rotate the pattern for the delay value; then mask it if there
+      // are any excess 1's in the pattern.
       for(int i = 0; i < d_delay; ++i) {
        puncpat = ((puncpat & 1) << (d_puncsize - 1)) + (puncpat >> 1);
       }
-      d_puncpat = puncpat;
+      d_puncpat = puncpat & mask;
+
+      // Calculate the number of holes in the pattern. The mask is all
+      // 1's given puncsize and puncpat is a pattern with >= puncsize
+      // 0's (masked to ensure this). The difference between the
+      // number of 1's in the mask and the puncpat is the number of
+      // holes.
+      uint32_t count_mask=0, count_pat=0;
+      volk_32u_popcnt(&count_mask, static_cast<uint32_t>(mask));
+      volk_32u_popcnt(&count_pat, static_cast<uint32_t>(d_puncpat));
+      d_puncholes = count_mask - count_pat;
 
       set_fixed_rate(true);
       set_relative_rate((double)(d_puncsize - d_puncholes)/d_puncsize);
@@ -112,14 +127,15 @@ namespace gr {
         }
       }
 
+      /*
       GR_LOG_DEBUG(d_debug_logger, ">>>>>> start");
       for(int i = 0, k=0; i < noutput_items; ++i) {
         if((d_puncpat >> (d_puncsize - 1 - (i % d_puncsize))) & 1) {
-         GR_LOG_DEBUG(d_debug_logger, boost::format("%1%...%2%") \
+          GR_LOG_DEBUG(d_debug_logger, boost::format("%1%...%2%") \
                        % out[k++] % in[i]);
         }
         else {
-         GR_LOG_DEBUG(d_debug_logger, boost::format("snit %1%") % in[i]);
+          GR_LOG_DEBUG(d_debug_logger, boost::format("snit %1%") % in[i]);
         }
       }
 
@@ -127,6 +143,7 @@ namespace gr {
                    % noutput_items % ninput_items[0]);
       GR_LOG_DEBUG(d_debug_logger, boost::format("consuming %1%") \
                    % ((int)(((1.0/relative_rate()) * noutput_items) + .5)));
+      */
 
       consume_each((int)(((1.0/relative_rate()) * noutput_items) + .5));
       return noutput_items;
@@ -134,4 +151,3 @@ namespace gr {
 
   } /* namespace fec */
 }/* namespace gr */
-
diff --git a/gr-fec/lib/puncture_bb_impl.h b/gr-fec/lib/puncture_bb_impl.h
index 6480a74..abf9c09 100644
--- a/gr-fec/lib/puncture_bb_impl.h
+++ b/gr-fec/lib/puncture_bb_impl.h
@@ -31,14 +31,13 @@ namespace gr {
     class FEC_API puncture_bb_impl : public puncture_bb
     {
     private:
+      int d_puncsize;
       int d_delay;
       int d_puncholes;
-      int d_puncsize;
       int d_puncpat;
 
     public:
-      puncture_bb_impl(int delay, int puncpat,
-                       int puncholes, int puncsize);
+      puncture_bb_impl(int puncsize, int puncpat, int delay=0);
       ~puncture_bb_impl();
 
       //void catch_msg(pmt::pmt_t msg);
diff --git a/gr-fec/lib/puncture_ff_impl.cc b/gr-fec/lib/puncture_ff_impl.cc
index a534bef..9a7c8f6 100644
--- a/gr-fec/lib/puncture_ff_impl.cc
+++ b/gr-fec/lib/puncture_ff_impl.cc
@@ -26,6 +26,7 @@
 
 #include "puncture_ff_impl.h"
 #include <gnuradio/io_signature.h>
+#include <volk/volk.h>
 #include <boost/bind.hpp>
 #include <pmt/pmt.h>
 #include <string>
@@ -35,25 +36,39 @@ namespace gr {
   namespace fec {
 
     puncture_ff::sptr
-    puncture_ff::make(int delay, int puncpat,
-                      int puncholes, int puncsize)
+    puncture_ff::make(int puncsize, int puncpat, int delay)
     {
       return gnuradio::get_initial_sptr
-        (new puncture_ff_impl(delay, puncpat,
-                              puncholes, puncsize));
+        (new puncture_ff_impl(puncsize, puncpat, delay));
     }
 
-    puncture_ff_impl::puncture_ff_impl(int delay, int puncpat,
-                                       int puncholes, int puncsize)
+    puncture_ff_impl::puncture_ff_impl(int puncsize, int puncpat, int delay)
       : block("puncture_ff",
               io_signature::make(1, 1, sizeof(float)),
               io_signature::make(1, 1, sizeof(float))),
-        d_delay(delay), d_puncholes(puncholes), d_puncsize(puncsize)
+        d_puncsize(puncsize), d_delay(delay)
     {
+      // Create a mask of all 1's of puncsize length
+      int mask = 0;
+      for(int i = 0; i < d_puncsize; i++)
+        mask |= 1 << i;
+
+      // Rotate the pattern for the delay value; then mask it if there
+      // are any excess 1's in the pattern.
       for(int i = 0; i < d_delay; ++i) {
        puncpat = ((puncpat & 1) << (d_puncsize - 1)) + (puncpat >> 1);
       }
-      d_puncpat = puncpat;
+      d_puncpat = puncpat & mask;
+
+      // Calculate the number of holes in the pattern. The mask is all
+      // 1's given puncsize and puncpat is a pattern with >= puncsize
+      // 0's (masked to ensure this). The difference between the
+      // number of 1's in the mask and the puncpat is the number of
+      // holes.
+      uint32_t count_mask=0, count_pat=0;
+      volk_32u_popcnt(&count_mask, static_cast<uint32_t>(mask));
+      volk_32u_popcnt(&count_pat, static_cast<uint32_t>(d_puncpat));
+      d_puncholes = count_mask - count_pat;
 
       set_fixed_rate(true);
       set_relative_rate((double)(d_puncsize - d_puncholes)/d_puncsize);
@@ -112,6 +127,7 @@ namespace gr {
         }
       }
 
+      /*
       GR_LOG_DEBUG(d_debug_logger, ">>>>>> start");
       for(int i = 0, k=0; i < noutput_items; ++i) {
         if((d_puncpat >> (d_puncsize - 1 - (i % d_puncsize))) & 1) {
@@ -127,6 +143,7 @@ namespace gr {
                    % noutput_items % ninput_items[0]);
       GR_LOG_DEBUG(d_debug_logger, boost::format("consuming %1%") \
                    % ((int)(((1.0/relative_rate()) * noutput_items) + .5)));
+      */
 
       consume_each((int)(((1.0/relative_rate()) * noutput_items) + .5));
       return noutput_items;
@@ -134,4 +151,3 @@ namespace gr {
 
   } /* namespace fec */
 }/* namespace gr */
-
diff --git a/gr-fec/lib/puncture_ff_impl.h b/gr-fec/lib/puncture_ff_impl.h
index bea6673..e86d0d2 100644
--- a/gr-fec/lib/puncture_ff_impl.h
+++ b/gr-fec/lib/puncture_ff_impl.h
@@ -31,14 +31,13 @@ namespace gr {
     class FEC_API puncture_ff_impl : public puncture_ff
     {
     private:
+      int d_puncsize;
       int d_delay;
       int d_puncholes;
-      int d_puncsize;
       int d_puncpat;
 
     public:
-      puncture_ff_impl(int delay, int puncpat,
-                       int puncholes, int puncsize);
+      puncture_ff_impl(int puncsize, int puncpat, int delay);
       ~puncture_ff_impl();
 
       //void catch_msg(pmt::pmt_t msg);
diff --git a/gr-fec/python/fec/extended_decoder.py 
b/gr-fec/python/fec/extended_decoder.py
index 7f08a10..dafedd8 100644
--- a/gr-fec/python/fec/extended_decoder.py
+++ b/gr-fec/python/fec/extended_decoder.py
@@ -22,6 +22,7 @@
 
 from gnuradio import gr, blocks, digital
 import fec_swig as fec
+from bitflip import *
 
 from threaded_decoder import threaded_decoder
 from capillary_threaded_decoder import capillary_threaded_decoder
@@ -123,8 +124,8 @@ class extended_decoder(gr.hier_block2):
 
         #print puncpat
         if self.puncpat != '11':
-            self.blocks.append(fec.reinflate_bb(0, fec.read_bitlist(puncpat),
-                                                puncpat.count('0'), 
len(puncpat)))
+            self.blocks.append(fec.depuncture_bb(0, read_bitlist(puncpat),
+                                                 puncpat.count('0'), 
len(puncpat)))
 
         if fec.get_conversion(decoder_obj_list[0]) == "packed_bits":
             self.blocks.append(blocks.uchar_to_float())
diff --git a/gr-fec/python/fec/extended_encoder.py 
b/gr-fec/python/fec/extended_encoder.py
index 0e4bc09..b2dcc26 100644
--- a/gr-fec/python/fec/extended_encoder.py
+++ b/gr-fec/python/fec/extended_encoder.py
@@ -49,8 +49,7 @@ class extended_encoder(gr.hier_block2):
                                            gr.sizeof_char))
 
         if self.puncpat != '11':
-            self.blocks.append(fec.puncture_bb(0, read_bitlist(puncpat),
-                                               puncpat.count('0'), 
len(puncpat)))
+            self.blocks.append(fec.puncture_bb(len(puncpat), 
read_bitlist(puncpat), 0))
 
         # Connect the input to the encoder and the output to the
         # puncture if used or the encoder if not.
@@ -61,4 +60,3 @@ class extended_encoder(gr.hier_block2):
         # the encoder.
         for i in range(len(self.blocks) - 1):
             self.connect((self.blocks[i], 0), (self.blocks[i+1], 0));
-
diff --git a/gr-fec/python/fec/qa_puncture.py b/gr-fec/python/fec/qa_puncture.py
new file mode 100644
index 0000000..fdd15c9
--- /dev/null
+++ b/gr-fec/python/fec/qa_puncture.py
@@ -0,0 +1,244 @@
+#!/usr/bin/env python
+#
+# Copyright 2014 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio 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.
+#
+# GNU Radio 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 GNU Radio; see the file COPYING.  If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+from gnuradio import gr, gr_unittest
+import fec_swig as fec
+import blocks_swig as blocks
+from collections import deque
+
+class test_puncture (gr_unittest.TestCase):
+
+    def puncture_setup(self):
+        p = []
+        for i in range(self.puncsize):
+            p.append(self.puncpat >> (self.puncsize - 1 - i) & 1)
+        d = deque(p)
+        d.rotate(self.delay)
+        _puncpat = list(d)
+
+        self.expected = []
+        for n in range(len(self.src_data)/self.puncsize):
+            for i in range(self.puncsize):
+                if _puncpat[i] == 1:
+                    self.expected.append(self.src_data[n*self.puncsize+i]);
+
+    def setUp(self):
+        self.src_data = 10000*range(64)
+        self.tb = gr.top_block()
+
+    def tearDown(self):
+        self.tb = None
+
+    def test_000(self):
+        # Test normal operation of the puncture block
+
+        self.puncsize = 8
+        self.puncpat = 0xEF
+        self.delay = 0
+
+        self.puncture_setup()
+
+        src = blocks.vector_source_b(self.src_data)
+       op  = fec.puncture_bb(self.puncsize, self.puncpat, self.delay)
+       dst = blocks.vector_sink_b()
+
+       self.tb.connect(src, op, dst)
+       self.tb.run()
+
+       dst_data = list(dst.data())
+        for i in xrange(len(dst_data)):
+            dst_data[i] = int(dst_data[i])
+
+        self.assertEqual(self.expected, dst_data)
+
+
+    def test_001(self):
+        # Test normal operation of the puncture block with a delay
+
+        self.puncsize = 8
+        self.puncpat = 0xEE
+        self.delay = 1
+
+        self.src_data = range(16)
+
+        self.puncture_setup()
+
+        src = blocks.vector_source_b(self.src_data)
+       op  = fec.puncture_bb(self.puncsize, self.puncpat, self.delay)
+       dst = blocks.vector_sink_b()
+
+       self.tb.connect(src, op, dst)
+       self.tb.run()
+
+       dst_data = list(dst.data())
+        for i in xrange(len(dst_data)):
+            dst_data[i] = int(dst_data[i])
+
+        self.assertEqual(self.expected, dst_data)
+
+
+    def test_002(self):
+        # Test scenario where we have defined a puncture pattern with
+        # more bits than the puncsize.
+
+        self.puncsize = 4
+        self.puncpat = 0x5555
+        self.delay = 0
+
+        self.puncture_setup()
+
+        src = blocks.vector_source_b(self.src_data)
+       op  = fec.puncture_bb(self.puncsize, self.puncpat, self.delay)
+       dst = blocks.vector_sink_b()
+
+       self.tb.connect(src, op, dst)
+       self.tb.run()
+
+       dst_data = list(dst.data())
+        for i in xrange(len(dst_data)):
+            dst_data[i] = int(dst_data[i])
+
+        self.assertEqual(self.expected, dst_data)
+
+    def test_003(self):
+        # Test scenario where we have defined a puncture pattern with
+        # more bits than the puncsize with a delay. The python code
+        # doesn't account for this when creating self.expected, but
+        # this should be equivalent to a puncpat of the correct size.
+
+        self.puncsize = 4
+        self.puncpat0 = 0x5555 # too many bits set
+        self.puncpat1 = 0x55   # num bits = puncsize
+        self.delay = 1
+
+        src = blocks.vector_source_b(self.src_data)
+       op0  = fec.puncture_bb(self.puncsize, self.puncpat0, self.delay)
+       op1  = fec.puncture_bb(self.puncsize, self.puncpat1, self.delay)
+       dst0 = blocks.vector_sink_b()
+       dst1 = blocks.vector_sink_b()
+
+       self.tb.connect(src, op0, dst0)
+       self.tb.connect(src, op1, dst1)
+       self.tb.run()
+
+       dst_data0 = list(dst0.data())
+        for i in xrange(len(dst_data0)):
+            dst_data0[i] = int(dst_data0[i])
+
+       dst_data1 = list(dst1.data())
+        for i in xrange(len(dst_data1)):
+            dst_data1[i] = int(dst_data1[i])
+
+        self.assertEqual(dst_data1, dst_data0)
+
+
+
+    def test_f_000(self):
+        # Test normal operation of the float puncture block
+
+        self.puncsize = 8
+        self.puncpat = 0xEF
+        self.delay = 0
+
+        self.puncture_setup()
+
+        src = blocks.vector_source_f(self.src_data)
+       op  = fec.puncture_ff(self.puncsize, self.puncpat, self.delay)
+       dst = blocks.vector_sink_f()
+
+       self.tb.connect(src, op, dst)
+       self.tb.run()
+
+       dst_data = list(dst.data())
+        self.assertEqual(self.expected, dst_data)
+
+
+    def test_f_001(self):
+        # Test normal operation of the puncture block with a delay
+
+        self.puncsize = 8
+        self.puncpat = 0xEE
+        self.delay = 1
+
+        self.src_data = range(16)
+
+        self.puncture_setup()
+
+        src = blocks.vector_source_f(self.src_data)
+       op  = fec.puncture_ff(self.puncsize, self.puncpat, self.delay)
+       dst = blocks.vector_sink_f()
+
+       self.tb.connect(src, op, dst)
+       self.tb.run()
+
+       dst_data = list(dst.data())
+        self.assertEqual(self.expected, dst_data)
+
+
+    def test_f_002(self):
+        # Test scenariou where we have defined a puncture pattern with
+        # more bits than the puncsize.
+
+        self.puncsize = 4
+        self.puncpat = 0x5555
+        self.delay = 0
+
+        self.puncture_setup()
+
+        src = blocks.vector_source_f(self.src_data)
+       op  = fec.puncture_ff(self.puncsize, self.puncpat, self.delay)
+       dst = blocks.vector_sink_f()
+
+       self.tb.connect(src, op, dst)
+       self.tb.run()
+
+       dst_data = list(dst.data())
+        self.assertEqual(self.expected, dst_data)
+
+    def test_f_003(self):
+        # Test scenariou where we have defined a puncture pattern with
+        # more bits than the puncsize with a delay. The python code
+        # doesn't account for this when creating self.expected, but
+        # this should be equivalent to a puncpat of the correct size.
+
+        self.puncsize = 4
+        self.puncpat0 = 0x5555 # too many bits set
+        self.puncpat1 = 0x55   # num bits = puncsize
+        self.delay = 1
+
+        src = blocks.vector_source_f(self.src_data)
+       op0  = fec.puncture_ff(self.puncsize, self.puncpat0, self.delay)
+       op1  = fec.puncture_ff(self.puncsize, self.puncpat1, self.delay)
+       dst0 = blocks.vector_sink_f()
+       dst1 = blocks.vector_sink_f()
+
+       self.tb.connect(src, op0, dst0)
+       self.tb.connect(src, op1, dst1)
+       self.tb.run()
+
+       dst_data0 = list(dst0.data())
+       dst_data1 = list(dst1.data())
+
+        self.assertEqual(dst_data1, dst_data0)
+
+if __name__ == '__main__':
+    gr_unittest.run(test_puncture, "test_puncture.xml")
diff --git a/gr-fec/swig/fec_swig.i b/gr-fec/swig/fec_swig.i
index 506ea99..e3cbd33 100644
--- a/gr-fec/swig/fec_swig.i
+++ b/gr-fec/swig/fec_swig.i
@@ -44,6 +44,7 @@
 #include "gnuradio/fec/encode_ccsds_27_bb.h"
 #include "gnuradio/fec/ber_bf.h"
 #include "gnuradio/fec/conv_bit_corr_bb.h"
+#include "gnuradio/fec/puncture_bb.h"
 #include "gnuradio/fec/puncture_ff.h"
 #include "gnuradio/fec/depuncture_bb.h"
 %}
@@ -58,6 +59,7 @@
 %include "gnuradio/fec/encode_ccsds_27_bb.h"
 %include "gnuradio/fec/ber_bf.h"
 %include "gnuradio/fec/conv_bit_corr_bb.h"
+%include "gnuradio/fec/puncture_bb.h"
 %include "gnuradio/fec/puncture_ff.h"
 %include "gnuradio/fec/depuncture_bb.h"
 
@@ -67,5 +69,6 @@ GR_SWIG_BLOCK_MAGIC2(fec, decode_ccsds_27_fb);
 GR_SWIG_BLOCK_MAGIC2(fec, encode_ccsds_27_bb);
 GR_SWIG_BLOCK_MAGIC2(fec, ber_bf);
 GR_SWIG_BLOCK_MAGIC2(fec, conv_bit_corr_bb);
+GR_SWIG_BLOCK_MAGIC2(fec, puncture_bb);
 GR_SWIG_BLOCK_MAGIC2(fec, puncture_ff);
 GR_SWIG_BLOCK_MAGIC2(fec, depuncture_bb);



reply via email to

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