[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 > 0</check>
- <check>$vlen >= 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 > 0</check>
+ <check>$vlen >= 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 > 0</check>
- <check>$vlen >= 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 > 0</check>
+ <check>$vlen >= 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);
- [Commit-gnuradio] [gnuradio] 19/57: volk: missing updates for volk qa and profile from last checkin., (continued)
- [Commit-gnuradio] [gnuradio] 19/57: volk: missing updates for volk qa and profile from last checkin., git, 2014/05/20
- [Commit-gnuradio] [gnuradio] 25/57: fec: encoder now outputs bytes to make it more easily integratable with modulators., git, 2014/05/20
- [Commit-gnuradio] [gnuradio] 21/57: fec: improved fecapi stuff., git, 2014/05/20
- [Commit-gnuradio] [gnuradio] 23/57: fec: wip: allowing ber block to be used as a streaming block., git, 2014/05/20
- [Commit-gnuradio] [gnuradio] 17/57: adding ber sink to qt gui, git, 2014/05/20
- [Commit-gnuradio] [gnuradio] 24/57: digital: use FFT filters for the correlate_and_sync block., git, 2014/05/20
- [Commit-gnuradio] [gnuradio] 27/57: grc: adding advanced tab feature to set a block's alias., git, 2014/05/20
- [Commit-gnuradio] [gnuradio] 29/57: grc: fixes bug with controlport monitors where true/false enable parameter is not respected., git, 2014/05/20
- [Commit-gnuradio] [gnuradio] 02/57: runtime: white space removal., git, 2014/05/20
- [Commit-gnuradio] [gnuradio] 31/57: fec: use logger to explain exception when using threading with history., git, 2014/05/20
- [Commit-gnuradio] [gnuradio] 26/57: fec: changed puncture block for easier to use API.,
git <=
- [Commit-gnuradio] [gnuradio] 18/57: volk: added conv kernel puppet and added to QA and profile., git, 2014/05/20
- [Commit-gnuradio] [gnuradio] 34/57: qtgui: work on ber sink for fecapi, git, 2014/05/20
- [Commit-gnuradio] [gnuradio] 35/57: runtime: don't add the log appender --> adds to C++, too., git, 2014/05/20
- [Commit-gnuradio] [gnuradio] 43/57: digital: added option to packet_utils.unmake_packet to check or not check the CRC., git, 2014/05/20
- [Commit-gnuradio] [gnuradio] 44/57: blocks: adds kernels for pack_k_bits and unpack_k_bits., git, 2014/05/20
- [Commit-gnuradio] [gnuradio] 30/57: runtime: configuring loggers in gr Python module for easy use in Python., git, 2014/05/20
- [Commit-gnuradio] [gnuradio] 39/57: digital: modified tagged stream correlate access code., git, 2014/05/20
- [Commit-gnuradio] [gnuradio] 37/57: Revert "blocks: add optional argument to deinterleave and interleave ctors to not set relative rate.", git, 2014/05/20
- [Commit-gnuradio] [gnuradio] 42/57: fec: wip: fixing formatting., git, 2014/05/20
- [Commit-gnuradio] [gnuradio] 32/57: blocks: add optional argument to deinterleave and interleave ctors to not set relative rate., git, 2014/05/20