summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt6
-rw-r--r--cmake/Modules/FindQwt.cmake2
-rw-r--r--gnuradio-runtime/lib/block_executor.cc4
-rw-r--r--gnuradio-runtime/lib/pmt/pmt_unv.cc12
-rw-r--r--gnuradio-runtime/python/gnuradio/CMakeLists.txt1
-rw-r--r--gnuradio-runtime/python/gnuradio/gr_unittest.py134
-rw-r--r--gnuradio-runtime/python/gnuradio/gr_xmlrunner.py421
-rw-r--r--gr-analog/CMakeLists.txt4
-rw-r--r--gr-analog/include/gnuradio/analog/random_uniform_source.h2
-rw-r--r--gr-analog/include/gnuradio/analog/sig_source.h3
-rw-r--r--gr-audio/CMakeLists.txt5
-rw-r--r--gr-audio/lib/windows/windows_sink.cc1
-rw-r--r--gr-audio/lib/windows/windows_source.cc2
-rw-r--r--gr-blocks/CMakeLists.txt4
-rw-r--r--gr-blocks/lib/integrate_impl.cc4
-rw-r--r--gr-blocks/lib/tcp_server_sink_impl.h2
-rw-r--r--gr-blocks/lib/vector_sink_impl.cc2
-rw-r--r--gr-blocks/lib/vector_source_impl.cc2
-rw-r--r--gr-blocks/python/blocks/qa_keep_m_in_n.py2
-rw-r--r--gr-blocks/python/blocks/qa_moving_average.py4
-rw-r--r--gr-blocks/python/blocks/qa_pack_k_bits.py1
-rw-r--r--gr-blocks/python/blocks/qa_packed_to_unpacked.py1
-rw-r--r--gr-blocks/python/blocks/qa_repack_bits_bb.py1
-rw-r--r--gr-blocks/python/blocks/qa_socket_pdu.py1
-rw-r--r--gr-blocks/python/blocks/qa_udp_source_sink.py74
-rw-r--r--gr-blocks/python/blocks/qa_unpack_k_bits.py1
-rw-r--r--gr-channels/CMakeLists.txt4
-rw-r--r--gr-channels/grc/channels_channel_model.block.yml4
-rw-r--r--gr-digital/CMakeLists.txt4
-rw-r--r--gr-digital/grc/digital_ofdm_cyclic_prefixer.block.yml3
-rw-r--r--gr-digital/include/gnuradio/digital/constellation.h10
-rw-r--r--gr-digital/lib/constellation.cc33
-rw-r--r--gr-digital/lib/crc32_bb_impl.cc4
-rw-r--r--gr-digital/lib/crc32_bb_impl.h2
-rw-r--r--gr-digital/python/digital/qa_binary_slicer_fb.py1
-rw-r--r--gr-digital/python/digital/qa_clock_recovery_mm.py1
-rw-r--r--gr-digital/python/digital/qa_constellation.py1
-rw-r--r--gr-digital/python/digital/qa_constellation_receiver.py3
-rw-r--r--gr-digital/python/digital/qa_constellation_soft_decoder_cf.py1
-rw-r--r--gr-digital/python/digital/qa_costas_loop_cc.py1
-rw-r--r--gr-digital/python/digital/qa_crc32.py1
-rw-r--r--gr-digital/python/digital/qa_diff_encoder.py1
-rw-r--r--gr-digital/python/digital/qa_fll_band_edge.py1
-rw-r--r--gr-digital/python/digital/qa_header_payload_demux.py164
-rw-r--r--gr-digital/python/digital/qa_ofdm_chanest_vcvc.py1
-rw-r--r--gr-digital/python/digital/qa_ofdm_sync_sc_cfb.py89
-rw-r--r--gr-digital/python/digital/qa_ofdm_txrx.py1
-rw-r--r--gr-digital/python/digital/qa_packet_headerparser_b.py1
-rw-r--r--gr-digital/python/digital/qa_pfb_clock_sync.py1
-rw-r--r--gr-dtv/CMakeLists.txt4
-rw-r--r--gr-dtv/grc/CMakeLists.txt1
-rw-r--r--gr-dtv/grc/dtv_dvb_bbheader_bb.block.yml16
-rw-r--r--gr-dtv/grc/dtv_dvb_bbscrambler_bb.block.yml14
-rw-r--r--gr-dtv/grc/dtv_dvb_bch_bb.block.yml14
-rw-r--r--gr-dtv/grc/dtv_dvb_ldpc_bb.block.yml16
-rw-r--r--gr-dtv/grc/dtv_dvbs2_interleaver_bb.block.yml6
-rw-r--r--gr-dtv/grc/dtv_dvbs2_modulator_bc.block.yml10
-rw-r--r--gr-dtv/grc/dtv_dvbs2_physical_cc.block.yml6
-rw-r--r--gr-dtv/grc/dtv_dvbt2_framemapper_cc.block.yml10
-rw-r--r--gr-dtv/grc/dtv_dvbt2_freqinterleaver_cc.block.yml4
-rw-r--r--gr-dtv/grc/dtv_dvbt2_miso_cc.block.yml4
-rw-r--r--gr-dtv/grc/dtv_dvbt2_p1insertion_cc.block.yml12
-rw-r--r--gr-dtv/grc/dtv_dvbt2_paprtr_cc.block.yml8
-rw-r--r--gr-dtv/grc/dtv_dvbt2_pilotgenerator_cc.block.yml15
-rw-r--r--gr-dtv/lib/dvb/dvb_bbscrambler_bb_impl.cc11
-rw-r--r--gr-dtv/lib/dvb/dvb_bbscrambler_bb_impl.h3
-rw-r--r--gr-dtv/lib/dvb/dvb_bch_bb_impl.cc375
-rw-r--r--gr-dtv/lib/dvb/dvb_bch_bb_impl.h19
-rw-r--r--gr-dtv/lib/dvb/dvb_ldpc_bb_impl.cc66
-rw-r--r--gr-dtv/lib/dvb/dvb_ldpc_bb_impl.h9
-rw-r--r--gr-dtv/lib/dvbt2/dvbt2_interleaver_bb_impl.cc434
-rw-r--r--gr-dtv/lib/dvbt2/dvbt2_interleaver_bb_impl.h6
-rw-r--r--gr-dtv/lib/dvbt2/dvbt2_pilotgenerator_cc_impl.cc31
-rw-r--r--gr-dtv/lib/dvbt2/dvbt2_pilotgenerator_cc_impl.h7
-rw-r--r--gr-fec/CMakeLists.txt4
-rw-r--r--gr-fec/grc/variable_polar_encoder.block.yml4
-rw-r--r--gr-fec/lib/polar_common.cc2
-rw-r--r--gr-fft/CMakeLists.txt4
-rw-r--r--gr-fft/grc/fft_fft_vxx.block.yml5
-rw-r--r--gr-fft/include/gnuradio/fft/fft_vcc.h2
-rw-r--r--gr-fft/include/gnuradio/fft/fft_vfc.h1
-rw-r--r--gr-filter/CMakeLists.txt4
-rw-r--r--gr-filter/lib/pfb_decimator_ccf_impl.cc2
-rw-r--r--gr-filter/python/filter/qa_fft_filter.py2
-rw-r--r--gr-filter/python/filter/qa_filterbank.py1
-rw-r--r--gr-qtgui/CMakeLists.txt4
-rw-r--r--gr-qtgui/grc/qtgui_freq_sink_x.block.yml4
-rw-r--r--gr-qtgui/grc/qtgui_time_sink_x.block.yml617
-rw-r--r--gr-qtgui/grc/qtgui_time_sink_x.block.yml.py362
-rw-r--r--gr-qtgui/grc/qtgui_waterfall_sink_x.block.yml4
-rw-r--r--gr-qtgui/include/gnuradio/qtgui/freq_sink_c.h9
-rw-r--r--gr-qtgui/include/gnuradio/qtgui/freq_sink_f.h9
-rw-r--r--gr-qtgui/include/gnuradio/qtgui/waterfall_sink_c.h7
-rw-r--r--gr-qtgui/include/gnuradio/qtgui/waterfall_sink_f.h9
-rw-r--r--gr-qtgui/lib/freq_sink_c_impl.cc19
-rw-r--r--gr-qtgui/lib/freq_sink_c_impl.h5
-rw-r--r--gr-qtgui/lib/freq_sink_f_impl.cc24
-rw-r--r--gr-qtgui/lib/freq_sink_f_impl.h5
-rw-r--r--gr-qtgui/lib/time_sink_c_impl.cc2
-rw-r--r--gr-qtgui/lib/time_sink_f_impl.cc2
-rw-r--r--gr-qtgui/lib/vector_sink_f_impl.cc6
-rw-r--r--gr-qtgui/lib/waterfall_sink_c_impl.cc19
-rw-r--r--gr-qtgui/lib/waterfall_sink_c_impl.h7
-rw-r--r--gr-qtgui/lib/waterfall_sink_f_impl.cc23
-rw-r--r--gr-qtgui/lib/waterfall_sink_f_impl.h5
-rw-r--r--gr-trellis/CMakeLists.txt4
-rw-r--r--gr-trellis/include/gnuradio/trellis/interleaver.h8
-rw-r--r--gr-trellis/lib/interleaver.cc29
-rw-r--r--gr-uhd/CMakeLists.txt4
-rw-r--r--gr-uhd/grc/CMakeLists.txt2
-rw-r--r--gr-uhd/grc/gen_uhd_usrp_blocks.py82
-rw-r--r--gr-uhd/lib/usrp_block_impl.cc5
-rw-r--r--gr-uhd/lib/usrp_block_impl.h3
-rw-r--r--gr-uhd/lib/usrp_sink_impl.cc61
-rw-r--r--gr-uhd/lib/usrp_sink_impl.h18
-rw-r--r--gr-uhd/python/uhd/__init__.py1
-rw-r--r--gr-uhd/swig/uhd_swig.i4
-rw-r--r--gr-utils/python/modtool/gr-newmod/CMakeLists.txt8
-rw-r--r--gr-video-sdl/CMakeLists.txt4
-rw-r--r--gr-vocoder/CMakeLists.txt4
-rw-r--r--gr-zeromq/CMakeLists.txt4
-rw-r--r--gr-zeromq/include/gnuradio/zeromq/pub_msg_sink.h5
-rw-r--r--gr-zeromq/include/gnuradio/zeromq/pub_sink.h5
-rw-r--r--gr-zeromq/include/gnuradio/zeromq/pull_msg_source.h5
-rw-r--r--gr-zeromq/include/gnuradio/zeromq/pull_source.h5
-rw-r--r--gr-zeromq/include/gnuradio/zeromq/push_msg_sink.h5
-rw-r--r--gr-zeromq/include/gnuradio/zeromq/push_sink.h5
-rw-r--r--gr-zeromq/include/gnuradio/zeromq/rep_msg_sink.h5
-rw-r--r--gr-zeromq/include/gnuradio/zeromq/rep_sink.h5
-rw-r--r--gr-zeromq/include/gnuradio/zeromq/req_msg_source.h5
-rw-r--r--gr-zeromq/include/gnuradio/zeromq/req_source.h5
-rw-r--r--gr-zeromq/include/gnuradio/zeromq/sub_msg_source.h5
-rw-r--r--gr-zeromq/include/gnuradio/zeromq/sub_source.h5
-rw-r--r--gr-zeromq/lib/base_impl.cc9
-rw-r--r--gr-zeromq/lib/base_impl.h1
-rw-r--r--gr-zeromq/lib/pub_msg_sink_impl.h6
-rw-r--r--gr-zeromq/lib/pub_sink_impl.h1
-rw-r--r--gr-zeromq/lib/pull_msg_source_impl.h7
-rw-r--r--gr-zeromq/lib/pull_source_impl.h1
-rw-r--r--gr-zeromq/lib/push_msg_sink_impl.h6
-rw-r--r--gr-zeromq/lib/push_sink_impl.h2
-rw-r--r--gr-zeromq/lib/rep_msg_sink_impl.h7
-rw-r--r--gr-zeromq/lib/rep_sink_impl.h1
-rw-r--r--gr-zeromq/lib/req_msg_source_impl.h7
-rw-r--r--gr-zeromq/lib/req_source_impl.h1
-rw-r--r--gr-zeromq/lib/sub_msg_source_impl.h7
-rw-r--r--gr-zeromq/lib/sub_source_impl.h2
-rw-r--r--gr-zeromq/python/zeromq/qa_zeromq_pub.py5
-rw-r--r--gr-zeromq/python/zeromq/qa_zeromq_pubsub.py5
-rw-r--r--gr-zeromq/python/zeromq/qa_zeromq_pushpull.py5
-rw-r--r--gr-zeromq/python/zeromq/qa_zeromq_reqrep.py5
-rwxr-xr-xgr-zeromq/python/zeromq/qa_zeromq_sub.py7
-rw-r--r--grc/CMakeLists.txt7
-rw-r--r--grc/core/FlowGraph.py7
-rw-r--r--grc/core/ParseXML.py185
-rw-r--r--grc/gui/Application.py228
-rwxr-xr-xtools/clang_format.py826
157 files changed, 3100 insertions, 1841 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index dfdca5d9bf..6136cbc22e 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -27,7 +27,7 @@ endif(${CMAKE_SOURCE_DIR} STREQUAL ${CMAKE_BINARY_DIR})
########################################################################
# Make sure this version matches ${GR_CMAKE_MIN_VERSION} (a variable can't be
# used here).
-cmake_minimum_required(VERSION 2.8.12)
+cmake_minimum_required(VERSION 3.5.1)
project(gnuradio CXX C)
enable_testing()
@@ -53,9 +53,9 @@ SET(VERSION_INFO_MAINT_VERSION 0)
include(GrVersion) #setup version info
# Minimum dependency versions for central dependencies:
-set(GR_BOOST_MIN_VERSION "1.54")
+set(GR_BOOST_MIN_VERSION "1.53")
set(GR_SWIG_MIN_VERSION "3.0.8")
-set(GR_CMAKE_MIN_VERSION "2.8.12")
+set(GR_CMAKE_MIN_VERSION "3.5.1")
set(GR_MAKO_MIN_VERSION "0.4.2")
set(GR_PYTHON_MIN_VERSION "2.7")
set(GR_PYTHON3_MIN_VERSION "3.4")
diff --git a/cmake/Modules/FindQwt.cmake b/cmake/Modules/FindQwt.cmake
index bfdded88e1..d0694c942c 100644
--- a/cmake/Modules/FindQwt.cmake
+++ b/cmake/Modules/FindQwt.cmake
@@ -29,7 +29,7 @@ find_path(QWT_INCLUDE_DIRS
)
find_library (QWT_LIBRARIES
- NAMES qwt6-${QWT_QT_VERSION} qwt-${QWT_QT_VERSION}
+ NAMES ${PC_QWT_LIBRARIES} qwt6-${QWT_QT_VERSION} qwt-${QWT_QT_VERSION}
HINTS
${PC_QWT_LIBDIR}
${CMAKE_INSTALL_PREFIX}/lib
diff --git a/gnuradio-runtime/lib/block_executor.cc b/gnuradio-runtime/lib/block_executor.cc
index 5f9552415a..40521e10b5 100644
--- a/gnuradio-runtime/lib/block_executor.cc
+++ b/gnuradio-runtime/lib/block_executor.cc
@@ -147,7 +147,7 @@ namespace gr {
for(t = rtags.begin(); t != rtags.end(); t++) {
tag_t new_tag = *t;
mpz_import(offset.get_mpz_t(), 1, 1, sizeof(new_tag.offset), 0, 0, &new_tag.offset);
- offset *= mp_rrate + one_half;
+ offset = offset * mp_rrate + one_half;
new_tag.offset = offset.get_ui();
for(int o = 0; o < d->noutputs(); o++)
out_buf[o]->add_item_tag(new_tag);
@@ -190,7 +190,7 @@ namespace gr {
for(t = rtags.begin(); t != rtags.end(); t++) {
tag_t new_tag = *t;
mpz_import(offset.get_mpz_t(), 1, 1, sizeof(new_tag.offset), 0, 0, &new_tag.offset);
- offset *= mp_rrate + one_half;
+ offset = offset * mp_rrate + one_half;
new_tag.offset = offset.get_ui();
out_buf->add_item_tag(new_tag);
}
diff --git a/gnuradio-runtime/lib/pmt/pmt_unv.cc b/gnuradio-runtime/lib/pmt/pmt_unv.cc
index cda0c085cd..25cd9a3c95 100644
--- a/gnuradio-runtime/lib/pmt/pmt_unv.cc
+++ b/gnuradio-runtime/lib/pmt/pmt_unv.cc
@@ -474,7 +474,7 @@ u16vector_writable_elements(pmt_t vector, size_t &len)
const std::string
pmt_u16vector::string_ref(size_t k) const
{
- return boost::lexical_cast< std::string, uint16_t > (ref(k));
+ return std::to_string(ref(k));
}
} /* namespace pmt */
@@ -623,7 +623,7 @@ s16vector_writable_elements(pmt_t vector, size_t &len)
const std::string
pmt_s16vector::string_ref(size_t k) const
{
- return boost::lexical_cast< std::string, int16_t > (ref(k));
+ return std::to_string(ref(k));
}
} /* namespace pmt */
@@ -772,7 +772,7 @@ u32vector_writable_elements(pmt_t vector, size_t &len)
const std::string
pmt_u32vector::string_ref(size_t k) const
{
- return boost::lexical_cast< std::string, uint32_t > (ref(k));
+ return std::to_string(ref(k));
}
} /* namespace pmt */
@@ -921,7 +921,7 @@ s32vector_writable_elements(pmt_t vector, size_t &len)
const std::string
pmt_s32vector::string_ref(size_t k) const
{
- return boost::lexical_cast< std::string, int32_t > (ref(k));
+ return std::to_string(ref(k));
}
} /* namespace pmt */
@@ -1070,7 +1070,7 @@ u64vector_writable_elements(pmt_t vector, size_t &len)
const std::string
pmt_u64vector::string_ref(size_t k) const
{
- return boost::lexical_cast< std::string, uint64_t > (ref(k));
+ return std::to_string(ref(k));
}
} /* namespace pmt */
@@ -1219,7 +1219,7 @@ s64vector_writable_elements(pmt_t vector, size_t &len)
const std::string
pmt_s64vector::string_ref(size_t k) const
{
- return boost::lexical_cast< std::string, int64_t > (ref(k));
+ return std::to_string(ref(k));
}
} /* namespace pmt */
diff --git a/gnuradio-runtime/python/gnuradio/CMakeLists.txt b/gnuradio-runtime/python/gnuradio/CMakeLists.txt
index 736db499dc..aea94643de 100644
--- a/gnuradio-runtime/python/gnuradio/CMakeLists.txt
+++ b/gnuradio-runtime/python/gnuradio/CMakeLists.txt
@@ -33,6 +33,5 @@ GR_PYTHON_INSTALL(FILES
eng_option.py
eng_arg.py
gr_unittest.py
- gr_xmlrunner.py
DESTINATION ${GR_PYTHON_DIR}/gnuradio
)
diff --git a/gnuradio-runtime/python/gnuradio/gr_unittest.py b/gnuradio-runtime/python/gnuradio/gr_unittest.py
index 190ea63354..57ce9a3761 100644
--- a/gnuradio-runtime/python/gnuradio/gr_unittest.py
+++ b/gnuradio-runtime/python/gnuradio/gr_unittest.py
@@ -26,13 +26,7 @@ from __future__ import absolute_import
from __future__ import unicode_literals
from __future__ import division
-import os
-import stat
-
import unittest
-from . import gr_xmlrunner
-
-
class TestCase(unittest.TestCase):
"""A subclass of unittest.TestCase that adds additional assertions
@@ -41,7 +35,7 @@ class TestCase(unittest.TestCase):
assertComplexTuplesAlmostEqual and assertFloatTuplesAlmostEqual
"""
- def assertComplexAlmostEqual (self, first, second, places=7, msg=None):
+ def assertComplexAlmostEqual(self, first, second, places=7, msg=None):
"""Fail if the two complex objects are unequal as determined by their
difference rounded to the given number of decimal places
(default 7) and comparing to zero.
@@ -57,9 +51,11 @@ class TestCase(unittest.TestCase):
msg or '%r != %r within %r places' % (first, second, places)
)
- def assertComplexAlmostEqual2 (self, ref, x, abs_eps=1e-12, rel_eps=1e-6, msg=None):
+
+ def assertComplexAlmostEqual2(self, ref, x, abs_eps=1e-12, rel_eps=1e-6, msg=None):
"""
- Fail if the two complex objects are unequal as determined by...
+ Fail if the two complex objects are unequal as determined by both
+ absolute delta (abs_eps) and relative delta (rel_eps).
"""
if abs(ref - x) < abs_eps:
return
@@ -79,40 +75,52 @@ class TestCase(unittest.TestCase):
)
+ def assertComplexTuplesAlmostEqual(self, a, b, places=7, msg=None):
+ """
+ Fail if the two complex tuples are not approximately equal.
+ Approximate equality is determined by specifying the number of decimal
+ places.0
+ """
+ self.assertEqual(len(a), len(b))
+ return all((
+ self.assertComplexAlmostEqual(x, y, places, msg)
+ for (x, y) in zip(a, b)
+ ))
- def assertComplexTuplesAlmostEqual (self, a, b, places=7, msg=None):
- self.assertEqual (len(a), len(b))
- for i in range (len(a)):
- self.assertComplexAlmostEqual (a[i], b[i], places, msg)
- def assertComplexTuplesAlmostEqual2 (self, ref, x,
- abs_eps=1e-12, rel_eps=1e-6, msg=None):
- self.assertEqual (len(ref), len(x))
- for i in range (len(ref)):
- try:
- self.assertComplexAlmostEqual2 (ref[i], x[i], abs_eps, rel_eps, msg)
- except self.failureException as e:
- #sys.stderr.write("index = %d " % (i,))
- #sys.stderr.write("%r\n" % (e,))
- raise
+ def assertComplexTuplesAlmostEqual2(self, a, b,
+ abs_eps=1e-12, rel_eps=1e-6, msg=None):
+ """
+ Fail if the two complex tuples are not approximately equal.
+ Approximate equality is determined by calling assertComplexAlmostEqual().
+ """
+ self.assertEqual(len(a), len(b))
+ return all((
+ self.assertComplexAlmostEqual2(x, y, abs_eps, rel_eps, msg)
+ for (x, y) in zip(a, b)
+ ))
- def assertFloatTuplesAlmostEqual (self, a, b, places=7, msg=None):
- self.assertEqual (len(a), len(b))
- for i in range (len(a)):
- self.assertAlmostEqual (a[i], b[i], places, msg)
+ def assertFloatTuplesAlmostEqual(self, a, b, places=7, msg=None):
+ """
+ Fail if the two real-valued tuples are not approximately equal.
+ Approximate equality is determined by specifying the number of decimal
+ places.
+ """
+ self.assertEqual(len(a), len(b))
+ return all((
+ self.assertAlmostEqual(x, y, places, msg)
+ for (x, y) in zip(a, b)
+ ))
- def assertFloatTuplesAlmostEqual2 (self, ref, x,
- abs_eps=1e-12, rel_eps=1e-6, msg=None):
- self.assertEqual (len(ref), len(x))
- for i in range (len(ref)):
- try:
- self.assertComplexAlmostEqual2 (ref[i], x[i], abs_eps, rel_eps, msg)
- except self.failureException as e:
- #sys.stderr.write("index = %d " % (i,))
- #sys.stderr.write("%r\n" % (e,))
- raise
+ def assertFloatTuplesAlmostEqual2(self, a, b,
+ abs_eps=1e-12, rel_eps=1e-6, msg=None):
+ self.assertEqual(len(a), len(b))
+ return all((
+ self.assertComplexAlmostEqual2(x, y, abs_eps, rel_eps, msg)
+ for (x, y) in zip(a, b)
+ ))
TestResult = unittest.TestResult
TestSuite = unittest.TestSuite
@@ -125,54 +133,14 @@ main = TestProgram
def run(PUT, filename=None, verbosity=1):
'''
- Runs the unittest on a TestCase and produces an optional XML report
+ Runs the unittest on a TestCase
PUT: the program under test and should be a gr_unittest.TestCase
- filename: an optional filename to save the XML report of the tests
- this will live in ./.unittests/python
+ filename: This argument is here for historical reasons.
'''
-
- # Run this is given a file name
- if(filename is not None):
- basepath = "./.unittests"
- path = basepath + "/python"
-
- if not os.path.exists(basepath):
- os.makedirs(basepath, mode=0o750)
-
- xmlrunner = None
- # only proceed if .unittests is writable
- st = os.stat(basepath)[stat.ST_MODE]
- if(st & stat.S_IWUSR > 0):
- # Test if path exists; if not, build it
- if not os.path.exists(path):
- os.makedirs(path, mode=0o750)
-
- # Just for safety: make sure we can write here, too
- st = os.stat(path)[stat.ST_MODE]
- if(st & stat.S_IWUSR > 0):
- # Create an XML runner to filename
- fout = open(path+"/"+filename, "w")
- xmlrunner = gr_xmlrunner.XMLTestRunner(fout)
-
- txtrunner = TextTestRunner(verbosity=verbosity)
-
- # Run the test; runner also creates XML output file
- # FIXME: make xmlrunner output to screen so we don't have to do run and main
- suite = TestLoader().loadTestsFromTestCase(PUT)
-
- # use the xmlrunner if we can write the the directory
- if xmlrunner is not None:
- xmlrunner.run(suite)
-
- main(verbosity=verbosity)
-
- # This will run and fail make check if problem
- # but does not output to screen.
- #main(testRunner = xmlrunner)
-
- else:
- # If no filename is given, just run the test
- main(verbosity=verbosity)
+ if filename:
+ print("DEPRECATED: Using filename with gr_unittest does no longer "
+ "have any effect.")
+ main(verbosity=verbosity)
##############################################################################
diff --git a/gnuradio-runtime/python/gnuradio/gr_xmlrunner.py b/gnuradio-runtime/python/gnuradio/gr_xmlrunner.py
deleted file mode 100644
index fccb1b76f0..0000000000
--- a/gnuradio-runtime/python/gnuradio/gr_xmlrunner.py
+++ /dev/null
@@ -1,421 +0,0 @@
-"""
-XML Test Runner for PyUnit
-"""
-# Written by Sebastian Rittau <srittau@jroger.in-berlin.de> and placed in
-# the Public Domain. With contributions by Paolo Borelli and others.
-# Added to GNU Radio Oct. 3, 2010
-
-from __future__ import unicode_literals
-
-import os.path
-import re
-import sys
-import time
-import unittest
-import linecache
-from xml.sax.saxutils import escape
-from io import StringIO
-
-
-__version__ = "0.1"
-
-
-# inline trackeback.print_tb so that py2 uses unicode literals (py2/3 compat)
-def print_tb(tb, limit=None, out=None):
- """Print up to 'limit' stack trace entries from the traceback 'tb'.
-
- If 'limit' is omitted or None, all entries are printed. If 'file'
- is omitted or None, the output goes to sys.stderr; otherwise
- 'file' should be an open file or file-like object with a write()
- method.
- """
- def _print(out, s='', terminator='\n'):
- out.write(s+terminator)
-
- if out is None:
- out = sys.stderr
- if limit is None:
- if hasattr(sys, 'tracebacklimit'):
- limit = sys.tracebacklimit
- n = 0
- while tb is not None and (limit is None or n < limit):
- f = tb.tb_frame
- lineno = tb.tb_lineno
- co = f.f_code
- filename = co.co_filename
- name = co.co_name
- _print(out, ' Out "%s", line %d, in %s' % (filename, lineno, name))
- linecache.checkcache(filename)
- line = linecache.getline(filename, lineno, f.f_globals)
- if line:
- _print(out, ' ' + line.strip())
- tb = tb.tb_next
- n = n+1
-
-
-class _TestInfo(object):
-
- """Information about a particular test.
-
- Used by _XMLTestResult.
-
- """
-
- def __init__(self, test, time):
- (self._class, self._method) = test.id().rsplit(".", 1)
- self._time = time
- self._error = None
- self._failure = None
-
- @staticmethod
- def create_success(test, time):
- """Create a _TestInfo instance for a successful test."""
- return _TestInfo(test, time)
-
- @staticmethod
- def create_failure(test, time, failure):
- """Create a _TestInfo instance for a failed test."""
- info = _TestInfo(test, time)
- info._failure = failure
- return info
-
- @staticmethod
- def create_error(test, time, error):
- """Create a _TestInfo instance for an erroneous test."""
- info = _TestInfo(test, time)
- info._error = error
- return info
-
- def print_report(self, stream):
- """Print information about this test case in XML format to the
- supplied stream.
-
- """
- stream.write(' <testcase classname="%(class)s" name="%(method)s" time="%(time).4f">' %
- {
- 'class': self._class,
- 'method': self._method,
- 'time': self._time,
- })
- if self._failure is not None:
- self._print_error(stream, 'failure', self._failure)
- if self._error is not None:
- self._print_error(stream, 'error', self._error)
- stream.write('</testcase>\n')
-
- def _print_error(self, stream, tagname, error):
- """Print information from a failure or error to the supplied stream."""
- text = escape(str(error[1]))
- stream.write('\n')
- stream.write(' <%s type="%s">%s\n'
- % (tagname, _clsname(error[0]), text))
- tb_stream = StringIO()
- print_tb(error[2], None, tb_stream)
- stream.write(escape(tb_stream.getvalue()))
- stream.write(' </%s>\n' % tagname)
- stream.write(' ')
-
-
-def _clsname(cls):
- return cls.__module__ + "." + cls.__name__
-
-
-class _XMLTestResult(unittest.TestResult):
-
- """A test result class that stores result as XML.
-
- Used by XMLTestRunner.
-
- """
-
- def __init__(self, classname):
- unittest.TestResult.__init__(self)
- self._test_name = classname
- self._start_time = None
- self._tests = []
- self._error = None
- self._failure = None
-
- def startTest(self, test):
- unittest.TestResult.startTest(self, test)
- self._error = None
- self._failure = None
- self._start_time = time.time()
-
- def stopTest(self, test):
- time_taken = time.time() - self._start_time
- unittest.TestResult.stopTest(self, test)
- if self._error:
- info = _TestInfo.create_error(test, time_taken, self._error)
- elif self._failure:
- info = _TestInfo.create_failure(test, time_taken, self._failure)
- else:
- info = _TestInfo.create_success(test, time_taken)
- self._tests.append(info)
-
- def addError(self, test, err):
- unittest.TestResult.addError(self, test, err)
- self._error = err
-
- def addFailure(self, test, err):
- unittest.TestResult.addFailure(self, test, err)
- self._failure = err
-
- def print_report(self, stream, time_taken, out, err):
- """Prints the XML report to the supplied stream.
-
- The time the tests took to perform as well as the captured standard
- output and standard error streams must be passed in.a
-
- """
- stream.write('<testsuite errors="%(e)d" failures="%(f)d" ' %
- {
- "e": len(self.errors),
- "f": len(self.failures)
- })
- stream.write('name="%(n)s" tests="%(t)d" time="%(time).3f">\n' %
- {
- "n": self._test_name,
- "t": self.testsRun,
- "time": time_taken
- })
- for info in self._tests:
- info.print_report(stream)
- stream.write(' <system-out><![CDATA[%s]]></system-out>\n' % out)
- stream.write(' <system-err><![CDATA[%s]]></system-err>\n' % err)
- stream.write('</testsuite>\n')
-
-
-class XMLTestRunner(object):
-
- """A test runner that stores results in XML format compatible with JUnit.
-
- XMLTestRunner(stream=None) -> XML test runner
-
- The XML file is written to the supplied stream. If stream is None, the
- results are stored in a file called TEST-<module>.<class>.xml in the
- current working directory (if not overridden with the path property),
- where <module> and <class> are the module and class name of the test class.
-
- """
-
- def __init__(self, stream=None):
- self._stream = stream
- self._path = "."
-
- def run(self, test):
- """Run the given test case or test suite."""
- class_ = test.__class__
- classname = class_.__module__ + "." + class_.__name__
- if self._stream is None:
- filename = "TEST-%s.xml" % classname
- stream = open(os.path.join(self._path, filename), "w")
- stream.write('<?xml version="1.0" encoding="utf-8"?>\n')
- else:
- stream = self._stream
-
- result = _XMLTestResult(classname)
- start_time = time.time()
-
- fss = _fake_std_streams()
- fss.__enter__()
- try:
- test(result)
- try:
- out_s = sys.stdout.getvalue()
- except AttributeError:
- out_s = ""
- try:
- err_s = sys.stderr.getvalue()
- except AttributeError:
- err_s = ""
- finally:
- fss.__exit__(None, None, None)
-
- time_taken = time.time() - start_time
- result.print_report(stream, time_taken, out_s, err_s)
- if self._stream is None:
- stream.close()
-
- return result
-
- def _set_path(self, path):
- self._path = path
-
- path = property(lambda self: self._path, _set_path, None,
- """The path where the XML files are stored.
-
- This property is ignored when the XML file is written to a file
- stream.""")
-
-
-class _fake_std_streams(object):
-
- def __enter__(self):
- self._orig_stdout = sys.stdout
- self._orig_stderr = sys.stderr
- #sys.stdout = StringIO()
- #sys.stderr = StringIO()
-
- def __exit__(self, exc_type, exc_val, exc_tb):
- sys.stdout = self._orig_stdout
- sys.stderr = self._orig_stderr
-
-
-class XMLTestRunnerTest(unittest.TestCase):
-
- def setUp(self):
- self._stream = StringIO()
-
- def _try_test_run(self, test_class, expected):
-
- """Run the test suite against the supplied test class and compare the
- XML result against the expected XML string. Fail if the expected
- string doesn't match the actual string. All time attributes in the
- expected string should have the value "0.000". All error and failure
- messages are reduced to "Foobar".
-
- """
-
- runner = XMLTestRunner(self._stream)
- runner.run(unittest.makeSuite(test_class))
-
- got = self._stream.getvalue()
- # Replace all time="X.YYY" attributes by time="0.000" to enable a
- # simple string comparison.
- got = re.sub(r'time="\d+\.\d+"', 'time="0.000"', got)
- # Likewise, replace all failure and error messages by a simple "Foobar"
- # string.
- got = re.sub(r'(?s)<failure (.*?)>.*?</failure>', r'<failure \1>Foobar</failure>', got)
- got = re.sub(r'(?s)<error (.*?)>.*?</error>', r'<error \1>Foobar</error>', got)
- # And finally Python 3 compatibility.
- got = got.replace('type="builtins.', 'type="exceptions.')
-
- self.assertEqual(expected, got)
-
- def test_no_tests(self):
- """Regression test: Check whether a test run without any tests
- matches a previous run.
-
- """
- class TestTest(unittest.TestCase):
- pass
- self._try_test_run(TestTest, """<testsuite errors="0" failures="0" name="unittest.TestSuite" tests="0" time="0.000">
- <system-out><![CDATA[]]></system-out>
- <system-err><![CDATA[]]></system-err>
-</testsuite>
-""")
-
- def test_success(self):
- """Regression test: Check whether a test run with a successful test
- matches a previous run.
-
- """
- class TestTest(unittest.TestCase):
- def test_foo(self):
- pass
- self._try_test_run(TestTest, """<testsuite errors="0" failures="0" name="unittest.TestSuite" tests="1" time="0.000">
- <testcase classname="__main__.TestTest" name="test_foo" time="0.000"></testcase>
- <system-out><![CDATA[]]></system-out>
- <system-err><![CDATA[]]></system-err>
-</testsuite>
-""")
-
- def test_failure(self):
- """Regression test: Check whether a test run with a failing test
- matches a previous run.
-
- """
- class TestTest(unittest.TestCase):
- def test_foo(self):
- self.assert_(False)
- self._try_test_run(TestTest, """<testsuite errors="0" failures="1" name="unittest.TestSuite" tests="1" time="0.000">
- <testcase classname="__main__.TestTest" name="test_foo" time="0.000">
- <failure type="exceptions.AssertionError">Foobar</failure>
- </testcase>
- <system-out><![CDATA[]]></system-out>
- <system-err><![CDATA[]]></system-err>
-</testsuite>
-""")
-
- def test_error(self):
- """Regression test: Check whether a test run with a erroneous test
- matches a previous run.
-
- """
- class TestTest(unittest.TestCase):
- def test_foo(self):
- raise IndexError()
- self._try_test_run(TestTest, """<testsuite errors="1" failures="0" name="unittest.TestSuite" tests="1" time="0.000">
- <testcase classname="__main__.TestTest" name="test_foo" time="0.000">
- <error type="exceptions.IndexError">Foobar</error>
- </testcase>
- <system-out><![CDATA[]]></system-out>
- <system-err><![CDATA[]]></system-err>
-</testsuite>
-""")
-
- def test_stdout_capture(self):
- """Regression test: Check whether a test run with output to stdout
- matches a previous run.
-
- """
- class TestTest(unittest.TestCase):
- def test_foo(self):
- sys.stdout.write("Test\n")
- self._try_test_run(TestTest, """<testsuite errors="0" failures="0" name="unittest.TestSuite" tests="1" time="0.000">
- <testcase classname="__main__.TestTest" name="test_foo" time="0.000"></testcase>
- <system-out><![CDATA[Test
-]]></system-out>
- <system-err><![CDATA[]]></system-err>
-</testsuite>
-""")
-
- def test_stderr_capture(self):
- """Regression test: Check whether a test run with output to stderr
- matches a previous run.
-
- """
- class TestTest(unittest.TestCase):
- def test_foo(self):
- sys.stderr.write("Test\n")
- self._try_test_run(TestTest, """<testsuite errors="0" failures="0" name="unittest.TestSuite" tests="1" time="0.000">
- <testcase classname="__main__.TestTest" name="test_foo" time="0.000"></testcase>
- <system-out><![CDATA[]]></system-out>
- <system-err><![CDATA[Test
-]]></system-err>
-</testsuite>
-""")
-
- class NullStream(object):
- """A file-like object that discards everything written to it."""
- def write(self, buffer):
- pass
-
- def test_unittests_changing_stdout(self):
- """Check whether the XMLTestRunner recovers gracefully from unit tests
- that change stdout, but don't change it back properly.
-
- """
- class TestTest(unittest.TestCase):
- def test_foo(self):
- sys.stdout = XMLTestRunnerTest.NullStream()
-
- runner = XMLTestRunner(self._stream)
- runner.run(unittest.makeSuite(TestTest))
-
- def test_unittests_changing_stderr(self):
- """Check whether the XMLTestRunner recovers gracefully from unit tests
- that change stderr, but don't change it back properly.
-
- """
- class TestTest(unittest.TestCase):
- def test_foo(self):
- sys.stderr = XMLTestRunnerTest.NullStream()
-
- runner = XMLTestRunner(self._stream)
- runner.run(unittest.makeSuite(TestTest))
-
-
-if __name__ == "__main__":
- unittest.main()
diff --git a/gr-analog/CMakeLists.txt b/gr-analog/CMakeLists.txt
index d874ae3cf6..c6ca6192dd 100644
--- a/gr-analog/CMakeLists.txt
+++ b/gr-analog/CMakeLists.txt
@@ -60,10 +60,12 @@ add_subdirectory(docs)
if(ENABLE_PYTHON)
add_subdirectory(swig)
add_subdirectory(python/analog)
- add_subdirectory(grc)
add_subdirectory(examples)
add_subdirectory(examples/tags)
endif(ENABLE_PYTHON)
+if(ENABLE_GRC)
+ add_subdirectory(grc)
+endif(ENABLE_GRC)
########################################################################
# Create Pkg Config File
diff --git a/gr-analog/include/gnuradio/analog/random_uniform_source.h b/gr-analog/include/gnuradio/analog/random_uniform_source.h
index 95948cc24e..1cd0f3016d 100644
--- a/gr-analog/include/gnuradio/analog/random_uniform_source.h
+++ b/gr-analog/include/gnuradio/analog/random_uniform_source.h
@@ -31,7 +31,7 @@ namespace gr {
namespace analog {
/*!
- * \brief Uniform Random Number Generator with @TYPE@ output.
+ * \brief Uniform Random Number Generator
* \ingroup waveform_generators_blk
*/
template<class T>
diff --git a/gr-analog/include/gnuradio/analog/sig_source.h b/gr-analog/include/gnuradio/analog/sig_source.h
index 915433a5ab..5d8ee05614 100644
--- a/gr-analog/include/gnuradio/analog/sig_source.h
+++ b/gr-analog/include/gnuradio/analog/sig_source.h
@@ -50,6 +50,7 @@ template<class T>
* \param wave_freq Frequency of waveform (relative to sampling_freq).
* \param ampl Signal amplitude.
* \param offset offset of signal.
+ * \param phase Initial phase of the signal
*/
static sptr make(double sampling_freq,
gr::analog::gr_waveform_t waveform,
@@ -83,7 +84,7 @@ template<class T>
/*!
* Sets the amplitude of a signal.
- * \param amplitude of the signal
+ * \param ampl amplitude of the signal
*/
virtual void set_amplitude(double ampl) = 0;
diff --git a/gr-audio/CMakeLists.txt b/gr-audio/CMakeLists.txt
index a43a58c6b7..6f373b7b94 100644
--- a/gr-audio/CMakeLists.txt
+++ b/gr-audio/CMakeLists.txt
@@ -51,11 +51,12 @@ add_subdirectory(docs)
if(ENABLE_PYTHON)
add_subdirectory(swig)
add_subdirectory(python/audio)
- add_subdirectory(grc)
add_subdirectory(examples/python)
add_subdirectory(examples/grc)
endif(ENABLE_PYTHON)
-
+if(ENABLE_GRC)
+ add_subdirectory(grc)
+endif(ENABLE_GRC)
if(ENABLE_GR_ANALOG)
add_subdirectory(examples/c++)
endif(ENABLE_GR_ANALOG)
diff --git a/gr-audio/lib/windows/windows_sink.cc b/gr-audio/lib/windows/windows_sink.cc
index bd9e0e5660..067c71cbf7 100644
--- a/gr-audio/lib/windows/windows_sink.cc
+++ b/gr-audio/lib/windows/windows_sink.cc
@@ -38,7 +38,6 @@
#include <stdexcept>
#include <string>
#include <sstream>
-#include "boost/lexical_cast.hpp"
namespace gr {
namespace audio {
diff --git a/gr-audio/lib/windows/windows_source.cc b/gr-audio/lib/windows/windows_source.cc
index 372a8ba3a8..9f177462e2 100644
--- a/gr-audio/lib/windows/windows_source.cc
+++ b/gr-audio/lib/windows/windows_source.cc
@@ -38,8 +38,6 @@
#include <gnuradio/prefs.h>
#include <gnuradio/logger.h>
-#include "boost/lexical_cast.hpp"
-
namespace gr {
namespace audio {
diff --git a/gr-blocks/CMakeLists.txt b/gr-blocks/CMakeLists.txt
index 34fac58823..86ad046d16 100644
--- a/gr-blocks/CMakeLists.txt
+++ b/gr-blocks/CMakeLists.txt
@@ -56,10 +56,12 @@ add_subdirectory(lib)
if(ENABLE_PYTHON)
add_subdirectory(python/blocks)
add_subdirectory(swig)
- add_subdirectory(grc)
add_subdirectory(docs)
add_subdirectory(examples)
endif(ENABLE_PYTHON)
+if(ENABLE_GRC)
+ add_subdirectory(grc)
+endif(ENABLE_GRC)
########################################################################
# Create Pkg Config File
diff --git a/gr-blocks/lib/integrate_impl.cc b/gr-blocks/lib/integrate_impl.cc
index 9fa4035726..90f0ef18ce 100644
--- a/gr-blocks/lib/integrate_impl.cc
+++ b/gr-blocks/lib/integrate_impl.cc
@@ -58,11 +58,11 @@ namespace gr {
T *out = (T *)output_items[0];
for (int i = 0; i < noutput_items; i++) {
- for (int j = 0; j < d_vlen; ++j) {
+ for (unsigned int j = 0; j < d_vlen; ++j) {
out[i*d_vlen + j] = (T)0;
}
for (int j = 0; j < d_decim; j++) {
- for (int k = 0; k < d_vlen; ++k) {
+ for (unsigned int k = 0; k < d_vlen; ++k) {
out[i*d_vlen + k] += in[i*d_decim*d_vlen + j*d_vlen + k];
}
}
diff --git a/gr-blocks/lib/tcp_server_sink_impl.h b/gr-blocks/lib/tcp_server_sink_impl.h
index ea1aa3e84a..db26b705fe 100644
--- a/gr-blocks/lib/tcp_server_sink_impl.h
+++ b/gr-blocks/lib/tcp_server_sink_impl.h
@@ -43,7 +43,7 @@ namespace gr {
std::set<boost::asio::ip::tcp::socket *> d_sockets;
boost::asio::ip::tcp::acceptor d_acceptor;
- boost::shared_ptr<uint8_t> d_buf;
+ boost::shared_ptr<uint8_t[]> d_buf;
enum {
BUF_SIZE = 256 * 1024,
};
diff --git a/gr-blocks/lib/vector_sink_impl.cc b/gr-blocks/lib/vector_sink_impl.cc
index dfa6dbb4a5..b09c8e81b7 100644
--- a/gr-blocks/lib/vector_sink_impl.cc
+++ b/gr-blocks/lib/vector_sink_impl.cc
@@ -94,7 +94,7 @@ namespace gr {
// can't touch this (as long as work() is working, the accessors shall not
// read the data
gr::thread::scoped_lock guard(d_data_mutex);
- for(int i = 0; i < noutput_items * d_vlen; i++)
+ for(unsigned int i = 0; i < noutput_items * d_vlen; i++)
d_data.push_back (iptr[i]);
std::vector<tag_t> tags;
this->get_tags_in_range(tags, 0, this->nitems_read(0), this->nitems_read(0) + noutput_items);
diff --git a/gr-blocks/lib/vector_source_impl.cc b/gr-blocks/lib/vector_source_impl.cc
index d49c37f5dd..24a21854f2 100644
--- a/gr-blocks/lib/vector_source_impl.cc
+++ b/gr-blocks/lib/vector_source_impl.cc
@@ -114,7 +114,7 @@ namespace gr {
}
}
else {
- for(int i = 0; i < noutput_items*d_vlen; i++) {
+ for(int i = 0; i < static_cast<int>(noutput_items*d_vlen); i++) {
optr[i] = d_data[offset++];
if(offset >= size) {
offset = 0;
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 14d7863bbd..7ef9ae791d 100644
--- a/gr-blocks/python/blocks/qa_keep_m_in_n.py
+++ b/gr-blocks/python/blocks/qa_keep_m_in_n.py
@@ -29,7 +29,7 @@ import random
class test_keep_m_in_n(gr_unittest.TestCase):
def setUp(self):
- pass
+ random.seed(0)
def tearDown(self):
pass
diff --git a/gr-blocks/python/blocks/qa_moving_average.py b/gr-blocks/python/blocks/qa_moving_average.py
index 87f8d3015f..fa8383c7c9 100644
--- a/gr-blocks/python/blocks/qa_moving_average.py
+++ b/gr-blocks/python/blocks/qa_moving_average.py
@@ -41,6 +41,7 @@ def make_random_float_tuple(L, scale=1):
class test_moving_average(gr_unittest.TestCase):
def setUp(self):
+ random.seed(0)
self.tb = gr.top_block()
def tearDown(self):
@@ -54,7 +55,6 @@ class test_moving_average(gr_unittest.TestCase):
tb = self.tb
N = 10000
- seed = 0
data = make_random_float_tuple(N, 1)
expected_result = N*[0,]
@@ -75,7 +75,6 @@ class test_moving_average(gr_unittest.TestCase):
tb = self.tb
N = 10000
- seed = 0
data = make_random_complex_tuple(N, 1)
expected_result = N*[0,]
@@ -99,7 +98,6 @@ class test_moving_average(gr_unittest.TestCase):
vlen = 5
N = 10*vlen
- seed = 0
data = make_random_float_tuple(N, 2**10)
data = [int(d*1000) for d in data]
src = blocks.vector_source_i(data, False)
diff --git a/gr-blocks/python/blocks/qa_pack_k_bits.py b/gr-blocks/python/blocks/qa_pack_k_bits.py
index 28285845b3..c82c025306 100644
--- a/gr-blocks/python/blocks/qa_pack_k_bits.py
+++ b/gr-blocks/python/blocks/qa_pack_k_bits.py
@@ -28,6 +28,7 @@ from gnuradio import gr, gr_unittest, blocks
class test_pack(gr_unittest.TestCase):
def setUp(self):
+ random.seed(0)
self.tb = gr.top_block()
def tearDown(self):
diff --git a/gr-blocks/python/blocks/qa_packed_to_unpacked.py b/gr-blocks/python/blocks/qa_packed_to_unpacked.py
index 13e93a7136..ea68b8263c 100644
--- a/gr-blocks/python/blocks/qa_packed_to_unpacked.py
+++ b/gr-blocks/python/blocks/qa_packed_to_unpacked.py
@@ -28,6 +28,7 @@ import random
class test_packing(gr_unittest.TestCase):
def setUp(self):
+ random.seed(0)
self.tb = gr.top_block ()
def tearDown(self):
diff --git a/gr-blocks/python/blocks/qa_repack_bits_bb.py b/gr-blocks/python/blocks/qa_repack_bits_bb.py
index fa86c0ccac..419630b0c5 100644
--- a/gr-blocks/python/blocks/qa_repack_bits_bb.py
+++ b/gr-blocks/python/blocks/qa_repack_bits_bb.py
@@ -28,6 +28,7 @@ import pmt
class qa_repack_bits_bb (gr_unittest.TestCase):
def setUp (self):
+ random.seed(0)
self.tb = gr.top_block ()
self.tsb_key = "length"
diff --git a/gr-blocks/python/blocks/qa_socket_pdu.py b/gr-blocks/python/blocks/qa_socket_pdu.py
index 961dc914ea..21f8ead6ec 100644
--- a/gr-blocks/python/blocks/qa_socket_pdu.py
+++ b/gr-blocks/python/blocks/qa_socket_pdu.py
@@ -29,6 +29,7 @@ import time
class qa_socket_pdu (gr_unittest.TestCase):
def setUp (self):
+ random.seed(0)
self.tb = gr.top_block ()
def tearDown (self):
diff --git a/gr-blocks/python/blocks/qa_udp_source_sink.py b/gr-blocks/python/blocks/qa_udp_source_sink.py
index f0418357fd..fe3fea5d9c 100644
--- a/gr-blocks/python/blocks/qa_udp_source_sink.py
+++ b/gr-blocks/python/blocks/qa_udp_source_sink.py
@@ -22,9 +22,22 @@
from gnuradio import gr, gr_unittest, blocks
+import numpy
import os
+import socket
+import time
+
+from threading import Timer, Thread
+
+
+def recv_data(sock, result):
+ while True:
+ data = sock.recv(4*1000)
+ if len(data) == 0:
+ break
+ real_data = numpy.frombuffer(data, dtype=numpy.float32)
+ result.extend(list(real_data))
-from threading import Timer
class test_udp_sink_source(gr_unittest.TestCase):
@@ -52,36 +65,66 @@ class test_udp_sink_source(gr_unittest.TestCase):
self.tb_snd.run()
udp_snd.disconnect()
+
udp_snd.connect('localhost', port+1)
src.rewind()
self.tb_snd.run()
- def test_002(self):
+
+ def test_sink_001(self):
port = 65520
n_data = 100
src_data = [float(x) for x in range(n_data)]
expected_result = tuple(src_data)
+
+ recvsock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
+ recvsock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
+ recvsock.bind(('127.0.0.1', port))
+
+ result = []
+ t = Thread(target=recv_data, args=(recvsock, result))
+ t.start()
+
src = blocks.vector_source_f(src_data, False)
- udp_snd = blocks.udp_sink(gr.sizeof_float, 'localhost', port)
+ udp_snd = blocks.udp_sink(gr.sizeof_float, '127.0.0.1', port)
self.tb_snd.connect(src, udp_snd)
- udp_rcv = blocks.udp_source(gr.sizeof_float, 'localhost', port)
- dst = blocks.vector_sink_f()
- self.tb_rcv.connect(udp_rcv, dst)
- self.tb_rcv.start()
self.tb_snd.run()
udp_snd.disconnect()
- self.timeout = False
- q = Timer(2.0,self.stop_rcv)
- q.start()
+ t.join()
+ recvsock.close()
+
+ self.assertEqual(expected_result, tuple(result))
+
+ def test_source_001(self):
+ port = 65520
+
+ n_data = 100
+ src_data = [float(x) for x in range(n_data)]
+ expected_result = tuple(src_data)
+ send_data = numpy.array(src_data, dtype=numpy.float32)
+ send_data = send_data.tobytes()
+
+ udp_rcv = blocks.udp_source(gr.sizeof_float, '127.0.0.1', port)
+ dst = blocks.vector_sink_f()
+ self.tb_rcv.connect(udp_rcv, dst)
+ self.tb_rcv.start()
+ time.sleep(1.0)
+ sendsock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
+ sendsock.sendto(send_data, ('127.0.0.1', port))
+ time.sleep(1.0)
+ sendsock.sendto(b'', ('127.0.0.1', port))
+ sendsock.sendto(b'', ('127.0.0.1', port))
+ sendsock.sendto(b'', ('127.0.0.1', port))
self.tb_rcv.wait()
- q.cancel()
+ sendsock.close()
+ recv_data = tuple(dst.data())
+
+ self.assertEqual(expected_result, recv_data)
+
- result_data = dst.data()
- self.assertEqual(expected_result, result_data)
- self.assert_(not self.timeout)
def test_003(self):
port = 65530
@@ -102,6 +145,7 @@ class test_udp_sink_source(gr_unittest.TestCase):
self.tb_rcv.connect(udp_rcv, dst)
self.tb_rcv.start()
+ time.sleep(0.1)
self.tb_snd.run()
udp_snd.disconnect()
self.timeout = False
@@ -112,7 +156,7 @@ class test_udp_sink_source(gr_unittest.TestCase):
result_data = dst.data()
self.assertEqual(expected_result, result_data)
- self.assert_(self.timeout) # source ignores EOF?
+ self.assertTrue(self.timeout) # source ignores EOF?
def stop_rcv(self):
self.timeout = True
diff --git a/gr-blocks/python/blocks/qa_unpack_k_bits.py b/gr-blocks/python/blocks/qa_unpack_k_bits.py
index f351e75d30..3e2a107b30 100644
--- a/gr-blocks/python/blocks/qa_unpack_k_bits.py
+++ b/gr-blocks/python/blocks/qa_unpack_k_bits.py
@@ -28,6 +28,7 @@ import random
class test_unpack(gr_unittest.TestCase):
def setUp(self):
+ random.seed(0)
self.tb = gr.top_block ()
def tearDown(self):
diff --git a/gr-channels/CMakeLists.txt b/gr-channels/CMakeLists.txt
index 5d073e1c66..a508362be0 100644
--- a/gr-channels/CMakeLists.txt
+++ b/gr-channels/CMakeLists.txt
@@ -57,9 +57,11 @@ add_subdirectory(lib)
if(ENABLE_PYTHON)
add_subdirectory(swig)
add_subdirectory(python/channels)
- add_subdirectory(grc)
add_subdirectory(examples)
endif(ENABLE_PYTHON)
+if(ENABLE_GRC)
+ add_subdirectory(grc)
+endif(ENABLE_GRC)
add_subdirectory(docs)
########################################################################
diff --git a/gr-channels/grc/channels_channel_model.block.yml b/gr-channels/grc/channels_channel_model.block.yml
index 53337f6ab0..01701c3610 100644
--- a/gr-channels/grc/channels_channel_model.block.yml
+++ b/gr-channels/grc/channels_channel_model.block.yml
@@ -28,9 +28,7 @@ parameters:
default: 'False'
options: ['True', 'False']
option_labels: ['Yes', 'No']
- option_attributes:
- hide_block: ['', part]
- hide: ${ block_tags.hide_block }
+ hide: ${ 'none' if block_tags == 'False' else 'part' }
inputs:
- domain: stream
diff --git a/gr-digital/CMakeLists.txt b/gr-digital/CMakeLists.txt
index 7de895f09b..bc02e96331 100644
--- a/gr-digital/CMakeLists.txt
+++ b/gr-digital/CMakeLists.txt
@@ -61,9 +61,11 @@ add_subdirectory(docs)
if(ENABLE_PYTHON)
add_subdirectory(swig)
add_subdirectory(python/digital)
- add_subdirectory(grc)
add_subdirectory(examples)
endif(ENABLE_PYTHON)
+if(ENABLE_GRC)
+ add_subdirectory(grc)
+endif(ENABLE_GRC)
########################################################################
# Create Pkg Config File
diff --git a/gr-digital/grc/digital_ofdm_cyclic_prefixer.block.yml b/gr-digital/grc/digital_ofdm_cyclic_prefixer.block.yml
index cd475a0601..9054be5753 100644
--- a/gr-digital/grc/digital_ofdm_cyclic_prefixer.block.yml
+++ b/gr-digital/grc/digital_ofdm_cyclic_prefixer.block.yml
@@ -6,7 +6,6 @@ parameters:
label: FFT Length
dtype: int
default: fft_len
- hide: ${ 'part' if vlen == 1 else 'none' }
- id: cp_len
label: CP Length
dtype: int
@@ -32,7 +31,7 @@ outputs:
templates:
imports: from gnuradio import digital
- make: digital.ofdm_cyclic_prefixer(${input_size}, ${input_size+cp_len}, ${rolloff},
+ make: digital.ofdm_cyclic_prefixer(${input_size}, ${input_size} + ${cp_len}, ${rolloff},
${tagname})
file_format: 1
diff --git a/gr-digital/include/gnuradio/digital/constellation.h b/gr-digital/include/gnuradio/digital/constellation.h
index 8ccd576eda..0a90d7e8d3 100644
--- a/gr-digital/include/gnuradio/digital/constellation.h
+++ b/gr-digital/include/gnuradio/digital/constellation.h
@@ -66,7 +66,8 @@ namespace gr {
constellation(std::vector<gr_complex> constell,
std::vector<int> pre_diff_code,
unsigned int rotational_symmetry,
- unsigned int dimensionality);
+ unsigned int dimensionality,
+ bool normalize_points=true);
constellation();
virtual ~constellation();
@@ -253,11 +254,13 @@ namespace gr {
* coding) (order of list matches constell)
* \param rotational_symmetry Number of rotations around unit circle that have the same representation.
* \param dimensionality Number of dimensions to the constellation.
+ * \param normalize_points Normalize constellation points to mean(abs(points))=1 (default is true)
*/
static sptr make(std::vector<gr_complex> constell,
std::vector<int> pre_diff_code,
unsigned int rotational_symmetry,
- unsigned int dimensionality);
+ unsigned int dimensionality,
+ bool normalize_points=true);
unsigned int decision_maker(const gr_complex *sample);
// void calc_metric(gr_complex *sample, float *metric, trellis_metric_type_t type);
@@ -268,7 +271,8 @@ namespace gr {
constellation_calcdist(std::vector<gr_complex> constell,
std::vector<int> pre_diff_code,
unsigned int rotational_symmetry,
- unsigned int dimensionality);
+ unsigned int dimensionality,
+ bool nomalize_points=true);
};
diff --git a/gr-digital/lib/constellation.cc b/gr-digital/lib/constellation.cc
index cf7039b313..93fd95da8e 100644
--- a/gr-digital/lib/constellation.cc
+++ b/gr-digital/lib/constellation.cc
@@ -43,7 +43,8 @@ namespace gr {
constellation::constellation(std::vector<gr_complex> constell,
std::vector<int> pre_diff_code,
unsigned int rotational_symmetry,
- unsigned int dimensionality
+ unsigned int dimensionality,
+ bool normalize_points
) :
d_constellation(constell),
d_pre_diff_code(pre_diff_code),
@@ -56,16 +57,18 @@ namespace gr {
d_lut_precision(0),
d_lut_scale(0)
{
- // Scale constellation points so that average magnitude is 1.
- float summed_mag = 0;
unsigned int constsize = d_constellation.size();
- for (unsigned int i=0; i<constsize; i++) {
- gr_complex c = d_constellation[i];
- summed_mag += sqrt(c.real()*c.real() + c.imag()*c.imag());
- }
- d_scalefactor = constsize/summed_mag;
- for (unsigned int i=0; i<constsize; i++) {
- d_constellation[i] = d_constellation[i]*d_scalefactor;
+ if (normalize_points) {
+ // Scale constellation points so that average magnitude is 1.
+ float summed_mag = 0;
+ for (unsigned int i=0; i<constsize; i++) {
+ gr_complex c = d_constellation[i];
+ summed_mag += sqrt(c.real()*c.real() + c.imag()*c.imag());
+ }
+ d_scalefactor = constsize/summed_mag;
+ for (unsigned int i=0; i<constsize; i++) {
+ d_constellation[i] = d_constellation[i]*d_scalefactor;
+ }
}
if(pre_diff_code.size() == 0)
d_apply_pre_diff_code = false;
@@ -406,19 +409,21 @@ namespace gr {
constellation_calcdist::make(std::vector<gr_complex> constell,
std::vector<int> pre_diff_code,
unsigned int rotational_symmetry,
- unsigned int dimensionality)
+ unsigned int dimensionality,
+ bool normalize_points)
{
return constellation_calcdist::sptr(
new constellation_calcdist(constell, pre_diff_code,
- rotational_symmetry, dimensionality));
+ rotational_symmetry, dimensionality, normalize_points));
}
constellation_calcdist::constellation_calcdist(
std::vector<gr_complex> constell,
std::vector<int> pre_diff_code,
unsigned int rotational_symmetry,
- unsigned int dimensionality)
- : constellation(constell, pre_diff_code, rotational_symmetry, dimensionality)
+ unsigned int dimensionality,
+ bool normalize_points)
+ : constellation(constell, pre_diff_code, rotational_symmetry, dimensionality, normalize_points)
{}
// Chooses points base on shortest distance.
diff --git a/gr-digital/lib/crc32_bb_impl.cc b/gr-digital/lib/crc32_bb_impl.cc
index ad82aef595..4df1869a70 100644
--- a/gr-digital/lib/crc32_bb_impl.cc
+++ b/gr-digital/lib/crc32_bb_impl.cc
@@ -108,7 +108,7 @@ namespace gr {
}
}
else{
- for(int i=0; i < d_crc_length; i++){
+ for(unsigned int i=0; i < d_crc_length; i++){
if(((crc >> i) & 0x1) != *(in + packet_length - d_crc_length + i)) { // Drop package
return 0;
}
@@ -122,7 +122,7 @@ namespace gr {
memcpy((void *) (out + packet_length), &crc, d_crc_length); // FIXME big-endian/little-endian, this might be wrong
}
else {
- for (int i = 0; i < d_crc_length; i++) { // unpack CRC and store in buffer
+ for (unsigned int i = 0; i < d_crc_length; i++) { // unpack CRC and store in buffer
d_buffer[i] = (crc >> i) & 0x1;
}
memcpy((void *) (out + packet_length), (void *) &d_buffer[0], d_crc_length);
diff --git a/gr-digital/lib/crc32_bb_impl.h b/gr-digital/lib/crc32_bb_impl.h
index d7316eb548..07a798c8b9 100644
--- a/gr-digital/lib/crc32_bb_impl.h
+++ b/gr-digital/lib/crc32_bb_impl.h
@@ -35,7 +35,7 @@ namespace gr {
bool d_check;
bool d_packed;
boost::crc_optimal<32, 0x04C11DB7, 0xFFFFFFFF, 0xFFFFFFFF, true, true> d_crc_impl;
- int d_crc_length;
+ unsigned int d_crc_length;
std::vector<char> d_buffer;
unsigned int calculate_crc32(const unsigned char* in, size_t packet_length);
diff --git a/gr-digital/python/digital/qa_binary_slicer_fb.py b/gr-digital/python/digital/qa_binary_slicer_fb.py
index 0b2879380b..9b18af6d4a 100644
--- a/gr-digital/python/digital/qa_binary_slicer_fb.py
+++ b/gr-digital/python/digital/qa_binary_slicer_fb.py
@@ -28,6 +28,7 @@ from gnuradio import gr, gr_unittest, digital, blocks
class test_binary_slicer_fb(gr_unittest.TestCase):
def setUp(self):
+ random.seed(0)
self.tb = gr.top_block()
def tearDown(self):
diff --git a/gr-digital/python/digital/qa_clock_recovery_mm.py b/gr-digital/python/digital/qa_clock_recovery_mm.py
index 0618ec321c..6c7de5b50c 100644
--- a/gr-digital/python/digital/qa_clock_recovery_mm.py
+++ b/gr-digital/python/digital/qa_clock_recovery_mm.py
@@ -29,6 +29,7 @@ from gnuradio import gr, gr_unittest, digital, blocks
class test_clock_recovery_mm(gr_unittest.TestCase):
def setUp(self):
+ random.seed(0)
self.tb = gr.top_block()
def tearDown(self):
diff --git a/gr-digital/python/digital/qa_constellation.py b/gr-digital/python/digital/qa_constellation.py
index 3436ce6f45..c21afc03a6 100644
--- a/gr-digital/python/digital/qa_constellation.py
+++ b/gr-digital/python/digital/qa_constellation.py
@@ -171,6 +171,7 @@ class test_constellation(gr_unittest.TestCase):
src_length = 256
def setUp(self):
+ random.seed(0)
# Generate a list of random bits.
self.src_data = tuple([random.randint(0,1) for i in range(0, self.src_length)])
diff --git a/gr-digital/python/digital/qa_constellation_receiver.py b/gr-digital/python/digital/qa_constellation_receiver.py
index 4850863fa5..ffe7355c32 100644
--- a/gr-digital/python/digital/qa_constellation_receiver.py
+++ b/gr-digital/python/digital/qa_constellation_receiver.py
@@ -89,6 +89,9 @@ class test_constellation_receiver(gr_unittest.TestCase):
max_data_length = DATA_LENGTH * 6
max_num_samples = 1000
+ def setUp(self):
+ random.seed(0)
+
def test_basic(self):
"""
Tests a bunch of different constellations by using generic
diff --git a/gr-digital/python/digital/qa_constellation_soft_decoder_cf.py b/gr-digital/python/digital/qa_constellation_soft_decoder_cf.py
index 629d52c0a4..66151481c6 100644
--- a/gr-digital/python/digital/qa_constellation_soft_decoder_cf.py
+++ b/gr-digital/python/digital/qa_constellation_soft_decoder_cf.py
@@ -28,6 +28,7 @@ from numpy import random, vectorize
class test_constellation_soft_decoder(gr_unittest.TestCase):
def setUp(self):
+ random.seed(0)
self.tb = gr.top_block()
def tearDown(self):
diff --git a/gr-digital/python/digital/qa_costas_loop_cc.py b/gr-digital/python/digital/qa_costas_loop_cc.py
index 283a9199df..bd65d7a209 100644
--- a/gr-digital/python/digital/qa_costas_loop_cc.py
+++ b/gr-digital/python/digital/qa_costas_loop_cc.py
@@ -31,6 +31,7 @@ from gnuradio.digital import psk
class test_costas_loop_cc(gr_unittest.TestCase):
def setUp(self):
+ random.seed(0)
self.tb = gr.top_block()
def tearDown(self):
diff --git a/gr-digital/python/digital/qa_crc32.py b/gr-digital/python/digital/qa_crc32.py
index 6d3d2fa3ce..6bb00328f6 100644
--- a/gr-digital/python/digital/qa_crc32.py
+++ b/gr-digital/python/digital/qa_crc32.py
@@ -21,7 +21,6 @@
#
-import random
import cmath
from gnuradio import gr, gr_unittest, digital
diff --git a/gr-digital/python/digital/qa_diff_encoder.py b/gr-digital/python/digital/qa_diff_encoder.py
index 58d757d0c2..d328020fad 100644
--- a/gr-digital/python/digital/qa_diff_encoder.py
+++ b/gr-digital/python/digital/qa_diff_encoder.py
@@ -35,6 +35,7 @@ def make_random_int_tuple(L, min, max):
class test_diff_encoder(gr_unittest.TestCase):
def setUp(self):
+ random.seed(0)
self.tb = gr.top_block()
def tearDown(self):
diff --git a/gr-digital/python/digital/qa_fll_band_edge.py b/gr-digital/python/digital/qa_fll_band_edge.py
index a4859565ec..a9018931ed 100644
--- a/gr-digital/python/digital/qa_fll_band_edge.py
+++ b/gr-digital/python/digital/qa_fll_band_edge.py
@@ -30,6 +30,7 @@ from gnuradio import gr, gr_unittest, digital, filter, blocks, analog
class test_fll_band_edge_cc(gr_unittest.TestCase):
def setUp(self):
+ random.seed(0)
self.tb = gr.top_block()
def tearDown(self):
diff --git a/gr-digital/python/digital/qa_header_payload_demux.py b/gr-digital/python/digital/qa_header_payload_demux.py
index d77f7c689d..be1178c4ac 100644
--- a/gr-digital/python/digital/qa_header_payload_demux.py
+++ b/gr-digital/python/digital/qa_header_payload_demux.py
@@ -1,5 +1,5 @@
#!/usr/bin/env python
-# Copyright 2012-2016 Free Software Foundation, Inc.
+# Copyright 2012-2016,2018 Free Software Foundation, Inc.
#
# This file is part of GNU Radio
#
@@ -34,6 +34,7 @@ import pmt
def make_tag(key, value, offset):
+ """Create a gr.tag_t() from key, value, offset."""
tag = gr.tag_t()
tag.offset = offset
tag.key = pmt.string_to_symbol(key)
@@ -46,7 +47,7 @@ class HeaderToMessageBlock(gr.sync_block):
Helps with testing the HPD. Receives a header, stores it, posts
a predetermined message.
"""
- def __init__(self, itemsize, header_len, messages, header_is_symbol=False):
+ def __init__(self, itemsize, header_len, messages):
gr.sync_block.__init__(
self,
name="HeaderToMessageBlock",
@@ -59,9 +60,9 @@ class HeaderToMessageBlock(gr.sync_block):
self.msg_count = 0
def work(self, input_items, output_items):
- for i in range(len(input_items[0]) // self.header_len):
+ """Where the magic happens."""
+ for _ in range(len(input_items[0]) // self.header_len):
msg = self.messages[self.msg_count] or False
- #print("Sending message: {0}".format(msg))
self.message_port_pub(pmt.intern('header_data'), pmt.to_pmt(msg))
self.msg_count += 1
output_items[0][:] = input_items[0][:]
@@ -71,32 +72,35 @@ class HeaderToMessageBlock(gr.sync_block):
class qa_header_payload_demux (gr_unittest.TestCase):
def setUp (self):
+ """Runs before every test."""
self.tb = gr.top_block ()
+ random.seed(0)
def tearDown (self):
+ """Runs after every test."""
self.tb = None
def connect_all_blocks(self,
- data_src, trigger_src,
- hpd,
- mock_header_demod,
- payload_sink, header_sink
- ):
+ data_src, trigger_src,
+ hpd,
+ mock_header_demod,
+ payload_sink, header_sink):
"""
Connect the standard HPD test flowgraph
"""
- self.tb.connect(data_src, (hpd, 0))
+ self.tb.connect(data_src, (hpd, 0))
if trigger_src is not None:
self.tb.connect(trigger_src, (hpd, 1))
self.tb.connect((hpd, 0), mock_header_demod)
self.tb.connect(mock_header_demod, header_sink)
self.tb.msg_connect(
- mock_header_demod, 'header_data',
- hpd, 'header_data'
+ mock_header_demod, 'header_data',
+ hpd, 'header_data'
)
self.tb.connect((hpd, 1), payload_sink)
def run_tb(self, payload_sink, payload_len, header_sink, header_len, timeout=30):
+ """Execute self.tb"""
stop_time = time.time() + timeout
self.tb.start()
while len(payload_sink.data()) < payload_len and \
@@ -106,7 +110,7 @@ class qa_header_payload_demux (gr_unittest.TestCase):
self.tb.stop()
self.tb.wait()
- def test_001_t (self):
+ def test_001_t(self):
""" Simplest possible test: put in zeros, then header,
then payload, trigger signal, try to demux.
The return signal from the header parser is faked via _post()
@@ -127,23 +131,29 @@ class qa_header_payload_demux (gr_unittest.TestCase):
# This goes on output 1, item 3:
testtag4 = make_tag('tag4', 314, n_zeros + len(header) + 3)
data_src = blocks.vector_source_f(
- data_signal,
- False,
- tags=(testtag1, testtag2, testtag3, testtag4)
+ data_signal,
+ False,
+ tags=(testtag1, testtag2, testtag3, testtag4)
)
trigger_src = blocks.vector_source_b(trigger_signal, False)
hpd = digital.header_payload_demux(
len(header), 1, 0, "frame_len", "detect", False, gr.sizeof_float
)
mock_header_demod = HeaderToMessageBlock(
- numpy.float32,
- len(header),
- [len(payload)]
+ numpy.float32,
+ len(header),
+ [len(payload)]
)
self.assertEqual(pmt.length(hpd.message_ports_in()), 2) #extra system port defined for you
payload_sink = blocks.vector_sink_f()
header_sink = blocks.vector_sink_f()
- self.connect_all_blocks(data_src, trigger_src, hpd, mock_header_demod, payload_sink, header_sink)
+ self.connect_all_blocks(
+ data_src,
+ trigger_src,
+ hpd,
+ mock_header_demod,
+ payload_sink,
+ header_sink)
self.run_tb(payload_sink, len(payload), header_sink, len(header))
self.assertEqual(header_sink.data(), header)
self.assertEqual(payload_sink.data(), payload)
@@ -152,8 +162,8 @@ class qa_header_payload_demux (gr_unittest.TestCase):
ptag = gr.tag_to_python(tag)
ptags_header.append({'key': ptag.key, 'offset': ptag.offset})
expected_tags_header = [
- {'key': 'tag2', 'offset': 0},
- {'key': 'tag3', 'offset': 2},
+ {'key': 'tag2', 'offset': 0},
+ {'key': 'tag3', 'offset': 2},
]
self.assertEqual(expected_tags_header, ptags_header)
ptags_payload = []
@@ -161,12 +171,12 @@ class qa_header_payload_demux (gr_unittest.TestCase):
ptag = gr.tag_to_python(tag)
ptags_payload.append({'key': ptag.key, 'offset': ptag.offset})
expected_tags_payload = [
- {'key': 'frame_len', 'offset': 0},
- {'key': 'tag4', 'offset': 3},
+ {'key': 'frame_len', 'offset': 0},
+ {'key': 'tag4', 'offset': 3},
]
self.assertEqual(expected_tags_payload, ptags_payload)
- def test_001_t_tags (self):
+ def test_001_t_tags(self):
""" Like the previous test, but use a trigger tag instead of
a trigger signal.
"""
@@ -185,9 +195,9 @@ class qa_header_payload_demux (gr_unittest.TestCase):
# This goes on output 1, item 3:
testtag4 = make_tag('tag4', 314, n_zeros + len(header) + 3)
data_src = blocks.vector_source_f(
- data_signal,
- False,
- tags=(trigger_tag, testtag1, testtag2, testtag3, testtag4)
+ data_signal,
+ False,
+ tags=(trigger_tag, testtag1, testtag2, testtag3, testtag4)
)
hpd = digital.header_payload_demux(
len(header), 1, 0, "frame_len", "detect", False, gr.sizeof_float
@@ -196,22 +206,22 @@ class qa_header_payload_demux (gr_unittest.TestCase):
header_sink = blocks.vector_sink_f()
payload_sink = blocks.vector_sink_f()
mock_header_demod = HeaderToMessageBlock(
- numpy.float32,
- len(header),
- [len(payload)]
+ numpy.float32,
+ len(header),
+ [len(payload)]
)
self.connect_all_blocks(data_src, None, hpd, mock_header_demod, payload_sink, header_sink)
self.run_tb(payload_sink, len(payload), header_sink, len(header))
# Check results
- self.assertEqual(header_sink.data(), header)
+ self.assertEqual(header_sink.data(), header)
self.assertEqual(payload_sink.data(), payload)
ptags_header = []
for tag in header_sink.tags():
ptag = gr.tag_to_python(tag)
ptags_header.append({'key': ptag.key, 'offset': ptag.offset})
expected_tags_header = [
- {'key': 'tag2', 'offset': 0},
- {'key': 'tag3', 'offset': 2},
+ {'key': 'tag2', 'offset': 0},
+ {'key': 'tag3', 'offset': 2},
]
self.assertEqual(expected_tags_header, ptags_header)
ptags_payload = []
@@ -219,8 +229,8 @@ class qa_header_payload_demux (gr_unittest.TestCase):
ptag = gr.tag_to_python(tag)
ptags_payload.append({'key': ptag.key, 'offset': ptag.offset})
expected_tags_payload = [
- {'key': 'frame_len', 'offset': 0},
- {'key': 'tag4', 'offset': 3},
+ {'key': 'frame_len', 'offset': 0},
+ {'key': 'tag4', 'offset': 3},
]
self.assertEqual(expected_tags_payload, ptags_payload)
@@ -242,9 +252,9 @@ class qa_header_payload_demux (gr_unittest.TestCase):
# This goes on output 1, item 3:
testtag4 = make_tag('tag4', 314, n_zeros + len(header) + 3)
data_src = blocks.vector_source_f(
- data_signal,
- False,
- tags=(testtag1, testtag2, testtag3, testtag4)
+ data_signal,
+ False,
+ tags=(testtag1, testtag2, testtag3, testtag4)
)
trigger_src = blocks.vector_source_b(trigger_signal, False)
hpd = digital.header_payload_demux(
@@ -271,15 +281,15 @@ class qa_header_payload_demux (gr_unittest.TestCase):
self.run_tb(payload_sink, len(payload), header_sink, len(header)+2)
# Check values
# Header now is padded:
- self.assertEqual(header_sink.data(), (0,) + header + (payload[0],))
+ self.assertEqual(header_sink.data(), (0,) + header + (payload[0],))
self.assertEqual(payload_sink.data(), payload)
ptags_header = []
for tag in header_sink.tags():
ptag = gr.tag_to_python(tag)
ptags_header.append({'key': ptag.key, 'offset': ptag.offset})
expected_tags_header = [
- {'key': 'tag2', 'offset': 1},
- {'key': 'tag3', 'offset': 3},
+ {'key': 'tag2', 'offset': 1},
+ {'key': 'tag3', 'offset': 3},
]
self.assertEqual(expected_tags_header, ptags_header)
ptags_payload = []
@@ -287,8 +297,8 @@ class qa_header_payload_demux (gr_unittest.TestCase):
ptag = gr.tag_to_python(tag)
ptags_payload.append({'key': ptag.key, 'offset': ptag.offset})
expected_tags_payload = [
- {'key': 'frame_len', 'offset': 0},
- {'key': 'tag4', 'offset': 3},
+ {'key': 'frame_len', 'offset': 0},
+ {'key': 'tag4', 'offset': 3},
]
self.assertEqual(expected_tags_payload, ptags_payload)
@@ -305,9 +315,9 @@ class qa_header_payload_demux (gr_unittest.TestCase):
# This goes on output 1, item 3 + 1 (for payload offset)
testtag4 = make_tag('tag4', 314, n_zeros + len(header) + 3)
data_src = blocks.vector_source_f(
- data_signal,
- False,
- tags=(testtag4,)
+ data_signal,
+ False,
+ tags=(testtag4,)
)
trigger_src = blocks.vector_source_b(trigger_signal, False)
hpd = digital.header_payload_demux(
@@ -333,8 +343,8 @@ class qa_header_payload_demux (gr_unittest.TestCase):
self.tb.start()
time.sleep(.2) # Need this, otherwise, the next message is ignored
hpd.to_basic_block()._post(
- pmt.intern('header_data'),
- pmt.to_pmt({'frame_len': len(payload), 'payload_offset': payload_offset})
+ pmt.intern('header_data'),
+ pmt.to_pmt({'frame_len': len(payload), 'payload_offset': payload_offset})
)
while len(payload_sink.data()) < len(payload):
time.sleep(.2)
@@ -344,22 +354,22 @@ class qa_header_payload_demux (gr_unittest.TestCase):
self.assertEqual(header_sink.data(), (0,) + header + (payload[0],))
# Payload is now offset:
self.assertEqual(
- payload_sink.data(),
- data_signal[n_zeros + len(header) + payload_offset:n_zeros + len(header) + payload_offset + len(payload)]
+ payload_sink.data(),
+ data_signal[n_zeros + len(header) + payload_offset:n_zeros + len(header) + payload_offset + len(payload)]
)
ptags_payload = {}
for tag in payload_sink.tags():
ptag = gr.tag_to_python(tag)
ptags_payload[ptag.key] = ptag.offset
expected_tags_payload = {
- 'frame_len': 0,
- 'payload_offset': 0,
- 'tag4': 3 - payload_offset,
+ 'frame_len': 0,
+ 'payload_offset': 0,
+ 'tag4': 3 - payload_offset,
}
self.assertEqual(expected_tags_payload, ptags_payload)
- def test_002_symbols (self):
+ def test_002_symbols(self):
"""
Same as before, but operate on symbols
"""
@@ -401,8 +411,8 @@ class qa_header_payload_demux (gr_unittest.TestCase):
self.tb.start()
time.sleep(.2) # Need this, otherwise, the next message is ignored
hpd.to_basic_block()._post(
- pmt.intern('header_data'),
- pmt.from_long(n_symbols)
+ pmt.intern('header_data'),
+ pmt.from_long(n_symbols)
)
while len(payload_sink.data()) < len(payload) * n_symbols:
time.sleep(.2)
@@ -415,8 +425,8 @@ class qa_header_payload_demux (gr_unittest.TestCase):
ptag = gr.tag_to_python(tag)
ptags_header.append({'key': ptag.key, 'offset': ptag.offset})
expected_tags_header = [
- {'key': 'tag2', 'offset': 0},
- {'key': 'tag3', 'offset': 0},
+ {'key': 'tag2', 'offset': 0},
+ {'key': 'tag3', 'offset': 0},
]
self.assertEqual(expected_tags_header, ptags_header)
ptags_payload = []
@@ -424,12 +434,12 @@ class qa_header_payload_demux (gr_unittest.TestCase):
ptag = gr.tag_to_python(tag)
ptags_payload.append({'key': ptag.key, 'offset': ptag.offset})
expected_tags_payload = [
- {'key': 'frame_len', 'offset': 0},
- {'key': 'tag4', 'offset': 1},
+ {'key': 'frame_len', 'offset': 0},
+ {'key': 'tag4', 'offset': 1},
]
self.assertEqual(expected_tags_payload, ptags_payload)
- def test_003_t (self):
+ def test_003_t(self):
"""
Like test 1, but twice, plus one fail
"""
@@ -448,8 +458,7 @@ class qa_header_payload_demux (gr_unittest.TestCase):
print("Triggers at: {0} {1} {2}".format(
n_zeros,
len(data_signal),
- len(data_signal)+len(header_fail)+n_zeros)
- )
+ len(data_signal)+len(header_fail)+n_zeros))
tx_signal = data_signal + \
header_fail + (0,) * n_zeros + \
header + payload2 + (0,) * 1000
@@ -487,21 +496,21 @@ class qa_header_payload_demux (gr_unittest.TestCase):
self.tb.start()
time.sleep(.2) # Need this, otherwise, the next message is ignored
hpd.to_basic_block()._post(
- pmt.intern('header_data'),
- pmt.from_long(len(payload1))
+ pmt.intern('header_data'),
+ pmt.from_long(len(payload1))
)
while len(payload_sink.data()) < len(payload1):
time.sleep(.2)
hpd.to_basic_block()._post(
- pmt.intern('header_data'),
- pmt.PMT_F
+ pmt.intern('header_data'),
+ pmt.PMT_F
)
# This next command is a bit of a showstopper, but there's no condition to check upon
# to see if the previous msg handling is finished
time.sleep(.7)
hpd.to_basic_block()._post(
- pmt.intern('header_data'),
- pmt.from_long(len(payload2))
+ pmt.intern('header_data'),
+ pmt.from_long(len(payload2))
)
while len(payload_sink.data()) < len(payload1) + len(payload2):
time.sleep(.2)
@@ -552,7 +561,7 @@ class qa_header_payload_demux (gr_unittest.TestCase):
indexes = []
burst_sizes = []
total_payload_len = 0
- for burst_count in range(n_bursts):
+ for _ in range(n_bursts):
gap_size = random.randint(0, max_gap)
signal += [0] * gap_size
is_failure = random.random() < fail_rate
@@ -579,11 +588,12 @@ class qa_header_payload_demux (gr_unittest.TestCase):
trigger_tags += [make_tag('detect', True, index)]
return (trigger_signal, trigger_tags)
### Go, go, go
+ # Uncomment this if you want true randomness -- good for actual fuzzing
# The divide-by-20 means we'll usually get the same random seed
# between the first run and the XML run.
- random_seed = int(time.time() / 20)
- random.seed(random_seed)
- print("Random seed: {0}".format(random_seed))
+ # random_seed = int(time.time() / 20)
+ # random.seed(random_seed)
+ # print("Random seed: {0}".format(random_seed))
n_bursts = 400
header_len = 5
max_gap = 50
@@ -612,9 +622,9 @@ class qa_header_payload_demux (gr_unittest.TestCase):
special_tags=('rx_freq',),
)
mock_header_demod = HeaderToMessageBlock(
- numpy.float32,
- header_len,
- burst_sizes
+ numpy.float32,
+ header_len,
+ burst_sizes
)
header_sink = blocks.vector_sink_f()
payload_sink = blocks.vector_sink_f()
diff --git a/gr-digital/python/digital/qa_ofdm_chanest_vcvc.py b/gr-digital/python/digital/qa_ofdm_chanest_vcvc.py
index e39247da0a..501afd413c 100644
--- a/gr-digital/python/digital/qa_ofdm_chanest_vcvc.py
+++ b/gr-digital/python/digital/qa_ofdm_chanest_vcvc.py
@@ -45,6 +45,7 @@ def rand_range(min_val, max_val):
class qa_ofdm_chanest_vcvc (gr_unittest.TestCase):
def setUp (self):
+ random.seed(0)
self.tb = gr.top_block ()
def tearDown (self):
diff --git a/gr-digital/python/digital/qa_ofdm_sync_sc_cfb.py b/gr-digital/python/digital/qa_ofdm_sync_sc_cfb.py
index 610d883b6c..5b67d868a0 100644
--- a/gr-digital/python/digital/qa_ofdm_sync_sc_cfb.py
+++ b/gr-digital/python/digital/qa_ofdm_sync_sc_cfb.py
@@ -22,23 +22,37 @@
from __future__ import division
-import numpy
import random
+import numpy
from gnuradio import gr, gr_unittest, blocks, analog, channels
from gnuradio import digital
from gnuradio.digital.utils import tagged_streams
from gnuradio.digital.ofdm_txrx import ofdm_tx
+def make_bpsk_burst(fft_len, cp_len, num_bits):
+ """ Create a burst of a sync symbol and some BPSK bits """
+ sync_symbol = [
+ (random.randint(0, 1)*2)-1
+ for x in range(fft_len // 2)
+ ] * 2
+ sync_symbols = sync_symbol[-cp_len:] + sync_symbol
+ mod_symbols = [
+ (random.randint(0, 1)*2)-1
+ for x in range(num_bits)
+ ]
+ return sync_symbols + mod_symbols
+
class qa_ofdm_sync_sc_cfb (gr_unittest.TestCase):
- def setUp (self):
+ def setUp(self):
+ random.seed(0)
self.tb = gr.top_block ()
- def tearDown (self):
+ def tearDown(self):
self.tb = None
- def test_001_detect (self):
+ def test_001_detect(self):
""" Send two bursts, with zeros in between, and check
they are both detected at the correct position and no
false alarms occur """
@@ -46,15 +60,11 @@ class qa_ofdm_sync_sc_cfb (gr_unittest.TestCase):
fft_len = 32
cp_len = 4
sig_len = (fft_len + cp_len) * 10
- sync_symbol = [(random.randint(0, 1)*2)-1 for x in range(fft_len // 2)] * 2
- tx_signal = [0,] * n_zeros + \
- sync_symbol[-cp_len:] + \
- sync_symbol + \
- [(random.randint(0, 1)*2)-1 for x in range(sig_len)]
+ tx_signal = [0,] * n_zeros + make_bpsk_burst(fft_len, cp_len, sig_len)
tx_signal = tx_signal * 2
add = blocks.add_cc()
sync = digital.ofdm_sync_sc_cfb(fft_len, cp_len)
- sink_freq = blocks.vector_sink_f()
+ sink_freq = blocks.vector_sink_f()
sink_detect = blocks.vector_sink_b()
self.tb.connect(blocks.vector_source_c(tx_signal), (add, 0))
self.tb.connect(analog.noise_source_c(analog.GR_GAUSSIAN, .01), (add, 1))
@@ -69,7 +79,7 @@ class qa_ofdm_sync_sc_cfb (gr_unittest.TestCase):
self.assertEqual(numpy.sum(sig1_detect), 1)
self.assertEqual(numpy.sum(sig2_detect), 1)
- def test_002_freq (self):
+ def test_002_freq(self):
""" Add a fine frequency offset and see if that gets detected properly """
fft_len = 32
cp_len = 4
@@ -77,12 +87,9 @@ class qa_ofdm_sync_sc_cfb (gr_unittest.TestCase):
max_freq_offset = 2*numpy.pi/fft_len # Otherwise, it's coarse
freq_offset = ((2 * random.random()) - 1) * max_freq_offset
sig_len = (fft_len + cp_len) * 10
- sync_symbol = [(random.randint(0, 1)*2)-1 for x in range(fft_len // 2)] * 2
- tx_signal = sync_symbol[-cp_len:] + \
- sync_symbol + \
- [(random.randint(0, 1)*2)-1 for x in range(sig_len)]
+ tx_signal = make_bpsk_burst(fft_len, cp_len, sig_len)
sync = digital.ofdm_sync_sc_cfb(fft_len, cp_len, True)
- sink_freq = blocks.vector_sink_f()
+ sink_freq = blocks.vector_sink_f()
sink_detect = blocks.vector_sink_b()
channel = channels.channel_model(0.005, freq_offset / 2.0 / numpy.pi)
self.tb.connect(blocks.vector_source_c(tx_signal), channel, sync)
@@ -93,39 +100,45 @@ class qa_ofdm_sync_sc_cfb (gr_unittest.TestCase):
est_freq_offset = 2 * phi_hat / fft_len
self.assertAlmostEqual(est_freq_offset, freq_offset, places=2)
- def test_003_multiburst (self):
+ def test_003_multiburst(self):
""" Send several bursts, see if the number of detects is correct.
Burst lengths and content are random.
+
+ The channel is assumed AWGN for this test.
"""
n_bursts = 42
fft_len = 32
cp_len = 4
tx_signal = []
- for i in range(n_bursts):
- sync_symbol = [(random.randint(0, 1)*2)-1 for x in range(fft_len // 2)] * 2
- tx_signal += [0,] * random.randint(0, 2*fft_len) + \
- sync_symbol[-cp_len:] + \
- sync_symbol + \
- [(random.randint(0, 1)*2)-1 for x in range(fft_len * random.randint(5,23))]
- add = blocks.add_cc()
+ for _ in range(n_bursts):
+ gap = [0,] * random.randint(0, 2*fft_len)
+ tx_signal += \
+ gap + \
+ make_bpsk_burst(fft_len, cp_len, fft_len * random.randint(5, 23))
+ # Very loose definition of SNR here
+ snr = 20 # dB
+ sigma = 10**(-snr/10)
+ # Add noise -- we don't use the channel model blocks, we want to keep
+ # this test as self-contained as possible, and all randomness should
+ # derive from random.seed() above
+ complex_randn = \
+ lambda N: (numpy.random.randn(N) + 1j * numpy.random.randn(N)) * sigma / numpy.sqrt(2)
+ tx_signal += complex_randn(len(tx_signal))
sync = digital.ofdm_sync_sc_cfb(fft_len, cp_len)
- sink_freq = blocks.vector_sink_f()
+ sink_freq = blocks.vector_sink_f()
sink_detect = blocks.vector_sink_b()
- channel = channels.channel_model(0.005)
- self.tb.connect(blocks.vector_source_c(tx_signal), channel, sync)
+ self.tb.connect(blocks.vector_source_c(tx_signal), sync)
self.tb.connect((sync, 0), sink_freq)
self.tb.connect((sync, 1), sink_detect)
self.tb.run()
n_bursts_detected = numpy.sum(sink_detect.data())
- # We allow for one false alarm or missed burst
- self.assertTrue(abs(n_bursts_detected - n_bursts) <= 1,
- msg="""Because of statistics, it is possible (though unlikely)
-that the number of detected bursts differs slightly. If the number of detects is
-off by one or two, run the test again and see what happen.
-Detection error was: %d """ % (numpy.sum(sink_detect.data()) - n_bursts)
+ self.assertEqual(
+ n_bursts_detected, n_bursts,
+ msg="Detection error (missed bursts): {}".format(
+ (numpy.sum(sink_detect.data()) - n_bursts))
)
- def test_004_ofdm_packets (self):
+ def test_004_ofdm_packets(self):
"""
Send several bursts using ofdm_tx, see if the number of detects is correct.
Burst lengths and content are random.
@@ -136,23 +149,20 @@ Detection error was: %d """ % (numpy.sum(sink_detect.data()) - n_bursts)
# Here, coarse freq offset is allowed
max_freq_offset = 2*numpy.pi/fft_len * 4
freq_offset = ((2 * random.random()) - 1) * max_freq_offset
- tx_signal = []
packets = []
tagname = "packet_length"
min_packet_length = 10
max_packet_length = 50
- sync_sequence = [random.randint(0, 1)*2-1 for x in range(fft_len // 2)]
- for i in range(n_bursts):
+ for _ in range(n_bursts):
packet_length = random.randint(min_packet_length,
max_packet_length+1)
packet = [random.randint(0, 255) for i in range(packet_length)]
packets.append(packet)
data, tags = tagged_streams.packets_to_vectors(packets, tagname, vlen=1)
- total_length = len(data)
src = blocks.vector_source_b(data, False, 1, tags)
mod = ofdm_tx(packet_length_tag_key=tagname)
sync = digital.ofdm_sync_sc_cfb(fft_len, cp_len)
- sink_freq = blocks.vector_sink_f()
+ sink_freq = blocks.vector_sink_f()
sink_detect = blocks.vector_sink_b()
noise_level = 0.005
channel = channels.channel_model(noise_level, freq_offset / 2 / numpy.pi)
@@ -164,4 +174,3 @@ Detection error was: %d """ % (numpy.sum(sink_detect.data()) - n_bursts)
if __name__ == '__main__':
gr_unittest.run(qa_ofdm_sync_sc_cfb, "qa_ofdm_sync_sc_cfb.xml")
-
diff --git a/gr-digital/python/digital/qa_ofdm_txrx.py b/gr-digital/python/digital/qa_ofdm_txrx.py
index 2e8d101317..74a836a047 100644
--- a/gr-digital/python/digital/qa_ofdm_txrx.py
+++ b/gr-digital/python/digital/qa_ofdm_txrx.py
@@ -67,6 +67,7 @@ class ofdm_rx_fg (gr.top_block):
class test_ofdm_txrx (gr_unittest.TestCase):
def setUp (self):
+ random.seed(0)
self.tb = gr.top_block ()
def tearDown (self):
diff --git a/gr-digital/python/digital/qa_packet_headerparser_b.py b/gr-digital/python/digital/qa_packet_headerparser_b.py
index 3e22fa9100..e41cb35599 100644
--- a/gr-digital/python/digital/qa_packet_headerparser_b.py
+++ b/gr-digital/python/digital/qa_packet_headerparser_b.py
@@ -30,6 +30,7 @@ import pmt
class qa_packet_headerparser_b (gr_unittest.TestCase):
def setUp (self):
+ random.seed(0)
self.tb = gr.top_block ()
def tearDown (self):
diff --git a/gr-digital/python/digital/qa_pfb_clock_sync.py b/gr-digital/python/digital/qa_pfb_clock_sync.py
index 77980d19e5..3f07b328c9 100644
--- a/gr-digital/python/digital/qa_pfb_clock_sync.py
+++ b/gr-digital/python/digital/qa_pfb_clock_sync.py
@@ -31,6 +31,7 @@ from gnuradio import gr, gr_unittest, filter, digital, blocks
class test_pfb_clock_sync(gr_unittest.TestCase):
def setUp(self):
+ random.seed(0)
self.tb = gr.top_block()
def tearDown(self):
diff --git a/gr-dtv/CMakeLists.txt b/gr-dtv/CMakeLists.txt
index 11488ac413..119837ace4 100644
--- a/gr-dtv/CMakeLists.txt
+++ b/gr-dtv/CMakeLists.txt
@@ -57,10 +57,12 @@ add_subdirectory(lib)
if(ENABLE_PYTHON)
add_subdirectory(swig)
add_subdirectory(python/dtv)
- add_subdirectory(grc)
add_subdirectory(examples)
add_subdirectory(apps)
endif(ENABLE_PYTHON)
+if(ENABLE_GRC)
+ add_subdirectory(grc)
+endif(ENABLE_GRC)
add_subdirectory(docs)
########################################################################
diff --git a/gr-dtv/grc/CMakeLists.txt b/gr-dtv/grc/CMakeLists.txt
index 3ed47f2311..ef4b37aae1 100644
--- a/gr-dtv/grc/CMakeLists.txt
+++ b/gr-dtv/grc/CMakeLists.txt
@@ -72,5 +72,6 @@ install(FILES
dtv_catv_randomizer_bb.block.yml
dtv_catv_frame_sync_enc_bb.block.yml
dtv_catv_trellis_enc_bb.block.yml
+ dtv.tree.yml
DESTINATION ${GRC_BLOCKS_DIR}
)
diff --git a/gr-dtv/grc/dtv_dvb_bbheader_bb.block.yml b/gr-dtv/grc/dtv_dvb_bbheader_bb.block.yml
index 520e5dd4c8..6c3c54df75 100644
--- a/gr-dtv/grc/dtv_dvb_bbheader_bb.block.yml
+++ b/gr-dtv/grc/dtv_dvb_bbheader_bb.block.yml
@@ -8,8 +8,8 @@ parameters:
options: [STANDARD_DVBS2, STANDARD_DVBT2]
option_labels: [DVB-S2, DVB-T2]
option_attributes:
- hide_dvbs2: ['', all]
- hide_dvbt2: [all, '']
+ hide_dvbs2: [none, all]
+ hide_dvbt2: [all, none]
val: [dtv.STANDARD_DVBS2, dtv.STANDARD_DVBT2]
- id: framesize1
label: FECFRAME size
@@ -18,8 +18,8 @@ parameters:
option_labels: [Normal, Short]
option_attributes:
hide_medium: [all, all]
- hide_normal: ['', all]
- hide_short: [all, '']
+ hide_normal: [none, all]
+ hide_short: [all, none]
val: [dtv.FECFRAME_NORMAL, dtv.FECFRAME_SHORT]
hide: ${ standard.hide_dvbt2 }
- id: framesize2
@@ -28,9 +28,9 @@ parameters:
options: [FECFRAME_NORMAL, FECFRAME_MEDIUM, FECFRAME_SHORT]
option_labels: [Normal, Medium, Short]
option_attributes:
- hide_medium: [all, '', all]
- hide_normal: ['', all, all]
- hide_short: [all, all, '']
+ hide_medium: [all, none, all]
+ hide_normal: [none, all, all]
+ hide_short: [all, all, none]
val: [dtv.FECFRAME_NORMAL, dtv.FECFRAME_MEDIUM, dtv.FECFRAME_SHORT]
hide: ${ standard.hide_dvbs2 }
- id: rate1
@@ -119,7 +119,7 @@ parameters:
options: [INBAND_OFF, INBAND_ON]
option_labels: ['Off', Type B]
option_attributes:
- hide_rate: [all, '']
+ hide_rate: [all, none]
val: [dtv.INBAND_OFF, dtv.INBAND_ON]
hide: ${ standard.hide_dvbt2 }
- id: fecblocks
diff --git a/gr-dtv/grc/dtv_dvb_bbscrambler_bb.block.yml b/gr-dtv/grc/dtv_dvb_bbscrambler_bb.block.yml
index 86872688ed..6b9c95cef1 100644
--- a/gr-dtv/grc/dtv_dvb_bbscrambler_bb.block.yml
+++ b/gr-dtv/grc/dtv_dvb_bbscrambler_bb.block.yml
@@ -8,8 +8,8 @@ parameters:
options: [STANDARD_DVBS2, STANDARD_DVBT2]
option_labels: [DVB-S2, DVB-T2]
option_attributes:
- hide_dvbs2: ['', all]
- hide_dvbt2: [all, '']
+ hide_dvbs2: [none, all]
+ hide_dvbt2: [all, none]
val: [dtv.STANDARD_DVBS2, dtv.STANDARD_DVBT2]
- id: framesize1
label: FECFRAME size
@@ -18,8 +18,8 @@ parameters:
option_labels: [Normal, Short]
option_attributes:
hide_medium: [all, all]
- hide_normal: ['', all]
- hide_short: [all, '']
+ hide_normal: [none, all]
+ hide_short: [all, none]
val: [dtv.FECFRAME_NORMAL, dtv.FECFRAME_SHORT]
hide: ${ standard.hide_dvbt2 }
- id: framesize2
@@ -28,9 +28,9 @@ parameters:
options: [FECFRAME_NORMAL, FECFRAME_MEDIUM, FECFRAME_SHORT]
option_labels: [Normal, Medium, Short]
option_attributes:
- hide_medium: [all, '', all]
- hide_normal: ['', all, all]
- hide_short: [all, all, '']
+ hide_medium: [all, none, all]
+ hide_normal: [none, all, all]
+ hide_short: [all, all, none]
val: [dtv.FECFRAME_NORMAL, dtv.FECFRAME_MEDIUM, dtv.FECFRAME_SHORT]
hide: ${ standard.hide_dvbs2 }
- id: rate1
diff --git a/gr-dtv/grc/dtv_dvb_bch_bb.block.yml b/gr-dtv/grc/dtv_dvb_bch_bb.block.yml
index a9b47a52b2..817ee54c5d 100644
--- a/gr-dtv/grc/dtv_dvb_bch_bb.block.yml
+++ b/gr-dtv/grc/dtv_dvb_bch_bb.block.yml
@@ -8,8 +8,8 @@ parameters:
options: [STANDARD_DVBS2, STANDARD_DVBT2]
option_labels: [DVB-S2, DVB-T2]
option_attributes:
- hide_dvbs2: ['', all]
- hide_dvbt2: [all, '']
+ hide_dvbs2: [none, all]
+ hide_dvbt2: [all, none]
val: [dtv.STANDARD_DVBS2, dtv.STANDARD_DVBT2]
- id: framesize1
label: FECFRAME size
@@ -18,8 +18,8 @@ parameters:
option_labels: [Normal, Short]
option_attributes:
hide_medium: [all, all]
- hide_normal: ['', all]
- hide_short: [all, '']
+ hide_normal: [none, all]
+ hide_short: [all, none]
val: [dtv.FECFRAME_NORMAL, dtv.FECFRAME_SHORT]
hide: ${ standard.hide_dvbt2 }
- id: framesize2
@@ -28,9 +28,9 @@ parameters:
options: [FECFRAME_NORMAL, FECFRAME_MEDIUM, FECFRAME_SHORT]
option_labels: [Normal, Medium, Short]
option_attributes:
- hide_medium: [all, '', all]
- hide_normal: ['', all, all]
- hide_short: [all, all, '']
+ hide_medium: [all, none, all]
+ hide_normal: [none, all, all]
+ hide_short: [all, all, none]
val: [dtv.FECFRAME_NORMAL, dtv.FECFRAME_MEDIUM, dtv.FECFRAME_SHORT]
hide: ${ standard.hide_dvbs2 }
- id: rate1
diff --git a/gr-dtv/grc/dtv_dvb_ldpc_bb.block.yml b/gr-dtv/grc/dtv_dvb_ldpc_bb.block.yml
index c8b5df4274..863643ce9b 100644
--- a/gr-dtv/grc/dtv_dvb_ldpc_bb.block.yml
+++ b/gr-dtv/grc/dtv_dvb_ldpc_bb.block.yml
@@ -8,8 +8,8 @@ parameters:
options: [STANDARD_DVBS2, STANDARD_DVBT2]
option_labels: [DVB-S2, DVB-T2]
option_attributes:
- hide_dvbs2: ['', all]
- hide_dvbt2: [all, '']
+ hide_dvbs2: [none, all]
+ hide_dvbt2: [all, none]
val: [dtv.STANDARD_DVBS2, dtv.STANDARD_DVBT2]
- id: framesize1
label: FECFRAME size
@@ -18,8 +18,8 @@ parameters:
option_labels: [Normal, Short]
option_attributes:
hide_medium: [all, all]
- hide_normal: ['', all]
- hide_short: [all, '']
+ hide_normal: [none, all]
+ hide_short: [all, none]
val: [dtv.FECFRAME_NORMAL, dtv.FECFRAME_SHORT]
hide: ${ standard.hide_dvbt2 }
- id: framesize2
@@ -28,9 +28,9 @@ parameters:
options: [FECFRAME_NORMAL, FECFRAME_MEDIUM, FECFRAME_SHORT]
option_labels: [Normal, Medium, Short]
option_attributes:
- hide_medium: [all, '', all]
- hide_normal: ['', all, all]
- hide_short: [all, all, '']
+ hide_medium: [all, none, all]
+ hide_normal: [none, all, all]
+ hide_short: [all, all, none]
val: [dtv.FECFRAME_NORMAL, dtv.FECFRAME_MEDIUM, dtv.FECFRAME_SHORT]
hide: ${ standard.hide_dvbs2 }
- id: rate1
@@ -119,7 +119,7 @@ templates:
make: |-
dtv.dvb_ldpc_bb(
${standard.val},
- if str(standard) == 'STANDARD_DVBT2':
+ % if str(standard) == 'STANDARD_DVBT2':
${framesize1.val},
% else:
${framesize2.val},
diff --git a/gr-dtv/grc/dtv_dvbs2_interleaver_bb.block.yml b/gr-dtv/grc/dtv_dvbs2_interleaver_bb.block.yml
index d3a8a77abd..f9ab3446ac 100644
--- a/gr-dtv/grc/dtv_dvbs2_interleaver_bb.block.yml
+++ b/gr-dtv/grc/dtv_dvbs2_interleaver_bb.block.yml
@@ -8,9 +8,9 @@ parameters:
options: [FECFRAME_NORMAL, FECFRAME_MEDIUM, FECFRAME_SHORT]
option_labels: [Normal, Medium, Short]
option_attributes:
- hide_medium: [all, '', all]
- hide_normal: ['', all, all]
- hide_short: [all, all, '']
+ hide_medium: [all, none, all]
+ hide_normal: [none, all, all]
+ hide_short: [all, all, none]
val: [dtv.FECFRAME_NORMAL, dtv.FECFRAME_MEDIUM, dtv.FECFRAME_SHORT]
- id: rate1
label: Code rate
diff --git a/gr-dtv/grc/dtv_dvbs2_modulator_bc.block.yml b/gr-dtv/grc/dtv_dvbs2_modulator_bc.block.yml
index dee9dba9b0..7935e0d85b 100644
--- a/gr-dtv/grc/dtv_dvbs2_modulator_bc.block.yml
+++ b/gr-dtv/grc/dtv_dvbs2_modulator_bc.block.yml
@@ -8,9 +8,9 @@ parameters:
options: [FECFRAME_NORMAL, FECFRAME_MEDIUM, FECFRAME_SHORT]
option_labels: [Normal, Medium, Short]
option_attributes:
- hide_medium: [all, '', all]
- hide_normal: ['', all, all]
- hide_short: [all, all, '']
+ hide_medium: [all, none, all]
+ hide_normal: [none, all, all]
+ hide_short: [all, all, none]
val: [dtv.FECFRAME_NORMAL, dtv.FECFRAME_MEDIUM, dtv.FECFRAME_SHORT]
hide: ${ constellation.hide_dvb }
- id: rate1
@@ -71,8 +71,8 @@ parameters:
64APSK, 8+16+20+20APSK, 4+12+20+28APSK, 128APSK, 256APSK, 64QAM (ITU-T J.83B),
256QAM (ITU-T J.83B), PI/2 BPSK, PI/2 BPSK-SF2, 8VSB (ATSC)]
option_attributes:
- hide_dvb: ['', '', '', '', '', '', '', '', '', '', '', '', '', all, all, '',
- '', all]
+ hide_dvb: [none, none, none, none, none, none, none, none, none, none, none, none, none, all, all, none,
+ none, all]
val: [dtv.MOD_QPSK, dtv.MOD_8PSK, dtv.MOD_8APSK, dtv.MOD_16APSK, dtv.MOD_8_8APSK,
dtv.MOD_32APSK, dtv.MOD_4_12_16APSK, dtv.MOD_4_8_4_16APSK, dtv.MOD_64APSK,
dtv.MOD_8_16_20_20APSK, dtv.MOD_4_12_20_28APSK, dtv.MOD_128APSK, dtv.MOD_256APSK,
diff --git a/gr-dtv/grc/dtv_dvbs2_physical_cc.block.yml b/gr-dtv/grc/dtv_dvbs2_physical_cc.block.yml
index 9872446d08..5aa0fda307 100644
--- a/gr-dtv/grc/dtv_dvbs2_physical_cc.block.yml
+++ b/gr-dtv/grc/dtv_dvbs2_physical_cc.block.yml
@@ -8,9 +8,9 @@ parameters:
options: [FECFRAME_NORMAL, FECFRAME_MEDIUM, FECFRAME_SHORT]
option_labels: [Normal, Medium, Short]
option_attributes:
- hide_medium: [all, '', all]
- hide_normal: ['', all, all]
- hide_short: [all, all, '']
+ hide_medium: [all, none, all]
+ hide_normal: [none, all, all]
+ hide_short: [all, all, none]
val: [dtv.FECFRAME_NORMAL, dtv.FECFRAME_MEDIUM, dtv.FECFRAME_SHORT]
- id: rate1
label: Code rate
diff --git a/gr-dtv/grc/dtv_dvbt2_framemapper_cc.block.yml b/gr-dtv/grc/dtv_dvbt2_framemapper_cc.block.yml
index bb753e4625..7a11df6680 100644
--- a/gr-dtv/grc/dtv_dvbt2_framemapper_cc.block.yml
+++ b/gr-dtv/grc/dtv_dvbt2_framemapper_cc.block.yml
@@ -123,8 +123,8 @@ parameters:
options: [VERSION_111, VERSION_131]
option_labels: [1.1.1, 1.3.1]
option_attributes:
- hide_111: ['', all]
- hide_131: [all, '']
+ hide_111: [none, all]
+ hide_131: [all, none]
val: [dtv.VERSION_111, dtv.VERSION_131]
- id: preamble1
label: Preamble
@@ -132,7 +132,7 @@ parameters:
options: [PREAMBLE_T2_SISO, PREAMBLE_T2_MISO]
option_labels: [T2 SISO, T2 MISO]
option_attributes:
- hide_base: ['', '']
+ hide_base: [none, none]
hide_lite: [all, all]
val: [dtv.PREAMBLE_T2_SISO, dtv.PREAMBLE_T2_MISO]
hide: ${ version.hide_111 }
@@ -142,8 +142,8 @@ parameters:
options: [PREAMBLE_T2_SISO, PREAMBLE_T2_MISO, PREAMBLE_T2_LITE_SISO, PREAMBLE_T2_LITE_MISO]
option_labels: [T2 SISO, T2 MISO, T2-Lite SISO, T2-Lite MISO]
option_attributes:
- hide_base: ['', '', all, all]
- hide_lite: [all, all, '', '']
+ hide_base: [none, none, all, all]
+ hide_lite: [all, all, none, none]
val: [dtv.PREAMBLE_T2_SISO, dtv.PREAMBLE_T2_MISO, dtv.PREAMBLE_T2_LITE_SISO,
dtv.PREAMBLE_T2_LITE_MISO]
hide: ${ version.hide_131 }
diff --git a/gr-dtv/grc/dtv_dvbt2_freqinterleaver_cc.block.yml b/gr-dtv/grc/dtv_dvbt2_freqinterleaver_cc.block.yml
index e6977374f0..15d7d80f75 100644
--- a/gr-dtv/grc/dtv_dvbt2_freqinterleaver_cc.block.yml
+++ b/gr-dtv/grc/dtv_dvbt2_freqinterleaver_cc.block.yml
@@ -64,8 +64,8 @@ parameters:
options: [VERSION_111, VERSION_131]
option_labels: [1.1.1, 1.3.1]
option_attributes:
- hide_111: ['', all]
- hide_131: [all, '']
+ hide_111: [none, all]
+ hide_131: [all, none]
val: [dtv.VERSION_111, dtv.VERSION_131]
- id: preamble1
label: Preamble
diff --git a/gr-dtv/grc/dtv_dvbt2_miso_cc.block.yml b/gr-dtv/grc/dtv_dvbt2_miso_cc.block.yml
index e00a0b047e..d26dae4a2d 100644
--- a/gr-dtv/grc/dtv_dvbt2_miso_cc.block.yml
+++ b/gr-dtv/grc/dtv_dvbt2_miso_cc.block.yml
@@ -64,8 +64,8 @@ parameters:
options: [VERSION_111, VERSION_131]
option_labels: [1.1.1, 1.3.1]
option_attributes:
- hide_111: ['', all]
- hide_131: [all, '']
+ hide_111: [none, all]
+ hide_131: [all, none]
val: [dtv.VERSION_111, dtv.VERSION_131]
inputs:
diff --git a/gr-dtv/grc/dtv_dvbt2_p1insertion_cc.block.yml b/gr-dtv/grc/dtv_dvbt2_p1insertion_cc.block.yml
index 2749f035d0..42ce872421 100644
--- a/gr-dtv/grc/dtv_dvbt2_p1insertion_cc.block.yml
+++ b/gr-dtv/grc/dtv_dvbt2_p1insertion_cc.block.yml
@@ -48,8 +48,8 @@ parameters:
options: [VERSION_111, VERSION_131]
option_labels: [1.1.1, 1.3.1]
option_attributes:
- hide_111: ['', all]
- hide_131: [all, '']
+ hide_111: [none, all]
+ hide_131: [all, none]
val: [dtv.VERSION_111, dtv.VERSION_131]
- id: preamble1
label: Preamble
@@ -57,7 +57,7 @@ parameters:
options: [PREAMBLE_T2_SISO, PREAMBLE_T2_MISO]
option_labels: [T2 SISO, T2 MISO]
option_attributes:
- hide_base: ['', '']
+ hide_base: [none, none]
hide_lite: [all, all]
val: [dtv.PREAMBLE_T2_SISO, dtv.PREAMBLE_T2_MISO]
hide: ${ version.hide_111 }
@@ -67,8 +67,8 @@ parameters:
options: [PREAMBLE_T2_SISO, PREAMBLE_T2_MISO, PREAMBLE_T2_LITE_SISO, PREAMBLE_T2_LITE_MISO]
option_labels: [T2 SISO, T2 MISO, T2-Lite SISO, T2-Lite MISO]
option_attributes:
- hide_base: ['', '', all, all]
- hide_lite: [all, all, '', '']
+ hide_base: [none, none, all, all]
+ hide_lite: [all, all, none, none]
val: [dtv.PREAMBLE_T2_SISO, dtv.PREAMBLE_T2_MISO, dtv.PREAMBLE_T2_LITE_SISO,
dtv.PREAMBLE_T2_LITE_MISO]
hide: ${ version.hide_131 }
@@ -78,7 +78,7 @@ parameters:
options: [SHOWLEVELS_OFF, SHOWLEVELS_ON]
option_labels: ['Off', 'On']
option_attributes:
- hide_vclip: [all, '']
+ hide_vclip: [all, none]
val: [dtv.SHOWLEVELS_OFF, dtv.SHOWLEVELS_ON]
- id: vclip
label: Vclip
diff --git a/gr-dtv/grc/dtv_dvbt2_paprtr_cc.block.yml b/gr-dtv/grc/dtv_dvbt2_paprtr_cc.block.yml
index 646291b1af..1ec6670e36 100644
--- a/gr-dtv/grc/dtv_dvbt2_paprtr_cc.block.yml
+++ b/gr-dtv/grc/dtv_dvbt2_paprtr_cc.block.yml
@@ -50,7 +50,7 @@ parameters:
option_labels: ['Off', Active Constellation Extension, Tone Reservation, Both
ACE and TR]
option_attributes:
- hide_vclip: [all, all, '', '']
+ hide_vclip: [all, all, none, none]
val: [dtv.PAPR_OFF, dtv.PAPR_ACE, dtv.PAPR_TR, dtv.PAPR_BOTH]
hide: ${ version.hide_111 }
- id: paprmode2
@@ -60,7 +60,7 @@ parameters:
option_labels: [P2 Only, Active Constellation Extension, Tone Reservation, Both
ACE and TR]
option_attributes:
- hide_vclip: [all, all, '', '']
+ hide_vclip: [all, all, none, none]
val: [dtv.PAPR_OFF, dtv.PAPR_ACE, dtv.PAPR_TR, dtv.PAPR_BOTH]
hide: ${ version.hide_131 }
- id: version
@@ -69,8 +69,8 @@ parameters:
options: [VERSION_111, VERSION_131]
option_labels: [1.1.1, 1.3.1]
option_attributes:
- hide_111: ['', all]
- hide_131: [all, '']
+ hide_111: [none, all]
+ hide_131: [all, none]
val: [dtv.VERSION_111, dtv.VERSION_131]
- id: vclip
label: Vclip
diff --git a/gr-dtv/grc/dtv_dvbt2_pilotgenerator_cc.block.yml b/gr-dtv/grc/dtv_dvbt2_pilotgenerator_cc.block.yml
index 1e9d7a9b74..021e7f90ae 100644
--- a/gr-dtv/grc/dtv_dvbt2_pilotgenerator_cc.block.yml
+++ b/gr-dtv/grc/dtv_dvbt2_pilotgenerator_cc.block.yml
@@ -19,9 +19,8 @@ parameters:
option_attributes:
val: [dtv.FFTSIZE_1K, dtv.FFTSIZE_2K, dtv.FFTSIZE_4K, dtv.FFTSIZE_8K, dtv.FFTSIZE_8K_T2GI,
dtv.FFTSIZE_16K, dtv.FFTSIZE_16K_T2GI, dtv.FFTSIZE_32K, dtv.FFTSIZE_32K_T2GI]
- vlength: ['1024', '2048', '4096', '8192', '8192', '16384', '16384', '32768',
- '32768']
- hide: ${ 'part' if vlen == 1 else 'none' }
+ vlength: [1024, 2048, 4096, 8192, 8192, 16384, 16384, 32768,
+ 32768]
- id: pilotpattern
label: Pilot Pattern
dtype: enum
@@ -67,8 +66,8 @@ parameters:
options: [VERSION_111, VERSION_131]
option_labels: [1.1.1, 1.3.1]
option_attributes:
- hide_111: ['', all]
- hide_131: [all, '']
+ hide_111: [none, all]
+ hide_131: [all, none]
val: [dtv.VERSION_111, dtv.VERSION_131]
- id: preamble1
label: Preamble
@@ -76,7 +75,7 @@ parameters:
options: [PREAMBLE_T2_SISO, PREAMBLE_T2_MISO]
option_labels: [T2 SISO, T2 MISO]
option_attributes:
- hide_miso: [all, '']
+ hide_miso: [all, none]
val: [dtv.PREAMBLE_T2_SISO, dtv.PREAMBLE_T2_MISO]
hide: ${ version.hide_111 }
- id: preamble2
@@ -85,7 +84,7 @@ parameters:
options: [PREAMBLE_T2_SISO, PREAMBLE_T2_MISO, PREAMBLE_T2_LITE_SISO, PREAMBLE_T2_LITE_MISO]
option_labels: [T2 SISO, T2 MISO, T2-Lite SISO, T2-Lite MISO]
option_attributes:
- hide_miso: [all, '', all, '']
+ hide_miso: [all, none, all, none]
val: [dtv.PREAMBLE_T2_SISO, dtv.PREAMBLE_T2_MISO, dtv.PREAMBLE_T2_LITE_SISO,
dtv.PREAMBLE_T2_LITE_MISO]
hide: ${ version.hide_131 }
@@ -104,7 +103,7 @@ parameters:
options: [EQUALIZATION_OFF, EQUALIZATION_ON]
option_labels: ['Off', 'On']
option_attributes:
- hide_bandwidth: [all, '']
+ hide_bandwidth: [all, none]
val: [dtv.EQUALIZATION_OFF, dtv.EQUALIZATION_ON]
- id: bandwidth
label: Bandwidth
diff --git a/gr-dtv/lib/dvb/dvb_bbscrambler_bb_impl.cc b/gr-dtv/lib/dvb/dvb_bbscrambler_bb_impl.cc
index 8e86eb4f64..c9401258b7 100644
--- a/gr-dtv/lib/dvb/dvb_bbscrambler_bb_impl.cc
+++ b/gr-dtv/lib/dvb/dvb_bbscrambler_bb_impl.cc
@@ -268,6 +268,8 @@ namespace gr {
sr |= 0x4000;
}
}
+ bb_randomize64 = (uint64_t*)&bb_randomise[0];
+
}
int
@@ -275,12 +277,13 @@ namespace gr {
gr_vector_const_void_star &input_items,
gr_vector_void_star &output_items)
{
- const unsigned char *in = (const unsigned char *) input_items[0];
- unsigned char *out = (unsigned char *) output_items[0];
+ // noutput_items is multiple of kbch and kbch is always divisible by 8
+ const uint64_t *in = (const uint64_t *) input_items[0];
+ uint64_t *out = (uint64_t *) output_items[0];
for (int i = 0; i < noutput_items; i += kbch) {
- for (int j = 0; j < (int)kbch; ++j) {
- out[i + j] = in[i + j] ^ bb_randomise[j];
+ for (int j = 0; j < kbch/8; ++j) {
+ *out++ = *in++ ^ bb_randomize64[j];
}
}
diff --git a/gr-dtv/lib/dvb/dvb_bbscrambler_bb_impl.h b/gr-dtv/lib/dvb/dvb_bbscrambler_bb_impl.h
index d717731502..062e1b68a2 100644
--- a/gr-dtv/lib/dvb/dvb_bbscrambler_bb_impl.h
+++ b/gr-dtv/lib/dvb/dvb_bbscrambler_bb_impl.h
@@ -30,8 +30,9 @@ namespace gr {
class dvb_bbscrambler_bb_impl : public dvb_bbscrambler_bb
{
private:
- unsigned int kbch;
+ int kbch;
unsigned char bb_randomise[FRAME_SIZE_NORMAL];
+ uint64_t* bb_randomize64;
void init_bb_randomiser(void);
public:
diff --git a/gr-dtv/lib/dvb/dvb_bch_bb_impl.cc b/gr-dtv/lib/dvb/dvb_bch_bb_impl.cc
index 8d89f9b04a..6f184c8e05 100644
--- a/gr-dtv/lib/dvb/dvb_bch_bb_impl.cc
+++ b/gr-dtv/lib/dvb/dvb_bch_bb_impl.cc
@@ -1,6 +1,6 @@
/* -*- c++ -*- */
/*
- * Copyright 2015,2016 Free Software Foundation, Inc.
+ * Copyright 2015,2016,2018 Free Software Foundation, Inc.
*
* This is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -371,6 +371,24 @@ namespace gr {
}
}
+ switch (bch_code) {
+ case BCH_CODE_N12:
+ num_parity_bits = 192;
+ break;
+ case BCH_CODE_N10:
+ num_parity_bits = 160;
+ break;
+ case BCH_CODE_N8:
+ num_parity_bits = 128;
+ break;
+ case BCH_CODE_M12:
+ num_parity_bits = 180;
+ break;
+ case BCH_CODE_S12:
+ num_parity_bits = 168;
+ break;
+ }
+
bch_poly_build_tables();
set_output_multiple(nbch);
}
@@ -415,82 +433,28 @@ namespace gr {
return max + 1;
}
- /*
- * Pack the polynomial into a 32 bit array
- */
+ //precalculate the crc from: http://www.sunshine2k.de/articles/coding/crc/understanding_crc.html - cf. CRC-32 Lookup
void
- dvb_bch_bb_impl::poly_pack(const int *pin, unsigned int* pout, int len)
+ dvb_bch_bb_impl::calculate_crc_table(void)
{
- int lw = len / 32;
- int ptr = 0;
- unsigned int temp;
- if (len % 32) {
- lw++;
- }
-
- for (int i = 0; i < lw; i++) {
- temp = 0x80000000;
- pout[i] = 0;
- for (int j = 0; j < 32; j++) {
- if (pin[ptr++]) {
- pout[i] |= temp;
+ for (int divident = 0; divident < 256; divident++) { /* iterate over all possible input byte values 0 - 255 */
+ std::bitset<MAX_BCH_PARITY_BITS> curByte(divident);
+ curByte <<= num_parity_bits - 8;
+
+ for (unsigned char bit = 0; bit < 8; bit++) {
+ if ((curByte[num_parity_bits - 1]) != 0) {
+ curByte <<= 1;
+ curByte ^= polynome;
+ }
+ else {
+ curByte <<= 1;
}
- temp >>= 1;
}
+ crc_table[divident] = curByte;
}
}
void
- dvb_bch_bb_impl::poly_reverse(int *pin, int *pout, int len)
- {
- int c;
- c = len - 1;
-
- for (int i = 0; i < len; i++) {
- pout[c--] = pin[i];
- }
- }
-
- /*
- *Shift a 128 bit register
- */
- inline void
- dvb_bch_bb_impl::reg_4_shift(unsigned int *sr)
- {
- sr[3] = (sr[3] >> 1) | (sr[2] << 31);
- sr[2] = (sr[2] >> 1) | (sr[1] << 31);
- sr[1] = (sr[1] >> 1) | (sr[0] << 31);
- sr[0] = (sr[0] >> 1);
- }
-
- /*
- * Shift 160 bits
- */
- inline void
- dvb_bch_bb_impl::reg_5_shift(unsigned int *sr)
- {
- sr[4] = (sr[4] >> 1) | (sr[3] << 31);
- sr[3] = (sr[3] >> 1) | (sr[2] << 31);
- sr[2] = (sr[2] >> 1) | (sr[1] << 31);
- sr[1] = (sr[1] >> 1) | (sr[0] << 31);
- sr[0] = (sr[0] >> 1);
- }
-
- /*
- * Shift 192 bits
- */
- inline void
- dvb_bch_bb_impl::reg_6_shift(unsigned int *sr)
- {
- sr[5] = (sr[5] >> 1) | (sr[4] << 31);
- sr[4] = (sr[4] >> 1) | (sr[3] << 31);
- sr[3] = (sr[3] >> 1) | (sr[2] << 31);
- sr[2] = (sr[2] >> 1) | (sr[1] << 31);
- sr[1] = (sr[1] >> 1) | (sr[0] << 31);
- sr[0] = (sr[0] >> 1);
- }
-
- void
dvb_bch_bb_impl::bch_poly_build_tables(void)
{
// Normal polynomials
@@ -538,48 +502,73 @@ namespace gr {
int len;
int polyout[2][200];
- len = poly_mult(polyn01, 17, polyn02, 17, polyout[0]);
- len = poly_mult(polyn03, 17, polyout[0], len, polyout[1]);
- len = poly_mult(polyn04, 17, polyout[1], len, polyout[0]);
- len = poly_mult(polyn05, 17, polyout[0], len, polyout[1]);
- len = poly_mult(polyn06, 17, polyout[1], len, polyout[0]);
- len = poly_mult(polyn07, 17, polyout[0], len, polyout[1]);
- len = poly_mult(polyn08, 17, polyout[1], len, polyout[0]);
- poly_pack(polyout[0], m_poly_n_8, 128);
-
- len = poly_mult(polyn09, 17, polyout[0], len, polyout[1]);
- len = poly_mult(polyn10, 17, polyout[1], len, polyout[0]);
- poly_pack(polyout[0], m_poly_n_10, 160);
-
- len = poly_mult(polyn11, 17, polyout[0], len, polyout[1]);
- len = poly_mult(polyn12, 17, polyout[1], len, polyout[0]);
- poly_pack(polyout[0], m_poly_n_12, 192);
-
- len = poly_mult(polys01, 15, polys02, 15, polyout[0]);
- len = poly_mult(polys03, 15, polyout[0], len, polyout[1]);
- len = poly_mult(polys04, 15, polyout[1], len, polyout[0]);
- len = poly_mult(polys05, 15, polyout[0], len, polyout[1]);
- len = poly_mult(polys06, 15, polyout[1], len, polyout[0]);
- len = poly_mult(polys07, 15, polyout[0], len, polyout[1]);
- len = poly_mult(polys08, 15, polyout[1], len, polyout[0]);
- len = poly_mult(polys09, 15, polyout[0], len, polyout[1]);
- len = poly_mult(polys10, 15, polyout[1], len, polyout[0]);
- len = poly_mult(polys11, 15, polyout[0], len, polyout[1]);
- len = poly_mult(polys12, 15, polyout[1], len, polyout[0]);
- poly_pack(polyout[0], m_poly_s_12, 168);
-
- len = poly_mult(polym01, 16, polym02, 16, polyout[0]);
- len = poly_mult(polym03, 16, polyout[0], len, polyout[1]);
- len = poly_mult(polym04, 16, polyout[1], len, polyout[0]);
- len = poly_mult(polym05, 16, polyout[0], len, polyout[1]);
- len = poly_mult(polym06, 16, polyout[1], len, polyout[0]);
- len = poly_mult(polym07, 16, polyout[0], len, polyout[1]);
- len = poly_mult(polym08, 16, polyout[1], len, polyout[0]);
- len = poly_mult(polym09, 16, polyout[0], len, polyout[1]);
- len = poly_mult(polym10, 16, polyout[1], len, polyout[0]);
- len = poly_mult(polym11, 16, polyout[0], len, polyout[1]);
- len = poly_mult(polym12, 16, polyout[1], len, polyout[0]);
- poly_pack(polyout[0], m_poly_m_12, 180);
+#define COPY_BCH_POLYNOME \
+for (unsigned int i = 0; i < num_parity_bits; i ++) {\
+ polynome[i] = polyout[0][i];\
+}
+
+ switch (bch_code) {
+ case BCH_CODE_N12:
+ case BCH_CODE_N10:
+ case BCH_CODE_N8:
+
+ len = poly_mult(polyn01, 17, polyn02, 17, polyout[0]);
+ len = poly_mult(polyn03, 17, polyout[0], len, polyout[1]);
+ len = poly_mult(polyn04, 17, polyout[1], len, polyout[0]);
+ len = poly_mult(polyn05, 17, polyout[0], len, polyout[1]);
+ len = poly_mult(polyn06, 17, polyout[1], len, polyout[0]);
+ len = poly_mult(polyn07, 17, polyout[0], len, polyout[1]);
+ len = poly_mult(polyn08, 17, polyout[1], len, polyout[0]);
+ if (bch_code == BCH_CODE_N8) {
+ COPY_BCH_POLYNOME
+ }
+
+ len = poly_mult(polyn09, 17, polyout[0], len, polyout[1]);
+ len = poly_mult(polyn10, 17, polyout[1], len, polyout[0]);
+ if (bch_code == BCH_CODE_N10) {
+ COPY_BCH_POLYNOME
+ }
+
+ len = poly_mult(polyn11, 17, polyout[0], len, polyout[1]);
+ len = poly_mult(polyn12, 17, polyout[1], len, polyout[0]);
+ if (bch_code == BCH_CODE_N12) {
+ COPY_BCH_POLYNOME
+ }
+ break;
+
+ case BCH_CODE_S12:
+ len = poly_mult(polys01, 15, polys02, 15, polyout[0]);
+ len = poly_mult(polys03, 15, polyout[0], len, polyout[1]);
+ len = poly_mult(polys04, 15, polyout[1], len, polyout[0]);
+ len = poly_mult(polys05, 15, polyout[0], len, polyout[1]);
+ len = poly_mult(polys06, 15, polyout[1], len, polyout[0]);
+ len = poly_mult(polys07, 15, polyout[0], len, polyout[1]);
+ len = poly_mult(polys08, 15, polyout[1], len, polyout[0]);
+ len = poly_mult(polys09, 15, polyout[0], len, polyout[1]);
+ len = poly_mult(polys10, 15, polyout[1], len, polyout[0]);
+ len = poly_mult(polys11, 15, polyout[0], len, polyout[1]);
+ len = poly_mult(polys12, 15, polyout[1], len, polyout[0]);
+
+ COPY_BCH_POLYNOME
+ break;
+
+ case BCH_CODE_M12:
+ len = poly_mult(polym01, 16, polym02, 16, polyout[0]);
+ len = poly_mult(polym03, 16, polyout[0], len, polyout[1]);
+ len = poly_mult(polym04, 16, polyout[1], len, polyout[0]);
+ len = poly_mult(polym05, 16, polyout[0], len, polyout[1]);
+ len = poly_mult(polym06, 16, polyout[1], len, polyout[0]);
+ len = poly_mult(polym07, 16, polyout[0], len, polyout[1]);
+ len = poly_mult(polym08, 16, polyout[1], len, polyout[0]);
+ len = poly_mult(polym09, 16, polyout[0], len, polyout[1]);
+ len = poly_mult(polym10, 16, polyout[1], len, polyout[0]);
+ len = poly_mult(polym11, 16, polyout[0], len, polyout[1]);
+ len = poly_mult(polym12, 16, polyout[1], len, polyout[0]);
+
+ COPY_BCH_POLYNOME
+ break;
+ }
+ calculate_crc_table();
}
int
@@ -590,143 +579,41 @@ namespace gr {
{
const unsigned char *in = (const unsigned char *) input_items[0];
unsigned char *out = (unsigned char *) output_items[0];
- unsigned char b, temp;
- unsigned int shift[6];
+ unsigned char b, temp, msb;
+
+ // We can use a 192 bits long bitset, all higher bits not used by the bch will just be ignored
+ std::bitset<MAX_BCH_PARITY_BITS> parity_bits;
int consumed = 0;
- switch (bch_code) {
- case BCH_CODE_N12:
- for (int i = 0; i < noutput_items; i += nbch) {
- //Zero the shift register
- memset(shift, 0, sizeof(unsigned int) * 6);
- // MSB of the codeword first
- for (int j = 0; j < (int)kbch; j++) {
- temp = *in++;
- *out++ = temp;
- consumed++;
- b = (temp ^ (shift[5] & 1));
- reg_6_shift(shift);
- if (b) {
- shift[0] ^= m_poly_n_12[0];
- shift[1] ^= m_poly_n_12[1];
- shift[2] ^= m_poly_n_12[2];
- shift[3] ^= m_poly_n_12[3];
- shift[4] ^= m_poly_n_12[4];
- shift[5] ^= m_poly_n_12[5];
- }
- }
- // Now add the parity bits to the output
- for (int n = 0; n < 192; n++) {
- *out++ = (shift[5] & 1);
- reg_6_shift(shift);
- }
- }
- break;
- case BCH_CODE_N10:
- for (int i = 0; i < noutput_items; i += nbch) {
- //Zero the shift register
- memset(shift, 0, sizeof(unsigned int) * 5);
- // MSB of the codeword first
- for (int j = 0; j < (int)kbch; j++) {
- temp = *in++;
- *out++ = temp;
- consumed++;
- b = (temp ^ (shift[4] & 1));
- reg_5_shift(shift);
- if (b) {
- shift[0] ^= m_poly_n_10[0];
- shift[1] ^= m_poly_n_10[1];
- shift[2] ^= m_poly_n_10[2];
- shift[3] ^= m_poly_n_10[3];
- shift[4] ^= m_poly_n_10[4];
- }
- }
- // Now add the parity bits to the output
- for( int n = 0; n < 160; n++ ) {
- *out++ = (shift[4] & 1);
- reg_5_shift(shift);
- }
- }
- break;
- case BCH_CODE_N8:
- for (int i = 0; i < noutput_items; i += nbch) {
- //Zero the shift register
- memset(shift, 0, sizeof(unsigned int) * 4);
- // MSB of the codeword first
- for (int j = 0; j < (int)kbch; j++) {
- temp = *in++;
- *out++ = temp;
- consumed++;
- b = temp ^ (shift[3] & 1);
- reg_4_shift(shift);
- if (b) {
- shift[0] ^= m_poly_n_8[0];
- shift[1] ^= m_poly_n_8[1];
- shift[2] ^= m_poly_n_8[2];
- shift[3] ^= m_poly_n_8[3];
- }
- }
- // Now add the parity bits to the output
- for (int n = 0; n < 128; n++) {
- *out++ = shift[3] & 1;
- reg_4_shift(shift);
- }
- }
- break;
- case BCH_CODE_S12:
- for (int i = 0; i < noutput_items; i += nbch) {
- //Zero the shift register
- memset(shift, 0, sizeof(unsigned int) * 6);
- // MSB of the codeword first
- for (int j = 0; j < (int)kbch; j++) {
- temp = *in++;
- *out++ = temp;
- consumed++;
- b = (temp ^ ((shift[5] & 0x01000000) ? 1 : 0));
- reg_6_shift(shift);
- if (b) {
- shift[0] ^= m_poly_s_12[0];
- shift[1] ^= m_poly_s_12[1];
- shift[2] ^= m_poly_s_12[2];
- shift[3] ^= m_poly_s_12[3];
- shift[4] ^= m_poly_s_12[4];
- shift[5] ^= m_poly_s_12[5];
- }
- }
- // Now add the parity bits to the output
- for (int n = 0; n < 168; n++) {
- *out++ = (shift[5] & 0x01000000) ? 1 : 0;
- reg_6_shift(shift);
- }
+ for (int i = 0; i < noutput_items; i += nbch) {
+ for (int j = 0; j < (int)kbch / 8; j++) {
+ b = 0;
+
+ // calculate the crc using the lookup table, cf. http://www.sunshine2k.de/articles/coding/crc/understanding_crc.html
+ for (int e = 0; e < 8; e++) {
+ temp = *in++;
+ *out++ = temp;
+ consumed++;
+
+ b |= temp << (7 - e);
}
- break;
- case BCH_CODE_M12:
- for (int i = 0; i < noutput_items; i += nbch) {
- //Zero the shift register
- memset(shift, 0, sizeof(unsigned int) * 6);
- // MSB of the codeword first
- for (int j = 0; j < (int)kbch; j++) {
- temp = *in++;
- *out++ = temp;
- consumed++;
- b = (temp ^ ((shift[5] & 0x00001000) ? 1 : 0));
- reg_6_shift(shift);
- if (b) {
- shift[0] ^= m_poly_m_12[0];
- shift[1] ^= m_poly_m_12[1];
- shift[2] ^= m_poly_m_12[2];
- shift[3] ^= m_poly_m_12[3];
- shift[4] ^= m_poly_m_12[4];
- shift[5] ^= m_poly_m_12[5];
- }
- }
- // Now add the parity bits to the output
- for (int n = 0; n < 180; n++) {
- *out++ = (shift[5] & 0x00001000) ? 1 : 0;
- reg_6_shift(shift);
- }
+
+ msb = 0;
+ for (int n = 1; n <= 8; n++) {
+ temp = parity_bits[num_parity_bits - n];
+ msb |= temp << (8 - n);
}
- break;
+ /* XOR-in next input byte into MSB of crc and get this MSB, that's our new intermediate divident */
+ unsigned char pos = (msb ^ b);
+ /* Shift out the MSB used for division per lookuptable and XOR with the remainder */
+ parity_bits = (parity_bits << 8) ^ crc_table[pos];
+ }
+
+ // Now add the parity bits to the output
+ for (unsigned int n = 0; n < num_parity_bits; n++) {
+ *out++ = (char) parity_bits[num_parity_bits - 1];
+ parity_bits <<= 1;
+ }
}
// Tell runtime system how many input items we consumed on
diff --git a/gr-dtv/lib/dvb/dvb_bch_bb_impl.h b/gr-dtv/lib/dvb/dvb_bch_bb_impl.h
index 56b4772b26..d715161431 100644
--- a/gr-dtv/lib/dvb/dvb_bch_bb_impl.h
+++ b/gr-dtv/lib/dvb/dvb_bch_bb_impl.h
@@ -23,6 +23,9 @@
#include <gnuradio/dtv/dvb_bch_bb.h>
#include "dvb_defines.h"
+#include <bitset>
+
+#define MAX_BCH_PARITY_BITS 192
namespace gr {
namespace dtv {
@@ -33,17 +36,13 @@ namespace gr {
unsigned int kbch;
unsigned int nbch;
unsigned int bch_code;
- unsigned int m_poly_n_8[4];
- unsigned int m_poly_n_10[5];
- unsigned int m_poly_n_12[6];
- unsigned int m_poly_s_12[6];
- unsigned int m_poly_m_12[6];
+
+ std::bitset<MAX_BCH_PARITY_BITS> crc_table[256];
+ unsigned int num_parity_bits;
+ std::bitset<MAX_BCH_PARITY_BITS> polynome;
+
+ void calculate_crc_table();
int poly_mult(const int*, int, const int*, int, int*);
- void poly_pack(const int*, unsigned int*, int);
- void poly_reverse(int*, int*, int);
- inline void reg_4_shift(unsigned int*);
- inline void reg_5_shift(unsigned int*);
- inline void reg_6_shift(unsigned int*);
void bch_poly_build_tables(void);
public:
diff --git a/gr-dtv/lib/dvb/dvb_ldpc_bb_impl.cc b/gr-dtv/lib/dvb/dvb_ldpc_bb_impl.cc
index 84328e1200..e907bbb499 100644
--- a/gr-dtv/lib/dvb/dvb_ldpc_bb_impl.cc
+++ b/gr-dtv/lib/dvb/dvb_ldpc_bb_impl.cc
@@ -364,6 +364,8 @@ namespace gr {
*/
dvb_ldpc_bb_impl::~dvb_ldpc_bb_impl()
{
+ delete[] ldpc_lut[0];
+ delete[] ldpc_lut;
}
void
@@ -373,29 +375,48 @@ namespace gr {
}
#define LDPC_BF(TABLE_NAME, ROWS) \
+for (int row = 0; row < ROWS; row++) { /* count the entries in the table */ \
+ max_lut_arraysize += TABLE_NAME[row][0]; \
+} \
+max_lut_arraysize *= 360; /* 360 bits per table entry */ \
+max_lut_arraysize /= pbits; /* spread over all parity bits */ \
+max_lut_arraysize += 2; /* 1 for the size at the start of the array, one as buffer */ \
+\
+/* Allocate a 2D Array with pbits * max_lut_arraysize
+ * while preserving two-subscript access
+ * see https://stackoverflow.com/questions/29375797/copy-2d-array-using-memcpy/29375830#29375830
+ */ \
+ldpc_lut = new int*[pbits]; \
+ldpc_lut[0] = new int[pbits * max_lut_arraysize]; \
+ldpc_lut[0][0] = 1; \
+for (int i = 1; i < pbits; i++) { \
+ ldpc_lut[i] = ldpc_lut[i-1] + max_lut_arraysize; \
+ ldpc_lut[i][0] = 1; \
+} \
for (int row = 0; row < ROWS; row++) { \
for (int n = 0; n < 360; n++) { \
for (int col = 1; col <= TABLE_NAME[row][0]; col++) { \
- ldpc_encode.p[index] = (TABLE_NAME[row][col] + (n * q)) % pbits; \
- ldpc_encode.d[index] = im; \
- index++; \
+ int current_pbit = (TABLE_NAME[row][col] + (n * q)) % pbits; \
+ ldpc_lut[current_pbit][ldpc_lut[current_pbit][0]] = im; \
+ ldpc_lut[current_pbit][0]++; \
} \
im++; \
} \
-}
+}
+ /*
+ * fill the lookup table, for each paritybit it contains
+ * {number of infobits, infobit1, infobit2, ... ]
+ * maximum number of infobits is calculated using the entries
+ * in the ldpc tables
+ */
void
dvb_ldpc_bb_impl::ldpc_lookup_generate(void)
{
- int im;
- int index;
- int pbits;
- int q;
- index = 0;
- im = 0;
-
- pbits = (frame_size_real + Xp) - nbch; //number of parity bits
- q = q_val;
+ int im = 0;
+ int pbits = (frame_size_real + Xp) - nbch; //number of parity bits
+ int q = q_val;
+ int max_lut_arraysize = 0;
if (frame_size_type == FECFRAME_NORMAL) {
if (code_rate == C1_4) {
@@ -593,7 +614,6 @@ for (int row = 0; row < ROWS; row++) { \
LDPC_BF(ldpc_tab_1_3M, 30);
}
}
- ldpc_encode.table_length = index;
}
int
@@ -628,14 +648,20 @@ for (int row = 0; row < ROWS; row++) { \
}
// First zero all the parity bits
memset(p, 0, sizeof(unsigned char) * plen);
- for (int j = 0; j < (int)nbch; j++) {
- out[i + j] = in[consumed];
- consumed++;
- }
+
+ // copy the information bits
+ memcpy(&out[i], &in[consumed], sizeof(unsigned char)*nbch);
+ consumed += nbch;
+
// now do the parity checking
- for (int j = 0; j < ldpc_encode.table_length; j++) {
- p[ldpc_encode.p[j]] ^= d[ldpc_encode.d[j]];
+ for (int i_p = 0; i_p < plen; i_p++) {
+ unsigned char pbit = 0;
+ for (int i_d = 1; i_d < ldpc_lut[i_p][0]; i_d++) {
+ pbit ^= d[ldpc_lut[i_p][i_d]];
+ }
+ p[i_p] = pbit;
}
+
if (P != 0) {
puncture = 0;
for (int j = 0; j < plen; j += P) {
diff --git a/gr-dtv/lib/dvb/dvb_ldpc_bb_impl.h b/gr-dtv/lib/dvb/dvb_ldpc_bb_impl.h
index c8f0fab698..5506411956 100644
--- a/gr-dtv/lib/dvb/dvb_ldpc_bb_impl.h
+++ b/gr-dtv/lib/dvb/dvb_ldpc_bb_impl.h
@@ -23,12 +23,8 @@
#include <gnuradio/dtv/dvb_ldpc_bb.h>
#include "dvb_defines.h"
+#include <boost/smart_ptr.hpp>
-typedef struct{
- int table_length;
- int d[LDPC_ENCODE_TABLE_LENGTH];
- int p[LDPC_ENCODE_TABLE_LENGTH];
-}ldpc_encode_table;
namespace gr {
namespace dtv {
@@ -50,7 +46,8 @@ namespace gr {
unsigned char puncturing_buffer[FRAME_SIZE_NORMAL];
unsigned char shortening_buffer[FRAME_SIZE_NORMAL];
void ldpc_lookup_generate(void);
- ldpc_encode_table ldpc_encode;
+
+ int** ldpc_lut;
const static int ldpc_tab_1_4N[45][13];
const static int ldpc_tab_1_3N[60][13];
diff --git a/gr-dtv/lib/dvbt2/dvbt2_interleaver_bb_impl.cc b/gr-dtv/lib/dvbt2/dvbt2_interleaver_bb_impl.cc
index 3e3dc430b6..a0d5fc447b 100644
--- a/gr-dtv/lib/dvbt2/dvbt2_interleaver_bb_impl.cc
+++ b/gr-dtv/lib/dvbt2/dvbt2_interleaver_bb_impl.cc
@@ -1,6 +1,6 @@
/* -*- c++ -*- */
/*
- * Copyright 2015,2016 Free Software Foundation, Inc.
+ * Copyright 2015,2016,2018 Free Software Foundation, Inc.
*
* This is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -146,6 +146,210 @@ namespace gr {
packed_items = frame_size / mod;
break;
}
+ generate_lookup();
+ }
+
+ inline void
+ dvbt2_interleaver_bb_impl::interleave_parity_bits(int *tempu, const int *&in)
+ {
+ for (int k = 0; k < nbch; k++) {
+ tempu[k] = *in++;
+ }
+ for (int t = 0; t < q_val; t++) {
+ for (int s = 0; s < 360; s++) {
+ tempu[nbch + (360 * t) + s] = in[(q_val * s) + t];
+ }
+ }
+ in = in + (q_val * 360);
+ }
+
+ inline void
+ dvbt2_interleaver_bb_impl::twist_interleave_columns(int* tempv, int* tempu, int rows, const int *twist)
+ {
+ int index = 0, offset;
+ for (int col = 0; col < (mod * 2); col++) {
+ offset = twist[col];
+ for (int row = 0; row < rows; row++) {
+ tempv[offset + (rows * col)] = tempu[index++];
+ offset++;
+ if (offset == rows) {
+ offset = 0;
+ }
+ }
+ }
+ }
+
+ void
+ dvbt2_interleaver_bb_impl::generate_lookup()
+ {
+ int rows, index = 0;
+ int tempv[FRAME_SIZE_NORMAL];
+ int tempu[FRAME_SIZE_NORMAL];
+ const int *twist;
+ const int *c1, *c2, *c3, *c4, *c5, *c6, *c7, *c8;
+ const int *c9, *c10, *c11, *c12, *c13, *c14, *c15, *c16;
+
+ for(int i = 0; i < FRAME_SIZE_NORMAL; i++) {
+ lookup_table[i] = i;
+ }
+
+ const int *in = &lookup_table[0];
+
+ switch (signal_constellation) {
+ //ignore QPSK, not worth it, as there is no column interleaving
+ case MOD_16QAM:
+ rows = frame_size / (mod * 2);
+
+ if (frame_size == FRAME_SIZE_NORMAL) {
+ twist = &twist16n[0];
+ }
+ else {
+ twist = &twist16s[0];
+ }
+
+ interleave_parity_bits(tempu, in);
+
+ c1 = &tempv[0];
+ c2 = &tempv[rows];
+ c3 = &tempv[rows * 2];
+ c4 = &tempv[rows * 3];
+ c5 = &tempv[rows * 4];
+ c6 = &tempv[rows * 5];
+ c7 = &tempv[rows * 6];
+ c8 = &tempv[rows * 7];
+
+ twist_interleave_columns(tempv, tempu, rows, twist);
+
+ for (int j = 0; j < rows; j++) {
+ tempu[index++] = c1[j];
+ tempu[index++] = c2[j];
+ tempu[index++] = c3[j];
+ tempu[index++] = c4[j];
+ tempu[index++] = c5[j];
+ tempu[index++] = c6[j];
+ tempu[index++] = c7[j];
+ tempu[index++] = c8[j];
+ }
+ break;
+
+ case MOD_64QAM:
+ rows = frame_size / (mod * 2);
+
+ if (frame_size == FRAME_SIZE_NORMAL) {
+ twist = twist64n;
+ }
+ else {
+ twist = twist64s;
+ }
+
+ interleave_parity_bits(tempu, in);
+
+ c1 = &tempv[0];
+ c2 = &tempv[rows];
+ c3 = &tempv[rows * 2];
+ c4 = &tempv[rows * 3];
+ c5 = &tempv[rows * 4];
+ c6 = &tempv[rows * 5];
+ c7 = &tempv[rows * 6];
+ c8 = &tempv[rows * 7];
+ c9 = &tempv[rows * 8];
+ c10 = &tempv[rows * 9];
+ c11 = &tempv[rows * 10];
+ c12 = &tempv[rows * 11];
+
+ twist_interleave_columns(tempv, tempu, rows, twist);
+
+ for (int j = 0; j < rows; j++) {
+ tempu[index++] = c1[j];
+ tempu[index++] = c2[j];
+ tempu[index++] = c3[j];
+ tempu[index++] = c4[j];
+ tempu[index++] = c5[j];
+ tempu[index++] = c6[j];
+ tempu[index++] = c7[j];
+ tempu[index++] = c8[j];
+ tempu[index++] = c9[j];
+ tempu[index++] = c10[j];
+ tempu[index++] = c11[j];
+ tempu[index++] = c12[j];
+ }
+ break;
+
+ case MOD_256QAM:
+ if (frame_size == FRAME_SIZE_NORMAL) {
+ rows = frame_size / (mod * 2);
+
+ interleave_parity_bits(tempu, in);
+
+ c1 = &tempv[0];
+ c2 = &tempv[rows];
+ c3 = &tempv[rows * 2];
+ c4 = &tempv[rows * 3];
+ c5 = &tempv[rows * 4];
+ c6 = &tempv[rows * 5];
+ c7 = &tempv[rows * 6];
+ c8 = &tempv[rows * 7];
+ c9 = &tempv[rows * 8];
+ c10 = &tempv[rows * 9];
+ c11 = &tempv[rows * 10];
+ c12 = &tempv[rows * 11];
+ c13 = &tempv[rows * 12];
+ c14 = &tempv[rows * 13];
+ c15 = &tempv[rows * 14];
+ c16 = &tempv[rows * 15];
+
+ twist_interleave_columns(tempv, tempu, rows, twist256n);
+
+ for (int j = 0; j < rows; j++) {
+ tempu[index++] = c1[j];
+ tempu[index++] = c2[j];
+ tempu[index++] = c3[j];
+ tempu[index++] = c4[j];
+ tempu[index++] = c5[j];
+ tempu[index++] = c6[j];
+ tempu[index++] = c7[j];
+ tempu[index++] = c8[j];
+ tempu[index++] = c9[j];
+ tempu[index++] = c10[j];
+ tempu[index++] = c11[j];
+ tempu[index++] = c12[j];
+ tempu[index++] = c13[j];
+ tempu[index++] = c14[j];
+ tempu[index++] = c15[j];
+ tempu[index++] = c16[j];
+ }
+ }
+ else { //frame_size == FRAME_SIZE_SHORT
+ rows = frame_size / mod;
+
+ interleave_parity_bits(tempu, in);
+
+ c1 = &tempv[0];
+ c2 = &tempv[rows];
+ c3 = &tempv[rows * 2];
+ c4 = &tempv[rows * 3];
+ c5 = &tempv[rows * 4];
+ c6 = &tempv[rows * 5];
+ c7 = &tempv[rows * 6];
+ c8 = &tempv[rows * 7];
+
+ twist_interleave_columns(tempv, tempu, rows, twist256s);
+
+ for (int j = 0; j < rows; j++) {
+ tempu[index++] = c1[j];
+ tempu[index++] = c2[j];
+ tempu[index++] = c3[j];
+ tempu[index++] = c4[j];
+ tempu[index++] = c5[j];
+ tempu[index++] = c6[j];
+ tempu[index++] = c7[j];
+ tempu[index++] = c8[j];
+ }
+ }
+ }
+
+ //tempu now has the input indices interleaved correctly, so save it
+ memcpy(lookup_table, tempu, frame_size * sizeof(int));
}
/*
@@ -173,7 +377,6 @@ namespace gr {
int produced = 0;
int rows, offset, index;
unsigned int pack;
- const int *twist;
const int *mux;
switch (signal_constellation) {
@@ -205,13 +408,8 @@ namespace gr {
}
}
break;
+
case MOD_16QAM:
- if (frame_size == FRAME_SIZE_NORMAL) {
- twist = &twist16n[0];
- }
- else {
- twist = &twist16s[0];
- }
if (code_rate == C3_5 && frame_size == FRAME_SIZE_NORMAL) {
mux = &mux16_35[0];
}
@@ -225,67 +423,22 @@ namespace gr {
mux = &mux16[0];
}
for (int i = 0; i < noutput_items; i += packed_items) {
- rows = frame_size / (mod * 2);
- const unsigned char *c1, *c2, *c3, *c4, *c5, *c6, *c7, *c8;
- c1 = &tempv[0];
- c2 = &tempv[rows];
- c3 = &tempv[rows * 2];
- c4 = &tempv[rows * 3];
- c5 = &tempv[rows * 4];
- c6 = &tempv[rows * 5];
- c7 = &tempv[rows * 6];
- c8 = &tempv[rows * 7];
- for (int k = 0; k < nbch; k++) {
- tempu[k] = *in++;
- }
- for (int t = 0; t < q_val; t++) {
- for (int s = 0; s < 360; s++) {
- tempu[nbch + (360 * t) + s] = in[(q_val * s) + t];
- }
- }
- in = in + (q_val * 360);
- index = 0;
- for (int col = 0; col < (mod * 2); col++) {
- offset = twist[col];
- for (int row = 0; row < rows; row++) {
- tempv[offset + (rows * col)] = tempu[index++];
- offset++;
- if (offset == rows) {
- offset = 0;
- }
- }
- }
- index = 0;
- for (int j = 0; j < rows; j++) {
- tempu[index++] = c1[j];
- tempu[index++] = c2[j];
- tempu[index++] = c3[j];
- tempu[index++] = c4[j];
- tempu[index++] = c5[j];
- tempu[index++] = c6[j];
- tempu[index++] = c7[j];
- tempu[index++] = c8[j];
- }
index = 0;
for (int d = 0; d < frame_size / (mod * 2); d++) {
pack = 0;
for (int e = 0; e < (mod * 2); e++) {
offset = mux[e];
- pack |= tempu[index++] << (((mod * 2) - 1) - offset);
+ pack |= in[lookup_table[index++]] << (((mod * 2) - 1) - offset);
}
out[produced++] = pack >> 4;
out[produced++] = pack & 0xf;
- consumed += (mod * 2);
}
+ consumed += frame_size;
+ in += frame_size;
}
break;
+
case MOD_64QAM:
- if (frame_size == FRAME_SIZE_NORMAL) {
- twist = &twist64n[0];
- }
- else {
- twist = &twist64s[0];
- }
if (code_rate == C3_5 && frame_size == FRAME_SIZE_NORMAL) {
mux = &mux64_35[0];
}
@@ -299,68 +452,21 @@ namespace gr {
mux = &mux64[0];
}
for (int i = 0; i < noutput_items; i += packed_items) {
- rows = frame_size / (mod * 2);
- const unsigned char *c1, *c2, *c3, *c4, *c5, *c6, *c7, *c8, *c9, *c10, *c11, *c12;
- c1 = &tempv[0];
- c2 = &tempv[rows];
- c3 = &tempv[rows * 2];
- c4 = &tempv[rows * 3];
- c5 = &tempv[rows * 4];
- c6 = &tempv[rows * 5];
- c7 = &tempv[rows * 6];
- c8 = &tempv[rows * 7];
- c9 = &tempv[rows * 8];
- c10 = &tempv[rows * 9];
- c11 = &tempv[rows * 10];
- c12 = &tempv[rows * 11];
- for (int k = 0; k < nbch; k++) {
- tempu[k] = *in++;
- }
- for (int t = 0; t < q_val; t++) {
- for (int s = 0; s < 360; s++) {
- tempu[nbch + (360 * t) + s] = in[(q_val * s) + t];
- }
- }
- in = in + (q_val * 360);
- index = 0;
- for (int col = 0; col < (mod * 2); col++) {
- offset = twist[col];
- for (int row = 0; row < rows; row++) {
- tempv[offset + (rows * col)] = tempu[index++];
- offset++;
- if (offset == rows) {
- offset = 0;
- }
- }
- }
- index = 0;
- for (int j = 0; j < rows; j++) {
- tempu[index++] = c1[j];
- tempu[index++] = c2[j];
- tempu[index++] = c3[j];
- tempu[index++] = c4[j];
- tempu[index++] = c5[j];
- tempu[index++] = c6[j];
- tempu[index++] = c7[j];
- tempu[index++] = c8[j];
- tempu[index++] = c9[j];
- tempu[index++] = c10[j];
- tempu[index++] = c11[j];
- tempu[index++] = c12[j];
- }
index = 0;
for (int d = 0; d < frame_size / (mod * 2); d++) {
pack = 0;
for (int e = 0; e < (mod * 2); e++) {
offset = mux[e];
- pack |= tempu[index++] << (((mod * 2) - 1) - offset);
+ pack |= in[lookup_table[index++]] << (((mod * 2) - 1) - offset);
}
out[produced++] = pack >> 6;
out[produced++] = pack & 0x3f;
- consumed += (mod * 2);
}
+ consumed += frame_size;
+ in += frame_size;
}
break;
+
case MOD_256QAM:
if (frame_size == FRAME_SIZE_NORMAL) {
if (code_rate == C3_5) {
@@ -373,78 +479,22 @@ namespace gr {
mux = &mux256[0];
}
for (int i = 0; i < noutput_items; i += packed_items) {
- rows = frame_size / (mod * 2);
- const unsigned char *c1, *c2, *c3, *c4, *c5, *c6, *c7, *c8;
- const unsigned char *c9, *c10, *c11, *c12, *c13, *c14, *c15, *c16;
- c1 = &tempv[0];
- c2 = &tempv[rows];
- c3 = &tempv[rows * 2];
- c4 = &tempv[rows * 3];
- c5 = &tempv[rows * 4];
- c6 = &tempv[rows * 5];
- c7 = &tempv[rows * 6];
- c8 = &tempv[rows * 7];
- c9 = &tempv[rows * 8];
- c10 = &tempv[rows * 9];
- c11 = &tempv[rows * 10];
- c12 = &tempv[rows * 11];
- c13 = &tempv[rows * 12];
- c14 = &tempv[rows * 13];
- c15 = &tempv[rows * 14];
- c16 = &tempv[rows * 15];
- for (int k = 0; k < nbch; k++) {
- tempu[k] = *in++;
- }
- for (int t = 0; t < q_val; t++) {
- for (int s = 0; s < 360; s++) {
- tempu[nbch + (360 * t) + s] = in[(q_val * s) + t];
- }
- }
- in = in + (q_val * 360);
- index = 0;
- for (int col = 0; col < (mod * 2); col++) {
- offset = twist256n[col];
- for (int row = 0; row < rows; row++) {
- tempv[offset + (rows * col)] = tempu[index++];
- offset++;
- if (offset == rows) {
- offset = 0;
- }
- }
- }
- index = 0;
- for (int j = 0; j < rows; j++) {
- tempu[index++] = c1[j];
- tempu[index++] = c2[j];
- tempu[index++] = c3[j];
- tempu[index++] = c4[j];
- tempu[index++] = c5[j];
- tempu[index++] = c6[j];
- tempu[index++] = c7[j];
- tempu[index++] = c8[j];
- tempu[index++] = c9[j];
- tempu[index++] = c10[j];
- tempu[index++] = c11[j];
- tempu[index++] = c12[j];
- tempu[index++] = c13[j];
- tempu[index++] = c14[j];
- tempu[index++] = c15[j];
- tempu[index++] = c16[j];
- }
index = 0;
for (int d = 0; d < frame_size / (mod * 2); d++) {
pack = 0;
for (int e = 0; e < (mod * 2); e++) {
offset = mux[e];
- pack |= tempu[index++] << (((mod * 2) - 1) - offset);
+ pack |= in[lookup_table[index++]] << (((mod * 2) - 1) - offset);
}
out[produced++] = pack >> 8;
out[produced++] = pack & 0xff;
- consumed += (mod * 2);
}
+ consumed += frame_size;
+ in += frame_size;
}
}
- else {
+
+ else { //frame_size = FRAME_SIZE_SHORT
if (code_rate == C1_3) {
mux = &mux256s_13[0];
}
@@ -455,57 +505,17 @@ namespace gr {
mux = &mux256s[0];
}
for (int i = 0; i < noutput_items; i += packed_items) {
- rows = frame_size / mod;
- const unsigned char *c1, *c2, *c3, *c4, *c5, *c6, *c7, *c8;
- c1 = &tempv[0];
- c2 = &tempv[rows];
- c3 = &tempv[rows * 2];
- c4 = &tempv[rows * 3];
- c5 = &tempv[rows * 4];
- c6 = &tempv[rows * 5];
- c7 = &tempv[rows * 6];
- c8 = &tempv[rows * 7];
- for (int k = 0; k < nbch; k++) {
- tempu[k] = *in++;
- }
- for (int t = 0; t < q_val; t++) {
- for (int s = 0; s < 360; s++) {
- tempu[nbch + (360 * t) + s] = in[(q_val * s) + t];
- }
- }
- in = in + (q_val * 360);
- index = 0;
- for (int col = 0; col < mod; col++) {
- offset = twist256s[col];
- for (int row = 0; row < rows; row++) {
- tempv[offset + (rows * col)] = tempu[index++];
- offset++;
- if (offset == rows) {
- offset = 0;
- }
- }
- }
- index = 0;
- for (int j = 0; j < rows; j++) {
- tempu[index++] = c1[j];
- tempu[index++] = c2[j];
- tempu[index++] = c3[j];
- tempu[index++] = c4[j];
- tempu[index++] = c5[j];
- tempu[index++] = c6[j];
- tempu[index++] = c7[j];
- tempu[index++] = c8[j];
- }
index = 0;
for (int d = 0; d < frame_size / mod; d++) {
pack = 0;
for (int e = 0; e < mod; e++) {
offset = mux[e];
- pack |= tempu[index++] << ((mod - 1) - offset);
+ pack |= in[lookup_table[index++]] << ((mod - 1) - offset);
}
out[produced++] = pack & 0xff;
- consumed += mod;
}
+ consumed += frame_size;
+ in += frame_size;
}
}
break;
diff --git a/gr-dtv/lib/dvbt2/dvbt2_interleaver_bb_impl.h b/gr-dtv/lib/dvbt2/dvbt2_interleaver_bb_impl.h
index c737af0716..ef6098d4a3 100644
--- a/gr-dtv/lib/dvbt2/dvbt2_interleaver_bb_impl.h
+++ b/gr-dtv/lib/dvbt2/dvbt2_interleaver_bb_impl.h
@@ -38,7 +38,11 @@ namespace gr {
int mod;
int packed_items;
unsigned char tempu[FRAME_SIZE_NORMAL];
- unsigned char tempv[FRAME_SIZE_NORMAL];
+ int lookup_table[FRAME_SIZE_NORMAL];
+
+ void generate_lookup();
+ inline void interleave_parity_bits(int *tempu, const int *&in);
+ inline void twist_interleave_columns(int* tempv, int* tempu, int rows, const int *twist);
const static int twist16n[8];
const static int twist64n[12];
diff --git a/gr-dtv/lib/dvbt2/dvbt2_pilotgenerator_cc_impl.cc b/gr-dtv/lib/dvbt2/dvbt2_pilotgenerator_cc_impl.cc
index f4d6233b53..d653eae1dc 100644
--- a/gr-dtv/lib/dvbt2/dvbt2_pilotgenerator_cc_impl.cc
+++ b/gr-dtv/lib/dvbt2/dvbt2_pilotgenerator_cc_impl.cc
@@ -1113,7 +1113,7 @@ namespace gr {
break;
}
fstep = fs / vlength;
- for (int i = 0; i < vlength / 2; i++) {
+ for (unsigned int i = 0; i < vlength / 2; i++) {
x = GR_M_PI * f / fs;
if (i == 0) {
sinc = 1.0;
@@ -1127,7 +1127,7 @@ namespace gr {
f = f + fstep;
}
sincrms = std::sqrt(sincrms / (vlength / 2));
- for (int i = 0; i < vlength; i++) {
+ for (unsigned int i = 0; i < vlength; i++) {
inverse_sinc[i] *= sincrms;
}
equalization_enable = equalization;
@@ -1137,7 +1137,14 @@ namespace gr {
GR_LOG_FATAL(d_logger, "Pilot Generator and IFFT, cannot allocate memory for ofdm_fft.");
throw std::bad_alloc();
}
+
num_symbols = numdatasyms + N_P2;
+ data_carrier_map.resize(num_symbols);
+ for (std::vector< std::vector<int> >::size_type i = 0; i != data_carrier_map.size(); i++){
+ data_carrier_map[i].resize(MAX_CARRIERS);
+ }
+ init_pilots();
+
set_output_multiple(num_symbols);
}
@@ -1179,9 +1186,11 @@ namespace gr {
}
void
- dvbt2_pilotgenerator_cc_impl::init_pilots(int symbol)
+ dvbt2_pilotgenerator_cc_impl::init_pilots()
{
+ for (int symbol = 0; symbol < num_symbols; ++symbol){
int remainder, shift;
+ std::vector<int> &data_carrier_map = this->data_carrier_map[symbol];
for (int i = 0; i < C_PS; i++) {
data_carrier_map[i] = DATA_CARRIER;
}
@@ -2675,8 +2684,11 @@ namespace gr {
break;
}
}
+ }
}
+ const gr_complex zero = gr_complex(0.0, 0.0);
+
int
dvbt2_pilotgenerator_cc_impl::general_work (int noutput_items,
gr_vector_int &ninput_items,
@@ -2685,17 +2697,14 @@ namespace gr {
{
const gr_complex *in = (const gr_complex *) input_items[0];
gr_complex *out = (gr_complex *) output_items[0];
- gr_complex zero;
gr_complex *dst;
int L_FC = 0;
- zero = gr_complex(0.0, 0.0);
if (N_FC != 0) {
L_FC = 1;
}
for (int i = 0; i < noutput_items; i += num_symbols) {
for (int j = 0; j < num_symbols; j++) {
- init_pilots(j);
if (j < N_P2) {
for (int n = 0; n < left_nulls; n++) {
*out++ = zero;
@@ -2745,19 +2754,19 @@ namespace gr {
*out++ = zero;
}
for (int n = 0; n < C_PS; n++) {
- if (data_carrier_map[n] == SCATTERED_CARRIER) {
+ if (data_carrier_map[j][n] == SCATTERED_CARRIER) {
*out++ = sp_bpsk[prbs[n + K_OFFSET] ^ pn_sequence[j]];
}
- else if (data_carrier_map[n] == SCATTERED_CARRIER_INVERTED) {
+ else if (data_carrier_map[j][n] == SCATTERED_CARRIER_INVERTED) {
*out++ = sp_bpsk_inverted[prbs[n + K_OFFSET] ^ pn_sequence[j]];
}
- else if (data_carrier_map[n] == CONTINUAL_CARRIER) {
+ else if (data_carrier_map[j][n] == CONTINUAL_CARRIER) {
*out++ = cp_bpsk[prbs[n + K_OFFSET] ^ pn_sequence[j]];
}
- else if (data_carrier_map[n] == CONTINUAL_CARRIER_INVERTED) {
+ else if (data_carrier_map[j][n] == CONTINUAL_CARRIER_INVERTED) {
*out++ = cp_bpsk_inverted[prbs[n + K_OFFSET] ^ pn_sequence[j]];
}
- else if (data_carrier_map[n] == TRPAPR_CARRIER) {
+ else if (data_carrier_map[j][n] == TRPAPR_CARRIER) {
*out++ = zero;
}
else {
diff --git a/gr-dtv/lib/dvbt2/dvbt2_pilotgenerator_cc_impl.h b/gr-dtv/lib/dvbt2/dvbt2_pilotgenerator_cc_impl.h
index 6543e26512..9f06721d04 100644
--- a/gr-dtv/lib/dvbt2/dvbt2_pilotgenerator_cc_impl.h
+++ b/gr-dtv/lib/dvbt2/dvbt2_pilotgenerator_cc_impl.h
@@ -22,8 +22,9 @@
#define INCLUDED_DTV_DVBT2_PILOTGENERATOR_CC_IMPL_H
#include <gnuradio/dtv/dvbt2_pilotgenerator_cc.h>
-#include <gnuradio/fft/fft.h>
#include "dvb/dvb_defines.h"
+#include <gnuradio/fft/fft.h>
+#include <vector>
#define CHIPS 2624
#define MAX_CARRIERS 27841
@@ -66,7 +67,7 @@ namespace gr {
int prbs[MAX_CARRIERS];
int pn_sequence[CHIPS];
int p2_carrier_map[MAX_CARRIERS];
- int data_carrier_map[MAX_CARRIERS];
+ std::vector< std::vector<int> > data_carrier_map;
int fc_carrier_map[MAX_CARRIERS];
int N_P2;
int C_P2;
@@ -81,7 +82,7 @@ namespace gr {
int miso;
int miso_group;
void init_prbs(void);
- void init_pilots(int);
+ void init_pilots(void);
fft::fft_complex *ofdm_fft;
int ofdm_fft_size;
diff --git a/gr-fec/CMakeLists.txt b/gr-fec/CMakeLists.txt
index adb2a941fd..be554db7ef 100644
--- a/gr-fec/CMakeLists.txt
+++ b/gr-fec/CMakeLists.txt
@@ -59,8 +59,10 @@ if(ENABLE_PYTHON)
add_subdirectory(swig)
add_subdirectory(python/fec)
add_subdirectory(python/fec/LDPC)
- add_subdirectory(grc)
endif(ENABLE_PYTHON)
+if(ENABLE_GRC)
+ add_subdirectory(grc)
+endif(ENABLE_GRC)
add_subdirectory(examples)
add_subdirectory(docs)
add_subdirectory(ldpc_alist)
diff --git a/gr-fec/grc/variable_polar_encoder.block.yml b/gr-fec/grc/variable_polar_encoder.block.yml
index dbaa619f5f..10e07cdcb0 100644
--- a/gr-fec/grc/variable_polar_encoder.block.yml
+++ b/gr-fec/grc/variable_polar_encoder.block.yml
@@ -4,10 +4,8 @@ label: POLAR Encoder Definition
parameters:
- id: is_packed
label: Packed Bits
- dtype: enum
+ dtype: bool
default: 'False'
- options: ['False', 'True']
- option_labels: ['No', 'Yes']
- id: ndim
label: Parallelism
dtype: enum
diff --git a/gr-fec/lib/polar_common.cc b/gr-fec/lib/polar_common.cc
index fcb34c2d35..68d1b97f40 100644
--- a/gr-fec/lib/polar_common.cc
+++ b/gr-fec/lib/polar_common.cc
@@ -111,7 +111,7 @@ namespace gr {
std::copy(d_frozen_bit_values.begin(), d_frozen_bit_values.end(), d_volk_frozen_bits);
std::fill(d_volk_frozen_bits + d_frozen_bit_values.size(), d_volk_frozen_bits + nfrozen, 0);
- int nfbit = 0;
+ unsigned int nfbit = 0;
for(int i = 0; i < block_size(); i++){
unsigned char m = 0x00;
if(nfbit < d_frozen_bit_positions.size() && d_frozen_bit_positions[nfbit] == i){
diff --git a/gr-fft/CMakeLists.txt b/gr-fft/CMakeLists.txt
index 992ca5ca86..4bf8263965 100644
--- a/gr-fft/CMakeLists.txt
+++ b/gr-fft/CMakeLists.txt
@@ -55,8 +55,10 @@ add_subdirectory(lib)
if(ENABLE_PYTHON)
add_subdirectory(swig)
add_subdirectory(python/fft)
- add_subdirectory(grc)
endif(ENABLE_PYTHON)
+if(ENABLE_GRC)
+ add_subdirectory(grc)
+endif(ENABLE_GRC)
add_subdirectory(docs)
########################################################################
diff --git a/gr-fft/grc/fft_fft_vxx.block.yml b/gr-fft/grc/fft_fft_vxx.block.yml
index 33143f688a..d28bf5ccbe 100644
--- a/gr-fft/grc/fft_fft_vxx.block.yml
+++ b/gr-fft/grc/fft_fft_vxx.block.yml
@@ -6,14 +6,11 @@ parameters:
label: Input Type
dtype: enum
options: [complex, float]
- option_attributes:
- hide_shift: ['', all]
hide: part
- id: fft_size
label: FFT Size
dtype: int
default: '1024'
- hide: ${ 'part' if vlen == 1 else 'none' }
- id: forward
label: Forward/Reverse
dtype: enum
@@ -28,7 +25,7 @@ parameters:
dtype: enum
options: ['True', 'False']
option_labels: ['Yes', 'No']
- hide: ${ type.hide_shift }
+ hide: ${ 'all' if type == 'float' else 'none' }
- id: nthreads
label: Num. Threads
dtype: int
diff --git a/gr-fft/include/gnuradio/fft/fft_vcc.h b/gr-fft/include/gnuradio/fft/fft_vcc.h
index 28f6d1d0d4..03e82a9989 100644
--- a/gr-fft/include/gnuradio/fft/fft_vcc.h
+++ b/gr-fft/include/gnuradio/fft/fft_vcc.h
@@ -66,7 +66,7 @@ namespace gr {
* \param[in] fft_size N.
* \param[in] forward True performs FFT, False performs IFFT.
* \param[in] window Window function to be used.
- * \param[in] shifted True moves DC carrier to the middle.
+ * \param[in] shift True moves DC carrier to the middle.
* \param[in] nthreads Number of underlying threads.
*/
static sptr make(int fft_size, bool forward,
diff --git a/gr-fft/include/gnuradio/fft/fft_vfc.h b/gr-fft/include/gnuradio/fft/fft_vfc.h
index 5639465ab5..e5ec9bf3ee 100644
--- a/gr-fft/include/gnuradio/fft/fft_vfc.h
+++ b/gr-fft/include/gnuradio/fft/fft_vfc.h
@@ -67,7 +67,6 @@ namespace gr {
* \param[in] fft_size N.
* \param[in] forward True performs FFT, False performs IFFT.
* \param[in] window Window function to be used.
- * \param[in] shifted True moves DC carrier to the middle.
* \param[in] nthreads Number of underlying threads.
*/
static sptr make(int fft_size, bool forward,
diff --git a/gr-filter/CMakeLists.txt b/gr-filter/CMakeLists.txt
index fd5f3cc25c..ed1e52ab91 100644
--- a/gr-filter/CMakeLists.txt
+++ b/gr-filter/CMakeLists.txt
@@ -60,9 +60,11 @@ if(ENABLE_PYTHON)
add_subdirectory(python/filter)
add_subdirectory(python/filter/design)
add_subdirectory(python/filter/gui)
- add_subdirectory(grc)
add_subdirectory(apps)
endif(ENABLE_PYTHON)
+if(ENABLE_GRC)
+ add_subdirectory(grc)
+endif(ENABLE_GRC)
add_subdirectory(examples)
add_subdirectory(docs)
diff --git a/gr-filter/lib/pfb_decimator_ccf_impl.cc b/gr-filter/lib/pfb_decimator_ccf_impl.cc
index 75ca47d85b..ff6264ba90 100644
--- a/gr-filter/lib/pfb_decimator_ccf_impl.cc
+++ b/gr-filter/lib/pfb_decimator_ccf_impl.cc
@@ -98,7 +98,7 @@ namespace gr {
pfb_decimator_ccf_impl::~pfb_decimator_ccf_impl()
{
- delete d_rotator;
+ delete[] d_rotator;
}
void
diff --git a/gr-filter/python/filter/qa_fft_filter.py b/gr-filter/python/filter/qa_fft_filter.py
index 01b225d901..2ab49e7cec 100644
--- a/gr-filter/python/filter/qa_fft_filter.py
+++ b/gr-filter/python/filter/qa_fft_filter.py
@@ -89,7 +89,7 @@ def print_complex(x):
class test_fft_filter(gr_unittest.TestCase):
def setUp(self):
- pass
+ random.seed(0)
def tearDown(self):
pass
diff --git a/gr-filter/python/filter/qa_filterbank.py b/gr-filter/python/filter/qa_filterbank.py
index 9a99c6832f..036f34498b 100644
--- a/gr-filter/python/filter/qa_filterbank.py
+++ b/gr-filter/python/filter/qa_filterbank.py
@@ -43,6 +43,7 @@ def convolution(A, B):
class test_filterbank_vcvcf(gr_unittest.TestCase):
def setUp(self):
+ random.seed(0)
self.tb = gr.top_block()
def tearDown(self):
diff --git a/gr-qtgui/CMakeLists.txt b/gr-qtgui/CMakeLists.txt
index a418f457f3..b0b109f55c 100644
--- a/gr-qtgui/CMakeLists.txt
+++ b/gr-qtgui/CMakeLists.txt
@@ -80,12 +80,14 @@ add_subdirectory(lib)
add_subdirectory(docs)
add_subdirectory(examples/c++)
if(ENABLE_PYTHON)
- add_subdirectory(grc)
add_subdirectory(swig)
add_subdirectory(python/qtgui)
add_subdirectory(examples)
add_subdirectory(apps)
endif(ENABLE_PYTHON)
+if(ENABLE_GRC)
+ add_subdirectory(grc)
+endif(ENABLE_GRC)
########################################################################
# Create Pkg Config File
diff --git a/gr-qtgui/grc/qtgui_freq_sink_x.block.yml b/gr-qtgui/grc/qtgui_freq_sink_x.block.yml
index 9eb49b8605..d0b7f45eba 100644
--- a/gr-qtgui/grc/qtgui_freq_sink_x.block.yml
+++ b/gr-qtgui/grc/qtgui_freq_sink_x.block.yml
@@ -375,6 +375,10 @@ inputs:
id: freq
optional: true
hide: ${ showports }
+- domain: message
+ id: bw
+ optional: true
+ hide: ${ showports }
outputs:
- domain: message
diff --git a/gr-qtgui/grc/qtgui_time_sink_x.block.yml b/gr-qtgui/grc/qtgui_time_sink_x.block.yml
index f97b30e8db..b179020e49 100644
--- a/gr-qtgui/grc/qtgui_time_sink_x.block.yml
+++ b/gr-qtgui/grc/qtgui_time_sink_x.block.yml
@@ -155,330 +155,657 @@ parameters:
hide: part
- id: label1
label: Line 1 Label
- category: Config
dtype: string
- hide: ${ ('part' if int(nconnections) >= 1 else 'all') }
+ default: 'Signal 1'
+ hide: ${ ('part' if (
+ int(nconnections) >= 1
+ or (type == "complex" and int(nconnections) >= 1)
+ or (type == "msg_complex")) and (not type == "msg_float")
+ else 'all')
+ }
- id: width1
label: Line 1 Width
- category: Config
- dtype: int
- default: '1'
- hide: ${ ('part' if int(nconnections) >= 1 else 'all') }
+ default: 1
+ hide: ${ ('part' if (
+ int(nconnections) >= 1
+ or (type == "complex" and int(nconnections) >= 1)
+ or (type == "msg_complex")) and (not type == "msg_float")
+ else 'all')
+ }
- id: color1
label: Line 1 Color
- category: Config
- dtype: enum
- options: ['"blue"', '"red"', '"green"', '"black"', '"cyan"', '"magenta"', '"yellow"',
- '"dark red"', '"dark green"', '"Dark Blue"']
- option_labels: [Blue, Red, Green, Black, Cyan, Magenta, Yellow, Dark Red, Dark
- Green, Dark Blue]
- hide: ${ ('part' if int(nconnections) >= 1 else 'all') }
+ dtype: string
+ default: 'blue'
+ hide: ${ ('part' if (
+ int(nconnections) >= 1
+ or (type == "complex" and int(nconnections) >= 1)
+ or (type == "msg_complex")) and (not type == "msg_float")
+ else 'all')
+ }
- id: style1
label: Line 1 Style
- category: Config
- dtype: enum
- options: ['1', '2', '3', '4', '5', '0']
- option_labels: [Solid, Dash, Dots, Dash-Dot, Dash-Dot-Dot, None]
- hide: ${ ('part' if int(nconnections) >= 1 else 'all') }
+ dtype: int
+ default: 1
+ hide: ${ ('part' if (
+ int(nconnections) >= 1
+ or (type == "complex" and int(nconnections) >= 1)
+ or (type == "msg_complex")) and (not type == "msg_float")
+ else 'all')
+ }
- id: marker1
label: Line 1 Marker
- category: Config
- dtype: enum
- options: ['-1', '0', '1', '2', '3', '4', '6', '7', '8', '9']
- option_labels: [None, Circle, Rectangle, Diamond, Triangle, Down Triangle, Left
- Triangle, Right Triangle, Cross, X-Cross]
- hide: ${ ('part' if int(nconnections) >= 1 else 'all') }
+ dtype: int
+ default: 1
+ hide: ${ ('part' if (
+ int(nconnections) >= 1
+ or (type == "complex" and int(nconnections) >= 1)
+ or (type == "msg_complex")) and (not type == "msg_float")
+ else 'all')
+ }
- id: alpha1
label: Line 1 Alpha
- category: Config
- dtype: float
- default: '1.0'
- hide: ${ ('part' if int(nconnections) >= 1 else 'all') }
+ dtype: real
+ default: 1.0
+ hide: ${ ('part' if (
+ int(nconnections) >= 1
+ or (type == "complex" and int(nconnections) >= 1)
+ or (type == "msg_complex")) and (not type == "msg_float")
+ else 'all')
+ }
+
- id: label2
label: Line 2 Label
+ dtype: string
+ default: 'Signal 2'
base_key: label1
- hide: ${ ('part' if (int(nconnections) >= 2 or (type == "complex" and int(nconnections)
- >= 1) or (type == "msg_complex")) and (not type == "msg_float") else 'all')
+ hide: ${ ('part' if (
+ int(nconnections) >= 2
+ or (type == "complex" and int(nconnections) >= 1)
+ or (type == "msg_complex")) and (not type == "msg_float")
+ else 'all')
}
- id: width2
label: Line 2 Width
+ default: 1
base_key: width1
- hide: ${ ('part' if (int(nconnections) >= 2 or (type == "complex" and int(nconnections)
- >= 1) or (type == "msg_complex")) and (not type == "msg_float") else 'all')
+ hide: ${ ('part' if (
+ int(nconnections) >= 2
+ or (type == "complex" and int(nconnections) >= 1)
+ or (type == "msg_complex")) and (not type == "msg_float")
+ else 'all')
}
- id: color2
label: Line 2 Color
+ dtype: string
+ default: 'green'
base_key: color1
- default: '"red"'
- hide: ${ ('part' if (int(nconnections) >= 2 or (type == "complex" and int(nconnections)
- >= 1) or (type == "msg_complex")) and (not type == "msg_float") else 'all')
+ hide: ${ ('part' if (
+ int(nconnections) >= 2
+ or (type == "complex" and int(nconnections) >= 1)
+ or (type == "msg_complex")) and (not type == "msg_float")
+ else 'all')
}
- id: style2
label: Line 2 Style
+ dtype: int
+ default: 1
base_key: style1
- hide: ${ ('part' if (int(nconnections) >= 2 or (type == "complex" and int(nconnections)
- >= 1) or (type == "msg_complex")) and (not type == "msg_float") else 'all')
+ hide: ${ ('part' if (
+ int(nconnections) >= 2
+ or (type == "complex" and int(nconnections) >= 1)
+ or (type == "msg_complex")) and (not type == "msg_float")
+ else 'all')
}
- id: marker2
label: Line 2 Marker
+ dtype: int
+ default: 1
base_key: marker1
- hide: ${ ('part' if (int(nconnections) >= 2 or (type == "complex" and int(nconnections)
- >= 1) or (type == "msg_complex")) and (not type == "msg_float") else 'all')
+ hide: ${ ('part' if (
+ int(nconnections) >= 2
+ or (type == "complex" and int(nconnections) >= 1)
+ or (type == "msg_complex")) and (not type == "msg_float")
+ else 'all')
}
- id: alpha2
label: Line 2 Alpha
+ dtype: real
+ default: 1.0
base_key: alpha1
- hide: ${ ('part' if (int(nconnections) >= 2 or (type == "complex" and int(nconnections)
- >= 1) or (type == "msg_complex")) and (not type == "msg_float") else 'all')
+ hide: ${ ('part' if (
+ int(nconnections) >= 2
+ or (type == "complex" and int(nconnections) >= 1)
+ or (type == "msg_complex")) and (not type == "msg_float")
+ else 'all')
}
+
- id: label3
label: Line 3 Label
+ dtype: string
+ default: 'Signal 3'
base_key: label1
- hide: ${ ('part' if ((int(nconnections) >= 3 or (type == "complex" and int(nconnections)
- >= 2)) and not type.t == "message") else 'all') }
+ hide: ${ ('part' if (
+ int(nconnections) >= 3
+ or (type == "complex" and int(nconnections) >= 2)
+ or (type == "msg_complex")) and (not type == "msg_float")
+ else 'all')
+ }
- id: width3
label: Line 3 Width
+ default: 1
base_key: width1
- hide: ${ ('part' if ((int(nconnections) >= 3 or (type == "complex" and int(nconnections)
- >= 2)) and not type.t == "message") else 'all') }
+ hide: ${ ('part' if (
+ int(nconnections) >= 3
+ or (type == "complex" and int(nconnections) >= 2)
+ or (type == "msg_complex")) and (not type == "msg_float")
+ else 'all')
+ }
- id: color3
label: Line 3 Color
+ dtype: string
+ default: 'black'
base_key: color1
- default: '"green"'
- hide: ${ ('part' if ((int(nconnections) >= 3 or (type == "complex" and int(nconnections)
- >= 2)) and not type.t == "message") else 'all') }
+ hide: ${ ('part' if (
+ int(nconnections) >= 3
+ or (type == "complex" and int(nconnections) >= 2)
+ or (type == "msg_complex")) and (not type == "msg_float")
+ else 'all')
+ }
- id: style3
label: Line 3 Style
+ dtype: int
+ default: 1
base_key: style1
- hide: ${ ('part' if ((int(nconnections) >= 3 or (type == "complex" and int(nconnections)
- >= 2)) and not type.t == "message") else 'all') }
+ hide: ${ ('part' if (
+ int(nconnections) >= 3
+ or (type == "complex" and int(nconnections) >= 2)
+ or (type == "msg_complex")) and (not type == "msg_float")
+ else 'all')
+ }
- id: marker3
label: Line 3 Marker
+ dtype: int
+ default: 1
base_key: marker1
- hide: ${ ('part' if ((int(nconnections) >= 3 or (type == "complex" and int(nconnections)
- >= 2)) and not type.t == "message") else 'all') }
+ hide: ${ ('part' if (
+ int(nconnections) >= 3
+ or (type == "complex" and int(nconnections) >= 2)
+ or (type == "msg_complex")) and (not type == "msg_float")
+ else 'all')
+ }
- id: alpha3
label: Line 3 Alpha
+ dtype: real
+ default: 1.0
base_key: alpha1
- hide: ${ ('part' if ((int(nconnections) >= 3 or (type == "complex" and int(nconnections)
- >= 2)) and not type.t == "message") else 'all') }
+ hide: ${ ('part' if (
+ int(nconnections) >= 3
+ or (type == "complex" and int(nconnections) >= 2)
+ or (type == "msg_complex")) and (not type == "msg_float")
+ else 'all')
+ }
+
- id: label4
label: Line 4 Label
+ dtype: string
+ default: 'Signal 4'
base_key: label1
- hide: ${ ('part' if ((int(nconnections) >= 4 or (type == "complex" and int(nconnections)
- >= 2)) and not type.t == "message") else 'all') }
+ hide: ${ ('part' if (
+ int(nconnections) >= 4
+ or (type == "complex" and int(nconnections) >= 2)
+ or (type == "msg_complex")) and (not type == "msg_float")
+ else 'all')
+ }
- id: width4
label: Line 4 Width
+ default: 1
base_key: width1
- hide: ${ ('part' if ((int(nconnections) >= 4 or (type == "complex" and int(nconnections)
- >= 2)) and not type.t == "message") else 'all') }
+ hide: ${ ('part' if (
+ int(nconnections) >= 4
+ or (type == "complex" and int(nconnections) >= 2)
+ or (type == "msg_complex")) and (not type == "msg_float")
+ else 'all')
+ }
- id: color4
label: Line 4 Color
+ dtype: string
+ default: 'cyan'
base_key: color1
- default: '"black"'
- hide: ${ ('part' if ((int(nconnections) >= 4 or (type == "complex" and int(nconnections)
- >= 2)) and not type.t == "message") else 'all') }
+ hide: ${ ('part' if (
+ int(nconnections) >= 4
+ or (type == "complex" and int(nconnections) >= 2)
+ or (type == "msg_complex")) and (not type == "msg_float")
+ else 'all')
+ }
- id: style4
label: Line 4 Style
+ dtype: int
+ default: 1
base_key: style1
- hide: ${ ('part' if ((int(nconnections) >= 4 or (type == "complex" and int(nconnections)
- >= 2)) and not type.t == "message") else 'all') }
+ hide: ${ ('part' if (
+ int(nconnections) >= 4
+ or (type == "complex" and int(nconnections) >= 2)
+ or (type == "msg_complex")) and (not type == "msg_float")
+ else 'all')
+ }
- id: marker4
label: Line 4 Marker
+ dtype: int
+ default: 1
base_key: marker1
- hide: ${ ('part' if ((int(nconnections) >= 4 or (type == "complex" and int(nconnections)
- >= 2)) and not type.t == "message") else 'all') }
+ hide: ${ ('part' if (
+ int(nconnections) >= 4
+ or (type == "complex" and int(nconnections) >= 2)
+ or (type == "msg_complex")) and (not type == "msg_float")
+ else 'all')
+ }
- id: alpha4
label: Line 4 Alpha
+ dtype: real
+ default: 1.0
base_key: alpha1
- hide: ${ ('part' if ((int(nconnections) >= 4 or (type == "complex" and int(nconnections)
- >= 2)) and not type.t == "message") else 'all') }
+ hide: ${ ('part' if (
+ int(nconnections) >= 4
+ or (type == "complex" and int(nconnections) >= 2)
+ or (type == "msg_complex")) and (not type == "msg_float")
+ else 'all')
+ }
+
- id: label5
label: Line 5 Label
+ dtype: string
+ default: 'Signal 5'
base_key: label1
- hide: ${ ('part' if ((int(nconnections) >= 5 or (type == "complex" and int(nconnections)
- >= 3)) and not type.t == "message") else 'all') }
+ hide: ${ ('part' if (
+ int(nconnections) >= 5
+ or (type == "complex" and int(nconnections) >= 3)
+ or (type == "msg_complex")) and (not type == "msg_float")
+ else 'all')
+ }
- id: width5
label: Line 5 Width
+ default: 1
base_key: width1
- hide: ${ ('part' if ((int(nconnections) >= 5 or (type == "complex" and int(nconnections)
- >= 3)) and not type.t == "message") else 'all') }
+ hide: ${ ('part' if (
+ int(nconnections) >= 5
+ or (type == "complex" and int(nconnections) >= 3)
+ or (type == "msg_complex")) and (not type == "msg_float")
+ else 'all')
+ }
- id: color5
label: Line 5 Color
+ dtype: string
+ default: 'magenta'
base_key: color1
- default: '"cyan"'
- hide: ${ ('part' if ((int(nconnections) >= 5 or (type == "complex" and int(nconnections)
- >= 3)) and not type.t == "message") else 'all') }
+ hide: ${ ('part' if (
+ int(nconnections) >= 5
+ or (type == "complex" and int(nconnections) >= 3)
+ or (type == "msg_complex")) and (not type == "msg_float")
+ else 'all')
+ }
- id: style5
label: Line 5 Style
+ dtype: int
+ default: 1
base_key: style1
- hide: ${ ('part' if ((int(nconnections) >= 5 or (type == "complex" and int(nconnections)
- >= 3)) and not type.t == "message") else 'all') }
+ hide: ${ ('part' if (
+ int(nconnections) >= 5
+ or (type == "complex" and int(nconnections) >= 3)
+ or (type == "msg_complex")) and (not type == "msg_float")
+ else 'all')
+ }
- id: marker5
label: Line 5 Marker
+ dtype: int
+ default: 1
base_key: marker1
- hide: ${ ('part' if ((int(nconnections) >= 5 or (type == "complex" and int(nconnections)
- >= 3)) and not type.t == "message") else 'all') }
+ hide: ${ ('part' if (
+ int(nconnections) >= 5
+ or (type == "complex" and int(nconnections) >= 3)
+ or (type == "msg_complex")) and (not type == "msg_float")
+ else 'all')
+ }
- id: alpha5
label: Line 5 Alpha
+ dtype: real
+ default: 1.0
base_key: alpha1
- hide: ${ ('part' if ((int(nconnections) >= 5 or (type == "complex" and int(nconnections)
- >= 3)) and not type.t == "message") else 'all') }
+ hide: ${ ('part' if (
+ int(nconnections) >= 5
+ or (type == "complex" and int(nconnections) >= 3)
+ or (type == "msg_complex")) and (not type == "msg_float")
+ else 'all')
+ }
+
- id: label6
label: Line 6 Label
+ dtype: string
+ default: 'Signal 6'
base_key: label1
- hide: ${ ('part' if ((int(nconnections) >= 6 or (type == "complex" and int(nconnections)
- >= 3)) and not type.t == "message") else 'all') }
+ hide: ${ ('part' if (
+ int(nconnections) >= 6
+ or (type == "complex" and int(nconnections) >= 3)
+ or (type == "msg_complex")) and (not type == "msg_float")
+ else 'all')
+ }
- id: width6
label: Line 6 Width
+ default: 1
base_key: width1
- hide: ${ ('part' if ((int(nconnections) >= 6 or (type == "complex" and int(nconnections)
- >= 3)) and not type.t == "message") else 'all') }
+ hide: ${ ('part' if (
+ int(nconnections) >= 6
+ or (type == "complex" and int(nconnections) >= 3)
+ or (type == "msg_complex")) and (not type == "msg_float")
+ else 'all')
+ }
- id: color6
label: Line 6 Color
+ dtype: string
+ default: 'yellow'
base_key: color1
- default: '"magenta"'
- hide: ${ ('part' if ((int(nconnections) >= 6 or (type == "complex" and int(nconnections)
- >= 3)) and not type.t == "message") else 'all') }
+ hide: ${ ('part' if (
+ int(nconnections) >= 6
+ or (type == "complex" and int(nconnections) >= 3)
+ or (type == "msg_complex")) and (not type == "msg_float")
+ else 'all')
+ }
- id: style6
label: Line 6 Style
+ dtype: int
+ default: 1
base_key: style1
- hide: ${ ('part' if ((int(nconnections) >= 6 or (type == "complex" and int(nconnections)
- >= 3)) and not type.t == "message") else 'all') }
+ hide: ${ ('part' if (
+ int(nconnections) >= 6
+ or (type == "complex" and int(nconnections) >= 3)
+ or (type == "msg_complex")) and (not type == "msg_float")
+ else 'all')
+ }
- id: marker6
label: Line 6 Marker
+ dtype: int
+ default: 1
base_key: marker1
- hide: ${ ('part' if ((int(nconnections) >= 6 or (type == "complex" and int(nconnections)
- >= 3)) and not type.t == "message") else 'all') }
+ hide: ${ ('part' if (
+ int(nconnections) >= 6
+ or (type == "complex" and int(nconnections) >= 3)
+ or (type == "msg_complex")) and (not type == "msg_float")
+ else 'all')
+ }
- id: alpha6
label: Line 6 Alpha
+ dtype: real
+ default: 1.0
base_key: alpha1
- hide: ${ ('part' if ((int(nconnections) >= 6 or (type == "complex" and int(nconnections)
- >= 3)) and not type.t == "message") else 'all') }
+ hide: ${ ('part' if (
+ int(nconnections) >= 6
+ or (type == "complex" and int(nconnections) >= 3)
+ or (type == "msg_complex")) and (not type == "msg_float")
+ else 'all')
+ }
+
- id: label7
label: Line 7 Label
+ dtype: string
+ default: 'Signal 7'
base_key: label1
- hide: ${ ('part' if ((int(nconnections) >= 7 or (type == "complex" and int(nconnections)
- >= 4)) and not type.t == "message") else 'all') }
+ hide: ${ ('part' if (
+ int(nconnections) >= 7
+ or (type == "complex" and int(nconnections) >= 4)
+ or (type == "msg_complex")) and (not type == "msg_float")
+ else 'all')
+ }
- id: width7
label: Line 7 Width
+ default: 1
base_key: width1
- hide: ${ ('part' if ((int(nconnections) >= 7 or (type == "complex" and int(nconnections)
- >= 4)) and not type.t == "message") else 'all') }
+ hide: ${ ('part' if (
+ int(nconnections) >= 7
+ or (type == "complex" and int(nconnections) >= 4)
+ or (type == "msg_complex")) and (not type == "msg_float")
+ else 'all')
+ }
- id: color7
label: Line 7 Color
+ dtype: string
+ default: 'dark red'
base_key: color1
- default: '"yellow"'
- hide: ${ ('part' if ((int(nconnections) >= 7 or (type == "complex" and int(nconnections)
- >= 4)) and not type.t == "message") else 'all') }
+ hide: ${ ('part' if (
+ int(nconnections) >= 7
+ or (type == "complex" and int(nconnections) >= 4)
+ or (type == "msg_complex")) and (not type == "msg_float")
+ else 'all')
+ }
- id: style7
label: Line 7 Style
+ dtype: int
+ default: 1
base_key: style1
- hide: ${ ('part' if ((int(nconnections) >= 7 or (type == "complex" and int(nconnections)
- >= 4)) and not type.t == "message") else 'all') }
+ hide: ${ ('part' if (
+ int(nconnections) >= 7
+ or (type == "complex" and int(nconnections) >= 4)
+ or (type == "msg_complex")) and (not type == "msg_float")
+ else 'all')
+ }
- id: marker7
label: Line 7 Marker
+ dtype: int
+ default: 1
base_key: marker1
- hide: ${ ('part' if ((int(nconnections) >= 7 or (type == "complex" and int(nconnections)
- >= 4)) and not type.t == "message") else 'all') }
+ hide: ${ ('part' if (
+ int(nconnections) >= 7
+ or (type == "complex" and int(nconnections) >= 4)
+ or (type == "msg_complex")) and (not type == "msg_float")
+ else 'all')
+ }
- id: alpha7
label: Line 7 Alpha
+ dtype: real
+ default: 1.0
base_key: alpha1
- hide: ${ ('part' if ((int(nconnections) >= 7 or (type == "complex" and int(nconnections)
- >= 4)) and not type.t == "message") else 'all') }
+ hide: ${ ('part' if (
+ int(nconnections) >= 7
+ or (type == "complex" and int(nconnections) >= 4)
+ or (type == "msg_complex")) and (not type == "msg_float")
+ else 'all')
+ }
+
- id: label8
label: Line 8 Label
+ dtype: string
+ default: 'Signal 8'
base_key: label1
- hide: ${ ('part' if ((int(nconnections) >= 8 or (type == "complex" and int(nconnections)
- >= 4)) and not type.t == "message") else 'all') }
+ hide: ${ ('part' if (
+ int(nconnections) >= 8
+ or (type == "complex" and int(nconnections) >= 4)
+ or (type == "msg_complex")) and (not type == "msg_float")
+ else 'all')
+ }
- id: width8
label: Line 8 Width
+ default: 1
base_key: width1
- hide: ${ ('part' if ((int(nconnections) >= 8 or (type == "complex" and int(nconnections)
- >= 4)) and not type.t == "message") else 'all') }
+ hide: ${ ('part' if (
+ int(nconnections) >= 8
+ or (type == "complex" and int(nconnections) >= 4)
+ or (type == "msg_complex")) and (not type == "msg_float")
+ else 'all')
+ }
- id: color8
label: Line 8 Color
+ dtype: string
+ default: 'dark green'
base_key: color1
- default: '"dark red"'
- hide: ${ ('part' if ((int(nconnections) >= 8 or (type == "complex" and int(nconnections)
- >= 4)) and not type.t == "message") else 'all') }
+ hide: ${ ('part' if (
+ int(nconnections) >= 8
+ or (type == "complex" and int(nconnections) >= 4)
+ or (type == "msg_complex")) and (not type == "msg_float")
+ else 'all')
+ }
- id: style8
label: Line 8 Style
+ dtype: int
+ default: 1
base_key: style1
- hide: ${ ('part' if ((int(nconnections) >= 8 or (type == "complex" and int(nconnections)
- >= 4)) and not type.t == "message") else 'all') }
+ hide: ${ ('part' if (
+ int(nconnections) >= 8
+ or (type == "complex" and int(nconnections) >= 4)
+ or (type == "msg_complex")) and (not type == "msg_float")
+ else 'all')
+ }
- id: marker8
label: Line 8 Marker
+ dtype: int
+ default: 1
base_key: marker1
- hide: ${ ('part' if ((int(nconnections) >= 8 or (type == "complex" and int(nconnections)
- >= 4)) and not type.t == "message") else 'all') }
+ hide: ${ ('part' if (
+ int(nconnections) >= 8
+ or (type == "complex" and int(nconnections) >= 4)
+ or (type == "msg_complex")) and (not type == "msg_float")
+ else 'all')
+ }
- id: alpha8
label: Line 8 Alpha
+ dtype: real
+ default: 1.0
base_key: alpha1
- hide: ${ ('part' if ((int(nconnections) >= 8 or (type == "complex" and int(nconnections)
- >= 4)) and not type.t == "message") else 'all') }
+ hide: ${ ('part' if (
+ int(nconnections) >= 8
+ or (type == "complex" and int(nconnections) >= 4)
+ or (type == "msg_complex")) and (not type == "msg_float")
+ else 'all')
+ }
+
- id: label9
label: Line 9 Label
+ dtype: string
+ default: 'Signal 9'
base_key: label1
- hide: ${ ('part' if ((int(nconnections) >= 9 or (type == "complex" and int(nconnections)
- >= 5)) and not type.t == "message") else 'all') }
+ hide: ${ ('part' if (
+ int(nconnections) >= 9
+ or (type == "complex" and int(nconnections) >= 5)
+ or (type == "msg_complex")) and (not type == "msg_float")
+ else 'all')
+ }
- id: width9
label: Line 9 Width
+ default: 1
base_key: width1
- hide: ${ ('part' if ((int(nconnections) >= 9 or (type == "complex" and int(nconnections)
- >= 5)) and not type.t == "message") else 'all') }
+ hide: ${ ('part' if (
+ int(nconnections) >= 9
+ or (type == "complex" and int(nconnections) >= 5)
+ or (type == "msg_complex")) and (not type == "msg_float")
+ else 'all')
+ }
- id: color9
label: Line 9 Color
+ dtype: string
+ default: 'Dark Blue'
base_key: color1
- default: '"dark green"'
- hide: ${ ('part' if ((int(nconnections) >= 9 or (type == "complex" and int(nconnections)
- >= 5)) and not type.t == "message") else 'all') }
+ hide: ${ ('part' if (
+ int(nconnections) >= 9
+ or (type == "complex" and int(nconnections) >= 5)
+ or (type == "msg_complex")) and (not type == "msg_float")
+ else 'all')
+ }
- id: style9
label: Line 9 Style
+ dtype: int
+ default: 1
base_key: style1
- hide: ${ ('part' if ((int(nconnections) >= 9 or (type == "complex" and int(nconnections)
- >= 5)) and not type.t == "message") else 'all') }
+ hide: ${ ('part' if (
+ int(nconnections) >= 9
+ or (type == "complex" and int(nconnections) >= 5)
+ or (type == "msg_complex")) and (not type == "msg_float")
+ else 'all')
+ }
- id: marker9
label: Line 9 Marker
+ dtype: int
+ default: 1
base_key: marker1
- hide: ${ ('part' if ((int(nconnections) >= 9 or (type == "complex" and int(nconnections)
- >= 5)) and not type.t == "message") else 'all') }
+ hide: ${ ('part' if (
+ int(nconnections) >= 9
+ or (type == "complex" and int(nconnections) >= 5)
+ or (type == "msg_complex")) and (not type == "msg_float")
+ else 'all')
+ }
- id: alpha9
label: Line 9 Alpha
+ dtype: real
+ default: 1.0
base_key: alpha1
- hide: ${ ('part' if ((int(nconnections) >= 9 or (type == "complex" and int(nconnections)
- >= 5)) and not type.t == "message") else 'all') }
+ hide: ${ ('part' if (
+ int(nconnections) >= 9
+ or (type == "complex" and int(nconnections) >= 5)
+ or (type == "msg_complex")) and (not type == "msg_float")
+ else 'all')
+ }
+
- id: label10
label: Line 10 Label
+ dtype: string
+ default: 'Signal 10'
base_key: label1
- hide: ${ ('part' if ((int(nconnections) >= 10 or (type == "complex" and int(nconnections)
- >= 5)) and not type.t == "message") else 'all') }
+ hide: ${ ('part' if (
+ int(nconnections) >= 10
+ or (type == "complex" and int(nconnections) >= 5)
+ or (type == "msg_complex")) and (not type == "msg_float")
+ else 'all')
+ }
- id: width10
label: Line 10 Width
+ default: 1
base_key: width1
- hide: ${ ('part' if ((int(nconnections) >= 10 or (type == "complex" and int(nconnections)
- >= 5)) and not type.t == "message") else 'all') }
+ hide: ${ ('part' if (
+ int(nconnections) >= 10
+ or (type == "complex" and int(nconnections) >= 5)
+ or (type == "msg_complex")) and (not type == "msg_float")
+ else 'all')
+ }
- id: color10
label: Line 10 Color
+ dtype: string
+ default: 'blue'
base_key: color1
- default: '"dark blue"'
- hide: ${ ('part' if ((int(nconnections) >= 10 or (type == "complex" and int(nconnections)
- >= 5)) and not type.t == "message") else 'all') }
+ hide: ${ ('part' if (
+ int(nconnections) >= 10
+ or (type == "complex" and int(nconnections) >= 5)
+ or (type == "msg_complex")) and (not type == "msg_float")
+ else 'all')
+ }
- id: style10
label: Line 10 Style
+ dtype: int
+ default: 1
base_key: style1
- hide: ${ ('part' if ((int(nconnections) >= 10 or (type == "complex" and int(nconnections)
- >= 5)) and not type.t == "message") else 'all') }
+ hide: ${ ('part' if (
+ int(nconnections) >= 10
+ or (type == "complex" and int(nconnections) >= 5)
+ or (type == "msg_complex")) and (not type == "msg_float")
+ else 'all')
+ }
- id: marker10
label: Line 10 Marker
+ dtype: int
+ default: 1
base_key: marker1
- hide: ${ ('part' if ((int(nconnections) >= 10 or (type == "complex" and int(nconnections)
- >= 5)) and not type.t == "message") else 'all') }
+ hide: ${ ('part' if (
+ int(nconnections) >= 10
+ or (type == "complex" and int(nconnections) >= 5)
+ or (type == "msg_complex")) and (not type == "msg_float")
+ else 'all')
+ }
- id: alpha10
label: Line 10 Alpha
+ dtype: real
+ default: 1.0
base_key: alpha1
- hide: ${ ('part' if ((int(nconnections) >= 10 or (type == "complex" and int(nconnections)
- >= 5)) and not type.t == "message") else 'all') }
+ hide: ${ ('part' if (
+ int(nconnections) >= 10
+ or (type == "complex" and int(nconnections) >= 5)
+ or (type == "msg_complex")) and (not type == "msg_float")
+ else 'all')
+ }
asserts:
- ${nconnections <= (5 if type == 'complex' else 10)}
diff --git a/gr-qtgui/grc/qtgui_time_sink_x.block.yml.py b/gr-qtgui/grc/qtgui_time_sink_x.block.yml.py
new file mode 100644
index 0000000000..571a5dfba8
--- /dev/null
+++ b/gr-qtgui/grc/qtgui_time_sink_x.block.yml.py
@@ -0,0 +1,362 @@
+#!/usr/bin/env python
+
+import math
+import re
+
+EVERYTHING_BEFORE_PARAMS = """id: qtgui_time_sink_x
+label: QT GUI Time Sink
+
+parameters:
+- id: type
+ label: Type
+ dtype: enum
+ default: complex
+ options: [complex, float, msg_complex, msg_float]
+ option_labels: [Complex, Float, Complex Message, Float Message]
+ option_attributes:
+ fcn: [time_sink_c, time_sink_f, time_sink_c, time_sink_f]
+ t: [complex, float, message, message]
+ hide: part
+- id: name
+ label: Name
+ dtype: string
+ default: '""'
+ hide: ${ ('none' if len(name) > 0 else 'part') }
+- id: ylabel
+ label: Y Axis Label
+ dtype: string
+ default: Amplitude
+ hide: part
+- id: yunit
+ label: Y Axis Unit
+ dtype: string
+ default: '""'
+ hide: part
+- id: size
+ label: Number of Points
+ dtype: int
+ default: '1024'
+ hide: ${ ('all' if type.startswith('msg') else 'none') }
+- id: srate
+ label: Sample Rate
+ dtype: float
+ default: samp_rate
+- id: grid
+ label: Grid
+ dtype: enum
+ default: 'False'
+ options: ['True', 'False']
+ option_labels: ['Yes', 'No']
+ hide: part
+- id: autoscale
+ label: Autoscale
+ dtype: enum
+ default: 'False'
+ options: ['True', 'False']
+ option_labels: ['Yes', 'No']
+- id: ymin
+ label: Y min
+ dtype: float
+ default: '-1'
+ hide: part
+- id: ymax
+ label: Y max
+ dtype: float
+ default: '1'
+ hide: part
+- id: nconnections
+ label: Number of Inputs
+ dtype: int
+ default: '1'
+ hide: ${ ('all' if type.startswith('msg') else 'part') }
+- id: update_time
+ label: Update Period
+ dtype: float
+ default: '0.10'
+ hide: part
+- id: entags
+ label: Disp. Tags
+ dtype: enum
+ default: 'True'
+ options: ['True', 'False']
+ option_labels: ['Yes', 'No']
+ hide: ${ ('all' if type.startswith('msg') else 'part') }
+- id: gui_hint
+ label: GUI Hint
+ dtype: gui_hint
+ hide: part
+- id: tr_mode
+ label: Trigger Mode
+ category: Trigger
+ dtype: enum
+ default: qtgui.TRIG_MODE_FREE
+ options: [qtgui.TRIG_MODE_FREE, qtgui.TRIG_MODE_AUTO, qtgui.TRIG_MODE_NORM, qtgui.TRIG_MODE_TAG]
+ option_labels: [Free, Auto, Normal, Tag]
+ hide: part
+- id: tr_slope
+ label: Trigger Slope
+ category: Trigger
+ dtype: enum
+ default: qtgui.TRIG_MODE_POS
+ options: [qtgui.TRIG_SLOPE_POS, qtgui.TRIG_SLOPE_NEG]
+ option_labels: [Positive, Negative]
+ hide: part
+- id: tr_level
+ label: Trigger Level
+ category: Trigger
+ dtype: float
+ default: '0.0'
+ hide: part
+- id: tr_delay
+ label: Trigger Delay
+ category: Trigger
+ dtype: float
+ default: '0'
+ hide: part
+- id: tr_chan
+ label: Trigger Channel
+ category: Trigger
+ dtype: int
+ default: '0'
+ hide: part
+- id: tr_tag
+ label: Trigger Tag Key
+ category: Trigger
+ dtype: string
+ default: '""'
+ hide: part
+- id: ctrlpanel
+ label: Control Panel
+ category: Config
+ dtype: enum
+ default: 'False'
+ options: ['True', 'False']
+ option_labels: ['Yes', 'No']
+ hide: part
+- id: legend
+ label: Legend
+ category: Config
+ dtype: enum
+ default: 'True'
+ options: ['True', 'False']
+ option_labels: ['Yes', 'No']
+ hide: part
+- id: axislabels
+ label: Axis Labels
+ category: Config
+ dtype: enum
+ default: 'True'
+ options: ['True', 'False']
+ option_labels: ['Yes', 'No']
+ hide: part
+- id: stemplot
+ label: Stem Plot
+ category: Config
+ dtype: enum
+ default: 'False'
+ options: ['True', 'False']
+ option_labels: ['Yes', 'No']
+ hide: part"""
+
+LINE_PARAMS = """
+- id: label{i}
+ label: Line {i} Label
+ dtype: string
+ default: 'Signal {i}'
+ base_key: label1
+ hide: ${{ ('part' if (
+ int(nconnections) >= {i}
+ or (type == "complex" and int(nconnections) >= {i_cplx})
+ or (type == "msg_complex")) and (not type == "msg_float")
+ else 'all')
+ }}
+- id: width{i}
+ label: Line {i} Width
+ default: 1
+ base_key: width1
+ hide: ${{ ('part' if (
+ int(nconnections) >= {i}
+ or (type == "complex" and int(nconnections) >= {i_cplx})
+ or (type == "msg_complex")) and (not type == "msg_float")
+ else 'all')
+ }}
+- id: color{i}
+ label: Line {i} Color
+ dtype: string
+ default: '{i_color}'
+ base_key: color1
+ hide: ${{ ('part' if (
+ int(nconnections) >= {i}
+ or (type == "complex" and int(nconnections) >= {i_cplx})
+ or (type == "msg_complex")) and (not type == "msg_float")
+ else 'all')
+ }}
+- id: style{i}
+ label: Line {i} Style
+ dtype: int
+ default: 1
+ base_key: style1
+ hide: ${{ ('part' if (
+ int(nconnections) >= {i}
+ or (type == "complex" and int(nconnections) >= {i_cplx})
+ or (type == "msg_complex")) and (not type == "msg_float")
+ else 'all')
+ }}
+- id: marker{i}
+ label: Line {i} Marker
+ dtype: int
+ default: 1
+ base_key: marker1
+ hide: ${{ ('part' if (
+ int(nconnections) >= {i}
+ or (type == "complex" and int(nconnections) >= {i_cplx})
+ or (type == "msg_complex")) and (not type == "msg_float")
+ else 'all')
+ }}
+- id: alpha{i}
+ label: Line {i} Alpha
+ dtype: real
+ default: 1.0
+ base_key: alpha1
+ hide: ${{ ('part' if (
+ int(nconnections) >= {i}
+ or (type == "complex" and int(nconnections) >= {i_cplx})
+ or (type == "msg_complex")) and (not type == "msg_float")
+ else 'all')
+ }}
+"""
+
+EVERYTHING_AFTER_PARAMS = """
+asserts:
+- ${nconnections <= (5 if type == 'complex' else 10)}
+
+inputs:
+- domain: stream
+ dtype: ${ type.t }
+ multiplicity: ${ (0 if type.startswith('msg') else nconnections) }
+ optional: true
+
+templates:
+ imports: |-
+ from PyQt5 import Qt
+ from gnuradio import qtgui
+ from gnuradio.filter import firdes
+ import sip
+ callbacks:
+ - set_time_domain_axis(${min}, ${max})
+ - set_update_time(${update_time})
+ - set_y_axis(${ymin}, ${ymax})
+ - set_samp_rate(${srate})
+ - self.${id}.set_trigger_mode(${tr_mode}, ${tr_slope}, ${tr_level}, ${tr_delay},
+ ${tr_chan}, ${tr_tag})
+ make: |-
+ <%
+ win = 'self._%s_win'%id
+ %>\\
+ qtgui.${type.fcn}(
+ ${size}, #size
+ ${srate}, #samp_rate
+ ${name}, #name
+ ${0 if type.startswith('msg') else nconnections} #number of inputs
+ )
+ self.${id}.set_update_time(${update_time})
+ self.${id}.set_y_axis(${ymin}, ${ymax})
+
+ self.${id}.set_y_label(${ylabel}, ${yunit})
+
+ self.${id}.enable_tags(${entags})
+ self.${id}.set_trigger_mode(${tr_mode}, ${tr_slope}, ${tr_level}, ${tr_delay}, ${tr_chan}, ${tr_tag})
+ self.${id}.enable_autoscale(${autoscale})
+ self.${id}.enable_grid(${grid})
+ self.${id}.enable_axis_labels(${axislabels})
+ self.${id}.enable_control_panel(${ctrlpanel})
+ self.${id}.enable_stem_plot(${stemplot})
+
+ % if legend == "False":
+ self.${id}.disable_legend()
+ % endif
+
+ labels = [${label1}, ${label2}, ${label3}, ${label4}, ${label5},
+ ${label6}, ${label7}, ${label8}, ${label9}, ${label10}]
+ widths = [${width1}, ${width2}, ${width3}, ${width4}, ${width5},
+ ${width6}, ${width7}, ${width8}, ${width9}, ${width10}]
+ colors = [${color1}, ${color2}, ${color3}, ${color4}, ${color5},
+ ${color6}, ${color7}, ${color8}, ${color9}, ${color10}]
+ alphas = [${alpha1}, ${alpha2}, ${alpha3}, ${alpha4}, ${alpha5},
+ ${alpha6}, ${alpha7}, ${alpha8}, ${alpha9}, ${alpha10}]
+ styles = [${style1}, ${style2}, ${style3}, ${style4}, ${style5},
+ ${style6}, ${style7}, ${style8}, ${style9}, ${style10}]
+ markers = [${marker1}, ${marker2}, ${marker3}, ${marker4}, ${marker5},
+ ${marker6}, ${marker7}, ${marker8}, ${marker9}, ${marker10}]
+
+
+ % if type.endswith('complex'):
+ for i in range(${2 if type.startswith('msg') else 2*int(nconnections)}):
+ if len(labels[i]) == 0:
+ if (i % 2 == 0):
+ self.${id}.set_line_label(i, "Re{{Data {0}}}".format(i/2))
+ else:
+ self.${id}.set_line_label(i, "Im{{Data {0}}}".format(i/2))
+ else:
+ self.${id}.set_line_label(i, labels[i])
+ self.${id}.set_line_width(i, widths[i])
+ self.${id}.set_line_color(i, colors[i])
+ self.${id}.set_line_style(i, styles[i])
+ self.${id}.set_line_marker(i, markers[i])
+ self.${id}.set_line_alpha(i, alphas[i])
+ % else:
+ for i in range(${1 if type.startswith('msg') else int(nconnections)}):
+ if len(labels[i]) == 0:
+ self.${id}.set_line_label(i, "Data {0}".format(i))
+ else:
+ self.${id}.set_line_label(i, labels[i])
+ self.${id}.set_line_width(i, widths[i])
+ self.${id}.set_line_color(i, colors[i])
+ self.${id}.set_line_style(i, styles[i])
+ self.${id}.set_line_marker(i, markers[i])
+ self.${id}.set_line_alpha(i, alphas[i])
+ % endif
+
+ ${win} = sip.wrapinstance(self.${id}.pyqwidget(), Qt.QWidget)
+ ${gui_hint() % win}
+
+documentation: |-
+ The GUI hint can be used to position the widget within the application. The hint is of the form [tab_id@tab_index]: [row, col, row_span, col_span]. Both the tab specification and the grid position are optional.
+
+file_format: 1
+"""
+
+def make_yml():
+ """Return the YML file as a string"""
+ default_colors = [
+ 'blue', 'red', 'green', 'black', 'cyan', 'magenta', 'yellow',
+ 'dark red', 'dark green', 'Dark Blue'
+ ]
+ line_params_1 = LINE_PARAMS.format(i=1, i_cplx=1, i_color=default_colors[0])
+ line_params_1 = re.sub(r' base_key:.*\n', '', line_params_1)
+ line_params_n = ''.join([
+ LINE_PARAMS.format(
+ i=i,
+ i_cplx=int(math.ceil(float(i)/2)),
+ i_color=default_colors[i % len(default_colors)],
+ )
+ for i in range(2, 11)
+ ])
+ return ''.join((
+ EVERYTHING_BEFORE_PARAMS,
+ line_params_1,
+ line_params_n,
+ EVERYTHING_AFTER_PARAMS,
+ ))
+
+
+if __name__ == '__main__':
+ import sys
+ try:
+ filename = sys.argv[1]
+ except IndexError:
+ filename = __file__[:-3]
+ data = make_yml()
+ with open(filename, 'wb') as fp:
+ fp.write(data.encode())
+
diff --git a/gr-qtgui/grc/qtgui_waterfall_sink_x.block.yml b/gr-qtgui/grc/qtgui_waterfall_sink_x.block.yml
index 75fd432a35..add262f507 100644
--- a/gr-qtgui/grc/qtgui_waterfall_sink_x.block.yml
+++ b/gr-qtgui/grc/qtgui_waterfall_sink_x.block.yml
@@ -237,6 +237,10 @@ inputs:
id: freq
optional: true
hide: ${ showports }
+- domain: message
+ id: bw
+ optional: true
+ hide: ${ showports }
outputs:
- domain: message
diff --git a/gr-qtgui/include/gnuradio/qtgui/freq_sink_c.h b/gr-qtgui/include/gnuradio/qtgui/freq_sink_c.h
index 0adc85eda9..c96185da54 100644
--- a/gr-qtgui/include/gnuradio/qtgui/freq_sink_c.h
+++ b/gr-qtgui/include/gnuradio/qtgui/freq_sink_c.h
@@ -62,12 +62,17 @@ namespace gr {
* Message Ports:
*
* - freq (input):
- * Receives a PMT pair: (intern("freq"), double(frequency).
+ * Receives a PMT pair: (intern("freq"), double(frequency)).
* This is used to retune the center frequency of the
* display's x-axis.
+ *
+ * - bw (input):
+ * Receives a PMT pair: (intern("bw"), double(bandwidth)).
+ * This is used to programmatically change the bandwidth of
+ * of the display's x-axis.
*
* - freq (output):
- * Produces a PMT pair with (intern("freq"), double(frequency).
+ * Produces a PMT pair with (intern("freq"), double(frequency)).
* When a user double-clicks on the display, the block
* produces and emits a message containing the frequency of
* where on the x-axis the user clicked. This value can be
diff --git a/gr-qtgui/include/gnuradio/qtgui/freq_sink_f.h b/gr-qtgui/include/gnuradio/qtgui/freq_sink_f.h
index 0dc1f7700d..5e621a4f82 100644
--- a/gr-qtgui/include/gnuradio/qtgui/freq_sink_f.h
+++ b/gr-qtgui/include/gnuradio/qtgui/freq_sink_f.h
@@ -62,12 +62,17 @@ namespace gr {
* Message Ports:
*
* - freq (input):
- * Receives a PMT pair: (intern("freq"), double(frequency).
+ * Receives a PMT pair: (intern("freq"), double(frequency)).
* This is used to retune the center frequency of the
* display's x-axis.
+ *
+ * - bw (input):
+ * Receives a PMT pair: (intern("bw"), double(bandwidth)).
+ * This is used to programmatically change the bandwidth of
+ * of the display's x-axis.
*
* - freq (output):
- * Produces a PMT pair with (intern("freq"), double(frequency).
+ * Produces a PMT pair with (intern("freq"), double(frequency)).
* When a user double-clicks on the display, the block
* produces and emits a message containing the frequency of
* where on the x-axis the user clicked. This value can be
diff --git a/gr-qtgui/include/gnuradio/qtgui/waterfall_sink_c.h b/gr-qtgui/include/gnuradio/qtgui/waterfall_sink_c.h
index 8891529753..d90851e602 100644
--- a/gr-qtgui/include/gnuradio/qtgui/waterfall_sink_c.h
+++ b/gr-qtgui/include/gnuradio/qtgui/waterfall_sink_c.h
@@ -70,7 +70,12 @@ namespace gr {
* Receives a PMT pair: (intern("freq"), double(frequency)).
* This is used to retune the center frequency of the
* display's x-axis.
- *
+ *
+ * - bw (input):
+ * Receives a PMT pair: (intern("bw"), double(bandwidth)).
+ * This is used to programmatically change the bandwidth of
+ * of the display's x-axis.
+ *
* - freq (output):
* Produces a PMT pair with (intern("freq"), double(frequency)).
* When a user double-clicks on the display, the block
diff --git a/gr-qtgui/include/gnuradio/qtgui/waterfall_sink_f.h b/gr-qtgui/include/gnuradio/qtgui/waterfall_sink_f.h
index e8c659cb09..8f4a88db9c 100644
--- a/gr-qtgui/include/gnuradio/qtgui/waterfall_sink_f.h
+++ b/gr-qtgui/include/gnuradio/qtgui/waterfall_sink_f.h
@@ -68,12 +68,17 @@ namespace gr {
* Message Ports:
*
* - freq (input):
- * Receives a PMT pair: (intern("freq"), double(frequency).
+ * Receives a PMT pair: (intern("freq"), double(frequency)).
* This is used to retune the center frequency of the
* display's x-axis.
+ *
+ * - bw (input):
+ * Receives a PMT pair: (intern("bw"), double(bandwidth)).
+ * This is used to programmatically change the bandwidth of
+ * of the display's x-axis.
*
* - freq (output):
- * Produces a PMT pair with (intern("freq"), double(frequency).
+ * Produces a PMT pair with (intern("freq"), double(frequency)).
* When a user double-clicks on the display, the block
* produces and emits a message containing the frequency of
* where on the x-axis the user clicked. This value can be
diff --git a/gr-qtgui/lib/freq_sink_c_impl.cc b/gr-qtgui/lib/freq_sink_c_impl.cc
index 1acbb9d001..36a9fca07d 100644
--- a/gr-qtgui/lib/freq_sink_c_impl.cc
+++ b/gr-qtgui/lib/freq_sink_c_impl.cc
@@ -64,6 +64,7 @@ namespace gr {
d_center_freq(fc), d_bandwidth(bw), d_name(name),
d_nconnections(nconnections),
d_port(pmt::mp("freq")),
+ d_port_bw(pmt::mp("bw")),
d_parent(parent)
{
// Required now for Qt; argc must be greater than 0 and argv
@@ -74,6 +75,11 @@ namespace gr {
d_argv = new char;
d_argv[0] = '\0';
+ // setup bw input port
+ message_port_register_in(d_port_bw);
+ set_msg_handler(d_port_bw,
+ boost::bind(&freq_sink_c_impl::handle_set_bw, this, _1));
+
// setup output message port to post frequency when display is
// double-clicked
message_port_register_out(d_port);
@@ -610,6 +616,19 @@ namespace gr {
}
void
+ freq_sink_c_impl::handle_set_bw(pmt::pmt_t msg)
+ {
+ if(pmt::is_pair(msg)) {
+ pmt::pmt_t x = pmt::cdr(msg);
+ if(pmt::is_real(x)) {
+ d_bandwidth = pmt::to_double(x);
+ d_qApplication->postEvent(d_main_gui,
+ new SetFreqEvent(d_center_freq, d_bandwidth));
+ }
+ }
+ }
+
+ void
freq_sink_c_impl::_gui_update_trigger()
{
trigger_mode new_trigger_mode = d_main_gui->getTriggerMode();
diff --git a/gr-qtgui/lib/freq_sink_c_impl.h b/gr-qtgui/lib/freq_sink_c_impl.h
index d5b32e0cf4..842b525193 100644
--- a/gr-qtgui/lib/freq_sink_c_impl.h
+++ b/gr-qtgui/lib/freq_sink_c_impl.h
@@ -49,6 +49,7 @@ namespace gr {
int d_nconnections;
const pmt::pmt_t d_port;
+ const pmt::pmt_t d_port_bw;
bool d_shift;
fft::fft_complex *d_fft;
@@ -74,6 +75,10 @@ namespace gr {
void check_clicked();
void fft(float *data_out, const gr_complex *data_in, int size);
+ // Handles message input port for setting new bandwidth
+ // The message is a PMT pair (intern('bw'), double(bw))
+ void handle_set_bw(pmt::pmt_t msg);
+
// Handles message input port for setting new center frequency.
// The message is a PMT pair (intern('freq'), double(frequency)).
void handle_set_freq(pmt::pmt_t msg);
diff --git a/gr-qtgui/lib/freq_sink_f_impl.cc b/gr-qtgui/lib/freq_sink_f_impl.cc
index 2b14f02d72..8f4728be0a 100644
--- a/gr-qtgui/lib/freq_sink_f_impl.cc
+++ b/gr-qtgui/lib/freq_sink_f_impl.cc
@@ -62,8 +62,10 @@ namespace gr {
d_fftsize(fftsize), d_fftavg(1.0),
d_wintype((filter::firdes::win_type)(wintype)),
d_center_freq(fc), d_bandwidth(bw), d_name(name),
- d_nconnections(nconnections), d_parent(parent),
- d_port(pmt::mp("freq"))
+ d_nconnections(nconnections),
+ d_port(pmt::mp("freq")),
+ d_port_bw(pmt::mp("bw")),
+ d_parent(parent)
{
// Required now for Qt; argc must be greater than 0 and argv
// must have at least one valid character. Must be valid through
@@ -73,6 +75,11 @@ namespace gr {
d_argv = new char;
d_argv[0] = '\0';
+ // setup bw input port
+ message_port_register_in(d_port_bw);
+ set_msg_handler(d_port_bw,
+ boost::bind(&freq_sink_f_impl::handle_set_bw, this, _1));
+
// setup output message port to post frequency when display is
// double-clicked
message_port_register_out(d_port);
@@ -614,6 +621,19 @@ namespace gr {
}
void
+ freq_sink_f_impl::handle_set_bw(pmt::pmt_t msg)
+ {
+ if(pmt::is_pair(msg)) {
+ pmt::pmt_t x = pmt::cdr(msg);
+ if(pmt::is_real(x)) {
+ d_bandwidth = pmt::to_double(x);
+ d_qApplication->postEvent(d_main_gui,
+ new SetFreqEvent(d_center_freq, d_bandwidth));
+ }
+ }
+ }
+
+ void
freq_sink_f_impl::_gui_update_trigger()
{
trigger_mode new_trigger_mode = d_main_gui->getTriggerMode();
diff --git a/gr-qtgui/lib/freq_sink_f_impl.h b/gr-qtgui/lib/freq_sink_f_impl.h
index 31fa768b13..9b656f6e57 100644
--- a/gr-qtgui/lib/freq_sink_f_impl.h
+++ b/gr-qtgui/lib/freq_sink_f_impl.h
@@ -49,6 +49,7 @@ namespace gr {
int d_nconnections;
const pmt::pmt_t d_port;
+ const pmt::pmt_t d_port_bw;
bool d_shift;
fft::fft_complex *d_fft;
@@ -74,6 +75,10 @@ namespace gr {
void check_clicked();
void fft(float *data_out, const float *data_in, int size);
+ // Handles message input port for setting new bandwidth
+ // The message is a PMT pair (intern('bw'), double(bw))
+ void handle_set_bw(pmt::pmt_t msg);
+
// Handles message input port for setting new center frequency.
// The message is a PMT pair (intern('freq'), double(frequency)).
void handle_set_freq(pmt::pmt_t msg);
diff --git a/gr-qtgui/lib/time_sink_c_impl.cc b/gr-qtgui/lib/time_sink_c_impl.cc
index ead8764a10..31c17f3a9c 100644
--- a/gr-qtgui/lib/time_sink_c_impl.cc
+++ b/gr-qtgui/lib/time_sink_c_impl.cc
@@ -127,7 +127,7 @@ namespace gr {
bool
time_sink_c_impl::check_topology(int ninputs, int noutputs)
{
- return 2*ninputs == d_nconnections;
+ return (unsigned int) (2*ninputs) == d_nconnections;
}
void
diff --git a/gr-qtgui/lib/time_sink_f_impl.cc b/gr-qtgui/lib/time_sink_f_impl.cc
index 6b32d71e95..4fbd0705f7 100644
--- a/gr-qtgui/lib/time_sink_f_impl.cc
+++ b/gr-qtgui/lib/time_sink_f_impl.cc
@@ -122,7 +122,7 @@ namespace gr {
bool
time_sink_f_impl::check_topology(int ninputs, int noutputs)
{
- return ninputs == d_nconnections;
+ return (unsigned int)(ninputs) == d_nconnections;
}
void
diff --git a/gr-qtgui/lib/vector_sink_f_impl.cc b/gr-qtgui/lib/vector_sink_f_impl.cc
index 705482266e..b1789354b0 100644
--- a/gr-qtgui/lib/vector_sink_f_impl.cc
+++ b/gr-qtgui/lib/vector_sink_f_impl.cc
@@ -80,9 +80,9 @@ namespace gr {
d_vecavg(1.0),
d_name(name),
d_nconnections(nconnections),
+ d_port(pmt::mp(MSG_PORT_OUT_XVAL)),
d_msg(pmt::mp("x")),
- d_parent(parent),
- d_port(pmt::mp(MSG_PORT_OUT_XVAL))
+ d_parent(parent)
{
// Required now for Qt; argc must be greater than 0 and argv
// must have at least one valid character. Must be valid through
@@ -421,7 +421,7 @@ namespace gr {
if(gr::high_res_timer_now() - d_last_time > d_update_time) {
for(int n = 0; n < d_nconnections; n++) {
in = ((const float*)input_items[n]) + d_vlen;
- for(int x = 0; x < d_vlen; x++) {
+ for(unsigned int x = 0; x < d_vlen; x++) {
d_magbufs[n][x] = (double)((1.0-d_vecavg)*d_magbufs[n][x] + (d_vecavg)*in[x]);
}
}
diff --git a/gr-qtgui/lib/waterfall_sink_c_impl.cc b/gr-qtgui/lib/waterfall_sink_c_impl.cc
index f9a4ad3e5e..8945cda214 100644
--- a/gr-qtgui/lib/waterfall_sink_c_impl.cc
+++ b/gr-qtgui/lib/waterfall_sink_c_impl.cc
@@ -68,6 +68,7 @@ namespace gr {
d_nconnections(nconnections),
d_nrows(200),
d_port(pmt::mp("freq")),
+ d_port_bw(pmt::mp("bw")),
d_parent(parent)
{
// Required now for Qt; argc must be greater than 0 and argv
@@ -112,6 +113,11 @@ namespace gr {
initialize();
+ // setup bw input port
+ message_port_register_in(d_port_bw);
+ set_msg_handler(d_port_bw,
+ boost::bind(&waterfall_sink_c_impl::handle_set_bw, this, _1));
+
// setup output message port to post frequency when display is
// double-clicked
message_port_register_out(d_port);
@@ -513,6 +519,19 @@ namespace gr {
}
void
+ waterfall_sink_c_impl::handle_set_bw(pmt::pmt_t msg)
+ {
+ if(pmt::is_pair(msg)) {
+ pmt::pmt_t x = pmt::cdr(msg);
+ if(pmt::is_real(x)) {
+ d_bandwidth = pmt::to_double(x);
+ d_qApplication->postEvent(d_main_gui,
+ new SetFreqEvent(d_center_freq, d_bandwidth));
+ }
+ }
+ }
+
+ void
waterfall_sink_c_impl::set_time_per_fft(double t)
{
d_main_gui->setTimePerFFT(t);
diff --git a/gr-qtgui/lib/waterfall_sink_c_impl.h b/gr-qtgui/lib/waterfall_sink_c_impl.h
index 5cd65d40a7..e0d421e36b 100644
--- a/gr-qtgui/lib/waterfall_sink_c_impl.h
+++ b/gr-qtgui/lib/waterfall_sink_c_impl.h
@@ -51,7 +51,8 @@ namespace gr {
int d_nrows;
const pmt::pmt_t d_port;
-
+ const pmt::pmt_t d_port_bw;
+
bool d_shift;
fft::fft_complex *d_fft;
@@ -75,6 +76,10 @@ namespace gr {
void check_clicked();
void fft(float *data_out, const gr_complex *data_in, int size);
+ // Handles message input port for setting new bandwidth
+ // The message is a PMT pair (intern('bw'), double(bw))
+ void handle_set_bw(pmt::pmt_t msg);
+
// Handles message input port for setting new center frequency.
// The message is a PMT pair (intern('freq'), double(frequency)).
void handle_set_freq(pmt::pmt_t msg);
diff --git a/gr-qtgui/lib/waterfall_sink_f_impl.cc b/gr-qtgui/lib/waterfall_sink_f_impl.cc
index 5a5d72ddc9..eb5dcf1822 100644
--- a/gr-qtgui/lib/waterfall_sink_f_impl.cc
+++ b/gr-qtgui/lib/waterfall_sink_f_impl.cc
@@ -63,8 +63,9 @@ namespace gr {
d_wintype((filter::firdes::win_type)(wintype)),
d_center_freq(fc), d_bandwidth(bw), d_name(name),
d_nconnections(nconnections), d_nrows(200),
- d_parent(parent),
- d_port(pmt::mp("freq"))
+ d_port(pmt::mp("freq")),
+ d_port_bw(pmt::mp("bw")),
+ d_parent(parent)
{
// Required now for Qt; argc must be greater than 0 and argv
// must have at least one valid character. Must be valid through
@@ -108,6 +109,11 @@ namespace gr {
initialize();
+ // setup bw input port
+ message_port_register_in(d_port_bw);
+ set_msg_handler(d_port_bw,
+ boost::bind(&waterfall_sink_f_impl::handle_set_bw, this, _1));
+
// setup output message port to post frequency when display is
// double-clicked
message_port_register_out(d_port);
@@ -517,6 +523,19 @@ namespace gr {
}
void
+ waterfall_sink_f_impl::handle_set_bw(pmt::pmt_t msg)
+ {
+ if(pmt::is_pair(msg)) {
+ pmt::pmt_t x = pmt::cdr(msg);
+ if(pmt::is_real(x)) {
+ d_bandwidth = pmt::to_double(x);
+ d_qApplication->postEvent(d_main_gui,
+ new SetFreqEvent(d_center_freq, d_bandwidth));
+ }
+ }
+ }
+
+ void
waterfall_sink_f_impl::set_time_per_fft(double t)
{
d_main_gui->setTimePerFFT(t);
diff --git a/gr-qtgui/lib/waterfall_sink_f_impl.h b/gr-qtgui/lib/waterfall_sink_f_impl.h
index c320c628eb..aca87b187a 100644
--- a/gr-qtgui/lib/waterfall_sink_f_impl.h
+++ b/gr-qtgui/lib/waterfall_sink_f_impl.h
@@ -51,6 +51,7 @@ namespace gr {
int d_nrows;
const pmt::pmt_t d_port;
+ const pmt::pmt_t d_port_bw;
bool d_shift;
fft::fft_complex *d_fft;
@@ -75,6 +76,10 @@ namespace gr {
void check_clicked();
void fft(float *data_out, const float *data_in, int size);
+ // Handles message input port for setting new bandwidth
+ // The message is a PMT pair (intern('bw'), double(bw))
+ void handle_set_bw(pmt::pmt_t msg);
+
// Handles message input port for setting new center frequency.
// The message is a PMT pair (intern('freq'), double(frequency)).
void handle_set_freq(pmt::pmt_t msg);
diff --git a/gr-trellis/CMakeLists.txt b/gr-trellis/CMakeLists.txt
index 2de5c04a0a..af4d94ae66 100644
--- a/gr-trellis/CMakeLists.txt
+++ b/gr-trellis/CMakeLists.txt
@@ -61,8 +61,10 @@ if(ENABLE_PYTHON)
add_subdirectory(python/trellis)
add_subdirectory(examples/python)
add_subdirectory(examples/grc)
- add_subdirectory(grc)
endif(ENABLE_PYTHON)
+if(ENABLE_GRC)
+ add_subdirectory(grc)
+endif(ENABLE_GRC)
########################################################################
# Create Pkg Config File
diff --git a/gr-trellis/include/gnuradio/trellis/interleaver.h b/gr-trellis/include/gnuradio/trellis/interleaver.h
index 4dd0beb3a1..9e30c75e95 100644
--- a/gr-trellis/include/gnuradio/trellis/interleaver.h
+++ b/gr-trellis/include/gnuradio/trellis/interleaver.h
@@ -37,17 +37,17 @@ namespace gr {
class TRELLIS_API interleaver
{
private:
- int d_K;
+ unsigned int d_K;
std::vector<int> d_INTER;
std::vector<int> d_DEINTER;
public:
interleaver();
interleaver(const interleaver & INTERLEAVER);
- interleaver(int K, const std::vector<int> & INTER);
+ interleaver(unsigned int K, const std::vector<int> & INTER);
interleaver(const char *name);
- interleaver(int K, int seed);
- int K () const { return d_K; }
+ interleaver(unsigned int K, int seed);
+ unsigned int K () const { return d_K; }
const std::vector<int> & INTER() const { return d_INTER; }
const std::vector<int> & DEINTER() const { return d_DEINTER; }
void write_interleaver_txt(std::string filename);
diff --git a/gr-trellis/lib/interleaver.cc b/gr-trellis/lib/interleaver.cc
index eb7998b8ce..72bb296e5f 100644
--- a/gr-trellis/lib/interleaver.cc
+++ b/gr-trellis/lib/interleaver.cc
@@ -48,14 +48,14 @@ namespace gr {
d_DEINTER=INTERLEAVER.DEINTER();
}
- interleaver::interleaver(int K, const std::vector<int> &INTER)
+ interleaver::interleaver(unsigned int K, const std::vector<int> &INTER)
{
d_K=K;
d_INTER=INTER;
d_DEINTER.resize(d_K);
// generate DEINTER table
- for(int i=0;i<d_K;i++) {
+ for(unsigned int i = 0; i < d_K; i++) {
d_DEINTER[d_INTER[i]]=i;
}
}
@@ -84,16 +84,17 @@ namespace gr {
d_INTER.resize(d_K);
d_DEINTER.resize(d_K);
- for(int i=0;i<d_K;i++) {
- if(fscanf(interleaverfile,"%d",&(d_INTER[i])) == EOF) {
- if(ferror(interleaverfile) != 0)
- throw std::runtime_error("interleaver::interleaver(const char *name): file read error\n");
- }
+ for (unsigned int i = 0; i < d_K; i++) {
+ if (fscanf(interleaverfile, "%d", &(d_INTER[i])) == EOF) {
+ if (ferror(interleaverfile) != 0)
+ throw std::runtime_error(
+ "interleaver::interleaver(const char *name): file read error\n");
+ }
}
// generate DEINTER table
- for(int i=0;i<d_K;i++) {
- d_DEINTER[d_INTER[i]]=i;
+ for (unsigned int i = 0; i < d_K; i++) {
+ d_DEINTER[d_INTER[i]] = i;
}
fclose(interleaverfile);
@@ -102,7 +103,7 @@ namespace gr {
//######################################################################
//# Generate a random interleaver
//######################################################################
- interleaver::interleaver(int K, int seed)
+ interleaver::interleaver(unsigned int K, int seed)
{
d_K=K;
d_INTER.resize(d_K);
@@ -123,13 +124,13 @@ namespace gr {
bytes[idx] = *valptr++;
}
}
- for(int i=0;i<d_K;i++) {
- d_INTER[i]=i;
+ for (unsigned int i = 0; i < d_K; i++) {
+ d_INTER[i] = i;
}
quicksort_index <int> (tmp,d_INTER,0,d_K-1);
// generate DEINTER table
- for(int i=0;i<d_K;i++) {
+ for(unsigned int i=0;i<d_K;i++) {
d_DEINTER[d_INTER[i]]=i;
}
}
@@ -151,7 +152,7 @@ namespace gr {
}
interleaver_fname << d_K << std::endl;
interleaver_fname << std::endl;
- for(int i=0;i<d_K;i++)
+ for(unsigned int i=0;i<d_K;i++)
interleaver_fname << d_INTER[i] << ' ';
interleaver_fname << std::endl;
interleaver_fname.close();
diff --git a/gr-uhd/CMakeLists.txt b/gr-uhd/CMakeLists.txt
index 74c8159274..e136d4f97f 100644
--- a/gr-uhd/CMakeLists.txt
+++ b/gr-uhd/CMakeLists.txt
@@ -59,10 +59,12 @@ add_subdirectory(examples/c++)
if(ENABLE_PYTHON)
add_subdirectory(swig)
add_subdirectory(python/uhd)
- add_subdirectory(grc)
add_subdirectory(apps)
add_subdirectory(examples/grc)
endif(ENABLE_PYTHON)
+if(ENABLE_GRC)
+ add_subdirectory(grc)
+endif(ENABLE_GRC)
########################################################################
# Create Pkg Config File
diff --git a/gr-uhd/grc/CMakeLists.txt b/gr-uhd/grc/CMakeLists.txt
index 72a6543df3..0f4ef3678a 100644
--- a/gr-uhd/grc/CMakeLists.txt
+++ b/gr-uhd/grc/CMakeLists.txt
@@ -1,4 +1,4 @@
-# Copyright 2011 Free Software Foundation, Inc.
+# Copyright 2011,2018 Free Software Foundation, Inc.
#
# This file is part of GNU Radio
#
diff --git a/gr-uhd/grc/gen_uhd_usrp_blocks.py b/gr-uhd/grc/gen_uhd_usrp_blocks.py
index a969ab95d1..96ba6dbf3f 100644
--- a/gr-uhd/grc/gen_uhd_usrp_blocks.py
+++ b/gr-uhd/grc/gen_uhd_usrp_blocks.py
@@ -18,6 +18,8 @@ along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
"""
+import sys
+
MAIN_TMPL = """\
id: uhd_usrp_${sourk}
label: 'UHD: USRP ${sourk.title()}'
@@ -62,8 +64,8 @@ parameters:
- id: sync
label: Sync
dtype: enum
- options: [sync, pc_clock, '']
- option_labels: [unknown PPS, PC Clock, don't sync]
+ options: [sync, pc_clock, none]
+ option_labels: [Unknown PPS, PC Clock, No Sync]
hide: ${'$'}{ 'none' if sync else 'part'}
- id: clock_rate
label: Clock Rate (Hz)
@@ -112,16 +114,20 @@ inputs:
- domain: message
id: command
optional: true
- hide: ${'$'}{hide_cmd_port}
-% if sourk == 'sink':
-- domain: stream
-% else:
+% if sourk == 'source':
outputs:
-- domain: stream
% endif
+- domain: stream
dtype: ${'$'}{type.type}
multiplicity: ${'$'}{nchan}
+% if sourk == 'sink':
+
+outputs:
+- domain: message
+ id: async_msgs
+ optional: true
+% endif
templates:
imports: |-
@@ -133,7 +139,7 @@ templates:
uhd.stream_args(
cpu_format="${'$'}{type}",
${'%'} if otw:
- otw_format=${'$'}{otw},
+ otw_format="${'$'}{otw}",
${'%'} endif
${'%'} if stream_args:
args=${'$'}{stream_args},
@@ -148,6 +154,37 @@ templates:
${'$'}{len_tag_name},
${'%'} endif
)
+ % for m in range(max_mboards):
+ ${'%'} if context.get('num_mboards')() > ${m}:
+ ${'%'} if context.get('sd_spec${m}')():
+ self.${'$'}{id}.set_subdev_spec(${'$'}{${'sd_spec' + str(m)}}, ${m})
+ ${'%'} endif
+ ${'%'} if context.get('time_source${m}')():
+ self.${'$'}{id}.set_time_source(${'$'}{${'time_source' + str(m)}}, ${m})
+ ${'%'} endif
+ ${'%'} if context.get('clock_source${m}')():
+ self.${'$'}{id}.set_clock_source(${'$'}{${'clock_source' + str(m)}}, ${m})
+ ${'%'} endif
+ ${'%'} endif
+ % endfor
+ % for n in range(max_nchan):
+ ${'%'} if context.get('nchan')() > ${n}:
+ self.${'$'}{id}.set_center_freq(${'$'}{${'center_freq' + str(n)}}, ${n})
+ ${'%'} if bool(eval(context.get('norm_gain' + '${n}')())):
+ self.${'$'}{id}.set_normalized_gain(${'$'}{${'gain' + str(n)}}, ${n})
+ ${'%'} else:
+ self.${'$'}{id}.set_gain(${'$'}{${'gain' + str(n)}}, ${n})
+ ${'%'} endif
+ self.${'$'}{id}.set_antenna(${'$'}{${'ant' + str(n)}}, ${n})
+ ${'%'} if context.get('bw${n}')():
+ self.${'$'}{id}.set_bandwidth(${'$'}{${'bw' + str(n)}}, ${n})
+ ${'%'} endif
+ ${'%'} if context.get('show_lo_controls')():
+ self.${'$'}{id}.set_lo_source(${'$'}{${'lo_source' + str(n)}}, uhd.ALL_LOS, ${n})
+ self.${'$'}{id}.set_lo_export_enabled(${'$'}{${'lo_export' + str(n)}}, uhd.ALL_LOS, ${n})
+ ${'%'} endif
+ ${'%'} endif
+ % endfor
${'%'} if clock_rate():
self.${'$'}{id}.set_clock_rate(${'$'}{clock_rate}, uhd.ALL_MBOARDS)
${'%'} endif
@@ -156,16 +193,18 @@ templates:
self.${'$'}{id}.set_time_unknown_pps(uhd.time_spec())
${'%'} elif sync == 'pc_clock':
self.${'$'}{id}.set_time_now(uhd.time_spec(time.time()), uhd.ALL_MBOARDS)
+ ${'%'} else:
+ # No synchronization enforced.
${'%'} endif
callbacks:
- set_samp_rate(${'$'}{samp_rate})
% for n in range(max_nchan):
- - set_center_freq(${'center_freq' + str(n)}, ${n})
- - self.${'$'}{id}.set_${'$'}{'normalized_' if norm_gain${n} else ''}gain(gain${n}, ${n})
- - ${'$'}{'set_lo_source(lo_source${n}, uhd.ALL_LOS, ${n})' if show_lo_controls else ''}
- - ${'$'}{'set_lo_export_enabled(lo_export${n}, uhd.ALL_LOS, ${n})' if show_lo_controls else ''}
- - set_antenna(${'ant' + str(n)}, ${n})
- - set_bandwidth(${'bw' + str(n)}, ${n})
+ - set_center_freq(${'$'}{${'center_freq' + str(n)}}, ${n})
+ - self.${'$'}{id}.set_${'$'}{'normalized_' if bool(eval(context.get('norm_gain${n}')())) else ''}gain(${'$'}{${'gain' + str(n)}}, ${n})
+ - ${'$'}{'set_lo_source(' + lo_source${n} + ', uhd.ALL_LOS, ${n})' if show_lo_controls else ''}
+ - ${'$'}{'set_lo_export_enabled(' + lo_export${n} + ', uhd.ALL_LOS, ${n})' if show_lo_controls else ''}
+ - set_antenna(${'$'}{${'ant' + str(n)}}, ${n})
+ - set_bandwidth(${'$'}{${'bw' + str(n)}}, ${n})
% endfor
@@ -288,7 +327,6 @@ PARAMS_TMPL = """
dtype: real
default: '0'
hide: ${'$'}{ 'all' if not nchan > ${n} else ('none' if eval('bw' + str(${n})) else 'part')}
-% if sourk == 'source':
- id: lo_source${n}
label: 'Ch${n}: LO Source'
category: RF Options
@@ -303,6 +341,7 @@ PARAMS_TMPL = """
default: 'False'
options: ['True', 'False']
hide: ${'$'}{ 'all' if not nchan > ${n} else ('none' if show_lo_controls else 'all')}
+% if sourk == 'source':
- id: dc_offs_enb${n}
label: 'Ch${n}: Enable DC Offset Correction'
category: FE Corrections
@@ -318,17 +357,6 @@ PARAMS_TMPL = """
% endif
"""
-SHOW_CMD_PORT_PARAM = """
-- id: hide_cmd_port
- label: Show Command Port
- category: Advanced
- dtype: enum
- default: 'False'
- options: ['False', 'True']
- option_labels: ['Yes', 'No']
- hide: part
-"""
-
SHOW_LO_CONTROLS_PARAM = """
- id: show_lo_controls
label: Show LO Controls
@@ -361,7 +389,6 @@ MAX_NUM_MBOARDS = 8
MAX_NUM_CHANNELS = MAX_NUM_MBOARDS*4
if __name__ == '__main__':
- import sys
for file in sys.argv[1:]:
if file.endswith('source.block.yml'):
sourk = 'source'
@@ -375,7 +402,6 @@ if __name__ == '__main__':
parse_tmpl(PARAMS_TMPL, n=n, sourk=sourk)
for n in range(MAX_NUM_CHANNELS)
])
- params += SHOW_CMD_PORT_PARAM
params += SHOW_LO_CONTROLS_PARAM
if sourk == 'sink':
params += TSBTAG_PARAM
diff --git a/gr-uhd/lib/usrp_block_impl.cc b/gr-uhd/lib/usrp_block_impl.cc
index bbdb347a1f..8fc4a83e73 100644
--- a/gr-uhd/lib/usrp_block_impl.cc
+++ b/gr-uhd/lib/usrp_block_impl.cc
@@ -132,11 +132,6 @@ usrp_block_impl::usrp_block_impl(
_curr_tune_req(stream_args.channels.size(), ::uhd::tune_request_t()),
_chans_to_tune(stream_args.channels.size())
{
- // TODO remove this when we update UHD
- if(stream_args.cpu_format == "fc32")
- _type = boost::make_shared< ::uhd::io_type_t >(::uhd::io_type_t::COMPLEX_FLOAT32);
- if(stream_args.cpu_format == "sc16")
- _type = boost::make_shared< ::uhd::io_type_t >(::uhd::io_type_t::COMPLEX_INT16);
_dev = ::uhd::usrp::multi_usrp::make(device_addr);
_check_mboard_sensors_locked();
diff --git a/gr-uhd/lib/usrp_block_impl.h b/gr-uhd/lib/usrp_block_impl.h
index 75706fbf85..efae28074e 100644
--- a/gr-uhd/lib/usrp_block_impl.h
+++ b/gr-uhd/lib/usrp_block_impl.h
@@ -33,8 +33,6 @@
namespace gr {
namespace uhd {
- static const size_t ALL_MBOARDS = ::uhd::usrp::multi_usrp::ALL_MBOARDS;
- static const size_t ALL_CHANS = ::uhd::usrp::multi_usrp::ALL_CHANS;
static const std::string ALL_GAINS = ::uhd::usrp::multi_usrp::ALL_GAINS;
#ifdef UHD_USRP_MULTI_USRP_LO_CONFIG_API
@@ -218,7 +216,6 @@ namespace gr {
//! Shared pointer to the underlying multi_usrp object
::uhd::usrp::multi_usrp::sptr _dev;
::uhd::stream_args_t _stream_args;
- boost::shared_ptr< ::uhd::io_type_t > _type;
//! Number of channels (i.e. number of in- or outputs)
size_t _nchan;
bool _stream_now;
diff --git a/gr-uhd/lib/usrp_sink_impl.cc b/gr-uhd/lib/usrp_sink_impl.cc
index 2b393443c4..92ff805191 100644
--- a/gr-uhd/lib/usrp_sink_impl.cc
+++ b/gr-uhd/lib/usrp_sink_impl.cc
@@ -1,6 +1,6 @@
/* -*- c++ -*- */
/*
- * Copyright 2010-2016 Free Software Foundation, Inc.
+ * Copyright 2010-2016,2018 Free Software Foundation, Inc.
*
* This file is part of GNU Radio
*
@@ -47,13 +47,20 @@ namespace gr {
io_signature::make(0, 0, 0)),
usrp_block_impl(device_addr, stream_args, length_tag_name),
_length_tag_key(length_tag_name.empty() ? pmt::PMT_NIL : pmt::string_to_symbol(length_tag_name)),
- _nitems_to_send(0)
+ _nitems_to_send(0),
+ _async_event_loop_running(true)
{
+ message_port_register_out(ASYNC_MSGS_PORT_KEY);
+ _async_event_thread = gr::thread::thread([this](){
+ this->async_event_loop();
+ });
_sample_rate = get_samp_rate();
}
usrp_sink_impl::~usrp_sink_impl()
{
+ _async_event_loop_running = false;
+ _async_event_thread.join();
}
::uhd::dict<std::string, std::string>
@@ -702,5 +709,55 @@ namespace gr {
#endif /* GR_CTRLPORT */
}
+ void
+ usrp_sink_impl::async_event_loop()
+ {
+ typedef ::uhd::async_metadata_t md_t;
+ md_t metadata;
+
+ while(_async_event_loop_running) {
+ while(!_dev->get_device()->recv_async_msg(metadata, 0.1)) {
+ if(!_async_event_loop_running){
+ return;
+ }
+ }
+
+ pmt::pmt_t event_list = pmt::PMT_NIL;
+
+ if(metadata.event_code & md_t::EVENT_CODE_BURST_ACK){
+ event_list = pmt::list_add(event_list, BURST_ACK_KEY);
+ }
+ if(metadata.event_code & md_t::EVENT_CODE_UNDERFLOW){
+ event_list = pmt::list_add(event_list, UNDERFLOW_KEY);
+ }
+ if(metadata.event_code & md_t::EVENT_CODE_UNDERFLOW_IN_PACKET){
+ event_list = pmt::list_add(event_list, UNDERFLOW_IN_PACKET_KEY);
+ }
+ if(metadata.event_code & md_t::EVENT_CODE_SEQ_ERROR){
+ event_list = pmt::list_add(event_list, SEQ_ERROR_KEY);
+ }
+ if(metadata.event_code & md_t::EVENT_CODE_SEQ_ERROR_IN_BURST){
+ event_list = pmt::list_add(event_list, SEQ_ERROR_IN_BURST_KEY);
+ }
+ if(metadata.event_code & md_t::EVENT_CODE_TIME_ERROR){
+ event_list = pmt::list_add(event_list, TIME_ERROR_KEY);
+ }
+
+ if(!pmt::eq(event_list, pmt::PMT_NIL)){
+ pmt::pmt_t value = pmt::dict_add(pmt::make_dict(), EVENT_CODE_KEY, event_list);
+ if(metadata.has_time_spec){
+ pmt::pmt_t time_spec = pmt::cons(
+ pmt::from_long(metadata.time_spec.get_full_secs()),
+ pmt::from_double(metadata.time_spec.get_frac_secs())
+ );
+ value = pmt::dict_add(value, TIME_SPEC_KEY, time_spec);
+ }
+ value = pmt::dict_add(value, CHANNEL_KEY, pmt::from_uint64(metadata.channel));
+ pmt::pmt_t msg = pmt::cons(ASYNC_MSG_KEY, value);
+ message_port_pub(ASYNC_MSGS_PORT_KEY, msg);
+ }
+ }
+ }
+
} /* namespace uhd */
} /* namespace gr */
diff --git a/gr-uhd/lib/usrp_sink_impl.h b/gr-uhd/lib/usrp_sink_impl.h
index 10f55848ec..774baf1f24 100644
--- a/gr-uhd/lib/usrp_sink_impl.h
+++ b/gr-uhd/lib/usrp_sink_impl.h
@@ -30,6 +30,20 @@ static const pmt::pmt_t TIME_KEY = pmt::string_to_symbol("tx_time");
static const pmt::pmt_t FREQ_KEY = pmt::string_to_symbol("tx_freq");
static const pmt::pmt_t COMMAND_KEY = pmt::string_to_symbol("tx_command");
+//Asynchronous message handling related PMTs
+static const pmt::pmt_t ASYNC_MSG_KEY = pmt::string_to_symbol("uhd_async_msg");
+static const pmt::pmt_t CHANNEL_KEY = pmt::string_to_symbol("channel");
+static const pmt::pmt_t TIME_SPEC_KEY = pmt::string_to_symbol("time_spec");
+static const pmt::pmt_t EVENT_CODE_KEY = pmt::string_to_symbol("event_code");
+static const pmt::pmt_t BURST_ACK_KEY = pmt::string_to_symbol("burst_ack");
+static const pmt::pmt_t UNDERFLOW_KEY = pmt::string_to_symbol("underflow");
+static const pmt::pmt_t UNDERFLOW_IN_PACKET_KEY = pmt::string_to_symbol("underflow_in_packet");
+static const pmt::pmt_t SEQ_ERROR_KEY = pmt::string_to_symbol("seq_error");
+static const pmt::pmt_t SEQ_ERROR_IN_BURST_KEY = pmt::string_to_symbol("seq_error_in_burst");
+static const pmt::pmt_t TIME_ERROR_KEY = pmt::string_to_symbol("time_error");
+static const pmt::pmt_t ASYNC_MSGS_PORT_KEY = pmt::string_to_symbol("async_msgs");
+
+
namespace gr {
namespace uhd {
@@ -119,6 +133,10 @@ namespace gr {
const pmt::pmt_t _length_tag_key;
long _nitems_to_send;
+ //asynchronous messages related stuff
+ bool _async_event_loop_running;
+ void async_event_loop();
+ gr::thread::thread _async_event_thread;
};
} /* namespace uhd */
diff --git a/gr-uhd/python/uhd/__init__.py b/gr-uhd/python/uhd/__init__.py
index c5c05ddb2e..d88cd4b32d 100644
--- a/gr-uhd/python/uhd/__init__.py
+++ b/gr-uhd/python/uhd/__init__.py
@@ -113,7 +113,6 @@ def _prepare_uhd_swig():
kwargs = dict(kwargs)
for index, key, cast in (
(0, 'device_addr', device_addr),
- (1, 'io_type', io_type),
):
if len(args) > index:
args[index] = cast(args[index])
diff --git a/gr-uhd/swig/uhd_swig.i b/gr-uhd/swig/uhd_swig.i
index 2852447c80..fb9a8e58fb 100644
--- a/gr-uhd/swig/uhd_swig.i
+++ b/gr-uhd/swig/uhd_swig.i
@@ -79,8 +79,6 @@
%include <uhd/types/device_addr.hpp>
-%include <uhd/types/io_type.hpp>
-
%template(range_vector_t) std::vector<uhd::range_t>; //define before range
%include <uhd/types/ranges.hpp>
@@ -88,8 +86,6 @@
%include <uhd/types/tune_result.hpp>
-%include <uhd/types/io_type.hpp>
-
%include <uhd/types/time_spec.hpp>
%extend uhd::time_spec_t{
diff --git a/gr-utils/python/modtool/gr-newmod/CMakeLists.txt b/gr-utils/python/modtool/gr-newmod/CMakeLists.txt
index 0496ceeaa4..e03d787828 100644
--- a/gr-utils/python/modtool/gr-newmod/CMakeLists.txt
+++ b/gr-utils/python/modtool/gr-newmod/CMakeLists.txt
@@ -190,11 +190,13 @@ add_custom_target(uninstall
########################################################################
add_subdirectory(include/howto)
add_subdirectory(lib)
-add_subdirectory(swig)
-add_subdirectory(python)
-add_subdirectory(grc)
add_subdirectory(apps)
add_subdirectory(docs)
+add_subdirectory(swig)
+add_subdirectory(python)
+if(ENABLE_GRC)
+ add_subdirectory(grc)
+endif(ENABLE_GRC)
########################################################################
# Install cmake search helper for this library
diff --git a/gr-video-sdl/CMakeLists.txt b/gr-video-sdl/CMakeLists.txt
index a171535c37..4067006dfe 100644
--- a/gr-video-sdl/CMakeLists.txt
+++ b/gr-video-sdl/CMakeLists.txt
@@ -50,10 +50,12 @@ if(ENABLE_GR_VIDEO_SDL)
add_subdirectory(include/gnuradio/video_sdl)
add_subdirectory(lib)
if(ENABLE_PYTHON)
- add_subdirectory(grc)
add_subdirectory(swig)
add_subdirectory(python/video_sdl)
endif(ENABLE_PYTHON)
+if(ENABLE_GRC)
+ add_subdirectory(grc)
+endif(ENABLE_GRC)
########################################################################
# Create Pkg Config File
diff --git a/gr-vocoder/CMakeLists.txt b/gr-vocoder/CMakeLists.txt
index e90ba29727..cab10fdf84 100644
--- a/gr-vocoder/CMakeLists.txt
+++ b/gr-vocoder/CMakeLists.txt
@@ -80,9 +80,11 @@ add_subdirectory(docs)
if(ENABLE_PYTHON)
add_subdirectory(swig)
add_subdirectory(python/vocoder)
- add_subdirectory(grc)
add_subdirectory(examples)
endif(ENABLE_PYTHON)
+if(ENABLE_GRC)
+ add_subdirectory(grc)
+endif(ENABLE_GRC)
########################################################################
# Create Pkg Config File
diff --git a/gr-zeromq/CMakeLists.txt b/gr-zeromq/CMakeLists.txt
index 1ebd0ff4f5..39977ce45e 100644
--- a/gr-zeromq/CMakeLists.txt
+++ b/gr-zeromq/CMakeLists.txt
@@ -55,9 +55,11 @@ add_subdirectory(lib)
if(ENABLE_PYTHON)
add_subdirectory(swig)
add_subdirectory(python/zeromq)
- add_subdirectory(grc)
add_subdirectory(examples)
endif(ENABLE_PYTHON)
+if(ENABLE_GRC)
+ add_subdirectory(grc)
+endif(ENABLE_GRC)
########################################################################
# Create Pkg Config File
diff --git a/gr-zeromq/include/gnuradio/zeromq/pub_msg_sink.h b/gr-zeromq/include/gnuradio/zeromq/pub_msg_sink.h
index fb046ca84b..cb79dacc01 100644
--- a/gr-zeromq/include/gnuradio/zeromq/pub_msg_sink.h
+++ b/gr-zeromq/include/gnuradio/zeromq/pub_msg_sink.h
@@ -52,6 +52,11 @@ namespace gr {
* \param timeout Receive timeout in milliseconds, default is 100ms, 1us increments
*/
static sptr make(char *address, int timeout=100);
+
+ /*!
+ * \brief Return a std::string of ZMQ_LAST_ENDPOINT from the underlying ZMQ socket.
+ */
+ virtual std::string last_endpoint() = 0;
};
} // namespace zeromq
diff --git a/gr-zeromq/include/gnuradio/zeromq/pub_sink.h b/gr-zeromq/include/gnuradio/zeromq/pub_sink.h
index 3fecc10b59..d6a03c7f89 100644
--- a/gr-zeromq/include/gnuradio/zeromq/pub_sink.h
+++ b/gr-zeromq/include/gnuradio/zeromq/pub_sink.h
@@ -57,6 +57,11 @@ namespace gr {
*/
static sptr make(size_t itemsize, size_t vlen, char *address,
int timeout=100, bool pass_tags=false, int hwm=-1);
+
+ /*!
+ * \brief Return a std::string of ZMQ_LAST_ENDPOINT from the underlying ZMQ socket.
+ */
+ virtual std::string last_endpoint() = 0;
};
} // namespace zeromq
diff --git a/gr-zeromq/include/gnuradio/zeromq/pull_msg_source.h b/gr-zeromq/include/gnuradio/zeromq/pull_msg_source.h
index 13857ead5f..a0fe8e880f 100644
--- a/gr-zeromq/include/gnuradio/zeromq/pull_msg_source.h
+++ b/gr-zeromq/include/gnuradio/zeromq/pull_msg_source.h
@@ -50,6 +50,11 @@ namespace gr {
*
*/
static sptr make(char *address, int timeout=100);
+
+ /*!
+ * \brief Return a std::string of ZMQ_LAST_ENDPOINT from the underlying ZMQ socket.
+ */
+ virtual std::string last_endpoint() = 0;
};
} // namespace zeromq
diff --git a/gr-zeromq/include/gnuradio/zeromq/pull_source.h b/gr-zeromq/include/gnuradio/zeromq/pull_source.h
index ecfe508b0a..47628cf20d 100644
--- a/gr-zeromq/include/gnuradio/zeromq/pull_source.h
+++ b/gr-zeromq/include/gnuradio/zeromq/pull_source.h
@@ -54,6 +54,11 @@ namespace gr {
*/
static sptr make(size_t itemsize, size_t vlen, char *address,
int timeout=100, bool pass_tags=false, int hwm=-1);
+
+ /*!
+ * \brief Return a std::string of ZMQ_LAST_ENDPOINT from the underlying ZMQ socket.
+ */
+ virtual std::string last_endpoint() = 0;
};
} // namespace zeromq
diff --git a/gr-zeromq/include/gnuradio/zeromq/push_msg_sink.h b/gr-zeromq/include/gnuradio/zeromq/push_msg_sink.h
index 941ad549f5..d13ddfe708 100644
--- a/gr-zeromq/include/gnuradio/zeromq/push_msg_sink.h
+++ b/gr-zeromq/include/gnuradio/zeromq/push_msg_sink.h
@@ -52,6 +52,11 @@ namespace gr {
*
*/
static sptr make(char *address, int timeout=100);
+
+ /*!
+ * \brief Return a std::string of ZMQ_LAST_ENDPOINT from the underlying ZMQ socket.
+ */
+ virtual std::string last_endpoint() = 0;
};
} // namespace zeromq
diff --git a/gr-zeromq/include/gnuradio/zeromq/push_sink.h b/gr-zeromq/include/gnuradio/zeromq/push_sink.h
index f81dcaa941..3cb52535f9 100644
--- a/gr-zeromq/include/gnuradio/zeromq/push_sink.h
+++ b/gr-zeromq/include/gnuradio/zeromq/push_sink.h
@@ -58,6 +58,11 @@ namespace gr {
*/
static sptr make(size_t itemsize, size_t vlen, char *address,
int timeout=100, bool pass_tags=false, int hwm=-1);
+
+ /*!
+ * \brief Return a std::string of ZMQ_LAST_ENDPOINT from the underlying ZMQ socket.
+ */
+ virtual std::string last_endpoint() = 0;
};
} // namespace zeromq
diff --git a/gr-zeromq/include/gnuradio/zeromq/rep_msg_sink.h b/gr-zeromq/include/gnuradio/zeromq/rep_msg_sink.h
index d11550d149..e84964a74b 100644
--- a/gr-zeromq/include/gnuradio/zeromq/rep_msg_sink.h
+++ b/gr-zeromq/include/gnuradio/zeromq/rep_msg_sink.h
@@ -52,6 +52,11 @@ namespace gr {
*
*/
static sptr make(char *address, int timeout=100);
+
+ /*!
+ * \brief Return a std::string of ZMQ_LAST_ENDPOINT from the underlying ZMQ socket.
+ */
+ virtual std::string last_endpoint() = 0;
};
} // namespace zeromq
diff --git a/gr-zeromq/include/gnuradio/zeromq/rep_sink.h b/gr-zeromq/include/gnuradio/zeromq/rep_sink.h
index c1d2d370fc..138d0f13da 100644
--- a/gr-zeromq/include/gnuradio/zeromq/rep_sink.h
+++ b/gr-zeromq/include/gnuradio/zeromq/rep_sink.h
@@ -56,6 +56,11 @@ namespace gr {
*/
static sptr make(size_t itemsize, size_t vlen, char *address,
int timeout=100, bool pass_tags=false, int hwm=-1);
+
+ /*!
+ * \brief Return a std::string of ZMQ_LAST_ENDPOINT from the underlying ZMQ socket.
+ */
+ virtual std::string last_endpoint() = 0;
};
} // namespace zeromq
diff --git a/gr-zeromq/include/gnuradio/zeromq/req_msg_source.h b/gr-zeromq/include/gnuradio/zeromq/req_msg_source.h
index 28ac9f84f3..80a6ae559e 100644
--- a/gr-zeromq/include/gnuradio/zeromq/req_msg_source.h
+++ b/gr-zeromq/include/gnuradio/zeromq/req_msg_source.h
@@ -50,6 +50,11 @@ namespace gr {
*
*/
static sptr make(char *address, int timeout=100);
+
+ /*!
+ * \brief Return a std::string of ZMQ_LAST_ENDPOINT from the underlying ZMQ socket.
+ */
+ virtual std::string last_endpoint() = 0;
};
} // namespace zeromq
diff --git a/gr-zeromq/include/gnuradio/zeromq/req_source.h b/gr-zeromq/include/gnuradio/zeromq/req_source.h
index 103da90f71..dfe3929ebf 100644
--- a/gr-zeromq/include/gnuradio/zeromq/req_source.h
+++ b/gr-zeromq/include/gnuradio/zeromq/req_source.h
@@ -54,6 +54,11 @@ namespace gr {
*/
static sptr make(size_t itemsize, size_t vlen, char *address,
int timeout=100, bool pass_tags=false, int hwm=-1);
+
+ /*!
+ * \brief Return a std::string of ZMQ_LAST_ENDPOINT from the underlying ZMQ socket.
+ */
+ virtual std::string last_endpoint() = 0;
};
} // namespace zeromq
diff --git a/gr-zeromq/include/gnuradio/zeromq/sub_msg_source.h b/gr-zeromq/include/gnuradio/zeromq/sub_msg_source.h
index 5c91d1e1ed..ac68e8aa59 100644
--- a/gr-zeromq/include/gnuradio/zeromq/sub_msg_source.h
+++ b/gr-zeromq/include/gnuradio/zeromq/sub_msg_source.h
@@ -50,6 +50,11 @@ namespace gr {
*
*/
static sptr make(char *address, int timeout=100);
+
+ /*!
+ * \brief Return a std::string of ZMQ_LAST_ENDPOINT from the underlying ZMQ socket.
+ */
+ virtual std::string last_endpoint() = 0;
};
} // namespace zeromq
diff --git a/gr-zeromq/include/gnuradio/zeromq/sub_source.h b/gr-zeromq/include/gnuradio/zeromq/sub_source.h
index 990c74cabd..874730403f 100644
--- a/gr-zeromq/include/gnuradio/zeromq/sub_source.h
+++ b/gr-zeromq/include/gnuradio/zeromq/sub_source.h
@@ -54,6 +54,11 @@ namespace gr {
*/
static sptr make(size_t itemsize, size_t vlen, char *address,
int timeout=100, bool pass_tags=false, int hwm=-1);
+
+ /*!
+ * \brief Return a std::string of ZMQ_LAST_ENDPOINT from the underlying ZMQ socket.
+ */
+ virtual std::string last_endpoint() = 0;
};
} // namespace zeromq
diff --git a/gr-zeromq/lib/base_impl.cc b/gr-zeromq/lib/base_impl.cc
index 20c5d3845d..0465ec3abb 100644
--- a/gr-zeromq/lib/base_impl.cc
+++ b/gr-zeromq/lib/base_impl.cc
@@ -54,6 +54,15 @@ namespace gr {
delete d_context;
}
+ std::string
+ base_impl::last_endpoint()
+ {
+ char addr[256];
+ size_t addr_len = sizeof(addr);
+ d_socket->getsockopt(ZMQ_LAST_ENDPOINT, addr, &addr_len);
+ return std::string(addr, addr_len-1);
+ }
+
base_sink_impl::base_sink_impl(int type, size_t itemsize, size_t vlen, char *address, int timeout, bool pass_tags, int hwm)
: base_impl(type, itemsize, vlen, timeout, pass_tags)
diff --git a/gr-zeromq/lib/base_impl.h b/gr-zeromq/lib/base_impl.h
index ed1695102e..e09e652768 100644
--- a/gr-zeromq/lib/base_impl.h
+++ b/gr-zeromq/lib/base_impl.h
@@ -37,6 +37,7 @@ namespace gr {
virtual ~base_impl();
protected:
+ std::string last_endpoint();
zmq::context_t *d_context;
zmq::socket_t *d_socket;
size_t d_vsize;
diff --git a/gr-zeromq/lib/pub_msg_sink_impl.h b/gr-zeromq/lib/pub_msg_sink_impl.h
index 747ac7ee85..0cedfed482 100644
--- a/gr-zeromq/lib/pub_msg_sink_impl.h
+++ b/gr-zeromq/lib/pub_msg_sink_impl.h
@@ -41,6 +41,12 @@ namespace gr {
~pub_msg_sink_impl();
void handler(pmt::pmt_t msg);
+ std::string last_endpoint() override {
+ char addr[256];
+ size_t addr_len = sizeof(addr);
+ d_socket->getsockopt(ZMQ_LAST_ENDPOINT, addr, &addr_len);
+ return std::string(addr, addr_len-1);
+ }
};
} // namespace zeromq
diff --git a/gr-zeromq/lib/pub_sink_impl.h b/gr-zeromq/lib/pub_sink_impl.h
index 8637c3565a..78b5c1e1bd 100644
--- a/gr-zeromq/lib/pub_sink_impl.h
+++ b/gr-zeromq/lib/pub_sink_impl.h
@@ -39,6 +39,7 @@ namespace gr {
int work(int noutput_items,
gr_vector_const_void_star &input_items,
gr_vector_void_star &output_items);
+ std::string last_endpoint() override {return base_sink_impl::last_endpoint();}
};
} // namespace zeromq
diff --git a/gr-zeromq/lib/pull_msg_source_impl.h b/gr-zeromq/lib/pull_msg_source_impl.h
index 972dab5aff..25cd2dee31 100644
--- a/gr-zeromq/lib/pull_msg_source_impl.h
+++ b/gr-zeromq/lib/pull_msg_source_impl.h
@@ -48,6 +48,13 @@ namespace gr {
bool start();
bool stop();
+
+ std::string last_endpoint() override {
+ char addr[256];
+ size_t addr_len = sizeof(addr);
+ d_socket->getsockopt(ZMQ_LAST_ENDPOINT, addr, &addr_len);
+ return std::string(addr, addr_len-1);
+ }
};
} // namespace zeromq
diff --git a/gr-zeromq/lib/pull_source_impl.h b/gr-zeromq/lib/pull_source_impl.h
index 7d8ab53bd0..c08ab0521b 100644
--- a/gr-zeromq/lib/pull_source_impl.h
+++ b/gr-zeromq/lib/pull_source_impl.h
@@ -39,6 +39,7 @@ namespace gr {
int work(int noutput_items,
gr_vector_const_void_star &input_items,
gr_vector_void_star &output_items);
+ std::string last_endpoint() override {return base_source_impl::last_endpoint();}
};
} // namespace zeromq
diff --git a/gr-zeromq/lib/push_msg_sink_impl.h b/gr-zeromq/lib/push_msg_sink_impl.h
index d669d327cb..0d0503cd55 100644
--- a/gr-zeromq/lib/push_msg_sink_impl.h
+++ b/gr-zeromq/lib/push_msg_sink_impl.h
@@ -41,6 +41,12 @@ namespace gr {
~push_msg_sink_impl();
void handler(pmt::pmt_t msg);
+ std::string last_endpoint() override {
+ char addr[256];
+ size_t addr_len = sizeof(addr);
+ d_socket->getsockopt(ZMQ_LAST_ENDPOINT, addr, &addr_len);
+ return std::string(addr, addr_len-1);
+ }
};
} // namespace zeromq
diff --git a/gr-zeromq/lib/push_sink_impl.h b/gr-zeromq/lib/push_sink_impl.h
index 0a5de10787..73480e1047 100644
--- a/gr-zeromq/lib/push_sink_impl.h
+++ b/gr-zeromq/lib/push_sink_impl.h
@@ -39,6 +39,8 @@ namespace gr {
int work(int noutput_items,
gr_vector_const_void_star &input_items,
gr_vector_void_star &output_items);
+
+ std::string last_endpoint() override {return base_sink_impl::last_endpoint();}
};
} // namespace zeromq
diff --git a/gr-zeromq/lib/rep_msg_sink_impl.h b/gr-zeromq/lib/rep_msg_sink_impl.h
index a8485304d7..6f788690c9 100644
--- a/gr-zeromq/lib/rep_msg_sink_impl.h
+++ b/gr-zeromq/lib/rep_msg_sink_impl.h
@@ -48,6 +48,13 @@ namespace gr {
bool start();
bool stop();
+
+ std::string last_endpoint() override {
+ char addr[256];
+ size_t addr_len = sizeof(addr);
+ d_socket->getsockopt(ZMQ_LAST_ENDPOINT, addr, &addr_len);
+ return std::string(addr, addr_len-1);
+ }
};
} // namespace zeromq
diff --git a/gr-zeromq/lib/rep_sink_impl.h b/gr-zeromq/lib/rep_sink_impl.h
index 012fc45e7b..b9451cfeaf 100644
--- a/gr-zeromq/lib/rep_sink_impl.h
+++ b/gr-zeromq/lib/rep_sink_impl.h
@@ -39,6 +39,7 @@ namespace gr {
int work(int noutput_items,
gr_vector_const_void_star &input_items,
gr_vector_void_star &output_items);
+ std::string last_endpoint() override {return base_sink_impl::last_endpoint();}
};
} // namespace zeromq
diff --git a/gr-zeromq/lib/req_msg_source_impl.h b/gr-zeromq/lib/req_msg_source_impl.h
index 322ce4cf51..c9e81efc5d 100644
--- a/gr-zeromq/lib/req_msg_source_impl.h
+++ b/gr-zeromq/lib/req_msg_source_impl.h
@@ -48,6 +48,13 @@ namespace gr {
bool start();
bool stop();
+
+ std::string last_endpoint() override {
+ char addr[256];
+ size_t addr_len = sizeof(addr);
+ d_socket->getsockopt(ZMQ_LAST_ENDPOINT, addr, &addr_len);
+ return std::string(addr, addr_len-1);
+ }
};
} // namespace zeromq
diff --git a/gr-zeromq/lib/req_source_impl.h b/gr-zeromq/lib/req_source_impl.h
index 8bdbd33459..ec87832518 100644
--- a/gr-zeromq/lib/req_source_impl.h
+++ b/gr-zeromq/lib/req_source_impl.h
@@ -40,6 +40,7 @@ namespace gr {
gr_vector_const_void_star &input_items,
gr_vector_void_star &output_items);
+ std::string last_endpoint() override {return base_source_impl::last_endpoint();}
private:
bool d_req_pending;
};
diff --git a/gr-zeromq/lib/sub_msg_source_impl.h b/gr-zeromq/lib/sub_msg_source_impl.h
index 4cf85d10ba..f0367c6c70 100644
--- a/gr-zeromq/lib/sub_msg_source_impl.h
+++ b/gr-zeromq/lib/sub_msg_source_impl.h
@@ -48,6 +48,13 @@ namespace gr {
bool start();
bool stop();
+
+ std::string last_endpoint() override {
+ char addr[256];
+ size_t addr_len = sizeof(addr);
+ d_socket->getsockopt(ZMQ_LAST_ENDPOINT, addr, &addr_len);
+ return std::string(addr, addr_len-1);
+ }
};
} // namespace zeromq
diff --git a/gr-zeromq/lib/sub_source_impl.h b/gr-zeromq/lib/sub_source_impl.h
index 8f82a9ab94..727d76d6a2 100644
--- a/gr-zeromq/lib/sub_source_impl.h
+++ b/gr-zeromq/lib/sub_source_impl.h
@@ -39,6 +39,8 @@ namespace gr {
int work(int noutput_items,
gr_vector_const_void_star &input_items,
gr_vector_void_star &output_items);
+
+ std::string last_endpoint() override {return base_source_impl::last_endpoint();}
};
} // namespace zeromq
diff --git a/gr-zeromq/python/zeromq/qa_zeromq_pub.py b/gr-zeromq/python/zeromq/qa_zeromq_pub.py
index 01f32c5e7f..0eb5c86eb4 100644
--- a/gr-zeromq/python/zeromq/qa_zeromq_pub.py
+++ b/gr-zeromq/python/zeromq/qa_zeromq_pub.py
@@ -40,10 +40,11 @@ class qa_zeromq_pub (gr_unittest.TestCase):
self.rx_data = None
src_data = list(range(vlen))*100
src = blocks.vector_source_f(src_data, False, vlen)
- zeromq_pub_sink = zeromq.pub_sink(gr.sizeof_float, vlen, "tcp://127.0.0.1:5555")
+ zeromq_pub_sink = zeromq.pub_sink(gr.sizeof_float, vlen, "tcp://127.0.0.1:0")
+ address = zeromq_pub_sink.last_endpoint()
self.tb.connect(src, zeromq_pub_sink)
self.probe_manager = zeromq.probe_manager()
- self.probe_manager.add_socket("tcp://127.0.0.1:5555", 'float32', self.recv_data)
+ self.probe_manager.add_socket(address, 'float32', self.recv_data)
zmq_pull_t = threading.Thread(target=self.probe_manager.watcher)
zmq_pull_t.daemon = True
zmq_pull_t.start()
diff --git a/gr-zeromq/python/zeromq/qa_zeromq_pubsub.py b/gr-zeromq/python/zeromq/qa_zeromq_pubsub.py
index 81b081bde3..94a709bba5 100644
--- a/gr-zeromq/python/zeromq/qa_zeromq_pubsub.py
+++ b/gr-zeromq/python/zeromq/qa_zeromq_pubsub.py
@@ -40,8 +40,9 @@ class qa_zeromq_pubsub (gr_unittest.TestCase):
vlen = 10
src_data = list(range(vlen))*100
src = blocks.vector_source_f(src_data, False, vlen)
- zeromq_pub_sink = zeromq.pub_sink(gr.sizeof_float, vlen, "tcp://127.0.0.1:5556", 0)
- zeromq_sub_source = zeromq.sub_source(gr.sizeof_float, vlen, "tcp://127.0.0.1:5556", 0)
+ zeromq_pub_sink = zeromq.pub_sink(gr.sizeof_float, vlen, "tcp://127.0.0.1:0", 0)
+ address = zeromq_pub_sink.last_endpoint()
+ zeromq_sub_source = zeromq.sub_source(gr.sizeof_float, vlen, address, 0)
sink = blocks.vector_sink_f(vlen)
self.send_tb.connect(src, zeromq_pub_sink)
self.recv_tb.connect(zeromq_sub_source, sink)
diff --git a/gr-zeromq/python/zeromq/qa_zeromq_pushpull.py b/gr-zeromq/python/zeromq/qa_zeromq_pushpull.py
index 35e4e2de25..41c937358a 100644
--- a/gr-zeromq/python/zeromq/qa_zeromq_pushpull.py
+++ b/gr-zeromq/python/zeromq/qa_zeromq_pushpull.py
@@ -38,8 +38,9 @@ class qa_zeromq_pushpull (gr_unittest.TestCase):
vlen = 10
src_data = list(range(vlen))*100
src = blocks.vector_source_f(src_data, False, vlen)
- zeromq_push_sink = zeromq.push_sink(gr.sizeof_float, vlen, "tcp://127.0.0.1:5557")
- zeromq_pull_source = zeromq.pull_source(gr.sizeof_float, vlen, "tcp://127.0.0.1:5557", 0)
+ zeromq_push_sink = zeromq.push_sink(gr.sizeof_float, vlen, "tcp://127.0.0.1:0")
+ address = zeromq_push_sink.last_endpoint()
+ zeromq_pull_source = zeromq.pull_source(gr.sizeof_float, vlen, address, 0)
sink = blocks.vector_sink_f(vlen)
self.send_tb.connect(src, zeromq_push_sink)
self.recv_tb.connect(zeromq_pull_source, sink)
diff --git a/gr-zeromq/python/zeromq/qa_zeromq_reqrep.py b/gr-zeromq/python/zeromq/qa_zeromq_reqrep.py
index 6f08368577..bbe2904950 100644
--- a/gr-zeromq/python/zeromq/qa_zeromq_reqrep.py
+++ b/gr-zeromq/python/zeromq/qa_zeromq_reqrep.py
@@ -41,8 +41,9 @@ class qa_zeromq_reqrep (gr_unittest.TestCase):
vlen = 10
src_data = list(range(vlen))*100
src = blocks.vector_source_f(src_data, False, vlen)
- zeromq_rep_sink = zeromq.rep_sink(gr.sizeof_float, vlen, "tcp://127.0.0.1:5558", 0)
- zeromq_req_source = zeromq.req_source(gr.sizeof_float, vlen, "tcp://127.0.0.1:5558", 0)
+ zeromq_rep_sink = zeromq.rep_sink(gr.sizeof_float, vlen, "tcp://127.0.0.1:0", 0)
+ address = zeromq_rep_sink.last_endpoint()
+ zeromq_req_source = zeromq.req_source(gr.sizeof_float, vlen, address, 0)
sink = blocks.vector_sink_f(vlen)
self.send_tb.connect(src, zeromq_rep_sink)
self.recv_tb.connect(zeromq_req_source, sink)
diff --git a/gr-zeromq/python/zeromq/qa_zeromq_sub.py b/gr-zeromq/python/zeromq/qa_zeromq_sub.py
index 684bb211c0..d3d18eb0dd 100755
--- a/gr-zeromq/python/zeromq/qa_zeromq_sub.py
+++ b/gr-zeromq/python/zeromq/qa_zeromq_sub.py
@@ -35,7 +35,8 @@ class qa_zeromq_sub (gr_unittest.TestCase):
self.tb = gr.top_block ()
self.zmq_context = zmq.Context()
self.pub_socket = self.zmq_context.socket(zmq.PUB)
- self.pub_socket.bind("tcp://127.0.0.1:5559")
+ self.pub_socket.bind("tcp://127.0.0.1:0")
+ self._address = self.pub_socket.getsockopt(zmq.LAST_ENDPOINT).decode()
def tearDown (self):
self.pub_socket.close()
@@ -45,7 +46,7 @@ class qa_zeromq_sub (gr_unittest.TestCase):
def test_001 (self):
vlen = 10
src_data = numpy.array(list(range(vlen))*100, 'float32')
- zeromq_sub_source = zeromq.sub_source(gr.sizeof_float, vlen, "tcp://127.0.0.1:5559")
+ zeromq_sub_source = zeromq.sub_source(gr.sizeof_float, vlen, self._address)
sink = blocks.vector_sink_f(vlen)
self.tb.connect(zeromq_sub_source, sink)
@@ -63,7 +64,7 @@ class qa_zeromq_sub (gr_unittest.TestCase):
# Construct multipart source data to publish
raw_data = [numpy.array(range(vlen), 'float32')*100, numpy.array(range(vlen, 2*vlen), 'float32')*100]
src_data = [a.tostring() for a in raw_data]
- zeromq_sub_source = zeromq.sub_source(gr.sizeof_float, vlen, "tcp://127.0.0.1:5559")
+ zeromq_sub_source = zeromq.sub_source(gr.sizeof_float, vlen, self._address)
sink = blocks.vector_sink_f(vlen)
self.tb.connect(zeromq_sub_source, sink)
diff --git a/grc/CMakeLists.txt b/grc/CMakeLists.txt
index 77c8d4c00d..9e5341bc17 100644
--- a/grc/CMakeLists.txt
+++ b/grc/CMakeLists.txt
@@ -45,12 +45,6 @@ GR_PYTHON_CHECK_MODULE_RAW(
)
GR_PYTHON_CHECK_MODULE_RAW(
- "lxml >= 1.3.6"
- "import lxml.etree; assert lxml.etree.LXML_VERSION >= (1, 3, 6, 0)"
- LXML_FOUND
-)
-
-GR_PYTHON_CHECK_MODULE_RAW(
"pygobject >= 2.28.6"
"import gi; assert gi.version_info >= (2, 28, 6)"
PYGI_FOUND
@@ -90,7 +84,6 @@ if(NOT CMAKE_CROSSCOMPILING)
PYTHON_MIN_VER_FOUND
PYYAML_FOUND
MAKO_FOUND
- LXML_FOUND
PYGI_FOUND
GTK_GI_FOUND
CAIRO_GI_FOUND
diff --git a/grc/core/FlowGraph.py b/grc/core/FlowGraph.py
index 6786bbee30..bf26225e48 100644
--- a/grc/core/FlowGraph.py
+++ b/grc/core/FlowGraph.py
@@ -191,8 +191,13 @@ class FlowGraph(Element):
for expr in self.imports():
try:
exec(expr, namespace)
+ except ImportError:
+ # We do not have a good way right now to determine if an import is for a
+ # hier block, these imports will fail as they are not in the search path
+ # this is ok behavior, unfortunately we could be hiding other import bugs
+ pass
except Exception:
- log.exception('Failed to evaluate expression in namespace', exc_info=True)
+ log.exception('Failed to evaluate import expression "{0}"'.format(expr), exc_info=True)
pass
for id, expr in self.get_python_modules():
diff --git a/grc/core/ParseXML.py b/grc/core/ParseXML.py
deleted file mode 100644
index 430ba5b474..0000000000
--- a/grc/core/ParseXML.py
+++ /dev/null
@@ -1,185 +0,0 @@
-"""
-Copyright 2008, 2015 Free Software Foundation, Inc.
-This file is part of GNU Radio
-
-GNU Radio Companion 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 2
-of the License, or (at your option) any later version.
-
-GNU Radio Companion 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 this program; if not, write to the Free Software
-Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
-"""
-
-from __future__ import absolute_import
-
-from lxml import etree
-
-import six
-from six.moves import map
-
-
-xml_failures = {}
-etree.set_default_parser(etree.XMLParser(remove_comments=True))
-
-
-class XMLSyntaxError(Exception):
- def __init__(self, error_log):
- self._error_log = error_log
- xml_failures[error_log.last_error.filename] = error_log
-
- def __str__(self):
- return '\n'.join(map(str, self._error_log.filter_from_errors()))
-
-
-def validate_dtd(xml_file, dtd_file=None):
- """
- Validate an xml file against its dtd.
-
- Args:
- xml_file: the xml file
- dtd_file: the optional dtd file
- @throws Exception validation fails
- """
- # Perform parsing, use dtd validation if dtd file is not specified
- parser = etree.XMLParser(dtd_validation=not dtd_file)
- try:
- xml = etree.parse(xml_file, parser=parser)
- except etree.LxmlError:
- pass
- if parser.error_log:
- raise XMLSyntaxError(parser.error_log)
-
- # Perform dtd validation if the dtd file is specified
- if not dtd_file:
- return
- try:
- dtd = etree.DTD(dtd_file)
- if not dtd.validate(xml.getroot()):
- raise XMLSyntaxError(dtd.error_log)
- except etree.LxmlError:
- raise XMLSyntaxError(dtd.error_log)
-
-
-def from_file(xml_file):
- """
- Create nested data from an xml file using the from xml helper.
- Also get the grc version information.
-
- Args:
- xml_file: the xml file path
-
- Returns:
- the nested data with grc version information
- """
- xml = etree.parse(xml_file)
-
- tag, nested_data = _from_file(xml.getroot())
- nested_data = {tag: nested_data, '_instructions': {}}
-
- # Get the embedded instructions and build a dictionary item
- xml_instructions = xml.xpath('/processing-instruction()')
- for inst in xml_instructions:
- if inst.target != 'grc':
- continue
- nested_data['_instructions'] = dict(inst.attrib)
- return nested_data
-
-
-WANT_A_LIST = {
- '/block': 'import callback param check sink source'.split(),
- '/block/param_tab_order': 'tab'.split(),
- '/block/param': 'option'.split(),
- '/block/param/option': 'opt'.split(),
- '/flow_graph': 'block connection'.split(),
- '/flow_graph/block': 'param'.split(),
- '/cat': 'cat block'.split(),
- '/cat/cat': 'cat block'.split(),
- '/cat/cat/cat': 'cat block'.split(),
- '/cat/cat/cat/cat': 'cat block'.split(),
- '/domain': 'connection'.split(),
-}
-
-
-def _from_file(xml, parent_tag=''):
- """
- Recursively parse the xml tree into nested data format.
-
- Args:
- xml: the xml tree
-
- Returns:
- the nested data
- """
- tag = xml.tag
- tag_path = parent_tag + '/' + tag
-
- if not len(xml):
- return tag, xml.text or '' # store empty tags (text is None) as empty string
-
- nested_data = {}
- for elem in xml:
- key, value = _from_file(elem, tag_path)
-
- if key in WANT_A_LIST.get(tag_path, []):
- try:
- nested_data[key].append(value)
- except KeyError:
- nested_data[key] = [value]
- else:
- nested_data[key] = value
-
- return tag, nested_data
-
-
-def to_file(nested_data, xml_file):
- """
- Write to an xml file and insert processing instructions for versioning
-
- Args:
- nested_data: the nested data
- xml_file: the xml file path
- """
- xml_data = ""
- instructions = nested_data.pop('_instructions', None)
- # Create the processing instruction from the array
- if instructions:
- xml_data += etree.tostring(etree.ProcessingInstruction(
- 'grc', ' '.join(
- "{0}='{1}'".format(*item) for item in six.iteritems(instructions))
- ), xml_declaration=True, pretty_print=True, encoding='utf-8')
- xml_data += etree.tostring(_to_file(nested_data)[0],
- pretty_print=True, encoding='utf-8')
- with open(xml_file, 'wb') as fp:
- fp.write(xml_data)
-
-
-def _to_file(nested_data):
- """
- Recursively parse the nested data into xml tree format.
-
- Args:
- nested_data: the nested data
-
- Returns:
- the xml tree filled with child nodes
- """
- nodes = list()
- for key, values in six.iteritems(nested_data):
- # Listify the values if not a list
- if not isinstance(values, (list, set, tuple)):
- values = [values]
- for value in values:
- node = etree.Element(key)
- if isinstance(value, (str, six.text_type)):
- node.text = six.text_type(value)
- else:
- node.extend(_to_file(value))
- nodes.append(node)
- return nodes
diff --git a/grc/gui/Application.py b/grc/gui/Application.py
index 2a42a0b345..698f1f109d 100644
--- a/grc/gui/Application.py
+++ b/grc/gui/Application.py
@@ -213,10 +213,6 @@ class Application(Gtk.Application):
main.update_panel_visibility(main.CONSOLE, Actions.TOGGLE_CONSOLE_WINDOW.get_active())
main.update_panel_visibility(main.VARIABLES, Actions.TOGGLE_FLOW_GRAPH_VAR_EDITOR.get_active())
- #if ParseXML.xml_failures:
- # Messages.send_xml_errors_if_any(ParseXML.xml_failures)
- # Actions.XML_PARSER_ERRORS_DISPLAY.set_enabled(True)
-
# Force an update on the current page to match loaded preferences.
# In the future, change the __init__ order to load preferences first
page = main.current_page
@@ -264,132 +260,141 @@ class Application(Gtk.Application):
flow_graph_update()
page.state_cache.save_new_state(flow_graph.export_data())
page.saved = False
- ##################################################
- # Create heir block
- ##################################################
+ ##################################################
+ # Create hier block
+ ##################################################
elif action == Actions.BLOCK_CREATE_HIER:
- # keeping track of coordinates for pasting later
- coords = flow_graph.selected_blocks()[0].coordinate
- x,y = coords
- x_min = x
- y_min = y
-
- pads = [];
- params = [];
-
- # Save the state of the leaf blocks
- for block in flow_graph.selected_blocks():
-
- # Check for string variables within the blocks
- for param in block.params.values():
- for variable in flow_graph.get_variables():
- # If a block parameter exists that is a variable, create a parameter for it
- if param.get_value() == variable.name:
- params.append(param.get_value())
- for flow_param in flow_graph.get_parameters():
- # If a block parameter exists that is a parameter, create a parameter for it
- if param.get_value() == flow_param.name:
- params.append(param.get_value())
-
-
- # keep track of x,y mins for pasting later
- (x,y) = block.coordinate
- if x < x_min:
- x_min = x
- if y < y_min:
- y_min = y
-
- for connection in block.connections:
-
- # Get id of connected blocks
- source_id = connection.source_block.name
- sink_id = connection.sink_block.name
-
- # If connected block is not in the list of selected blocks create a pad for it
- if flow_graph.get_block(source_id) not in flow_graph.selected_blocks():
- pads.append({'key': connection.sink_port.key, 'coord': connection.source_port.coordinate, 'block_id' : block.name, 'direction': 'source'})
-
- if flow_graph.get_block(sink_id) not in flow_graph.selected_blocks():
- pads.append({'key': connection.source_port.key, 'coord': connection.sink_port.coordinate, 'block_id' : block.name, 'direction': 'sink'})
-
-
- # Copy the selected blocks and paste them into a new page
- # then move the flowgraph to a reasonable position
- Actions.BLOCK_COPY()
- main.new_page()
- Actions.BLOCK_PASTE()
- coords = (x_min,y_min)
- flow_graph.move_selected(coords)
+ # keeping track of coordinates for pasting later
+ coords = flow_graph.selected_blocks()[0].coordinate
+ x,y = coords
+ x_min = x
+ y_min = y
+
+ pads = []
+ params = []
+
+ # Save the state of the leaf blocks
+ for block in flow_graph.selected_blocks():
+
+ # Check for string variables within the blocks
+ for param in block.params.values():
+ for variable in flow_graph.get_variables():
+ # If a block parameter exists that is a variable, create a parameter for it
+ if param.get_value() == variable.name:
+ params.append(param.get_value())
+ for flow_param in flow_graph.get_parameters():
+ # If a block parameter exists that is a parameter, create a parameter for it
+ if param.get_value() == flow_param.name:
+ params.append(param.get_value())
+
+ # keep track of x,y mins for pasting later
+ (x,y) = block.coordinate
+ if x < x_min:
+ x_min = x
+ if y < y_min:
+ y_min = y
+
+ for connection in block.connections:
+
+ # Get id of connected blocks
+ source_id = connection.source_block.name
+ sink_id = connection.sink_block.name
+
+ # If connected block is not in the list of selected blocks create a pad for it
+ if flow_graph.get_block(
+ source_id) not in flow_graph.selected_blocks():
+ pads.append({
+ 'key':
+ connection.sink_port.key,
+ 'coord':
+ connection.source_port.coordinate,
+ 'block_id':
+ block.name,
+ 'direction':
+ 'source'
+ })
+
+ if flow_graph.get_block(sink_id) not in flow_graph.selected_blocks():
+ pads.append({'key': connection.source_port.key, 'coord': connection.sink_port.coordinate, 'block_id' : block.name, 'direction': 'sink'})
+
+
+ # Copy the selected blocks and paste them into a new page
+ # then move the flowgraph to a reasonable position
+ Actions.BLOCK_COPY()
+ main.new_page()
+ Actions.BLOCK_PASTE()
+ coords = (x_min,y_min)
+ flow_graph.move_selected(coords)
- # Set flow graph to heir block type
- top_block = flow_graph.get_block("top_block")
- top_block.params['generate_options'].set_value('hb')
+ # Set flow graph to heir block type
+ top_block = flow_graph.get_block("top_block")
+ top_block.params['generate_options'].set_value('hb')
- # this needs to be a unique name
- top_block.params['id'].set_value('new_heir')
+ # this needs to be a unique name
+ top_block.params['id'].set_value('new_heir')
- # Remove the default samp_rate variable block that is created
- remove_me = flow_graph.get_block("samp_rate")
- flow_graph.remove_element(remove_me)
+ # Remove the default samp_rate variable block that is created
+ remove_me = flow_graph.get_block("samp_rate")
+ flow_graph.remove_element(remove_me)
- # Add the param blocks along the top of the window
- x_pos = 150
- for param in params:
- param_id = flow_graph.add_new_block('parameter',(x_pos,10))
- param_block = flow_graph.get_block(param_id)
- param_block.params['id'].set_value(param)
- x_pos = x_pos + 100
+ # Add the param blocks along the top of the window
+ x_pos = 150
+ for param in params:
+ param_id = flow_graph.add_new_block('parameter',(x_pos,10))
+ param_block = flow_graph.get_block(param_id)
+ param_block.params['id'].set_value(param)
+ x_pos = x_pos + 100
- for pad in pads:
- # Add the pad sources and sinks within the new heir block
- if pad['direction'] == 'sink':
+ for pad in pads:
+ # Add the pad sources and sinks within the new heir block
+ if pad['direction'] == 'sink':
- # Add new PAD_SINK block to the canvas
- pad_id = flow_graph.add_new_block('pad_sink', pad['coord'])
+ # Add new PAD_SINK block to the canvas
+ pad_id = flow_graph.add_new_block('pad_sink', pad['coord'])
- # setup the references to the sink and source
- pad_block = flow_graph.get_block(pad_id)
- pad_sink = pad_block.sinks[0]
+ # setup the references to the sink and source
+ pad_block = flow_graph.get_block(pad_id)
+ pad_sink = pad_block.sinks[0]
- source_block = flow_graph.get_block(pad['block_id'])
- source = source_block.get_source(pad['key'])
+ source_block = flow_graph.get_block(pad['block_id'])
+ source = source_block.get_source(pad['key'])
- # Ensure the port types match
- while pad_sink.dtype != source.dtype:
+ # Ensure the port types match
+ while pad_sink.dtype != source.dtype:
- # Special case for some blocks that have non-standard type names, e.g. uhd
- if pad_sink.dtype == 'complex' and source.dtype == 'fc32':
- break;
- pad_block.type_controller_modify(1)
+ # Special case for some blocks that have non-standard type names, e.g. uhd
+ if pad_sink.dtype == 'complex' and source.dtype == 'fc32':
+ break;
+ pad_block.type_controller_modify(1)
- # Connect the pad to the proper sinks
- new_connection = flow_graph.connect(source,pad_sink)
+ # Connect the pad to the proper sinks
+ new_connection = flow_graph.connect(source,pad_sink)
- elif pad['direction'] == 'source':
- pad_id = flow_graph.add_new_block('pad_source', pad['coord'])
+ elif pad['direction'] == 'source':
+ pad_id = flow_graph.add_new_block('pad_source', pad['coord'])
- # setup the references to the sink and source
- pad_block = flow_graph.get_block(pad_id)
- pad_source = pad_block.sources[0]
+ # setup the references to the sink and source
+ pad_block = flow_graph.get_block(pad_id)
+ pad_source = pad_block.sources[0]
- sink_block = flow_graph.get_block(pad['block_id'])
- sink = sink_block.get_sink(pad['key'])
+ sink_block = flow_graph.get_block(pad['block_id'])
+ sink = sink_block.get_sink(pad['key'])
- # Ensure the port types match
- while sink.dtype != pad_source.dtype:
- # Special case for some blocks that have non-standard type names, e.g. uhd
- if pad_source.dtype == 'complex' and sink.dtype == 'fc32':
- break;
- pad_block.type_controller_modify(1)
+ # Ensure the port types match
+ while sink.dtype != pad_source.dtype:
+ # Special case for some blocks that have non-standard type names, e.g. uhd
+ if pad_source.dtype == 'complex' and sink.dtype == 'fc32':
+ break
+ pad_block.type_controller_modify(1)
- # Connect the pad to the proper sinks
- new_connection = flow_graph.connect(pad_source,sink)
+ # Connect the pad to the proper sinks
+ new_connection = flow_graph.connect(pad_source, sink)
- # update the new heir block flow graph
- flow_graph_update()
+ # update the new heir block flow graph
+ flow_graph_update()
##################################################
@@ -575,7 +580,6 @@ class Application(Gtk.Application):
# View Parser Errors
##################################################
elif action == Actions.XML_PARSER_ERRORS_DISPLAY:
- # ParserErrorsDialog(ParseXML.xml_failures).run()
pass
##################################################
# Undo/Redo
@@ -627,7 +631,7 @@ class Application(Gtk.Application):
elif action == Actions.FLOW_GRAPH_OPEN_RECENT:
file_path = str(args[0])[1:-1]
main.new_page(file_path, show=True)
- main.tool_bar.refresh_submenus()
+ main.tool_bar.refresh_submenus()
elif action == Actions.FLOW_GRAPH_SAVE:
#read-only or undefined file path, do save-as
if page.get_read_only() or not page.file_path:
@@ -730,8 +734,6 @@ class Application(Gtk.Application):
main.btwin.repopulate()
#todo: implement parser error dialog for YAML
- #Actions.XML_PARSER_ERRORS_DISPLAY.set_enabled(bool(ParseXML.xml_failures))
- #Messages.send_xml_errors_if_any(ParseXML.xml_failures)
# Force a redraw of the graph, by getting the current state and re-importing it
main.update_pages()
diff --git a/tools/clang_format.py b/tools/clang_format.py
new file mode 100755
index 0000000000..67c4c16ac1
--- /dev/null
+++ b/tools/clang_format.py
@@ -0,0 +1,826 @@
+#!/usr/bin/env python
+# Copyright (C) 2015,2016 MongoDB Inc.
+# Copyright (C) 2018 Free Software Foundation
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License, version 3,
+# as published by the Free Software Foundation.
+#
+# This program 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 Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+"""
+A script that provides:
+1. Validates clang-format is the right version.
+2. Has support for checking which files are to be checked.
+3. Supports validating and updating a set of files to the right coding style.
+"""
+from __future__ import print_function, absolute_import
+
+import queue
+import difflib
+import glob
+import itertools
+import os
+import re
+import subprocess
+from subprocess import check_output, CalledProcessError
+import sys
+import threading
+import time
+from distutils import spawn
+from argparse import ArgumentParser
+from multiprocessing import cpu_count
+
+# Get relative imports to work when
+# the package is not installed on the PYTHONPATH.
+if __name__ == "__main__" and __package__ is None:
+ sys.path.append(
+ os.path.dirname(
+ os.path.dirname(os.path.abspath(os.path.realpath(__file__)))))
+
+##############################################################################
+#
+# Constants for clang-format
+#
+#
+
+# Expected version of clang-format
+CLANG_FORMAT_VERSION = "4.0.1"
+CLANG_FORMAT_SHORT_VERSION = "4.0"
+
+# Name of clang-format as a binary
+CLANG_FORMAT_PROGNAME = "clang-format"
+# only valid c/c++ implementations and headers
+files_match = re.compile('\\.(h|cc|c)$')
+
+##############################################################################
+
+
+def callo(args):
+ """Call a program, and capture its output
+ """
+ return check_output(args).decode('utf-8')
+
+
+class ClangFormat(object):
+ """Class encapsulates finding a suitable copy of clang-format,
+ and linting/formating an individual file
+ """
+
+ def __init__(self, path):
+ self.path = None
+ clang_format_progname_ext = ""
+
+ if sys.platform == "win32":
+ clang_format_progname_ext += ".exe"
+
+ # Check the clang-format the user specified
+ if path is not None:
+ if os.path.isfile(path):
+ self.path = path
+ else:
+ print("WARNING: Could not find clang-format %s" % (path))
+
+ # Check the users' PATH environment variable now
+ if self.path is None:
+ # Check for various versions staring with binaries with version specific suffixes in the
+ # user's path
+ programs = [
+ CLANG_FORMAT_PROGNAME + "-" + CLANG_FORMAT_VERSION,
+ CLANG_FORMAT_PROGNAME + "-" + CLANG_FORMAT_SHORT_VERSION,
+ CLANG_FORMAT_PROGNAME,
+ ]
+
+ if sys.platform == "win32":
+ for i in range(len(programs)):
+ programs[i] += '.exe'
+
+ for program in programs:
+ self.path = spawn.find_executable(program)
+
+ if self.path:
+ if not self._validate_version():
+ self.path = None
+ else:
+ break
+
+ # If Windows, try to grab it from Program Files
+ # Check both native Program Files and WOW64 version
+ if sys.platform == "win32":
+ programfiles = [
+ os.environ["ProgramFiles"],
+ os.environ["ProgramFiles(x86)"],
+ ]
+
+ for programfile in programfiles:
+ win32bin = os.path.join(programfile,
+ "LLVM\\bin\\clang-format.exe")
+ if os.path.exists(win32bin):
+ self.path = win32bin
+ break
+
+ if self.path is None or not os.path.isfile(
+ self.path) or not self._validate_version():
+ print(
+ "ERROR:clang-format not found in $PATH, please install clang-format "
+ + CLANG_FORMAT_VERSION)
+ raise NameError("No suitable clang-format found")
+ self.print_lock = threading.Lock()
+
+ def _validate_version(self):
+ """Validate clang-format is the expected version
+ """
+ cf_version = callo([self.path, "--version"])
+
+ if CLANG_FORMAT_VERSION in cf_version:
+ return True
+
+ print(
+ "WARNING: clang-format found in path, but incorrect version found at "
+ + self.path + " with version: " + cf_version)
+
+ return False
+
+ def _lint(self, file_name, print_diff):
+ """Check the specified file has the correct format
+ """
+ with open(file_name, 'rb') as original_text:
+ original_file = original_text.read().decode("utf-8")
+
+ # Get formatted file as clang-format would format the file
+ formatted_file = callo([self.path, "--style=file", file_name])
+
+ if original_file != formatted_file:
+ if print_diff:
+ original_lines = original_file.splitlines()
+ formatted_lines = formatted_file.splitlines()
+ result = difflib.unified_diff(original_lines, formatted_lines)
+
+ # Take a lock to ensure diffs do not get mixed when printed to the screen
+ with self.print_lock:
+ print("ERROR: Found diff for " + file_name)
+ print("To fix formatting errors, run %s --style=file -i %s"
+ % (self.path, file_name))
+ for line in result:
+ print(line.rstrip())
+
+ return False
+
+ return True
+
+ def lint(self, file_name):
+ """Check the specified file has the correct format
+ """
+ return self._lint(file_name, print_diff=True)
+
+ def format(self, file_name):
+ """Update the format of the specified file
+ """
+ if self._lint(file_name, print_diff=False):
+ return True
+
+ # Update the file with clang-format
+ formatted = not subprocess.call(
+ [self.path, "--style=file", "-i", file_name])
+
+ # Version 3.8 generates files like foo.cpp~RF83372177.TMP when it formats foo.cpp
+ # on Windows, we must clean these up
+ if sys.platform == "win32":
+ glob_pattern = file_name + "*.TMP"
+ for fglob in glob.glob(glob_pattern):
+ os.unlink(fglob)
+
+ return formatted
+
+
+def parallel_process(items, func):
+ """Run a set of work items to completion
+ """
+ try:
+ cpus = cpu_count()
+ except NotImplementedError:
+ cpus = 1
+
+ task_queue = queue.Queue()
+
+ # Use a list so that worker function will capture this variable
+ pp_event = threading.Event()
+ pp_result = [True]
+
+ def worker():
+ """Worker thread to process work items in parallel
+ """
+ while not pp_event.is_set():
+ try:
+ item = task_queue.get_nowait()
+ except queue.Empty:
+ # if the queue is empty, exit the worker thread
+ pp_event.set()
+ return
+
+ try:
+ ret = func(item)
+ finally:
+ # Tell the queue we finished with the item
+ task_queue.task_done()
+
+ # Return early if we fail, and signal we are done
+ if not ret:
+ # with pp_lock:
+ # pp_result[0] = False
+ print("{} failed on item {}".format(func, item))
+
+ # pp_event.set()
+ return
+
+ # Enqueue all the work we want to process
+ for item in items:
+ task_queue.put(item)
+
+ # Process all the work
+ threads = []
+ for cpu in range(cpus):
+ thread = threading.Thread(target=worker)
+
+ thread.daemon = True
+ thread.start()
+ threads.append(thread)
+
+ # Wait for the threads to finish
+ # Loop with a timeout so that we can process Ctrl-C interrupts
+ # Note: On Python 2.6 wait always returns None so we check is_set also,
+ # This works because we only set the event once, and never reset it
+ while not pp_event.wait(1) and not pp_event.is_set():
+ time.sleep(1)
+
+ for thread in threads:
+ thread.join()
+
+ return pp_result[0]
+
+
+def get_base_dir():
+ """Get the base directory for mongo repo.
+ This script assumes that it is running in buildscripts/, and uses
+ that to find the base directory.
+ """
+ try:
+ return subprocess.check_output(
+ ['git', 'rev-parse', '--show-toplevel']).rstrip().decode('utf-8')
+ except CalledProcessError:
+ # We are not in a valid git directory. Use the script path instead.
+ return os.path.dirname(os.path.dirname(os.path.realpath(__file__)))
+
+
+def get_repos():
+ """Get a list of Repos to check clang-format for
+ """
+ base_dir = get_base_dir()
+
+ # Get a list of modules
+ # GNU Radio is a single-git repo
+
+ # paths = [os.path.join(base_dir, MODULE_DIR, m) for m in gnuradio_modules]
+
+ paths = [base_dir]
+
+ return [Repo(p) for p in paths]
+
+
+class Repo(object):
+ """Class encapsulates all knowledge about a git repository, and its metadata
+ to run clang-format.
+ """
+
+ def __init__(self, path):
+ self.path = path
+
+ self.root = self._get_root()
+
+ def _callgito(self, args):
+ """Call git for this repository, and return the captured output
+ """
+ # These two flags are the equivalent of -C in newer versions of Git
+ # but we use these to support versions pre 1.8.5 but it depends on the command
+ # and what the current directory is
+ return callo([
+ 'git', '--git-dir', os.path.join(self.path, ".git"), '--work-tree',
+ self.path
+ ] + args)
+
+ def _callgit(self, args):
+ """Call git for this repository without capturing output
+ This is designed to be used when git returns non-zero exit codes.
+ """
+ # These two flags are the equivalent of -C in newer versions of Git
+ # but we use these to support versions pre 1.8.5 but it depends on the command
+ # and what the current directory is
+ return subprocess.call([
+ 'git', '--git-dir', os.path.join(self.path, ".git"), '--work-tree',
+ self.path
+ ] + args)
+
+ def _get_local_dir(self, path):
+ """Get a directory path relative to the git root directory
+ """
+ if os.path.isabs(path):
+ return os.path.relpath(path, self.root)
+ return path
+
+ def get_candidates(self, candidates):
+ """Get the set of candidate files to check by querying the repository
+
+ Returns the full path to the file for clang-format to consume.
+ """
+ if candidates is not None and len(candidates) > 0:
+ candidates = [self._get_local_dir(f) for f in candidates]
+ valid_files = list(
+ set(candidates).intersection(self.get_candidate_files()))
+ else:
+ valid_files = list(self.get_candidate_files())
+
+ # Get the full file name here
+ valid_files = [
+ os.path.normpath(os.path.join(self.root, f)) for f in valid_files
+ ]
+
+ return valid_files
+
+ def get_root(self):
+ """Get the root directory for this repository
+ """
+ return self.root
+
+ def _get_root(self):
+ """Gets the root directory for this repository from git
+ """
+ gito = self._callgito(['rev-parse', '--show-toplevel'])
+
+ return gito.rstrip()
+
+ def _git_ls_files(self, cmd):
+ """Run git-ls-files and filter the list of files to a valid candidate list
+ """
+ gito = self._callgito(cmd)
+
+ # This allows us to pick all the interesting files
+ # in the mongo and mongo-enterprise repos
+ file_list = [
+ line.rstrip()
+ for line in gito.splitlines()
+ # TODO: exclude directories if needed
+ # We don't want to lint volk
+ if not "volk" in line
+ ]
+
+ file_list = [a for a in file_list if files_match.search(a)]
+
+ return file_list
+
+ def get_candidate_files(self):
+ """Query git to get a list of all files in the repo to consider for analysis
+ """
+ return self._git_ls_files(["ls-files", "--cached"])
+
+ def get_working_tree_candidate_files(self):
+ """Query git to get a list of all files in the working tree to consider for analysis
+ """
+ return self._git_ls_files(["ls-files", "--cached", "--others"])
+
+ def get_working_tree_candidates(self):
+ """Get the set of candidate files to check by querying the repository
+
+ Returns the full path to the file for clang-format to consume.
+ """
+ valid_files = list(self.get_working_tree_candidate_files())
+
+ # Get the full file name here
+ valid_files = [
+ os.path.normpath(os.path.join(self.root, f)) for f in valid_files
+ ]
+
+ return valid_files
+
+ def is_detached(self):
+ """Is the current working tree in a detached HEAD state?
+ """
+ # symbolic-ref returns 1 if the repo is in a detached HEAD state
+ return self._callgit(["symbolic-ref", "--quiet", "HEAD"])
+
+ def is_ancestor(self, parent, child):
+ """Is the specified parent hash an ancestor of child hash?
+ """
+ # merge base returns 0 if parent is an ancestor of child
+ return not self._callgit(
+ ["merge-base", "--is-ancestor", parent, child])
+
+ def is_commit(self, sha1):
+ """Is the specified hash a valid git commit?
+ """
+ # cat-file -e returns 0 if it is a valid hash
+ return not self._callgit(["cat-file", "-e", "%s^{commit}" % sha1])
+
+ def is_working_tree_dirty(self):
+ """Does the current working tree have changes?
+ """
+ # diff returns 1 if the working tree has local changes
+ return self._callgit(["diff", "--quiet"])
+
+ def does_branch_exist(self, branch):
+ """Does the branch exist?
+ """
+ # rev-parse returns 0 if the branch exists
+ return not self._callgit(["rev-parse", "--verify", branch])
+
+ def get_merge_base(self, commit):
+ """Get the merge base between 'commit' and HEAD
+ """
+ return self._callgito(["merge-base", "HEAD", commit]).rstrip()
+
+ def get_branch_name(self):
+ """Get the current branch name, short form
+ This returns "master", not "refs/head/master"
+ Will not work if the current branch is detached
+ """
+ branch = self.rev_parse(["--abbrev-ref", "HEAD"])
+ if branch == "HEAD":
+ raise ValueError("Branch is currently detached")
+
+ return branch
+
+ def add(self, command):
+ """git add wrapper
+ """
+ return self._callgito(["add"] + command)
+
+ def checkout(self, command):
+ """git checkout wrapper
+ """
+ return self._callgito(["checkout"] + command)
+
+ def commit(self, command):
+ """git commit wrapper
+ """
+ return self._callgito(["commit"] + command)
+
+ def diff(self, command):
+ """git diff wrapper
+ """
+ return self._callgito(["diff"] + command)
+
+ def log(self, command):
+ """git log wrapper
+ """
+ return self._callgito(["log"] + command)
+
+ def rev_parse(self, command):
+ """git rev-parse wrapper
+ """
+ return self._callgito(["rev-parse"] + command).rstrip()
+
+ def rm(self, command):
+ """git rm wrapper
+ """
+ return self._callgito(["rm"] + command)
+
+ def show(self, command):
+ """git show wrapper
+ """
+ return self._callgito(["show"] + command)
+
+
+def get_list_from_lines(lines):
+ """"Convert a string containing a series of lines into a list of strings
+ """
+ return [line.rstrip() for line in lines.splitlines()]
+
+
+def get_files_to_check_working_tree():
+ """Get a list of files to check form the working tree.
+ This will pick up files not managed by git.
+ """
+ repos = get_repos()
+
+ valid_files = list(
+ itertools.chain.from_iterable(
+ [r.get_working_tree_candidates() for r in repos]))
+ return valid_files
+
+
+def get_files_to_check():
+ """Get a list of files that need to be checked
+ based on which files are managed by git.
+ """
+ repos = get_repos()
+
+ valid_files = list(
+ itertools.chain.from_iterable([r.get_candidates(None) for r in repos]))
+
+ return valid_files
+
+
+def get_files_to_check_from_patch(patches):
+ """
+ Take a patch file generated by git diff,
+ and scan the patch for a list of files to check.
+ """
+ candidates = []
+
+ # Get a list of candidate_files
+ check = re.compile(
+ r"^diff --git a\/([a-z\/\.\-_0-9]+) b\/[a-z\/\.\-_0-9]+")
+
+ candidates = []
+ for patch in patches:
+ if patch == "-":
+ infile = sys.stdin
+ else:
+ infile = open(patch, "rb")
+ candidates.extend([
+ check.match(line).group(1) for line in infile.readlines()
+ if check.match(line)
+ ])
+ infile.close()
+
+ repos = get_repos()
+
+ valid_files = list(
+ itertools.chain.from_iterable(
+ [r.get_candidates(candidates) for r in repos]))
+
+ return valid_files
+
+
+def _lint_files(clang_format, files):
+ """Lint a list of files with clang-format
+ """
+ try:
+ clang_format = ClangFormat(clang_format)
+ except NameError as e:
+ print(e)
+ return False
+
+ lint_clean = parallel_process([os.path.abspath(f) for f in files],
+ clang_format.lint)
+
+ if not lint_clean:
+ print("ERROR: Code Style does not match coding style")
+ sys.exit(1)
+
+
+def lint(args):
+ """Lint files command entry point
+ """
+ if args.patch and args.all:
+ print("Only specify patch or all, but not both!")
+ return False
+ if args.patch:
+ files = get_files_to_check_from_patch(args.patch)
+ elif args.all:
+ files = get_files_to_check_working_tree()
+ else:
+ files = get_files_to_check()
+
+ if files:
+ _lint_files(args.clang_format, files)
+
+ return True
+
+
+def _format_files(clang_format, files):
+ """Format a list of files with clang-format
+ """
+ try:
+ clang_format = ClangFormat(clang_format)
+ except NameError as e:
+ print(e)
+ return (False)
+
+ format_clean = parallel_process([os.path.abspath(f) for f in files],
+ clang_format.format)
+
+ if not format_clean:
+ print("ERROR: failed to format files")
+ sys.exit(1)
+
+
+def _reformat_branch(clang_format, commit_prior_to_reformat,
+ commit_after_reformat):
+ """Reformat a branch made before a clang-format run
+ """
+ try:
+ clang_format = ClangFormat(clang_format)
+ except NameError as e:
+ print(e)
+ return False
+
+ if os.getcwd() != get_base_dir():
+ raise ValueError("reformat-branch must be run from the repo root")
+
+ repo = Repo(get_base_dir())
+
+ # Validate that user passes valid commits
+ if not repo.is_commit(commit_prior_to_reformat):
+ raise ValueError(
+ "Commit Prior to Reformat '%s' is not a valid commit in this repo"
+ % commit_prior_to_reformat)
+
+ if not repo.is_commit(commit_after_reformat):
+ raise ValueError(
+ "Commit After Reformat '%s' is not a valid commit in this repo" %
+ commit_after_reformat)
+
+ if not repo.is_ancestor(commit_prior_to_reformat, commit_after_reformat):
+ raise ValueError((
+ "Commit Prior to Reformat '%s' is not a valid ancestor of Commit After"
+ + " Reformat '%s' in this repo") % (commit_prior_to_reformat,
+ commit_after_reformat))
+
+ # Validate the user is on a local branch that has the right merge base
+ if repo.is_detached():
+ raise ValueError(
+ "You must not run this script in a detached HEAD state")
+
+ # Validate the user has no pending changes
+ if repo.is_working_tree_dirty():
+ raise ValueError(
+ "Your working tree has pending changes. You must have a clean working tree before proceeding."
+ )
+
+ merge_base = repo.get_merge_base(commit_prior_to_reformat)
+
+ if not merge_base == commit_prior_to_reformat:
+ raise ValueError(
+ "Please rebase to '%s' and resolve all conflicts before running this script"
+ % (commit_prior_to_reformat))
+
+ # We assume the target branch is master, it could be a different branch if needed for testing
+ merge_base = repo.get_merge_base("master")
+
+ if not merge_base == commit_prior_to_reformat:
+ raise ValueError(
+ "This branch appears to already have advanced too far through the merge process"
+ )
+
+ # Everything looks good so lets start going through all the commits
+ branch_name = repo.get_branch_name()
+ new_branch = "%s-reformatted" % branch_name
+
+ if repo.does_branch_exist(new_branch):
+ raise ValueError(
+ "The branch '%s' already exists. Please delete the branch '%s', or rename the current branch."
+ % (new_branch, new_branch))
+
+ commits = get_list_from_lines(
+ repo.log([
+ "--reverse", "--pretty=format:%H", "%s..HEAD" %
+ commit_prior_to_reformat
+ ]))
+
+ previous_commit_base = commit_after_reformat
+
+ # Go through all the commits the user made on the local branch and migrate to a new branch
+ # that is based on post_reformat commits instead
+ for commit_hash in commits:
+ repo.checkout(["--quiet", commit_hash])
+
+ deleted_files = []
+
+ # Format each of the files by checking out just a single commit from the user's branch
+ commit_files = get_list_from_lines(repo.diff(["HEAD~", "--name-only"]))
+
+ for commit_file in commit_files:
+
+ # Format each file needed if it was not deleted
+ if not os.path.exists(commit_file):
+ print(
+ "Skipping file '%s' since it has been deleted in commit '%s'"
+ % (commit_file, commit_hash))
+ deleted_files.append(commit_file)
+ continue
+
+ if files_match.search(commit_file):
+ clang_format.format(commit_file)
+ else:
+ print(
+ "Skipping file '%s' since it is not a file clang_format should format"
+ % commit_file)
+
+ # Check if anything needed reformatting, and if so amend the commit
+ if not repo.is_working_tree_dirty():
+ print("Commit %s needed no reformatting" % commit_hash)
+ else:
+ repo.commit(["--all", "--amend", "--no-edit"])
+
+ # Rebase our new commit on top the post-reformat commit
+ previous_commit = repo.rev_parse(["HEAD"])
+
+ # Checkout the new branch with the reformatted commits
+ # Note: we will not name as a branch until we are done with all commits on the local branch
+ repo.checkout(["--quiet", previous_commit_base])
+
+ # Copy each file from the reformatted commit on top of the post reformat
+ diff_files = get_list_from_lines(
+ repo.diff([
+ "%s~..%s" % (previous_commit, previous_commit), "--name-only"
+ ]))
+
+ for diff_file in diff_files:
+ # If the file was deleted in the commit we are reformatting, we need to delete it again
+ if diff_file in deleted_files:
+ repo.rm([diff_file])
+ continue
+
+ if "volk" in diff_file:
+ continue
+ # The file has been added or modified, continue as normal
+ file_contents = repo.show(["%s:%s" % (previous_commit, diff_file)])
+
+ root_dir = os.path.dirname(diff_file)
+ if root_dir and not os.path.exists(root_dir):
+ os.makedirs(root_dir)
+
+ with open(diff_file, "w+") as new_file:
+ new_file.write(file_contents)
+
+ repo.add([diff_file])
+
+ # Create a new commit onto clang-formatted branch
+ repo.commit(["--reuse-message=%s" % previous_commit])
+
+ previous_commit_base = repo.rev_parse(["HEAD"])
+
+ # Create a new branch to mark the hashes we have been using
+ repo.checkout(["-b", new_branch])
+
+ print("reformat-branch is done running.\n")
+ print(
+ "A copy of your branch has been made named '%s', and formatted with clang-format.\n"
+ % new_branch)
+ print("The original branch has been left unchanged.")
+ print("The next step is to rebase the new branch on 'master'.")
+
+
+def format_func(args):
+ """Format files command entry point
+ """
+ if args.all and args.branch is not None:
+ print("Only specify branch or all, but not both!")
+ return False
+ if not args.branch:
+ if args.all:
+ files = get_files_to_check_working_tree()
+ else:
+ files = get_files_to_check()
+ _format_files(args.clang_format, files)
+ else:
+ _reformat_branch(args.clang_format, *args.branch)
+
+
+def parse_args():
+ """
+ Parse commandline arguments
+ """
+ parser = ArgumentParser()
+ parser.add_argument(
+ "-c",
+ "--clang-format",
+ default="clang-format",
+ help="clang-format binary")
+ subparsers = parser.add_subparsers(help="clang-format action", dest="action")
+ subparsers.required = True
+ lint_parser = subparsers.add_parser(
+ "lint", help="Lint-only (no modifications)")
+ lint_parser.add_argument("-a", "--all", action="store_true")
+ lint_parser.add_argument("-p", "--patch", help="patch to check")
+ lint_parser.set_defaults(func=lint)
+
+ format_parser = subparsers.add_parser(
+ "format", help="Format files in place")
+ format_parser.add_argument(
+ "-b",
+ "--branch",
+ nargs=2,
+ default=None,
+ help="specify the commit hash before the format and after the format has been done"
+ )
+ format_parser.add_argument("-a", "--all", action="store_true")
+ format_parser.set_defaults(func=format_func)
+ return parser.parse_args()
+
+
+def main():
+ """Main entry point
+ """
+ args = parse_args()
+ if hasattr(args, "func"):
+ args.func(args)
+
+
+if __name__ == "__main__":
+ main()