diff options
author | Tom Rondeau <tom@trondeau.com> | 2014-05-02 12:48:34 -0400 |
---|---|---|
committer | Tom Rondeau <tom@trondeau.com> | 2014-05-17 17:45:14 -0400 |
commit | 4c2cb19a23a0b608617330bba80dd19cbb0c37dc (patch) | |
tree | 13045f35312e64677a1a95029bb715158b6223eb /gr-fec | |
parent | dd62061699a53e535f57a0ce0587bf1485db734f (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.xml | 27 | ||||
-rw-r--r-- | gr-fec/include/gnuradio/fec/puncture_bb.h | 63 | ||||
-rw-r--r-- | gr-fec/include/gnuradio/fec/puncture_ff.h | 62 | ||||
-rw-r--r-- | gr-fec/lib/puncture_bb_impl.cc | 38 | ||||
-rw-r--r-- | gr-fec/lib/puncture_bb_impl.h | 5 | ||||
-rw-r--r-- | gr-fec/lib/puncture_ff_impl.cc | 34 | ||||
-rw-r--r-- | gr-fec/lib/puncture_ff_impl.h | 5 | ||||
-rw-r--r-- | gr-fec/python/fec/extended_decoder.py | 5 | ||||
-rw-r--r-- | gr-fec/python/fec/extended_encoder.py | 4 | ||||
-rw-r--r-- | gr-fec/python/fec/qa_puncture.py | 244 | ||||
-rw-r--r-- | gr-fec/swig/fec_swig.i | 3 |
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); |