summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--config/grc_gr_qtgui.m412
-rw-r--r--config/grc_gr_uhd.m42
-rw-r--r--config/grc_grc.m411
-rw-r--r--config/grc_volk.m418
-rw-r--r--config/usrp_sdcc.m42
-rw-r--r--gnuradio-core/src/lib/filter/Makefile.am10
-rw-r--r--gnuradio-core/src/lib/filter/filter.i4
-rw-r--r--gnuradio-core/src/lib/filter/gr_dc_blocker_cc.cc138
-rw-r--r--gnuradio-core/src/lib/filter/gr_dc_blocker_cc.h111
-rw-r--r--gnuradio-core/src/lib/filter/gr_dc_blocker_cc.i34
-rw-r--r--gnuradio-core/src/lib/filter/gr_dc_blocker_ff.cc138
-rw-r--r--gnuradio-core/src/lib/filter/gr_dc_blocker_ff.h111
-rw-r--r--gnuradio-core/src/lib/filter/gr_dc_blocker_ff.i34
-rw-r--r--gnuradio-core/src/lib/general/gr_frequency_modulator_fc.h4
-rw-r--r--gnuradio-core/src/lib/general/gr_frequency_modulator_fc.i3
-rw-r--r--gnuradio-core/src/python/gnuradio/gr/Makefile.am1
-rwxr-xr-xgnuradio-core/src/python/gnuradio/gr/qa_dc_blocker.py108
-rw-r--r--gnuradio-examples/grc/Makefile.am3
-rw-r--r--gnuradio-examples/grc/simple/var_sink_taps.grc488
-rwxr-xr-xgnuradio-examples/python/usrp2/usrp2_wfm_rcv.py3
-rw-r--r--gr-audio/include/gr_audio_api.h6
-rw-r--r--gr-qtgui/apps/Makefile.am1
-rwxr-xr-xgr-qtgui/apps/pyqt_example_c.py3
-rwxr-xr-xgr-qtgui/apps/pyqt_example_f.py12
-rwxr-xr-xgr-qtgui/apps/pyqt_time_c.py163
-rwxr-xr-xgr-qtgui/apps/pyqt_time_f.py163
-rwxr-xr-xgr-qtgui/apps/qt_digital.py1
-rw-r--r--gr-qtgui/grc/Makefile.am1
-rw-r--r--gr-qtgui/grc/qtgui_time_sink_x.xml78
-rw-r--r--gr-qtgui/lib/ConstellationDisplayPlot.cc30
-rw-r--r--gr-qtgui/lib/ConstellationDisplayPlot.h27
-rw-r--r--gr-qtgui/lib/FrequencyDisplayPlot.cc28
-rw-r--r--gr-qtgui/lib/FrequencyDisplayPlot.h26
-rw-r--r--gr-qtgui/lib/Makefile.am12
-rw-r--r--gr-qtgui/lib/SpectrumGUIClass.cc44
-rw-r--r--gr-qtgui/lib/SpectrumGUIClass.h30
-rw-r--r--gr-qtgui/lib/TimeDomainDisplayPlot.cc141
-rw-r--r--gr-qtgui/lib/TimeDomainDisplayPlot.h47
-rw-r--r--gr-qtgui/lib/WaterfallDisplayPlot.cc81
-rw-r--r--gr-qtgui/lib/WaterfallDisplayPlot.h28
-rw-r--r--gr-qtgui/lib/gr_qtgui_api.h33
-rw-r--r--gr-qtgui/lib/highResTimeFunctions.h315
-rw-r--r--gr-qtgui/lib/qtgui_sink_c.cc2
-rw-r--r--gr-qtgui/lib/qtgui_sink_c.h7
-rw-r--r--gr-qtgui/lib/qtgui_sink_f.cc2
-rw-r--r--gr-qtgui/lib/qtgui_sink_f.h7
-rw-r--r--gr-qtgui/lib/qtgui_time_sink_c.cc199
-rw-r--r--gr-qtgui/lib/qtgui_time_sink_c.h93
-rw-r--r--gr-qtgui/lib/qtgui_time_sink_f.cc197
-rw-r--r--gr-qtgui/lib/qtgui_time_sink_f.h93
-rw-r--r--gr-qtgui/lib/qtgui_util.h6
-rw-r--r--gr-qtgui/lib/spectrumUpdateEvents.cc51
-rw-r--r--gr-qtgui/lib/spectrumUpdateEvents.h38
-rw-r--r--gr-qtgui/lib/spectrumdisplayform.cc46
-rw-r--r--gr-qtgui/lib/spectrumdisplayform.h22
-rw-r--r--gr-qtgui/lib/timedisplayform.cc177
-rw-r--r--gr-qtgui/lib/timedisplayform.h85
-rw-r--r--gr-qtgui/swig/Makefile.am5
-rw-r--r--gr-qtgui/swig/qtgui_sink_c.i (renamed from gr-qtgui/swig/qtgui.i)47
-rw-r--r--gr-qtgui/swig/qtgui_sink_f.i66
-rw-r--r--gr-qtgui/swig/qtgui_swig.i9
-rw-r--r--gr-qtgui/swig/qtgui_time_sink_c.i56
-rw-r--r--gr-qtgui/swig/qtgui_time_sink_f.i56
-rw-r--r--gr-trellis/doc/gr-trellis.xml34
-rw-r--r--gr-trellis/src/examples/Makefile.am2
-rw-r--r--gr-trellis/src/examples/README24
-rwxr-xr-xgr-trellis/src/examples/test_pccc_turbo1.py119
-rwxr-xr-xgr-trellis/src/examples/test_sccc_hard.py1
-rwxr-xr-xgr-trellis/src/examples/test_sccc_soft.py1
-rwxr-xr-xgr-trellis/src/examples/test_sccc_turbo.py9
-rwxr-xr-xgr-trellis/src/examples/test_sccc_turbo1.py (renamed from gr-trellis/src/examples/test_tcm2.py)75
-rwxr-xr-xgr-trellis/src/examples/test_sccc_turbo2.py101
-rwxr-xr-xgr-trellis/src/examples/test_tcm.py30
-rwxr-xr-xgr-trellis/src/examples/test_tcm_bit.py (renamed from gr-trellis/src/examples/test_tcm1.py)32
-rwxr-xr-xgr-trellis/src/examples/test_tcm_combined.py29
-rwxr-xr-xgr-trellis/src/examples/test_tcm_parallel.py29
-rwxr-xr-xgr-trellis/src/examples/test_turbo_equalization.py1
-rwxr-xr-xgr-trellis/src/examples/test_turbo_equalization1.py1
-rwxr-xr-xgr-trellis/src/examples/test_turbo_equalization2.py1
-rwxr-xr-xgr-trellis/src/examples/test_viterbi_equalization.py1
-rwxr-xr-xgr-trellis/src/examples/test_viterbi_equalization1.py1
-rw-r--r--gr-trellis/src/lib/.gitignore72
-rw-r--r--gr-trellis/src/lib/Makefile.am25
-rw-r--r--gr-trellis/src/lib/Makefile.gen72
-rw-r--r--gr-trellis/src/lib/calc_metric.cc (renamed from gr-trellis/src/lib/trellis_calc_metric.cc)2
-rw-r--r--gr-trellis/src/lib/calc_metric.h (renamed from gr-trellis/src/lib/trellis_calc_metric.h)6
-rw-r--r--gr-trellis/src/lib/core_algorithms.cc1239
-rw-r--r--gr-trellis/src/lib/core_algorithms.h128
-rw-r--r--gr-trellis/src/lib/generate_trellis.py10
-rw-r--r--gr-trellis/src/lib/interleaver.cc2
-rw-r--r--gr-trellis/src/lib/metric_type.h (renamed from gr-trellis/src/lib/trellis_metric_type.h)0
-rw-r--r--gr-trellis/src/lib/siso_type.h (renamed from gr-trellis/src/lib/trellis_siso_type.h)0
-rw-r--r--gr-trellis/src/lib/trellis.i4
-rw-r--r--gr-trellis/src/lib/trellis_metrics_X.cc.t2
-rw-r--r--gr-trellis/src/lib/trellis_metrics_X.h.t2
-rw-r--r--gr-trellis/src/lib/trellis_pccc_decoder_X.cc.t124
-rw-r--r--gr-trellis/src/lib/trellis_pccc_decoder_X.h.t102
-rw-r--r--gr-trellis/src/lib/trellis_pccc_decoder_X.i.t60
-rw-r--r--gr-trellis/src/lib/trellis_pccc_encoder_XX.cc.t90
-rw-r--r--gr-trellis/src/lib/trellis_pccc_encoder_XX.h.t83
-rw-r--r--gr-trellis/src/lib/trellis_pccc_encoder_XX.i.t50
-rw-r--r--gr-trellis/src/lib/trellis_sccc_decoder_X.cc.t124
-rw-r--r--gr-trellis/src/lib/trellis_sccc_decoder_X.h.t102
-rw-r--r--gr-trellis/src/lib/trellis_sccc_decoder_X.i.t60
-rw-r--r--gr-trellis/src/lib/trellis_sccc_decoder_combined_XX.cc.t147
-rw-r--r--gr-trellis/src/lib/trellis_sccc_decoder_combined_XX.h.t124
-rw-r--r--gr-trellis/src/lib/trellis_sccc_decoder_combined_XX.i.t73
-rw-r--r--gr-trellis/src/lib/trellis_sccc_encoder_XX.cc.t91
-rw-r--r--gr-trellis/src/lib/trellis_sccc_encoder_XX.h.t83
-rw-r--r--gr-trellis/src/lib/trellis_sccc_encoder_XX.i.t50
-rw-r--r--gr-trellis/src/lib/trellis_siso_combined_f.cc9
-rw-r--r--gr-trellis/src/lib/trellis_siso_combined_f.h5
-rw-r--r--gr-trellis/src/lib/trellis_siso_f.cc7
-rw-r--r--gr-trellis/src/lib/trellis_siso_f.h3
-rw-r--r--gr-trellis/src/lib/trellis_viterbi_X.cc.t15
-rw-r--r--gr-trellis/src/lib/trellis_viterbi_X.h.t9
-rw-r--r--gr-trellis/src/lib/trellis_viterbi_combined_XX.cc.t3
-rw-r--r--gr-trellis/src/lib/trellis_viterbi_combined_XX.h.t3
-rw-r--r--gr-uhd/Makefile.am4
-rw-r--r--gr-uhd/apps/.gitignore3
-rw-r--r--gr-uhd/apps/Makefile.am32
-rwxr-xr-xgr-uhd/apps/uhd_fft.py267
-rwxr-xr-xgr-uhd/apps/uhd_rx_cfile.py149
-rw-r--r--gr-uhd/gnuradio-uhd.pc.in11
-rw-r--r--gr-uhd/grc/gen_uhd_usrp_blocks.py2
-rw-r--r--gr-uhd/include/gr_uhd_usrp_sink.h32
-rw-r--r--gr-uhd/include/gr_uhd_usrp_source.h32
-rw-r--r--gr-uhd/lib/gr_uhd_usrp_sink.cc16
-rw-r--r--gr-uhd/lib/gr_uhd_usrp_source.cc16
-rw-r--r--gr-uhd/swig/uhd_swig.i3
-rwxr-xr-xgr-utils/src/python/gr_plot_psd.py30
-rw-r--r--grc/Makefile.am1
-rw-r--r--grc/base/Block.py14
-rw-r--r--grc/base/Connection.py12
-rw-r--r--grc/base/FlowGraph.py20
-rw-r--r--grc/base/Param.py30
-rw-r--r--grc/base/Platform.py21
-rw-r--r--grc/base/Port.py6
-rw-r--r--grc/base/odict.py8
-rw-r--r--grc/blocks/Makefile.am1
-rw-r--r--grc/blocks/block_tree.xml1
-rw-r--r--grc/blocks/gr_dc_blocker.xml51
-rw-r--r--grc/blocks/gr_frequency_modulator_fc.xml1
-rw-r--r--grc/grc.conf.in1
-rw-r--r--grc/gui/ActionHandler.py5
-rw-r--r--grc/gui/Actions.py5
-rw-r--r--grc/gui/FlowGraph.py10
-rw-r--r--grc/gui/Utils.py5
-rw-r--r--grc/python/Block.py13
-rw-r--r--grc/python/Connection.py6
-rw-r--r--grc/python/Constants.py6
-rw-r--r--grc/python/FlowGraph.py31
-rw-r--r--grc/python/Generator.py21
-rw-r--r--grc/python/Param.py75
-rw-r--r--grc/python/Platform.py4
-rw-r--r--grc/python/Port.py21
-rw-r--r--grc/python/convert_hier.py14
-rw-r--r--grc/python/expr_utils.py6
-rw-r--r--grc/python/extract_docs.py6
-rw-r--r--grc/python/flow_graph.tmpl16
-rw-r--r--gruel/src/include/gruel/Makefile.am1
-rw-r--r--gruel/src/include/gruel/high_res_timer.h124
-rw-r--r--gruel/src/python/Makefile.am4
-rw-r--r--gruel/src/python/__init__.py2
-rw-r--r--gruel/src/python/pmt/__init__.py25
165 files changed, 7031 insertions, 1374 deletions
diff --git a/config/grc_gr_qtgui.m4 b/config/grc_gr_qtgui.m4
index a4592fa41..ddb7c7ca9 100644
--- a/config/grc_gr_qtgui.m4
+++ b/config/grc_gr_qtgui.m4
@@ -47,12 +47,12 @@ AC_DEFUN([GRC_GR_QTGUI],[
if test $passed = yes; then
dnl Check for package qt or qt-mt, set QT_CFLAGS and QT_LIBS
- PKG_CHECK_MODULES(QTCORE, QtCore >= 4.2, [],
- [passed=no; AC_MSG_RESULT([gr-qtgui requires libQtCore >= 4.2.])])
- PKG_CHECK_MODULES(QTGUI, QtGui >= 4.2, [],
- [passed=no; AC_MSG_RESULT([gr-qtgui requires libQtGui >= 4.2.])])
- PKG_CHECK_MODULES(QTOPENGL, QtOpenGL >= 4.2, [],
- [passed=no; AC_MSG_RESULT([gr-qtgui requires libQtOpenGL >- 4.2.])])
+ PKG_CHECK_MODULES(QTCORE, QtCore >= 4.4, [],
+ [passed=no; AC_MSG_RESULT([gr-qtgui requires libQtCore >= 4.4.])])
+ PKG_CHECK_MODULES(QTGUI, QtGui >= 4.4, [],
+ [passed=no; AC_MSG_RESULT([gr-qtgui requires libQtGui >= 4..])])
+ PKG_CHECK_MODULES(QTOPENGL, QtOpenGL >= 4.4, [],
+ [passed=no; AC_MSG_RESULT([gr-qtgui requires libQtOpenGL >- 4.4.])])
dnl Fetch QWT variables
GR_QWT([], [passed=no])
diff --git a/config/grc_gr_uhd.m4 b/config/grc_gr_uhd.m4
index 3cc9691e5..111b0ae43 100644
--- a/config/grc_gr_uhd.m4
+++ b/config/grc_gr_uhd.m4
@@ -40,6 +40,7 @@ AC_DEFUN([GRC_GR_UHD],[
AM_CONDITIONAL([GR_DEFINE_HAVE_UHD],[test $passed = yes])
AC_CONFIG_FILES([ \
+ gr-uhd/gnuradio-uhd.pc \
gr-uhd/Makefile \
gr-uhd/grc/Makefile \
gr-uhd/include/Makefile \
@@ -47,6 +48,7 @@ AC_DEFUN([GRC_GR_UHD],[
gr-uhd/swig/Makefile \
gr-uhd/swig/run_tests \
gr-uhd/swig/run_guile_tests \
+ gr-uhd/apps/Makefile \
])
GRC_BUILD_CONDITIONAL(gr-uhd,[
diff --git a/config/grc_grc.m4 b/config/grc_grc.m4
index c21acccff..0474c4e89 100644
--- a/config/grc_grc.m4
+++ b/config/grc_grc.m4
@@ -34,17 +34,6 @@ AC_DEFUN([GRC_GRC],[
PYTHON_CHECK_MODULE([numpy],[NumPy],[],[passed=no],[True])
fi
- dnl ########################################
- dnl # platform dependency pythonw
- dnl ########################################
- dnl FIXME: move this test to Python config m4
- if test `${PYTHON} -c "import sys; print sys.platform"` = 'darwin'; then
- PYTHONW=pythonw
- else
- PYTHONW=python
- fi
- AC_SUBST(PYTHONW)
-
AC_CONFIG_FILES([ \
grc/Makefile \
grc/base/Makefile \
diff --git a/config/grc_volk.m4 b/config/grc_volk.m4
index 1b3c54dd7..f349d5e99 100644
--- a/config/grc_volk.m4
+++ b/config/grc_volk.m4
@@ -21,19 +21,23 @@ AC_DEFUN([GRC_VOLK],[
GRC_ENABLE(volk)
GRC_WITH(volk)
- dnl volk uses a subsidiary configure.ac
- AC_CONFIG_SUBDIRS([volk])
-
- dnl If execution gets to here, $passed will be:
- dnl with : if the --with code didn't error out
+ dnl If execution gets to here, test if $passed is:
+ dnl with : if the --with code didn't error out, use these values
+ dnl Test if $enable_volk is:
dnl yes : if the --enable code passed muster and all dependencies are met
- dnl no : otherwise
- if test $passed != with; then
+ dnl no : otherwise, then do not set variables
+ if test $passed != with && test x$enable_volk == xyes; then
dnl how and where to find INCLUDES and LA
volk_INCLUDES="-I\${abs_top_srcdir}/volk/include"
volk_LA="\${abs_top_builddir}/volk/lib/libvolk.la \
\${abs_top_builddir}/volk/lib/libvolk_runtime.la"
fi
+ dnl volk uses a subsidiary configure.ac
+ dnl only run if building Volk
+ if test $passed == yes && test x$enable_volk != xno; then
+ AC_CONFIG_SUBDIRS([volk])
+ fi
+
GRC_BUILD_CONDITIONAL(volk, [])
])
diff --git a/config/usrp_sdcc.m4 b/config/usrp_sdcc.m4
index 86f6429e5..3aae0bfa6 100644
--- a/config/usrp_sdcc.m4
+++ b/config/usrp_sdcc.m4
@@ -24,7 +24,7 @@ AC_DEFUN([USRP_SDCC],
AC_CHECK_PROG(XAS, asx8051, asx8051 -plosgff,no)
if test "$XCC" = "no" -o "$XAS" = "no" ; then
- AC_MSG_RESULT([USRP requires sdcc. sdcc not found. See http://sdcc.sf.net])
+ AC_MSG_RESULT([USRP requires sdcc version 2. sdcc not found. See http://sdcc.sf.net])
sdccok=no
else
sdcc_version_min=$1
diff --git a/gnuradio-core/src/lib/filter/Makefile.am b/gnuradio-core/src/lib/filter/Makefile.am
index dee13e239..0314079a2 100644
--- a/gnuradio-core/src/lib/filter/Makefile.am
+++ b/gnuradio-core/src/lib/filter/Makefile.am
@@ -216,7 +216,9 @@ libfilter_la_common_SOURCES = \
gr_pfb_interpolator_ccf.cc \
gr_pfb_arb_resampler_ccf.cc \
gr_pfb_clock_sync_ccf.cc \
- gr_pfb_clock_sync_fff.cc
+ gr_pfb_clock_sync_fff.cc \
+ gr_dc_blocker_cc.cc \
+ gr_dc_blocker_ff.cc
libfilter_qa_la_common_SOURCES = \
qa_filter.cc \
@@ -306,7 +308,9 @@ grinclude_HEADERS = \
gr_pfb_interpolator_ccf.h \
gr_pfb_arb_resampler_ccf.h \
gr_pfb_clock_sync_ccf.h \
- gr_pfb_clock_sync_fff.h
+ gr_pfb_clock_sync_fff.h \
+ gr_dc_blocker_cc.h \
+ gr_dc_blocker_ff.h
noinst_HEADERS = \
assembly.h \
@@ -372,6 +376,8 @@ swiginclude_HEADERS = \
gr_pfb_arb_resampler_ccf.i \
gr_pfb_clock_sync_ccf.i \
gr_pfb_clock_sync_fff.i \
+ gr_dc_blocker_cc.i \
+ gr_dc_blocker_ff.i \
$(GENERATED_I)
diff --git a/gnuradio-core/src/lib/filter/filter.i b/gnuradio-core/src/lib/filter/filter.i
index 645607cba..58bb4f0d5 100644
--- a/gnuradio-core/src/lib/filter/filter.i
+++ b/gnuradio-core/src/lib/filter/filter.i
@@ -39,6 +39,8 @@
#include <gr_pfb_arb_resampler_ccf.h>
#include <gr_pfb_clock_sync_ccf.h>
#include <gr_pfb_clock_sync_fff.h>
+#include <gr_dc_blocker_cc.h>
+#include <gr_dc_blocker_ff.h>
%}
%include "gr_iir_filter_ffd.i"
@@ -62,5 +64,7 @@
%include "gr_pfb_arb_resampler_ccf.i"
%include "gr_pfb_clock_sync_ccf.i"
%include "gr_pfb_clock_sync_fff.i"
+%include "gr_dc_blocker_cc.i"
+%include "gr_dc_blocker_ff.i"
%include "filter_generated.i"
diff --git a/gnuradio-core/src/lib/filter/gr_dc_blocker_cc.cc b/gnuradio-core/src/lib/filter/gr_dc_blocker_cc.cc
new file mode 100644
index 000000000..e7d5ced25
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_dc_blocker_cc.cc
@@ -0,0 +1,138 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2011 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_dc_blocker_cc.h>
+#include <gr_io_signature.h>
+#include <cstdio>
+
+moving_averager_c::moving_averager_c(int D)
+ : d_length(D), d_out(0), d_out_d1(0), d_out_d2(0)
+{
+ d_delay_line = std::deque<gr_complex>(d_length-1, gr_complex(0,0));
+}
+
+moving_averager_c::~moving_averager_c()
+{
+}
+
+gr_complex
+moving_averager_c::filter(gr_complex x)
+{
+ d_out_d1 = d_out;
+ d_delay_line.push_back(x);
+ d_out = d_delay_line[0];
+ d_delay_line.pop_front();
+
+ gr_complex y = x - d_out_d1 + d_out_d2;
+ d_out_d2 = y;
+
+ return (y / (float)(d_length));
+}
+
+
+
+gr_dc_blocker_cc_sptr gr_make_dc_blocker_cc (int D, bool long_form)
+{
+ return gnuradio::get_initial_sptr(new gr_dc_blocker_cc(D, long_form));
+}
+
+
+gr_dc_blocker_cc::gr_dc_blocker_cc (int D, bool long_form)
+ : gr_sync_block ("dc_blocker_cc",
+ gr_make_io_signature (1, 1, sizeof(gr_complex)),
+ gr_make_io_signature (1, 1, sizeof(gr_complex))),
+ d_length(D), d_long_form(long_form)
+{
+ if(d_long_form) {
+ d_ma_0 = new moving_averager_c(D);
+ d_ma_1 = new moving_averager_c(D);
+ d_ma_2 = new moving_averager_c(D);
+ d_ma_3 = new moving_averager_c(D);
+ d_delay_line = std::deque<gr_complex>(d_length-1, gr_complex(0,0));
+ }
+ else {
+ d_ma_0 = new moving_averager_c(D);
+ d_ma_1 = new moving_averager_c(D);
+ }
+}
+
+gr_dc_blocker_cc::~gr_dc_blocker_cc()
+{
+ if(d_long_form) {
+ delete d_ma_0;
+ delete d_ma_1;
+ delete d_ma_2;
+ delete d_ma_3;
+ }
+ else {
+ delete d_ma_0;
+ delete d_ma_1;
+ }
+}
+
+int
+gr_dc_blocker_cc::get_group_delay()
+{
+ if(d_long_form)
+ return (2*d_length-2);
+ else
+ return d_length - 1;
+}
+
+int
+gr_dc_blocker_cc::work(int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ const gr_complex *in = (const gr_complex*)input_items[0];
+ gr_complex *out = (gr_complex*)output_items[0];
+
+ if(d_long_form) {
+ gr_complex y1, y2, y3, y4, d;
+ for(int i = 0; i < noutput_items; i++) {
+ y1 = d_ma_0->filter(in[i]);
+ y2 = d_ma_1->filter(y1);
+ y3 = d_ma_2->filter(y2);
+ y4 = d_ma_3->filter(y3);
+
+ d_delay_line.push_back(d_ma_0->delayed_sig());
+ d = d_delay_line[0];
+ d_delay_line.pop_front();
+
+ out[i] = d - y4;
+ }
+ }
+ else {
+ gr_complex y1, y2;
+ for(int i = 0; i < noutput_items; i++) {
+ y1 = d_ma_0->filter(in[i]);
+ y2 = d_ma_1->filter(y1);
+ out[i] = d_ma_0->delayed_sig() - y2;
+ }
+ }
+
+ return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/filter/gr_dc_blocker_cc.h b/gnuradio-core/src/lib/filter/gr_dc_blocker_cc.h
new file mode 100644
index 000000000..de9ccc0ea
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_dc_blocker_cc.h
@@ -0,0 +1,111 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2011 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+
+#ifndef INCLUDED_GR_DC_BLOCKER_CC_H
+#define INCLUDED_GR_DC_BLOCKER_CC_H
+
+#include <gr_sync_block.h>
+#include <deque>
+
+class gr_dc_blocker_cc;
+typedef boost::shared_ptr<gr_dc_blocker_cc> gr_dc_blocker_cc_sptr;
+gr_dc_blocker_cc_sptr gr_make_dc_blocker_cc (int D=32, bool long_form=true);
+
+/*!
+ * \class gr_dc_blocker_cc
+ * \brief a computationally efficient controllabel DC blocker
+ *
+ * \ingroup filter_blk
+ *
+ * This block implements a computationally efficient DC blocker that produces
+ * a tigher notch filter around DC for a smaller group delay than an
+ * equivalent FIR filter or using a single pole IIR filter (though the IIR
+ * filter is computationally cheaper).
+ *
+ * The block defaults to using a delay line of length 32 and the long form
+ * of the filter. Optionally, the delay line length can be changed to alter
+ * the width of the DC notch (longer lines will decrease the width).
+ *
+ * The long form of the filter produces a nearly flat response outside of
+ * the notch but at the cost of a group delay of 2D-2.
+ *
+ * The short form of the filter does not have as flat a response in the
+ * passband but has a group delay of only D-1 and is cheaper to compute.
+ *
+ * The theory behind this block can be found in the paper:
+ *
+ * <B><EM>R. Yates, "DC Blocker Algorithms," IEEE Signal Processing Magazine,
+ * Mar. 2008, pp 132-134.</EM></B>
+ */
+class moving_averager_c
+{
+public:
+ moving_averager_c(int D);
+ ~moving_averager_c();
+
+ gr_complex filter(gr_complex x);
+ gr_complex delayed_sig() { return d_out; }
+
+private:
+ int d_length;
+ gr_complex d_out, d_out_d1, d_out_d2;
+ std::deque<gr_complex> d_delay_line;
+};
+
+class gr_dc_blocker_cc : public gr_sync_block
+{
+ private:
+ /*!
+ * Build the DC blocker.
+ * \param D (int) the length of the delay line
+ * \param long_form (bool) whether to use long (true, default) or short form
+ * \param channel (unsigned integer) Selects the channel to return [default=0].
+ */
+ friend gr_dc_blocker_cc_sptr gr_make_dc_blocker_cc (int D, bool long_form);
+
+ int d_length;
+ bool d_long_form;
+ moving_averager_c *d_ma_0;
+ moving_averager_c *d_ma_1;
+ moving_averager_c *d_ma_2;
+ moving_averager_c *d_ma_3;
+ std::deque<gr_complex> d_delay_line;
+
+ gr_dc_blocker_cc (int D, bool long_form);
+
+public:
+ ~gr_dc_blocker_cc ();
+
+ /*!
+ * Get the blocker's group delay that is based on length of delay lines
+ */
+ int get_group_delay();
+
+ //int set_length(int D);
+
+ int work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+};
+
+#endif
diff --git a/gnuradio-core/src/lib/filter/gr_dc_blocker_cc.i b/gnuradio-core/src/lib/filter/gr_dc_blocker_cc.i
new file mode 100644
index 000000000..b88fecbde
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_dc_blocker_cc.i
@@ -0,0 +1,34 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2011 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,dc_blocker_cc);
+
+gr_dc_blocker_cc_sptr gr_make_dc_blocker_cc (int D=32, bool long_form=true);
+
+class gr_dc_blocker_cc : public gr_sync_block
+{
+ private:
+ gr_dc_blocker_cc (int D, bool long_form);
+
+ public:
+ ~gr_dc_blocker_cc ();
+};
diff --git a/gnuradio-core/src/lib/filter/gr_dc_blocker_ff.cc b/gnuradio-core/src/lib/filter/gr_dc_blocker_ff.cc
new file mode 100644
index 000000000..d684bc7e8
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_dc_blocker_ff.cc
@@ -0,0 +1,138 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2011 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_dc_blocker_ff.h>
+#include <gr_io_signature.h>
+#include <cstdio>
+
+moving_averager_f::moving_averager_f(int D)
+ : d_length(D), d_out(0), d_out_d1(0), d_out_d2(0)
+{
+ d_delay_line = std::deque<float>(d_length-1, 0);
+}
+
+moving_averager_f::~moving_averager_f()
+{
+}
+
+float
+moving_averager_f::filter(float x)
+{
+ d_out_d1 = d_out;
+ d_delay_line.push_back(x);
+ d_out = d_delay_line[0];
+ d_delay_line.pop_front();
+
+ float y = x - d_out_d1 + d_out_d2;
+ d_out_d2 = y;
+
+ return (y / (float)(d_length));
+}
+
+
+
+gr_dc_blocker_ff_sptr gr_make_dc_blocker_ff (int D, bool long_form)
+{
+ return gnuradio::get_initial_sptr(new gr_dc_blocker_ff(D, long_form));
+}
+
+
+gr_dc_blocker_ff::gr_dc_blocker_ff (int D, bool long_form)
+ : gr_sync_block ("dc_blocker_ff",
+ gr_make_io_signature (1, 1, sizeof(float)),
+ gr_make_io_signature (1, 1, sizeof(float))),
+ d_length(D), d_long_form(long_form)
+{
+ if(d_long_form) {
+ d_ma_0 = new moving_averager_f(D);
+ d_ma_1 = new moving_averager_f(D);
+ d_ma_2 = new moving_averager_f(D);
+ d_ma_3 = new moving_averager_f(D);
+ d_delay_line = std::deque<float>(d_length-1, 0);
+ }
+ else {
+ d_ma_0 = new moving_averager_f(D);
+ d_ma_1 = new moving_averager_f(D);
+ }
+}
+
+gr_dc_blocker_ff::~gr_dc_blocker_ff()
+{
+ if(d_long_form) {
+ delete d_ma_0;
+ delete d_ma_1;
+ delete d_ma_2;
+ delete d_ma_3;
+ }
+ else {
+ delete d_ma_0;
+ delete d_ma_1;
+ }
+}
+
+int
+gr_dc_blocker_ff::get_group_delay()
+{
+ if(d_long_form)
+ return (2*d_length-2);
+ else
+ return d_length - 1;
+}
+
+int
+gr_dc_blocker_ff::work(int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ const float *in = (const float*)input_items[0];
+ float *out = (float*)output_items[0];
+
+ if(d_long_form) {
+ float y1, y2, y3, y4, d;
+ for(int i = 0; i < noutput_items; i++) {
+ y1 = d_ma_0->filter(in[i]);
+ y2 = d_ma_1->filter(y1);
+ y3 = d_ma_2->filter(y2);
+ y4 = d_ma_3->filter(y3);
+
+ d_delay_line.push_back(d_ma_0->delayed_sig());
+ d = d_delay_line[0];
+ d_delay_line.pop_front();
+
+ out[i] = d - y4;
+ }
+ }
+ else {
+ float y1, y2;
+ for(int i = 0; i < noutput_items; i++) {
+ y1 = d_ma_0->filter(in[i]);
+ y2 = d_ma_1->filter(y1);
+ out[i] = d_ma_0->delayed_sig() - y2;
+ }
+ }
+
+ return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/filter/gr_dc_blocker_ff.h b/gnuradio-core/src/lib/filter/gr_dc_blocker_ff.h
new file mode 100644
index 000000000..b632d81da
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_dc_blocker_ff.h
@@ -0,0 +1,111 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2011 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+
+#ifndef INCLUDED_GR_DC_BLOCKER_FF_H
+#define INCLUDED_GR_DC_BLOCKER_FF_H
+
+#include <gr_sync_block.h>
+#include <deque>
+
+class gr_dc_blocker_ff;
+typedef boost::shared_ptr<gr_dc_blocker_ff> gr_dc_blocker_ff_sptr;
+gr_dc_blocker_ff_sptr gr_make_dc_blocker_ff (int D=32, bool long_form=true);
+
+/*!
+ * \class gr_dc_blocker_ff
+ * \brief a computationally efficient controllabel DC blocker
+ *
+ * \ingroup filter_blk
+ *
+ * This block implements a computationally efficient DC blocker that produces
+ * a tigher notch filter around DC for a smaller group delay than an
+ * equivalent FIR filter or using a single pole IIR filter (though the IIR
+ * filter is computationally cheaper).
+ *
+ * The block defaults to using a delay line of length 32 and the long form
+ * of the filter. Optionally, the delay line length can be changed to alter
+ * the width of the DC notch (longer lines will decrease the width).
+ *
+ * The long form of the filter produces a nearly flat response outside of
+ * the notch but at the cost of a group delay of 2D-2.
+ *
+ * The short form of the filter does not have as flat a response in the
+ * passband but has a group delay of only D-1 and is cheaper to compute.
+ *
+ * The theory behind this block can be found in the paper:
+ *
+ * <B><EM>R. Yates, "DC Blocker Algorithms," IEEE Signal Processing Magazine,
+ * Mar. 2008, pp 132-134.</EM></B>
+ */
+class moving_averager_f
+{
+public:
+ moving_averager_f(int D);
+ ~moving_averager_f();
+
+ float filter(float x);
+ float delayed_sig() { return d_out; }
+
+private:
+ int d_length;
+ float d_out, d_out_d1, d_out_d2;
+ std::deque<float> d_delay_line;
+};
+
+class gr_dc_blocker_ff : public gr_sync_block
+{
+ private:
+ /*!
+ * Build the DC blocker.
+ * \param D (int) the length of the delay line
+ * \param long_form (bool) whether to use long (true, default) or short form
+ * \param channel (unsigned integer) Selects the channel to return [default=0].
+ */
+ friend gr_dc_blocker_ff_sptr gr_make_dc_blocker_ff (int D, bool long_form);
+
+ int d_length;
+ bool d_long_form;
+ moving_averager_f *d_ma_0;
+ moving_averager_f *d_ma_1;
+ moving_averager_f *d_ma_2;
+ moving_averager_f *d_ma_3;
+ std::deque<float> d_delay_line;
+
+ gr_dc_blocker_ff (int D, bool long_form);
+
+public:
+ ~gr_dc_blocker_ff ();
+
+ /*!
+ * Get the blocker's group delay that is based on length of delay lines
+ */
+ int get_group_delay();
+
+ //int set_length(int D);
+
+ int work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+};
+
+#endif
diff --git a/gnuradio-core/src/lib/filter/gr_dc_blocker_ff.i b/gnuradio-core/src/lib/filter/gr_dc_blocker_ff.i
new file mode 100644
index 000000000..032145c9e
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_dc_blocker_ff.i
@@ -0,0 +1,34 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2011 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,dc_blocker_ff);
+
+gr_dc_blocker_ff_sptr gr_make_dc_blocker_ff (int D=32, bool long_form=true);
+
+class gr_dc_blocker_ff : public gr_sync_block
+{
+ private:
+ gr_dc_blocker_ff (int D, bool long_form);
+
+ public:
+ ~gr_dc_blocker_ff ();
+};
diff --git a/gnuradio-core/src/lib/general/gr_frequency_modulator_fc.h b/gnuradio-core/src/lib/general/gr_frequency_modulator_fc.h
index 4ba05d709..55f8412ce 100644
--- a/gnuradio-core/src/lib/general/gr_frequency_modulator_fc.h
+++ b/gnuradio-core/src/lib/general/gr_frequency_modulator_fc.h
@@ -47,7 +47,9 @@ class gr_frequency_modulator_fc : public gr_sync_block
gr_frequency_modulator_fc (double sensitivity);
public:
-
+ void set_sensitivity(float sens) { d_sensitivity = sens; }
+ float get_sensitivity() { return d_sensitivity; }
+
int work (int noutput_items,
gr_vector_const_void_star &input_items,
gr_vector_void_star &output_items);
diff --git a/gnuradio-core/src/lib/general/gr_frequency_modulator_fc.i b/gnuradio-core/src/lib/general/gr_frequency_modulator_fc.i
index 612b59026..04d9a41ba 100644
--- a/gnuradio-core/src/lib/general/gr_frequency_modulator_fc.i
+++ b/gnuradio-core/src/lib/general/gr_frequency_modulator_fc.i
@@ -28,4 +28,7 @@ class gr_frequency_modulator_fc : public gr_sync_block
{
private:
gr_frequency_modulator_fc (double sensitivity);
+public:
+ void set_sensitivity(float sens) { d_sensitivity = sens; }
+ float get_sensitivity() { return d_sensitivity; }
};
diff --git a/gnuradio-core/src/python/gnuradio/gr/Makefile.am b/gnuradio-core/src/python/gnuradio/gr/Makefile.am
index f1b4ba2b1..45c970227 100644
--- a/gnuradio-core/src/python/gnuradio/gr/Makefile.am
+++ b/gnuradio-core/src/python/gnuradio/gr/Makefile.am
@@ -55,6 +55,7 @@ noinst_PYTHON = \
qa_copy.py \
qa_correlate_access_code.py \
qa_delay.py \
+ qa_dc_blocker.py \
qa_diff_encoder.py \
qa_diff_phasor_cc.py \
qa_ecc_ccsds_27.py \
diff --git a/gnuradio-core/src/python/gnuradio/gr/qa_dc_blocker.py b/gnuradio-core/src/python/gnuradio/gr/qa_dc_blocker.py
new file mode 100755
index 000000000..8977b475a
--- /dev/null
+++ b/gnuradio-core/src/python/gnuradio/gr/qa_dc_blocker.py
@@ -0,0 +1,108 @@
+#!/usr/bin/env python
+#
+# Copyright 2011 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+from gnuradio import gr, gr_unittest
+
+class test_dc_blocker(gr_unittest.TestCase):
+
+ def setUp (self):
+ self.tb = gr.top_block ()
+
+ def tearDown (self):
+ self.tb = None
+
+ def test_001(self):
+ ''' Test impulse response - long form, cc '''
+ src_data = [1,] + 100*[0,]
+ expected_result = ((-0.02072429656982422+0j), (-0.02081298828125+0j),
+ (0.979156494140625+0j), (-0.02081298828125+0j),
+ (-0.02072429656982422+0j))
+
+ src = gr.vector_source_c(src_data)
+ op = gr.dc_blocker_cc(32, True)
+ dst = gr.vector_sink_c()
+
+ self.tb.connect (src, op, dst)
+ self.tb.run()
+
+ # only test samples around 2D-2
+ result_data = dst.data()[60:65]
+ self.assertFloatTuplesAlmostEqual (expected_result, result_data)
+
+ def test_002(self):
+ ''' Test impulse response - short form, cc '''
+ src_data = [1,] + 100*[0,]
+ expected_result = ((-0.029296875+0j), (-0.0302734375+0j),
+ (0.96875+0j), (-0.0302734375+0j),
+ (-0.029296875+0j))
+
+ src = gr.vector_source_c(src_data)
+ op = gr.dc_blocker_cc(32, False)
+ dst = gr.vector_sink_c()
+
+ self.tb.connect (src, op, dst)
+ self.tb.run()
+
+ # only test samples around D-1
+ result_data = dst.data()[29:34]
+ self.assertFloatTuplesAlmostEqual (expected_result, result_data)
+
+
+ def test_003(self):
+ ''' Test impulse response - long form, ff '''
+ src_data = [1,] + 100*[0,]
+ expected_result = ((-0.02072429656982422), (-0.02081298828125),
+ (0.979156494140625), (-0.02081298828125),
+ (-0.02072429656982422))
+
+ src = gr.vector_source_f(src_data)
+ op = gr.dc_blocker_ff(32, True)
+ dst = gr.vector_sink_f()
+
+ self.tb.connect (src, op, dst)
+ self.tb.run()
+
+ # only test samples around 2D-2
+ result_data = dst.data()[60:65]
+ self.assertFloatTuplesAlmostEqual (expected_result, result_data)
+
+ def test_004(self):
+ ''' Test impulse response - short form, ff '''
+ src_data = [1,] + 100*[0,]
+ expected_result = ((-0.029296875), (-0.0302734375),
+ (0.96875), (-0.0302734375),
+ (-0.029296875))
+
+ src = gr.vector_source_f(src_data)
+ op = gr.dc_blocker_ff(32, False)
+ dst = gr.vector_sink_f()
+
+ self.tb.connect (src, op, dst)
+ self.tb.run()
+
+ # only test samples around D-1
+ result_data = dst.data()[29:34]
+ self.assertFloatTuplesAlmostEqual (expected_result, result_data)
+
+if __name__ == '__main__':
+ gr_unittest.run(test_dc_blocker, "test_dc_blocker.xml")
+
diff --git a/gnuradio-examples/grc/Makefile.am b/gnuradio-examples/grc/Makefile.am
index 118ecd593..d9a0d9c2c 100644
--- a/gnuradio-examples/grc/Makefile.am
+++ b/gnuradio-examples/grc/Makefile.am
@@ -39,8 +39,7 @@ simpledatadir = $(grc_examples_prefix)/simple
dist_simpledata_DATA = \
simple/ber_simulation.grc \
simple/dpsk_loopback.grc \
- simple/variable_config.grc \
- simple/var_sink_taps.grc
+ simple/variable_config.grc
trellisdatadir = $(grc_examples_prefix)/trellis
dist_trellisdata_DATA = \
diff --git a/gnuradio-examples/grc/simple/var_sink_taps.grc b/gnuradio-examples/grc/simple/var_sink_taps.grc
deleted file mode 100644
index 07207850e..000000000
--- a/gnuradio-examples/grc/simple/var_sink_taps.grc
+++ /dev/null
@@ -1,488 +0,0 @@
-<?xml version='1.0' encoding='ASCII'?>
-<flow_graph>
- <timestamp>Tue May 19 16:45:51 2009</timestamp>
- <block>
- <key>options</key>
- <param>
- <key>id</key>
- <value>var_sink_taps</value>
- </param>
- <param>
- <key>_enabled</key>
- <value>True</value>
- </param>
- <param>
- <key>title</key>
- <value>Variable Sink + Taps</value>
- </param>
- <param>
- <key>author</key>
- <value>Example</value>
- </param>
- <param>
- <key>description</key>
- <value>gnuradio flow graph</value>
- </param>
- <param>
- <key>window_size</key>
- <value>1280, 1024</value>
- </param>
- <param>
- <key>generate_options</key>
- <value>wx_gui</value>
- </param>
- <param>
- <key>category</key>
- <value>Custom</value>
- </param>
- <param>
- <key>realtime_scheduling</key>
- <value></value>
- </param>
- <param>
- <key>_coordinate</key>
- <value>(10, 10)</value>
- </param>
- <param>
- <key>_rotation</key>
- <value>0</value>
- </param>
- </block>
- <block>
- <key>gr_noise_source_x</key>
- <param>
- <key>id</key>
- <value>gr_noise_source_x_0</value>
- </param>
- <param>
- <key>_enabled</key>
- <value>True</value>
- </param>
- <param>
- <key>type</key>
- <value>complex</value>
- </param>
- <param>
- <key>noise_type</key>
- <value>gr.GR_GAUSSIAN</value>
- </param>
- <param>
- <key>amp</key>
- <value>1</value>
- </param>
- <param>
- <key>seed</key>
- <value>42</value>
- </param>
- <param>
- <key>_coordinate</key>
- <value>(619, 36)</value>
- </param>
- <param>
- <key>_rotation</key>
- <value>0</value>
- </param>
- </block>
- <block>
- <key>gr_fir_filter_xxx</key>
- <param>
- <key>id</key>
- <value>gr_fir_filter_xxx_0</value>
- </param>
- <param>
- <key>_enabled</key>
- <value>True</value>
- </param>
- <param>
- <key>type</key>
- <value>ccc</value>
- </param>
- <param>
- <key>decim</key>
- <value>1</value>
- </param>
- <param>
- <key>taps</key>
- <value>dest_taps</value>
- </param>
- <param>
- <key>_coordinate</key>
- <value>(831, 47)</value>
- </param>
- <param>
- <key>_rotation</key>
- <value>0</value>
- </param>
- </block>
- <block>
- <key>gr_throttle</key>
- <param>
- <key>id</key>
- <value>gr_throttle_0</value>
- </param>
- <param>
- <key>_enabled</key>
- <value>True</value>
- </param>
- <param>
- <key>type</key>
- <value>complex</value>
- </param>
- <param>
- <key>samples_per_second</key>
- <value>samp_rate</value>
- </param>
- <param>
- <key>vlen</key>
- <value>1</value>
- </param>
- <param>
- <key>_coordinate</key>
- <value>(999, 198)</value>
- </param>
- <param>
- <key>_rotation</key>
- <value>270</value>
- </param>
- </block>
- <block>
- <key>wxgui_fftsink2</key>
- <param>
- <key>id</key>
- <value>wxgui_fftsink2_0</value>
- </param>
- <param>
- <key>_enabled</key>
- <value>True</value>
- </param>
- <param>
- <key>type</key>
- <value>complex</value>
- </param>
- <param>
- <key>title</key>
- <value>FFT Plot</value>
- </param>
- <param>
- <key>samp_rate</key>
- <value>samp_rate</value>
- </param>
- <param>
- <key>baseband_freq</key>
- <value>0</value>
- </param>
- <param>
- <key>y_per_div</key>
- <value>10</value>
- </param>
- <param>
- <key>y_divs</key>
- <value>10</value>
- </param>
- <param>
- <key>ref_level</key>
- <value>50</value>
- </param>
- <param>
- <key>fft_size</key>
- <value>1024</value>
- </param>
- <param>
- <key>fft_rate</key>
- <value>30</value>
- </param>
- <param>
- <key>peak_hold</key>
- <value>False</value>
- </param>
- <param>
- <key>average</key>
- <value>False</value>
- </param>
- <param>
- <key>avg_alpha</key>
- <value>0</value>
- </param>
- <param>
- <key>grid_pos</key>
- <value></value>
- </param>
- <param>
- <key>_coordinate</key>
- <value>(629, 184)</value>
- </param>
- <param>
- <key>_rotation</key>
- <value>180</value>
- </param>
- </block>
- <block>
- <key>import</key>
- <param>
- <key>id</key>
- <value>import_0</value>
- </param>
- <param>
- <key>_enabled</key>
- <value>True</value>
- </param>
- <param>
- <key>import</key>
- <value>from gnuradio.gr import firdes</value>
- </param>
- <param>
- <key>_coordinate</key>
- <value>(330, 120)</value>
- </param>
- <param>
- <key>_rotation</key>
- <value>0</value>
- </param>
- </block>
- <block>
- <key>variable</key>
- <param>
- <key>id</key>
- <value>dest_taps</value>
- </param>
- <param>
- <key>_enabled</key>
- <value>True</value>
- </param>
- <param>
- <key>value</key>
- <value>[0]</value>
- </param>
- <param>
- <key>_coordinate</key>
- <value>(836, 223)</value>
- </param>
- <param>
- <key>_rotation</key>
- <value>0</value>
- </param>
- </block>
- <block>
- <key>variable</key>
- <param>
- <key>id</key>
- <value>samp_rate</value>
- </param>
- <param>
- <key>_enabled</key>
- <value>True</value>
- </param>
- <param>
- <key>value</key>
- <value>32000</value>
- </param>
- <param>
- <key>_coordinate</key>
- <value>(831, 130)</value>
- </param>
- <param>
- <key>_rotation</key>
- <value>0</value>
- </param>
- </block>
- <block>
- <key>variable</key>
- <param>
- <key>id</key>
- <value>source_taps</value>
- </param>
- <param>
- <key>_enabled</key>
- <value>True</value>
- </param>
- <param>
- <key>value</key>
- <value>firdes.low_pass(1, samp_rate, 4000, 2000)</value>
- </param>
- <param>
- <key>_coordinate</key>
- <value>(397, 191)</value>
- </param>
- <param>
- <key>_rotation</key>
- <value>0</value>
- </param>
- </block>
- <block>
- <key>variable</key>
- <param>
- <key>id</key>
- <value>taps_rate</value>
- </param>
- <param>
- <key>_enabled</key>
- <value>True</value>
- </param>
- <param>
- <key>value</key>
- <value>10</value>
- </param>
- <param>
- <key>_coordinate</key>
- <value>(268, 189)</value>
- </param>
- <param>
- <key>_rotation</key>
- <value>0</value>
- </param>
- </block>
- <block>
- <key>gr_vector_source_x</key>
- <param>
- <key>id</key>
- <value>gr_vector_source_x_0</value>
- </param>
- <param>
- <key>_enabled</key>
- <value>True</value>
- </param>
- <param>
- <key>type</key>
- <value>complex</value>
- </param>
- <param>
- <key>vector</key>
- <value>source_taps</value>
- </param>
- <param>
- <key>repeat</key>
- <value>True</value>
- </param>
- <param>
- <key>vlen</key>
- <value>len(source_taps)</value>
- </param>
- <param>
- <key>_coordinate</key>
- <value>(205, 33)</value>
- </param>
- <param>
- <key>_rotation</key>
- <value>0</value>
- </param>
- </block>
- <block>
- <key>note</key>
- <param>
- <key>id</key>
- <value>note_0</value>
- </param>
- <param>
- <key>_enabled</key>
- <value>True</value>
- </param>
- <param>
- <key>note</key>
- <value>Pass the FIR taps via a variable sink.</value>
- </param>
- <param>
- <key>_coordinate</key>
- <value>(14, 141)</value>
- </param>
- <param>
- <key>_rotation</key>
- <value>0</value>
- </param>
- </block>
- <block>
- <key>gr_throttle</key>
- <param>
- <key>id</key>
- <value>gr_throttle</value>
- </param>
- <param>
- <key>_enabled</key>
- <value>True</value>
- </param>
- <param>
- <key>type</key>
- <value>complex</value>
- </param>
- <param>
- <key>samples_per_second</key>
- <value>taps_rate</value>
- </param>
- <param>
- <key>vlen</key>
- <value>len(source_taps)</value>
- </param>
- <param>
- <key>_coordinate</key>
- <value>(440, 41)</value>
- </param>
- <param>
- <key>_rotation</key>
- <value>0</value>
- </param>
- </block>
- <block>
- <key>blks2_variable_sink_x</key>
- <param>
- <key>id</key>
- <value>blks2_variable_sink_x_0</value>
- </param>
- <param>
- <key>_enabled</key>
- <value>True</value>
- </param>
- <param>
- <key>type</key>
- <value>complex</value>
- </param>
- <param>
- <key>variable</key>
- <value>dest_taps</value>
- </param>
- <param>
- <key>decim</key>
- <value>1</value>
- </param>
- <param>
- <key>vlen</key>
- <value>len(source_taps)</value>
- </param>
- <param>
- <key>_coordinate</key>
- <value>(305, 283)</value>
- </param>
- <param>
- <key>_rotation</key>
- <value>180</value>
- </param>
- </block>
- <connection>
- <source_block_id>gr_noise_source_x_0</source_block_id>
- <sink_block_id>gr_fir_filter_xxx_0</sink_block_id>
- <source_key>0</source_key>
- <sink_key>0</sink_key>
- </connection>
- <connection>
- <source_block_id>gr_fir_filter_xxx_0</source_block_id>
- <sink_block_id>gr_throttle_0</sink_block_id>
- <source_key>0</source_key>
- <sink_key>0</sink_key>
- </connection>
- <connection>
- <source_block_id>gr_throttle_0</source_block_id>
- <sink_block_id>wxgui_fftsink2_0</sink_block_id>
- <source_key>0</source_key>
- <sink_key>0</sink_key>
- </connection>
- <connection>
- <source_block_id>gr_vector_source_x_0</source_block_id>
- <sink_block_id>gr_throttle</sink_block_id>
- <source_key>0</source_key>
- <sink_key>0</sink_key>
- </connection>
- <connection>
- <source_block_id>gr_throttle</source_block_id>
- <sink_block_id>blks2_variable_sink_x_0</sink_block_id>
- <source_key>0</source_key>
- <sink_key>0</sink_key>
- </connection>
-</flow_graph>
diff --git a/gnuradio-examples/python/usrp2/usrp2_wfm_rcv.py b/gnuradio-examples/python/usrp2/usrp2_wfm_rcv.py
index 1783660d6..2b94c458e 100755
--- a/gnuradio-examples/python/usrp2/usrp2_wfm_rcv.py
+++ b/gnuradio-examples/python/usrp2/usrp2_wfm_rcv.py
@@ -87,7 +87,8 @@ class wfm_rx_block (stdgui2.std_top_block):
dbid == 0x0040 or #usrp_dbid.TV_RX_REV_3
dbid == 0x0043 or #usrp_dbid.TV_RX_MIMO
dbid == 0x0044 or #usrp_dbid.TV_RX_REV_2_MIMO
- dbid == 0x0045 ): #usrp_dbid.TV_RX_REV_3_MIMO
+ dbid == 0x0045 or #usrp_dbid.TV_RX_REV_3_MIMO
+ dbid == 0x0053 ): #usrp_dbid.WBX
print "This daughterboard does not cover the required frequency range"
print "for this application. Please use a BasicRX or TVRX daughterboard."
raw_input("Press ENTER to continue anyway, or Ctrl-C to exit.")
diff --git a/gr-audio/include/gr_audio_api.h b/gr-audio/include/gr_audio_api.h
index b21819bab..65782d308 100644
--- a/gr-audio/include/gr_audio_api.h
+++ b/gr-audio/include/gr_audio_api.h
@@ -22,10 +22,12 @@
#ifndef INCLUDED_GR_AUDIO_API_H
#define INCLUDED_GR_AUDIO_API_H
+#include <gruel/attributes.h>
+
#ifdef gnuradio_audio_EXPORTS
-# define GR_AUDIO_API //FIXME needs attributes defines
+# define GR_AUDIO_API __GR_ATTR_EXPORT
#else
-# define GR_AUDIO_API //FIXME needs attributes defines
+# define GR_AUDIO_API __GR_ATTR_IMPORT
#endif
#endif /* INCLUDED_GR_AUDIO_API_H */
diff --git a/gr-qtgui/apps/Makefile.am b/gr-qtgui/apps/Makefile.am
index c8d967334..7b35d949e 100644
--- a/gr-qtgui/apps/Makefile.am
+++ b/gr-qtgui/apps/Makefile.am
@@ -30,6 +30,7 @@ nodist_bin_SCRIPTS = \
noinst_PYTHON = \
pyqt_example_f.py \
pyqt_example_c.py \
+ pyqt_time_c.py \
qt_digital.py \
qt_digital_window.py \
usrp2_display.py \
diff --git a/gr-qtgui/apps/pyqt_example_c.py b/gr-qtgui/apps/pyqt_example_c.py
index e1b58442f..607ab12ee 100755
--- a/gr-qtgui/apps/pyqt_example_c.py
+++ b/gr-qtgui/apps/pyqt_example_c.py
@@ -145,5 +145,6 @@ class my_top_block(gr.top_block):
if __name__ == "__main__":
tb = my_top_block();
tb.start()
- sys.exit(tb.qapp.exec_())
+ tb.qapp.exec_()
+ tb.stop()
diff --git a/gr-qtgui/apps/pyqt_example_f.py b/gr-qtgui/apps/pyqt_example_f.py
index 6b2131019..2d957c85a 100755
--- a/gr-qtgui/apps/pyqt_example_f.py
+++ b/gr-qtgui/apps/pyqt_example_f.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python
-from gnuradio import gr, blks2
+from gnuradio import gr
from gnuradio import qtgui
from PyQt4 import QtGui, QtCore
import sys, sip
@@ -117,6 +117,8 @@ class my_top_block(gr.top_block):
src2 = gr.sig_source_f(Rs, gr.GR_SIN_WAVE, f2, 0.1, 0)
src = gr.add_ff()
thr = gr.throttle(gr.sizeof_float, 100*fftsize)
+ noise = gr.noise_source_f(gr.GR_GAUSSIAN, 0.001)
+ add = gr.add_ff()
self.snk1 = qtgui.sink_f(fftsize, gr.firdes.WIN_BLACKMAN_hARRIS,
0, Rs,
"Float Signal Example",
@@ -124,7 +126,9 @@ class my_top_block(gr.top_block):
self.connect(src1, (src,0))
self.connect(src2, (src,1))
- self.connect(src, thr, self.snk1)
+ self.connect(src, thr, (add,0))
+ self.connect(noise, (add,1))
+ self.connect(add, self.snk1)
self.ctrl_win = control_box()
self.ctrl_win.attach_signal1(src1)
@@ -144,5 +148,5 @@ class my_top_block(gr.top_block):
if __name__ == "__main__":
tb = my_top_block();
tb.start()
- sys.exit(tb.qapp.exec_())
-
+ tb.qapp.exec_()
+ tb.stop()
diff --git a/gr-qtgui/apps/pyqt_time_c.py b/gr-qtgui/apps/pyqt_time_c.py
new file mode 100755
index 000000000..fa7d60e81
--- /dev/null
+++ b/gr-qtgui/apps/pyqt_time_c.py
@@ -0,0 +1,163 @@
+#!/usr/bin/env python
+
+from gnuradio import gr
+from gnuradio import qtgui
+from PyQt4 import QtGui, QtCore
+import sys, sip
+
+class dialog_box(QtGui.QWidget):
+ def __init__(self, display, control):
+ QtGui.QWidget.__init__(self, None)
+ self.setWindowTitle('PyQt Test GUI')
+
+ self.boxlayout = QtGui.QBoxLayout(QtGui.QBoxLayout.LeftToRight, self)
+ self.boxlayout.addWidget(display, 1)
+ self.boxlayout.addWidget(control)
+
+ self.resize(800, 500)
+
+class control_box(QtGui.QWidget):
+ def __init__(self, parent=None):
+ QtGui.QWidget.__init__(self, parent)
+ self.setWindowTitle('Control Panel')
+
+ self.setToolTip('Control the signals')
+ QtGui.QToolTip.setFont(QtGui.QFont('OldEnglish', 10))
+
+ self.layout = QtGui.QFormLayout(self)
+
+ # Control the first signal
+ self.freq1Edit = QtGui.QLineEdit(self)
+ self.freq1Edit.setMinimumWidth(100)
+ self.layout.addRow("Signal 1 Frequency:", self.freq1Edit)
+ self.connect(self.freq1Edit, QtCore.SIGNAL("editingFinished()"),
+ self.freq1EditText)
+
+ self.amp1Edit = QtGui.QLineEdit(self)
+ self.amp1Edit.setMinimumWidth(100)
+ self.layout.addRow("Signal 1 Amplitude:", self.amp1Edit)
+ self.connect(self.amp1Edit, QtCore.SIGNAL("editingFinished()"),
+ self.amp1EditText)
+
+
+ # Control the second signal
+ self.freq2Edit = QtGui.QLineEdit(self)
+ self.freq2Edit.setMinimumWidth(100)
+ self.layout.addRow("Signal 2 Frequency:", self.freq2Edit)
+ self.connect(self.freq2Edit, QtCore.SIGNAL("editingFinished()"),
+ self.freq2EditText)
+
+
+ self.amp2Edit = QtGui.QLineEdit(self)
+ self.amp2Edit.setMinimumWidth(100)
+ self.layout.addRow("Signal 2 Amplitude:", self.amp2Edit)
+ self.connect(self.amp2Edit, QtCore.SIGNAL("editingFinished()"),
+ self.amp2EditText)
+
+ self.quit = QtGui.QPushButton('Close', self)
+ self.quit.setMinimumWidth(100)
+ self.layout.addWidget(self.quit)
+
+ self.connect(self.quit, QtCore.SIGNAL('clicked()'),
+ QtGui.qApp, QtCore.SLOT('quit()'))
+
+ def attach_signal1(self, signal):
+ self.signal1 = signal
+ self.freq1Edit.setText(QtCore.QString("%1").arg(self.signal1.frequency()))
+ self.amp1Edit.setText(QtCore.QString("%1").arg(self.signal1.amplitude()))
+
+ def attach_signal2(self, signal):
+ self.signal2 = signal
+ self.freq2Edit.setText(QtCore.QString("%1").arg(self.signal2.frequency()))
+ self.amp2Edit.setText(QtCore.QString("%1").arg(self.signal2.amplitude()))
+
+ def freq1EditText(self):
+ try:
+ newfreq = float(self.freq1Edit.text())
+ self.signal1.set_frequency(newfreq)
+ except ValueError:
+ print "Bad frequency value entered"
+
+ def amp1EditText(self):
+ try:
+ newamp = float(self.amp1Edit.text())
+ self.signal1.set_amplitude(newamp)
+ except ValueError:
+ print "Bad amplitude value entered"
+
+
+ def freq2EditText(self):
+ try:
+ newfreq = float(self.freq2Edit.text())
+ self.signal2.set_frequency(newfreq)
+ except ValueError:
+ print "Bad frequency value entered"
+
+ def amp2EditText(self):
+ try:
+ newamp = float(self.amp2Edit.text())
+ self.signal2.set_amplitude(newamp)
+ except ValueError:
+ print "Bad amplitude value entered"
+
+
+class my_top_block(gr.top_block):
+ def __init__(self):
+ gr.top_block.__init__(self)
+
+ Rs = 8000
+ f1 = 100
+ f2 = 200
+
+ npts = 2048
+
+ self.qapp = QtGui.QApplication(sys.argv)
+
+ src1 = gr.sig_source_c(Rs, gr.GR_SIN_WAVE, f1, 0.1, 0)
+ src2 = gr.sig_source_c(Rs, gr.GR_SIN_WAVE, f2, 0.1, 0)
+ src = gr.add_cc()
+ channel = gr.channel_model(0.01)
+ thr = gr.throttle(gr.sizeof_gr_complex, 100*npts)
+ self.snk1 = qtgui.time_sink_c(npts, Rs,
+ "Complex Time Example", 3)
+
+ self.connect(src1, (src,0))
+ self.connect(src2, (src,1))
+ self.connect(src, channel, thr, (self.snk1, 0))
+ self.connect(src1, (self.snk1, 1))
+ self.connect(src2, (self.snk1, 2))
+
+ self.ctrl_win = control_box()
+ self.ctrl_win.attach_signal1(src1)
+ self.ctrl_win.attach_signal2(src2)
+
+ # Get the reference pointer to the SpectrumDisplayForm QWidget
+ pyQt = self.snk1.pyqwidget()
+
+ # Wrap the pointer as a PyQt SIP object
+ # This can now be manipulated as a PyQt4.QtGui.QWidget
+ pyWin = sip.wrapinstance(pyQt, QtGui.QWidget)
+
+ # Example of using signal/slot to set the title of a curve
+ pyWin.connect(pyWin, QtCore.SIGNAL("setTitle(int, QString)"),
+ pyWin, QtCore.SLOT("setTitle(int, QString)"))
+ pyWin.emit(QtCore.SIGNAL("setTitle(int, QString)"), 0, "Re{sum}")
+ self.snk1.set_title(1, "Im{Sum}")
+ self.snk1.set_title(2, "Re{src1}")
+ self.snk1.set_title(3, "Im{src1}")
+ self.snk1.set_title(4, "Re{src2}")
+ self.snk1.set_title(5, "Im{src2}")
+
+ # Can also set the color of a curve
+ #self.snk1.set_color(5, "blue")
+
+ #pyWin.show()
+ self.main_box = dialog_box(pyWin, self.ctrl_win)
+ self.main_box.show()
+
+if __name__ == "__main__":
+ tb = my_top_block();
+ tb.start()
+ tb.qapp.exec_()
+ tb.stop()
+
diff --git a/gr-qtgui/apps/pyqt_time_f.py b/gr-qtgui/apps/pyqt_time_f.py
new file mode 100755
index 000000000..1b9efa10d
--- /dev/null
+++ b/gr-qtgui/apps/pyqt_time_f.py
@@ -0,0 +1,163 @@
+#!/usr/bin/env python
+
+from gnuradio import gr
+from gnuradio import qtgui
+from PyQt4 import QtGui, QtCore
+import sys, sip
+
+class dialog_box(QtGui.QWidget):
+ def __init__(self, display, control):
+ QtGui.QWidget.__init__(self, None)
+ self.setWindowTitle('PyQt Test GUI')
+
+ self.boxlayout = QtGui.QBoxLayout(QtGui.QBoxLayout.LeftToRight, self)
+ self.boxlayout.addWidget(display, 1)
+ self.boxlayout.addWidget(control)
+
+ self.resize(800, 500)
+
+class control_box(QtGui.QWidget):
+ def __init__(self, parent=None):
+ QtGui.QWidget.__init__(self, parent)
+ self.setWindowTitle('Control Panel')
+
+ self.setToolTip('Control the signals')
+ QtGui.QToolTip.setFont(QtGui.QFont('OldEnglish', 10))
+
+ self.layout = QtGui.QFormLayout(self)
+
+ # Control the first signal
+ self.freq1Edit = QtGui.QLineEdit(self)
+ self.freq1Edit.setMinimumWidth(100)
+ self.layout.addRow("Signal 1 Frequency:", self.freq1Edit)
+ self.connect(self.freq1Edit, QtCore.SIGNAL("editingFinished()"),
+ self.freq1EditText)
+
+ self.amp1Edit = QtGui.QLineEdit(self)
+ self.amp1Edit.setMinimumWidth(100)
+ self.layout.addRow("Signal 1 Amplitude:", self.amp1Edit)
+ self.connect(self.amp1Edit, QtCore.SIGNAL("editingFinished()"),
+ self.amp1EditText)
+
+
+ # Control the second signal
+ self.freq2Edit = QtGui.QLineEdit(self)
+ self.freq2Edit.setMinimumWidth(100)
+ self.layout.addRow("Signal 2 Frequency:", self.freq2Edit)
+ self.connect(self.freq2Edit, QtCore.SIGNAL("editingFinished()"),
+ self.freq2EditText)
+
+
+ self.amp2Edit = QtGui.QLineEdit(self)
+ self.amp2Edit.setMinimumWidth(100)
+ self.layout.addRow("Signal 2 Amplitude:", self.amp2Edit)
+ self.connect(self.amp2Edit, QtCore.SIGNAL("editingFinished()"),
+ self.amp2EditText)
+
+ self.quit = QtGui.QPushButton('Close', self)
+ self.quit.setMinimumWidth(100)
+ self.layout.addWidget(self.quit)
+
+ self.connect(self.quit, QtCore.SIGNAL('clicked()'),
+ QtGui.qApp, QtCore.SLOT('quit()'))
+
+ def attach_signal1(self, signal):
+ self.signal1 = signal
+ self.freq1Edit.setText(QtCore.QString("%1").arg(self.signal1.frequency()))
+ self.amp1Edit.setText(QtCore.QString("%1").arg(self.signal1.amplitude()))
+
+ def attach_signal2(self, signal):
+ self.signal2 = signal
+ self.freq2Edit.setText(QtCore.QString("%1").arg(self.signal2.frequency()))
+ self.amp2Edit.setText(QtCore.QString("%1").arg(self.signal2.amplitude()))
+
+ def freq1EditText(self):
+ try:
+ newfreq = float(self.freq1Edit.text())
+ self.signal1.set_frequency(newfreq)
+ except ValueError:
+ print "Bad frequency value entered"
+
+ def amp1EditText(self):
+ try:
+ newamp = float(self.amp1Edit.text())
+ self.signal1.set_amplitude(newamp)
+ except ValueError:
+ print "Bad amplitude value entered"
+
+
+ def freq2EditText(self):
+ try:
+ newfreq = float(self.freq2Edit.text())
+ self.signal2.set_frequency(newfreq)
+ except ValueError:
+ print "Bad frequency value entered"
+
+ def amp2EditText(self):
+ try:
+ newamp = float(self.amp2Edit.text())
+ self.signal2.set_amplitude(newamp)
+ except ValueError:
+ print "Bad amplitude value entered"
+
+
+class my_top_block(gr.top_block):
+ def __init__(self):
+ gr.top_block.__init__(self)
+
+ Rs = 8000
+ f1 = 100
+ f2 = 200
+
+ npts = 2048
+
+ self.qapp = QtGui.QApplication(sys.argv)
+
+ src1 = gr.sig_source_f(Rs, gr.GR_SIN_WAVE, f1, 0.1, 0)
+ src2 = gr.sig_source_f(Rs, gr.GR_SIN_WAVE, f2, 0.1, 0)
+ src = gr.add_ff()
+ thr = gr.throttle(gr.sizeof_float, 100*npts)
+ noise = gr.noise_source_f(gr.GR_GAUSSIAN, 0.001)
+ add = gr.add_ff()
+ self.snk1 = qtgui.time_sink_f(npts, Rs,
+ "Complex Time Example", 3)
+
+ self.connect(src1, (src,0))
+ self.connect(src2, (src,1))
+ self.connect(src, thr, (add,0))
+ self.connect(noise, (add,1))
+ self.connect(add, self.snk1)
+ self.connect(src1, (self.snk1, 1))
+ self.connect(src2, (self.snk1, 2))
+
+ self.ctrl_win = control_box()
+ self.ctrl_win.attach_signal1(src1)
+ self.ctrl_win.attach_signal2(src2)
+
+ # Get the reference pointer to the SpectrumDisplayForm QWidget
+ pyQt = self.snk1.pyqwidget()
+
+ # Wrap the pointer as a PyQt SIP object
+ # This can now be manipulated as a PyQt4.QtGui.QWidget
+ pyWin = sip.wrapinstance(pyQt, QtGui.QWidget)
+
+ # Example of using signal/slot to set the title of a curve
+ pyWin.connect(pyWin, QtCore.SIGNAL("setTitle(int, QString)"),
+ pyWin, QtCore.SLOT("setTitle(int, QString)"))
+ pyWin.emit(QtCore.SIGNAL("setTitle(int, QString)"), 0, "sum")
+ self.snk1.set_title(1, "src1")
+ self.snk1.set_title(2, "src2")
+
+ # Can also set the color of a curve
+ #self.snk1.set_color(5, "blue")
+
+ #pyWin.show()
+ self.main_box = dialog_box(pyWin, self.ctrl_win)
+ self.main_box.show()
+
+if __name__ == "__main__":
+ tb = my_top_block();
+ tb.start()
+ tb.qapp.exec_()
+ tb.stop()
+
diff --git a/gr-qtgui/apps/qt_digital.py b/gr-qtgui/apps/qt_digital.py
index c6920a05d..99c799f2a 100755
--- a/gr-qtgui/apps/qt_digital.py
+++ b/gr-qtgui/apps/qt_digital.py
@@ -274,3 +274,4 @@ if __name__ == "__main__":
tb = my_top_block();
tb.start()
tb.qapp.exec_()
+ tb.stop()
diff --git a/gr-qtgui/grc/Makefile.am b/gr-qtgui/grc/Makefile.am
index b3114268c..ccd459a13 100644
--- a/gr-qtgui/grc/Makefile.am
+++ b/gr-qtgui/grc/Makefile.am
@@ -29,5 +29,6 @@ dist_grcblocks_DATA = \
qtgui_label.xml \
qtgui_range.xml \
qtgui_sink_x.xml \
+ qtgui_time_sink_x.xml \
qtgui_tab_widget.xml \
qtgui_chooser.xml
diff --git a/gr-qtgui/grc/qtgui_time_sink_x.xml b/gr-qtgui/grc/qtgui_time_sink_x.xml
new file mode 100644
index 000000000..9c8da6fbc
--- /dev/null
+++ b/gr-qtgui/grc/qtgui_time_sink_x.xml
@@ -0,0 +1,78 @@
+<?xml version="1.0"?>
+<!--
+###################################################
+##QT GUI Sink
+###################################################
+ -->
+<block>
+ <name>QT GUI Time Sink</name>
+ <key>qtgui_time_sink_x</key>
+ <category>QT GUI Widgets</category>
+ <import>from PyQt4 import Qt</import>
+ <import>from gnuradio.qtgui import qtgui</import>
+ <import>from gnuradio.gr import firdes</import>
+ <import>import sip</import>
+ <make>#set $win = 'self._%s_win'%$id
+qtgui.$(type.fcn)(
+ $size, \#size
+ $bw, \#bw
+ $name, \#name
+ $nconnections \#number of inputs
+)
+self._$(id)_win = sip.wrapinstance(self.$(id).pyqwidget(), Qt.QWidget)
+$(gui_hint()($win))</make>
+ <callback>set_time_domain_axis($min, $max)</callback>
+ <callback>set_update_time($t)</callback>
+ <callback>set_title($which, $title)</callback>
+ <callback>set_color($which, $color)</callback>
+ <param>
+ <name>Type</name>
+ <key>type</key>
+ <value>complex</value>
+ <type>enum</type>
+ <option><name>Complex</name><key>complex</key><opt>fcn:time_sink_c</opt></option>
+ <option><name>Float</name><key>float</key><opt>fcn:time_sink_f</opt></option>
+ </param>
+ <param>
+ <name>Name</name>
+ <key>name</key>
+ <value>QT GUI Plot</value>
+ <type>string</type>
+ </param>
+ <param>
+ <name>Number of Points</name>
+ <key>size</key>
+ <value>1024</value>
+ <type>int</type>
+ </param>
+ <param>
+ <name>Bandwidth (Hz)</name>
+ <key>bw</key>
+ <value>samp_rate</value>
+ <type>real</type>
+ </param>
+ <param>
+ <name>Number of Inputs</name>
+ <key>nconnections</key>
+ <value>1</value>
+ <type>int</type>
+ <hide>part</hide>
+ </param>
+ <param>
+ <name>GUI Hint</name>
+ <key>gui_hint</key>
+ <value></value>
+ <type>gui_hint</type>
+ <hide>part</hide>
+ </param>
+ <sink>
+ <name>in</name>
+ <type>$type</type>
+ <nports>$nconnections</nports>
+ </sink>
+ <doc>
+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.
+ </doc>
+</block>
diff --git a/gr-qtgui/lib/ConstellationDisplayPlot.cc b/gr-qtgui/lib/ConstellationDisplayPlot.cc
index 75dbe9c37..dda7cfea2 100644
--- a/gr-qtgui/lib/ConstellationDisplayPlot.cc
+++ b/gr-qtgui/lib/ConstellationDisplayPlot.cc
@@ -1,3 +1,25 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2008,2009,2010,2011 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
#ifndef CONSTELLATION_DISPLAY_PLOT_C
#define CONSTELLATION_DISPLAY_PLOT_C
@@ -36,7 +58,7 @@ protected:
ConstellationDisplayPlot::ConstellationDisplayPlot(QWidget* parent)
: QwtPlot(parent)
{
- timespec_reset(&_lastReplot);
+ _lastReplot = 0;
resize(parent->width(), parent->height());
@@ -161,8 +183,8 @@ void ConstellationDisplayPlot::PlotNewData(const double* realDataPoints,
const double timeInterval)
{
if((numDataPoints > 0) &&
- (diff_timespec(get_highres_clock(), _lastReplot) > timeInterval)) {
-
+ (gruel::high_res_timer_now() - _lastReplot > timeInterval*gruel::high_res_timer_tps())) {
+
if(numDataPoints != _numPoints){
_numPoints = numDataPoints;
@@ -177,7 +199,7 @@ void ConstellationDisplayPlot::PlotNewData(const double* realDataPoints,
memcpy(_realDataPoints, realDataPoints, numDataPoints*sizeof(double));
memcpy(_imagDataPoints, imagDataPoints, numDataPoints*sizeof(double));
- _lastReplot = get_highres_clock();
+ _lastReplot = gruel::high_res_timer_now();
}
}
diff --git a/gr-qtgui/lib/ConstellationDisplayPlot.h b/gr-qtgui/lib/ConstellationDisplayPlot.h
index bf4531e0a..23004f86c 100644
--- a/gr-qtgui/lib/ConstellationDisplayPlot.h
+++ b/gr-qtgui/lib/ConstellationDisplayPlot.h
@@ -1,6 +1,29 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2008,2009,2010,2011 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
#ifndef CONSTELLATION_DISPLAY_PLOT_HPP
#define CONSTELLATION_DISPLAY_PLOT_HPP
+#include <stdint.h>
#include <cstdio>
#include <qwt_plot.h>
#include <qwt_painter.h>
@@ -11,7 +34,7 @@
#include <qwt_plot_zoomer.h>
#include <qwt_plot_panner.h>
#include <qwt_plot_marker.h>
-#include <highResTimeFunctions.h>
+#include <gruel/high_res_timer.h>
#include <qwt_symbol.h>
#include <qtgui_util.h>
@@ -60,7 +83,7 @@ private:
double* _realDataPoints;
double* _imagDataPoints;
- timespec _lastReplot;
+ gruel::high_res_timer_type _lastReplot;
int64_t _numPoints;
int64_t _penSize;
diff --git a/gr-qtgui/lib/FrequencyDisplayPlot.cc b/gr-qtgui/lib/FrequencyDisplayPlot.cc
index 30b318184..f57edd8f6 100644
--- a/gr-qtgui/lib/FrequencyDisplayPlot.cc
+++ b/gr-qtgui/lib/FrequencyDisplayPlot.cc
@@ -1,3 +1,25 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2008,2009,2010,2011 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
#ifndef FREQUENCY_DISPLAY_PLOT_C
#define FREQUENCY_DISPLAY_PLOT_C
@@ -98,7 +120,7 @@ FrequencyDisplayPlot::FrequencyDisplayPlot(QWidget* parent)
_startFrequency = 0;
_stopFrequency = 4000;
- timespec_reset(&_lastReplot);
+ _lastReplot = 0;
resize(parent->width(), parent->height());
@@ -340,7 +362,7 @@ FrequencyDisplayPlot::PlotNewData(const double* dataPoints, const int64_t numDat
{
// Only update plot if there is data and if the time interval has elapsed
if((numDataPoints > 0) &&
- (diff_timespec(get_highres_clock(), _lastReplot) > timeInterval)) {
+ (gruel::high_res_timer_now() - _lastReplot > timeInterval*gruel::high_res_timer_tps())) {
if(numDataPoints != _numPoints) {
_numPoints = numDataPoints;
@@ -379,7 +401,7 @@ FrequencyDisplayPlot::PlotNewData(const double* dataPoints, const int64_t numDat
SetUpperIntensityLevel(_peakAmplitude);
- _lastReplot = get_highres_clock();
+ _lastReplot = gruel::high_res_timer_now();
}
}
diff --git a/gr-qtgui/lib/FrequencyDisplayPlot.h b/gr-qtgui/lib/FrequencyDisplayPlot.h
index 7a207ab8d..a263fec2f 100644
--- a/gr-qtgui/lib/FrequencyDisplayPlot.h
+++ b/gr-qtgui/lib/FrequencyDisplayPlot.h
@@ -1,3 +1,25 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2008,2009,2010,2011 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
#ifndef FREQUENCY_DISPLAY_PLOT_HPP
#define FREQUENCY_DISPLAY_PLOT_HPP
@@ -13,7 +35,7 @@
#include <qwt_plot_panner.h>
#include <qwt_plot_marker.h>
#include <qwt_plot_magnifier.h>
-#include <highResTimeFunctions.h>
+#include <gruel/high_res_timer.h>
#include <qwt_symbol.h>
#include <qtgui_util.h>
@@ -100,7 +122,7 @@ private:
double _noiseFloorAmplitude;
- timespec _lastReplot;
+ gruel::high_res_timer_type _lastReplot;
bool _useCenterFrequencyFlag;
};
diff --git a/gr-qtgui/lib/Makefile.am b/gr-qtgui/lib/Makefile.am
index 7dee39eb4..849ee8360 100644
--- a/gr-qtgui/lib/Makefile.am
+++ b/gr-qtgui/lib/Makefile.am
@@ -24,12 +24,14 @@ include $(top_srcdir)/Makefile.common
EXTRA_DIST += spectrumdisplayform.ui
AM_CPPFLAGS = -I. $(STD_DEFINES_AND_INCLUDES) $(PYTHON_CPPFLAGS) \
- $(QT_INCLUDES) $(BOOST_CPPFLAGS) $(WITH_INCLUDES)
+ $(QT_INCLUDES) $(BOOST_CPPFLAGS) $(WITH_INCLUDES) \
+ -Dlibgnuradio_qtgui_EXPORTS
# Only include these files in the build if qtgui passes configure checks
# This is mostly to help make distcheck pass
QMAKE_SOURCES = \
spectrumdisplayform.moc.cc \
+ timedisplayform.moc.cc \
FrequencyDisplayPlot.moc.cc \
TimeDomainDisplayPlot.moc.cc \
WaterfallDisplayPlot.moc.cc \
@@ -49,11 +51,14 @@ libgnuradio_qtgui_la_SOURCES = \
waterfallGlobalData.cc \
ConstellationDisplayPlot.cc \
spectrumdisplayform.cc \
+ timedisplayform.cc \
SpectrumGUIClass.cc \
spectrumUpdateEvents.cc \
plot_waterfall.cc \
qtgui_sink_c.cc \
qtgui_sink_f.cc \
+ qtgui_time_sink_c.cc \
+ qtgui_time_sink_f.cc \
qtgui_util.cc
nodist_libgnuradio_qtgui_la_SOURCES=$(QMAKE_SOURCES)
@@ -65,13 +70,16 @@ grinclude_HEADERS = \
WaterfallDisplayPlot.h \
waterfallGlobalData.h \
ConstellationDisplayPlot.h \
- highResTimeFunctions.h \
plot_waterfall.h \
spectrumdisplayform.h \
+ timedisplayform.h \
SpectrumGUIClass.h \
spectrumUpdateEvents.h \
+ gr_qtgui_api.h \
qtgui_sink_c.h \
qtgui_sink_f.h \
+ qtgui_time_sink_c.h \
+ qtgui_time_sink_f.h \
qtgui_util.h
#QT_MOC_FLAGS=-DQT_SHARED -DQT_NO_DEBUG -DQT_OPENGL_LIB -DQT_GUI_LIB -DQT_CORE_LIB
diff --git a/gr-qtgui/lib/SpectrumGUIClass.cc b/gr-qtgui/lib/SpectrumGUIClass.cc
index 1a519591d..af95e2bb2 100644
--- a/gr-qtgui/lib/SpectrumGUIClass.cc
+++ b/gr-qtgui/lib/SpectrumGUIClass.cc
@@ -1,3 +1,25 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2008,2009,2010,2011 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
#ifndef SPECTRUM_GUI_CLASS_CPP
#define SPECTRUM_GUI_CLASS_CPP
@@ -32,7 +54,7 @@ SpectrumGUIClass::SpectrumGUIClass(const uint64_t maxDataSize,
_windowType = 5;
- timespec_reset(&_lastGUIUpdateTime);
+ _lastGUIUpdateTime = 0;
_windowOpennedFlag = false;
_fftBuffersCreatedFlag = false;
@@ -101,10 +123,10 @@ SpectrumGUIClass::OpenSpectrumWindow(QWidget* parent,
qApp->postEvent(_spectrumDisplayForm,
new QEvent(QEvent::Type(QEvent::User+3)));
- timespec_reset(&_lastGUIUpdateTime);
+ _lastGUIUpdateTime = 0;
// Draw Blank Display
- UpdateWindow(false, NULL, 0, NULL, 0, NULL, 0, get_highres_clock(), true);
+ UpdateWindow(false, NULL, 0, NULL, 0, NULL, 0, gruel::high_res_timer_now(), true);
// Set up the initial frequency axis settings
SetFrequencyRange(_centerFrequency, _startFrequency, _stopFrequency);
@@ -207,7 +229,7 @@ SpectrumGUIClass::UpdateWindow(const bool updateDisplayFlag,
const uint64_t realTimeDomainDataSize,
const float* complexTimeDomainData,
const uint64_t complexTimeDomainDataSize,
- const timespec timestamp,
+ const gruel::high_res_timer_type timestamp,
const bool lastOfMultipleFFTUpdateFlag)
{
//gruel::scoped_lock lock(d_mutex);
@@ -261,11 +283,11 @@ SpectrumGUIClass::UpdateWindow(const bool updateDisplayFlag,
_lastDataPointCount = bufferSize;
}
- const timespec currentTime = get_highres_clock();
- const timespec lastUpdateGUITime = GetLastGUIUpdateTime();
+ const gruel::high_res_timer_type currentTime = gruel::high_res_timer_now();
+ const gruel::high_res_timer_type lastUpdateGUITime = GetLastGUIUpdateTime();
- if((diff_timespec(currentTime, lastUpdateGUITime) > (4*_updateTime)) &&
- (GetPendingGUIUpdateEvents() > 0) && !timespec_empty(&lastUpdateGUITime)) {
+ if((currentTime - lastUpdateGUITime > (4*_updateTime)*gruel::high_res_timer_tps()) &&
+ (GetPendingGUIUpdateEvents() > 0) && lastUpdateGUITime != 0) {
// Do not update the display if too much data is pending to be displayed
_droppedEntriesCount++;
}
@@ -354,17 +376,17 @@ SpectrumGUIClass::SetFFTSize(const int newSize)
_fftSize = newSize;
}
-timespec
+gruel::high_res_timer_type
SpectrumGUIClass::GetLastGUIUpdateTime()
{
gruel::scoped_lock lock(d_mutex);
- timespec returnValue;
+ gruel::high_res_timer_type returnValue;
returnValue = _lastGUIUpdateTime;
return returnValue;
}
void
-SpectrumGUIClass::SetLastGUIUpdateTime(const timespec newTime)
+SpectrumGUIClass::SetLastGUIUpdateTime(const gruel::high_res_timer_type newTime)
{
gruel::scoped_lock lock(d_mutex);
_lastGUIUpdateTime = newTime;
diff --git a/gr-qtgui/lib/SpectrumGUIClass.h b/gr-qtgui/lib/SpectrumGUIClass.h
index 48f45a0f5..857c2515f 100644
--- a/gr-qtgui/lib/SpectrumGUIClass.h
+++ b/gr-qtgui/lib/SpectrumGUIClass.h
@@ -1,3 +1,25 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2008,2009,2010,2011 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
#ifndef SPECTRUM_GUI_CLASS_HPP
#define SPECTRUM_GUI_CLASS_HPP
@@ -44,7 +66,7 @@ public:
const uint64_t, const float*,
const uint64_t, const float*,
const uint64_t,
- const timespec, const bool);
+ const gruel::high_res_timer_type, const bool);
float GetPowerValue();
void SetPowerValue(const float);
@@ -56,8 +78,8 @@ public:
int GetFFTSizeIndex();
void SetFFTSize(const int);
- timespec GetLastGUIUpdateTime();
- void SetLastGUIUpdateTime(const timespec);
+ gruel::high_res_timer_type GetLastGUIUpdateTime();
+ void SetLastGUIUpdateTime(const gruel::high_res_timer_type);
unsigned int GetPendingGUIUpdateEvents();
void IncrementPendingGUIUpdateEvents();
@@ -92,7 +114,7 @@ private:
int _windowType;
int64_t _lastDataPointCount;
int _fftSize;
- timespec _lastGUIUpdateTime;
+ gruel::high_res_timer_type _lastGUIUpdateTime;
unsigned int _pendingGUIUpdateEventsCount;
int _droppedEntriesCount;
bool _fftBuffersCreatedFlag;
diff --git a/gr-qtgui/lib/TimeDomainDisplayPlot.cc b/gr-qtgui/lib/TimeDomainDisplayPlot.cc
index be25a6cde..f635a2b0c 100644
--- a/gr-qtgui/lib/TimeDomainDisplayPlot.cc
+++ b/gr-qtgui/lib/TimeDomainDisplayPlot.cc
@@ -1,3 +1,25 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2008,2009,2010,2011 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
#ifndef TIME_DOMAIN_DISPLAY_PLOT_C
#define TIME_DOMAIN_DISPLAY_PLOT_C
@@ -5,7 +27,8 @@
#include <qwt_scale_draw.h>
#include <qwt_legend.h>
-
+#include <QColor>
+#include <iostream>
class TimePrecisionClass
{
@@ -70,16 +93,14 @@ private:
std::string _unitType;
};
-TimeDomainDisplayPlot::TimeDomainDisplayPlot(QWidget* parent):QwtPlot(parent)
+TimeDomainDisplayPlot::TimeDomainDisplayPlot(int nplots, QWidget* parent)
+ : QwtPlot(parent), _nplots(nplots)
{
- timespec_reset(&_lastReplot);
-
resize(parent->width(), parent->height());
_numPoints = 1024;
- _realDataPoints = new double[_numPoints];
- _imagDataPoints = new double[_numPoints];
_xAxisPoints = new double[_numPoints];
+ memset(_xAxisPoints, 0x0, _numPoints*sizeof(double));
_zoomer = new TimeDomainDisplayZoomer(canvas(), 0);
_zoomer->setSelectionFlags(QwtPicker::RectSelection | QwtPicker::DragSelection);
@@ -96,41 +117,40 @@ TimeDomainDisplayPlot::TimeDomainDisplayPlot(QWidget* parent):QwtPlot(parent)
canvas()->setPalette(palette);
setAxisScaleEngine(QwtPlot::xBottom, new QwtLinearScaleEngine);
- set_xaxis(0, _numPoints);
+ setXaxis(0, _numPoints);
setAxisTitle(QwtPlot::xBottom, "Time (sec)");
setAxisScaleEngine(QwtPlot::yLeft, new QwtLinearScaleEngine);
- set_yaxis(-2.0, 2.0);
- setAxisTitle(QwtPlot::yLeft, "Normalized Voltage");
+ setYaxis(-2.0, 2.0);
+ setAxisTitle(QwtPlot::yLeft, "Amplitude");
+ QList<QColor> colors;
+ colors << QColor(Qt::blue) << QColor(Qt::red) << QColor(Qt::green)
+ << QColor(Qt::black) << QColor(Qt::cyan) << QColor(Qt::magenta)
+ << QColor(Qt::yellow) << QColor(Qt::gray) << QColor(Qt::darkRed)
+ << QColor(Qt::darkGreen) << QColor(Qt::darkBlue) << QColor(Qt::darkGray);
+
+ int ncolors = colors.size();
+
+ // Setup dataPoints and plot vectors
// Automatically deleted when parent is deleted
- _real_plot_curve = new QwtPlotCurve("Real Data");
- _real_plot_curve->attach(this);
- _real_plot_curve->setPen(QPen(Qt::blue));
- _real_plot_curve->setRawData(_xAxisPoints, _realDataPoints, _numPoints);
-
- _imag_plot_curve = new QwtPlotCurve("Imaginary Data");
- _imag_plot_curve->attach(this);
- _imag_plot_curve->setPen(QPen(Qt::magenta));
- _imag_plot_curve->setRawData(_xAxisPoints, _imagDataPoints, _numPoints);
- // _imag_plot_curve->setVisible(false);
-
- memset(_realDataPoints, 0x0, _numPoints*sizeof(double));
- memset(_imagDataPoints, 0x0, _numPoints*sizeof(double));
- memset(_xAxisPoints, 0x0, _numPoints*sizeof(double));
+ for(int i = 0; i < _nplots; i++) {
+ _dataPoints.push_back(new double[_numPoints]);
+ memset(_dataPoints[i], 0x0, _numPoints*sizeof(double));
+
+ _plot_curve.push_back(new QwtPlotCurve(QString("Data %1").arg(i)));
+ _plot_curve[i]->attach(this);
+ _plot_curve[i]->setPen(QPen(colors[i]));
+ _plot_curve[i]->setRawData(_xAxisPoints, _dataPoints[i], _numPoints);
+ }
_sampleRate = 1;
_resetXAxisPoints();
-#if QT_VERSION < 0x040000
- _zoomer->setMousePattern(QwtEventPattern::MouseSelect2,
- Qt::RightButton, Qt::ControlModifier);
-#else
_zoomer->setMousePattern(QwtEventPattern::MouseSelect2,
- Qt::RightButton, Qt::ControlModifier);
-#endif
+ Qt::RightButton, Qt::ControlModifier);
_zoomer->setMousePattern(QwtEventPattern::MouseSelect3,
- Qt::RightButton);
+ Qt::RightButton);
_panner = new QwtPlotPanner(canvas());
_panner->setAxisEnabled(QwtPlot::yRight, false);
@@ -164,29 +184,40 @@ TimeDomainDisplayPlot::TimeDomainDisplayPlot(QWidget* parent):QwtPlot(parent)
this, SLOT( LegendEntryChecked(QwtPlotItem *, bool ) ));
}
-TimeDomainDisplayPlot::~TimeDomainDisplayPlot(){
- delete[] _realDataPoints;
- delete[] _imagDataPoints;
+TimeDomainDisplayPlot::~TimeDomainDisplayPlot()
+{
+ for(int i = 0; i < _nplots; i++)
+ delete [] _dataPoints[i];
delete[] _xAxisPoints;
- // _fft_plot_curves deleted when parent deleted
// _zoomer and _panner deleted when parent deleted
}
void
-TimeDomainDisplayPlot::set_yaxis(double min, double max)
+TimeDomainDisplayPlot::setYaxis(double min, double max)
{
setAxisScale(QwtPlot::yLeft, min, max);
_zoomer->setZoomBase();
}
void
-TimeDomainDisplayPlot::set_xaxis(double min, double max)
+TimeDomainDisplayPlot::setXaxis(double min, double max)
{
setAxisScale(QwtPlot::xBottom, min, max);
_zoomer->setZoomBase();
}
+void
+TimeDomainDisplayPlot::setTitle(int which, QString title)
+{
+ _plot_curve[which]->setTitle(title);
+}
+
+void
+TimeDomainDisplayPlot::setColor(int which, QString color)
+{
+ _plot_curve[which]->setPen(QPen(color));
+}
void TimeDomainDisplayPlot::replot()
{
@@ -196,47 +227,37 @@ void TimeDomainDisplayPlot::replot()
void
TimeDomainDisplayPlot::resizeSlot( QSize *s )
{
- resize(s->width(), s->height());
+ // -10 is to spare some room for the legend and x-axis label
+ resize(s->width()-10, s->height()-10);
}
-void TimeDomainDisplayPlot::PlotNewData(const double* realDataPoints,
- const double* imagDataPoints,
+void TimeDomainDisplayPlot::PlotNewData(const std::vector<double*> dataPoints,
const int64_t numDataPoints,
const double timeInterval)
{
- if((numDataPoints > 0) &&
- (diff_timespec(get_highres_clock(), _lastReplot) > timeInterval)) {
-
+ if((numDataPoints > 0)) {
if(numDataPoints != _numPoints){
_numPoints = numDataPoints;
- delete[] _realDataPoints;
- delete[] _imagDataPoints;
delete[] _xAxisPoints;
- _realDataPoints = new double[_numPoints];
- _imagDataPoints = new double[_numPoints];
_xAxisPoints = new double[_numPoints];
-
- _real_plot_curve->setRawData(_xAxisPoints, _realDataPoints, _numPoints);
- _imag_plot_curve->setRawData(_xAxisPoints, _imagDataPoints, _numPoints);
-
- set_xaxis(0, numDataPoints);
+ for(int i = 0; i < _nplots; i++) {
+ delete[] _dataPoints[i];
+ _dataPoints[i] = new double[_numPoints];
+ _plot_curve[i]->setRawData(_xAxisPoints, _dataPoints[i], _numPoints);
+ }
+
+ setXaxis(0, numDataPoints);
_resetXAxisPoints();
}
- memcpy(_realDataPoints, realDataPoints, numDataPoints*sizeof(double));
- memcpy(_imagDataPoints, imagDataPoints, numDataPoints*sizeof(double));
-
- _lastReplot = get_highres_clock();
+ for(int i = 0; i < _nplots; i++) {
+ memcpy(_dataPoints[i], dataPoints[i], numDataPoints*sizeof(double));
+ }
}
}
-void TimeDomainDisplayPlot::SetImaginaryDataVisible(const bool visibleFlag)
-{
- _imag_plot_curve->setVisible(visibleFlag);
-}
-
void TimeDomainDisplayPlot::_resetXAxisPoints()
{
double delt = 1.0/_sampleRate;
diff --git a/gr-qtgui/lib/TimeDomainDisplayPlot.h b/gr-qtgui/lib/TimeDomainDisplayPlot.h
index 01338300c..af87e1b14 100644
--- a/gr-qtgui/lib/TimeDomainDisplayPlot.h
+++ b/gr-qtgui/lib/TimeDomainDisplayPlot.h
@@ -1,8 +1,31 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2008,2009,2010,2011 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
#ifndef TIME_DOMAIN_DISPLAY_PLOT_HPP
#define TIME_DOMAIN_DISPLAY_PLOT_HPP
#include <stdint.h>
#include <cstdio>
+#include <vector>
#include <qwt_plot.h>
#include <qwt_painter.h>
#include <qwt_plot_canvas.h>
@@ -13,7 +36,6 @@
#include <qwt_plot_panner.h>
#include <qwt_plot_magnifier.h>
#include <qwt_plot_marker.h>
-#include <highResTimeFunctions.h>
#include <qwt_symbol.h>
#include <qtgui_util.h>
@@ -21,20 +43,20 @@ class TimeDomainDisplayPlot:public QwtPlot{
Q_OBJECT
public:
- TimeDomainDisplayPlot(QWidget*);
+ TimeDomainDisplayPlot(int nplots, QWidget*);
virtual ~TimeDomainDisplayPlot();
- void PlotNewData(const double* realDataPoints, const double* imagDataPoints,
+ void PlotNewData(const std::vector<double*> dataPoints,
const int64_t numDataPoints, const double timeInterval);
- void SetImaginaryDataVisible(const bool);
-
virtual void replot();
- void set_yaxis(double min, double max);
- void set_xaxis(double min, double max);
-
public slots:
+ void setYaxis(double min, double max);
+ void setXaxis(double min, double max);
+ void setTitle(int which, QString title);
+ void setColor(int which, QString color);
+
void resizeSlot( QSize *s );
void SetSampleRate(double sr, double units,
const std::string &strunits);
@@ -52,8 +74,8 @@ protected:
private:
void _resetXAxisPoints();
- QwtPlotCurve* _real_plot_curve;
- QwtPlotCurve* _imag_plot_curve;
+ int _nplots;
+ std::vector<QwtPlotCurve*> _plot_curve;
QwtPlotPanner* _panner;
QwtPlotZoomer* _zoomer;
@@ -61,14 +83,11 @@ private:
QwtDblClickPlotPicker *_picker;
QwtPlotMagnifier *_magnifier;
- double* _realDataPoints;
- double* _imagDataPoints;
+ std::vector<double*> _dataPoints;
double* _xAxisPoints;
double _sampleRate;
- timespec _lastReplot;
-
int64_t _numPoints;
};
diff --git a/gr-qtgui/lib/WaterfallDisplayPlot.cc b/gr-qtgui/lib/WaterfallDisplayPlot.cc
index 2234f4238..1476be2bd 100644
--- a/gr-qtgui/lib/WaterfallDisplayPlot.cc
+++ b/gr-qtgui/lib/WaterfallDisplayPlot.cc
@@ -1,3 +1,25 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2008,2009,2010,2011 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
#ifndef WATERFALL_DISPLAY_PLOT_C
#define WATERFALL_DISPLAY_PLOT_C
@@ -88,7 +110,7 @@ class TimeScaleData
public:
TimeScaleData()
{
- timespec_reset(&_zeroTime);
+ _zeroTime = 0;
_secondsPerLine = 1.0;
}
@@ -96,14 +118,14 @@ public:
{
}
- virtual timespec GetZeroTime() const
+ virtual gruel::high_res_timer_type GetZeroTime() const
{
return _zeroTime;
}
- virtual void SetZeroTime(const timespec newTime)
+ virtual void SetZeroTime(const gruel::high_res_timer_type newTime)
{
- _zeroTime = newTime;
+ _zeroTime = newTime - gruel::high_res_timer_epoch();
}
virtual void SetSecondsPerLine(const double newTime)
@@ -118,13 +140,26 @@ public:
protected:
- timespec _zeroTime;
+ gruel::high_res_timer_type _zeroTime;
double _secondsPerLine;
private:
};
+static QString
+make_time_label(double secs)
+{
+ std::string time_str = pt::to_simple_string(pt::from_time_t(time_t(secs)));
+
+ // lops off the YYYY-mmm-DD part of the string
+ size_t ind = time_str.find(" ");
+ if(ind != std::string::npos)
+ time_str = time_str.substr(ind);
+
+ return QString("").sprintf("%s.%03ld", time_str.c_str(), long(std::fmod(secs*1000, 1000)));
+}
+
class QwtTimeScaleDraw: public QwtScaleDraw, public TimeScaleData
{
public:
@@ -138,14 +173,8 @@ public:
virtual QwtText label(double value) const
{
- timespec lineTime = timespec_add(GetZeroTime(), (-value) * GetSecondsPerLine());
- std::string time_str = pt::to_simple_string(pt::from_time_t(lineTime.tv_sec));
-
- // lops off the YYYY-mmm-DD part of the string
- size_t ind = time_str.find(" ");
- if(ind != std::string::npos)
- time_str = time_str.substr(ind);
- return QwtText(QString("").sprintf("%s.%03ld", time_str.c_str(), lineTime.tv_nsec/1000000));
+ double secs = GetZeroTime()/double(gruel::high_res_timer_tps()) - (value * GetSecondsPerLine());
+ return QwtText(make_time_label(secs));
}
virtual void initiateUpdate()
@@ -190,18 +219,10 @@ protected:
using QwtPlotZoomer::trackerText;
virtual QwtText trackerText( const QwtDoublePoint& p ) const
{
- timespec lineTime = timespec_add(GetZeroTime(), (-p.y()) * GetSecondsPerLine());
- std::string time_str = pt::to_simple_string(pt::from_time_t(lineTime.tv_sec));
-
- // lops off the YYYY-mmm-DD part of the string
- size_t ind = time_str.find(" ");
- if(ind != std::string::npos)
- time_str = time_str.substr(ind);
- QString yLabel(QString("").sprintf("%s.%03ld", time_str.c_str(), lineTime.tv_nsec/1000000));
-
+ double secs = GetZeroTime()/double(gruel::high_res_timer_tps()) - (p.y() * GetSecondsPerLine());
QwtText t(QString("%1 %2, %3").
- arg(p.x(), 0, 'f', GetFrequencyPrecision()).
- arg(_unitType.c_str()).arg(yLabel));
+ arg(p.x(), 0, 'f', GetFrequencyPrecision()).
+ arg(_unitType.c_str()).arg(make_time_label(secs)));
return t;
}
@@ -232,7 +253,7 @@ WaterfallDisplayPlot::WaterfallDisplayPlot(QWidget* parent)
setAxisTitle(QwtPlot::yLeft, "Time");
setAxisScaleDraw(QwtPlot::yLeft, new QwtTimeScaleDraw());
- timespec_reset(&_lastReplot);
+ _lastReplot = 0;
d_spectrogram = new PlotWaterfall(_waterfallData, "Waterfall Display");
@@ -367,7 +388,7 @@ void
WaterfallDisplayPlot::PlotNewData(const double* dataPoints,
const int64_t numDataPoints,
const double timePerFFT,
- const timespec timestamp,
+ const gruel::high_res_timer_type timestamp,
const int droppedFrames)
{
if(numDataPoints > 0){
@@ -383,10 +404,10 @@ WaterfallDisplayPlot::PlotNewData(const double* dataPoints,
replot();
}
- _lastReplot = get_highres_clock();
+ _lastReplot = gruel::high_res_timer_now();
}
- if(diff_timespec(get_highres_clock(), _lastReplot) > timePerFFT) {
+ if(gruel::high_res_timer_now() - _lastReplot > timePerFFT*gruel::high_res_timer_tps()) {
//FIXME: We may want to average the data between these updates to smooth display
_waterfallData->addFFTData(dataPoints, numDataPoints, droppedFrames);
_waterfallData->IncrementNumLinesToUpdate();
@@ -403,7 +424,7 @@ WaterfallDisplayPlot::PlotNewData(const double* dataPoints,
replot();
- _lastReplot = get_highres_clock();
+ _lastReplot = gruel::high_res_timer_now();
}
}
}
@@ -546,7 +567,7 @@ WaterfallDisplayPlot::_UpdateIntensityRangeDisplay()
replot();
// Update the last replot timer
- _lastReplot = get_highres_clock();
+ _lastReplot = gruel::high_res_timer_now();
}
void
diff --git a/gr-qtgui/lib/WaterfallDisplayPlot.h b/gr-qtgui/lib/WaterfallDisplayPlot.h
index faa48d6aa..0c6a521b1 100644
--- a/gr-qtgui/lib/WaterfallDisplayPlot.h
+++ b/gr-qtgui/lib/WaterfallDisplayPlot.h
@@ -1,3 +1,25 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2008,2009,2010,2011 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
#ifndef WATERFALL_DISPLAY_PLOT_HPP
#define WATERFALL_DISPLAY_PLOT_HPP
@@ -10,7 +32,7 @@
#include <qtgui_util.h>
#include <plot_waterfall.h>
-#include <highResTimeFunctions.h>
+#include <gruel/high_res_timer.h>
class WaterfallDisplayPlot:public QwtPlot{
Q_OBJECT
@@ -29,7 +51,7 @@ public:
double GetStopFrequency()const;
void PlotNewData(const double* dataPoints, const int64_t numDataPoints,
- const double timePerFFT, const timespec timestamp,
+ const double timePerFFT, const gruel::high_res_timer_type timestamp,
const int droppedFrames);
void SetIntensityRange(const double minIntensity, const double maxIntensity);
@@ -76,7 +98,7 @@ private:
WaterfallData* _waterfallData;
- timespec _lastReplot;
+ gruel::high_res_timer_type _lastReplot;
bool _useCenterFrequencyFlag;
diff --git a/gr-qtgui/lib/gr_qtgui_api.h b/gr-qtgui/lib/gr_qtgui_api.h
new file mode 100644
index 000000000..65033a093
--- /dev/null
+++ b/gr-qtgui/lib/gr_qtgui_api.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_QTGUI_API_H
+#define INCLUDED_GR_QTGUI_API_H
+
+#include <gruel/attributes.h>
+
+#ifdef libgnuradio_qtgui_EXPORTS
+# define GR_QTGUI_API __GR_ATTR_EXPORT
+#else
+# define GR_QTGUI_API __GR_ATTR_IMPORT
+#endif
+
+#endif /* INCLUDED_GR_QTGUI_API_H */
diff --git a/gr-qtgui/lib/highResTimeFunctions.h b/gr-qtgui/lib/highResTimeFunctions.h
index 251bbad8b..6b3844901 100644
--- a/gr-qtgui/lib/highResTimeFunctions.h
+++ b/gr-qtgui/lib/highResTimeFunctions.h
@@ -1,299 +1,36 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2011 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
#ifndef HIGH_RES_TIME_FUNCTIONS_H
#define HIGH_RES_TIME_FUNCTIONS_H
-#include <ctime>
-#include <sys/time.h>
-#include <cmath>
-/* Requires the librt and libm libraries */
-
-static const long NSEC_PER_SEC = 1000000000L;
-
-static inline bool
-timespec_greater(const struct timespec* t1,
- const struct timespec* t0)
-{
- return ((t1->tv_sec > t0->tv_sec) ||
- ((t1->tv_sec == t0->tv_sec) &&
- (t1->tv_nsec > t0->tv_nsec)));
-}
-
-static inline bool
-timespec_greater(const struct timespec t1,
- const struct timespec t0)
-{
- return ((t1.tv_sec > t0.tv_sec) ||
- ((t1.tv_sec == t0.tv_sec) &&
- (t1.tv_nsec > t0.tv_nsec)));
-}
-
-static inline bool
-timespec_less(const struct timespec* t1,
- const struct timespec* t0)
-{
- return ((t1->tv_sec < t0->tv_sec) ||
- ((t1->tv_sec == t0->tv_sec) &&
- (t1->tv_nsec < t0->tv_nsec)));
-}
-
-static inline bool
-timespec_less(const struct timespec t1,
- const struct timespec t0)
-{
- return ((t1.tv_sec < t0.tv_sec) ||
- ((t1.tv_sec == t0.tv_sec) &&
- (t1.tv_nsec < t0.tv_nsec)));
-}
-
-static inline bool
-timespec_equal(const struct timespec* t1,
- const struct timespec* t0)
-{
- return ((t1->tv_sec == t0->tv_sec) &&
- (t1->tv_nsec == t0->tv_nsec));
-}
-
-static inline bool
-timespec_equal(const struct timespec t1,
- const struct timespec t0)
-{
- return ((t1.tv_sec == t0.tv_sec) &&
- (t1.tv_nsec == t0.tv_nsec));
-}
-
-static inline void
-timespec_reset(struct timespec* ret)
-{
- ret->tv_sec = 0;
- ret->tv_nsec = 0;
-}
-
-static inline void
-set_normalized_timespec(struct timespec *ts,
- time_t sec, long nsec)
-{
- while (nsec > NSEC_PER_SEC) {
- nsec -= NSEC_PER_SEC;
- ++sec;
- }
- while(nsec < 0) {
- nsec += NSEC_PER_SEC;
- --sec;
- }
- ts->tv_sec = sec;
- ts->tv_nsec = nsec;
-}
-
-static inline struct timespec
-convert_to_timespec(const double timeValue)
-{
- struct timespec ret;
- double seconds = 0;
- long nsec = static_cast<long>(modf(timeValue, &seconds) *
- static_cast<double>(NSEC_PER_SEC));
- time_t sec = static_cast<time_t>(seconds);
-
- set_normalized_timespec(&ret, sec, nsec);
-
- return ret;
-}
-
-static inline double
-convert_from_timespec(const timespec actual)
-{
- return (static_cast<double>(actual.tv_sec) +
- (static_cast<double>(actual.tv_nsec) /
- static_cast<double>(NSEC_PER_SEC)));
-}
-
-static inline void
-timespec_add(struct timespec *ret,
- const struct timespec* t1,
- const struct timespec* t0)
-{
- time_t sec = t1->tv_sec + t0->tv_sec;
- long nsec = t1->tv_nsec + t0->tv_nsec;
+#include <gruel/high_res_timer.h>
- set_normalized_timespec(ret, sec, nsec);
-}
-
-static inline void
-timespec_add(struct timespec *ret,
- const struct timespec t1,
- const struct timespec t0)
-{
- return timespec_add(ret, &t1, &t0);
-}
-
-static inline struct timespec
-timespec_add(const struct timespec t1,
- const struct timespec t0)
-{
- struct timespec ret;
- timespec_add(&ret, &t1, &t0);
- return ret;
-}
-
-static inline struct timespec
-timespec_add(const struct timespec t1,
- const double time0)
-{
- struct timespec ret;
- struct timespec t0;
- t0 = convert_to_timespec(time0);
-
- timespec_add(&ret, &t1, &t0);
-
- return ret;
-}
+typedef gruel::high_res_timer_type highres_timespec;
-static inline void
-timespec_subtract(struct timespec *ret,
- const struct timespec* t1,
- const struct timespec* t0)
-{
- time_t sec = t1->tv_sec - t0->tv_sec;
- long nsec = t1->tv_nsec - t0->tv_nsec;
-
- set_normalized_timespec(ret, sec, nsec);
-}
-
-static inline void
-timespec_subtract(struct timespec *ret,
- const struct timespec t1,
- const struct timespec t0)
-{
- return timespec_subtract(ret, &t1, &t0);
-}
-
-static inline struct timespec
-timespec_subtract(const struct timespec t1,
- const struct timespec t0)
-{
- struct timespec ret;
- timespec_subtract(&ret, &t1, &t0);
- return ret;
-}
-
-static inline struct timespec
-timespec_subtract(const struct timespec t1,
- const double time0)
-{
- struct timespec ret;
- struct timespec t0;
- t0 = convert_to_timespec(time0);
-
- timespec_subtract(&ret, &t1, &t0);
-
- return ret;
-}
-
-static inline double
-diff_timespec(struct timespec* ret,
- const struct timespec *t1,
- const struct timespec* t0)
-{
- struct timespec actual;
- time_t sec = 0;
- long nsec = 0;
-
- if(timespec_greater(t1, t0)){
- sec = t1->tv_sec - t0->tv_sec;
- nsec = t1->tv_nsec - t0->tv_nsec;
-
- set_normalized_timespec(&actual, sec, nsec);
-
- if(ret != NULL){
- ret->tv_sec = actual.tv_sec;
- ret->tv_nsec = actual.tv_nsec;
- }
-
- return convert_from_timespec(actual);
- }
- else{
- sec = t0->tv_sec - t1->tv_sec;
- nsec = t0->tv_nsec - t1->tv_nsec;
-
- // Do nothing with the ret value as the ret value
- // would have to store a negative, which it can't.
-
- set_normalized_timespec(&actual, sec, nsec);
-
- return (-convert_from_timespec(actual));
- }
-}
-
-static inline double
-diff_timespec(struct timespec* ret,
- const struct timespec t1,
- const struct timespec t0)
-{
- return diff_timespec(ret, &t1, &t0);
-}
-
-static inline double
-diff_timespec(const struct timespec t1,
- const struct timespec t0)
-{
- return diff_timespec(NULL, &t1, &t0);
-}
-
-
-static inline double
-diff_timespec(const struct timespec* t1,
- const struct timespec* t0)
-{
- return diff_timespec(NULL, t1, t0);
-}
-
-
-#ifdef CLOCK_REALTIME
-// If we can use clock_gettime, use it;
-// otherwise, use gettimeofday
-static inline void
-get_highres_clock(struct timespec* ret)
-{
- if(clock_gettime(CLOCK_REALTIME, ret) != 0){
- // Unable to get high resolution time -
- // fail over to low resolution time
- timeval lowResTime;
- gettimeofday(&lowResTime, NULL);
- ret->tv_sec = lowResTime.tv_sec;
- ret->tv_nsec = lowResTime.tv_usec*1000;
- }
-}
-
-#else
-
-// Trick timer functions into thinking it has an nsec timer
-// but only use the low resolution (usec) timer.
-static inline void
-get_highres_clock(struct timespec* ret)
-{
- timeval lowResTime;
- gettimeofday(&lowResTime, NULL);
- ret->tv_sec = lowResTime.tv_sec;
- ret->tv_nsec = lowResTime.tv_usec*1000;
-}
-#endif
-
-static inline struct timespec
+static inline highres_timespec
get_highres_clock()
{
- struct timespec ret;
- get_highres_clock(&ret);
- return ret;
-}
-
-static inline bool
-timespec_empty(const struct timespec* ret)
-{
- return ( (ret->tv_sec == 0 ) && (ret->tv_nsec == 0) );
-}
-
-static inline bool
-timespec_empty(const struct timespec ret)
-{
- return timespec_empty(&ret);
+ return gruel::high_res_timer_now();
}
#endif /* HIGH_RES_TIME_FUNCTIONS_H */
diff --git a/gr-qtgui/lib/qtgui_sink_c.cc b/gr-qtgui/lib/qtgui_sink_c.cc
index 7b40dd01d..965be0773 100644
--- a/gr-qtgui/lib/qtgui_sink_c.cc
+++ b/gr-qtgui/lib/qtgui_sink_c.cc
@@ -272,7 +272,7 @@ qtgui_sink_c::general_work (int noutput_items,
// If we have enough input for one full FFT, do it
if(datasize >= resid) {
- const timespec currentTime = get_highres_clock();
+ const gruel::high_res_timer_type currentTime = gruel::high_res_timer_now();
// Fill up residbuf with d_fftsize number of items
memcpy(d_residbuf+d_index, &in[j], sizeof(gr_complex)*resid);
diff --git a/gr-qtgui/lib/qtgui_sink_c.h b/gr-qtgui/lib/qtgui_sink_c.h
index fb0cb6c5f..b0946885c 100644
--- a/gr-qtgui/lib/qtgui_sink_c.h
+++ b/gr-qtgui/lib/qtgui_sink_c.h
@@ -24,6 +24,7 @@
#define INCLUDED_QTGUI_SINK_C_H
#include <Python.h>
+#include <gr_qtgui_api.h>
#include <gr_block.h>
#include <gr_firdes.h>
#include <gri_fft.h>
@@ -33,17 +34,17 @@
class qtgui_sink_c;
typedef boost::shared_ptr<qtgui_sink_c> qtgui_sink_c_sptr;
-qtgui_sink_c_sptr qtgui_make_sink_c (int fftsize, int wintype,
+GR_QTGUI_API qtgui_sink_c_sptr qtgui_make_sink_c (int fftsize, int wintype,
double fc=0, double bandwidth=1.0,
const std::string &name="Spectrum Display",
bool plotfreq=true, bool plotwaterfall=true,
bool plottime=true, bool plotconst=true,
QWidget *parent=NULL);
-class qtgui_sink_c : public gr_block
+class GR_QTGUI_API qtgui_sink_c : public gr_block
{
private:
- friend qtgui_sink_c_sptr qtgui_make_sink_c (int fftsize, int wintype,
+ friend GR_QTGUI_API qtgui_sink_c_sptr qtgui_make_sink_c (int fftsize, int wintype,
double fc, double bw,
const std::string &name,
bool plotfreq, bool plotwaterfall,
diff --git a/gr-qtgui/lib/qtgui_sink_f.cc b/gr-qtgui/lib/qtgui_sink_f.cc
index 3312b9006..a435064c0 100644
--- a/gr-qtgui/lib/qtgui_sink_f.cc
+++ b/gr-qtgui/lib/qtgui_sink_f.cc
@@ -268,7 +268,7 @@ qtgui_sink_f::general_work (int noutput_items,
// If we have enough input for one full FFT, do it
if(datasize >= resid) {
- const timespec currentTime = get_highres_clock();
+ const gruel::high_res_timer_type currentTime = gruel::high_res_timer_now();
// Fill up residbuf with d_fftsize number of items
memcpy(d_residbuf+d_index, &in[j], sizeof(float)*resid);
diff --git a/gr-qtgui/lib/qtgui_sink_f.h b/gr-qtgui/lib/qtgui_sink_f.h
index 518aa3846..30db05eea 100644
--- a/gr-qtgui/lib/qtgui_sink_f.h
+++ b/gr-qtgui/lib/qtgui_sink_f.h
@@ -24,6 +24,7 @@
#define INCLUDED_QTGUI_SINK_F_H
#include <Python.h>
+#include <gr_qtgui_api.h>
#include <gr_block.h>
#include <gr_firdes.h>
#include <gri_fft.h>
@@ -34,17 +35,17 @@
class qtgui_sink_f;
typedef boost::shared_ptr<qtgui_sink_f> qtgui_sink_f_sptr;
-qtgui_sink_f_sptr qtgui_make_sink_f (int fftsize, int wintype,
+GR_QTGUI_API qtgui_sink_f_sptr qtgui_make_sink_f (int fftsize, int wintype,
double fc=0, double bw=1.0,
const std::string &name="Spectrum Display",
bool plotfreq=true, bool plotwaterfall=true,
bool plottime=true, bool plotconst=true,
QWidget *parent=NULL);
-class qtgui_sink_f : public gr_block
+class GR_QTGUI_API qtgui_sink_f : public gr_block
{
private:
- friend qtgui_sink_f_sptr qtgui_make_sink_f (int fftsize, int wintype,
+ friend GR_QTGUI_API qtgui_sink_f_sptr qtgui_make_sink_f (int fftsize, int wintype,
double fc, double bw,
const std::string &name,
bool plotfreq, bool plotwaterfall,
diff --git a/gr-qtgui/lib/qtgui_time_sink_c.cc b/gr-qtgui/lib/qtgui_time_sink_c.cc
new file mode 100644
index 000000000..3d38419b2
--- /dev/null
+++ b/gr-qtgui/lib/qtgui_time_sink_c.cc
@@ -0,0 +1,199 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2011 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <qtgui_time_sink_c.h>
+#include <gr_io_signature.h>
+#include <string.h>
+
+#include <QTimer>
+
+qtgui_time_sink_c_sptr
+qtgui_make_time_sink_c (int size, double bw,
+ const std::string &name,
+ int nconnections,
+ QWidget *parent)
+{
+ return gnuradio::get_initial_sptr(new qtgui_time_sink_c (size, bw, name,
+ nconnections, parent));
+}
+
+qtgui_time_sink_c::qtgui_time_sink_c (int size, double bw,
+ const std::string &name,
+ int nconnections,
+ QWidget *parent)
+ : gr_block ("time_sink_c",
+ gr_make_io_signature (nconnections, nconnections, sizeof(gr_complex)),
+ gr_make_io_signature (0, 0, 0)),
+ d_size(size), d_bandwidth(bw), d_name(name),
+ d_nconnections(2*nconnections), d_parent(parent)
+{
+ d_main_gui = NULL;
+
+ d_index = 0;
+
+ for(int i = 0; i < d_nconnections; i++) {
+ d_residbufs.push_back(new double[d_size]);
+ }
+
+ initialize();
+}
+
+qtgui_time_sink_c::~qtgui_time_sink_c()
+{
+ // d_main_gui is a qwidget destroyed with its parent
+ for(int i = 0; i < d_nconnections; i++) {
+ delete [] d_residbufs[i];
+ }
+}
+
+void
+qtgui_time_sink_c::forecast(int noutput_items, gr_vector_int &ninput_items_required)
+{
+ unsigned int ninputs = ninput_items_required.size();
+ for (unsigned int i = 0; i < ninputs; i++) {
+ ninput_items_required[i] = std::min(d_size, 8191);
+ }
+}
+
+void
+qtgui_time_sink_c::initialize()
+{
+ if(qApp != NULL) {
+ d_qApplication = qApp;
+ }
+ else {
+ int argc=0;
+ char **argv = NULL;
+ d_qApplication = new QApplication(argc, argv);
+ }
+
+ d_main_gui = new TimeDisplayForm(d_nconnections, d_parent);
+
+ // initialize update time to 10 times a second
+ set_update_time(0.1);
+ d_last_time = 0;
+}
+
+
+void
+qtgui_time_sink_c::exec_()
+{
+ d_qApplication->exec();
+}
+
+QWidget*
+qtgui_time_sink_c::qwidget()
+{
+ return d_main_gui;
+}
+
+PyObject*
+qtgui_time_sink_c::pyqwidget()
+{
+ PyObject *w = PyLong_FromVoidPtr((void*)d_main_gui);
+ PyObject *retarg = Py_BuildValue("N", w);
+ return retarg;
+}
+
+void
+qtgui_time_sink_c::set_time_domain_axis(double min, double max)
+{
+ d_main_gui->setTimeDomainAxis(min, max);
+}
+
+void
+qtgui_time_sink_c::set_update_time(double t)
+{
+ d_update_time = t;
+ d_main_gui->setUpdateTime(d_update_time);
+}
+
+void
+qtgui_time_sink_c::set_title(int which, const std::string &title)
+{
+ d_main_gui->setTitle(which, title.c_str());
+}
+
+void
+qtgui_time_sink_c::set_color(int which, const std::string &color)
+{
+ d_main_gui->setColor(which, color.c_str());
+}
+
+int
+qtgui_time_sink_c::general_work (int noutput_items,
+ gr_vector_int &ninput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ int n=0, j=0, idx=0;
+ const gr_complex *in = (const gr_complex*)input_items[idx];
+
+ for(int i=0; i < noutput_items; i+=d_size) {
+ unsigned int datasize = noutput_items - i;
+ unsigned int resid = d_size-d_index;
+ idx = 0;
+
+ // If we have enough input for one full plot, do it
+ if(datasize >= resid) {
+ d_current_time = gruel::high_res_timer_now();
+
+ // Fill up residbufs with d_size number of items
+ for(n = 0; n < d_nconnections; n+=2) {
+ in = (const gr_complex*)input_items[idx++];
+ for(unsigned int k = 0; k < resid; k++) {
+ d_residbufs[n][d_index+k] = in[j+k].real();
+ d_residbufs[n+1][d_index+k] = in[j+k].imag();
+ }
+ }
+
+ // Update the plot if its time
+ if(gruel::high_res_timer_now() - d_last_time > d_update_time) {
+ d_last_time = d_current_time;
+ d_qApplication->postEvent(d_main_gui,
+ new TimeUpdateEvent(d_residbufs, d_size));
+ }
+
+ d_index = 0;
+ j += resid;
+ }
+ // Otherwise, copy what we received into the residbufs for next time
+ else {
+ for(n = 0; n < d_nconnections; n+=2) {
+ in = (const gr_complex*)input_items[idx++];
+ for(unsigned int k = 0; k < resid; k++) {
+ d_residbufs[n][d_index+k] = in[j+k].real();
+ d_residbufs[n+1][d_index+k] = in[j+k].imag();
+ }
+ }
+ d_index += datasize;
+ j += datasize;
+ }
+ }
+
+ consume_each(j);
+ return j;
+}
diff --git a/gr-qtgui/lib/qtgui_time_sink_c.h b/gr-qtgui/lib/qtgui_time_sink_c.h
new file mode 100644
index 000000000..459423c40
--- /dev/null
+++ b/gr-qtgui/lib/qtgui_time_sink_c.h
@@ -0,0 +1,93 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2011 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_QTGUI_TIME_SINK_C_H
+#define INCLUDED_QTGUI_TIME_SINK_C_H
+
+#include <Python.h>
+#include <gr_qtgui_api.h>
+#include <gr_block.h>
+#include <gr_firdes.h>
+#include <gri_fft.h>
+#include <qapplication.h>
+#include <timedisplayform.h>
+
+class qtgui_time_sink_c;
+typedef boost::shared_ptr<qtgui_time_sink_c> qtgui_time_sink_c_sptr;
+
+GR_QTGUI_API qtgui_time_sink_c_sptr qtgui_make_time_sink_c(int size, double bw,
+ const std::string &name,
+ int nconnectons=1,
+ QWidget *parent=NULL);
+
+class GR_QTGUI_API qtgui_time_sink_c : public gr_block
+{
+private:
+ friend GR_QTGUI_API qtgui_time_sink_c_sptr qtgui_make_time_sink_c(int size, double bw,
+ const std::string &name,
+ int nconnections,
+ QWidget *parent);
+ qtgui_time_sink_c(int size, double bw,
+ const std::string &name,
+ int nconnections,
+ QWidget *parent=NULL);
+
+ void forecast(int noutput_items, gr_vector_int &ninput_items_required);
+
+ void initialize();
+
+ int d_size;
+ double d_bandwidth;
+ std::string d_name;
+ int d_nconnections;
+
+ int d_index;
+ std::vector<double*> d_residbufs;
+
+ double d_update_time;
+
+ QWidget *d_parent;
+ TimeDisplayForm *d_main_gui;
+
+ gruel::high_res_timer_type d_current_time;
+ gruel::high_res_timer_type d_last_time;
+
+public:
+ ~qtgui_time_sink_c();
+ void exec_();
+ QWidget* qwidget();
+ PyObject* pyqwidget();
+
+ void set_time_domain_axis(double min, double max);
+ void set_update_time(double t);
+ void set_title(int which, const std::string &title);
+ void set_color(int which, const std::string &color);
+
+ QApplication *d_qApplication;
+
+ int general_work (int noutput_items,
+ gr_vector_int &ninput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+};
+
+#endif /* INCLUDED_QTGUI_TIME_SINK_C_H */
diff --git a/gr-qtgui/lib/qtgui_time_sink_f.cc b/gr-qtgui/lib/qtgui_time_sink_f.cc
new file mode 100644
index 000000000..58cc7a38a
--- /dev/null
+++ b/gr-qtgui/lib/qtgui_time_sink_f.cc
@@ -0,0 +1,197 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2011 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <qtgui_time_sink_f.h>
+#include <gr_io_signature.h>
+#include <string.h>
+
+#include <QTimer>
+
+qtgui_time_sink_f_sptr
+qtgui_make_time_sink_f (int size, double bw,
+ const std::string &name,
+ int nconnections,
+ QWidget *parent)
+{
+ return gnuradio::get_initial_sptr(new qtgui_time_sink_f (size, bw, name,
+ nconnections, parent));
+}
+
+qtgui_time_sink_f::qtgui_time_sink_f (int size, double bw,
+ const std::string &name,
+ int nconnections,
+ QWidget *parent)
+ : gr_block ("time_sink_f",
+ gr_make_io_signature (nconnections, nconnections, sizeof(float)),
+ gr_make_io_signature (0, 0, 0)),
+ d_size(size), d_bandwidth(bw), d_name(name),
+ d_nconnections(nconnections), d_parent(parent)
+{
+ d_main_gui = NULL;
+
+ d_index = 0;
+
+ for(int i = 0; i < d_nconnections; i++) {
+ d_residbufs.push_back(new double[d_size]);
+ }
+
+ initialize();
+}
+
+qtgui_time_sink_f::~qtgui_time_sink_f()
+{
+ // d_main_gui is a qwidget destroyed with its parent
+ for(int i = 0; i < d_nconnections; i++) {
+ delete [] d_residbufs[i];
+ }
+}
+
+void
+qtgui_time_sink_f::forecast(int noutput_items, gr_vector_int &ninput_items_required)
+{
+ unsigned int ninputs = ninput_items_required.size();
+ for (unsigned int i = 0; i < ninputs; i++) {
+ ninput_items_required[i] = std::min(d_size, 8191);
+ }
+}
+
+void
+qtgui_time_sink_f::initialize()
+{
+ if(qApp != NULL) {
+ d_qApplication = qApp;
+ }
+ else {
+ int argc=0;
+ char **argv = NULL;
+ d_qApplication = new QApplication(argc, argv);
+ }
+
+ d_main_gui = new TimeDisplayForm(d_nconnections, d_parent);
+
+ // initialize update time to 10 times a second
+ set_update_time(0.1);
+ d_last_time = 0;
+}
+
+
+void
+qtgui_time_sink_f::exec_()
+{
+ d_qApplication->exec();
+}
+
+QWidget*
+qtgui_time_sink_f::qwidget()
+{
+ return d_main_gui;
+}
+
+PyObject*
+qtgui_time_sink_f::pyqwidget()
+{
+ PyObject *w = PyLong_FromVoidPtr((void*)d_main_gui);
+ PyObject *retarg = Py_BuildValue("N", w);
+ return retarg;
+}
+
+void
+qtgui_time_sink_f::set_time_domain_axis(double min, double max)
+{
+ d_main_gui->setTimeDomainAxis(min, max);
+}
+
+void
+qtgui_time_sink_f::set_update_time(double t)
+{
+ d_update_time = t;
+ d_main_gui->setUpdateTime(d_update_time);
+}
+
+void
+qtgui_time_sink_f::set_title(int which, const std::string &title)
+{
+ d_main_gui->setTitle(which, title.c_str());
+}
+
+void
+qtgui_time_sink_f::set_color(int which, const std::string &color)
+{
+ d_main_gui->setColor(which, color.c_str());
+}
+
+int
+qtgui_time_sink_f::general_work (int noutput_items,
+ gr_vector_int &ninput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ int n=0, j=0, idx=0;
+ const float *in = (const float*)input_items[idx];
+
+ for(int i=0; i < noutput_items; i+=d_size) {
+ unsigned int datasize = noutput_items - i;
+ unsigned int resid = d_size-d_index;
+ idx = 0;
+
+ // If we have enough input for one full plot, do it
+ if(datasize >= resid) {
+ d_current_time = gruel::high_res_timer_now();
+
+ // Fill up residbufs with d_size number of items
+ for(n = 0; n < d_nconnections; n++) {
+ in = (const float*)input_items[idx++];
+ for(unsigned int k = 0; k < resid; k++) {
+ d_residbufs[n][d_index+k] = in[j+k];
+ }
+ }
+
+ // Update the plot if its time
+ if(gruel::high_res_timer_now() - d_last_time > d_update_time) {
+ d_last_time = d_current_time;
+ d_qApplication->postEvent(d_main_gui,
+ new TimeUpdateEvent(d_residbufs, d_size));
+ }
+
+ d_index = 0;
+ j += resid;
+ }
+ // Otherwise, copy what we received into the residbufs for next time
+ else {
+ for(n = 0; n < d_nconnections; n++) {
+ in = (const float*)input_items[idx++];
+ for(unsigned int k = 0; k < resid; k++) {
+ d_residbufs[n][d_index+k] = in[j+k];
+ }
+ }
+ d_index += datasize;
+ j += datasize;
+ }
+ }
+
+ consume_each(j);
+ return j;
+}
diff --git a/gr-qtgui/lib/qtgui_time_sink_f.h b/gr-qtgui/lib/qtgui_time_sink_f.h
new file mode 100644
index 000000000..632246c6e
--- /dev/null
+++ b/gr-qtgui/lib/qtgui_time_sink_f.h
@@ -0,0 +1,93 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2011 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_QTGUI_TIME_SINK_F_H
+#define INCLUDED_QTGUI_TIME_SINK_F_H
+
+#include <Python.h>
+#include <gr_qtgui_api.h>
+#include <gr_block.h>
+#include <gr_firdes.h>
+#include <gri_fft.h>
+#include <qapplication.h>
+#include <timedisplayform.h>
+
+class qtgui_time_sink_f;
+typedef boost::shared_ptr<qtgui_time_sink_f> qtgui_time_sink_f_sptr;
+
+GR_QTGUI_API qtgui_time_sink_f_sptr qtgui_make_time_sink_f(int size, double bw,
+ const std::string &name,
+ int nconnectons=1,
+ QWidget *parent=NULL);
+
+class GR_QTGUI_API qtgui_time_sink_f : public gr_block
+{
+private:
+ friend GR_QTGUI_API qtgui_time_sink_f_sptr qtgui_make_time_sink_f(int size, double bw,
+ const std::string &name,
+ int nconnections,
+ QWidget *parent);
+ qtgui_time_sink_f(int size, double bw,
+ const std::string &name,
+ int nconnections,
+ QWidget *parent=NULL);
+
+ void forecast(int noutput_items, gr_vector_int &ninput_items_required);
+
+ void initialize();
+
+ int d_size;
+ double d_bandwidth;
+ std::string d_name;
+ int d_nconnections;
+
+ int d_index;
+ std::vector<double*> d_residbufs;
+
+ double d_update_time;
+
+ QWidget *d_parent;
+ TimeDisplayForm *d_main_gui;
+
+ gruel::high_res_timer_type d_current_time;
+ gruel::high_res_timer_type d_last_time;
+
+public:
+ ~qtgui_time_sink_f();
+ void exec_();
+ QWidget* qwidget();
+ PyObject* pyqwidget();
+
+ void set_time_domain_axis(double min, double max);
+ void set_update_time(double t);
+ void set_title(int which, const std::string &title);
+ void set_color(int which, const std::string &color);
+
+ QApplication *d_qApplication;
+
+ int general_work (int noutput_items,
+ gr_vector_int &ninput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+};
+
+#endif /* INCLUDED_QTGUI_TIME_SINK_F_H */
diff --git a/gr-qtgui/lib/qtgui_util.h b/gr-qtgui/lib/qtgui_util.h
index a519c66a2..5b129c7b5 100644
--- a/gr-qtgui/lib/qtgui_util.h
+++ b/gr-qtgui/lib/qtgui_util.h
@@ -24,12 +24,12 @@
#define INCLUDED_QTGUI_UTIL_H
#include <qevent.h>
-
+#include <gr_qtgui_api.h>
#include <qwt_plot_picker.h>
#include <qwt_picker_machine.h>
-class QwtDblClickPlotPicker: public QwtPlotPicker
+class GR_QTGUI_API QwtDblClickPlotPicker: public QwtPlotPicker
{
public:
QwtDblClickPlotPicker(QwtPlotCanvas *);
@@ -38,7 +38,7 @@ public:
virtual QwtPickerMachine * stateMachine(int) const;
};
-class QwtPickerDblClickPointMachine: public QwtPickerMachine
+class GR_QTGUI_API QwtPickerDblClickPointMachine: public QwtPickerMachine
{
public:
QwtPickerDblClickPointMachine();
diff --git a/gr-qtgui/lib/spectrumUpdateEvents.cc b/gr-qtgui/lib/spectrumUpdateEvents.cc
index 53a205fb7..9be2f5357 100644
--- a/gr-qtgui/lib/spectrumUpdateEvents.cc
+++ b/gr-qtgui/lib/spectrumUpdateEvents.cc
@@ -8,10 +8,10 @@ SpectrumUpdateEvent::SpectrumUpdateEvent(const std::complex<float>* fftPoints,
const double* realTimeDomainPoints,
const double* imagTimeDomainPoints,
const uint64_t numTimeDomainDataPoints,
- const timespec dataTimestamp,
+ const gruel::high_res_timer_type dataTimestamp,
const bool repeatDataFlag,
const bool lastOfMultipleUpdateFlag,
- const timespec generatedTimestamp,
+ const gruel::high_res_timer_type generatedTimestamp,
const int droppedFFTFrames)
: QEvent(QEvent::Type(10005))
{
@@ -90,7 +90,7 @@ SpectrumUpdateEvent::getNumTimeDomainDataPoints() const
return _numTimeDomainDataPoints;
}
-timespec
+gruel::high_res_timer_type
SpectrumUpdateEvent::getDataTimestamp() const
{
return _dataTimestamp;
@@ -108,7 +108,7 @@ SpectrumUpdateEvent::getLastOfMultipleUpdateFlag() const
return _lastOfMultipleUpdateFlag;
}
-timespec
+gruel::high_res_timer_type
SpectrumUpdateEvent::getEventGeneratedTimestamp() const
{
return _eventGeneratedTimestamp;
@@ -177,4 +177,47 @@ SpectrumFrequencyRangeEvent::GetStopFrequency() const
return _stopFrequency;
}
+
+/***************************************************************************/
+#include <iostream>
+TimeUpdateEvent::TimeUpdateEvent(const std::vector<double*> timeDomainPoints,
+ const uint64_t numTimeDomainDataPoints)
+ : QEvent(QEvent::Type(10005))
+{
+ if(numTimeDomainDataPoints < 1) {
+ _numTimeDomainDataPoints = 1;
+ }
+ else {
+ _numTimeDomainDataPoints = numTimeDomainDataPoints;
+ }
+
+ _nplots = timeDomainPoints.size();
+ for(size_t i = 0; i < _nplots; i++) {
+ _dataTimeDomainPoints.push_back(new double[_numTimeDomainDataPoints]);
+ if(numTimeDomainDataPoints > 0) {
+ memcpy(_dataTimeDomainPoints[i], timeDomainPoints[i],
+ _numTimeDomainDataPoints*sizeof(double));
+ }
+ }
+}
+
+TimeUpdateEvent::~TimeUpdateEvent()
+{
+ for(size_t i = 0; i < _nplots; i++) {
+ delete[] _dataTimeDomainPoints[i];
+ }
+}
+
+const std::vector<double*>
+TimeUpdateEvent::getTimeDomainPoints() const
+{
+ return _dataTimeDomainPoints;
+}
+
+uint64_t
+TimeUpdateEvent::getNumTimeDomainDataPoints() const
+{
+ return _numTimeDomainDataPoints;
+}
+
#endif /* SPECTRUM_UPDATE_EVENTS_C */
diff --git a/gr-qtgui/lib/spectrumUpdateEvents.h b/gr-qtgui/lib/spectrumUpdateEvents.h
index ccc072c3e..5a17657b7 100644
--- a/gr-qtgui/lib/spectrumUpdateEvents.h
+++ b/gr-qtgui/lib/spectrumUpdateEvents.h
@@ -5,7 +5,8 @@
#include <QEvent>
#include <QString>
#include <complex>
-#include <highResTimeFunctions.h>
+#include <vector>
+#include <gruel/high_res_timer.h>
class SpectrumUpdateEvent:public QEvent{
@@ -15,10 +16,10 @@ public:
const double* realTimeDomainPoints,
const double* imagTimeDomainPoints,
const uint64_t numTimeDomainDataPoints,
- const timespec dataTimestamp,
+ const gruel::high_res_timer_type dataTimestamp,
const bool repeatDataFlag,
const bool lastOfMultipleUpdateFlag,
- const timespec generatedTimestamp,
+ const gruel::high_res_timer_type generatedTimestamp,
const int droppedFFTFrames);
~SpectrumUpdateEvent();
@@ -28,10 +29,10 @@ public:
const double* getImagTimeDomainPoints() const;
uint64_t getNumFFTDataPoints() const;
uint64_t getNumTimeDomainDataPoints() const;
- timespec getDataTimestamp() const;
+ gruel::high_res_timer_type getDataTimestamp() const;
bool getRepeatDataFlag() const;
bool getLastOfMultipleUpdateFlag() const;
- timespec getEventGeneratedTimestamp() const;
+ gruel::high_res_timer_type getEventGeneratedTimestamp() const;
int getDroppedFFTFrames() const;
protected:
@@ -42,10 +43,10 @@ private:
double* _imagDataTimeDomainPoints;
uint64_t _numFFTDataPoints;
uint64_t _numTimeDomainDataPoints;
- timespec _dataTimestamp;
+ gruel::high_res_timer_type _dataTimestamp;
bool _repeatDataFlag;
bool _lastOfMultipleUpdateFlag;
- timespec _eventGeneratedTimestamp;
+ gruel::high_res_timer_type _eventGeneratedTimestamp;
int _droppedFFTFrames;
};
@@ -89,4 +90,27 @@ private:
};
+class TimeUpdateEvent: public QEvent
+{
+public:
+ TimeUpdateEvent(const std::vector<double*> timeDomainPoints,
+ const uint64_t numTimeDomainDataPoints);
+
+ ~TimeUpdateEvent();
+
+ int which() const;
+ const std::vector<double*> getTimeDomainPoints() const;
+ uint64_t getNumTimeDomainDataPoints() const;
+ timespec getDataTimestamp() const;
+ bool getRepeatDataFlag() const;
+
+protected:
+
+private:
+ size_t _nplots;
+ std::vector<double*> _dataTimeDomainPoints;
+ uint64_t _numTimeDomainDataPoints;
+};
+
+
#endif /* SPECTRUM_UPDATE_EVENTS_H */
diff --git a/gr-qtgui/lib/spectrumdisplayform.cc b/gr-qtgui/lib/spectrumdisplayform.cc
index 238c9889f..0e8594029 100644
--- a/gr-qtgui/lib/spectrumdisplayform.cc
+++ b/gr-qtgui/lib/spectrumdisplayform.cc
@@ -1,3 +1,25 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2008,2009,2010,2011 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
#include <cmath>
#include <QColorDialog>
#include <QMessageBox>
@@ -14,13 +36,16 @@ SpectrumDisplayForm::SpectrumDisplayForm(QWidget* parent)
_frequencyDisplayPlot = new FrequencyDisplayPlot(FrequencyPlotDisplayFrame);
_waterfallDisplayPlot = new WaterfallDisplayPlot(WaterfallPlotDisplayFrame);
- _timeDomainDisplayPlot = new TimeDomainDisplayPlot(TimeDomainDisplayFrame);
+ _timeDomainDisplayPlot = new TimeDomainDisplayPlot(2, TimeDomainDisplayFrame);
_constellationDisplayPlot = new ConstellationDisplayPlot(ConstellationDisplayFrame);
_numRealDataPoints = 1024;
_realFFTDataPoints = new double[_numRealDataPoints];
_averagedValues = new double[_numRealDataPoints];
_historyVector = new std::vector<double*>;
+ _timeDomainDisplayPlot->setTitle(0, "real");
+ _timeDomainDisplayPlot->setTitle(1, "imag");
+
AvgLineEdit->setRange(0, 500); // Set range of Average box value from 0 to 500
MinHoldCheckBox_toggled( false );
MaxHoldCheckBox_toggled( false );
@@ -119,13 +144,17 @@ SpectrumDisplayForm::newFrequencyData( const SpectrumUpdateEvent* spectrumUpdate
//_lastSpectrumEvent = (SpectrumUpdateEvent)(*spectrumUpdateEvent);
const std::complex<float>* complexDataPoints = spectrumUpdateEvent->getFFTPoints();
const uint64_t numFFTDataPoints = spectrumUpdateEvent->getNumFFTDataPoints();
- const double* realTimeDomainDataPoints = spectrumUpdateEvent->getRealTimeDomainPoints();
- const double* imagTimeDomainDataPoints = spectrumUpdateEvent->getImagTimeDomainPoints();
const uint64_t numTimeDomainDataPoints = spectrumUpdateEvent->getNumTimeDomainDataPoints();
- const timespec dataTimestamp = spectrumUpdateEvent->getDataTimestamp();
+ const gruel::high_res_timer_type dataTimestamp = spectrumUpdateEvent->getDataTimestamp();
const bool repeatDataFlag = spectrumUpdateEvent->getRepeatDataFlag();
const bool lastOfMultipleUpdatesFlag = spectrumUpdateEvent->getLastOfMultipleUpdateFlag();
- const timespec generatedTimestamp = spectrumUpdateEvent->getEventGeneratedTimestamp();
+ const gruel::high_res_timer_type generatedTimestamp = spectrumUpdateEvent->getEventGeneratedTimestamp();
+ double* realTimeDomainDataPoints = (double*)spectrumUpdateEvent->getRealTimeDomainPoints();
+ double* imagTimeDomainDataPoints = (double*)spectrumUpdateEvent->getImagTimeDomainPoints();
+
+ std::vector<double*> timeDomainDataPoints;
+ timeDomainDataPoints.push_back(realTimeDomainDataPoints);
+ timeDomainDataPoints.push_back(imagTimeDomainDataPoints);
// REMEMBER: The dataTimestamp is NOT valid when the repeat data flag is true...
ResizeBuffers(numFFTDataPoints, numTimeDomainDataPoints);
@@ -210,11 +239,10 @@ SpectrumDisplayForm::newFrequencyData( const SpectrumUpdateEvent* spectrumUpdate
_peakAmplitude, d_update_time);
}
if(tabindex == d_plot_time) {
- _timeDomainDisplayPlot->PlotNewData(realTimeDomainDataPoints,
- imagTimeDomainDataPoints,
+ _timeDomainDisplayPlot->PlotNewData(timeDomainDataPoints,
numTimeDomainDataPoints,
d_update_time);
- }
+ }
if(tabindex == d_plot_constellation) {
_constellationDisplayPlot->PlotNewData(realTimeDomainDataPoints,
imagTimeDomainDataPoints,
@@ -673,7 +701,7 @@ SpectrumDisplayForm::ToggleTabConstellation(const bool state)
void
SpectrumDisplayForm::SetTimeDomainAxis(double min, double max)
{
- _timeDomainDisplayPlot->set_yaxis(min, max);
+ _timeDomainDisplayPlot->setYaxis(min, max);
}
void
diff --git a/gr-qtgui/lib/spectrumdisplayform.h b/gr-qtgui/lib/spectrumdisplayform.h
index 860edf2d1..30303a36f 100644
--- a/gr-qtgui/lib/spectrumdisplayform.h
+++ b/gr-qtgui/lib/spectrumdisplayform.h
@@ -1,3 +1,25 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2008,2009,2010,2011 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
#ifndef SPECTRUM_DISPLAY_FORM_H
#define SPECTRUM_DISPLAY_FORM_H
diff --git a/gr-qtgui/lib/timedisplayform.cc b/gr-qtgui/lib/timedisplayform.cc
new file mode 100644
index 000000000..cc4ac9951
--- /dev/null
+++ b/gr-qtgui/lib/timedisplayform.cc
@@ -0,0 +1,177 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2011 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <cmath>
+#include <QColorDialog>
+#include <QMessageBox>
+#include <timedisplayform.h>
+#include <iostream>
+
+TimeDisplayForm::TimeDisplayForm(int nplots, QWidget* parent)
+ : QWidget(parent)
+{
+ _systemSpecifiedFlag = false;
+ _intValidator = new QIntValidator(this);
+ _intValidator->setBottom(0);
+
+ _layout = new QGridLayout(this);
+ _timeDomainDisplayPlot = new TimeDomainDisplayPlot(nplots, this);
+ _layout->addWidget(_timeDomainDisplayPlot, 0, 0);
+
+ _numRealDataPoints = 1024;
+
+ setLayout(_layout);
+
+ Reset();
+
+ // Create a timer to update plots at the specified rate
+ displayTimer = new QTimer(this);
+ connect(displayTimer, SIGNAL(timeout()), this, SLOT(updateGuiTimer()));
+
+ connect(_timeDomainDisplayPlot, SIGNAL(plotPointSelected(const QPointF)),
+ this, SLOT(onTimePlotPointSelected(const QPointF)));
+}
+
+TimeDisplayForm::~TimeDisplayForm()
+{
+ // Qt deletes children when parent is deleted
+
+ // Don't worry about deleting Display Plots - they are deleted when parents are deleted
+ delete _intValidator;
+
+ displayTimer->stop();
+ delete displayTimer;
+}
+
+void
+TimeDisplayForm::newData( const TimeUpdateEvent* spectrumUpdateEvent)
+{
+ const std::vector<double*> timeDomainDataPoints = spectrumUpdateEvent->getTimeDomainPoints();
+ const uint64_t numTimeDomainDataPoints = spectrumUpdateEvent->getNumTimeDomainDataPoints();
+
+ _timeDomainDisplayPlot->PlotNewData(timeDomainDataPoints,
+ numTimeDomainDataPoints,
+ d_update_time);
+}
+
+void
+TimeDisplayForm::resizeEvent( QResizeEvent *e )
+{
+ QSize s = size();
+ emit _timeDomainDisplayPlot->resizeSlot(&s);
+}
+
+void
+TimeDisplayForm::customEvent( QEvent * e)
+{
+ if(e->type() == 10005) {
+ TimeUpdateEvent* timeUpdateEvent = (TimeUpdateEvent*)e;
+ newData(timeUpdateEvent);
+ }
+ //else if(e->type() == 10008){
+ //setWindowTitle(((SpectrumWindowCaptionEvent*)e)->getLabel());
+ //}
+ //else if(e->type() == 10009){
+ //Reset();
+ //if(_systemSpecifiedFlag){
+ // _system->ResetPendingGUIUpdateEvents();
+ //}
+ //}
+}
+
+void
+TimeDisplayForm::updateGuiTimer()
+{
+ _timeDomainDisplayPlot->canvas()->update();
+}
+
+void
+TimeDisplayForm::onTimePlotPointSelected(const QPointF p)
+{
+ emit plotPointSelected(p, 3);
+}
+
+void
+TimeDisplayForm::setFrequencyRange(const double newCenterFrequency,
+ const double newStartFrequency,
+ const double newStopFrequency)
+{
+ double fdiff = std::max(fabs(newStartFrequency), fabs(newStopFrequency));
+
+ if(fdiff > 0) {
+ std::string strtime[4] = {"sec", "ms", "us", "ns"};
+ double units10 = floor(log10(fdiff));
+ double units3 = std::max(floor(units10 / 3.0), 0.0);
+ double units = pow(10, (units10-fmod(units10, 3.0)));
+ int iunit = static_cast<int>(units3);
+
+ _startFrequency = newStartFrequency;
+ _stopFrequency = newStopFrequency;
+
+ _timeDomainDisplayPlot->SetSampleRate(_stopFrequency - _startFrequency,
+ units, strtime[iunit]);
+ }
+}
+
+void
+TimeDisplayForm::Reset()
+{
+}
+
+
+void
+TimeDisplayForm::closeEvent( QCloseEvent *e )
+{
+ //if(_systemSpecifiedFlag){
+ // _system->SetWindowOpenFlag(false);
+ //}
+
+ qApp->processEvents();
+
+ QWidget::closeEvent(e);
+}
+
+void
+TimeDisplayForm::setTimeDomainAxis(double min, double max)
+{
+ _timeDomainDisplayPlot->setYaxis(min, max);
+}
+
+void
+TimeDisplayForm::setUpdateTime(double t)
+{
+ d_update_time = t;
+ // QTimer class takes millisecond input
+ displayTimer->start(d_update_time*1000);
+}
+
+void
+TimeDisplayForm::setTitle(int which, QString title)
+{
+ _timeDomainDisplayPlot->setTitle(which, title);
+}
+
+void
+TimeDisplayForm::setColor(int which, QString color)
+{
+ _timeDomainDisplayPlot->setColor(which, color);
+}
diff --git a/gr-qtgui/lib/timedisplayform.h b/gr-qtgui/lib/timedisplayform.h
new file mode 100644
index 000000000..1216a1ef5
--- /dev/null
+++ b/gr-qtgui/lib/timedisplayform.h
@@ -0,0 +1,85 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2011 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef TIME_DISPLAY_FORM_H
+#define TIME_DISPLAY_FORM_H
+
+#include <spectrumUpdateEvents.h>
+#include <FrequencyDisplayPlot.h>
+#include <WaterfallDisplayPlot.h>
+#include <TimeDomainDisplayPlot.h>
+#include <ConstellationDisplayPlot.h>
+#include <QtGui/QApplication>
+#include <QtGui/QGridLayout>
+#include <QValidator>
+#include <QTimer>
+#include <vector>
+
+class TimeDisplayForm : public QWidget
+{
+ Q_OBJECT
+
+ public:
+ TimeDisplayForm(int nplots=1, QWidget* parent = 0);
+ ~TimeDisplayForm();
+
+ void Reset();
+
+public slots:
+ void resizeEvent( QResizeEvent * e );
+ void customEvent( QEvent * e );
+ void setFrequencyRange( const double newCenterFrequency,
+ const double newStartFrequency,
+ const double newStopFrequency );
+ void closeEvent( QCloseEvent * e );
+
+ void setTimeDomainAxis(double min, double max);
+
+ void setUpdateTime(double t);
+
+ void setTitle(int which, QString title);
+ void setColor(int which, QString color);
+
+private slots:
+ void newData( const TimeUpdateEvent* );
+ void updateGuiTimer();
+
+ void onTimePlotPointSelected(const QPointF p);
+
+signals:
+ void plotPointSelected(const QPointF p, int type);
+
+private:
+ uint64_t _numRealDataPoints;
+ QIntValidator* _intValidator;
+
+ QGridLayout *_layout;
+ TimeDomainDisplayPlot* _timeDomainDisplayPlot;
+ bool _systemSpecifiedFlag;
+ double _startFrequency;
+ double _stopFrequency;
+
+ QTimer *displayTimer;
+ double d_update_time;
+};
+
+#endif /* TIME_DISPLAY_FORM_H */
diff --git a/gr-qtgui/swig/Makefile.am b/gr-qtgui/swig/Makefile.am
index 8c695ba5b..1d8319987 100644
--- a/gr-qtgui/swig/Makefile.am
+++ b/gr-qtgui/swig/Makefile.am
@@ -51,4 +51,7 @@ qtgui_swig_la_swig_libadd = \
# additional SWIG files to be installed
qtgui_swig_swiginclude_headers = \
- qtgui.i
+ qtgui_sink_c.i \
+ qtgui_sink_f.i \
+ qtgui_time_sink_c.i \
+ qtgui_time_sink_f.i
diff --git a/gr-qtgui/swig/qtgui.i b/gr-qtgui/swig/qtgui_sink_c.i
index 77c6ccdd7..ff6241482 100644
--- a/gr-qtgui/swig/qtgui.i
+++ b/gr-qtgui/swig/qtgui_sink_c.i
@@ -1,6 +1,6 @@
/* -*- c++ -*- */
/*
- * Copyright 2008,2009 Free Software Foundation, Inc.
+ * Copyright 2008,2009,2011 Free Software Foundation, Inc.
*
* This file is part of GNU Radio
*
@@ -24,7 +24,6 @@
%{
#include <qtgui_sink_c.h>
-#include <qtgui_sink_f.h>
%}
GR_SWIG_BLOCK_MAGIC(qtgui,sink_c)
@@ -65,47 +64,3 @@ public:
void set_constellation_pen_size(int size);
void set_update_time(double t);
};
-
-
-
-/*********************************************************************/
-
-
-GR_SWIG_BLOCK_MAGIC(qtgui,sink_f)
-
-qtgui_sink_f_sptr qtgui_make_sink_f (int fftsize, int wintype,
- double fc=0, double bw=0.0,
- const std::string &name="Display",
- bool plotfreq=true, bool plotwaterfall=true,
- bool plottime=true, bool plotconst=true,
- QWidget *parent=NULL);
-
-class qtgui_sink_f : public gr_block
-{
-private:
- friend qtgui_sink_f_sptr qtgui_make_sink_f (int fftsize, int wintype,
- double fc, double bw,
- const std::string &name,
- bool plotfreq, bool plotwaterfall,
- bool plottime, bool plotconst,
- QWidget *parent);
- qtgui_sink_f (int fftsize, int wintype,
- double fc, double bw,
- const std::string &name,
- bool plotfreq, bool plotwaterfall,
- bool plottime, bool plotconst,
- QWidget *parent);
-
-public:
- void exec_();
- PyObject* pyqwidget();
-
- void set_frequency_range(const double centerfreq,
- const double bandwidth);
- void set_time_domain_axis(double min, double max);
- void set_constellation_axis(double xmin, double xmax,
- double ymin, double ymax);
- void set_frequency_axis(double min, double max);
- void set_constellation_pen_size(int size);
- void set_update_time(double t);
-};
diff --git a/gr-qtgui/swig/qtgui_sink_f.i b/gr-qtgui/swig/qtgui_sink_f.i
new file mode 100644
index 000000000..c5eb656b9
--- /dev/null
+++ b/gr-qtgui/swig/qtgui_sink_f.i
@@ -0,0 +1,66 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2008,2009,2011 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+%include "gnuradio.i"
+
+%{
+#include <qtgui_sink_f.h>
+%}
+
+GR_SWIG_BLOCK_MAGIC(qtgui,sink_f)
+
+qtgui_sink_f_sptr qtgui_make_sink_f (int fftsize, int wintype,
+ double fc=0, double bw=0.0,
+ const std::string &name="Display",
+ bool plotfreq=true, bool plotwaterfall=true,
+ bool plottime=true, bool plotconst=true,
+ QWidget *parent=NULL);
+
+class qtgui_sink_f : public gr_block
+{
+private:
+ friend qtgui_sink_f_sptr qtgui_make_sink_f (int fftsize, int wintype,
+ double fc, double bw,
+ const std::string &name,
+ bool plotfreq, bool plotwaterfall,
+ bool plottime, bool plotconst,
+ QWidget *parent);
+ qtgui_sink_f (int fftsize, int wintype,
+ double fc, double bw,
+ const std::string &name,
+ bool plotfreq, bool plotwaterfall,
+ bool plottime, bool plotconst,
+ QWidget *parent);
+
+public:
+ void exec_();
+ PyObject* pyqwidget();
+
+ void set_frequency_range(const double centerfreq,
+ const double bandwidth);
+ void set_time_domain_axis(double min, double max);
+ void set_constellation_axis(double xmin, double xmax,
+ double ymin, double ymax);
+ void set_frequency_axis(double min, double max);
+ void set_constellation_pen_size(int size);
+ void set_update_time(double t);
+};
diff --git a/gr-qtgui/swig/qtgui_swig.i b/gr-qtgui/swig/qtgui_swig.i
index c250cdd04..5a4ffd6fb 100644
--- a/gr-qtgui/swig/qtgui_swig.i
+++ b/gr-qtgui/swig/qtgui_swig.i
@@ -25,8 +25,11 @@
%{
#include <qtgui_sink_c.h>
#include <qtgui_sink_f.h>
+#include <qtgui_time_sink_c.h>
+#include <qtgui_time_sink_f.h>
%}
-%include "qtgui.i"
-
-
+%include "qtgui_sink_c.i"
+%include "qtgui_sink_f.i"
+%include "qtgui_time_sink_c.i"
+%include "qtgui_time_sink_f.i"
diff --git a/gr-qtgui/swig/qtgui_time_sink_c.i b/gr-qtgui/swig/qtgui_time_sink_c.i
new file mode 100644
index 000000000..8f5c9f4f0
--- /dev/null
+++ b/gr-qtgui/swig/qtgui_time_sink_c.i
@@ -0,0 +1,56 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2011 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+%include "gnuradio.i"
+
+%{
+#include <qtgui_time_sink_c.h>
+%}
+
+GR_SWIG_BLOCK_MAGIC(qtgui,time_sink_c)
+
+qtgui_time_sink_c_sptr qtgui_make_time_sink_c(int size, double bw,
+ const std::string &name,
+ int nconnections=1,
+ QWidget *parent=NULL);
+
+class qtgui_time_sink_c : public gr_block
+{
+private:
+ friend qtgui_time_sink_c_sptr qtgui_make_time_sink_c(int size, double bw,
+ const std::string &name,
+ int nconnections,
+ QWidget *parent);
+ qtgui_time_sink_c(int size, double bw,
+ const std::string &name,
+ int nconnections,
+ QWidget *parent=NULL);
+
+public:
+ void exec_();
+ PyObject* pyqwidget();
+
+ void set_time_domain_axis(double min, double max);
+ void set_update_time(double t);
+ void set_title(int which, const std::string &title);
+ void set_color(int which, const std::string &color);
+};
diff --git a/gr-qtgui/swig/qtgui_time_sink_f.i b/gr-qtgui/swig/qtgui_time_sink_f.i
new file mode 100644
index 000000000..b92efe7be
--- /dev/null
+++ b/gr-qtgui/swig/qtgui_time_sink_f.i
@@ -0,0 +1,56 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2011 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+%include "gnuradio.i"
+
+%{
+#include <qtgui_time_sink_f.h>
+%}
+
+GR_SWIG_BLOCK_MAGIC(qtgui,time_sink_f)
+
+qtgui_time_sink_f_sptr qtgui_make_time_sink_f(int size, double bw,
+ const std::string &name,
+ int nconnections=1,
+ QWidget *parent=NULL);
+
+class qtgui_time_sink_f : public gr_block
+{
+private:
+ friend qtgui_time_sink_f_sptr qtgui_make_time_sink_f(int size, double bw,
+ const std::string &name,
+ int nconnections,
+ QWidget *parent);
+ qtgui_time_sink_f(int size, double bw,
+ const std::string &name,
+ int nconnections,
+ QWidget *parent=NULL);
+
+public:
+ void exec_();
+ PyObject* pyqwidget();
+
+ void set_time_domain_axis(double min, double max);
+ void set_update_time(double t);
+ void set_title(int which, const std::string &title);
+ void set_color(int which, const std::string &color);
+};
diff --git a/gr-trellis/doc/gr-trellis.xml b/gr-trellis/doc/gr-trellis.xml
index ed53715a8..5f1921343 100644
--- a/gr-trellis/doc/gr-trellis.xml
+++ b/gr-trellis/doc/gr-trellis.xml
@@ -279,6 +279,15 @@ The fourth way is specific to FSMs resulting from shift registers, and the outpu
</programlisting>
</listitem>
+<listitem>
+<para>
+I have added other constructors as well, eg, one that constructs an FSM appropriate for modeling an arbitrary CPM scheme; one that constructs the radix-n version of a given FSM; one that constructs the "concatenation" of two FSMs, etc.
+</para>
+</listitem>
+
+
+
+
</itemizedlist>
@@ -397,8 +406,8 @@ r<subscript>k</subscript>=
evaluates
</para>
<para>
-i<subscript>0</subscript>= argmax<subscript>i</subscript> ||r<subscript>k</subscript>-c<subscript>i</subscript>||<superscript>2</superscript> =
-argmax<subscript>i</subscript> sum<subscript>j=1</subscript><superscript>D</superscript> |r<subscript>k,j</subscript>-c<subscript>i,j</subscript>|<superscript>2</superscript>
+i<subscript>0</subscript>= argmin<subscript>i</subscript> ||r<subscript>k</subscript>-c<subscript>i</subscript>||<superscript>2</superscript> =
+argmin<subscript>i</subscript> sum<subscript>j=1</subscript><superscript>D</superscript> |r<subscript>k,j</subscript>-c<subscript>i,j</subscript>|<superscript>2</superscript>
</para>
<para>
and outputs a sequence of O floats of the form (0,...,0,1,0,...,0), where the
@@ -413,8 +422,8 @@ r<subscript>k</subscript>=
evaluates
</para>
<para>
-i<subscript>0</subscript>= argmax<subscript>i</subscript> ||r<subscript>k</subscript>-c<subscript>i</subscript>||<superscript>2</superscript> =
-argmax<subscript>i</subscript> sum<subscript>j=1</subscript><superscript>D</superscript> (r<subscript>k,j</subscript>-c<subscript>i,j</subscript>)<superscript>2</superscript>
+i<subscript>0</subscript>= argmin<subscript>i</subscript> ||r<subscript>k</subscript>-c<subscript>i</subscript>||<superscript>2</superscript> =
+argmin<subscript>i</subscript> sum<subscript>j=1</subscript><superscript>D</superscript> (r<subscript>k,j</subscript>-c<subscript>i,j</subscript>)<superscript>2</superscript>
</para>
<para>
and outputs a sequence of O floats of the form (d<subscript>1</subscript>,d<subscript>2</subscript>,...,d<subscript>O</subscript>), where the
@@ -813,7 +822,7 @@ The modulated symbols are filtered by the ISI channel and AWGN with appropriate
<para>
Since the output alphabet of the equivalent FSM is quite large (1024) we chose to utilize the combined metrics calculator and Viterbi algorithm block.
-also note that the first L observations are irrelevant and tus can be skipped.
+Also note that the first L observations are irrelevant and thus can be skipped.
</para>
<programlisting>
33 # RX
@@ -863,7 +872,20 @@ The function returns the number of symbols and the number of symbols in error. O
<sect1 id="turbo"><title>Support for Concatenated Coding and Turbo Decoding</title>
<para>
-To do...
+Soft versions of the algorithms have been implemented.
+Also examples of turbo equalization/decoding and of sccc can
+be found in the examples directory.
+
+Recently we added gnuradio blocks for sccc and pccc encoders and
+turbo decoders.
+Although these can be generated by existing gr-trellis blocks (in particular,
+the SISO blocks, as done in some of the python examples) there is an advantage
+in having this functionality as a single block. To see why, think of a turbo decoder with 10 iterations. Previously we needed to concatenate 10 x 2 SISO blocks
+(for a sccc decoder) to emulate the passing of soft information between SISOs over 10 iterartions. With the new block however, only a single such block is needed that internally loops through 10 iterations; this results in space savings
+and possibly time saving as well (since queueing at the input/ouput of the gr-blocks is avoided).
+
+
+Still need to document them...
</para>
diff --git a/gr-trellis/src/examples/Makefile.am b/gr-trellis/src/examples/Makefile.am
index 8fb727acd..92aeadfad 100644
--- a/gr-trellis/src/examples/Makefile.am
+++ b/gr-trellis/src/examples/Makefile.am
@@ -31,8 +31,6 @@ dist_ourdata_DATA = \
dist_ourdata_SCRIPTS = \
fsm_utils.py \
test_tcm.py \
- test_tcm1.py \
- test_tcm2.py \
test_tcm_parallel.py \
test_tcm_combined.py \
test_sccc_hard.py \
diff --git a/gr-trellis/src/examples/README b/gr-trellis/src/examples/README
index d5bad85f5..bd28e3d61 100644
--- a/gr-trellis/src/examples/README
+++ b/gr-trellis/src/examples/README
@@ -6,28 +6,10 @@ fsm_utils.py contains several useful functions.
fsm_files is a directory with some FSM definitions
-If you just want to see what these programs do, run each of the following:
+If you just want to see what these programs do run them;
+in your terminal you will see something like this:
-./test_tcm.py fsm_files/awgn1o2_4.fsm 6.0 1000
-./test_tcm1.py fsm_files/awgn1o2_4.fsm 6.0 1000
-./test_tcm2.py 6.0 1000
-./test_tcm_combined.py fsm_files/awgn1o2_4.fsm 6.0 1000
-./test_tcm_parallel.py fsm_files/awgn1o2_4.fsm 6.0 1000
-
-./test_sccc_hard.py fsm_files/awgn1o2_4.fsm fsm_files/awgn2o3_4_msb.fsm 10.0 100
-./test_sccc_soft.py fsm_files/awgn1o2_4.fsm fsm_files/awgn2o3_4_msb.fsm 8.0 100
-./test_sccc_turbo.py fsm_files/awgn1o2_4.fsm fsm_files/awgn2o3_4_msb.fsm 5.0 100
-
-./test_viterbi_equalization.py 12.0 100
-./test_viterbi_equalization1.py 12.0 100
-./test_turbo_equalization1.py fsm_files/awgn1o2_4.fsm 8.0 100
-./test_turbo_equalization2.py fsm_files/awgn1o2_4.fsm 8.0 100
-
-
-In your terminal you will see something like this:
-
-
-$ ./test_tcm.py fsm_files/awgn1o2_4.fsm 6.0 1000
+$ ./test_tcm.py --esn0 6.0 --repetitions 1000
100 98 9.80e-01 102400 9 8.79e-05
200 198 9.90e-01 204800 20 9.77e-05
300 298 9.93e-01 307200 40 1.30e-04
diff --git a/gr-trellis/src/examples/test_pccc_turbo1.py b/gr-trellis/src/examples/test_pccc_turbo1.py
new file mode 100755
index 000000000..1173d0734
--- /dev/null
+++ b/gr-trellis/src/examples/test_pccc_turbo1.py
@@ -0,0 +1,119 @@
+#!/usr/bin/env python
+
+from gnuradio import gr
+from gnuradio import trellis
+from gnuradio import eng_notation
+import math
+import sys
+import random
+import fsm_utils
+
+
+def run_test (fo,fi,interleaver,Kb,bitspersymbol,K,dimensionality,constellation,Es,N0,IT,seed):
+ tb = gr.top_block ()
+
+
+ # TX
+ src = gr.lfsr_32k_source_s()
+ src_head = gr.head (gr.sizeof_short,Kb/16) # packet size in shorts
+ s2fsmi = gr.packed_to_unpacked_ss(bitspersymbol,gr.GR_MSB_FIRST) # unpack shorts to symbols compatible with the outer FSM input cardinality
+ #src = gr.vector_source_s([0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1],False)
+ enc = trellis.pccc_encoder_ss(fo,0,fi,0,interleaver,K)
+ code = gr.vector_sink_s()
+ mod = gr.chunks_to_symbols_sf(constellation,dimensionality)
+
+ # CHANNEL
+ add = gr.add_ff()
+ noise = gr.noise_source_f(gr.GR_GAUSSIAN,math.sqrt(N0/2),seed)
+
+ # RX
+ metrics_in = trellis.metrics_f(fi.O()*fo.O(),dimensionality,constellation,trellis.TRELLIS_EUCLIDEAN) # data preprocessing to generate metrics for innner SISO
+ scale = gr.multiply_const_ff(1.0/N0)
+ dec = trellis.pccc_decoder_s(fo,0,-1,fi,0,-1,interleaver,K,IT,trellis.TRELLIS_MIN_SUM)
+
+ fsmi2s = gr.unpacked_to_packed_ss(bitspersymbol,gr.GR_MSB_FIRST) # pack FSM input symbols to shorts
+ dst = gr.check_lfsr_32k_s()
+
+ tb.connect (src,src_head,s2fsmi,enc,mod)
+ #tb.connect (src,enc,mod)
+ #tb.connect(enc,code)
+ tb.connect (mod,(add,0))
+ tb.connect (noise,(add,1))
+ tb.connect (add,metrics_in,scale,dec,fsmi2s,dst)
+
+ tb.run()
+
+ #print code.data()
+
+ ntotal = dst.ntotal ()
+ nright = dst.nright ()
+ runlength = dst.runlength ()
+ return (ntotal,ntotal-nright)
+
+
+def main(args):
+ nargs = len (args)
+ if nargs == 5:
+ fname_out=args[0]
+ fname_in=args[1]
+ esn0_db=float(args[2]) # Es/No in dB
+ IT=int(args[3])
+ rep=int(args[4]) # number of times the experiment is run to collect enough errors
+ else:
+ sys.stderr.write ('usage: test_pccc_turbo.py fsm_name_1 fsm_fname_2 Es/No_db iterations repetitions\n')
+ sys.exit (1)
+
+ # system parameters
+ Kb=1024*16 # packet size in bits (make it multiple of 16 so it can be packed in a short)
+ fo=trellis.fsm(fname_out) # get the outer FSM specification from a file
+ fi=trellis.fsm(fname_in) # get the innner FSM specification from a file
+ bitspersymbol = int(round(math.log(fo.I())/math.log(2))) # bits per FSM input symbol
+ if fo.I() != fi.I():
+ sys.stderr.write ('Incompatible input cardinality between two FSMs.\n')
+ sys.exit (1)
+ K=Kb/bitspersymbol # packet size in trellis steps
+ interleaver=trellis.interleaver(K,666) # construct a random interleaver
+ #modulation = fsm_utils.psk8 # see fsm_utlis.py for available predefined modulations
+ dimensionality = 4
+ constellation = [ 1, 0, 1, 0,\
+ 1, 0,-1, 0,\
+ 1, 0, 0, 1,\
+ 1, 0, 0,-1,\
+ -1, 0, 1, 0,\
+ -1, 0,-1, 0,\
+ -1, 0, 0, 1,\
+ -1, 0, 0,-1,\
+ 0, 1, 1, 0,\
+ 0, 1,-1, 0,\
+ 0, 1, 0, 1,\
+ 0, 1, 0,-1,\
+ 0,-1, 1, 0,\
+ 0,-1,-1, 0,\
+ 0,-1, 0, 1,\
+ 0,-1, 0,-1,] # equivalent to 2 QPSK symbols
+ if len(constellation)/dimensionality != fi.O()*fo.O():
+ sys.stderr.write ('Incompatible FSM output cardinality and modulation size.\n')
+ sys.exit (1)
+ # calculate average symbol energy
+ Es = 0
+ for i in range(len(constellation)):
+ Es = Es + constellation[i]**2
+ Es = Es / (len(constellation)/dimensionality)
+ N0=Es/pow(10.0,esn0_db/10.0); # calculate noise variance
+
+ tot_s=0 # total number of transmitted shorts
+ terr_s=0 # total number of shorts in error
+ terr_p=0 # total number of packets in error
+ for i in range(rep):
+ (s,e)=run_test(fo,fi,interleaver,Kb,bitspersymbol,K,dimensionality,constellation,Es,N0,IT,-long(666+i)) # run experiment with different seed to get different noise realizations
+ tot_s=tot_s+s
+ terr_s=terr_s+e
+ terr_p=terr_p+(terr_s!=0)
+ if ((i+1)%10==0): # display progress
+ print i+1,terr_p, '%.2e' % ((1.0*terr_p)/(i+1)),tot_s,terr_s, '%.2e' % ((1.0*terr_s)/tot_s)
+ # estimate of the (short or bit) error rate
+ print rep,terr_p, '%.2e' % ((1.0*terr_p)/(i+1)),tot_s,terr_s, '%.2e' % ((1.0*terr_s)/tot_s)
+
+
+if __name__ == '__main__':
+ main (sys.argv[1:])
diff --git a/gr-trellis/src/examples/test_sccc_hard.py b/gr-trellis/src/examples/test_sccc_hard.py
index a7933a18e..1a81bc59b 100755
--- a/gr-trellis/src/examples/test_sccc_hard.py
+++ b/gr-trellis/src/examples/test_sccc_hard.py
@@ -1,7 +1,6 @@
#!/usr/bin/env python
from gnuradio import gr
-from gnuradio import audio
from gnuradio import trellis
from gnuradio import eng_notation
import math
diff --git a/gr-trellis/src/examples/test_sccc_soft.py b/gr-trellis/src/examples/test_sccc_soft.py
index d96d36e3f..ea296e1e9 100755
--- a/gr-trellis/src/examples/test_sccc_soft.py
+++ b/gr-trellis/src/examples/test_sccc_soft.py
@@ -1,7 +1,6 @@
#!/usr/bin/env python
from gnuradio import gr
-from gnuradio import audio
from gnuradio import trellis
from gnuradio import eng_notation
import math
diff --git a/gr-trellis/src/examples/test_sccc_turbo.py b/gr-trellis/src/examples/test_sccc_turbo.py
index f3a856de7..703ee410b 100755
--- a/gr-trellis/src/examples/test_sccc_turbo.py
+++ b/gr-trellis/src/examples/test_sccc_turbo.py
@@ -1,7 +1,6 @@
#!/usr/bin/env python
from gnuradio import gr
-from gnuradio import audio
from gnuradio import trellis
from gnuradio import eng_notation
import math
@@ -92,13 +91,14 @@ def run_test (fo,fi,interleaver,Kb,bitspersymbol,K,dimensionality,constellation,
def main(args):
nargs = len (args)
- if nargs == 4:
+ if nargs == 5:
fname_out=args[0]
fname_in=args[1]
esn0_db=float(args[2]) # Es/No in dB
- rep=int(args[3]) # number of times the experiment is run to collect enough errors
+ IT=int(args[3])
+ rep=int(args[4]) # number of times the experiment is run to collect enough errors
else:
- sys.stderr.write ('usage: test_tcm.py fsm_name_out fsm_fname_in Es/No_db repetitions\n')
+ sys.stderr.write ('usage: test_sccc_turbo.py fsm_name_out fsm_fname_in Es/No_db iterations repetitions\n')
sys.exit (1)
# system parameters
@@ -123,7 +123,6 @@ def main(args):
Es = Es + constellation[i]**2
Es = Es / (len(constellation)/dimensionality)
N0=Es/pow(10.0,esn0_db/10.0); # calculate noise variance
- IT = 3 # number of turbo iterations
tot_s=0 # total number of transmitted shorts
terr_s=0 # total number of shorts in error
diff --git a/gr-trellis/src/examples/test_tcm2.py b/gr-trellis/src/examples/test_sccc_turbo1.py
index e527fc5ed..8a630c0d4 100755
--- a/gr-trellis/src/examples/test_tcm2.py
+++ b/gr-trellis/src/examples/test_sccc_turbo1.py
@@ -1,7 +1,6 @@
#!/usr/bin/env python
from gnuradio import gr
-from gnuradio import audio
from gnuradio import trellis
from gnuradio import eng_notation
import math
@@ -9,20 +8,15 @@ import sys
import random
import fsm_utils
-def run_test (f,Kb,bitspersymbol,K,dimensionality,constellation,N0,seed):
- tb = gr.top_block ()
+def run_test (fo,fi,interleaver,Kb,bitspersymbol,K,dimensionality,constellation,Es,N0,IT,seed):
+ tb = gr.top_block ()
# TX
- #packet = [0]*Kb
- #for i in range(Kb-1*16): # last 16 bits = 0 to drive the final state to 0
- #packet[i] = random.randint(0, 1) # random 0s and 1s
- #src = gr.vector_source_s(packet,False)
src = gr.lfsr_32k_source_s()
src_head = gr.head (gr.sizeof_short,Kb/16) # packet size in shorts
- #b2s = gr.unpacked_to_packed_ss(1,gr.GR_MSB_FIRST) # pack bits in shorts
- s2fsmi = gr.packed_to_unpacked_ss(bitspersymbol,gr.GR_MSB_FIRST) # unpack shorts to symbols compatible with the FSM input cardinality
- enc = trellis.encoder_ss(f,0) # initial state = 0
+ s2fsmi = gr.packed_to_unpacked_ss(bitspersymbol,gr.GR_MSB_FIRST) # unpack shorts to symbols compatible with the outer FSM input cardinality
+ enc = trellis.sccc_encoder_ss(fo,0,fi,0,interleaver,K)
mod = gr.chunks_to_symbols_sf(constellation,dimensionality)
# CHANNEL
@@ -30,65 +24,54 @@ def run_test (f,Kb,bitspersymbol,K,dimensionality,constellation,N0,seed):
noise = gr.noise_source_f(gr.GR_GAUSSIAN,math.sqrt(N0/2),seed)
# RX
- metrics = trellis.metrics_f(f.O(),dimensionality,constellation,trellis.TRELLIS_EUCLIDEAN) # data preprocessing to generate metrics for Viterbi
- va = trellis.viterbi_s(f,K,0,-1) # Put -1 if the Initial/Final states are not set.
+ dec = trellis.sccc_decoder_combined_fs(fo,0,-1,fi,0,-1,interleaver,K,IT,trellis.TRELLIS_MIN_SUM,dimensionality,constellation,trellis.TRELLIS_EUCLIDEAN,1.0)
fsmi2s = gr.unpacked_to_packed_ss(bitspersymbol,gr.GR_MSB_FIRST) # pack FSM input symbols to shorts
- #s2b = gr.packed_to_unpacked_ss(1,gr.GR_MSB_FIRST) # unpack shorts to bits
- #dst = gr.vector_sink_s();
dst = gr.check_lfsr_32k_s()
-
+ #tb.connect (src,src_head,s2fsmi,enc_out,inter,enc_in,mod)
tb.connect (src,src_head,s2fsmi,enc,mod)
- #tb.connect (src,b2s,s2fsmi,enc,mod)
tb.connect (mod,(add,0))
tb.connect (noise,(add,1))
- tb.connect (add,metrics)
- tb.connect (metrics,va,fsmi2s,dst)
- #tb.connect (metrics,va,fsmi2s,s2b,dst)
-
+ #tb.connect (add,head)
+ #tb.connect (tail,fsmi2s,dst)
+ tb.connect (add,dec,fsmi2s,dst)
tb.run()
+
+ #print enc_out.ST(), enc_in.ST()
- # A bit of cheating: run the program once and print the
- # final encoder state..
- # Then put it as the last argument in the viterbi block
- #print "final state = " , enc.ST()
-
ntotal = dst.ntotal ()
nright = dst.nright ()
runlength = dst.runlength ()
- #ntotal = len(packet)
- #if len(dst.data()) != ntotal:
- #print "Error: not enough data\n"
- #nright = 0;
- #for i in range(ntotal):
- #if packet[i]==dst.data()[i]:
- #nright=nright+1
- #else:
- #print "Error in ", i
return (ntotal,ntotal-nright)
-
-
def main(args):
nargs = len (args)
- if nargs == 2:
- esn0_db=float(args[0]) # Es/No in dB
- rep=int(args[1]) # number of times the experiment is run to collect enough errors
+ if nargs == 5:
+ fname_out=args[0]
+ fname_in=args[1]
+ esn0_db=float(args[2]) # Es/No in dB
+ IT=int(args[3])
+ rep=int(args[4]) # number of times the experiment is run to collect enough errors
else:
- sys.stderr.write ('usage: test_tcm2.py Es/No_db repetitions\n')
+ sys.stderr.write ('usage: test_tcm.py fsm_name_out fsm_fname_in Es/No_db iterations repetitions\n')
sys.exit (1)
# system parameters
- f=trellis.fsm(1,2,[5,7]) # generate FSM specification from the generator matrix
Kb=1024*16 # packet size in bits (make it multiple of 16 so it can be packed in a short)
- bitspersymbol = int(round(math.log(f.I())/math.log(2))) # bits per FSM input symbol
+ fo=trellis.fsm(fname_out) # get the outer FSM specification from a file
+ fi=trellis.fsm(fname_in) # get the innner FSM specification from a file
+ bitspersymbol = int(round(math.log(fo.I())/math.log(2))) # bits per FSM input symbol
+ if fo.O() != fi.I():
+ sys.stderr.write ('Incompatible cardinality between outer and inner FSM.\n')
+ sys.exit (1)
K=Kb/bitspersymbol # packet size in trellis steps
- modulation = fsm_utils.psk4 # see fsm_utlis.py for available predefined modulations
+ interleaver=trellis.interleaver(K,666) # construct a random interleaver
+ modulation = fsm_utils.psk8 # see fsm_utlis.py for available predefined modulations
dimensionality = modulation[0]
constellation = modulation[1]
- if len(constellation)/dimensionality != f.O():
+ if len(constellation)/dimensionality != fi.O():
sys.stderr.write ('Incompatible FSM output cardinality and modulation size.\n')
sys.exit (1)
# calculate average symbol energy
@@ -102,11 +85,11 @@ def main(args):
terr_s=0 # total number of shorts in error
terr_p=0 # total number of packets in error
for i in range(rep):
- (s,e)=run_test(f,Kb,bitspersymbol,K,dimensionality,constellation,N0,-long(666+i)) # run experiment with different seed to get different noise realizations
+ (s,e)=run_test(fo,fi,interleaver,Kb,bitspersymbol,K,dimensionality,constellation,Es,N0,IT,-long(666+i)) # run experiment with different seed to get different noise realizations
tot_s=tot_s+s
terr_s=terr_s+e
terr_p=terr_p+(terr_s!=0)
- if ((i+1)%100==0) : # display progress
+ if ((i+1)%10==0): # display progress
print i+1,terr_p, '%.2e' % ((1.0*terr_p)/(i+1)),tot_s,terr_s, '%.2e' % ((1.0*terr_s)/tot_s)
# estimate of the (short or bit) error rate
print rep,terr_p, '%.2e' % ((1.0*terr_p)/(i+1)),tot_s,terr_s, '%.2e' % ((1.0*terr_s)/tot_s)
diff --git a/gr-trellis/src/examples/test_sccc_turbo2.py b/gr-trellis/src/examples/test_sccc_turbo2.py
new file mode 100755
index 000000000..a47f6400e
--- /dev/null
+++ b/gr-trellis/src/examples/test_sccc_turbo2.py
@@ -0,0 +1,101 @@
+#!/usr/bin/env python
+
+from gnuradio import gr
+from gnuradio import trellis
+from gnuradio import eng_notation
+import math
+import sys
+import random
+import fsm_utils
+
+
+def run_test (fo,fi,interleaver,Kb,bitspersymbol,K,dimensionality,constellation,Es,N0,IT,seed):
+ tb = gr.top_block ()
+
+ # TX
+ src = gr.lfsr_32k_source_s()
+ src_head = gr.head (gr.sizeof_short,Kb/16) # packet size in shorts
+ s2fsmi = gr.packed_to_unpacked_ss(bitspersymbol,gr.GR_MSB_FIRST) # unpack shorts to symbols compatible with the outer FSM input cardinality
+ enc = trellis.sccc_encoder_ss(fo,0,fi,0,interleaver,K)
+ mod = gr.chunks_to_symbols_sf(constellation,dimensionality)
+
+ # CHANNEL
+ add = gr.add_ff()
+ noise = gr.noise_source_f(gr.GR_GAUSSIAN,math.sqrt(N0/2),seed)
+
+ # RX
+ metrics_in = trellis.metrics_f(fi.O(),dimensionality,constellation,trellis.TRELLIS_EUCLIDEAN) # data preprocessing to generate metrics for innner SISO
+ scale = gr.multiply_const_ff(1.0/N0)
+ dec = trellis.sccc_decoder_s(fo,0,-1,fi,0,-1,interleaver,K,IT,trellis.TRELLIS_MIN_SUM)
+ fsmi2s = gr.unpacked_to_packed_ss(bitspersymbol,gr.GR_MSB_FIRST) # pack FSM input symbols to shorts
+ dst = gr.check_lfsr_32k_s()
+
+ #tb.connect (src,src_head,s2fsmi,enc_out,inter,enc_in,mod)
+ tb.connect (src,src_head,s2fsmi,enc,mod)
+ tb.connect (mod,(add,0))
+ tb.connect (noise,(add,1))
+ #tb.connect (add,head)
+ #tb.connect (tail,fsmi2s,dst)
+ tb.connect (add,metrics_in,scale,dec,fsmi2s,dst)
+
+ tb.run()
+
+ #print enc_out.ST(), enc_in.ST()
+
+ ntotal = dst.ntotal ()
+ nright = dst.nright ()
+ runlength = dst.runlength ()
+ return (ntotal,ntotal-nright)
+
+
+def main(args):
+ nargs = len (args)
+ if nargs == 5:
+ fname_out=args[0]
+ fname_in=args[1]
+ esn0_db=float(args[2]) # Es/No in dB
+ IT=int(args[3])
+ rep=int(args[4]) # number of times the experiment is run to collect enough errors
+ else:
+ sys.stderr.write ('usage: test_tcm.py fsm_name_out fsm_fname_in Es/No_db iterations repetitions\n')
+ sys.exit (1)
+
+ # system parameters
+ Kb=1024*16 # packet size in bits (make it multiple of 16 so it can be packed in a short)
+ fo=trellis.fsm(fname_out) # get the outer FSM specification from a file
+ fi=trellis.fsm(fname_in) # get the innner FSM specification from a file
+ bitspersymbol = int(round(math.log(fo.I())/math.log(2))) # bits per FSM input symbol
+ if fo.O() != fi.I():
+ sys.stderr.write ('Incompatible cardinality between outer and inner FSM.\n')
+ sys.exit (1)
+ K=Kb/bitspersymbol # packet size in trellis steps
+ interleaver=trellis.interleaver(K,666) # construct a random interleaver
+ modulation = fsm_utils.psk8 # see fsm_utlis.py for available predefined modulations
+ dimensionality = modulation[0]
+ constellation = modulation[1]
+ if len(constellation)/dimensionality != fi.O():
+ sys.stderr.write ('Incompatible FSM output cardinality and modulation size.\n')
+ sys.exit (1)
+ # calculate average symbol energy
+ Es = 0
+ for i in range(len(constellation)):
+ Es = Es + constellation[i]**2
+ Es = Es / (len(constellation)/dimensionality)
+ N0=Es/pow(10.0,esn0_db/10.0); # calculate noise variance
+
+ tot_s=0 # total number of transmitted shorts
+ terr_s=0 # total number of shorts in error
+ terr_p=0 # total number of packets in error
+ for i in range(rep):
+ (s,e)=run_test(fo,fi,interleaver,Kb,bitspersymbol,K,dimensionality,constellation,Es,N0,IT,-long(666+i)) # run experiment with different seed to get different noise realizations
+ tot_s=tot_s+s
+ terr_s=terr_s+e
+ terr_p=terr_p+(terr_s!=0)
+ if ((i+1)%10==0): # display progress
+ print i+1,terr_p, '%.2e' % ((1.0*terr_p)/(i+1)),tot_s,terr_s, '%.2e' % ((1.0*terr_s)/tot_s)
+ # estimate of the (short or bit) error rate
+ print rep,terr_p, '%.2e' % ((1.0*terr_p)/(i+1)),tot_s,terr_s, '%.2e' % ((1.0*terr_s)/tot_s)
+
+
+if __name__ == '__main__':
+ main (sys.argv[1:])
diff --git a/gr-trellis/src/examples/test_tcm.py b/gr-trellis/src/examples/test_tcm.py
index 62e0c413a..d2e3c6271 100755
--- a/gr-trellis/src/examples/test_tcm.py
+++ b/gr-trellis/src/examples/test_tcm.py
@@ -1,13 +1,14 @@
#!/usr/bin/env python
from gnuradio import gr
-from gnuradio import audio
from gnuradio import trellis
from gnuradio import eng_notation
import math
import sys
import random
import fsm_utils
+from gnuradio.eng_option import eng_option
+from optparse import OptionParser
def run_test (f,Kb,bitspersymbol,K,dimensionality,constellation,N0,seed):
tb = gr.top_block ()
@@ -71,18 +72,25 @@ def run_test (f,Kb,bitspersymbol,K,dimensionality,constellation,N0,seed):
-def main(args):
- nargs = len (args)
- if nargs == 3:
- fname=args[0]
- esn0_db=float(args[1]) # Es/No in dB
- rep=int(args[2]) # number of times the experiment is run to collect enough errors
- else:
- sys.stderr.write ('usage: test_tcm.py fsm_fname Es/No_db repetitions\n')
- sys.exit (1)
+def main():
+ parser = OptionParser(option_class=eng_option)
+ parser.add_option("-f", "--fsm_file", type="string", default="fsm_files/awgn1o2_4.fsm", help="Filename containing the fsm specification, e.g. -f fsm_files/awgn1o2_4.fsm (default=fsm_files/awgn1o2_4.fsm)")
+ parser.add_option("-e", "--esn0", type="eng_float", default=10.0, help="Symbol energy to noise PSD level ratio in dB, e.g., -e 10.0 (default=10.0)")
+ parser.add_option("-r", "--repetitions", type="int", default=100, help="Number of packets to be generated for the simulation, e.g., -r 100 (default=100)")
+
+ (options, args) = parser.parse_args ()
+ if len(args) != 0:
+ parser.print_help()
+ raise SystemExit, 1
+
+ fname=options.fsm_file
+ esn0_db=float(options.esn0)
+ rep=int(options.repetitions)
# system parameters
f=trellis.fsm(fname) # get the FSM specification from a file
+ # alternatively you can specify the fsm from its generator matrix
+ #f=trellis.fsm(1,2,[5,7])
Kb=1024*16 # packet size in bits (make it multiple of 16 so it can be packed in a short)
bitspersymbol = int(round(math.log(f.I())/math.log(2))) # bits per FSM input symbol
K=Kb/bitspersymbol # packet size in trellis steps
@@ -115,4 +123,4 @@ def main(args):
if __name__ == '__main__':
- main (sys.argv[1:])
+ main()
diff --git a/gr-trellis/src/examples/test_tcm1.py b/gr-trellis/src/examples/test_tcm_bit.py
index 746bd9336..008e1e6f0 100755
--- a/gr-trellis/src/examples/test_tcm1.py
+++ b/gr-trellis/src/examples/test_tcm_bit.py
@@ -1,13 +1,15 @@
#!/usr/bin/env python
from gnuradio import gr
-from gnuradio import audio
from gnuradio import trellis
from gnuradio import eng_notation
import math
import sys
import random
import fsm_utils
+from gnuradio.eng_option import eng_option
+from optparse import OptionParser
+
def run_test (f,Kb,bitspersymbol,K,dimensionality,constellation,N0,seed):
tb = gr.top_block ()
@@ -74,15 +76,21 @@ def run_test (f,Kb,bitspersymbol,K,dimensionality,constellation,N0,seed):
-def main(args):
- nargs = len (args)
- if nargs == 3:
- fname=args[0]
- esn0_db=float(args[1]) # Es/No in dB
- rep=int(args[2]) # number of times the experiment is run to collect enough errors
- else:
- sys.stderr.write ('usage: test_tcm.py fsm_fname Es/No_db repetitions\n')
- sys.exit (1)
+def main():
+ parser = OptionParser(option_class=eng_option)
+ parser.add_option("-f", "--fsm_file", type="string", default="fsm_files/awgn1o2_4.fsm", help="Filename containing the fsm specification, e.g. -f fsm_files/awgn1o2_4.fsm (default=fsm_files/awgn1o2_4.fsm)")
+ parser.add_option("-e", "--esn0", type="eng_float", default=10.0, help="Symbol energy to noise PSD level ratio in dB, e.g., -e 10.0 (default=10.0)")
+ parser.add_option("-r", "--repetitions", type="int", default=100, help="Number of packets to be generated for the simulation, e.g., -r 100 (default=100)")
+
+ (options, args) = parser.parse_args ()
+ if len(args) != 0:
+ parser.print_help()
+ raise SystemExit, 1
+
+ fname=options.fsm_file
+ esn0_db=float(options.esn0)
+ rep=int(options.repetitions)
+
# system parameters
f=trellis.fsm(fname) # get the FSM specification from a file
@@ -100,7 +108,7 @@ def main(args):
for i in range(len(constellation)):
Es = Es + constellation[i]**2
Es = Es / (len(constellation)/dimensionality)
- N0=Es/pow(10.0,esn0_db/10.0); # noise variance
+ N0=Es/pow(10.0,esn0_db/10.0); # calculate noise variance
tot_s=0 # total number of transmitted shorts
terr_s=0 # total number of shorts in error
@@ -118,4 +126,4 @@ def main(args):
if __name__ == '__main__':
- main (sys.argv[1:])
+ main()
diff --git a/gr-trellis/src/examples/test_tcm_combined.py b/gr-trellis/src/examples/test_tcm_combined.py
index d2d42b40b..f9b698ae9 100755
--- a/gr-trellis/src/examples/test_tcm_combined.py
+++ b/gr-trellis/src/examples/test_tcm_combined.py
@@ -1,12 +1,14 @@
#!/usr/bin/env python
from gnuradio import gr
-from gnuradio import audio
from gnuradio import trellis
from gnuradio import eng_notation
import math
import sys
import fsm_utils
+from gnuradio.eng_option import eng_option
+from optparse import OptionParser
+
def run_test (f,Kb,bitspersymbol,K,dimensionality,constellation,N0,seed):
tb = gr.top_block ()
@@ -52,15 +54,20 @@ def run_test (f,Kb,bitspersymbol,K,dimensionality,constellation,N0,seed):
-def main(args):
- nargs = len (args)
- if nargs == 3:
- fname=args[0]
- esn0_db=float(args[1]) # Es/No in dB
- rep=int(args[2]) # number of times the experiment is run to collect enough errors
- else:
- sys.stderr.write ('usage: test_tcm_combined.py fsm_fname Es/No_db repetitions\n')
- sys.exit (1)
+def main():
+ parser = OptionParser(option_class=eng_option)
+ parser.add_option("-f", "--fsm_file", type="string", default="fsm_files/awgn1o2_4.fsm", help="Filename containing the fsm specification, e.g. -f fsm_files/awgn1o2_4.fsm (default=fsm_files/awgn1o2_4.fsm)")
+ parser.add_option("-e", "--esn0", type="eng_float", default=10.0, help="Symbol energy to noise PSD level ratio in dB, e.g., -e 10.0 (default=10.0)")
+ parser.add_option("-r", "--repetitions", type="int", default=100, help="Number of packets to be generated for the simulation, e.g., -r 100 (default=100)")
+
+ (options, args) = parser.parse_args ()
+ if len(args) != 0:
+ parser.print_help()
+ raise SystemExit, 1
+
+ fname=options.fsm_file
+ esn0_db=float(options.esn0)
+ rep=int(options.repetitions)
# system parameters
f=trellis.fsm(fname) # get the FSM specification from a file (will hopefully be automated in the future...)
@@ -96,5 +103,5 @@ def main(args):
if __name__ == '__main__':
- main (sys.argv[1:])
+ main()
diff --git a/gr-trellis/src/examples/test_tcm_parallel.py b/gr-trellis/src/examples/test_tcm_parallel.py
index 8e2f5a230..94761fd01 100755
--- a/gr-trellis/src/examples/test_tcm_parallel.py
+++ b/gr-trellis/src/examples/test_tcm_parallel.py
@@ -1,12 +1,14 @@
#!/usr/bin/env python
from gnuradio import gr
-from gnuradio import audio
from gnuradio import trellis
from gnuradio import eng_notation
import math
import sys
import fsm_utils
+from gnuradio.eng_option import eng_option
+from optparse import OptionParser
+
def run_test (f,Kb,bitspersymbol,K,dimensionality,constellation,N0,seed,P):
tb = gr.top_block ()
@@ -58,15 +60,20 @@ def run_test (f,Kb,bitspersymbol,K,dimensionality,constellation,N0,seed,P):
-def main(args):
- nargs = len (args)
- if nargs == 3:
- fname=args[0]
- esn0_db=float(args[1]) # Es/No in dB
- rep=int(args[2]) # number of times the experiment is run to collect enough errors
- else:
- sys.stderr.write ('usage: test_tcm.py fsm_fname Es/No_db repetitions\n')
- sys.exit (1)
+def main():
+ parser = OptionParser(option_class=eng_option)
+ parser.add_option("-f", "--fsm_file", type="string", default="fsm_files/awgn1o2_4.fsm", help="Filename containing the fsm specification, e.g. -f fsm_files/awgn1o2_4.fsm (default=fsm_files/awgn1o2_4.fsm)")
+ parser.add_option("-e", "--esn0", type="eng_float", default=10.0, help="Symbol energy to noise PSD level ratio in dB, e.g., -e 10.0 (default=10.0)")
+ parser.add_option("-r", "--repetitions", type="int", default=100, help="Number of packets to be generated for the simulation, e.g., -r 100 (default=100)")
+
+ (options, args) = parser.parse_args ()
+ if len(args) != 0:
+ parser.print_help()
+ raise SystemExit, 1
+
+ fname=options.fsm_file
+ esn0_db=float(options.esn0)
+ rep=int(options.repetitions)
# system parameters
f=trellis.fsm(fname) # get the FSM specification from a file
@@ -102,5 +109,5 @@ def main(args):
if __name__ == '__main__':
- main (sys.argv[1:])
+ main()
diff --git a/gr-trellis/src/examples/test_turbo_equalization.py b/gr-trellis/src/examples/test_turbo_equalization.py
index 612f6951c..0bf691222 100755
--- a/gr-trellis/src/examples/test_turbo_equalization.py
+++ b/gr-trellis/src/examples/test_turbo_equalization.py
@@ -1,7 +1,6 @@
#!/usr/bin/env python
from gnuradio import gr
-from gnuradio import audio
from gnuradio import trellis
from gnuradio import eng_notation
import math
diff --git a/gr-trellis/src/examples/test_turbo_equalization1.py b/gr-trellis/src/examples/test_turbo_equalization1.py
index 8d2feec8a..feae4ce89 100755
--- a/gr-trellis/src/examples/test_turbo_equalization1.py
+++ b/gr-trellis/src/examples/test_turbo_equalization1.py
@@ -1,7 +1,6 @@
#!/usr/bin/env python
from gnuradio import gr
-from gnuradio import audio
from gnuradio import trellis
from gnuradio import eng_notation
import math
diff --git a/gr-trellis/src/examples/test_turbo_equalization2.py b/gr-trellis/src/examples/test_turbo_equalization2.py
index f1731016e..ff14299c6 100755
--- a/gr-trellis/src/examples/test_turbo_equalization2.py
+++ b/gr-trellis/src/examples/test_turbo_equalization2.py
@@ -1,7 +1,6 @@
#!/usr/bin/env python
from gnuradio import gr
-from gnuradio import audio
from gnuradio import trellis
from gnuradio import eng_notation
import math
diff --git a/gr-trellis/src/examples/test_viterbi_equalization.py b/gr-trellis/src/examples/test_viterbi_equalization.py
index 86fc00674..eda692024 100755
--- a/gr-trellis/src/examples/test_viterbi_equalization.py
+++ b/gr-trellis/src/examples/test_viterbi_equalization.py
@@ -1,7 +1,6 @@
#!/usr/bin/env python
from gnuradio import gr
-from gnuradio import audio
from gnuradio import trellis
from gnuradio import eng_notation
import math
diff --git a/gr-trellis/src/examples/test_viterbi_equalization1.py b/gr-trellis/src/examples/test_viterbi_equalization1.py
index d26f73bc0..3a65b9363 100755
--- a/gr-trellis/src/examples/test_viterbi_equalization1.py
+++ b/gr-trellis/src/examples/test_viterbi_equalization1.py
@@ -1,7 +1,6 @@
#!/usr/bin/env python
from gnuradio import gr
-from gnuradio import audio
from gnuradio import trellis
from gnuradio import eng_notation
import math
diff --git a/gr-trellis/src/lib/.gitignore b/gr-trellis/src/lib/.gitignore
index 5dcb1c2c7..816b0aab8 100644
--- a/gr-trellis/src/lib/.gitignore
+++ b/gr-trellis/src/lib/.gitignore
@@ -57,6 +57,24 @@
/trellis_viterbi_i.cc
/trellis_encoder_bb.h
/trellis_encoder_bb.i
+/trellis_sccc_encoder_bb.cc
+/trellis_sccc_encoder_bb.h
+/trellis_sccc_encoder_bb.i
+/trellis_sccc_encoder_bi.cc
+/trellis_sccc_encoder_bi.h
+/trellis_sccc_encoder_bi.i
+/trellis_sccc_encoder_bs.cc
+/trellis_sccc_encoder_bs.h
+/trellis_sccc_encoder_bs.i
+/trellis_sccc_encoder_ii.cc
+/trellis_sccc_encoder_ii.h
+/trellis_sccc_encoder_ii.i
+/trellis_sccc_encoder_si.cc
+/trellis_sccc_encoder_si.h
+/trellis_sccc_encoder_si.i
+/trellis_sccc_encoder_ss.cc
+/trellis_sccc_encoder_ss.h
+/trellis_sccc_encoder_ss.i
/trellis_metrics_s.cc
/trellis_viterbi_combined_fs.h
/trellis_viterbi_combined_fs.i
@@ -94,6 +112,60 @@
/trellis_viterbi_combined_ss.i
/trellis_viterbi_combined_ib.cc
/trellis_viterbi_combined_sb.cc
+/trellis_sccc_decoder_combined_fb.h
+/trellis_sccc_decoder_combined_fb.i
+/trellis_sccc_decoder_combined_fb.cc
+/trellis_sccc_decoder_combined_fs.h
+/trellis_sccc_decoder_combined_fs.i
+/trellis_sccc_decoder_combined_fs.cc
+/trellis_sccc_decoder_combined_fi.h
+/trellis_sccc_decoder_combined_fi.i
+/trellis_sccc_decoder_combined_fi.cc
+/trellis_sccc_decoder_combined_cb.h
+/trellis_sccc_decoder_combined_cb.i
+/trellis_sccc_decoder_combined_cb.cc
+/trellis_sccc_decoder_combined_cs.h
+/trellis_sccc_decoder_combined_cs.i
+/trellis_sccc_decoder_combined_cs.cc
+/trellis_sccc_decoder_combined_ci.h
+/trellis_sccc_decoder_combined_ci.i
+/trellis_sccc_decoder_combined_ci.cc
+/trellis_sccc_decoder_b.h
+/trellis_sccc_decoder_b.i
+/trellis_sccc_decoder_b.cc
+/trellis_sccc_decoder_s.h
+/trellis_sccc_decoder_s.i
+/trellis_sccc_decoder_s.cc
+/trellis_sccc_decoder_i.h
+/trellis_sccc_decoder_i.i
+/trellis_sccc_decoder_i.cc
+/trellis_pccc_decoder_b.h
+/trellis_pccc_decoder_b.i
+/trellis_pccc_decoder_b.cc
+/trellis_pccc_decoder_s.h
+/trellis_pccc_decoder_s.i
+/trellis_pccc_decoder_s.cc
+/trellis_pccc_decoder_i.h
+/trellis_pccc_decoder_i.i
+/trellis_pccc_decoder_i.cc
+/trellis_pccc_encoder_bb.cc
+/trellis_pccc_encoder_bb.h
+/trellis_pccc_encoder_bb.i
+/trellis_pccc_encoder_bi.cc
+/trellis_pccc_encoder_bi.h
+/trellis_pccc_encoder_bi.i
+/trellis_pccc_encoder_bs.cc
+/trellis_pccc_encoder_bs.h
+/trellis_pccc_encoder_bs.i
+/trellis_pccc_encoder_ii.cc
+/trellis_pccc_encoder_ii.h
+/trellis_pccc_encoder_ii.i
+/trellis_pccc_encoder_si.cc
+/trellis_pccc_encoder_si.h
+/trellis_pccc_encoder_si.i
+/trellis_pccc_encoder_ss.cc
+/trellis_pccc_encoder_ss.h
+/trellis_pccc_encoder_ss.i
/trellis_generated.i
/generate-stamp
/stamp-*
diff --git a/gr-trellis/src/lib/Makefile.am b/gr-trellis/src/lib/Makefile.am
index 08e75291a..ae7f21f56 100644
--- a/gr-trellis/src/lib/Makefile.am
+++ b/gr-trellis/src/lib/Makefile.am
@@ -40,12 +40,27 @@ core_generator = \
trellis_encoder_XX.cc.t \
trellis_encoder_XX.h.t \
trellis_encoder_XX.i.t \
+ trellis_sccc_encoder_XX.cc.t \
+ trellis_sccc_encoder_XX.h.t \
+ trellis_sccc_encoder_XX.i.t \
+ trellis_pccc_encoder_XX.cc.t \
+ trellis_pccc_encoder_XX.h.t \
+ trellis_pccc_encoder_XX.i.t \
trellis_metrics_X.cc.t \
trellis_metrics_X.h.t \
trellis_metrics_X.i.t \
trellis_viterbi_combined_XX.cc.t \
trellis_viterbi_combined_XX.h.t \
trellis_viterbi_combined_XX.i.t \
+ trellis_sccc_decoder_combined_XX.cc.t \
+ trellis_sccc_decoder_combined_XX.h.t \
+ trellis_sccc_decoder_combined_XX.i.t \
+ trellis_sccc_decoder_X.cc.t \
+ trellis_sccc_decoder_X.h.t \
+ trellis_sccc_decoder_X.i.t \
+ trellis_pccc_decoder_X.cc.t \
+ trellis_pccc_decoder_X.h.t \
+ trellis_pccc_decoder_X.i.t \
trellis_viterbi_X.cc.t \
trellis_viterbi_X.h.t \
trellis_viterbi_X.i.t
@@ -66,10 +81,11 @@ grinclude_HEADERS = \
quicksort_index.h \
base.h \
interleaver.h \
- trellis_metric_type.h \
- trellis_calc_metric.h \
+ metric_type.h \
+ calc_metric.h \
+ core_algorithms.h \
trellis_permutation.h \
- trellis_siso_type.h \
+ siso_type.h \
trellis_siso_f.h \
trellis_siso_combined_f.h \
$(GENERATED_H)
@@ -81,7 +97,8 @@ libgnuradio_trellis_la_SOURCES = \
quicksort_index.cc \
base.cc \
interleaver.cc \
- trellis_calc_metric.cc \
+ calc_metric.cc \
+ core_algorithms.cc \
trellis_permutation.cc \
trellis_siso_f.cc \
trellis_siso_combined_f.cc \
diff --git a/gr-trellis/src/lib/Makefile.gen b/gr-trellis/src/lib/Makefile.gen
index 6a3f83387..534a7466e 100644
--- a/gr-trellis/src/lib/Makefile.gen
+++ b/gr-trellis/src/lib/Makefile.gen
@@ -12,6 +12,30 @@ GENERATED_H = \
trellis_metrics_f.h \
trellis_metrics_i.h \
trellis_metrics_s.h \
+ trellis_pccc_decoder_b.h \
+ trellis_pccc_decoder_i.h \
+ trellis_pccc_decoder_s.h \
+ trellis_pccc_encoder_bb.h \
+ trellis_pccc_encoder_bi.h \
+ trellis_pccc_encoder_bs.h \
+ trellis_pccc_encoder_ii.h \
+ trellis_pccc_encoder_si.h \
+ trellis_pccc_encoder_ss.h \
+ trellis_sccc_decoder_b.h \
+ trellis_sccc_decoder_combined_cb.h \
+ trellis_sccc_decoder_combined_ci.h \
+ trellis_sccc_decoder_combined_cs.h \
+ trellis_sccc_decoder_combined_fb.h \
+ trellis_sccc_decoder_combined_fi.h \
+ trellis_sccc_decoder_combined_fs.h \
+ trellis_sccc_decoder_i.h \
+ trellis_sccc_decoder_s.h \
+ trellis_sccc_encoder_bb.h \
+ trellis_sccc_encoder_bi.h \
+ trellis_sccc_encoder_bs.h \
+ trellis_sccc_encoder_ii.h \
+ trellis_sccc_encoder_si.h \
+ trellis_sccc_encoder_ss.h \
trellis_viterbi_b.h \
trellis_viterbi_combined_cb.h \
trellis_viterbi_combined_ci.h \
@@ -39,6 +63,30 @@ GENERATED_I = \
trellis_metrics_f.i \
trellis_metrics_i.i \
trellis_metrics_s.i \
+ trellis_pccc_decoder_b.i \
+ trellis_pccc_decoder_i.i \
+ trellis_pccc_decoder_s.i \
+ trellis_pccc_encoder_bb.i \
+ trellis_pccc_encoder_bi.i \
+ trellis_pccc_encoder_bs.i \
+ trellis_pccc_encoder_ii.i \
+ trellis_pccc_encoder_si.i \
+ trellis_pccc_encoder_ss.i \
+ trellis_sccc_decoder_b.i \
+ trellis_sccc_decoder_combined_cb.i \
+ trellis_sccc_decoder_combined_ci.i \
+ trellis_sccc_decoder_combined_cs.i \
+ trellis_sccc_decoder_combined_fb.i \
+ trellis_sccc_decoder_combined_fi.i \
+ trellis_sccc_decoder_combined_fs.i \
+ trellis_sccc_decoder_i.i \
+ trellis_sccc_decoder_s.i \
+ trellis_sccc_encoder_bb.i \
+ trellis_sccc_encoder_bi.i \
+ trellis_sccc_encoder_bs.i \
+ trellis_sccc_encoder_ii.i \
+ trellis_sccc_encoder_si.i \
+ trellis_sccc_encoder_ss.i \
trellis_viterbi_b.i \
trellis_viterbi_combined_cb.i \
trellis_viterbi_combined_ci.i \
@@ -66,6 +114,30 @@ GENERATED_CC = \
trellis_metrics_f.cc \
trellis_metrics_i.cc \
trellis_metrics_s.cc \
+ trellis_pccc_decoder_b.cc \
+ trellis_pccc_decoder_i.cc \
+ trellis_pccc_decoder_s.cc \
+ trellis_pccc_encoder_bb.cc \
+ trellis_pccc_encoder_bi.cc \
+ trellis_pccc_encoder_bs.cc \
+ trellis_pccc_encoder_ii.cc \
+ trellis_pccc_encoder_si.cc \
+ trellis_pccc_encoder_ss.cc \
+ trellis_sccc_decoder_b.cc \
+ trellis_sccc_decoder_combined_cb.cc \
+ trellis_sccc_decoder_combined_ci.cc \
+ trellis_sccc_decoder_combined_cs.cc \
+ trellis_sccc_decoder_combined_fb.cc \
+ trellis_sccc_decoder_combined_fi.cc \
+ trellis_sccc_decoder_combined_fs.cc \
+ trellis_sccc_decoder_i.cc \
+ trellis_sccc_decoder_s.cc \
+ trellis_sccc_encoder_bb.cc \
+ trellis_sccc_encoder_bi.cc \
+ trellis_sccc_encoder_bs.cc \
+ trellis_sccc_encoder_ii.cc \
+ trellis_sccc_encoder_si.cc \
+ trellis_sccc_encoder_ss.cc \
trellis_viterbi_b.cc \
trellis_viterbi_combined_cb.cc \
trellis_viterbi_combined_ci.cc \
diff --git a/gr-trellis/src/lib/trellis_calc_metric.cc b/gr-trellis/src/lib/calc_metric.cc
index 0d03fd1a7..0e8f9c2d5 100644
--- a/gr-trellis/src/lib/trellis_calc_metric.cc
+++ b/gr-trellis/src/lib/calc_metric.cc
@@ -22,7 +22,7 @@
#include <float.h>
#include <stdexcept>
-#include "trellis_calc_metric.h"
+#include "calc_metric.h"
diff --git a/gr-trellis/src/lib/trellis_calc_metric.h b/gr-trellis/src/lib/calc_metric.h
index fabf4e145..d628f44e0 100644
--- a/gr-trellis/src/lib/trellis_calc_metric.h
+++ b/gr-trellis/src/lib/calc_metric.h
@@ -20,12 +20,12 @@
* Boston, MA 02110-1301, USA.
*/
-#ifndef INCLUDED_TRELLIS_CALC_METRIC_H
-#define INCLUDED_TRELLIS_CALC_METRIC_H
+#ifndef INCLUDED_CALC_METRIC_H
+#define INCLUDED_CALC_METRIC_H
#include <vector>
#include <gr_complex.h>
-#include <trellis_metric_type.h>
+#include <metric_type.h>
template <class T>
diff --git a/gr-trellis/src/lib/core_algorithms.cc b/gr-trellis/src/lib/core_algorithms.cc
new file mode 100644
index 000000000..91ac8fbdf
--- /dev/null
+++ b/gr-trellis/src/lib/core_algorithms.cc
@@ -0,0 +1,1239 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <cstring>
+#include <stdexcept>
+//#include <cstdio>
+#include <iostream>
+#include "core_algorithms.h"
+#include "calc_metric.h"
+
+static const float INF = 1.0e9;
+
+float min(float a, float b)
+{
+ return a <= b ? a : b;
+}
+
+float min_star(float a, float b)
+{
+ return (a <= b ? a : b)-log(1+exp(a <= b ? a-b : b-a));
+}
+
+
+
+
+template <class T>
+void viterbi_algorithm(int I, int S, int O,
+ const std::vector<int> &NS,
+ const std::vector<int> &OS,
+ const std::vector< std::vector<int> > &PS,
+ const std::vector< std::vector<int> > &PI,
+ int K,
+ int S0,int SK,
+ const float *in, T *out)//,
+ //std::vector<int> &trace)
+{
+ std::vector<int> trace(S*K);
+ std::vector<float> alpha(S*2);
+ int alphai;
+ float norm,mm,minm;
+ int minmi;
+ int st;
+
+
+ if(S0<0) { // initial state not specified
+ for(int i=0;i<S;i++) alpha[0*S+i]=0;
+ }
+ else {
+ for(int i=0;i<S;i++) alpha[0*S+i]=INF;
+ alpha[0*S+S0]=0.0;
+ }
+
+ alphai=0;
+ for(int k=0;k<K;k++) {
+ norm=INF;
+ for(int j=0;j<S;j++) { // for each next state do ACS
+ minm=INF;
+ minmi=0;
+ for(unsigned int i=0;i<PS[j].size();i++) {
+ //int i0 = j*I+i;
+ if((mm=alpha[alphai*S+PS[j][i]]+in[k*O+OS[PS[j][i]*I+PI[j][i]]])<minm)
+ minm=mm,minmi=i;
+ }
+ trace[k*S+j]=minmi;
+ alpha[((alphai+1)%2)*S+j]=minm;
+ if(minm<norm) norm=minm;
+ }
+ for(int j=0;j<S;j++)
+ alpha[((alphai+1)%2)*S+j]-=norm; // normalize total metrics so they do not explode
+ alphai=(alphai+1)%2;
+ }
+
+ if(SK<0) { // final state not specified
+ minm=INF;
+ minmi=0;
+ for(int i=0;i<S;i++)
+ if((mm=alpha[alphai*S+i])<minm) minm=mm,minmi=i;
+ st=minmi;
+ }
+ else {
+ st=SK;
+ }
+
+ for(int k=K-1;k>=0;k--) { // traceback
+ int i0=trace[k*S+st];
+ out[k]= (T) PI[st][i0];
+ st=PS[st][i0];
+ }
+
+}
+
+
+template
+void viterbi_algorithm<unsigned char>(int I, int S, int O,
+ const std::vector<int> &NS,
+ const std::vector<int> &OS,
+ const std::vector< std::vector<int> > &PS,
+ const std::vector< std::vector<int> > &PI,
+ int K,
+ int S0,int SK,
+ const float *in, unsigned char *out);
+
+
+template
+void viterbi_algorithm<short>(int I, int S, int O,
+ const std::vector<int> &NS,
+ const std::vector<int> &OS,
+ const std::vector< std::vector<int> > &PS,
+ const std::vector< std::vector<int> > &PI,
+ int K,
+ int S0,int SK,
+ const float *in, short *out);
+
+template
+void viterbi_algorithm<int>(int I, int S, int O,
+ const std::vector<int> &NS,
+ const std::vector<int> &OS,
+ const std::vector< std::vector<int> > &PS,
+ const std::vector< std::vector<int> > &PI,
+ int K,
+ int S0,int SK,
+ const float *in, int *out);
+
+
+
+//==============================================
+
+template <class Ti, class To>
+void viterbi_algorithm_combined(int I, int S, int O,
+ const std::vector<int> &NS,
+ const std::vector<int> &OS,
+ const std::vector< std::vector<int> > &PS,
+ const std::vector< std::vector<int> > &PI,
+ int K,
+ int S0,int SK,
+ int D,
+ const std::vector<Ti> &TABLE,
+ trellis_metric_type_t TYPE,
+ const Ti *in, To *out
+)
+{
+ std::vector<int> trace(S*K);
+ std::vector<float> alpha(S*2);
+ float *metric = new float[O];
+ int alphai;
+ float norm,mm,minm;
+ int minmi;
+ int st;
+
+ if(S0<0) { // initial state not specified
+ for(int i=0;i<S;i++) alpha[0*S+i]=0;
+ }
+ else {
+ for(int i=0;i<S;i++) alpha[0*S+i]=INF;
+ alpha[0*S+S0]=0.0;
+ }
+
+ alphai=0;
+ for(int k=0;k<K;k++) {
+ calc_metric(O, D, TABLE, &(in[k*D]), metric,TYPE); // calc metrics
+ norm=INF;
+ for(int j=0;j<S;j++) { // for each next state do ACS
+ minm=INF;
+ minmi=0;
+ for(unsigned int i=0;i<PS[j].size();i++) {
+ //int i0 = j*I+i;
+ if((mm=alpha[alphai*S+PS[j][i]]+metric[OS[PS[j][i]*I+PI[j][i]]])<minm)
+ minm=mm,minmi=i;
+ }
+ trace[k*S+j]=minmi;
+ alpha[((alphai+1)%2)*S+j]=minm;
+ if(minm<norm) norm=minm;
+ }
+ for(int j=0;j<S;j++)
+ alpha[((alphai+1)%2)*S+j]-=norm; // normalize total metrics so they do not explode
+ alphai=(alphai+1)%2;
+ }
+
+ if(SK<0) { // final state not specified
+ minm=INF;
+ minmi=0;
+ for(int i=0;i<S;i++)
+ if((mm=alpha[alphai*S+i])<minm) minm=mm,minmi=i;
+ st=minmi;
+ }
+ else {
+ st=SK;
+ }
+
+ for(int k=K-1;k>=0;k--) { // traceback
+ int i0=trace[k*S+st];
+ out[k]= (To) PI[st][i0];
+ st=PS[st][i0];
+ }
+
+ delete [] metric;
+
+}
+
+// Ti = s i f c
+// To = b s i
+
+//---------------
+
+template
+void viterbi_algorithm_combined<short,unsigned char>(int I, int S, int O,
+ const std::vector<int> &NS,
+ const std::vector<int> &OS,
+ const std::vector< std::vector<int> > &PS,
+ const std::vector< std::vector<int> > &PI,
+ int K,
+ int S0,int SK,
+ int D,
+ const std::vector<short> &TABLE,
+ trellis_metric_type_t TYPE,
+ const short *in, unsigned char *out
+);
+
+template
+void viterbi_algorithm_combined<int,unsigned char>(int I, int S, int O,
+ const std::vector<int> &NS,
+ const std::vector<int> &OS,
+ const std::vector< std::vector<int> > &PS,
+ const std::vector< std::vector<int> > &PI,
+ int K,
+ int S0,int SK,
+ int D,
+ const std::vector<int> &TABLE,
+ trellis_metric_type_t TYPE,
+ const int *in, unsigned char *out
+);
+
+template
+void viterbi_algorithm_combined<float,unsigned char>(int I, int S, int O,
+ const std::vector<int> &NS,
+ const std::vector<int> &OS,
+ const std::vector< std::vector<int> > &PS,
+ const std::vector< std::vector<int> > &PI,
+ int K,
+ int S0,int SK,
+ int D,
+ const std::vector<float> &TABLE,
+ trellis_metric_type_t TYPE,
+ const float *in, unsigned char *out
+);
+
+template
+void viterbi_algorithm_combined<gr_complex,unsigned char>(int I, int S, int O,
+ const std::vector<int> &NS,
+ const std::vector<int> &OS,
+ const std::vector< std::vector<int> > &PS,
+ const std::vector< std::vector<int> > &PI,
+ int K,
+ int S0,int SK,
+ int D,
+ const std::vector<gr_complex> &TABLE,
+ trellis_metric_type_t TYPE,
+ const gr_complex *in, unsigned char *out
+);
+
+//---------------
+
+template
+void viterbi_algorithm_combined<short,short>(int I, int S, int O,
+ const std::vector<int> &NS,
+ const std::vector<int> &OS,
+ const std::vector< std::vector<int> > &PS,
+ const std::vector< std::vector<int> > &PI,
+ int K,
+ int S0,int SK,
+ int D,
+ const std::vector<short> &TABLE,
+ trellis_metric_type_t TYPE,
+ const short *in, short *out
+);
+
+template
+void viterbi_algorithm_combined<int,short>(int I, int S, int O,
+ const std::vector<int> &NS,
+ const std::vector<int> &OS,
+ const std::vector< std::vector<int> > &PS,
+ const std::vector< std::vector<int> > &PI,
+ int K,
+ int S0,int SK,
+ int D,
+ const std::vector<int> &TABLE,
+ trellis_metric_type_t TYPE,
+ const int *in, short *out
+);
+
+template
+void viterbi_algorithm_combined<float,short>(int I, int S, int O,
+ const std::vector<int> &NS,
+ const std::vector<int> &OS,
+ const std::vector< std::vector<int> > &PS,
+ const std::vector< std::vector<int> > &PI,
+ int K,
+ int S0,int SK,
+ int D,
+ const std::vector<float> &TABLE,
+ trellis_metric_type_t TYPE,
+ const float *in, short *out
+);
+
+template
+void viterbi_algorithm_combined<gr_complex,short>(int I, int S, int O,
+ const std::vector<int> &NS,
+ const std::vector<int> &OS,
+ const std::vector< std::vector<int> > &PS,
+ const std::vector< std::vector<int> > &PI,
+ int K,
+ int S0,int SK,
+ int D,
+ const std::vector<gr_complex> &TABLE,
+ trellis_metric_type_t TYPE,
+ const gr_complex *in, short *out
+);
+
+//--------------
+
+template
+void viterbi_algorithm_combined<short,int>(int I, int S, int O,
+ const std::vector<int> &NS,
+ const std::vector<int> &OS,
+ const std::vector< std::vector<int> > &PS,
+ const std::vector< std::vector<int> > &PI,
+ int K,
+ int S0,int SK,
+ int D,
+ const std::vector<short> &TABLE,
+ trellis_metric_type_t TYPE,
+ const short *in, int *out
+);
+
+template
+void viterbi_algorithm_combined<int,int>(int I, int S, int O,
+ const std::vector<int> &NS,
+ const std::vector<int> &OS,
+ const std::vector< std::vector<int> > &PS,
+ const std::vector< std::vector<int> > &PI,
+ int K,
+ int S0,int SK,
+ int D,
+ const std::vector<int> &TABLE,
+ trellis_metric_type_t TYPE,
+ const int *in, int *out
+);
+
+template
+void viterbi_algorithm_combined<float,int>(int I, int S, int O,
+ const std::vector<int> &NS,
+ const std::vector<int> &OS,
+ const std::vector< std::vector<int> > &PS,
+ const std::vector< std::vector<int> > &PI,
+ int K,
+ int S0,int SK,
+ int D,
+ const std::vector<float> &TABLE,
+ trellis_metric_type_t TYPE,
+ const float *in, int *out
+);
+
+template
+void viterbi_algorithm_combined<gr_complex,int>(int I, int S, int O,
+ const std::vector<int> &NS,
+ const std::vector<int> &OS,
+ const std::vector< std::vector<int> > &PS,
+ const std::vector< std::vector<int> > &PI,
+ int K,
+ int S0,int SK,
+ int D,
+ const std::vector<gr_complex> &TABLE,
+ trellis_metric_type_t TYPE,
+ const gr_complex *in, int *out
+);
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+//===============================================
+
+
+void siso_algorithm(int I, int S, int O,
+ const std::vector<int> &NS,
+ const std::vector<int> &OS,
+ const std::vector< std::vector<int> > &PS,
+ const std::vector< std::vector<int> > &PI,
+ int K,
+ int S0,int SK,
+ bool POSTI, bool POSTO,
+ float (*p2mymin)(float,float),
+ const float *priori, const float *prioro, float *post//,
+ //std::vector<float> &alpha,
+ //std::vector<float> &beta
+ )
+{
+ float norm,mm,minm;
+ std::vector<float> alpha(S*(K+1));
+ std::vector<float> beta(S*(K+1));
+
+
+ if(S0<0) { // initial state not specified
+ for(int i=0;i<S;i++) alpha[0*S+i]=0;
+ }
+ else {
+ for(int i=0;i<S;i++) alpha[0*S+i]=INF;
+ alpha[0*S+S0]=0.0;
+ }
+
+ for(int k=0;k<K;k++) { // forward recursion
+ norm=INF;
+ for(int j=0;j<S;j++) {
+ minm=INF;
+ for(unsigned int i=0;i<PS[j].size();i++) {
+ //int i0 = j*I+i;
+ mm=alpha[k*S+PS[j][i]]+priori[k*I+PI[j][i]]+prioro[k*O+OS[PS[j][i]*I+PI[j][i]]];
+ minm=(*p2mymin)(minm,mm);
+ }
+ alpha[(k+1)*S+j]=minm;
+ if(minm<norm) norm=minm;
+ }
+ for(int j=0;j<S;j++)
+ alpha[(k+1)*S+j]-=norm; // normalize total metrics so they do not explode
+ }
+
+ if(SK<0) { // final state not specified
+ for(int i=0;i<S;i++) beta[K*S+i]=0;
+ }
+ else {
+ for(int i=0;i<S;i++) beta[K*S+i]=INF;
+ beta[K*S+SK]=0.0;
+ }
+
+ for(int k=K-1;k>=0;k--) { // backward recursion
+ norm=INF;
+ for(int j=0;j<S;j++) {
+ minm=INF;
+ for(int i=0;i<I;i++) {
+ int i0 = j*I+i;
+ mm=beta[(k+1)*S+NS[i0]]+priori[k*I+i]+prioro[k*O+OS[i0]];
+ minm=(*p2mymin)(minm,mm);
+ }
+ beta[k*S+j]=minm;
+ if(minm<norm) norm=minm;
+ }
+ for(int j=0;j<S;j++)
+ beta[k*S+j]-=norm; // normalize total metrics so they do not explode
+ }
+
+
+if (POSTI && POSTO)
+{
+ for(int k=0;k<K;k++) { // input combining
+ norm=INF;
+ for(int i=0;i<I;i++) {
+ minm=INF;
+ for(int j=0;j<S;j++) {
+ mm=alpha[k*S+j]+prioro[k*O+OS[j*I+i]]+beta[(k+1)*S+NS[j*I+i]];
+ minm=(*p2mymin)(minm,mm);
+ }
+ post[k*(I+O)+i]=minm;
+ if(minm<norm) norm=minm;
+ }
+ for(int i=0;i<I;i++)
+ post[k*(I+O)+i]-=norm; // normalize metrics
+ }
+
+
+ for(int k=0;k<K;k++) { // output combining
+ norm=INF;
+ for(int n=0;n<O;n++) {
+ minm=INF;
+ for(int j=0;j<S;j++) {
+ for(int i=0;i<I;i++) {
+ mm= (n==OS[j*I+i] ? alpha[k*S+j]+priori[k*I+i]+beta[(k+1)*S+NS[j*I+i]] : INF);
+ minm=(*p2mymin)(minm,mm);
+ }
+ }
+ post[k*(I+O)+I+n]=minm;
+ if(minm<norm) norm=minm;
+ }
+ for(int n=0;n<O;n++)
+ post[k*(I+O)+I+n]-=norm; // normalize metrics
+ }
+}
+else if(POSTI)
+{
+ for(int k=0;k<K;k++) { // input combining
+ norm=INF;
+ for(int i=0;i<I;i++) {
+ minm=INF;
+ for(int j=0;j<S;j++) {
+ mm=alpha[k*S+j]+prioro[k*O+OS[j*I+i]]+beta[(k+1)*S+NS[j*I+i]];
+ minm=(*p2mymin)(minm,mm);
+ }
+ post[k*I+i]=minm;
+ if(minm<norm) norm=minm;
+ }
+ for(int i=0;i<I;i++)
+ post[k*I+i]-=norm; // normalize metrics
+ }
+}
+else if(POSTO)
+{
+ for(int k=0;k<K;k++) { // output combining
+ norm=INF;
+ for(int n=0;n<O;n++) {
+ minm=INF;
+ for(int j=0;j<S;j++) {
+ for(int i=0;i<I;i++) {
+ mm= (n==OS[j*I+i] ? alpha[k*S+j]+priori[k*I+i]+beta[(k+1)*S+NS[j*I+i]] : INF);
+ minm=(*p2mymin)(minm,mm);
+ }
+ }
+ post[k*O+n]=minm;
+ if(minm<norm) norm=minm;
+ }
+ for(int n=0;n<O;n++)
+ post[k*O+n]-=norm; // normalize metrics
+ }
+}
+else
+ throw std::runtime_error ("Not both POSTI and POSTO can be false.");
+
+}
+
+
+//===========================================================
+
+template <class T>
+void siso_algorithm_combined(int I, int S, int O,
+ const std::vector<int> &NS,
+ const std::vector<int> &OS,
+ const std::vector< std::vector<int> > &PS,
+ const std::vector< std::vector<int> > &PI,
+ int K,
+ int S0,int SK,
+ bool POSTI, bool POSTO,
+ float (*p2mymin)(float,float),
+ int D,
+ const std::vector<T> &TABLE,
+ trellis_metric_type_t TYPE,
+ const float *priori, const T *observations, float *post
+)
+{
+ float norm,mm,minm;
+ std::vector<float> alpha(S*(K+1));
+ std::vector<float> beta(S*(K+1));
+ float *prioro = new float[O*K];
+
+
+ if(S0<0) { // initial state not specified
+ for(int i=0;i<S;i++) alpha[0*S+i]=0;
+ }
+ else {
+ for(int i=0;i<S;i++) alpha[0*S+i]=INF;
+ alpha[0*S+S0]=0.0;
+ }
+
+ for(int k=0;k<K;k++) { // forward recursion
+ calc_metric(O, D, TABLE, &(observations[k*D]), &(prioro[k*O]),TYPE); // calc metrics
+ norm=INF;
+ for(int j=0;j<S;j++) {
+ minm=INF;
+ for(unsigned int i=0;i<PS[j].size();i++) {
+ //int i0 = j*I+i;
+ mm=alpha[k*S+PS[j][i]]+priori[k*I+PI[j][i]]+prioro[k*O+OS[PS[j][i]*I+PI[j][i]]];
+ minm=(*p2mymin)(minm,mm);
+ }
+ alpha[(k+1)*S+j]=minm;
+ if(minm<norm) norm=minm;
+ }
+ for(int j=0;j<S;j++)
+ alpha[(k+1)*S+j]-=norm; // normalize total metrics so they do not explode
+ }
+
+ if(SK<0) { // final state not specified
+ for(int i=0;i<S;i++) beta[K*S+i]=0;
+ }
+ else {
+ for(int i=0;i<S;i++) beta[K*S+i]=INF;
+ beta[K*S+SK]=0.0;
+ }
+
+ for(int k=K-1;k>=0;k--) { // backward recursion
+ norm=INF;
+ for(int j=0;j<S;j++) {
+ minm=INF;
+ for(int i=0;i<I;i++) {
+ int i0 = j*I+i;
+ mm=beta[(k+1)*S+NS[i0]]+priori[k*I+i]+prioro[k*O+OS[i0]];
+ minm=(*p2mymin)(minm,mm);
+ }
+ beta[k*S+j]=minm;
+ if(minm<norm) norm=minm;
+ }
+ for(int j=0;j<S;j++)
+ beta[k*S+j]-=norm; // normalize total metrics so they do not explode
+ }
+
+
+ if (POSTI && POSTO)
+ {
+ for(int k=0;k<K;k++) { // input combining
+ norm=INF;
+ for(int i=0;i<I;i++) {
+ minm=INF;
+ for(int j=0;j<S;j++) {
+ mm=alpha[k*S+j]+prioro[k*O+OS[j*I+i]]+beta[(k+1)*S+NS[j*I+i]];
+ minm=(*p2mymin)(minm,mm);
+ }
+ post[k*(I+O)+i]=minm;
+ if(minm<norm) norm=minm;
+ }
+ for(int i=0;i<I;i++)
+ post[k*(I+O)+i]-=norm; // normalize metrics
+ }
+
+
+ for(int k=0;k<K;k++) { // output combining
+ norm=INF;
+ for(int n=0;n<O;n++) {
+ minm=INF;
+ for(int j=0;j<S;j++) {
+ for(int i=0;i<I;i++) {
+ mm= (n==OS[j*I+i] ? alpha[k*S+j]+priori[k*I+i]+beta[(k+1)*S+NS[j*I+i]] : INF);
+ minm=(*p2mymin)(minm,mm);
+ }
+ }
+ post[k*(I+O)+I+n]=minm;
+ if(minm<norm) norm=minm;
+ }
+ for(int n=0;n<O;n++)
+ post[k*(I+O)+I+n]-=norm; // normalize metrics
+ }
+ }
+ else if(POSTI)
+ {
+ for(int k=0;k<K;k++) { // input combining
+ norm=INF;
+ for(int i=0;i<I;i++) {
+ minm=INF;
+ for(int j=0;j<S;j++) {
+ mm=alpha[k*S+j]+prioro[k*O+OS[j*I+i]]+beta[(k+1)*S+NS[j*I+i]];
+ minm=(*p2mymin)(minm,mm);
+ }
+ post[k*I+i]=minm;
+ if(minm<norm) norm=minm;
+ }
+ for(int i=0;i<I;i++)
+ post[k*I+i]-=norm; // normalize metrics
+ }
+ }
+ else if(POSTO)
+ {
+ for(int k=0;k<K;k++) { // output combining
+ norm=INF;
+ for(int n=0;n<O;n++) {
+ minm=INF;
+ for(int j=0;j<S;j++) {
+ for(int i=0;i<I;i++) {
+ mm= (n==OS[j*I+i] ? alpha[k*S+j]+priori[k*I+i]+beta[(k+1)*S+NS[j*I+i]] : INF);
+ minm=(*p2mymin)(minm,mm);
+ }
+ }
+ post[k*O+n]=minm;
+ if(minm<norm) norm=minm;
+ }
+ for(int n=0;n<O;n++)
+ post[k*O+n]-=norm; // normalize metrics
+ }
+ }
+ else
+ throw std::runtime_error ("Not both POSTI and POSTO can be false.");
+
+ delete [] prioro;
+
+}
+
+//---------
+
+template
+void siso_algorithm_combined<short>(int I, int S, int O,
+ const std::vector<int> &NS,
+ const std::vector<int> &OS,
+ const std::vector< std::vector<int> > &PS,
+ const std::vector< std::vector<int> > &PI,
+ int K,
+ int S0,int SK,
+ bool POSTI, bool POSTO,
+ float (*p2mymin)(float,float),
+ int D,
+ const std::vector<short> &TABLE,
+ trellis_metric_type_t TYPE,
+ const float *priori, const short *observations, float *post
+);
+
+template
+void siso_algorithm_combined<int>(int I, int S, int O,
+ const std::vector<int> &NS,
+ const std::vector<int> &OS,
+ const std::vector< std::vector<int> > &PS,
+ const std::vector< std::vector<int> > &PI,
+ int K,
+ int S0,int SK,
+ bool POSTI, bool POSTO,
+ float (*p2mymin)(float,float),
+ int D,
+ const std::vector<int> &TABLE,
+ trellis_metric_type_t TYPE,
+ const float *priori, const int *observations, float *post
+);
+
+template
+void siso_algorithm_combined<float>(int I, int S, int O,
+ const std::vector<int> &NS,
+ const std::vector<int> &OS,
+ const std::vector< std::vector<int> > &PS,
+ const std::vector< std::vector<int> > &PI,
+ int K,
+ int S0,int SK,
+ bool POSTI, bool POSTO,
+ float (*p2mymin)(float,float),
+ int D,
+ const std::vector<float> &TABLE,
+ trellis_metric_type_t TYPE,
+ const float *priori, const float *observations, float *post
+);
+
+template
+void siso_algorithm_combined<gr_complex>(int I, int S, int O,
+ const std::vector<int> &NS,
+ const std::vector<int> &OS,
+ const std::vector< std::vector<int> > &PS,
+ const std::vector< std::vector<int> > &PI,
+ int K,
+ int S0,int SK,
+ bool POSTI, bool POSTO,
+ float (*p2mymin)(float,float),
+ int D,
+ const std::vector<gr_complex> &TABLE,
+ trellis_metric_type_t TYPE,
+ const float *priori, const gr_complex *observations, float *post
+);
+
+//=========================================================
+
+template<class Ti, class To>
+void sccc_decoder_combined(
+ const fsm &FSMo, int STo0, int SToK,
+ const fsm &FSMi, int STi0, int STiK,
+ const interleaver &INTERLEAVER, int blocklength, int repetitions,
+ float (*p2mymin)(float,float),
+ int D, const std::vector<Ti> &TABLE,
+ trellis_metric_type_t METRIC_TYPE,
+ float scaling,
+ const Ti *observations, To *data
+)
+{
+
+//allocate space for priori, prioro and posti of inner FSM
+std::vector<float> ipriori(blocklength*FSMi.I(),0.0);
+std::vector<float> iprioro(blocklength*FSMi.O());
+std::vector<float> iposti(blocklength*FSMi.I());
+
+//allocate space for priori, prioro and posto of outer FSM
+std::vector<float> opriori(blocklength*FSMo.I(),0.0);
+std::vector<float> oprioro(blocklength*FSMo.O());
+std::vector<float> oposti(blocklength*FSMo.I());
+std::vector<float> oposto(blocklength*FSMo.O());
+
+// turn observations to neg-log-priors
+for(int k=0;k<blocklength;k++) {
+ calc_metric(FSMi.O(), D, TABLE, &(observations[k*D]), &(iprioro[k*FSMi.O()]),METRIC_TYPE);
+ iprioro[k*FSMi.O()] *= scaling;
+}
+
+for(int rep=0;rep<repetitions;rep++) {
+ // run inner SISO
+ siso_algorithm(FSMi.I(),FSMi.S(),FSMi.O(),
+ FSMi.NS(), FSMi.OS(), FSMi.PS(), FSMi.PI(),
+ blocklength,
+ STi0,STiK,
+ true, false,
+ p2mymin,
+ &(ipriori[0]), &(iprioro[0]), &(iposti[0])
+ );
+
+ //interleave soft info inner -> outer
+ for(int k=0;k<blocklength;k++) {
+ int ki = INTERLEAVER.DEINTER()[k];
+ //for(int i=0;i<FSMi.I();i++) {
+ //oprioro[k*FSMi.I()+i]=iposti[ki*FSMi.I()+i];
+ //}
+ memcpy(&(oprioro[k*FSMi.I()]),&(iposti[ki*FSMi.I()]),FSMi.I()*sizeof(float));
+ }
+
+ // run outer SISO
+
+ if(rep<repetitions-1) { // do not produce posti
+ siso_algorithm(FSMo.I(),FSMo.S(),FSMo.O(),
+ FSMo.NS(), FSMo.OS(), FSMo.PS(), FSMo.PI(),
+ blocklength,
+ STo0,SToK,
+ false, true,
+ p2mymin,
+ &(opriori[0]), &(oprioro[0]), &(oposto[0])
+ );
+
+ //interleave soft info outer --> inner
+ for(int k=0;k<blocklength;k++) {
+ int ki = INTERLEAVER.DEINTER()[k];
+ //for(int i=0;i<FSMi.I();i++) {
+ //ipriori[ki*FSMi.I()+i]=oposto[k*FSMi.I()+i];
+ //}
+ memcpy(&(ipriori[ki*FSMi.I()]),&(oposto[k*FSMi.I()]),FSMi.I()*sizeof(float));
+ }
+ }
+ else // produce posti but not posto
+
+ siso_algorithm(FSMo.I(),FSMo.S(),FSMo.O(),
+ FSMo.NS(), FSMo.OS(), FSMo.PS(), FSMo.PI(),
+ blocklength,
+ STo0,SToK,
+ true, false,
+ p2mymin,
+ &(opriori[0]), &(oprioro[0]), &(oposti[0])
+ );
+
+ /*
+ viterbi_algorithm(FSMo.I(),FSMo.S(),FSMo.O(),
+ FSMo.NS(), FSMo.OS(), FSMo.PS(), FSMo.PI(),
+ blocklength,
+ STo0,SToK,
+ &(oprioro[0]), data
+ );
+ */
+
+}
+
+
+// generate hard decisions
+for(int k=0;k<blocklength;k++) {
+ float min=INF;
+ int mini=0;
+ for(int i=0;i<FSMo.I();i++) {
+ if(oposti[k*FSMo.I()+i]<min) {
+ min=oposti[k*FSMo.I()+i];
+ mini=i;
+ }
+ }
+ data[k]=(To)mini;
+}
+
+
+
+}
+
+//-------
+
+template
+void sccc_decoder_combined<float,unsigned char>(
+ const fsm &FSMo, int STo0, int SToK,
+ const fsm &FSMi, int STi0, int STiK,
+ const interleaver &INTERLEAVER, int blocklength, int repetitions,
+ float (*p2mymin)(float,float),
+ int D, const std::vector<float> &TABLE,
+ trellis_metric_type_t METRIC_TYPE,
+ float scaling,
+ const float *observations, unsigned char *data
+);
+
+template
+void sccc_decoder_combined<float,short>(
+ const fsm &FSMo, int STo0, int SToK,
+ const fsm &FSMi, int STi0, int STiK,
+ const interleaver &INTERLEAVER, int blocklength, int repetitions,
+ float (*p2mymin)(float,float),
+ int D, const std::vector<float> &TABLE,
+ trellis_metric_type_t METRIC_TYPE,
+ float scaling,
+ const float *observations, short *data
+);
+
+template
+void sccc_decoder_combined<float,int>(
+ const fsm &FSMo, int STo0, int SToK,
+ const fsm &FSMi, int STi0, int STiK,
+ const interleaver &INTERLEAVER, int blocklength, int repetitions,
+ float (*p2mymin)(float,float),
+ int D, const std::vector<float> &TABLE,
+ trellis_metric_type_t METRIC_TYPE,
+ float scaling,
+ const float *observations, int *data
+);
+
+template
+void sccc_decoder_combined<gr_complex,unsigned char>(
+ const fsm &FSMo, int STo0, int SToK,
+ const fsm &FSMi, int STi0, int STiK,
+ const interleaver &INTERLEAVER, int blocklength, int repetitions,
+ float (*p2mymin)(float,float),
+ int D, const std::vector<gr_complex> &TABLE,
+ trellis_metric_type_t METRIC_TYPE,
+ float scaling,
+ const gr_complex *observations, unsigned char *data
+);
+
+template
+void sccc_decoder_combined<gr_complex,short>(
+ const fsm &FSMo, int STo0, int SToK,
+ const fsm &FSMi, int STi0, int STiK,
+ const interleaver &INTERLEAVER, int blocklength, int repetitions,
+ float (*p2mymin)(float,float),
+ int D, const std::vector<gr_complex> &TABLE,
+ trellis_metric_type_t METRIC_TYPE,
+ float scaling,
+ const gr_complex *observations, short *data
+);
+
+template
+void sccc_decoder_combined<gr_complex,int>(
+ const fsm &FSMo, int STo0, int SToK,
+ const fsm &FSMi, int STi0, int STiK,
+ const interleaver &INTERLEAVER, int blocklength, int repetitions,
+ float (*p2mymin)(float,float),
+ int D, const std::vector<gr_complex> &TABLE,
+ trellis_metric_type_t METRIC_TYPE,
+ float scaling,
+ const gr_complex *observations, int *data
+);
+
+
+
+//=========================================================
+
+template<class T>
+void sccc_decoder(
+ const fsm &FSMo, int STo0, int SToK,
+ const fsm &FSMi, int STi0, int STiK,
+ const interleaver &INTERLEAVER, int blocklength, int repetitions,
+ float (*p2mymin)(float,float),
+ const float *iprioro, T *data
+)
+{
+ //allocate space for priori, and posti of inner FSM
+ std::vector<float> ipriori(blocklength*FSMi.I(),0.0);
+ std::vector<float> iposti(blocklength*FSMi.I());
+
+ //allocate space for priori, prioro and posto of outer FSM
+ std::vector<float> opriori(blocklength*FSMo.I(),0.0);
+ std::vector<float> oprioro(blocklength*FSMo.O());
+ std::vector<float> oposti(blocklength*FSMo.I());
+ std::vector<float> oposto(blocklength*FSMo.O());
+
+ for(int rep=0;rep<repetitions;rep++) {
+ // run inner SISO
+ siso_algorithm(FSMi.I(),FSMi.S(),FSMi.O(),
+ FSMi.NS(), FSMi.OS(), FSMi.PS(), FSMi.PI(),
+ blocklength,
+ STi0,STiK,
+ true, false,
+ p2mymin,
+ &(ipriori[0]), &(iprioro[0]), &(iposti[0])
+ );
+
+ //interleave soft info inner -> outer
+ for(int k=0;k<blocklength;k++) {
+ int ki = INTERLEAVER.DEINTER()[k];
+ //for(int i=0;i<FSMi.I();i++) {
+ //oprioro[k*FSMi.I()+i]=iposti[ki*FSMi.I()+i];
+ //}
+ memcpy(&(oprioro[k*FSMi.I()]),&(iposti[ki*FSMi.I()]),FSMi.I()*sizeof(float));
+ }
+
+ // run outer SISO
+
+ if(rep<repetitions-1) { // do not produce posti
+ siso_algorithm(FSMo.I(),FSMo.S(),FSMo.O(),
+ FSMo.NS(), FSMo.OS(), FSMo.PS(), FSMo.PI(),
+ blocklength,
+ STo0,SToK,
+ false, true,
+ p2mymin,
+ &(opriori[0]), &(oprioro[0]), &(oposto[0])
+ );
+
+ //interleave soft info outer --> inner
+ for(int k=0;k<blocklength;k++) {
+ int ki = INTERLEAVER.DEINTER()[k];
+ //for(int i=0;i<FSMi.I();i++) {
+ //ipriori[ki*FSMi.I()+i]=oposto[k*FSMi.I()+i];
+ //}
+ memcpy(&(ipriori[ki*FSMi.I()]),&(oposto[k*FSMi.I()]),FSMi.I()*sizeof(float));
+ }
+ }
+ else {// produce posti but not posto
+
+ siso_algorithm(FSMo.I(),FSMo.S(),FSMo.O(),
+ FSMo.NS(), FSMo.OS(), FSMo.PS(), FSMo.PI(),
+ blocklength,
+ STo0,SToK,
+ true, false,
+ p2mymin,
+ &(opriori[0]), &(oprioro[0]), &(oposti[0])
+ );
+
+ /*
+ viterbi_algorithm(FSMo.I(),FSMo.S(),FSMo.O(),
+ FSMo.NS(), FSMo.OS(), FSMo.PS(), FSMo.PI(),
+ blocklength,
+ STo0,SToK,
+ &(oprioro[0]), data
+ );
+ */
+ }
+
+ } // end repetitions
+
+ // generate hard decisions
+ for(int k=0;k<blocklength;k++) {
+ float min=INF;
+ int mini=0;
+ for(int i=0;i<FSMo.I();i++) {
+ if(oposti[k*FSMo.I()+i]<min) {
+ min=oposti[k*FSMo.I()+i];
+ mini=i;
+ }
+ }
+ data[k]=(T)mini;
+ }
+
+
+
+}
+
+//-------
+
+template
+void sccc_decoder<unsigned char>(
+ const fsm &FSMo, int STo0, int SToK,
+ const fsm &FSMi, int STi0, int STiK,
+ const interleaver &INTERLEAVER, int blocklength, int repetitions,
+ float (*p2mymin)(float,float),
+ const float *iprioro, unsigned char *data
+);
+
+template
+void sccc_decoder<short>(
+ const fsm &FSMo, int STo0, int SToK,
+ const fsm &FSMi, int STi0, int STiK,
+ const interleaver &INTERLEAVER, int blocklength, int repetitions,
+ float (*p2mymin)(float,float),
+ const float *iprioro, short *data
+);
+
+template
+void sccc_decoder<int>(
+ const fsm &FSMo, int STo0, int SToK,
+ const fsm &FSMi, int STi0, int STiK,
+ const interleaver &INTERLEAVER, int blocklength, int repetitions,
+ float (*p2mymin)(float,float),
+ const float *iprioro, int *data
+);
+
+
+//====================================================
+
+template<class T>
+void pccc_decoder(
+ const fsm &FSM1, int ST10, int ST1K,
+ const fsm &FSM2, int ST20, int ST2K,
+ const interleaver &INTERLEAVER, int blocklength, int repetitions,
+ float (*p2mymin)(float,float),
+ const float *cprioro, T *data
+)
+{
+
+ //allocate space for priori, prioro and posti of FSM1
+ std::vector<float> priori1(blocklength*FSM1.I(),0.0);
+ std::vector<float> prioro1(blocklength*FSM1.O());
+ std::vector<float> posti1(blocklength*FSM1.I());
+
+ //allocate space for priori, prioro and posti of FSM2
+ std::vector<float> priori2(blocklength*FSM2.I(),0.0);
+ std::vector<float> prioro2(blocklength*FSM2.O());
+ std::vector<float> posti2(blocklength*FSM2.I());
+
+ //generate prioro1,2 (metrics are not updated per iteration: this is not the best you can do...)
+ for (int k=0;k<blocklength;k++) {
+ //std::cout << k << std::endl;
+ for(int i=0;i<FSM1.O();i++) {
+ float x=cprioro[k*FSM1.O()*FSM2.O()+i*FSM1.O()+0];
+ for(int j=1;j<FSM2.O();j++)
+ x = (*p2mymin)(x,cprioro[k*FSM1.O()*FSM2.O()+i*FSM1.O()+j]);
+ prioro1[k*FSM1.O()+i]=x;
+ //std::cout << prioro1[k*FSM1.O()+i] << ", ";
+ }
+ //std::cout << std::endl;
+ for(int i=0;i<FSM2.O();i++) {
+ float x=cprioro[k*FSM1.O()*FSM2.O()+0*FSM1.O()+i];
+ for(int j=1;j<FSM1.O();j++)
+ x = (*p2mymin)(x,cprioro[k*FSM1.O()*FSM2.O()+j*FSM1.O()+i]);
+ prioro2[k*FSM2.O()+i]=x;
+ }
+ }
+
+ for(int rep=0;rep<repetitions;rep++) {
+ // run SISO 1
+ siso_algorithm(FSM1.I(),FSM1.S(),FSM1.O(),
+ FSM1.NS(), FSM1.OS(), FSM1.PS(), FSM1.PI(),
+ blocklength,
+ ST10,ST1K,
+ true, false,
+ p2mymin,
+ &(priori1[0]), &(prioro1[0]), &(posti1[0])
+ );
+
+ //for(int k=0;k<blocklength;k++){
+ //for(int i=0;i<FSM1.I();i++)
+ //std::cout << posti1[k*FSM1.I()+i] << ", ";
+ //std::cout << std::endl;
+ //}
+
+ //interleave soft info 1 -> 2
+ for(int k=0;k<blocklength;k++) {
+ int ki = INTERLEAVER.INTER()[k];
+ //for(int i=0;i<FSMi.I();i++) {
+ //oprioro[k*FSMi.I()+i]=iposti[ki*FSMi.I()+i];
+ //}
+ memcpy(&(priori2[k*FSM2.I()]),&(posti1[ki*FSM1.I()]),FSM1.I()*sizeof(float));
+ }
+
+ // run SISO 2
+ siso_algorithm(FSM2.I(),FSM2.S(),FSM2.O(),
+ FSM2.NS(), FSM2.OS(), FSM2.PS(), FSM2.PI(),
+ blocklength,
+ ST20,ST2K,
+ true, false,
+ p2mymin,
+ &(priori2[0]), &(prioro2[0]), &(posti2[0])
+ );
+
+ //interleave soft info 2 --> 1
+ for(int k=0;k<blocklength;k++) {
+ int ki = INTERLEAVER.INTER()[k];
+ //for(int i=0;i<FSMi.I();i++) {
+ //ipriori[ki*FSMi.I()+i]=oposto[k*FSMi.I()+i];
+ //}
+ memcpy(&(priori1[ki*FSM1.I()]),&(posti2[k*FSM2.I()]),FSM1.I()*sizeof(float));
+ }
+
+ } // end repetitions
+
+ // generate hard decisions
+ for(int k=0;k<blocklength;k++) {
+ for(int i=0;i<FSM1.I();i++)
+ posti1[k*FSM1.I()+i] = (*p2mymin)(priori1[k*FSM1.I()+i],posti1[k*FSM1.I()+i]);
+ float min=INF;
+ int mini=0;
+ for(int i=0;i<FSM1.I();i++) {
+ if(posti1[k*FSM1.I()+i]<min) {
+ min=posti1[k*FSM1.I()+i];
+ mini=i;
+ }
+ }
+ data[k]=(T)mini;
+ //std::cout << data[k] << ", "<< std::endl;
+ }
+ //std::cout << std::endl;
+
+
+
+}
+
+//----------------
+
+template
+void pccc_decoder<unsigned char>(
+ const fsm &FSM1, int ST10, int ST1K,
+ const fsm &FSM2, int ST20, int ST2K,
+ const interleaver &INTERLEAVER, int blocklength, int repetitions,
+ float (*p2mymin)(float,float),
+ const float *cprioro, unsigned char *data
+);
+
+template
+void pccc_decoder<short>(
+ const fsm &FSM1, int ST10, int ST1K,
+ const fsm &FSM2, int ST20, int ST2K,
+ const interleaver &INTERLEAVER, int blocklength, int repetitions,
+ float (*p2mymin)(float,float),
+ const float *cprioro, short *data
+);
+
+template
+void pccc_decoder<int>(
+ const fsm &FSM1, int ST10, int ST1K,
+ const fsm &FSM2, int ST20, int ST2K,
+ const interleaver &INTERLEAVER, int blocklength, int repetitions,
+ float (*p2mymin)(float,float),
+ const float *cprioro, int *data
+);
+
diff --git a/gr-trellis/src/lib/core_algorithms.h b/gr-trellis/src/lib/core_algorithms.h
new file mode 100644
index 000000000..fdb5f398e
--- /dev/null
+++ b/gr-trellis/src/lib/core_algorithms.h
@@ -0,0 +1,128 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_CORE_ALGORITHMS_H
+#define INCLUDED_CORE_ALGORITHMS_H
+
+#include <cmath>
+#include <vector>
+//#include <gr_complex.h>
+#include "metric_type.h"
+#include "fsm.h"
+#include "interleaver.h"
+
+
+float min(float a, float b);
+float min_star(float a, float b);
+
+template <class T>
+void viterbi_algorithm(int I, int S, int O,
+ const std::vector<int> &NS,
+ const std::vector<int> &OS,
+ const std::vector< std::vector<int> > &PS,
+ const std::vector< std::vector<int> > &PI,
+ int K,
+ int S0,int SK,
+ const float *in, T *out
+);
+
+template <class Ti, class To>
+void viterbi_algorithm_combined(int I, int S, int O,
+ const std::vector<int> &NS,
+ const std::vector<int> &OS,
+ const std::vector< std::vector<int> > &PS,
+ const std::vector< std::vector<int> > &PI,
+ int K,
+ int S0,int SK,
+ int D,
+ const std::vector<Ti> &TABLE,
+ trellis_metric_type_t TYPE,
+ const Ti *in, To *out
+);
+
+
+
+void siso_algorithm(int I, int S, int O,
+ const std::vector<int> &NS,
+ const std::vector<int> &OS,
+ const std::vector< std::vector<int> > &PS,
+ const std::vector< std::vector<int> > &PI,
+ int K,
+ int S0,int SK,
+ bool POSTI, bool POSTO,
+ float (*p2mymin)(float,float),
+ const float *priori, const float *prioro, float *post
+);
+
+
+template <class T>
+void siso_algorithm_combined(int I, int S, int O,
+ const std::vector<int> &NS,
+ const std::vector<int> &OS,
+ const std::vector< std::vector<int> > &PS,
+ const std::vector< std::vector<int> > &PI,
+ int K,
+ int S0,int SK,
+ bool POSTI, bool POSTO,
+ float (*p2mymin)(float,float),
+ int D,
+ const std::vector<T> &TABLE,
+ trellis_metric_type_t TYPE,
+ const float *priori, const T *observations, float *post
+);
+
+
+template<class Ti, class To>
+void sccc_decoder_combined(
+ const fsm &FSMo, int STo0, int SToK,
+ const fsm &FSMi, int STi0, int STiK,
+ const interleaver &INTERLEAVER, int blocklength, int repetitions,
+ float (*p2mymin)(float,float),
+ int D, const std::vector<Ti> &TABLE,
+ trellis_metric_type_t METRIC_TYPE,
+ float scaling,
+ const Ti *observations, To *data
+);
+
+
+template<class T>
+void sccc_decoder(
+ const fsm &FSMo, int STo0, int SToK,
+ const fsm &FSMi, int STi0, int STiK,
+ const interleaver &INTERLEAVER, int blocklength, int repetitions,
+ float (*p2mymin)(float,float),
+ const float *iprioro, T *data
+);
+
+
+template<class T>
+void pccc_decoder(
+ const fsm &FSM1, int ST10, int ST1K,
+ const fsm &FSM2, int ST20, int ST2K,
+ const interleaver &INTERLEAVER, int blocklength, int repetitions,
+ float (*p2mymin)(float,float),
+ const float *cprioro, T *data
+);
+
+
+
+#endif
diff --git a/gr-trellis/src/lib/generate_trellis.py b/gr-trellis/src/lib/generate_trellis.py
index a4206d268..9f845f74a 100644
--- a/gr-trellis/src/lib/generate_trellis.py
+++ b/gr-trellis/src/lib/generate_trellis.py
@@ -28,16 +28,26 @@ import re
other_roots = [
'trellis_encoder_XX',
+ 'trellis_sccc_encoder_XX',
+ 'trellis_pccc_encoder_XX',
'trellis_metrics_X',
'trellis_viterbi_X',
'trellis_viterbi_combined_XX',
+ 'trellis_sccc_decoder_combined_XX',
+ 'trellis_sccc_decoder_X',
+ 'trellis_pccc_decoder_X',
]
other_signatures = (
['bb','bs','bi','ss','si','ii'],
+ ['bb','bs','bi','ss','si','ii'],
+ ['bb','bs','bi','ss','si','ii'],
['s','i','f','c'],
['b','s','i'],
['sb','ss','si','ib','is','ii','fb','fs','fi','cb','cs','ci'],
+ ['fb','fs','fi','cb','cs','ci'],
+ ['b','s','i'],
+ ['b','s','i'],
)
diff --git a/gr-trellis/src/lib/interleaver.cc b/gr-trellis/src/lib/interleaver.cc
index ff15eeadc..131dcb07b 100644
--- a/gr-trellis/src/lib/interleaver.cc
+++ b/gr-trellis/src/lib/interleaver.cc
@@ -124,7 +124,7 @@ interleaver::interleaver(int K, int seed)
//######################################################################
-//# Write an INTERLEAVER specification from a file.
+//# Write an INTERLEAVER specification to a file.
//# Format
//# K
//# blank line
diff --git a/gr-trellis/src/lib/trellis_metric_type.h b/gr-trellis/src/lib/metric_type.h
index a1040f108..a1040f108 100644
--- a/gr-trellis/src/lib/trellis_metric_type.h
+++ b/gr-trellis/src/lib/metric_type.h
diff --git a/gr-trellis/src/lib/trellis_siso_type.h b/gr-trellis/src/lib/siso_type.h
index 3a7163d02..3a7163d02 100644
--- a/gr-trellis/src/lib/trellis_siso_type.h
+++ b/gr-trellis/src/lib/siso_type.h
diff --git a/gr-trellis/src/lib/trellis.i b/gr-trellis/src/lib/trellis.i
index d035cea54..8d1118436 100644
--- a/gr-trellis/src/lib/trellis.i
+++ b/gr-trellis/src/lib/trellis.i
@@ -38,8 +38,8 @@
%include "trellis_siso_f.i"
%include "trellis_siso_combined_f.i"
-%include "trellis_metric_type.h"
-%include "trellis_siso_type.h"
+%include "metric_type.h"
+%include "siso_type.h"
%include "trellis_generated.i"
diff --git a/gr-trellis/src/lib/trellis_metrics_X.cc.t b/gr-trellis/src/lib/trellis_metrics_X.cc.t
index 4bdaabc22..cd66df6fb 100644
--- a/gr-trellis/src/lib/trellis_metrics_X.cc.t
+++ b/gr-trellis/src/lib/trellis_metrics_X.cc.t
@@ -22,7 +22,7 @@
// @WARNING@
-#ifndef HAVE_CONFIG_H
+#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
diff --git a/gr-trellis/src/lib/trellis_metrics_X.h.t b/gr-trellis/src/lib/trellis_metrics_X.h.t
index f862a032d..45d4ace10 100644
--- a/gr-trellis/src/lib/trellis_metrics_X.h.t
+++ b/gr-trellis/src/lib/trellis_metrics_X.h.t
@@ -26,7 +26,7 @@
#define @GUARD_NAME@
#include <gr_block.h>
-#include "trellis_calc_metric.h"
+#include "calc_metric.h"
class @NAME@;
typedef boost::shared_ptr<@NAME@> @SPTR_NAME@;
diff --git a/gr-trellis/src/lib/trellis_pccc_decoder_X.cc.t b/gr-trellis/src/lib/trellis_pccc_decoder_X.cc.t
new file mode 100644
index 000000000..34dd2eb87
--- /dev/null
+++ b/gr-trellis/src/lib/trellis_pccc_decoder_X.cc.t
@@ -0,0 +1,124 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+// @WARNING@
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <@NAME@.h>
+#include <gr_io_signature.h>
+#include <assert.h>
+#include <iostream>
+#include "core_algorithms.h"
+
+
+static const float INF = 1.0e9;
+
+@SPTR_NAME@
+trellis_make_@BASE_NAME@ (
+ const fsm &FSM1, int ST10, int ST1K,
+ const fsm &FSM2, int ST20, int ST2K,
+ const interleaver &INTERLEAVER,
+ int blocklength,
+ int repetitions,
+ trellis_siso_type_t SISO_TYPE
+)
+{
+ return gnuradio::get_initial_sptr (new @NAME@ (
+ FSM1, ST10, ST1K,
+ FSM2, ST20, ST2K,
+ INTERLEAVER,
+ blocklength,
+ repetitions,
+ SISO_TYPE
+ ));
+}
+
+@NAME@::@NAME@ (
+ const fsm &FSM1, int ST10, int ST1K,
+ const fsm &FSM2, int ST20, int ST2K,
+ const interleaver &INTERLEAVER,
+ int blocklength,
+ int repetitions,
+ trellis_siso_type_t SISO_TYPE
+)
+ : gr_block ("@BASE_NAME@",
+ gr_make_io_signature (1, 1, sizeof (float)),
+ gr_make_io_signature (1, 1, sizeof (@O_TYPE@))),
+ d_FSM1 (FSM1), d_ST10 (ST10), d_ST1K (ST1K),
+ d_FSM2 (FSM2), d_ST20 (ST20), d_ST2K (ST2K),
+ d_INTERLEAVER (INTERLEAVER),
+ d_blocklength (blocklength),
+ d_repetitions (repetitions),
+ d_SISO_TYPE (SISO_TYPE)
+{
+ assert(d_FSM1.I() == d_FSM2.I());
+ set_relative_rate (1.0 / ((double) d_FSM1.O() * d_FSM2.O()));
+ set_output_multiple (d_blocklength);
+}
+
+
+void
+@NAME@::forecast (int noutput_items, gr_vector_int &ninput_items_required)
+{
+ assert (noutput_items % d_blocklength == 0);
+ int input_required = d_FSM1.O() * d_FSM2.O() * noutput_items ;
+ ninput_items_required[0] = input_required;
+}
+
+
+
+//===========================================================
+
+int
+@NAME@::general_work (int noutput_items,
+ gr_vector_int &ninput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ assert (noutput_items % d_blocklength == 0);
+ int nblocks = noutput_items / d_blocklength;
+
+ float (*p2min)(float, float) = NULL;
+ if(d_SISO_TYPE == TRELLIS_MIN_SUM)
+ p2min = &min;
+ else if(d_SISO_TYPE == TRELLIS_SUM_PRODUCT)
+ p2min = &min_star;
+
+
+ const float *in = (const float *) input_items[0];
+ @O_TYPE@ *out = (@O_TYPE@ *) output_items[0];
+ for (int n=0;n<nblocks;n++) {
+ pccc_decoder(
+ d_FSM1, d_ST10, d_ST1K,
+ d_FSM2, d_ST20, d_ST2K,
+ d_INTERLEAVER, d_blocklength, d_repetitions,
+ p2min,
+ &(in[n*d_blocklength*d_FSM1.O()*d_FSM2.O()]),&(out[n*d_blocklength])
+ );
+ }
+
+ consume_each (d_FSM1.O() * d_FSM2.O() * noutput_items );
+ return noutput_items;
+}
diff --git a/gr-trellis/src/lib/trellis_pccc_decoder_X.h.t b/gr-trellis/src/lib/trellis_pccc_decoder_X.h.t
new file mode 100644
index 000000000..ff4b7a1f8
--- /dev/null
+++ b/gr-trellis/src/lib/trellis_pccc_decoder_X.h.t
@@ -0,0 +1,102 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+// @WARNING@
+
+#ifndef @GUARD_NAME@
+#define @GUARD_NAME@
+
+#include "fsm.h"
+#include "interleaver.h"
+#include <gr_block.h>
+#include <vector>
+#include "siso_type.h"
+
+class @NAME@;
+typedef boost::shared_ptr<@NAME@> @SPTR_NAME@;
+
+@SPTR_NAME@ trellis_make_@BASE_NAME@ (
+ const fsm &FSM1, int ST10, int ST1K,
+ const fsm &FSM2, int ST20, int ST2K,
+ const interleaver &INTERLEAVER,
+ int blocklength,
+ int repetitions,
+ trellis_siso_type_t SISO_TYPE // perform "min-sum" or "sum-product" combining
+);
+
+
+/*!
+ * \ingroup coding_blk
+ */
+class @NAME@ : public gr_block
+{
+ fsm d_FSM1;
+ fsm d_FSM2;
+ int d_ST10;
+ int d_ST1K;
+ int d_ST20;
+ int d_ST2K;
+ interleaver d_INTERLEAVER;
+ int d_blocklength;
+ int d_repetitions;
+ trellis_siso_type_t d_SISO_TYPE;
+ std::vector<float> d_buffer;
+
+ friend @SPTR_NAME@ trellis_make_@BASE_NAME@ (
+ const fsm &FSM1, int ST10, int ST1K,
+ const fsm &FSM2, int ST20, int ST2K,
+ const interleaver &INTERLEAVER,
+ int blocklength,
+ int repetitions,
+ trellis_siso_type_t SISO_TYPE
+ );
+
+ @NAME@ (
+ const fsm &FSM1, int ST10, int ST1K,
+ const fsm &FSM2, int ST20, int ST2K,
+ const interleaver &INTERLEAVER,
+ int blocklength,
+ int repetitions,
+ trellis_siso_type_t SISO_TYPE
+ );
+
+public:
+ fsm FSM1 () const { return d_FSM1; }
+ fsm FSM2 () const { return d_FSM2; }
+ int ST10 () const { return d_ST10; }
+ int ST1K () const { return d_ST1K; }
+ int ST20 () const { return d_ST20; }
+ int ST2K () const { return d_ST2K; }
+ interleaver INTERLEAVER () const { return d_INTERLEAVER; }
+ int blocklength () const { return d_blocklength; }
+ int repetitions () const { return d_repetitions; }
+ trellis_siso_type_t SISO_TYPE () const { return d_SISO_TYPE; }
+
+ void forecast (int noutput_items,
+ gr_vector_int &ninput_items_required);
+ int general_work (int noutput_items,
+ gr_vector_int &ninput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+};
+
+#endif
diff --git a/gr-trellis/src/lib/trellis_pccc_decoder_X.i.t b/gr-trellis/src/lib/trellis_pccc_decoder_X.i.t
new file mode 100644
index 000000000..83d7fe969
--- /dev/null
+++ b/gr-trellis/src/lib/trellis_pccc_decoder_X.i.t
@@ -0,0 +1,60 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+// @WARNING@
+
+GR_SWIG_BLOCK_MAGIC(trellis,@BASE_NAME@);
+
+@SPTR_NAME@ trellis_make_@BASE_NAME@ (
+ const fsm &FSM1, int ST10, int ST1K,
+ const fsm &FSM2, int ST20, int ST2K,
+ const interleaver &INTERLEAVER,
+ int blocklength,
+ int repetitions,
+ trellis_siso_type_t SISO_TYPE
+);
+
+
+class @NAME@ : public gr_block
+{
+private:
+ @NAME@ (
+ const fsm &FSM1, int ST10, int ST1K,
+ const fsm &FSM2, int ST20, int ST2K,
+ const interleaver &INTERLEAVER,
+ int blocklength,
+ int repetitions,
+ trellis_siso_type_t SISO_TYPE
+ );
+
+public:
+ fsm FSM1 () const { return d_FSM1; }
+ fsm FSM2 () const { return d_FSM2; }
+ int ST10 () const { return d_ST10; }
+ int ST1K () const { return d_ST1K; }
+ int ST20 () const { return d_ST20; }
+ int ST2K () const { return d_ST2K; }
+ interleaver INTERLEAVER () const { return d_INTERLEAVER; }
+ int blocklength () const { return d_blocklength; }
+ int repetitions () const { return d_repetitions; }
+ trellis_siso_type_t SISO_TYPE () const { return d_SISO_TYPE; }
+};
diff --git a/gr-trellis/src/lib/trellis_pccc_encoder_XX.cc.t b/gr-trellis/src/lib/trellis_pccc_encoder_XX.cc.t
new file mode 100644
index 000000000..40dcd4105
--- /dev/null
+++ b/gr-trellis/src/lib/trellis_pccc_encoder_XX.cc.t
@@ -0,0 +1,90 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+// @WARNING@
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <@NAME@.h>
+#include <gr_io_signature.h>
+#include <iostream>
+
+@SPTR_NAME@
+trellis_make_@BASE_NAME@ (
+ const fsm &FSM1, int ST1,
+ const fsm &FSM2, int ST2,
+ const interleaver &INTERLEAVER,
+ int blocklength
+)
+{
+ return gnuradio::get_initial_sptr (new @NAME@ (FSM1,ST1,FSM2,ST2,INTERLEAVER,blocklength));
+}
+
+@NAME@::@NAME@ (
+ const fsm &FSM1, int ST1,
+ const fsm &FSM2, int ST2,
+ const interleaver &INTERLEAVER,
+ int blocklength
+)
+ : gr_sync_block ("@BASE_NAME@",
+ gr_make_io_signature (1, 1, sizeof (@I_TYPE@)),
+ gr_make_io_signature (1, 1, sizeof (@O_TYPE@))),
+ d_FSM1 (FSM1),
+ d_ST1 (ST1),
+ d_FSM2 (FSM2),
+ d_ST2 (ST2),
+ d_INTERLEAVER (INTERLEAVER),
+ d_blocklength (blocklength)
+{
+ assert(d_FSM1.I() == d_FSM2.I());
+ set_output_multiple(d_blocklength);
+ d_buffer.resize(d_blocklength);
+}
+
+
+
+int
+@NAME@::work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ assert(noutput_items%d_blocklength ==0);
+ for (int b = 0 ; b<noutput_items/d_blocklength; b++) {
+ const @I_TYPE@ *in = (const @I_TYPE@ *) input_items[0]+b*d_blocklength;
+ @O_TYPE@ *out = (@O_TYPE@ *) output_items[0]+b*d_blocklength;
+
+ int ST1_tmp = d_ST1;
+ int ST2_tmp = d_ST2;
+ for (int i = 0; i < d_blocklength; i++){
+ int k = d_INTERLEAVER.INTER()[i];
+ int o1 = d_FSM1.OS()[ST1_tmp*d_FSM1.I()+in[i]];
+ ST1_tmp = (int) d_FSM1.NS()[ST1_tmp*d_FSM1.I()+in[i]];
+ int o2 = d_FSM2.OS()[ST2_tmp*d_FSM2.I()+in[k]];
+ ST2_tmp = (int) d_FSM2.NS()[ST2_tmp*d_FSM2.I()+in[k]];
+ out[i] = (@O_TYPE@) (o1*d_FSM1.O() + o2);
+ }
+ }
+ return noutput_items;
+}
+
diff --git a/gr-trellis/src/lib/trellis_pccc_encoder_XX.h.t b/gr-trellis/src/lib/trellis_pccc_encoder_XX.h.t
new file mode 100644
index 000000000..68ccf75db
--- /dev/null
+++ b/gr-trellis/src/lib/trellis_pccc_encoder_XX.h.t
@@ -0,0 +1,83 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+// @WARNING@
+
+#ifndef @GUARD_NAME@
+#define @GUARD_NAME@
+
+#include <vector>
+#include "fsm.h"
+#include "interleaver.h"
+#include <gr_sync_block.h>
+
+class @NAME@;
+typedef boost::shared_ptr<@NAME@> @SPTR_NAME@;
+
+@SPTR_NAME@ trellis_make_@BASE_NAME@ (
+ const fsm &FSM1, int ST1,
+ const fsm &FSM2, int ST2,
+ const interleaver &INTERLEAVER,
+ int blocklength
+);
+
+/*!
+ * \brief SCCC encoder.
+ * \ingroup coding_blk
+ */
+class @NAME@ : public gr_sync_block
+{
+private:
+ friend @SPTR_NAME@ trellis_make_@BASE_NAME@ (
+ const fsm &FSM1, int ST1,
+ const fsm &FSM2, int ST2,
+ const interleaver &INTERLEAVER,
+ int blocklength
+ );
+ fsm d_FSM1;
+ int d_ST1;
+ fsm d_FSM2;
+ int d_ST2;
+ interleaver d_INTERLEAVER;
+ int d_blocklength;
+ std::vector<int> d_buffer;
+ @NAME@ (
+ const fsm &FSM1, int ST1,
+ const fsm &FSM2, int ST2,
+ const interleaver &INTERLEAVER,
+ int blocklength
+ );
+
+public:
+ fsm FSM1 () const { return d_FSM1; }
+ int ST1 () const { return d_ST1; }
+ fsm FSM2 () const { return d_FSM2; }
+ int ST2 () const { return d_ST2; }
+ interleaver INTERLEAVER () const { return d_INTERLEAVER; }
+ int blocklength () const { return d_blocklength; }
+
+ int work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+};
+
+#endif
diff --git a/gr-trellis/src/lib/trellis_pccc_encoder_XX.i.t b/gr-trellis/src/lib/trellis_pccc_encoder_XX.i.t
new file mode 100644
index 000000000..c02ee428a
--- /dev/null
+++ b/gr-trellis/src/lib/trellis_pccc_encoder_XX.i.t
@@ -0,0 +1,50 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+// @WARNING@
+
+GR_SWIG_BLOCK_MAGIC(trellis,@BASE_NAME@);
+
+@SPTR_NAME@ trellis_make_@BASE_NAME@ (
+ const fsm &FSM1, int ST1,
+ const fsm &FSM2, int ST2,
+ const interleaver &INTERLEAVER,
+ int blocklength
+);
+
+class @NAME@ : public gr_sync_block
+{
+private:
+ @NAME@ (
+ const fsm &FSM1, int ST1,
+ const fsm &FSM2, int ST2,
+ const interleaver &INTERLEAVER,
+ int blocklength
+ );
+public:
+ fsm FSM1 () const { return d_FSM1; }
+ int ST1 () const { return d_ST1; }
+ fsm FSM2 () const { return d_FSM2; }
+ int ST2 () const { return d_ST2; }
+ interleaver INTERLEAVER () const { return d_INTERLEAVER; }
+ int blocklength () const { return d_blocklength; }
+};
diff --git a/gr-trellis/src/lib/trellis_sccc_decoder_X.cc.t b/gr-trellis/src/lib/trellis_sccc_decoder_X.cc.t
new file mode 100644
index 000000000..4a0f471fa
--- /dev/null
+++ b/gr-trellis/src/lib/trellis_sccc_decoder_X.cc.t
@@ -0,0 +1,124 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+// @WARNING@
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <@NAME@.h>
+#include <gr_io_signature.h>
+#include <assert.h>
+#include <iostream>
+#include "core_algorithms.h"
+
+
+static const float INF = 1.0e9;
+
+@SPTR_NAME@
+trellis_make_@BASE_NAME@ (
+ const fsm &FSMo, int STo0, int SToK,
+ const fsm &FSMi, int STi0, int STiK,
+ const interleaver &INTERLEAVER,
+ int blocklength,
+ int repetitions,
+ trellis_siso_type_t SISO_TYPE
+)
+{
+ return gnuradio::get_initial_sptr (new @NAME@ (
+ FSMo, STo0, SToK,
+ FSMi, STi0, STiK,
+ INTERLEAVER,
+ blocklength,
+ repetitions,
+ SISO_TYPE
+ ));
+}
+
+@NAME@::@NAME@ (
+ const fsm &FSMo, int STo0, int SToK,
+ const fsm &FSMi, int STi0, int STiK,
+ const interleaver &INTERLEAVER,
+ int blocklength,
+ int repetitions,
+ trellis_siso_type_t SISO_TYPE
+)
+ : gr_block ("@BASE_NAME@",
+ gr_make_io_signature (1, 1, sizeof (float)),
+ gr_make_io_signature (1, 1, sizeof (@O_TYPE@))),
+ d_FSMo (FSMo), d_STo0 (STo0), d_SToK (SToK),
+ d_FSMi (FSMi), d_STi0 (STi0), d_STiK (STiK),
+ d_INTERLEAVER (INTERLEAVER),
+ d_blocklength (blocklength),
+ d_repetitions (repetitions),
+ d_SISO_TYPE (SISO_TYPE)
+{
+ assert(d_FSMo.O() == d_FSMi.I());
+ set_relative_rate (1.0 / ((double) d_FSMi.O()));
+ set_output_multiple (d_blocklength);
+}
+
+
+void
+@NAME@::forecast (int noutput_items, gr_vector_int &ninput_items_required)
+{
+ assert (noutput_items % d_blocklength == 0);
+ int input_required = d_FSMi.O() * noutput_items ;
+ ninput_items_required[0] = input_required;
+}
+
+
+
+//===========================================================
+
+int
+@NAME@::general_work (int noutput_items,
+ gr_vector_int &ninput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ assert (noutput_items % d_blocklength == 0);
+ int nblocks = noutput_items / d_blocklength;
+
+ float (*p2min)(float, float) = NULL;
+ if(d_SISO_TYPE == TRELLIS_MIN_SUM)
+ p2min = &min;
+ else if(d_SISO_TYPE == TRELLIS_SUM_PRODUCT)
+ p2min = &min_star;
+
+
+ const float *in = (const float *) input_items[0];
+ @O_TYPE@ *out = (@O_TYPE@ *) output_items[0];
+ for (int n=0;n<nblocks;n++) {
+ sccc_decoder(
+ d_FSMo, d_STo0, d_SToK,
+ d_FSMi, d_STi0, d_STiK,
+ d_INTERLEAVER, d_blocklength, d_repetitions,
+ p2min,
+ &(in[n*d_blocklength*d_FSMi.O()]),&(out[n*d_blocklength])
+ );
+ }
+
+ consume_each (d_FSMi.O() * noutput_items );
+ return noutput_items;
+}
diff --git a/gr-trellis/src/lib/trellis_sccc_decoder_X.h.t b/gr-trellis/src/lib/trellis_sccc_decoder_X.h.t
new file mode 100644
index 000000000..3adb8a5b7
--- /dev/null
+++ b/gr-trellis/src/lib/trellis_sccc_decoder_X.h.t
@@ -0,0 +1,102 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+// @WARNING@
+
+#ifndef @GUARD_NAME@
+#define @GUARD_NAME@
+
+#include "fsm.h"
+#include "interleaver.h"
+#include <gr_block.h>
+#include <vector>
+#include "siso_type.h"
+
+class @NAME@;
+typedef boost::shared_ptr<@NAME@> @SPTR_NAME@;
+
+@SPTR_NAME@ trellis_make_@BASE_NAME@ (
+ const fsm &FSMo, int STo0, int SToK,
+ const fsm &FSMi, int STi0, int STiK,
+ const interleaver &INTERLEAVER,
+ int blocklength,
+ int repetitions,
+ trellis_siso_type_t SISO_TYPE // perform "min-sum" or "sum-product" combining
+);
+
+
+/*!
+ * \ingroup coding_blk
+ */
+class @NAME@ : public gr_block
+{
+ fsm d_FSMo;
+ fsm d_FSMi;
+ int d_STo0;
+ int d_SToK;
+ int d_STi0;
+ int d_STiK;
+ interleaver d_INTERLEAVER;
+ int d_blocklength;
+ int d_repetitions;
+ trellis_siso_type_t d_SISO_TYPE;
+ std::vector<float> d_buffer;
+
+ friend @SPTR_NAME@ trellis_make_@BASE_NAME@ (
+ const fsm &FSMo, int STo0, int SToK,
+ const fsm &FSMi, int STi0, int STiK,
+ const interleaver &INTERLEAVER,
+ int blocklength,
+ int repetitions,
+ trellis_siso_type_t SISO_TYPE
+ );
+
+ @NAME@ (
+ const fsm &FSMo, int STo0, int SToK,
+ const fsm &FSMi, int STi0, int STiK,
+ const interleaver &INTERLEAVER,
+ int blocklength,
+ int repetitions,
+ trellis_siso_type_t SISO_TYPE
+ );
+
+public:
+ fsm FSMo () const { return d_FSMo; }
+ fsm FSMi () const { return d_FSMi; }
+ int STo0 () const { return d_STo0; }
+ int SToK () const { return d_SToK; }
+ int STi0 () const { return d_STi0; }
+ int STiK () const { return d_STiK; }
+ interleaver INTERLEAVER () const { return d_INTERLEAVER; }
+ int blocklength () const { return d_blocklength; }
+ int repetitions () const { return d_repetitions; }
+ trellis_siso_type_t SISO_TYPE () const { return d_SISO_TYPE; }
+
+ void forecast (int noutput_items,
+ gr_vector_int &ninput_items_required);
+ int general_work (int noutput_items,
+ gr_vector_int &ninput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+};
+
+#endif
diff --git a/gr-trellis/src/lib/trellis_sccc_decoder_X.i.t b/gr-trellis/src/lib/trellis_sccc_decoder_X.i.t
new file mode 100644
index 000000000..a4392ee6f
--- /dev/null
+++ b/gr-trellis/src/lib/trellis_sccc_decoder_X.i.t
@@ -0,0 +1,60 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+// @WARNING@
+
+GR_SWIG_BLOCK_MAGIC(trellis,@BASE_NAME@);
+
+@SPTR_NAME@ trellis_make_@BASE_NAME@ (
+ const fsm &FSMo, int STo0, int SToK,
+ const fsm &FSMi, int STi0, int STiK,
+ const interleaver &INTERLEAVER,
+ int blocklength,
+ int repetitions,
+ trellis_siso_type_t SISO_TYPE
+);
+
+
+class @NAME@ : public gr_block
+{
+private:
+ @NAME@ (
+ const fsm &FSMo, int STo0, int SToK,
+ const fsm &FSMi, int STi0, int STiK,
+ const interleaver &INTERLEAVER,
+ int blocklength,
+ int repetitions,
+ trellis_siso_type_t SISO_TYPE
+ );
+
+public:
+ fsm FSMo () const { return d_FSMo; }
+ fsm FSMi () const { return d_FSMi; }
+ int STo0 () const { return d_STo0; }
+ int SToK () const { return d_SToK; }
+ int STi0 () const { return d_STi0; }
+ int STiK () const { return d_STiK; }
+ interleaver INTERLEAVER () const { return d_INTERLEAVER; }
+ int blocklength () const { return d_blocklength; }
+ int repetitions () const { return d_repetitions; }
+ trellis_siso_type_t SISO_TYPE () const { return d_SISO_TYPE; }
+};
diff --git a/gr-trellis/src/lib/trellis_sccc_decoder_combined_XX.cc.t b/gr-trellis/src/lib/trellis_sccc_decoder_combined_XX.cc.t
new file mode 100644
index 000000000..2927e3fe3
--- /dev/null
+++ b/gr-trellis/src/lib/trellis_sccc_decoder_combined_XX.cc.t
@@ -0,0 +1,147 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+// @WARNING@
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <@NAME@.h>
+#include <gr_io_signature.h>
+#include <assert.h>
+#include <iostream>
+#include "core_algorithms.h"
+
+
+static const float INF = 1.0e9;
+
+@SPTR_NAME@
+trellis_make_@BASE_NAME@ (
+ const fsm &FSMo, int STo0, int SToK,
+ const fsm &FSMi, int STi0, int STiK,
+ const interleaver &INTERLEAVER,
+ int blocklength,
+ int repetitions,
+ trellis_siso_type_t SISO_TYPE,
+ int D,
+ const std::vector<@I_TYPE@> &TABLE,
+ trellis_metric_type_t METRIC_TYPE,
+ float scaling
+)
+{
+ return gnuradio::get_initial_sptr (new @NAME@ (
+ FSMo, STo0, SToK,
+ FSMi, STi0, STiK,
+ INTERLEAVER,
+ blocklength,
+ repetitions,
+ SISO_TYPE,
+ D,
+ TABLE,METRIC_TYPE,
+ scaling
+ ));
+}
+
+@NAME@::@NAME@ (
+ const fsm &FSMo, int STo0, int SToK,
+ const fsm &FSMi, int STi0, int STiK,
+ const interleaver &INTERLEAVER,
+ int blocklength,
+ int repetitions,
+ trellis_siso_type_t SISO_TYPE,
+ int D,
+ const std::vector<@I_TYPE@> &TABLE,
+ trellis_metric_type_t METRIC_TYPE,
+ float scaling
+)
+ : gr_block ("@BASE_NAME@",
+ gr_make_io_signature (1, 1, sizeof (@I_TYPE@)),
+ gr_make_io_signature (1, 1, sizeof (@O_TYPE@))),
+ d_FSMo (FSMo), d_STo0 (STo0), d_SToK (SToK),
+ d_FSMi (FSMi), d_STi0 (STi0), d_STiK (STiK),
+ d_INTERLEAVER (INTERLEAVER),
+ d_blocklength (blocklength),
+ d_repetitions (repetitions),
+ d_SISO_TYPE (SISO_TYPE),
+ d_D (D),
+ d_TABLE (TABLE),
+ d_METRIC_TYPE (METRIC_TYPE),
+ d_scaling (scaling)
+{
+ assert(d_FSMo.O() == d_FSMi.I());
+ set_relative_rate (1.0 / ((double) d_D));
+ set_output_multiple (d_blocklength);
+}
+
+void @NAME@::set_scaling(float scaling)
+{
+ d_scaling = scaling;
+}
+
+
+void
+@NAME@::forecast (int noutput_items, gr_vector_int &ninput_items_required)
+{
+ assert (noutput_items % d_blocklength == 0);
+ int input_required = d_D * noutput_items ;
+ ninput_items_required[0] = input_required;
+}
+
+
+
+//===========================================================
+
+int
+@NAME@::general_work (int noutput_items,
+ gr_vector_int &ninput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ assert (noutput_items % d_blocklength == 0);
+ int nblocks = noutput_items / d_blocklength;
+
+ float (*p2min)(float, float) = NULL;
+ if(d_SISO_TYPE == TRELLIS_MIN_SUM)
+ p2min = &min;
+ else if(d_SISO_TYPE == TRELLIS_SUM_PRODUCT)
+ p2min = &min_star;
+
+
+ const @I_TYPE@ *in = (const @I_TYPE@ *) input_items[0];
+ @O_TYPE@ *out = (@O_TYPE@ *) output_items[0];
+ for (int n=0;n<nblocks;n++) {
+ sccc_decoder_combined(
+ d_FSMo, d_STo0, d_SToK,
+ d_FSMi, d_STi0, d_STiK,
+ d_INTERLEAVER, d_blocklength, d_repetitions,
+ p2min,
+ d_D,d_TABLE,
+ d_METRIC_TYPE,
+ d_scaling,
+ &(in[n*d_blocklength*d_D]),&(out[n*d_blocklength])
+ );
+ }
+
+ consume_each (d_D * noutput_items );
+ return noutput_items;
+}
diff --git a/gr-trellis/src/lib/trellis_sccc_decoder_combined_XX.h.t b/gr-trellis/src/lib/trellis_sccc_decoder_combined_XX.h.t
new file mode 100644
index 000000000..146c26516
--- /dev/null
+++ b/gr-trellis/src/lib/trellis_sccc_decoder_combined_XX.h.t
@@ -0,0 +1,124 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+// @WARNING@
+
+#ifndef @GUARD_NAME@
+#define @GUARD_NAME@
+
+#include "fsm.h"
+#include "interleaver.h"
+#include <gr_block.h>
+#include <vector>
+#include "calc_metric.h"
+#include "siso_type.h"
+
+class @NAME@;
+typedef boost::shared_ptr<@NAME@> @SPTR_NAME@;
+
+@SPTR_NAME@ trellis_make_@BASE_NAME@ (
+ const fsm &FSMo, int STo0, int SToK,
+ const fsm &FSMi, int STi0, int STiK,
+ const interleaver &INTERLEAVER,
+ int blocklength,
+ int repetitions,
+ trellis_siso_type_t SISO_TYPE, // perform "min-sum" or "sum-product" combining
+ int D,
+ const std::vector<@I_TYPE@> &TABLE,
+ trellis_metric_type_t METRIC_TYPE,
+ float scaling
+);
+
+
+/*!
+ * \ingroup coding_blk
+ */
+class @NAME@ : public gr_block
+{
+ fsm d_FSMo;
+ fsm d_FSMi;
+ int d_STo0;
+ int d_SToK;
+ int d_STi0;
+ int d_STiK;
+ interleaver d_INTERLEAVER;
+ int d_blocklength;
+ int d_repetitions;
+ trellis_siso_type_t d_SISO_TYPE;
+ int d_D;
+ std::vector<@I_TYPE@> d_TABLE;
+ trellis_metric_type_t d_METRIC_TYPE;
+ float d_scaling;
+ std::vector<float> d_buffer;
+
+ friend @SPTR_NAME@ trellis_make_@BASE_NAME@ (
+ const fsm &FSMo, int STo0, int SToK,
+ const fsm &FSMi, int STi0, int STiK,
+ const interleaver &INTERLEAVER,
+ int blocklength,
+ int repetitions,
+ trellis_siso_type_t SISO_TYPE,
+ int D,
+ const std::vector<@I_TYPE@> &TABLE,
+ trellis_metric_type_t METRIC_TYPE,
+ float scaling
+ );
+
+ @NAME@ (
+ const fsm &FSMo, int STo0, int SToK,
+ const fsm &FSMi, int STi0, int STiK,
+ const interleaver &INTERLEAVER,
+ int blocklength,
+ int repetitions,
+ trellis_siso_type_t SISO_TYPE,
+ int D,
+ const std::vector<@I_TYPE@> &TABLE,
+ trellis_metric_type_t METRIC_TYPE,
+ float scaling
+ );
+
+public:
+ fsm FSMo () const { return d_FSMo; }
+ fsm FSMi () const { return d_FSMi; }
+ int STo0 () const { return d_STo0; }
+ int SToK () const { return d_SToK; }
+ int STi0 () const { return d_STi0; }
+ int STiK () const { return d_STiK; }
+ interleaver INTERLEAVER () const { return d_INTERLEAVER; }
+ int blocklength () const { return d_blocklength; }
+ int repetitions () const { return d_repetitions; }
+ int D () const { return d_D; }
+ std::vector<@I_TYPE@> TABLE () const { return d_TABLE; }
+ trellis_metric_type_t METRIC_TYPE () const { return d_METRIC_TYPE; }
+ trellis_siso_type_t SISO_TYPE () const { return d_SISO_TYPE; }
+ float scaling () const { return d_scaling; }
+ void set_scaling (float scaling);
+
+ void forecast (int noutput_items,
+ gr_vector_int &ninput_items_required);
+ int general_work (int noutput_items,
+ gr_vector_int &ninput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+};
+
+#endif
diff --git a/gr-trellis/src/lib/trellis_sccc_decoder_combined_XX.i.t b/gr-trellis/src/lib/trellis_sccc_decoder_combined_XX.i.t
new file mode 100644
index 000000000..84f2eb07d
--- /dev/null
+++ b/gr-trellis/src/lib/trellis_sccc_decoder_combined_XX.i.t
@@ -0,0 +1,73 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+// @WARNING@
+
+GR_SWIG_BLOCK_MAGIC(trellis,@BASE_NAME@);
+
+@SPTR_NAME@ trellis_make_@BASE_NAME@ (
+ const fsm &FSMo, int STo0, int SToK,
+ const fsm &FSMi, int STi0, int STiK,
+ const interleaver &INTERLEAVER,
+ int blocklength,
+ int repetitions,
+ trellis_siso_type_t SISO_TYPE,
+ int D,
+ const std::vector<@I_TYPE@> &TABLE,
+ trellis_metric_type_t METRIC_TYPE,
+ float scaling
+);
+
+
+class @NAME@ : public gr_block
+{
+private:
+ @NAME@ (
+ const fsm &FSMo, int STo0, int SToK,
+ const fsm &FSMi, int STi0, int STiK,
+ const interleaver &INTERLEAVER,
+ int blocklength,
+ int repetitions,
+ trellis_siso_type_t SISO_TYPE,
+ int D,
+ const std::vector<@I_TYPE@> &TABLE,
+ trellis_metric_type_t METRIC_TYPE,
+ float scaling
+ );
+
+public:
+ fsm FSMo () const { return d_FSMo; }
+ fsm FSMi () const { return d_FSMi; }
+ int STo0 () const { return d_STo0; }
+ int SToK () const { return d_SToK; }
+ int STi0 () const { return d_STi0; }
+ int STiK () const { return d_STiK; }
+ interleaver INTERLEAVER () const { return d_INTERLEAVER; }
+ int blocklength () const { return d_blocklength; }
+ int repetitions () const { return d_repetitions; }
+ int D () const { return d_D; }
+ std::vector<@I_TYPE@> TABLE () const { return d_TABLE; }
+ trellis_metric_type_t METRIC_TYPE () const { return d_METRIC_TYPE; }
+ trellis_siso_type_t SISO_TYPE () const { return d_SISO_TYPE; }
+ float scaling() const { return d_scaling; }
+ void set_scaling (float scaling);
+};
diff --git a/gr-trellis/src/lib/trellis_sccc_encoder_XX.cc.t b/gr-trellis/src/lib/trellis_sccc_encoder_XX.cc.t
new file mode 100644
index 000000000..b1a46ca60
--- /dev/null
+++ b/gr-trellis/src/lib/trellis_sccc_encoder_XX.cc.t
@@ -0,0 +1,91 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2010 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+// @WARNING@
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <@NAME@.h>
+#include <gr_io_signature.h>
+#include <iostream>
+
+@SPTR_NAME@
+trellis_make_@BASE_NAME@ (
+ const fsm &FSMo, int STo,
+ const fsm &FSMi, int STi,
+ const interleaver &INTERLEAVER,
+ int blocklength
+)
+{
+ return gnuradio::get_initial_sptr (new @NAME@ (FSMo,STo,FSMi,STi,INTERLEAVER,blocklength));
+}
+
+@NAME@::@NAME@ (
+ const fsm &FSMo, int STo,
+ const fsm &FSMi, int STi,
+ const interleaver &INTERLEAVER,
+ int blocklength
+)
+ : gr_sync_block ("@BASE_NAME@",
+ gr_make_io_signature (1, 1, sizeof (@I_TYPE@)),
+ gr_make_io_signature (1, 1, sizeof (@O_TYPE@))),
+ d_FSMo (FSMo),
+ d_STo (STo),
+ d_FSMi (FSMi),
+ d_STi (STi),
+ d_INTERLEAVER (INTERLEAVER),
+ d_blocklength (blocklength)
+{
+ assert(d_FSMo.O() == d_FSMi.I());
+ set_output_multiple(d_blocklength);
+ d_buffer.resize(d_blocklength);
+}
+
+
+
+int
+@NAME@::work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ assert(noutput_items%d_blocklength ==0);
+ for (int b = 0 ; b<noutput_items/d_blocklength; b++) {
+ const @I_TYPE@ *in = (const @I_TYPE@ *) input_items[0]+b*d_blocklength;
+ @O_TYPE@ *out = (@O_TYPE@ *) output_items[0]+b*d_blocklength;
+
+ int STo_tmp = d_STo;
+ for (int i = 0; i < d_blocklength; i++){
+ d_buffer[i] = d_FSMo.OS()[STo_tmp*d_FSMo.I()+in[i]];
+ STo_tmp = (int) d_FSMo.NS()[STo_tmp*d_FSMo.I()+in[i]];
+ }
+ int STi_tmp = d_STi;
+ for (int i = 0; i < d_blocklength; i++){
+ int k = d_INTERLEAVER.INTER()[i];
+ out[i] = (@O_TYPE@) d_FSMi.OS()[STi_tmp*d_FSMi.I()+d_buffer[k]];
+ STi_tmp = (int) d_FSMi.NS()[STi_tmp*d_FSMi.I()+d_buffer[k]];
+ }
+ }
+ return noutput_items;
+}
+
diff --git a/gr-trellis/src/lib/trellis_sccc_encoder_XX.h.t b/gr-trellis/src/lib/trellis_sccc_encoder_XX.h.t
new file mode 100644
index 000000000..a9e4dc454
--- /dev/null
+++ b/gr-trellis/src/lib/trellis_sccc_encoder_XX.h.t
@@ -0,0 +1,83 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+// @WARNING@
+
+#ifndef @GUARD_NAME@
+#define @GUARD_NAME@
+
+#include <vector>
+#include "fsm.h"
+#include "interleaver.h"
+#include <gr_sync_block.h>
+
+class @NAME@;
+typedef boost::shared_ptr<@NAME@> @SPTR_NAME@;
+
+@SPTR_NAME@ trellis_make_@BASE_NAME@ (
+ const fsm &FSMo, int STo,
+ const fsm &FSMi, int STi,
+ const interleaver &INTERLEAVER,
+ int blocklength
+);
+
+/*!
+ * \brief SCCC encoder.
+ * \ingroup coding_blk
+ */
+class @NAME@ : public gr_sync_block
+{
+private:
+ friend @SPTR_NAME@ trellis_make_@BASE_NAME@ (
+ const fsm &FSMo, int STo,
+ const fsm &FSMi, int STi,
+ const interleaver &INTERLEAVER,
+ int blocklength
+ );
+ fsm d_FSMo;
+ int d_STo;
+ fsm d_FSMi;
+ int d_STi;
+ interleaver d_INTERLEAVER;
+ int d_blocklength;
+ std::vector<int> d_buffer;
+ @NAME@ (
+ const fsm &FSMo, int STo,
+ const fsm &FSMi, int STi,
+ const interleaver &INTERLEAVER,
+ int blocklength
+ );
+
+public:
+ fsm FSMo () const { return d_FSMo; }
+ int STo () const { return d_STo; }
+ fsm FSMi () const { return d_FSMi; }
+ int STi () const { return d_STi; }
+ interleaver INTERLEAVER () const { return d_INTERLEAVER; }
+ int blocklength () const { return d_blocklength; }
+
+ int work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+};
+
+#endif
diff --git a/gr-trellis/src/lib/trellis_sccc_encoder_XX.i.t b/gr-trellis/src/lib/trellis_sccc_encoder_XX.i.t
new file mode 100644
index 000000000..ca6b56199
--- /dev/null
+++ b/gr-trellis/src/lib/trellis_sccc_encoder_XX.i.t
@@ -0,0 +1,50 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+// @WARNING@
+
+GR_SWIG_BLOCK_MAGIC(trellis,@BASE_NAME@);
+
+@SPTR_NAME@ trellis_make_@BASE_NAME@ (
+ const fsm &FSMo, int STo,
+ const fsm &FSMi, int STi,
+ const interleaver &INTERLEAVER,
+ int blocklength
+);
+
+class @NAME@ : public gr_sync_block
+{
+private:
+ @NAME@ (
+ const fsm &FSMo, int STo,
+ const fsm &FSMi, int STi,
+ const interleaver &INTERLEAVER,
+ int blocklength
+ );
+public:
+ fsm FSMo () const { return d_FSMo; }
+ int STo () const { return d_STo; }
+ fsm FSMi () const { return d_FSMi; }
+ int STi () const { return d_STi; }
+ interleaver INTERLEAVER () const { return d_INTERLEAVER; }
+ int blocklength () const { return d_blocklength; }
+};
diff --git a/gr-trellis/src/lib/trellis_siso_combined_f.cc b/gr-trellis/src/lib/trellis_siso_combined_f.cc
index 708608b16..2a4cfa123 100644
--- a/gr-trellis/src/lib/trellis_siso_combined_f.cc
+++ b/gr-trellis/src/lib/trellis_siso_combined_f.cc
@@ -125,6 +125,13 @@ trellis_siso_combined_f::forecast (int noutput_items, gr_vector_int &ninput_item
}
}
+
+
+
+
+/*
+
+
inline float min(float a, float b)
{
return a <= b ? a : b;
@@ -286,7 +293,7 @@ void siso_algorithm_combined(int I, int S, int O,
}
-
+*/
diff --git a/gr-trellis/src/lib/trellis_siso_combined_f.h b/gr-trellis/src/lib/trellis_siso_combined_f.h
index 6432c2262..786e79386 100644
--- a/gr-trellis/src/lib/trellis_siso_combined_f.h
+++ b/gr-trellis/src/lib/trellis_siso_combined_f.h
@@ -24,8 +24,9 @@
#define INCLUDED_TRELLIS_SISO_COMBINED_F_H
#include "fsm.h"
-#include "trellis_siso_type.h"
-#include "trellis_calc_metric.h"
+#include "siso_type.h"
+#include "calc_metric.h"
+#include "core_algorithms.h"
#include <gr_block.h>
class trellis_siso_combined_f;
diff --git a/gr-trellis/src/lib/trellis_siso_f.cc b/gr-trellis/src/lib/trellis_siso_f.cc
index c8fa8231d..d478c13a3 100644
--- a/gr-trellis/src/lib/trellis_siso_f.cc
+++ b/gr-trellis/src/lib/trellis_siso_f.cc
@@ -116,6 +116,11 @@ trellis_siso_f::forecast (int noutput_items, gr_vector_int &ninput_items_require
}
}
+
+
+
+/* Moved it to "core_algorithms.cc" */
+/*
inline float min(float a, float b)
{
return a <= b ? a : b;
@@ -270,7 +275,7 @@ else
}
-
+*/
diff --git a/gr-trellis/src/lib/trellis_siso_f.h b/gr-trellis/src/lib/trellis_siso_f.h
index 3e2c2498b..0e2cba67a 100644
--- a/gr-trellis/src/lib/trellis_siso_f.h
+++ b/gr-trellis/src/lib/trellis_siso_f.h
@@ -24,7 +24,8 @@
#define INCLUDED_TRELLIS_SISO_F_H
#include "fsm.h"
-#include "trellis_siso_type.h"
+#include "siso_type.h"
+#include "core_algorithms.h"
#include <gr_block.h>
class trellis_siso_f;
diff --git a/gr-trellis/src/lib/trellis_viterbi_X.cc.t b/gr-trellis/src/lib/trellis_viterbi_X.cc.t
index 178215362..2254f6450 100644
--- a/gr-trellis/src/lib/trellis_viterbi_X.cc.t
+++ b/gr-trellis/src/lib/trellis_viterbi_X.cc.t
@@ -73,9 +73,22 @@ void
}
}
+/*
+template
+void viterbi_algorithm<@O_TYPE@>(int I, int S, int O,
+ const std::vector<int> &NS,
+ const std::vector<int> &OS,
+ const std::vector< std::vector<int> > &PS,
+ const std::vector< std::vector<int> > &PI,
+ int K,
+ int S0,int SK,
+ const float *in, @O_TYPE@ *out);
+*/
+/* Moved it to "core_algorithms.cc" */
+/*
void viterbi_algorithm(int I, int S, int O,
const std::vector<int> &NS,
const std::vector<int> &OS,
@@ -141,7 +154,7 @@ void viterbi_algorithm(int I, int S, int O,
}
-
+*/
diff --git a/gr-trellis/src/lib/trellis_viterbi_X.h.t b/gr-trellis/src/lib/trellis_viterbi_X.h.t
index 67b46a8ee..362d3f57e 100644
--- a/gr-trellis/src/lib/trellis_viterbi_X.h.t
+++ b/gr-trellis/src/lib/trellis_viterbi_X.h.t
@@ -27,6 +27,7 @@
#include "fsm.h"
#include <gr_block.h>
+#include "core_algorithms.h"
class @NAME@;
typedef boost::shared_ptr<@NAME@> @SPTR_NAME@;
@@ -78,4 +79,12 @@ public:
gr_vector_void_star &output_items);
};
+
+
+
+
+
+
+
+
#endif
diff --git a/gr-trellis/src/lib/trellis_viterbi_combined_XX.cc.t b/gr-trellis/src/lib/trellis_viterbi_combined_XX.cc.t
index d365de75f..e883a0ba7 100644
--- a/gr-trellis/src/lib/trellis_viterbi_combined_XX.cc.t
+++ b/gr-trellis/src/lib/trellis_viterbi_combined_XX.cc.t
@@ -90,6 +90,7 @@ void
+/*
void viterbi_algorithm_combined(int I, int S, int O,
const std::vector<int> &NS,
const std::vector<int> &OS,
@@ -162,7 +163,7 @@ void viterbi_algorithm_combined(int I, int S, int O,
}
-
+*/
diff --git a/gr-trellis/src/lib/trellis_viterbi_combined_XX.h.t b/gr-trellis/src/lib/trellis_viterbi_combined_XX.h.t
index 21307d0e3..35e6c4ce0 100644
--- a/gr-trellis/src/lib/trellis_viterbi_combined_XX.h.t
+++ b/gr-trellis/src/lib/trellis_viterbi_combined_XX.h.t
@@ -27,7 +27,8 @@
#include "fsm.h"
#include <gr_block.h>
-#include "trellis_calc_metric.h"
+#include "calc_metric.h"
+#include "core_algorithms.h"
class @NAME@;
typedef boost::shared_ptr<@NAME@> @SPTR_NAME@;
diff --git a/gr-uhd/Makefile.am b/gr-uhd/Makefile.am
index 2e2d0fbe9..ea16c863c 100644
--- a/gr-uhd/Makefile.am
+++ b/gr-uhd/Makefile.am
@@ -21,9 +21,11 @@
include $(top_srcdir)/Makefile.common
-SUBDIRS = include lib
+SUBDIRS = include lib apps
if PYTHON
SUBDIRS += swig grc
endif
+pkgconfigdir = $(libdir)/pkgconfig
+dist_pkgconfig_DATA = gnuradio-uhd.pc
diff --git a/gr-uhd/apps/.gitignore b/gr-uhd/apps/.gitignore
new file mode 100644
index 000000000..22a4e7292
--- /dev/null
+++ b/gr-uhd/apps/.gitignore
@@ -0,0 +1,3 @@
+Makefile
+Makefile.in
+
diff --git a/gr-uhd/apps/Makefile.am b/gr-uhd/apps/Makefile.am
new file mode 100644
index 000000000..9bb9b6cdd
--- /dev/null
+++ b/gr-uhd/apps/Makefile.am
@@ -0,0 +1,32 @@
+#
+# Copyright 2011 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+include $(top_srcdir)/Makefile.common
+
+EXTRA_DIST += \
+ $(bin_SCRIPTS)
+
+ourpythondir = $(grpythondir)
+
+bin_SCRIPTS = \
+ uhd_fft.py \
+ uhd_rx_cfile.py
+
diff --git a/gr-uhd/apps/uhd_fft.py b/gr-uhd/apps/uhd_fft.py
new file mode 100755
index 000000000..87952ef3a
--- /dev/null
+++ b/gr-uhd/apps/uhd_fft.py
@@ -0,0 +1,267 @@
+#!/usr/bin/env python
+#
+# Copyright 2011 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+from gnuradio import gr, gru
+from gnuradio import uhd
+from gnuradio import eng_notation
+from gnuradio.eng_option import eng_option
+from gnuradio.wxgui import stdgui2, fftsink2, waterfallsink2, scopesink2, form, slider
+from optparse import OptionParser
+import wx
+import sys
+import numpy
+
+class app_top_block(stdgui2.std_top_block):
+ def __init__(self, frame, panel, vbox, argv):
+ stdgui2.std_top_block.__init__(self, frame, panel, vbox, argv)
+
+ self.frame = frame
+ self.panel = panel
+
+ parser = OptionParser(option_class=eng_option)
+ parser.add_option("-a", "--address", type="string", default="addr=192.168.10.2",
+ help="Address of UHD device, [default=%default]")
+ parser.add_option("-A", "--antenna", type="string", default=None,
+ help="select Rx Antenna where appropriate")
+ parser.add_option("-s", "--samp-rate", type="eng_float", default=1e6,
+ help="set sample rate (bandwidth) [default=%default]")
+ parser.add_option("-f", "--freq", type="eng_float", default=None,
+ help="set frequency to FREQ", metavar="FREQ")
+ parser.add_option("-g", "--gain", type="eng_float", default=None,
+ help="set gain in dB (default is midpoint)")
+ parser.add_option("-W", "--waterfall", action="store_true", default=False,
+ help="Enable waterfall display")
+ parser.add_option("-S", "--oscilloscope", action="store_true", default=False,
+ help="Enable oscilloscope display")
+ parser.add_option("", "--avg-alpha", type="eng_float", default=1e-1,
+ help="Set fftsink averaging factor, default=[%default]")
+ parser.add_option("", "--ref-scale", type="eng_float", default=1.0,
+ help="Set dBFS=0dB input value, default=[%default]")
+ parser.add_option("--fft-size", type="int", default=1024,
+ help="Set number of FFT bins [default=%default]")
+ (options, args) = parser.parse_args()
+ if len(args) != 0:
+ parser.print_help()
+ sys.exit(1)
+ self.options = options
+ self.show_debug_info = True
+
+ self.u = uhd.usrp_source(device_addr=options.address,
+ io_type=uhd.io_type.COMPLEX_FLOAT32,
+ num_channels=1)
+
+ self.u.set_samp_rate(options.samp_rate)
+ input_rate = self.u.get_samp_rate()
+
+ if options.waterfall:
+ self.scope = \
+ waterfallsink2.waterfall_sink_c (panel, fft_size=1024, sample_rate=input_rate)
+ self.frame.SetMinSize((800, 420))
+ elif options.oscilloscope:
+ self.scope = scopesink2.scope_sink_c(panel, sample_rate=input_rate)
+ self.frame.SetMinSize((800, 600))
+ else:
+ self.scope = fftsink2.fft_sink_c (panel,
+ fft_size=options.fft_size,
+ sample_rate=input_rate,
+ ref_scale=options.ref_scale,
+ ref_level=20.0,
+ y_divs = 12,
+ avg_alpha=options.avg_alpha)
+ self.frame.SetMinSize((800, 420))
+
+ self.connect(self.u, self.scope)
+
+ self._build_gui(vbox)
+ self._setup_events()
+
+
+ # set initial values
+
+ if options.gain is None:
+ # if no gain was specified, use the mid-point in dB
+ g = self.u.get_gain_range()
+ options.gain = float(g.start()+g.stop())/2
+
+ if options.freq is None:
+ # if no freq was specified, use the mid-point
+ r = self.u.get_freq_range()
+ options.freq = float(r.start()+r.stop())/2
+
+ self.set_gain(options.gain)
+
+ if(options.antenna):
+ self.u.set_antenna(options.antenna, 0)
+
+ if self.show_debug_info:
+ self.myform['samprate'].set_value(self.u.get_samp_rate())
+ self.myform['fs@gbe'].set_value(input_rate)
+ self.myform['baseband'].set_value(0)
+ self.myform['ddc'].set_value(0)
+
+ if not(self.set_freq(options.freq)):
+ self._set_status_msg("Failed to set initial frequency")
+
+ def _set_status_msg(self, msg):
+ self.frame.GetStatusBar().SetStatusText(msg, 0)
+
+ def _build_gui(self, vbox):
+
+ def _form_set_freq(kv):
+ return self.set_freq(kv['freq'])
+
+ vbox.Add(self.scope.win, 10, wx.EXPAND)
+
+ # add control area at the bottom
+ self.myform = myform = form.form()
+ hbox = wx.BoxSizer(wx.HORIZONTAL)
+ hbox.Add((5,0), 0, 0)
+ myform['freq'] = form.float_field(
+ parent=self.panel, sizer=hbox, label="Center freq", weight=1,
+ callback=myform.check_input_and_call(_form_set_freq, self._set_status_msg))
+
+ hbox.Add((5,0), 0, 0)
+ g = self.u.get_gain_range()
+
+ # some configurations don't have gain control
+ if g.stop() > g.start():
+ myform['gain'] = form.slider_field(parent=self.panel, sizer=hbox, label="Gain",
+ weight=3,
+ min=int(g.start()), max=int(g.stop()),
+ callback=self.set_gain)
+
+ hbox.Add((5,0), 0, 0)
+ vbox.Add(hbox, 0, wx.EXPAND)
+
+ self._build_subpanel(vbox)
+
+ def _build_subpanel(self, vbox_arg):
+ # build a secondary information panel (sometimes hidden)
+
+ # FIXME figure out how to have this be a subpanel that is always
+ # created, but has its visibility controlled by foo.Show(True/False)
+
+ def _form_set_samp_rate(kv):
+ return self.set_samp_rate(kv['samprate'])
+
+ if not(self.show_debug_info):
+ return
+
+ panel = self.panel
+ vbox = vbox_arg
+ myform = self.myform
+
+ hbox = wx.BoxSizer(wx.HORIZONTAL)
+
+ hbox.Add((5,0), 0)
+ myform['samprate'] = form.float_field(
+ parent=panel, sizer=hbox, label="Sample Rate",
+ callback=myform.check_input_and_call(_form_set_samp_rate, self._set_status_msg))
+
+ hbox.Add((5,0), 1)
+ myform['fs@gbe'] = form.static_float_field(
+ parent=panel, sizer=hbox, label="Fs@GbE")
+
+ hbox.Add((5,0), 1)
+ myform['baseband'] = form.static_float_field(
+ parent=panel, sizer=hbox, label="Analog BB")
+
+ hbox.Add((5,0), 1)
+ myform['ddc'] = form.static_float_field(
+ parent=panel, sizer=hbox, label="DDC")
+
+ hbox.Add((5,0), 0)
+ vbox.Add(hbox, 0, wx.EXPAND)
+
+ def set_freq(self, target_freq):
+ """
+ Set the center frequency we're interested in.
+
+ @param target_freq: frequency in Hz
+ @rypte: bool
+
+ Tuning is a two step process. First we ask the front-end to
+ tune as close to the desired frequency as it can. Then we use
+ the result of that operation and our target_frequency to
+ determine the value for the digital down converter.
+ """
+ r = self.u.set_center_freq(target_freq, 0)
+
+ if r:
+ self.myform['freq'].set_value(target_freq) # update displayed value
+ if self.show_debug_info:
+ self.myform['baseband'].set_value(r.actual_rf_freq)
+ self.myform['ddc'].set_value(r.actual_dsp_freq)
+ if not self.options.oscilloscope:
+ self.scope.set_baseband_freq(target_freq)
+ return True
+
+ return False
+
+ def set_gain(self, gain):
+ if self.myform.has_key('gain'):
+ self.myform['gain'].set_value(gain) # update displayed value
+ self.u.set_gain(gain, 0)
+
+ def set_samp_rate(self, samp_rate):
+ ok = self.u.set_samp_rate(samp_rate)
+ input_rate = self.u.get_samp_rate()
+ self.scope.set_sample_rate(input_rate)
+ if self.show_debug_info: # update displayed values
+ self.myform['samprate'].set_value(self.u.get_samp_rate())
+ self.myform['fs@gbe'].set_value(input_rate)
+
+ # uhd set_samp_rate never fails; always falls back to closest requested.
+ return True
+
+ def _setup_events(self):
+ if not self.options.waterfall and not self.options.oscilloscope:
+ self.scope.win.Bind(wx.EVT_LEFT_DCLICK, self.evt_left_dclick)
+
+ def evt_left_dclick(self, event):
+ (ux, uy) = self.scope.win.GetXY(event)
+ if event.CmdDown():
+ # Re-center on maximum power
+ points = self.scope.win._points
+ if self.scope.win.peak_hold:
+ if self.scope.win.peak_vals is not None:
+ ind = numpy.argmax(self.scope.win.peak_vals)
+ else:
+ ind = int(points.shape()[0]/2)
+ else:
+ ind = numpy.argmax(points[:,1])
+ (freq, pwr) = points[ind]
+ target_freq = freq/self.scope.win._scale_factor
+ print ind, freq, pwr
+ self.set_freq(target_freq)
+ else:
+ # Re-center on clicked frequency
+ target_freq = ux/self.scope.win._scale_factor
+ self.set_freq(target_freq)
+
+
+def main ():
+ app = stdgui2.stdapp(app_top_block, "UHD FFT", nstatus=1)
+ app.MainLoop()
+
+if __name__ == '__main__':
+ main ()
diff --git a/gr-uhd/apps/uhd_rx_cfile.py b/gr-uhd/apps/uhd_rx_cfile.py
new file mode 100755
index 000000000..f49052d9c
--- /dev/null
+++ b/gr-uhd/apps/uhd_rx_cfile.py
@@ -0,0 +1,149 @@
+#!/usr/bin/env python
+#
+# Copyright 2011 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+"""
+Read samples from a UHD device and write to file formatted as binary
+outputs single precision complex float values or complex short values
+(interleaved 16 bit signed short integers).
+"""
+
+from gnuradio import gr, eng_notation
+from gnuradio import uhd
+from gnuradio.eng_option import eng_option
+from optparse import OptionParser
+import sys
+
+n2s = eng_notation.num_to_str
+
+class rx_cfile_block(gr.top_block):
+
+ def __init__(self, options, filename):
+ gr.top_block.__init__(self)
+
+ # Create a UHD device source
+ if options.output_shorts:
+ self._u = uhd.usrp_source(device_addr=options.address,
+ io_type=uhd.io_type.COMPLEX_INT16,
+ num_channels=1)
+ self._sink = gr.file_sink(gr.sizeof_short*2, filename)
+ else:
+ self._u = uhd.usrp_source(device_addr=options.address,
+ io_type=uhd.io_type.COMPLEX_FLOAT32,
+ num_channels=1)
+ self._sink = gr.file_sink(gr.sizeof_gr_complex, filename)
+
+ # Set receiver sample rate
+ self._u.set_samp_rate(options.samp_rate)
+
+ # Set receive daughterboard gain
+ if options.gain is None:
+ g = self._u.get_gain_range()
+ options.gain = float(g.start()+g.stop())/2
+ print "Using mid-point gain of", options.gain, "(", g.start(), "-", g.stop(), ")"
+ self._u.set_gain(options.gain)
+
+ # Set the antenna
+ if(options.antenna):
+ self._u.set_antenna(options.antenna, 0)
+
+ # Set frequency (tune request takes lo_offset)
+ if(options.lo_offset is not None):
+ treq = uhd.tune_request(options.freq, options.lo_offset)
+ else:
+ treq = uhd.tune_request(options.freq)
+ tr = self._u.set_center_freq(treq)
+ if tr == None:
+ sys.stderr.write('Failed to set center frequency\n')
+ raise SystemExit, 1
+
+ # Create head block if needed and wire it up
+ if options.nsamples is None:
+ self.connect(self._u, self._sink)
+ else:
+ if options.output_shorts:
+ self._head = gr.head(gr.sizeof_short*2, int(options.nsamples))
+ else:
+ self._head = gr.head(gr.sizeof_gr_complex, int(options.nsamples))
+
+ self.connect(self._u, self._head, self._sink)
+
+ input_rate = self._u.get_samp_rate()
+
+ if options.verbose:
+ print "Address:", options.address
+ print "Rx gain:", options.gain
+ print "Rx baseband frequency:", n2s(tr.actual_rf_freq)
+ print "Rx DDC frequency:", n2s(tr.actual_dsp_freq)
+ print "Rx Sample Rate:", n2s(input_rate)
+ if options.nsamples is None:
+ print "Receiving samples until Ctrl-C"
+ else:
+ print "Receving", n2s(options.nsamples), "samples"
+ if options.output_shorts:
+ print "Writing 16-bit complex shorts"
+ else:
+ print "Writing 32-bit complex floats"
+ print "Output filename:", filename
+
+def get_options():
+ usage="%prog: [options] output_filename"
+ parser = OptionParser(option_class=eng_option, usage=usage)
+ parser.add_option("-a", "--address", type="string", default="addr=192.168.10.2",
+ help="Address of UHD device, [default=%default]")
+ parser.add_option("-A", "--antenna", type="string", default=None,
+ help="select Rx Antenna where appropriate")
+ parser.add_option("", "--samp-rate", type="eng_float", default=1e6,
+ help="set sample rate (bandwidth) [default=%default]")
+ parser.add_option("-f", "--freq", type="eng_float", default=None,
+ help="set frequency to FREQ", metavar="FREQ")
+ parser.add_option("-g", "--gain", type="eng_float", default=None,
+ help="set gain in dB (default is midpoint)")
+ parser.add_option( "-s","--output-shorts", action="store_true", default=False,
+ help="output interleaved shorts instead of complex floats")
+ parser.add_option("-N", "--nsamples", type="eng_float", default=None,
+ help="number of samples to collect [default=+inf]")
+ parser.add_option("-v", "--verbose", action="store_true", default=False,
+ help="verbose output")
+ parser.add_option("", "--lo-offset", type="eng_float", default=None,
+ help="set daughterboard LO offset to OFFSET [default=hw default]")
+
+ (options, args) = parser.parse_args ()
+ if len(args) != 1:
+ parser.print_help()
+ raise SystemExit, 1
+
+ if options.freq is None:
+ parser.print_help()
+ sys.stderr.write('You must specify the frequency with -f FREQ\n');
+ raise SystemExit, 1
+
+ return (options, args[0])
+
+
+if __name__ == '__main__':
+ (options, filename) = get_options()
+ tb = rx_cfile_block(options, filename)
+
+ try:
+ tb.run()
+ except KeyboardInterrupt:
+ pass
diff --git a/gr-uhd/gnuradio-uhd.pc.in b/gr-uhd/gnuradio-uhd.pc.in
new file mode 100644
index 000000000..383ad6011
--- /dev/null
+++ b/gr-uhd/gnuradio-uhd.pc.in
@@ -0,0 +1,11 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+
+Name: gnuradio-qtgui
+Description: GNU Radio blocks for UHD
+Requires: gnuradio-core
+Version: @LIBVER@
+Libs: -L${libdir} -lgnuradio-uhd
+Cflags: -I${includedir}
diff --git a/gr-uhd/grc/gen_uhd_usrp_blocks.py b/gr-uhd/grc/gen_uhd_usrp_blocks.py
index 8596e14a6..82b6aa964 100644
--- a/gr-uhd/grc/gen_uhd_usrp_blocks.py
+++ b/gr-uhd/grc/gen_uhd_usrp_blocks.py
@@ -298,7 +298,7 @@ def parse_tmpl(_tmpl, **kwargs):
from Cheetah import Template
return str(Template.Template(_tmpl, kwargs))
-max_num_mboards = 4
+max_num_mboards = 8
max_num_channels = max_num_mboards*4
if __name__ == '__main__':
diff --git a/gr-uhd/include/gr_uhd_usrp_sink.h b/gr-uhd/include/gr_uhd_usrp_sink.h
index 0475957de..320d07d41 100644
--- a/gr-uhd/include/gr_uhd_usrp_sink.h
+++ b/gr-uhd/include/gr_uhd_usrp_sink.h
@@ -101,6 +101,14 @@ public:
virtual void set_gain(double gain, size_t chan = 0) = 0;
/*!
+ * Set the named gain on the dboard.
+ * \param gain the gain in dB
+ * \param name the name of the gain stage
+ * \param chan the channel index 0 to N-1
+ */
+ virtual void set_gain(double gain, const std::string &name, size_t chan = 0) = 0;
+
+ /*!
* Get the actual dboard gain setting.
* \param chan the channel index 0 to N-1
* \return the actual gain in dB
@@ -108,6 +116,22 @@ public:
virtual double get_gain(size_t chan = 0) = 0;
/*!
+ * Get the actual dboard gain setting of named stage.
+ * \param name the name of the gain stage
+ * \param chan the channel index 0 to N-1
+ * \return the actual gain in dB
+ */
+ virtual double get_gain(const std::string &name, size_t chan = 0) = 0;
+
+ /*!
+ * Get the actual dboard gain setting of named stage.
+ * \param name the name of the gain stage
+ * \param chan the channel index 0 to N-1
+ * \return the actual gain in dB
+ */
+ virtual std::vector<std::string> get_gain_names(size_t chan = 0) = 0;
+
+ /*!
* Get the settable gain range.
* \param chan the channel index 0 to N-1
* \return the gain range in dB
@@ -115,6 +139,14 @@ public:
virtual uhd::gain_range_t get_gain_range(size_t chan = 0) = 0;
/*!
+ * Get the settable gain range.
+ * \param name the name of the gain stage
+ * \param chan the channel index 0 to N-1
+ * \return the gain range in dB
+ */
+ virtual uhd::gain_range_t get_gain_range(const std::string &name, size_t chan = 0) = 0;
+
+ /*!
* Set the antenna to use.
* \param ant the antenna string
* \param chan the channel index 0 to N-1
diff --git a/gr-uhd/include/gr_uhd_usrp_source.h b/gr-uhd/include/gr_uhd_usrp_source.h
index 038f9a91e..36331f782 100644
--- a/gr-uhd/include/gr_uhd_usrp_source.h
+++ b/gr-uhd/include/gr_uhd_usrp_source.h
@@ -101,6 +101,14 @@ public:
virtual void set_gain(double gain, size_t chan = 0) = 0;
/*!
+ * Set the named gain on the dboard.
+ * \param gain the gain in dB
+ * \param name the name of the gain stage
+ * \param chan the channel index 0 to N-1
+ */
+ virtual void set_gain(double gain, const std::string &name, size_t chan = 0) = 0;
+
+ /*!
* Get the actual dboard gain setting.
* \param chan the channel index 0 to N-1
* \return the actual gain in dB
@@ -108,6 +116,22 @@ public:
virtual double get_gain(size_t chan = 0) = 0;
/*!
+ * Get the actual dboard gain setting of named stage.
+ * \param name the name of the gain stage
+ * \param chan the channel index 0 to N-1
+ * \return the actual gain in dB
+ */
+ virtual double get_gain(const std::string &name, size_t chan = 0) = 0;
+
+ /*!
+ * Get the actual dboard gain setting of named stage.
+ * \param name the name of the gain stage
+ * \param chan the channel index 0 to N-1
+ * \return the actual gain in dB
+ */
+ virtual std::vector<std::string> get_gain_names(size_t chan = 0) = 0;
+
+ /*!
* Get the settable gain range.
* \param chan the channel index 0 to N-1
* \return the gain range in dB
@@ -115,6 +139,14 @@ public:
virtual uhd::gain_range_t get_gain_range(size_t chan = 0) = 0;
/*!
+ * Get the settable gain range.
+ * \param name the name of the gain stage
+ * \param chan the channel index 0 to N-1
+ * \return the gain range in dB
+ */
+ virtual uhd::gain_range_t get_gain_range(const std::string &name, size_t chan = 0) = 0;
+
+ /*!
* Set the antenna to use.
* \param ant the antenna string
* \param chan the channel index 0 to N-1
diff --git a/gr-uhd/lib/gr_uhd_usrp_sink.cc b/gr-uhd/lib/gr_uhd_usrp_sink.cc
index d44af25ab..ce9d89d8d 100644
--- a/gr-uhd/lib/gr_uhd_usrp_sink.cc
+++ b/gr-uhd/lib/gr_uhd_usrp_sink.cc
@@ -76,14 +76,30 @@ public:
return _dev->set_tx_gain(gain, chan);
}
+ void set_gain(double gain, const std::string &name, size_t chan){
+ return _dev->set_tx_gain(gain, name, chan);
+ }
+
double get_gain(size_t chan){
return _dev->get_tx_gain(chan);
}
+ double get_gain(const std::string &name, size_t chan){
+ return _dev->get_tx_gain(name, chan);
+ }
+
+ std::vector<std::string> get_gain_names(size_t chan){
+ return _dev->get_tx_gain_names(chan);
+ }
+
uhd::gain_range_t get_gain_range(size_t chan){
return _dev->get_tx_gain_range(chan);
}
+ uhd::gain_range_t get_gain_range(const std::string &name, size_t chan){
+ return _dev->get_tx_gain_range(name, chan);
+ }
+
void set_antenna(const std::string &ant, size_t chan){
return _dev->set_tx_antenna(ant, chan);
}
diff --git a/gr-uhd/lib/gr_uhd_usrp_source.cc b/gr-uhd/lib/gr_uhd_usrp_source.cc
index fed8e6624..9983489c3 100644
--- a/gr-uhd/lib/gr_uhd_usrp_source.cc
+++ b/gr-uhd/lib/gr_uhd_usrp_source.cc
@@ -78,14 +78,30 @@ public:
return _dev->set_rx_gain(gain, chan);
}
+ void set_gain(double gain, const std::string &name, size_t chan){
+ return _dev->set_rx_gain(gain, name, chan);
+ }
+
double get_gain(size_t chan){
return _dev->get_rx_gain(chan);
}
+ double get_gain(const std::string &name, size_t chan){
+ return _dev->get_rx_gain(name, chan);
+ }
+
+ std::vector<std::string> get_gain_names(size_t chan){
+ return _dev->get_rx_gain_names(chan);
+ }
+
uhd::gain_range_t get_gain_range(size_t chan){
return _dev->get_rx_gain_range(chan);
}
+ uhd::gain_range_t get_gain_range(const std::string &name, size_t chan){
+ return _dev->get_rx_gain_range(name, chan);
+ }
+
void set_antenna(const std::string &ant, size_t chan){
return _dev->set_rx_antenna(ant, chan);
}
diff --git a/gr-uhd/swig/uhd_swig.i b/gr-uhd/swig/uhd_swig.i
index 3ffcc7aea..9bdb962c9 100644
--- a/gr-uhd/swig/uhd_swig.i
+++ b/gr-uhd/swig/uhd_swig.i
@@ -100,6 +100,7 @@
////////////////////////////////////////////////////////////////////////
%include stdint.i
%include <uhd/types/serial.hpp>
+%template(byte_vector_t) std::vector<uint8_t>;
%include <uhd/usrp/dboard_iface.hpp>
%template(dboard_iface_sptr) boost::shared_ptr<uhd::usrp::dboard_iface>;
@@ -129,6 +130,6 @@ static const size_t ALL_MBOARDS;
%goops %{
(use-modules (gnuradio gnuradio_core_runtime))
%}
-#endif /* SWIGGUILE */
+#endif /* SWIGGUILE */
#endif /* GR_HAVE_UHD */
diff --git a/gr-utils/src/python/gr_plot_psd.py b/gr-utils/src/python/gr_plot_psd.py
index 3f90a7104..3dab0535a 100755
--- a/gr-utils/src/python/gr_plot_psd.py
+++ b/gr-utils/src/python/gr_plot_psd.py
@@ -93,12 +93,20 @@ class gr_plot_psd:
self.iq = scipy.fromfile(self.hfile, dtype=self.datatype, count=self.block_length)
except MemoryError:
print "End of File"
+ return False
else:
- tstep = 1.0 / self.sample_rate
- #self.time = scipy.array([tstep*(self.position + i) for i in xrange(len(self.iq))])
- self.time = scipy.array([tstep*(i) for i in xrange(len(self.iq))])
-
- self.iq_psd, self.freq = self.dopsd(self.iq)
+ # retesting length here as newer version of scipy does not throw a MemoryError, just
+ # returns a zero-length array
+ if(len(self.iq) > 0):
+ tstep = 1.0 / self.sample_rate
+ #self.time = scipy.array([tstep*(self.position + i) for i in xrange(len(self.iq))])
+ self.time = scipy.array([tstep*(i) for i in xrange(len(self.iq))])
+
+ self.iq_psd, self.freq = self.dopsd(self.iq)
+ return True
+ else:
+ print "End of File"
+ return False
def dopsd(self, iq):
''' Need to do this here and plot later so we can do the fftshift '''
@@ -130,7 +138,7 @@ class gr_plot_psd:
self.sp_psd.set_xlabel("Frequency (Hz)", fontsize=self.label_font_size, fontweight="bold")
self.sp_psd.set_ylabel("Power Spectrum (dBm)", fontsize=self.label_font_size, fontweight="bold")
- self.get_data()
+ r = self.get_data()
self.plot_iq = self.sp_iq.plot([], 'bo-') # make plot for reals
self.plot_iq += self.sp_iq.plot([], 'ro-') # make plot for imags
@@ -220,8 +228,9 @@ class gr_plot_psd:
self.step_forward()
def step_forward(self):
- self.get_data()
- self.update_plots()
+ r = self.get_data()
+ if(r):
+ self.update_plots()
def step_backward(self):
# Step back in file position
@@ -229,8 +238,9 @@ class gr_plot_psd:
self.hfile.seek(-2*self.sizeof_data*self.block_length, 1)
else:
self.hfile.seek(-self.hfile.tell(),1)
- self.get_data()
- self.update_plots()
+ r = self.get_data()
+ if(r):
+ self.update_plots()
def find(item_in, list_search):
try:
diff --git a/grc/Makefile.am b/grc/Makefile.am
index c36786281..9d473b4d3 100644
--- a/grc/Makefile.am
+++ b/grc/Makefile.am
@@ -43,7 +43,6 @@ BUILT_SOURCES += grc.conf
grc.conf: $(srcdir)/grc.conf.in Makefile
sed \
- -e 's|@pythonw[@]|$(PYTHONW)|g' \
-e 's|@blocksdir[@]|$(grc_blocksdir)|g' \
-e 's|@docdir[@]|$(gr_docdir)|g' \
$< > $@
diff --git a/grc/base/Block.py b/grc/base/Block.py
index 42eb6b3fb..fe7ad3c2f 100644
--- a/grc/base/Block.py
+++ b/grc/base/Block.py
@@ -1,5 +1,5 @@
"""
-Copyright 2008, 2009 Free Software Foundation, Inc.
+Copyright 2008-2011 Free Software Foundation, Inc.
This file is part of GNU Radio
GNU Radio Companion is free software; you can redistribute it and/or
@@ -92,8 +92,8 @@ class Block(Element):
for param in map(lambda n: self.get_parent().get_parent().Param(block=self, n=n), params):
key = param.get_key()
#test against repeated keys
- try: assert key not in self.get_param_keys()
- except AssertionError: raise Exception, 'Key "%s" already exists in params'%key
+ if key in self.get_param_keys():
+ raise Exception, 'Key "%s" already exists in params'%key
#store the param
self.get_params().append(param)
#create the source objects
@@ -101,8 +101,8 @@ class Block(Element):
for source in map(lambda n: self.get_parent().get_parent().Port(block=self, n=n, dir='source'), sources):
key = source.get_key()
#test against repeated keys
- try: assert key not in self.get_source_keys()
- except AssertionError: raise Exception, 'Key "%s" already exists in sources'%key
+ if key in self.get_source_keys():
+ raise Exception, 'Key "%s" already exists in sources'%key
#store the port
self.get_sources().append(source)
#create the sink objects
@@ -110,8 +110,8 @@ class Block(Element):
for sink in map(lambda n: self.get_parent().get_parent().Port(block=self, n=n, dir='sink'), sinks):
key = sink.get_key()
#test against repeated keys
- try: assert key not in self.get_sink_keys()
- except AssertionError: raise Exception, 'Key "%s" already exists in sinks'%key
+ if key in self.get_sink_keys():
+ raise Exception, 'Key "%s" already exists in sinks'%key
#store the port
self.get_sinks().append(sink)
diff --git a/grc/base/Connection.py b/grc/base/Connection.py
index 94d4751b2..3ce7fd07f 100644
--- a/grc/base/Connection.py
+++ b/grc/base/Connection.py
@@ -1,5 +1,5 @@
"""
-Copyright 2008, 2009 Free Software Foundation, Inc.
+Copyright 2008-2011 Free Software Foundation, Inc.
This file is part of GNU Radio
GNU Radio Companion is free software; you can redistribute it and/or
@@ -37,10 +37,12 @@ class Connection(Element):
for port in (porta, portb):
if port.is_source(): source = port
if port.is_sink(): sink = port
- assert(source and sink)
+ if not source: raise ValueError('Connection could not isolate source')
+ if not sink: raise ValueError('Connection could not isolate sink')
#ensure that this connection (source -> sink) is unique
for connection in self.get_parent().get_connections():
- assert not (connection.get_source() is source and connection.get_sink() is sink)
+ if connection.get_source() is source and connection.get_sink() is sink:
+ raise Exception('This connection between source and sink is not unique.')
self._source = source
self._sink = sink
@@ -62,8 +64,8 @@ class Connection(Element):
Element.validate(self)
source_type = self.get_source().get_type()
sink_type = self.get_sink().get_type()
- try: assert source_type == sink_type
- except AssertionError: self.add_error_message('Source type "%s" does not match sink type "%s".'%(source_type, sink_type))
+ if source_type != sink_type:
+ self.add_error_message('Source type "%s" does not match sink type "%s".'%(source_type, sink_type))
def get_enabled(self):
"""
diff --git a/grc/base/FlowGraph.py b/grc/base/FlowGraph.py
index b4ac8fc3a..0ba1f2389 100644
--- a/grc/base/FlowGraph.py
+++ b/grc/base/FlowGraph.py
@@ -1,5 +1,5 @@
"""
-Copyright 2008, 2009 Free Software Foundation, Inc.
+Copyright 2008-2011 Free Software Foundation, Inc.
This file is part of GNU Radio
GNU Radio Companion is free software; you can redistribute it and/or
@@ -194,18 +194,26 @@ class FlowGraph(Element):
sink_key = connection_n.find('sink_key')
#verify the blocks
block_ids = map(lambda b: b.get_id(), self.get_blocks())
- assert(source_block_id in block_ids)
- assert(sink_block_id in block_ids)
+ if source_block_id not in block_ids:
+ raise LookupError('source block id "%s" not in block ids'%source_block_id)
+ if sink_block_id not in block_ids:
+ raise LookupError('sink block id "%s" not in block ids'%sink_block_id)
#get the blocks
source_block = self.get_block(source_block_id)
sink_block = self.get_block(sink_block_id)
#verify the ports
- assert(source_key in source_block.get_source_keys())
- assert(sink_key in sink_block.get_sink_keys())
+ if source_key not in source_block.get_source_keys():
+ raise LookupError('source key "%s" not in source block keys'%source_key)
+ if sink_key not in sink_block.get_sink_keys():
+ raise LookupError('sink key "%s" not in sink block keys'%sink_key)
#get the ports
source = source_block.get_source(source_key)
sink = sink_block.get_sink(sink_key)
#build the connection
self.connect(source, sink)
- except AssertionError: Messages.send_error_load('Connection between %s(%s) and %s(%s) could not be made.'%(source_block_id, source_key, sink_block_id, sink_key))
+ except LookupError, e: Messages.send_error_load(
+ 'Connection between %s(%s) and %s(%s) could not be made.\n\t%s'%(
+ source_block_id, source_key, sink_block_id, sink_key, e
+ )
+ )
self.rewrite() #global rewrite
diff --git a/grc/base/Param.py b/grc/base/Param.py
index 5cd0f9d6d..c2fa5461a 100644
--- a/grc/base/Param.py
+++ b/grc/base/Param.py
@@ -1,5 +1,5 @@
"""
-Copyright 2008, 2009 Free Software Foundation, Inc.
+Copyright 2008-2011 Free Software Foundation, Inc.
This file is part of GNU Radio
GNU Radio Companion is free software; you can redistribute it and/or
@@ -34,16 +34,16 @@ class Option(Element):
self._opts = dict()
opts = n.findall('opt')
#test against opts when non enum
- try: assert self.get_parent().is_enum() or not opts
- except AssertionError: raise Exception, 'Options for non-enum types cannot have sub-options'
+ if not self.get_parent().is_enum() and opts:
+ raise Exception, 'Options for non-enum types cannot have sub-options'
#extract opts
for opt in opts:
#separate the key:value
try: key, value = opt.split(':')
except: raise Exception, 'Error separating "%s" into key:value'%opt
#test against repeated keys
- try: assert not self._opts.has_key(key)
- except AssertionError: raise Exception, 'Key "%s" already exists in option'%key
+ if self._opts.has_key(key):
+ raise Exception, 'Key "%s" already exists in option'%key
#store the option
self._opts[key] = value
@@ -79,24 +79,24 @@ class Param(Element):
for option in map(lambda o: Option(param=self, n=o), n.findall('option')):
key = option.get_key()
#test against repeated keys
- try: assert key not in self.get_option_keys()
- except AssertionError: raise Exception, 'Key "%s" already exists in options'%key
+ if key in self.get_option_keys():
+ raise Exception, 'Key "%s" already exists in options'%key
#store the option
self.get_options().append(option)
#test the enum options
if self.is_enum():
#test against options with identical keys
- try: assert len(set(self.get_option_keys())) == len(self.get_options())
- except AssertionError: raise Exception, 'Options keys "%s" are not unique.'%self.get_option_keys()
+ if len(set(self.get_option_keys())) != len(self.get_options()):
+ raise Exception, 'Options keys "%s" are not unique.'%self.get_option_keys()
#test against inconsistent keys in options
opt_keys = self.get_options()[0].get_opt_keys()
for option in self.get_options():
- try: assert set(opt_keys) == set(option.get_opt_keys())
- except AssertionError: raise Exception, 'Opt keys "%s" are not identical across all options.'%opt_keys
+ if set(opt_keys) != set(option.get_opt_keys()):
+ raise Exception, 'Opt keys "%s" are not identical across all options.'%opt_keys
#if a value is specified, it must be in the options keys
self._value = value if value or value in self.get_option_keys() else self.get_option_keys()[0]
- try: assert self.get_value() in self.get_option_keys()
- except AssertionError: raise Exception, 'The value "%s" is not in the possible values of "%s".'%(self.get_value(), self.get_option_keys())
+ if self.get_value() not in self.get_option_keys():
+ raise Exception, 'The value "%s" is not in the possible values of "%s".'%(self.get_value(), self.get_option_keys())
else: self._value = value or ''
def validate(self):
@@ -105,8 +105,8 @@ class Param(Element):
The value must be evaluated and type must a possible type.
"""
Element.validate(self)
- try: assert self.get_type() in self.get_types()
- except AssertionError: self.add_error_message('Type "%s" is not a possible type.'%self.get_type())
+ if self.get_type() not in self.get_types():
+ self.add_error_message('Type "%s" is not a possible type.'%self.get_type())
def get_evaluated(self): raise NotImplementedError
diff --git a/grc/base/Platform.py b/grc/base/Platform.py
index 096fdec41..a66c28ab9 100644
--- a/grc/base/Platform.py
+++ b/grc/base/Platform.py
@@ -1,5 +1,5 @@
"""
-Copyright 2008, 2009, 2011 Free Software Foundation, Inc.
+Copyright 2008-2011 Free Software Foundation, Inc.
This file is part of GNU Radio
GNU Radio Companion is free software; you can redistribute it and/or
@@ -17,16 +17,6 @@ along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
"""
-#Perform python integrity checks:
-# GRC will not work with interpreters that fail the checks below.
-# This can fail on interpreters built with special optimizations.
-try:
- assert False
- raise Exception, 'Failed python integrity check: assert not supported'
-except AssertionError: pass
-if __doc__ is None:
- raise Exception, 'Failed python integrity check: __doc__ not supported'
-
import os
import sys
from .. base import ParseXML, odict
@@ -91,13 +81,12 @@ class Platform(_Element):
block = self.Block(self._flow_graph, n)
key = block.get_key()
#test against repeated keys
- try:
- assert key not in self.get_block_keys()
- #store the block
+ if key in self.get_block_keys():
+ print >> sys.stderr, 'Warning: Block with key "%s" already exists.\n\tIgnoring: %s'%(key, xml_file)
+ #store the block
+ else:
self._blocks[key] = block
self._blocks_n[key] = n
- except AssertionError:
- print >> sys.stderr, 'Warning: Block with key "%s" already exists.\n\tIgnoring: %s'%(key, xml_file)
except ParseXML.XMLSyntaxError, e:
try: #try to add the xml file as a block tree
ParseXML.validate_dtd(xml_file, BLOCK_TREE_DTD)
diff --git a/grc/base/Port.py b/grc/base/Port.py
index 494ea894f..7a1b5d4e6 100644
--- a/grc/base/Port.py
+++ b/grc/base/Port.py
@@ -1,5 +1,5 @@
"""
-Copyright 2008, 2009 Free Software Foundation, Inc.
+Copyright 2008-2011 Free Software Foundation, Inc.
This file is part of GNU Radio
GNU Radio Companion is free software; you can redistribute it and/or
@@ -42,8 +42,8 @@ class Port(Element):
The port must be non-empty and type must a possible type.
"""
Element.validate(self)
- try: assert self.get_type() in self.get_types()
- except AssertionError: self.add_error_message('Type "%s" is not a possible type.'%self.get_type())
+ if self.get_type() not in self.get_types():
+ self.add_error_message('Type "%s" is not a possible type.'%self.get_type())
def __str__(self):
if self.is_source():
diff --git a/grc/base/odict.py b/grc/base/odict.py
index ac3cb2070..044d04ad7 100644
--- a/grc/base/odict.py
+++ b/grc/base/odict.py
@@ -1,5 +1,5 @@
"""
-Copyright 2008, 2009 Free Software Foundation, Inc.
+Copyright 2008-2011 Free Software Foundation, Inc.
This file is part of GNU Radio
GNU Radio Companion is free software; you can redistribute it and/or
@@ -55,7 +55,7 @@ class odict(DictMixin):
@param val the value for the new entry
"""
index = (pos_key is None) and len(self._keys) or self._keys.index(pos_key)
- assert key not in self._keys
+ if key in self._keys: raise KeyError('Cannot insert, key "%s" already exists'%str(key))
self._keys.insert(index+1, key)
self._data[key] = val
@@ -67,8 +67,8 @@ class odict(DictMixin):
@param key the key for the new entry
@param val the value for the new entry
"""
- index = (pos_key is not None) and self._keys.index(pos_key) or 0
- assert key not in self._keys
+ index = (pos_key is not None) and self._keys.index(pos_key) or 0
+ if key in self._keys: raise KeyError('Cannot insert, key "%s" already exists'%str(key))
self._keys.insert(index, key)
self._data[key] = val
diff --git a/grc/blocks/Makefile.am b/grc/blocks/Makefile.am
index 81eb81182..14ffe8358 100644
--- a/grc/blocks/Makefile.am
+++ b/grc/blocks/Makefile.am
@@ -90,6 +90,7 @@ dist_ourdata_DATA = \
gr_correlate_access_code_bb.xml \
gr_costas_loop_cc.xml \
gr_cpfsk_bc.xml \
+ gr_dc_blocker.xml \
gr_decode_ccsds_27_fb.xml \
gr_deinterleave.xml \
gr_delay.xml \
diff --git a/grc/blocks/block_tree.xml b/grc/blocks/block_tree.xml
index 66094a80d..0b641d79c 100644
--- a/grc/blocks/block_tree.xml
+++ b/grc/blocks/block_tree.xml
@@ -188,6 +188,7 @@
<block>gr_keep_one_in_n</block>
<block>gr_moving_average_xx</block>
<block>gr_iqcomp_cc</block>
+ <block>gr_dc_blocker</block>
</cat>
<cat>
<name>Modulators</name>
diff --git a/grc/blocks/gr_dc_blocker.xml b/grc/blocks/gr_dc_blocker.xml
new file mode 100644
index 000000000..e5aeeb031
--- /dev/null
+++ b/grc/blocks/gr_dc_blocker.xml
@@ -0,0 +1,51 @@
+<?xml version="1.0"?>
+<!--
+###################################################
+## DC Blocker
+###################################################
+ -->
+<block>
+ <name>DC Blocker</name>
+ <key>gr_dc_blocker</key>
+ <import>from gnuradio import gr</import>
+ <make>gr.dc_blocker_$(type)($length, $long_form)</make>
+ <!-- <callback>set_length($lenght)</callback> -->
+ <param>
+ <name>Type</name>
+ <key>type</key>
+ <type>enum</type>
+ <option>
+ <name>Complex->Complex</name>
+ <key>cc</key>
+ <opt>input:complex</opt>
+ <opt>output:complex</opt>
+ </option>
+ <option>
+ <name>Float->Float</name>
+ <key>ff</key>
+ <opt>input:float</opt>
+ <opt>output:float</opt>
+ </option>
+ </param>
+ <param>
+ <name>Length</name>
+ <key>length</key>
+ <value>32</value>
+ <type>int</type>
+ </param>
+ <param>
+ <name>Long Form</name>
+ <key>long_form</key>
+ <value>True</value>
+ <type>bool</type>
+ </param>
+
+ <sink>
+ <name>in</name>
+ <type>$type.input</type>
+ </sink>
+ <source>
+ <name>out</name>
+ <type>$type.output</type>
+ </source>
+</block>
diff --git a/grc/blocks/gr_frequency_modulator_fc.xml b/grc/blocks/gr_frequency_modulator_fc.xml
index f18d9f1e1..d5f8fcfe3 100644
--- a/grc/blocks/gr_frequency_modulator_fc.xml
+++ b/grc/blocks/gr_frequency_modulator_fc.xml
@@ -9,6 +9,7 @@
<key>gr_frequency_modulator_fc</key>
<import>from gnuradio import gr</import>
<make>gr.frequency_modulator_fc($sensitivity)</make>
+ <callback>set_sensitivity($sensitivity)</callback>
<param>
<name>Sensitivity</name>
<key>sensitivity</key>
diff --git a/grc/grc.conf.in b/grc/grc.conf.in
index 37a049971..9363ca981 100644
--- a/grc/grc.conf.in
+++ b/grc/grc.conf.in
@@ -3,7 +3,6 @@
# ~/.gnuradio/config.conf
[grc]
-pythonw = @pythonw@
doc_dir = @docdir@
global_blocks_path = @blocksdir@
local_blocks_path =
diff --git a/grc/gui/ActionHandler.py b/grc/gui/ActionHandler.py
index 350b297bb..15785f2ee 100644
--- a/grc/gui/ActionHandler.py
+++ b/grc/gui/ActionHandler.py
@@ -1,5 +1,5 @@
"""
-Copyright 2007, 2008, 2009, 2011 Free Software Foundation, Inc.
+Copyright 2007-2011 Free Software Foundation, Inc.
This file is part of GNU Radio
GNU Radio Companion is free software; you can redistribute it and/or
@@ -78,8 +78,7 @@ class ActionHandler:
When not in focus, gtk and the accelerators handle the the key press.
@return false to let gtk handle the key action
"""
- try: assert self.get_focus_flag()
- except AssertionError: return False
+ if not self.get_focus_flag(): return False
return Actions.handle_key_press(event)
def _quit(self, window, event):
diff --git a/grc/gui/Actions.py b/grc/gui/Actions.py
index f374efde1..4d196477e 100644
--- a/grc/gui/Actions.py
+++ b/grc/gui/Actions.py
@@ -1,5 +1,5 @@
"""
-Copyright 2007, 2008, 2009 Free Software Foundation, Inc.
+Copyright 2007-2011 Free Software Foundation, Inc.
This file is part of GNU Radio
GNU Radio Companion is free software; you can redistribute it and/or
@@ -76,7 +76,8 @@ class Action(gtk.Action):
for i in range(len(keypresses)/2):
keyval, mod_mask = keypresses[i*2:(i+1)*2]
#register this keypress
- assert not _actions_keypress_dict.has_key((keyval, mod_mask))
+ if _actions_keypress_dict.has_key((keyval, mod_mask)):
+ raise KeyError('keyval/mod_mask pair already registered "%s"'%str((keyval, mod_mask)))
_actions_keypress_dict[(keyval, mod_mask)] = self
#set the accelerator group, and accelerator path
#register the key name and mod mask with the accelerator path
diff --git a/grc/gui/FlowGraph.py b/grc/gui/FlowGraph.py
index 897145a1d..9f3326ada 100644
--- a/grc/gui/FlowGraph.py
+++ b/grc/gui/FlowGraph.py
@@ -1,5 +1,5 @@
"""
-Copyright 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
+Copyright 2007-2011 Free Software Foundation, Inc.
This file is part of GNU Radio
GNU Radio Companion is free software; you can redistribute it and/or
@@ -290,10 +290,10 @@ class FlowGraph(Element):
for selected in selected_elements:
if selected in elements: continue
selected_elements.remove(selected)
- try: assert self._old_selected_port.get_parent() in elements
- except: self._old_selected_port = None
- try: assert self._new_selected_port.get_parent() in elements
- except: self._new_selected_port = None
+ if self._old_selected_port and self._old_selected_port.get_parent() not in elements:
+ self._old_selected_port = None
+ if self._new_selected_port and self._new_selected_port.get_parent() not in elements:
+ self._new_selected_port = None
#update highlighting
for element in elements:
element.set_highlighted(element in selected_elements)
diff --git a/grc/gui/Utils.py b/grc/gui/Utils.py
index b5489d56e..bb19ed3d9 100644
--- a/grc/gui/Utils.py
+++ b/grc/gui/Utils.py
@@ -1,5 +1,5 @@
"""
-Copyright 2008, 2009 Free Software Foundation, Inc.
+Copyright 2008-2011 Free Software Foundation, Inc.
This file is part of GNU Radio
GNU Radio Companion is free software; you can redistribute it and/or
@@ -53,7 +53,8 @@ def get_rotated_coordinate(coor, rotation):
"""
#handles negative angles
rotation = (rotation + 360)%360
- assert rotation in POSSIBLE_ROTATIONS
+ if rotation not in POSSIBLE_ROTATIONS:
+ raise ValueError('unusable rotation angle "%s"'%str(rotation))
#determine the number of degrees to rotate
cos_r, sin_r = {
0: (1, 0),
diff --git a/grc/python/Block.py b/grc/python/Block.py
index bd03eb5cd..14a5859e4 100644
--- a/grc/python/Block.py
+++ b/grc/python/Block.py
@@ -1,5 +1,5 @@
"""
-Copyright 2008, 2009 Free Software Foundation, Inc.
+Copyright 2008-2011 Free Software Foundation, Inc.
This file is part of GNU Radio
GNU Radio Companion is free software; you can redistribute it and/or
@@ -65,9 +65,8 @@ class Block(_Block, _GUIBlock):
for check in self._checks:
check_res = self.resolve_dependencies(check)
try:
- check_eval = self.get_parent().evaluate(check_res)
- try: assert check_eval
- except AssertionError: self.add_error_message('Check "%s" failed.'%check)
+ if not self.get_parent().evaluate(check_res):
+ self.add_error_message('Check "%s" failed.'%check)
except: self.add_error_message('Check "%s" did not evaluate.'%check)
def rewrite(self):
@@ -134,9 +133,9 @@ class Block(_Block, _GUIBlock):
try:
value = param.get_evaluated()
value = value + direction
- assert 0 < value
- param.set_value(value)
- changed = True
+ if 0 < value:
+ param.set_value(value)
+ changed = True
except: pass
return changed
diff --git a/grc/python/Connection.py b/grc/python/Connection.py
index edc18841a..39f915740 100644
--- a/grc/python/Connection.py
+++ b/grc/python/Connection.py
@@ -1,5 +1,5 @@
"""
-Copyright 2008, 2009 Free Software Foundation, Inc.
+Copyright 2008-2011 Free Software Foundation, Inc.
This file is part of GNU Radio
GNU Radio Companion is free software; you can redistribute it and/or
@@ -38,5 +38,5 @@ class Connection(_Connection, _GUIConnection):
#check vector length
source_vlen = self.get_source().get_vlen()
sink_vlen = self.get_sink().get_vlen()
- try: assert source_vlen == sink_vlen
- except AssertionError: self.add_error_message('Source vector length "%s" does not match sink vector length "%s".'%(source_vlen, sink_vlen))
+ if source_vlen != sink_vlen:
+ self.add_error_message('Source vector length "%s" does not match sink vector length "%s".'%(source_vlen, sink_vlen))
diff --git a/grc/python/Constants.py b/grc/python/Constants.py
index e661c3927..868c822aa 100644
--- a/grc/python/Constants.py
+++ b/grc/python/Constants.py
@@ -1,5 +1,5 @@
"""
-Copyright 2008, 2009 Free Software Foundation, Inc.
+Copyright 2008-2011 Free Software Foundation, Inc.
This file is part of GNU Radio
GNU Radio Companion is free software; you can redistribute it and/or
@@ -23,10 +23,8 @@ from gnuradio import gr
_gr_prefs = gr.prefs()
-PYEXEC = os.environ.get('PYTHONW', _gr_prefs.get_string('grc', 'pythonw', ''))
-
#setup paths
-PATH_SEP = ':'
+PATH_SEP = {'/':':', '\\':';'}[os.path.sep]
DOCS_DIR = os.environ.get('GR_DOC_DIR', _gr_prefs.get_string('grc', 'doc_dir', ''))
HIER_BLOCKS_LIB_DIR = os.path.join(os.path.expanduser('~'), '.grc_gnuradio')
BLOCKS_DIRS = filter( #filter blank strings
diff --git a/grc/python/FlowGraph.py b/grc/python/FlowGraph.py
index b2d406bbd..89a169355 100644
--- a/grc/python/FlowGraph.py
+++ b/grc/python/FlowGraph.py
@@ -1,5 +1,5 @@
"""
-Copyright 2008, 2009 Free Software Foundation, Inc.
+Copyright 2008-2011 Free Software Foundation, Inc.
This file is part of GNU Radio
GNU Radio Companion is free software; you can redistribute it and/or
@@ -48,15 +48,16 @@ class FlowGraph(_FlowGraph, _GUIFlowGraph):
#return from cache
return self._eval_cache[my_hash]
- def _get_io_signaturev(self, pad_key):
+ def get_io_signaturev(self, direction):
"""
Get a list of io signatures for this flow graph.
- The pad key determines the directionality of the io signature.
- @param pad_key a string of pad_source or pad_sink
+ @param direction a string of 'in' or 'out'
@return a list of dicts with: type, label, vlen, size
"""
- pads = filter(lambda b: b.get_key() == pad_key, self.get_enabled_blocks())
- sorted_pads = sorted(pads, lambda x, y: cmp(x.get_id(), y.get_id()))
+ sorted_pads = {
+ 'in': self.get_pad_sources(),
+ 'out': self.get_pad_sinks(),
+ }[direction]
#load io signature
return [{
'label': str(pad.get_param('label').get_evaluated()),
@@ -65,19 +66,21 @@ class FlowGraph(_FlowGraph, _GUIFlowGraph):
'size': pad.get_param('type').get_opt('size'),
} for pad in sorted_pads]
- def get_input_signaturev(self):
+ def get_pad_sources(self):
"""
- Get the io signature for the input side of this flow graph.
- @return a list of io signature structures
+ Get a list of pad source blocks sorted by id order.
+ @return a list of pad source blocks in this flow graph
"""
- return self._get_io_signaturev('pad_source')
+ pads = filter(lambda b: b.get_key() == 'pad_source', self.get_enabled_blocks())
+ return sorted(pads, lambda x, y: cmp(x.get_id(), y.get_id()))
- def get_output_signaturev(self):
+ def get_pad_sinks(self):
"""
- Get the io signature for the output side of this flow graph.
- @return a list of io signature structures
+ Get a list of pad sink blocks sorted by id order.
+ @return a list of pad sink blocks in this flow graph
"""
- return self._get_io_signaturev('pad_sink')
+ pads = filter(lambda b: b.get_key() == 'pad_sink', self.get_enabled_blocks())
+ return sorted(pads, lambda x, y: cmp(x.get_id(), y.get_id()))
def get_imports(self):
"""
diff --git a/grc/python/Generator.py b/grc/python/Generator.py
index b669fa65a..2a2dfdd49 100644
--- a/grc/python/Generator.py
+++ b/grc/python/Generator.py
@@ -18,14 +18,14 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
"""
import os
+import sys
import subprocess
import tempfile
from Cheetah.Template import Template
import expr_utils
from Constants import \
TOP_BLOCK_FILE_MODE, HIER_BLOCK_FILE_MODE, \
- HIER_BLOCKS_LIB_DIR, PYEXEC, \
- FLOW_GRAPH_TEMPLATE
+ HIER_BLOCKS_LIB_DIR, FLOW_GRAPH_TEMPLATE
import convert_hier
from .. gui import Messages
@@ -74,10 +74,21 @@ Add a Misc->Throttle block to your flow graph to avoid CPU congestion.''')
Execute this python flow graph.
@return a popen object
"""
- #execute
- cmds = [PYEXEC, '-u', self.get_file_path()] #-u is unbuffered stdio
- if self._generate_options == 'no_gui':
+ #extract the path to the python executable
+ python_exe = sys.executable
+
+ #when using wx gui on mac os, execute with pythonw
+ #using pythonw is not necessary anymore, disabled below
+ #if self._generate_options == 'wx_gui' and 'darwin' in sys.platform.lower():
+ # python_exe = 'pythonw'
+
+ #setup the command args to run
+ cmds = [python_exe, '-u', self.get_file_path()] #-u is unbuffered stdio
+
+ #when in no gui mode on linux, use an xterm (looks nice)
+ if self._generate_options == 'no_gui' and 'linux' in sys.platform.lower():
cmds = ['xterm', '-e'] + cmds
+
p = subprocess.Popen(args=cmds, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, shell=False, universal_newlines=True)
return p
diff --git a/grc/python/Param.py b/grc/python/Param.py
index 303ab3ed8..5536138c1 100644
--- a/grc/python/Param.py
+++ b/grc/python/Param.py
@@ -213,8 +213,7 @@ class Param(_Param, _GUIParam):
lambda p: p._vlen, self.get_parent().get_ports())
):
try:
- assert int(self.get_evaluated()) == 1
- return 'part'
+ if int(self.get_evaluated()) == 1: return 'part'
except: pass
#hide empty grid positions
if self.get_key() in ('grid_pos', 'notebook') and not self.get_value(): return 'part'
@@ -244,8 +243,7 @@ class Param(_Param, _GUIParam):
def eval_string(v):
try:
e = self.get_parent().get_parent().evaluate(v)
- assert isinstance(e, str)
- return e
+ if isinstance(e, str): return e
except:
self._stringify_flag = True
return v
@@ -265,21 +263,21 @@ class Param(_Param, _GUIParam):
#raise an exception if the data is invalid
if t == 'raw': return e
elif t == 'complex':
- try: assert isinstance(e, COMPLEX_TYPES)
- except AssertionError: raise Exception, 'Expression "%s" is invalid for type complex.'%str(e)
+ if not isinstance(e, COMPLEX_TYPES):
+ raise Exception, 'Expression "%s" is invalid for type complex.'%str(e)
return e
elif t == 'real':
- try: assert isinstance(e, REAL_TYPES)
- except AssertionError: raise Exception, 'Expression "%s" is invalid for type real.'%str(e)
+ if not isinstance(e, REAL_TYPES):
+ raise Exception, 'Expression "%s" is invalid for type real.'%str(e)
return e
elif t == 'int':
- try: assert isinstance(e, INT_TYPES)
- except AssertionError: raise Exception, 'Expression "%s" is invalid for type integer.'%str(e)
+ if not isinstance(e, INT_TYPES):
+ raise Exception, 'Expression "%s" is invalid for type integer.'%str(e)
return e
elif t == 'hex': return hex(e)
elif t == 'bool':
- try: assert isinstance(e, bool)
- except AssertionError: raise Exception, 'Expression "%s" is invalid for type bool.'%str(e)
+ if not isinstance(e, bool):
+ raise Exception, 'Expression "%s" is invalid for type bool.'%str(e)
return e
else: raise TypeError, 'Type "%s" not handled'%t
#########################
@@ -295,25 +293,22 @@ class Param(_Param, _GUIParam):
if not isinstance(e, VECTOR_TYPES):
self._lisitify_flag = True
e = [e]
- try:
- for ei in e: assert isinstance(ei, COMPLEX_TYPES)
- except AssertionError: raise Exception, 'Expression "%s" is invalid for type complex vector.'%str(e)
+ if not all([isinstance(ei, COMPLEX_TYPES) for ei in e]):
+ raise Exception, 'Expression "%s" is invalid for type complex vector.'%str(e)
return e
elif t == 'real_vector':
if not isinstance(e, VECTOR_TYPES):
self._lisitify_flag = True
e = [e]
- try:
- for ei in e: assert isinstance(ei, REAL_TYPES)
- except AssertionError: raise Exception, 'Expression "%s" is invalid for type real vector.'%str(e)
+ if not all([isinstance(ei, REAL_TYPES) for ei in e]):
+ raise Exception, 'Expression "%s" is invalid for type real vector.'%str(e)
return e
elif t == 'int_vector':
if not isinstance(e, VECTOR_TYPES):
self._lisitify_flag = True
e = [e]
- try:
- for ei in e: assert isinstance(ei, INT_TYPES)
- except AssertionError: raise Exception, 'Expression "%s" is invalid for type integer vector.'%str(e)
+ if not all([isinstance(ei, INT_TYPES) for ei in e]):
+ raise Exception, 'Expression "%s" is invalid for type integer vector.'%str(e)
return e
#########################
# String Types
@@ -327,13 +322,13 @@ class Param(_Param, _GUIParam):
#########################
elif t == 'id':
#can python use this as a variable?
- try: assert _check_id_matcher.match(v)
- except AssertionError: raise Exception, 'ID "%s" must begin with a letter and may contain letters, numbers, and underscores.'%v
+ if not _check_id_matcher.match(v):
+ raise Exception, 'ID "%s" must begin with a letter and may contain letters, numbers, and underscores.'%v
ids = [param.get_value() for param in self.get_all_params(t)]
- try: assert ids.count(v) <= 1 #id should only appear once, or zero times if block is disabled
- except: raise Exception, 'ID "%s" is not unique.'%v
- try: assert v not in ID_BLACKLIST
- except: raise Exception, 'ID "%s" is blacklisted.'%v
+ if ids.count(v) > 1: #id should only appear once, or zero times if block is disabled
+ raise Exception, 'ID "%s" is not unique.'%v
+ if v in ID_BLACKLIST:
+ raise Exception, 'ID "%s" is blacklisted.'%v
return v
#########################
# Stream ID Type
@@ -346,12 +341,12 @@ class Param(_Param, _GUIParam):
)]
#check that the virtual sink's stream id is unique
if self.get_parent().is_virtual_sink():
- try: assert ids.count(v) <= 1 #id should only appear once, or zero times if block is disabled
- except: raise Exception, 'Stream ID "%s" is not unique.'%v
+ if ids.count(v) > 1: #id should only appear once, or zero times if block is disabled
+ raise Exception, 'Stream ID "%s" is not unique.'%v
#check that the virtual source's steam id is found
if self.get_parent().is_virtual_source():
- try: assert v in ids
- except: raise Exception, 'Stream ID "%s" is not found.'%v
+ if v not in ids:
+ raise Exception, 'Stream ID "%s" is not found.'%v
return v
#########################
# GUI Position/Hint
@@ -382,17 +377,15 @@ class Param(_Param, _GUIParam):
elif t == 'grid_pos':
if not v: return '' #allow for empty grid pos
e = self.get_parent().get_parent().evaluate(v)
- try:
- assert isinstance(e, (list, tuple)) and len(e) == 4
- for ei in e: assert isinstance(ei, int)
- except AssertionError: raise Exception, 'A grid position must be a list of 4 integers.'
+ if not isinstance(e, (list, tuple)) or len(e) != 4 or not all([isinstance(ei, int) for ei in e]):
+ raise Exception, 'A grid position must be a list of 4 integers.'
row, col, row_span, col_span = e
#check row, col
- try: assert row >= 0 and col >= 0
- except AssertionError: raise Exception, 'Row and column must be non-negative.'
+ if row < 0 or col < 0:
+ raise Exception, 'Row and column must be non-negative.'
#check row span, col span
- try: assert row_span > 0 and col_span > 0
- except AssertionError: raise Exception, 'Row and column span must be greater than zero.'
+ if row_span <= 0 or col_span <= 0:
+ raise Exception, 'Row and column span must be greater than zero.'
#get hostage cell parent
try: my_parent = self.get_parent().get_param('notebook').evaluate()
except: my_parent = ''
@@ -421,8 +414,8 @@ class Param(_Param, _GUIParam):
try: notebook_block = filter(lambda b: b.get_id() == notebook_id, notebook_blocks)[0]
except: raise Exception, 'Notebook id "%s" is not an existing notebook id.'%notebook_id
#check that page index exists
- try: assert int(page_index) in range(len(notebook_block.get_param('labels').evaluate()))
- except: raise Exception, 'Page index "%s" is not a valid index number.'%page_index
+ if int(page_index) not in range(len(notebook_block.get_param('labels').evaluate())):
+ raise Exception, 'Page index "%s" is not a valid index number.'%page_index
return notebook_id, page_index
#########################
# Import Type
diff --git a/grc/python/Platform.py b/grc/python/Platform.py
index ec3f94096..a9c2b18ad 100644
--- a/grc/python/Platform.py
+++ b/grc/python/Platform.py
@@ -1,5 +1,5 @@
-"""
-Copyright 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
+__doc__ = """
+Copyright 2008-2011 Free Software Foundation, Inc.
This file is part of GNU Radio
GNU Radio Companion is free software; you can redistribute it and/or
diff --git a/grc/python/Port.py b/grc/python/Port.py
index 6e5a5c59f..3846b0f4e 100644
--- a/grc/python/Port.py
+++ b/grc/python/Port.py
@@ -1,5 +1,5 @@
"""
-Copyright 2008, 2009 Free Software Foundation, Inc.
+Copyright 2008-2011 Free Software Foundation, Inc.
This file is part of GNU Radio
GNU Radio Companion is free software; you can redistribute it and/or
@@ -83,16 +83,16 @@ class Port(_Port, _GUIPort):
def validate(self):
_Port.validate(self)
- try: assert self.get_enabled_connections() or self.get_optional()
- except AssertionError: self.add_error_message('Port is not connected.')
- try: assert self.is_source() or len(self.get_enabled_connections()) <= 1
- except AssertionError: self.add_error_message('Port has too many connections.')
+ if not self.get_enabled_connections() and not self.get_optional():
+ self.add_error_message('Port is not connected.')
+ if not self.is_source() and len(self.get_enabled_connections()) > 1:
+ self.add_error_message('Port has too many connections.')
#message port logic
if self.get_type() == 'msg':
- try: assert not self.get_nports()
- except AssertionError: self.add_error_message('A port of type "msg" cannot have "nports" set.')
- try: assert self.get_vlen() == 1
- except AssertionError: self.add_error_message('A port of type "msg" must have a "vlen" of 1.')
+ if self.get_nports():
+ self.add_error_message('A port of type "msg" cannot have "nports" set.')
+ if self.get_vlen() != 1:
+ self.add_error_message('A port of type "msg" must have a "vlen" of 1.')
def rewrite(self):
"""
@@ -134,8 +134,7 @@ class Port(_Port, _GUIPort):
if not nports: return ''
try:
nports = int(self.get_parent().get_parent().evaluate(nports))
- assert 0 < nports
- return nports
+ if 0 < nports: return nports
except: return 1
def get_optional(self): return bool(self._optional)
diff --git a/grc/python/convert_hier.py b/grc/python/convert_hier.py
index befddccea..c6ca5b769 100644
--- a/grc/python/convert_hier.py
+++ b/grc/python/convert_hier.py
@@ -1,5 +1,5 @@
"""
-Copyright 2008 Free Software Foundation, Inc.
+Copyright 2008-2011 Free Software Foundation, Inc.
This file is part of GNU Radio
GNU Radio Companion is free software; you can redistribute it and/or
@@ -23,11 +23,11 @@ from .. base import odict
def convert_hier(flow_graph, python_file):
#extract info from the flow graph
- input_sigs = flow_graph.get_input_signaturev()
- output_sigs = flow_graph.get_output_signaturev()
+ input_sigs = flow_graph.get_io_signaturev('in')
+ output_sigs = flow_graph.get_io_signaturev('out')
parameters = flow_graph.get_parameters()
block_key = flow_graph.get_option('id')
- block_name = flow_graph.get_option('title')
+ block_name = flow_graph.get_option('title') or flow_graph.get_option('id').replace('_', ' ').title()
block_category = flow_graph.get_option('category')
block_desc = flow_graph.get_option('description')
block_author = flow_graph.get_option('author')
@@ -56,19 +56,21 @@ def convert_hier(flow_graph, python_file):
params_n.append(param_n)
block_n['param'] = params_n
#sink data
+ block_n['sink'] = list()
for input_sig in input_sigs:
sink_n = odict()
sink_n['name'] = input_sig['label']
sink_n['type'] = input_sig['type']
sink_n['vlen'] = input_sig['vlen']
- block_n['sink'] = sink_n
+ block_n['sink'].append(sink_n)
#source data
+ block_n['source'] = list()
for output_sig in output_sigs:
source_n = odict()
source_n['name'] = output_sig['label']
source_n['type'] = output_sig['type']
source_n['vlen'] = output_sig['vlen']
- block_n['source'] = source_n
+ block_n['source'].append(source_n)
#doc data
block_n['doc'] = "%s\n%s\n%s"%(block_author, block_desc, python_file)
#write the block_n to file
diff --git a/grc/python/expr_utils.py b/grc/python/expr_utils.py
index 3c39f5d89..a2e56eedf 100644
--- a/grc/python/expr_utils.py
+++ b/grc/python/expr_utils.py
@@ -1,5 +1,5 @@
"""
-Copyright 2008, 2009 Free Software Foundation, Inc.
+Copyright 2008-2011 Free Software Foundation, Inc.
This file is part of GNU Radio
GNU Radio Companion is free software; you can redistribute it and/or
@@ -118,7 +118,7 @@ def sort_variables(exprs):
Get a list of variables in order of dependencies.
@param exprs a mapping of variable name to expression
@return a list of variable names
- @throws AssertionError circular dependencies
+ @throws Exception circular dependencies
"""
var_graph = get_graph(exprs)
sorted_vars = list()
@@ -126,7 +126,7 @@ def sort_variables(exprs):
while var_graph.get_nodes():
#get a list of nodes with no edges
indep_vars = filter(lambda var: not var_graph.get_edges(var), var_graph.get_nodes())
- assert indep_vars
+ if not indep_vars: raise Exception('circular dependency caught in sort_variables')
#add the indep vars to the end of the list
sorted_vars.extend(sorted(indep_vars))
#remove each edge-less node from the graph
diff --git a/grc/python/extract_docs.py b/grc/python/extract_docs.py
index f41f415b2..aa85397f9 100644
--- a/grc/python/extract_docs.py
+++ b/grc/python/extract_docs.py
@@ -1,5 +1,5 @@
"""
-Copyright 2008, 2009 Free Software Foundation, Inc.
+Copyright 2008-2011 Free Software Foundation, Inc.
This file is part of GNU Radio
GNU Radio Companion is free software; you can redistribute it and/or
@@ -81,8 +81,8 @@ def extract(key):
@param key the block key
@return a string with documentation
"""
- try: assert _docs_cache.has_key(key)
- except: _docs_cache[key] = _extract(key)
+ if not _docs_cache.has_key(key):
+ _docs_cache[key] = _extract(key)
return _docs_cache[key]
if __name__ == '__main__':
diff --git a/grc/python/flow_graph.tmpl b/grc/python/flow_graph.tmpl
index 7a74cf84c..d5e53b52b 100644
--- a/grc/python/flow_graph.tmpl
+++ b/grc/python/flow_graph.tmpl
@@ -74,8 +74,8 @@ class $(class_name)(gr.top_block):
def __init__($param_str):
gr.top_block.__init__(self, "$title")
#elif $generate_options == 'hb'
- #set $in_sigs = $flow_graph.get_input_signaturev()
- #set $out_sigs = $flow_graph.get_output_signaturev()
+ #set $in_sigs = $flow_graph.get_io_signaturev('in')
+ #set $out_sigs = $flow_graph.get_io_signaturev('out')
class $(class_name)(gr.hier_block2):
#def make_io_sig($io_sigs)
#set $size_strs = ['%s*%s'%(io_sig['size'], io_sig['vlen']) for io_sig in $io_sigs]
@@ -153,11 +153,13 @@ gr.io_signaturev($(len($io_sigs)), $(len($io_sigs)), [$(', '.join($size_strs))])
## The port name should be the id of the parent block.
## However, port names for IO pads should be self.
########################################################
-#def make_port_name($port)
- #if $port.get_parent().get_key().startswith('pad_')
-self#slurp
+#def make_port_sig($port)
+ #if $port.get_parent().get_key() == 'pad_source'
+(self, $flow_graph.get_pad_sources().index($port.get_parent()))#slurp
+ #elif $port.get_parent().get_key() == 'pad_sink'
+(self, $flow_graph.get_pad_sinks().index($port.get_parent()))#slurp
#else
-self.$port.get_parent().get_id()#slurp
+(self.$port.get_parent().get_id(), $port.get_key())#slurp
#end if
#end def
#if $connections
@@ -175,7 +177,7 @@ self.$port.get_parent().get_id()#slurp
#end if
##do not generate connections with virtual sinks
#if not $sink.get_parent().is_virtual_sink()
- self.connect(($make_port_name($source), $source.get_key()), ($make_port_name($sink), $sink.get_key()))
+ self.connect($make_port_sig($source), $make_port_sig($sink))
#end if
#end for
diff --git a/gruel/src/include/gruel/Makefile.am b/gruel/src/include/gruel/Makefile.am
index 89a9da7f0..96aed326e 100644
--- a/gruel/src/include/gruel/Makefile.am
+++ b/gruel/src/include/gruel/Makefile.am
@@ -27,6 +27,7 @@ gruelincludedir = $(prefix)/include/gruel
gruelinclude_HEADERS = \
attributes.h \
+ high_res_timer.h \
inet.h \
msg_accepter.h \
msg_accepter_msgq.h \
diff --git a/gruel/src/include/gruel/high_res_timer.h b/gruel/src/include/gruel/high_res_timer.h
new file mode 100644
index 000000000..fe9ae763f
--- /dev/null
+++ b/gruel/src/include/gruel/high_res_timer.h
@@ -0,0 +1,124 @@
+/*
+ * Copyright 2011 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef INCLUDED_GRUEL_HIGH_RES_TIMER_H
+#define INCLUDED_GRUEL_HIGH_RES_TIMER_H
+
+namespace gruel {
+ //! Typedef for the timer tick count
+ typedef signed long long high_res_timer_type;
+
+ //! Get the current time in ticks
+ high_res_timer_type high_res_timer_now(void);
+
+ //! Get the number of ticks per second
+ high_res_timer_type high_res_timer_tps(void);
+
+ //! Get the tick count at the epoch
+ high_res_timer_type high_res_timer_epoch(void);
+
+} /* namespace gruel */
+
+////////////////////////////////////////////////////////////////////////
+// Use architecture defines to determine the implementation
+////////////////////////////////////////////////////////////////////////
+#if defined(linux) || defined(__linux) || defined(__linux__)
+ #define GRUEL_HRT_USE_CLOCK_GETTIME
+#elif defined(_WIN32) || defined(__WIN32__) || defined(WIN32)
+ #define GRUEL_HRT_USE_QUERY_PERFORMANCE_COUNTER
+#elif defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__)
+ #define GRUEL_HRT_USE_MACH_ABSOLUTE_TIME
+#elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)
+ #define GRUEL_HRT_USE_MACH_ABSOLUTE_TIME
+#else
+ #define GRUEL_HRT_USE_MICROSEC_CLOCK
+#endif
+
+////////////////////////////////////////////////////////////////////////
+#ifdef GRUEL_HRT_USE_CLOCK_GETTIME
+ #include <ctime>
+
+ inline gruel::high_res_timer_type gruel::high_res_timer_now(void){
+ timespec ts;
+ clock_gettime(CLOCK_MONOTONIC, &ts);
+ return high_res_timer_type(ts.tv_sec*1000000000UL) + ts.tv_nsec;
+ }
+
+ inline gruel::high_res_timer_type gruel::high_res_timer_tps(void){
+ return 1000000000UL;
+ }
+#endif /* GRUEL_HRT_USE_CLOCK_GETTIME */
+
+////////////////////////////////////////////////////////////////////////
+#ifdef GRUEL_HRT_USE_MACH_ABSOLUTE_TIME
+ #include <mach/mach_time.h>
+
+ inline gruel::high_res_timer_type gruel::high_res_timer_now(void){
+ return mach_absolute_time();
+ }
+
+ inline gruel::high_res_timer_type gruel::high_res_timer_tps(void){
+ mach_timebase_info_data_t info;
+ mach_timebase_info(&info);
+ return gruel::high_res_timer_type(info.numer*1000000000UL)/info.denom;
+ }
+#endif
+
+////////////////////////////////////////////////////////////////////////
+#ifdef GRUEL_HRT_USE_QUERY_PERFORMANCE_COUNTER
+ #include <Windows.h>
+
+ inline gruel::high_res_timer_type gruel::high_res_timer_now(void){
+ LARGE_INTEGER counts;
+ QueryPerformanceCounter(&counts);
+ return counts.QuadPart;
+ }
+
+ inline gruel::high_res_timer_type gruel::high_res_timer_tps(void){
+ LARGE_INTEGER freq;
+ QueryPerformanceFrequency(&freq);
+ return freq.QuadPart;
+ }
+#endif
+
+////////////////////////////////////////////////////////////////////////
+#ifdef GRUEL_HRT_USE_MICROSEC_CLOCK
+ #include <boost/date_time/posix_time/posix_time.hpp>
+
+ inline gruel::high_res_timer_type gruel::high_res_timer_now(void){
+ static const boost::posix_time::ptime epoch(boost::posix_time::from_time_t(0));
+ return (boost::posix_time::microsec_clock::universal_time() - epoch).ticks();
+ }
+
+ inline gruel::high_res_timer_type gruel::high_res_timer_tps(void){
+ return boost::posix_time::time_duration::ticks_per_second();
+ }
+#endif
+
+////////////////////////////////////////////////////////////////////////
+#include <boost/date_time/posix_time/posix_time.hpp>
+
+inline gruel::high_res_timer_type gruel::high_res_timer_epoch(void){
+ static const double hrt_ticks_per_utc_ticks = gruel::high_res_timer_tps()/double(boost::posix_time::time_duration::ticks_per_second());
+ boost::posix_time::time_duration utc = boost::posix_time::microsec_clock::universal_time() - boost::posix_time::from_time_t(0);
+ return gruel::high_res_timer_now() - utc.ticks()*hrt_ticks_per_utc_ticks;
+}
+
+#endif /* INCLUDED_GRUEL_HIGH_RES_TIMER_H */
diff --git a/gruel/src/python/Makefile.am b/gruel/src/python/Makefile.am
index 5a45510d5..80cb04b24 100644
--- a/gruel/src/python/Makefile.am
+++ b/gruel/src/python/Makefile.am
@@ -35,5 +35,9 @@ noinst_PYTHON = \
gruel_PYTHON = \
__init__.py
+gruelpmtdir = $(pythondir)/gruel/pmt
+
+gruelpmt_PYTHON = pmt/__init__.py
+
endif
diff --git a/gruel/src/python/__init__.py b/gruel/src/python/__init__.py
index 421a9aaa8..14014cc5a 100644
--- a/gruel/src/python/__init__.py
+++ b/gruel/src/python/__init__.py
@@ -21,5 +21,5 @@
# The presence of this file turns this directory into a Python package
-from pmt_swig import *
+import pmt;
diff --git a/gruel/src/python/pmt/__init__.py b/gruel/src/python/pmt/__init__.py
new file mode 100644
index 000000000..421a9aaa8
--- /dev/null
+++ b/gruel/src/python/pmt/__init__.py
@@ -0,0 +1,25 @@
+#
+# Copyright 2011 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+# The presence of this file turns this directory into a Python package
+
+from pmt_swig import *
+