summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorClayton Smith <argilo@gmail.com>2018-10-01 20:29:26 -0400
committerMarcus Müller <marcus@hostalia.de>2018-11-02 00:12:34 +0100
commit5b401b6500d381d69b3bc56feb1e6ad001218039 (patch)
tree7cf95738b5565d642f18ebc3d0ab628bc6d952f7
parent4cbe4ba15def9e0c40e6ea628df58ee55868307a (diff)
Allow the full range of offsets.
-rw-r--r--gr-blocks/grc/blocks_keep_m_in_n.block.yml2
-rw-r--r--gr-blocks/lib/keep_m_in_n_impl.cc21
-rw-r--r--gr-blocks/python/blocks/qa_keep_m_in_n.py79
3 files changed, 80 insertions, 22 deletions
diff --git a/gr-blocks/grc/blocks_keep_m_in_n.block.yml b/gr-blocks/grc/blocks_keep_m_in_n.block.yml
index 451899eae0..96cf25dde9 100644
--- a/gr-blocks/grc/blocks_keep_m_in_n.block.yml
+++ b/gr-blocks/grc/blocks_keep_m_in_n.block.yml
@@ -37,6 +37,8 @@ asserts:
- ${ n > 0 }
- ${ m > 0 }
- ${ m <= n }
+- ${ offset >= 0 }
+- ${ offset < n }
templates:
imports: from gnuradio import blocks
diff --git a/gr-blocks/lib/keep_m_in_n_impl.cc b/gr-blocks/lib/keep_m_in_n_impl.cc
index 4784d3c1a2..2c67af9c34 100644
--- a/gr-blocks/lib/keep_m_in_n_impl.cc
+++ b/gr-blocks/lib/keep_m_in_n_impl.cc
@@ -1,6 +1,6 @@
/* -*- c++ -*- */
/*
- * Copyright 2012 Free Software Foundation, Inc.
+ * Copyright 2012,2018 Free Software Foundation, Inc.
*
* This file is part of GNU Radio
*
@@ -59,9 +59,14 @@ namespace gr {
std::string s = boost::str(boost::format("keep_m_in_n: m (%1%) <= n %2%") % d_m % d_n);
throw std::runtime_error(s);
}
- if(d_offset > (d_n - d_m)) {
- std::string s = boost::str(boost::format("keep_m_in_n: offset (%1%) <= n (%2%) - m (%3%)") \
- % d_offset % d_n % d_m);
+ if(d_offset < 0) {
+ std::string s = boost::str(boost::format("keep_m_in_n: offset (%1%) must be >= 0") \
+ % d_offset);
+ throw std::runtime_error(s);
+ }
+ if(d_offset >= d_n) {
+ std::string s = boost::str(boost::format("keep_m_in_n: offset (%1%) < n (%2%)") \
+ % d_offset % d_n);
throw std::runtime_error(s);
}
@@ -107,13 +112,19 @@ namespace gr {
// iterate over data blocks of size {n, input : m, output}
int blks = std::min(noutput_items/d_m, ninput_items[0]/d_n);
+ int excess = (d_offset + d_m - d_n) * d_itemsize;
for(int i=0; i<blks; i++) {
// set up copy pointers
const uint8_t* iptr = &in[(i*d_n + d_offset)*d_itemsize];
uint8_t* optr = &out[i*d_m*d_itemsize];
// perform copy
- memcpy( optr, iptr, d_m*d_itemsize );
+ if(excess <= 0) {
+ memcpy( optr, iptr, d_m*d_itemsize );
+ } else {
+ memcpy( optr, &in[i*d_n*d_itemsize], excess);
+ memcpy( optr + excess, iptr, d_m*d_itemsize - excess);
+ }
}
consume_each(blks*d_n);
diff --git a/gr-blocks/python/blocks/qa_keep_m_in_n.py b/gr-blocks/python/blocks/qa_keep_m_in_n.py
index 30a15d9ded..14d7863bbd 100644
--- a/gr-blocks/python/blocks/qa_keep_m_in_n.py
+++ b/gr-blocks/python/blocks/qa_keep_m_in_n.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python
#
-# Copyright 2008,2010,2012,2013 Free Software Foundation, Inc.
+# Copyright 2008,2010,2012,2013,2018 Free Software Foundation, Inc.
#
# This file is part of GNU Radio
#
@@ -25,6 +25,7 @@ from gnuradio import gr, gr_unittest, blocks
import sys
import random
+
class test_keep_m_in_n(gr_unittest.TestCase):
def setUp(self):
@@ -34,25 +35,69 @@ class test_keep_m_in_n(gr_unittest.TestCase):
pass
def test_001(self):
- self.maxDiff = None;
+ self.maxDiff = None
tb = gr.top_block()
- src = blocks.vector_source_b( list(range(0,100)) )
+ src = blocks.vector_source_c(list(range(0, 100)))
# itemsize, M, N, offset
- km2 = blocks.keep_m_in_n( 1, 1, 2, 0 );
- km3 = blocks.keep_m_in_n( 1, 1, 3, 1 );
- km7 = blocks.keep_m_in_n( 1, 1, 7, 2 );
- snk2 = blocks.vector_sink_b();
- snk3 = blocks.vector_sink_b();
- snk7 = blocks.vector_sink_b();
- tb.connect(src,km2,snk2);
- tb.connect(src,km3,snk3);
- tb.connect(src,km7,snk7);
- tb.run();
-
- self.assertEqual(list(range(0,100,2)), list(snk2.data()));
- self.assertEqual(list(range(1,100,3)), list(snk3.data()));
- self.assertEqual(list(range(2,100,7)), list(snk7.data()));
+ km2 = blocks.keep_m_in_n(8, 1, 2, 0)
+ km3 = blocks.keep_m_in_n(8, 1, 3, 1)
+ km7 = blocks.keep_m_in_n(8, 1, 7, 2)
+ snk2 = blocks.vector_sink_c()
+ snk3 = blocks.vector_sink_c()
+ snk7 = blocks.vector_sink_c()
+ tb.connect(src, km2, snk2)
+ tb.connect(src, km3, snk3)
+ tb.connect(src, km7, snk7)
+ tb.run()
+
+ self.assertEqual(list(range(0, 100, 2)), list(snk2.data()))
+ self.assertEqual(list(range(1, 100, 3)), list(snk3.data()))
+ self.assertEqual(list(range(2, 100, 7)), list(snk7.data()))
+
+ def test_002(self):
+ self.maxDiff = None
+ tb = gr.top_block()
+ src = blocks.vector_source_f(list(range(0, 100)))
+
+ km = []
+ snk = []
+ for i in range(5):
+ km.append(blocks.keep_m_in_n(4, 3, 5, i))
+ snk.append(blocks.vector_sink_f())
+ tb.connect(src, km[i], snk[i])
+ tb.run()
+
+ for i in range(5):
+ self.assertEqual(
+ sorted(
+ list(range(i, 100, 5)) +
+ list(range((i+1) % 5, 100, 5)) +
+ list(range((i+2) % 5, 100, 5))
+ ),
+ list(snk[i].data())
+ )
+
+ def test_003(self):
+ with self.assertRaises(RuntimeError) as cm:
+ blocks.keep_m_in_n(8, 0, 5, 0)
+ self.assertEqual(str(cm.exception), 'keep_m_in_n: m=0 but must be > 0')
+
+ with self.assertRaises(RuntimeError) as cm:
+ blocks.keep_m_in_n(8, 5, 0, 0)
+ self.assertEqual(str(cm.exception), 'keep_m_in_n: n=0 but must be > 0')
+
+ with self.assertRaises(RuntimeError) as cm:
+ blocks.keep_m_in_n(8, 6, 5, 0)
+ self.assertEqual(str(cm.exception), 'keep_m_in_n: m (6) <= n 5')
+
+ with self.assertRaises(RuntimeError) as cm:
+ blocks.keep_m_in_n(8, 2, 5, -1)
+ self.assertEqual(str(cm.exception), 'keep_m_in_n: offset (-1) must be >= 0')
+
+ with self.assertRaises(RuntimeError) as cm:
+ blocks.keep_m_in_n(8, 2, 5, 5)
+ self.assertEqual(str(cm.exception), 'keep_m_in_n: offset (5) < n (5)')
if __name__ == '__main__':