summaryrefslogtreecommitdiff
path: root/gr-fec
diff options
context:
space:
mode:
authorTom Rondeau <tom@trondeau.com>2014-05-02 12:48:34 -0400
committerTom Rondeau <tom@trondeau.com>2014-05-17 17:45:14 -0400
commit4c2cb19a23a0b608617330bba80dd19cbb0c37dc (patch)
tree13045f35312e64677a1a95029bb715158b6223eb /gr-fec
parentdd62061699a53e535f57a0ce0587bf1485db734f (diff)
fec: changed puncture block for easier to use API.
Added documentation; added QA code.
Diffstat (limited to 'gr-fec')
-rw-r--r--gr-fec/grc/fec_puncture_xx.xml27
-rw-r--r--gr-fec/include/gnuradio/fec/puncture_bb.h63
-rw-r--r--gr-fec/include/gnuradio/fec/puncture_ff.h62
-rw-r--r--gr-fec/lib/puncture_bb_impl.cc38
-rw-r--r--gr-fec/lib/puncture_bb_impl.h5
-rw-r--r--gr-fec/lib/puncture_ff_impl.cc34
-rw-r--r--gr-fec/lib/puncture_ff_impl.h5
-rw-r--r--gr-fec/python/fec/extended_decoder.py5
-rw-r--r--gr-fec/python/fec/extended_encoder.py4
-rw-r--r--gr-fec/python/fec/qa_puncture.py244
-rw-r--r--gr-fec/swig/fec_swig.i3
11 files changed, 441 insertions, 49 deletions
diff --git a/gr-fec/grc/fec_puncture_xx.xml b/gr-fec/grc/fec_puncture_xx.xml
index 0bc55585d2..8ad9b0c411 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 b3d3db7737..b803297d78 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 927fc0bbd6..8625ab4ffb 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 2fedc7746c..63633b2748 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 6480a742be..abf9c09dc1 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 a534bef79f..9a7c8f6dc2 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 bea66731e9..e86d0d25c5 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 7f08a109c6..dafedd861a 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 0e4bc0901f..b2dcc26b13 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 0000000000..fdd15c9a08
--- /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 506ea99a1f..e3cbd3387d 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);