summaryrefslogtreecommitdiff
path: root/gr-howto-write-a-block
diff options
context:
space:
mode:
Diffstat (limited to 'gr-howto-write-a-block')
-rw-r--r--gr-howto-write-a-block/Makefile.am6
-rw-r--r--gr-howto-write-a-block/Makefile.common3
-rw-r--r--gr-howto-write-a-block/README15
-rw-r--r--gr-howto-write-a-block/README.hacking95
-rw-r--r--gr-howto-write-a-block/apps/.gitignore2
-rw-r--r--gr-howto-write-a-block/apps/Makefile.am32
-rw-r--r--gr-howto-write-a-block/apps/howto_square.grc325
-rwxr-xr-xgr-howto-write-a-block/apps/howto_square.py77
-rw-r--r--gr-howto-write-a-block/config/gr_standalone.m48
-rw-r--r--gr-howto-write-a-block/configure.ac2
-rw-r--r--gr-howto-write-a-block/grc/.gitignore2
-rw-r--r--gr-howto-write-a-block/grc/Makefile.am29
-rw-r--r--gr-howto-write-a-block/grc/howto_square2_ff.xml18
-rw-r--r--gr-howto-write-a-block/grc/howto_square_ff.xml18
-rw-r--r--gr-howto-write-a-block/lib/.gitignore1
-rw-r--r--gr-howto-write-a-block/lib/Makefile.am42
-rw-r--r--gr-howto-write-a-block/lib/qa_howto.cc41
-rw-r--r--gr-howto-write-a-block/lib/qa_howto.h36
-rw-r--r--gr-howto-write-a-block/lib/qa_howto_square2_ff.cc35
-rw-r--r--gr-howto-write-a-block/lib/qa_howto_square2_ff.h39
-rw-r--r--gr-howto-write-a-block/lib/qa_howto_square_ff.cc35
-rw-r--r--gr-howto-write-a-block/lib/qa_howto_square_ff.h39
-rw-r--r--gr-howto-write-a-block/lib/test_all.cc38
-rw-r--r--gr-howto-write-a-block/limbo/doc/.gitignore18
-rw-r--r--gr-howto-write-a-block/limbo/doc/Makefile.am81
-rw-r--r--gr-howto-write-a-block/limbo/doc/README1
-rw-r--r--gr-howto-write-a-block/limbo/doc/howto-write-a-block.xml959
-rw-r--r--gr-howto-write-a-block/limbo/doc/howto_1.i29
-rwxr-xr-xgr-howto-write-a-block/limbo/doc/make_numbered_listing.py45
-rwxr-xr-xgr-howto-write-a-block/limbo/doc/qa_howto_1.py27
-rw-r--r--gr-howto-write-a-block/limbo/doc/src_lib_Makefile_1.am25
-rw-r--r--gr-howto-write-a-block/limbo/doc/src_lib_Makefile_2.am86
-rw-r--r--gr-howto-write-a-block/python/Makefile.am11
-rw-r--r--gr-howto-write-a-block/python/__init__.py49
-rwxr-xr-xgr-howto-write-a-block/python/qa_howto.py6
-rw-r--r--gr-howto-write-a-block/swig/.gitignore4
-rw-r--r--gr-howto-write-a-block/swig/Makefile.am3
-rw-r--r--gr-howto-write-a-block/swig/Makefile.swig.gen22
38 files changed, 996 insertions, 1308 deletions
diff --git a/gr-howto-write-a-block/Makefile.am b/gr-howto-write-a-block/Makefile.am
index ce2e4e8ca..98368c211 100644
--- a/gr-howto-write-a-block/Makefile.am
+++ b/gr-howto-write-a-block/Makefile.am
@@ -29,9 +29,11 @@ EXTRA_DIST = \
config.h.in \
Makefile.swig \
Makefile.swig.gen.t \
- version.sh
+ version.sh \
+ README \
+ README.hacking
-SUBDIRS = config lib swig python
+SUBDIRS = config lib swig python grc apps
pkgconfigdir = $(libdir)/pkgconfig
pkgconfig_DATA =
diff --git a/gr-howto-write-a-block/Makefile.common b/gr-howto-write-a-block/Makefile.common
index 4b8081125..c81bc780d 100644
--- a/gr-howto-write-a-block/Makefile.common
+++ b/gr-howto-write-a-block/Makefile.common
@@ -50,6 +50,9 @@ swigincludedir = $(grincludedir)/swig
grpythondir = $(pythondir)/gnuradio
grpyexecdir = $(pyexecdir)/gnuradio
+# Data directory for grc block wrappers
+grc_blocksdir = $(prefix)/share/gnuradio/grc/blocks
+
# Don't assume that make predefines $(RM), because BSD make does
# not. We define it now in configure.ac using AM_PATH_PROG, but now
# here have to add a -f to be like GNU make.
diff --git a/gr-howto-write-a-block/README b/gr-howto-write-a-block/README
index 29c1e99b1..368e71994 100644
--- a/gr-howto-write-a-block/README
+++ b/gr-howto-write-a-block/README
@@ -1,5 +1,5 @@
#
-# Copyright 2005, 2006 Free Software Foundation, Inc.
+# Copyright 2005,2006,2009 Free Software Foundation, Inc.
#
# This file is part of GNU Radio
#
@@ -27,7 +27,8 @@ rest of GNU Radio in order to avoid problems for people who have begun
to write blocks with a modified copy of gr-howto-write-a-block.
This package requires that gnuradio-core is already installed. It
-also depends on some GNU Radio prerequisites, such as boost.
+also depends on some GNU Radio prerequisites, such as Boost and
+cppunit.
To build the examples from the tarball use the normal recipe:
@@ -35,16 +36,10 @@ To build the examples from the tarball use the normal recipe:
$ make
$ make check
-If you're building from CVS, you'll need to use this sequence, since
-CVS doesn't contain configure or the generated Makefiles.
+If you're building from git, you'll need to use this sequence, since
+git doesn't contain configure or the generated Makefiles.
$ ./bootstrap
$ ./configure
$ make
$ make check
-
-
-The doc directory is not built by default. This is to avoid spurious
-build problems on systems that don't have xmlto installed. If you
-have xmlto and its dependencies installed, you can build the html
-version of the howto article by cd'ing to doc and invoking make.
diff --git a/gr-howto-write-a-block/README.hacking b/gr-howto-write-a-block/README.hacking
new file mode 100644
index 000000000..c670fd19e
--- /dev/null
+++ b/gr-howto-write-a-block/README.hacking
@@ -0,0 +1,95 @@
+#
+# Copyright 2009 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 layout of this tree is as follows. The top-level directory contains
+the autoconf/automake build definition files:
+
+bootstrap
+config.guess
+config.sub
+configure.ac
+Makefile.am
+Makefile.common
+Makefile.swig
+Makefile.swig.gen.t
+version.sh
+
+Of these files, only configure.ac, Makefile.am, and Makefile.common would
+likely need changing in order to customize this into a new out-of-tree
+project.
+
+Subdirectory Layout
+-------------------
+
+config - autoconf configuration macros
+lib - GNU Radio blocks C++ API, shared lib and headers and QA code
+swig - Generates Python API from C++ blocks
+python - Pure Python modules (hierarchical blocks, other classes)
+grc - GNU Radio Companion block wrappers
+apps - GRC applications, scripts, or other executables installed to bin
+
+The 'config' directory contains autoconf configuration files which help the
+configuration script discover various things about the software development
+environment during the execution of the 'configure' script. These files
+would likely not need any changing to customize this tree.
+
+The 'lib' directory contains those files needed to generate GNU Radio
+signal processing blocks. These take the form of a shared library that one
+dynamically links against, and header files that one would include in
+their C++ GNU Radio application. This directory also contains the framework
+for adding QA tests that are executed during 'make check' using the cppunit
+unit testing framework. The generated shared library is installed into
+$prefix/lib and the header files are installed into $prefix/include/gnuradio.
+
+Adding new blocks starts here, by adding new .cc and new .h files for each
+new block, and modifying Makefile.am to add them to the build and link. If
+desired, one can add unit tests to the QA framework that get executed during
+'make check'.
+
+The 'swig' directory contains the SWIG machinery to create a Python module
+that exports the C++ API into a Python namespace. Each GNU Radio block gets a
+.i file (using SWIG syntax). The master howto.i file must also have a line
+to include the block header file and a line to import the block .i file. The
+resulting _howto_swig.so and _howto_swig.py files are installed into the
+system Python lib directory under gnuradio/howto and become part of the
+gnuradio.howto Python namespace. The Makefile.am must be customized to
+recognize new files created here.
+
+The 'python' directory contains pure Python modules that get installed into
+the system Python lib directory under gnuradio/howto and the __init__.py
+module needed to turn the directory into the gnuradio.howto namespace.
+This is the appropriate place to put hierarchical blocks and utility classes.
+Be sure to edit the __init__.py to add your module/symbol imports as
+necessary, and to modify the Makefile.am accordingly.
+
+This directory also contains Python-based QA code, which is executed during
+'make check'.
+
+The 'grc' directory contains the XML-based wrappers that describe your blocks
+to the GNU Radio Companion graphical flowgraph editor. These get installed
+into the $prefix/share/gnuradio/grc/blocks directory and require modification
+of the Makefile.am to recognize new files put here. Note: GRC only scans the
+system directory for wrapper files, so you must do a 'make install' before
+GRC will see your new files or modifications to existing ones.
+
+The 'apps' directory contains those Python and C++ programs which are to be
+installed into the system $prefix/bin directory. (FIXME: there is not
+currently an example of building a C++ binary in this directory.)
diff --git a/gr-howto-write-a-block/apps/.gitignore b/gr-howto-write-a-block/apps/.gitignore
new file mode 100644
index 000000000..b336cc7ce
--- /dev/null
+++ b/gr-howto-write-a-block/apps/.gitignore
@@ -0,0 +1,2 @@
+/Makefile
+/Makefile.in
diff --git a/gr-howto-write-a-block/apps/Makefile.am b/gr-howto-write-a-block/apps/Makefile.am
new file mode 100644
index 000000000..85ed222cf
--- /dev/null
+++ b/gr-howto-write-a-block/apps/Makefile.am
@@ -0,0 +1,32 @@
+#
+# Copyright 2009 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
+
+if PYTHON
+
+dist_bin_SCRIPTS = \
+ howto_square.py
+
+EXTRA_DIST = \
+ howto_square.grc
+
+endif
diff --git a/gr-howto-write-a-block/apps/howto_square.grc b/gr-howto-write-a-block/apps/howto_square.grc
new file mode 100644
index 000000000..a8563698b
--- /dev/null
+++ b/gr-howto-write-a-block/apps/howto_square.grc
@@ -0,0 +1,325 @@
+<?xml version='1.0' encoding='ASCII'?>
+<flow_graph>
+ <timestamp>Thu Nov 12 11:26:07 2009</timestamp>
+ <block>
+ <key>options</key>
+ <param>
+ <key>id</key>
+ <value>howto_square</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>title</key>
+ <value></value>
+ </param>
+ <param>
+ <key>author</key>
+ <value></value>
+ </param>
+ <param>
+ <key>description</key>
+ <value></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>run_options</key>
+ <value>prompt</value>
+ </param>
+ <param>
+ <key>run</key>
+ <value>True</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>variable</key>
+ <param>
+ <key>id</key>
+ <value>samp_rate</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>value</key>
+ <value>10e3</value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(10, 170)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>wxgui_scopesink2</key>
+ <param>
+ <key>id</key>
+ <value>sink</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>type</key>
+ <value>float</value>
+ </param>
+ <param>
+ <key>title</key>
+ <value>Input</value>
+ </param>
+ <param>
+ <key>samp_rate</key>
+ <value>samp_rate</value>
+ </param>
+ <param>
+ <key>v_scale</key>
+ <value>20</value>
+ </param>
+ <param>
+ <key>v_offset</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>t_scale</key>
+ <value>0.002</value>
+ </param>
+ <param>
+ <key>ac_couple</key>
+ <value>False</value>
+ </param>
+ <param>
+ <key>xy_mode</key>
+ <value>False</value>
+ </param>
+ <param>
+ <key>num_inputs</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>win_size</key>
+ <value></value>
+ </param>
+ <param>
+ <key>grid_pos</key>
+ <value></value>
+ </param>
+ <param>
+ <key>notebook</key>
+ <value></value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(691, 222)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>howto_square_ff</key>
+ <param>
+ <key>id</key>
+ <value>sqr</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(709, 344)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>gr_throttle</key>
+ <param>
+ <key>id</key>
+ <value>thr</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>type</key>
+ <value>float</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>(497, 340)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>gr_vector_source_x</key>
+ <param>
+ <key>id</key>
+ <value>src</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>type</key>
+ <value>float</value>
+ </param>
+ <param>
+ <key>vector</key>
+ <value>[float(n)-50 for n in range(100)]</value>
+ </param>
+ <param>
+ <key>repeat</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>vlen</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(246, 332)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>wxgui_scopesink2</key>
+ <param>
+ <key>id</key>
+ <value>sink2</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>type</key>
+ <value>float</value>
+ </param>
+ <param>
+ <key>title</key>
+ <value>Output</value>
+ </param>
+ <param>
+ <key>samp_rate</key>
+ <value>samp_rate</value>
+ </param>
+ <param>
+ <key>v_scale</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>v_offset</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>t_scale</key>
+ <value>0.002</value>
+ </param>
+ <param>
+ <key>ac_couple</key>
+ <value>False</value>
+ </param>
+ <param>
+ <key>xy_mode</key>
+ <value>False</value>
+ </param>
+ <param>
+ <key>num_inputs</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>win_size</key>
+ <value></value>
+ </param>
+ <param>
+ <key>grid_pos</key>
+ <value></value>
+ </param>
+ <param>
+ <key>notebook</key>
+ <value></value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(869, 324)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <connection>
+ <source_block_id>thr</source_block_id>
+ <sink_block_id>sqr</sink_block_id>
+ <source_key>0</source_key>
+ <sink_key>0</sink_key>
+ </connection>
+ <connection>
+ <source_block_id>src</source_block_id>
+ <sink_block_id>thr</sink_block_id>
+ <source_key>0</source_key>
+ <sink_key>0</sink_key>
+ </connection>
+ <connection>
+ <source_block_id>thr</source_block_id>
+ <sink_block_id>sink</sink_block_id>
+ <source_key>0</source_key>
+ <sink_key>0</sink_key>
+ </connection>
+ <connection>
+ <source_block_id>sqr</source_block_id>
+ <sink_block_id>sink2</sink_block_id>
+ <source_key>0</source_key>
+ <sink_key>0</sink_key>
+ </connection>
+</flow_graph>
diff --git a/gr-howto-write-a-block/apps/howto_square.py b/gr-howto-write-a-block/apps/howto_square.py
new file mode 100755
index 000000000..8d3d870d8
--- /dev/null
+++ b/gr-howto-write-a-block/apps/howto_square.py
@@ -0,0 +1,77 @@
+#!/usr/bin/env python
+##################################################
+# Gnuradio Python Flow Graph
+# Title: Howto Square
+# Generated: Thu Nov 12 11:26:07 2009
+##################################################
+
+from gnuradio import eng_notation
+from gnuradio import gr
+from gnuradio import howto
+from gnuradio.eng_option import eng_option
+from gnuradio.gr import firdes
+from gnuradio.wxgui import scopesink2
+from grc_gnuradio import wxgui as grc_wxgui
+from optparse import OptionParser
+import wx
+
+class howto_square(grc_wxgui.top_block_gui):
+
+ def __init__(self):
+ grc_wxgui.top_block_gui.__init__(self, title="Howto Square")
+
+ ##################################################
+ # Variables
+ ##################################################
+ self.samp_rate = samp_rate = 10e3
+
+ ##################################################
+ # Blocks
+ ##################################################
+ self.sink = scopesink2.scope_sink_f(
+ self.GetWin(),
+ title="Input",
+ sample_rate=samp_rate,
+ v_scale=20,
+ v_offset=0,
+ t_scale=0.002,
+ ac_couple=False,
+ xy_mode=False,
+ num_inputs=1,
+ )
+ self.Add(self.sink.win)
+ self.sink2 = scopesink2.scope_sink_f(
+ self.GetWin(),
+ title="Output",
+ sample_rate=samp_rate,
+ v_scale=0,
+ v_offset=0,
+ t_scale=0.002,
+ ac_couple=False,
+ xy_mode=False,
+ num_inputs=1,
+ )
+ self.Add(self.sink2.win)
+ self.sqr = howto.square_ff()
+ self.src = gr.vector_source_f(([float(n)-50 for n in range(100)]), True, 1)
+ self.thr = gr.throttle(gr.sizeof_float*1, samp_rate)
+
+ ##################################################
+ # Connections
+ ##################################################
+ self.connect((self.thr, 0), (self.sqr, 0))
+ self.connect((self.src, 0), (self.thr, 0))
+ self.connect((self.thr, 0), (self.sink, 0))
+ self.connect((self.sqr, 0), (self.sink2, 0))
+
+ def set_samp_rate(self, samp_rate):
+ self.samp_rate = samp_rate
+ self.sink.set_sample_rate(self.samp_rate)
+ self.sink2.set_sample_rate(self.samp_rate)
+
+if __name__ == '__main__':
+ parser = OptionParser(option_class=eng_option, usage="%prog: [options]")
+ (options, args) = parser.parse_args()
+ tb = howto_square()
+ tb.Run(True)
+
diff --git a/gr-howto-write-a-block/config/gr_standalone.m4 b/gr-howto-write-a-block/config/gr_standalone.m4
index 593583e2d..3f8ddf1d6 100644
--- a/gr-howto-write-a-block/config/gr_standalone.m4
+++ b/gr-howto-write-a-block/config/gr_standalone.m4
@@ -124,4 +124,12 @@ m4_define([GR_STANDALONE],
[enable_python=yes]
)
AM_CONDITIONAL([PYTHON], [test x$enable_python = xyes])
+
+ dnl Define where to look for cppunit includes and libs
+ dnl sets CPPUNIT_CFLAGS and CPPUNIT_LIBS
+ dnl Try using pkg-config first, then fall back to cppunit-config.
+ PKG_CHECK_EXISTS(cppunit,
+ [PKG_CHECK_MODULES(CPPUNIT, cppunit >= 1.9.14)],
+ [AM_PATH_CPPUNIT([1.9.14],[],
+ [AC_MSG_ERROR([GNU Radio requires cppunit. Stop])])])
])
diff --git a/gr-howto-write-a-block/configure.ac b/gr-howto-write-a-block/configure.ac
index 8241f7ec1..52c4639bb 100644
--- a/gr-howto-write-a-block/configure.ac
+++ b/gr-howto-write-a-block/configure.ac
@@ -71,7 +71,9 @@ dnl AX_BOOST_WSERIALIZATION
AC_CONFIG_FILES([\
Makefile \
+ apps/Makefile \
config/Makefile \
+ grc/Makefile \
lib/Makefile \
python/Makefile \
python/run_tests \
diff --git a/gr-howto-write-a-block/grc/.gitignore b/gr-howto-write-a-block/grc/.gitignore
new file mode 100644
index 000000000..b336cc7ce
--- /dev/null
+++ b/gr-howto-write-a-block/grc/.gitignore
@@ -0,0 +1,2 @@
+/Makefile
+/Makefile.in
diff --git a/gr-howto-write-a-block/grc/Makefile.am b/gr-howto-write-a-block/grc/Makefile.am
new file mode 100644
index 000000000..32dcf1b9e
--- /dev/null
+++ b/gr-howto-write-a-block/grc/Makefile.am
@@ -0,0 +1,29 @@
+#
+# Copyright 2009 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
+
+grcblocksdir = $(grc_blocksdir)
+
+dist_grcblocks_DATA = \
+ howto_square_ff.xml \
+ howto_square2_ff.xml
+
diff --git a/gr-howto-write-a-block/grc/howto_square2_ff.xml b/gr-howto-write-a-block/grc/howto_square2_ff.xml
new file mode 100644
index 000000000..2b46106e8
--- /dev/null
+++ b/gr-howto-write-a-block/grc/howto_square2_ff.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0"?>
+<block>
+ <name>Square2</name>
+ <key>howto_square2_ff</key>
+ <category>HOWTO</category>
+ <import>from gnuradio import howto</import>
+ <make>howto.square2_ff()</make>
+
+ <sink>
+ <name>in</name>
+ <type>float</type>
+ </sink>
+
+ <source>
+ <name>out</name>
+ <type>float</type>
+ </source>
+</block>
diff --git a/gr-howto-write-a-block/grc/howto_square_ff.xml b/gr-howto-write-a-block/grc/howto_square_ff.xml
new file mode 100644
index 000000000..ed318bfc6
--- /dev/null
+++ b/gr-howto-write-a-block/grc/howto_square_ff.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0"?>
+<block>
+ <name>Square</name>
+ <key>howto_square_ff</key>
+ <category>HOWTO</category>
+ <import>from gnuradio import howto</import>
+ <make>howto.square_ff()</make>
+
+ <sink>
+ <name>in</name>
+ <type>float</type>
+ </sink>
+
+ <source>
+ <name>out</name>
+ <type>float</type>
+ </source>
+</block>
diff --git a/gr-howto-write-a-block/lib/.gitignore b/gr-howto-write-a-block/lib/.gitignore
index d957a6821..b1e56d39e 100644
--- a/gr-howto-write-a-block/lib/.gitignore
+++ b/gr-howto-write-a-block/lib/.gitignore
@@ -9,3 +9,4 @@
/*.pyc
/howto.cc
/howto.py
+/test_all \ No newline at end of file
diff --git a/gr-howto-write-a-block/lib/Makefile.am b/gr-howto-write-a-block/lib/Makefile.am
index e553c193d..336cb8a20 100644
--- a/gr-howto-write-a-block/lib/Makefile.am
+++ b/gr-howto-write-a-block/lib/Makefile.am
@@ -21,8 +21,12 @@
include $(top_srcdir)/Makefile.common
-###################################
-# howto C++ library
+# list of programs run by "make check" and "make distcheck"
+TESTS = test_all
+
+# ----------------------------------------------------------------
+# howto C++ library: libgnuradio-howto.so
+# ----------------------------------------------------------------
# C/C++ headers get installed in ${prefix}/include/gnuradio
grinclude_HEADERS = \
@@ -40,3 +44,37 @@ libgnuradio_howto_la_LIBADD = \
libgnuradio_howto_la_LDFLAGS = \
$(NO_UNDEFINED)
+
+# ----------------------------------------------------------------
+# howto C++ QA library: libgnuradio-howto-qa.so (not installed)
+# ----------------------------------------------------------------
+
+noinst_LTLIBRARIES = libgnuradio-howto-qa.la
+
+libgnuradio_howto_qa_la_SOURCES = \
+ qa_howto.cc \
+ qa_howto_square_ff.cc \
+ qa_howto_square2_ff.cc
+
+libgnuradio_howto_qa_la_LDFLAGS = $(NO_UNDEFINED) -version-info 0:0:0
+
+libgnuradio_howto_qa_la_LIBADD = \
+ libgnuradio-howto.la \
+ $(CPPUNIT_LIBS)
+
+# ----------------------------------------------------------------
+# headers that don't get installed
+# ----------------------------------------------------------------
+noinst_HEADERS = \
+ qa_howto.h \
+ qa_howto_square_ff.h \
+ qa_howto_square2_ff.h
+
+# ----------------------------------------------------------------
+# test program
+# ----------------------------------------------------------------
+noinst_PROGRAMS = \
+ test_all
+
+test_all_SOURCES = test_all.cc
+test_all_LDADD = libgnuradio-howto-qa.la
diff --git a/gr-howto-write-a-block/lib/qa_howto.cc b/gr-howto-write-a-block/lib/qa_howto.cc
new file mode 100644
index 000000000..f1411a388
--- /dev/null
+++ b/gr-howto-write-a-block/lib/qa_howto.cc
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2009 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.
+ */
+
+/*
+ * This class gathers together all the test cases for the example
+ * directory into a single test suite. As you create new test cases,
+ * add them here.
+ */
+
+#include <qa_howto.h>
+#include <qa_howto_square_ff.h>
+#include <qa_howto_square2_ff.h>
+
+CppUnit::TestSuite *
+qa_howto::suite()
+{
+ CppUnit::TestSuite *s = new CppUnit::TestSuite("howto");
+
+ s->addTest(qa_howto_square_ff::suite());
+ s->addTest(qa_howto_square2_ff::suite());
+
+ return s;
+}
diff --git a/gr-howto-write-a-block/lib/qa_howto.h b/gr-howto-write-a-block/lib/qa_howto.h
new file mode 100644
index 000000000..fa5a42fd3
--- /dev/null
+++ b/gr-howto-write-a-block/lib/qa_howto.h
@@ -0,0 +1,36 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2009 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 Example 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 Example Public License for more details.
+ *
+ * You should have received a copy of the GNU Example 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_QA_HOWTO_H
+#define INCLUDED_QA_HOWTO_H
+
+#include <cppunit/TestSuite.h>
+
+//! collect all the tests for the example directory
+
+class qa_howto {
+ public:
+ //! return suite of tests for all of example directory
+ static CppUnit::TestSuite *suite ();
+};
+
+#endif /* INCLUDED_QA_HOWTO_H */
diff --git a/gr-howto-write-a-block/lib/qa_howto_square2_ff.cc b/gr-howto-write-a-block/lib/qa_howto_square2_ff.cc
new file mode 100644
index 000000000..a37465104
--- /dev/null
+++ b/gr-howto-write-a-block/lib/qa_howto_square2_ff.cc
@@ -0,0 +1,35 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2009 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.
+ */
+
+#include <qa_howto_square2_ff.h>
+#include <cppunit/TestAssert.h>
+
+void
+qa_howto_square2_ff::t1()
+{
+ // Insert CPPUNIT tests/asserts here
+}
+
+void
+qa_howto_square2_ff::t2()
+{
+ // Insert CPPUNIT tests/asserts here
+}
diff --git a/gr-howto-write-a-block/lib/qa_howto_square2_ff.h b/gr-howto-write-a-block/lib/qa_howto_square2_ff.h
new file mode 100644
index 000000000..c74d0866f
--- /dev/null
+++ b/gr-howto-write-a-block/lib/qa_howto_square2_ff.h
@@ -0,0 +1,39 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2009 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_QA_HOWTO_SQUARE2_FF_H
+#define INCLUDED_QA_HOWTO_SQUARE2_FF_H
+
+#include <cppunit/extensions/HelperMacros.h>
+#include <cppunit/TestCase.h>
+
+class qa_howto_square2_ff : public CppUnit::TestCase {
+
+ CPPUNIT_TEST_SUITE (qa_howto_square2_ff);
+ CPPUNIT_TEST (t1);
+ CPPUNIT_TEST (t2);
+ CPPUNIT_TEST_SUITE_END ();
+
+ private:
+ void t1 ();
+ void t2 ();
+};
+
+#endif /* INCLUDED_QA_HOWTO_SQUARE2_FF_H */
diff --git a/gr-howto-write-a-block/lib/qa_howto_square_ff.cc b/gr-howto-write-a-block/lib/qa_howto_square_ff.cc
new file mode 100644
index 000000000..2f0b59773
--- /dev/null
+++ b/gr-howto-write-a-block/lib/qa_howto_square_ff.cc
@@ -0,0 +1,35 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2009 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.
+ */
+
+#include <qa_howto_square_ff.h>
+#include <cppunit/TestAssert.h>
+
+void
+qa_howto_square_ff::t1()
+{
+ // Insert CPPUNIT tests/asserts here
+}
+
+void
+qa_howto_square_ff::t2()
+{
+ // Insert CPPUNIT tests/asserts here
+}
diff --git a/gr-howto-write-a-block/lib/qa_howto_square_ff.h b/gr-howto-write-a-block/lib/qa_howto_square_ff.h
new file mode 100644
index 000000000..1b7c5e99f
--- /dev/null
+++ b/gr-howto-write-a-block/lib/qa_howto_square_ff.h
@@ -0,0 +1,39 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2009 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_QA_HOWTO_SQUARE_FF_H
+#define INCLUDED_QA_HOWTO_SQUARE_FF_H
+
+#include <cppunit/extensions/HelperMacros.h>
+#include <cppunit/TestCase.h>
+
+class qa_howto_square_ff : public CppUnit::TestCase {
+
+ CPPUNIT_TEST_SUITE (qa_howto_square_ff);
+ CPPUNIT_TEST (t1);
+ CPPUNIT_TEST (t2);
+ CPPUNIT_TEST_SUITE_END ();
+
+ private:
+ void t1 ();
+ void t2 ();
+};
+
+#endif /* INCLUDED_QA_HOWTO_SQUARE_FF_H */
diff --git a/gr-howto-write-a-block/lib/test_all.cc b/gr-howto-write-a-block/lib/test_all.cc
new file mode 100644
index 000000000..192c537bc
--- /dev/null
+++ b/gr-howto-write-a-block/lib/test_all.cc
@@ -0,0 +1,38 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2009 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 <cppunit/TextTestRunner.h>
+
+#include <qa_howto.h>
+
+int
+main (int argc, char **argv)
+{
+
+ CppUnit::TextTestRunner runner;
+
+ runner.addTest(qa_howto::suite ());
+
+ bool was_successful = runner.run("", false);
+
+ return was_successful ? 0 : 1;
+}
diff --git a/gr-howto-write-a-block/limbo/doc/.gitignore b/gr-howto-write-a-block/limbo/doc/.gitignore
deleted file mode 100644
index f65ab6cf7..000000000
--- a/gr-howto-write-a-block/limbo/doc/.gitignore
+++ /dev/null
@@ -1,18 +0,0 @@
-/Makefile
-/Makefile.in
-/.deps
-/.libs
-/*.la
-/*.lo
-/autom4te.cache
-/*.cache
-/howto-write-a-block.html
-/gr_block.h.xml
-/howto_1.i.xml
-/howto_square_ff.cc.xml
-/howto_square_ff.h.xml
-/qa_howto_1.py.xml
-/src_lib_Makefile_1.am.xml
-/src_lib_Makefile_2.am.xml
-/howto_square2_ff.cc.xml
-/howto_square2_ff.h.xml
diff --git a/gr-howto-write-a-block/limbo/doc/Makefile.am b/gr-howto-write-a-block/limbo/doc/Makefile.am
deleted file mode 100644
index 5f58a21e9..000000000
--- a/gr-howto-write-a-block/limbo/doc/Makefile.am
+++ /dev/null
@@ -1,81 +0,0 @@
-#
-# Copyright 2004,2005,2007 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.
-#
-
-TARGETS = howto-write-a-block.html
-
-# To avoid build problems for folks who don't have xmlto installed, we
-# don't build the docs by default.
-
-# html: $(TARGETS)
-all: $(TARGETS)
-
-
-EXTRA_DIST = \
- README \
- howto-write-a-block.xml \
- howto_1.i \
- make_numbered_listing.py \
- qa_howto_1.py \
- src_lib_Makefile_1.am \
- src_lib_Makefile_2.am
-
-
-BUILT_XML_FILES = \
- gr_block.h.xml \
- howto_1.i.xml \
- howto_square_ff.cc.xml \
- howto_square_ff.h.xml \
- howto_square2_ff.cc.xml \
- howto_square2_ff.h.xml \
- qa_howto_1.py.xml \
- src_lib_Makefile_1.am.xml \
- src_lib_Makefile_2.am.xml
-
-
-howto-write-a-block.html : howto-write-a-block.xml $(BUILT_XML_FILES)
-
-
-gr_block.h.xml: $(GNURADIO_CORE_INCLUDEDIR)/gr_block.h make_numbered_listing.py
- $(PYTHON) ./make_numbered_listing.py $(GNURADIO_CORE_INCLUDEDIR)/gr_block.h
-
-howto_square_ff.cc.xml: $(top_srcdir)/src/lib/howto_square_ff.cc make_numbered_listing.py
- $(PYTHON) ./make_numbered_listing.py $(top_srcdir)/src/lib/howto_square_ff.cc
-
-howto_square_ff.h.xml: $(top_srcdir)/src/lib/howto_square_ff.h make_numbered_listing.py
- $(PYTHON) ./make_numbered_listing.py $(top_srcdir)/src/lib/howto_square_ff.h
-
-howto_square2_ff.cc.xml: $(top_srcdir)/src/lib/howto_square2_ff.cc make_numbered_listing.py
- $(PYTHON) ./make_numbered_listing.py $(top_srcdir)/src/lib/howto_square2_ff.cc
-
-howto_square2_ff.h.xml: $(top_srcdir)/src/lib/howto_square2_ff.h make_numbered_listing.py
- $(PYTHON) ./make_numbered_listing.py $(top_srcdir)/src/lib/howto_square2_ff.h
-
-
-# ----------------------------------------------------------------
-
-clean:
- -${RM} -f $(TARGETS) $(BUILT_XML_FILES)
-
-%.html : %.xml
- xmlto html-nochunks $<
-
-%.xml : % make_numbered_listing.py
- $(PYTHON) ./make_numbered_listing.py $<
diff --git a/gr-howto-write-a-block/limbo/doc/README b/gr-howto-write-a-block/limbo/doc/README
deleted file mode 100644
index ff3b75e57..000000000
--- a/gr-howto-write-a-block/limbo/doc/README
+++ /dev/null
@@ -1 +0,0 @@
-The contents of this directory are obsolete.
diff --git a/gr-howto-write-a-block/limbo/doc/howto-write-a-block.xml b/gr-howto-write-a-block/limbo/doc/howto-write-a-block.xml
deleted file mode 100644
index f8027b456..000000000
--- a/gr-howto-write-a-block/limbo/doc/howto-write-a-block.xml
+++ /dev/null
@@ -1,959 +0,0 @@
-<?xml version="1.0" encoding="ISO-8859-1"?>
-<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
- "docbookx.dtd" [
- <!ENTITY gnuradio "<application>GNU Radio</application>">
- <!ENTITY SWIG "<application>SWIG</application>">
- <!ENTITY gr_block "<classname>gr_block</classname>">
- <!ENTITY square "<classname>howto_square_ff</classname>">
-
- <!ENTITY were "we&apos;re">
- <!ENTITY well "we&apos;ll">
- <!ENTITY thats "that&apos;s">
- <!ENTITY its "it&apos;s">
- <!ENTITY lets "let&apos;s">
- <!ENTITY youre "you&apos;re">
-
- <!ENTITY gr_block_listing SYSTEM "gr_block.h.xml">
- <!ENTITY qa_howto_1_listing SYSTEM "qa_howto_1.py.xml">
- <!ENTITY howto_square_ff_h_listing SYSTEM "howto_square_ff.h.xml">
- <!ENTITY howto_square_ff_cc_listing SYSTEM "howto_square_ff.cc.xml">
- <!ENTITY howto_square2_ff_h_listing SYSTEM "howto_square2_ff.h.xml">
- <!ENTITY howto_square2_ff_cc_listing SYSTEM "howto_square2_ff.cc.xml">
- <!ENTITY howto_1_i_listing SYSTEM "howto_1.i.xml">
- <!ENTITY src_lib_Makefile_1_am_listing SYSTEM "src_lib_Makefile_1.am.xml">
- <!ENTITY src_lib_Makefile_2_am_listing SYSTEM "src_lib_Makefile_2.am.xml">
-
-]>
-
-<article>
-
-<articleinfo>
-<title>How to Write a Signal Processing Block</title>
-<author>
- <firstname>Eric</firstname>
- <surname>Blossom</surname>
- <affiliation>
- <address>
- <email>eb@comsec.com</email>
- </address>
- </affiliation>
-</author>
-
-<revhistory>
- <revision>
- <revnumber>0.1</revnumber>
- <date>2005-01-20</date>
- </revision>
- <revision>
- <revnumber>0.2</revnumber>
- <date>2005-02-02</date>
- <revremark>Updated for SWIG 1.3.24</revremark>
- </revision>
- <revision>
- <revnumber>0.3</revnumber>
- <date>2006-07-21</date>
- <revremark>Clarification of 1:1 fixed rate vs item size</revremark>
- </revision>
-</revhistory>
-
-<copyright>
- <year>2004</year>
- <year>2005</year>
- <holder>Free Software Foundation, Inc.</holder>
-</copyright>
-
-<abstract><para>This article explains how to write signal
-processing blocks for <application>GNU Radio</application>.
-</para></abstract>
-
-</articleinfo>
-
-<sect1 id="prereqs"><title>Prerequisites</title>
-<para>This article assumes that the reader has basic familiarity with
-GNU Radio and has read and understood
-<ulink url="http://www.gnu.org/software/gnuradio/doc/exploring-gnuradio.html">
-<citetitle>Exploring GNU Radio</citetitle></ulink>.
-</para>
-
-<para>There is a tarball of files that accompany this article. It
-includes the examples, DocBook source for the article and all the
-Makefiles etc it takes to make it work. Grab it at <ulink
-url="ftp://ftp.gnu.org/gnu/gnuradio">
-ftp://ftp.gnu.org/gnu/gnuradio</ulink> or one of the mirrors. The
-file you want is
-<filename>gr-howto-write-a-block-X.Y.tar.gz</filename>. Pick the one
-with the highest version number.
-See <ulink url="http://comsec.com/wiki?CvsAccess">
-http://comsec.com/wiki?CvsAccess</ulink> for CVS Access.
-</para>
-
-
-</sect1>
-
-<sect1 id="intro"><title>Introduction</title>
-<para>&gnuradio; provides a framework for building software radios.
-Waveforms -- signal processing applications -- are built using a
-combination of Python code for high level organization, policy, GUI and
-other non performance-critical functions, while performance critical
-signal processing blocks are written in C++.</para>
-
-<para>From the Python point of view, &gnuradio; provides a data flow
-abstraction. The fundamental concepts are signal processing
-blocks and the connections between them. This abstraction is
-implemented by the Python <classname>gr.flow_graph</classname> class.
-Each block has a set of input ports and output ports. Each port has
-an associated data type. The most common port types are
-<classname>float</classname> and <classname>gr_complex</classname>
-(equivalent to std::complex&lt;float&gt;), though other types are used,
-including those representing structures, arrays or other types of
-packetized data.</para>
-
-<para>From the high level point-of-view, infinite streams of data flow
-through the ports. At the C++ level, streams are dealt with in
-convenient sized pieces, represented as contiguous arrays of the
-underlying type.</para>
-
-</sect1>
-
-<sect1 id="overview"><title>The View from 30,000 Feet</title>
-
-<para>This article will walk through the construction of several
-simple signal processing blocks, and explain the techniques and idioms
-used. Later sections cover debugging signal processing blocks in the
-mixed Python/C++ environment and performance measurement and
-optimization.</para>
-
-<para>The example blocks will be built in the style of all &gnuradio;
-extensions. That is, they are built outside of the gnuradio-core build
-tree, and are constructed as shared libraries that may be dynamically
-loaded into Python using the "import" mechanism. &SWIG;, the
-Simplified Wrapper and Interface Generator, is used to generate the
-glue that allows our code to be used from Python.</para>
-
-</sect1>
-
-
-<sect1 id="gr_block"><title></title>
-
-<para>The C++ class &gr_block; is the base of all signal processing
-blocks in &gnuradio;. Writing a new signal processing block involves
-creating 3 files: The .h and .cc files that define the new class and
-the .i file that tells &SWIG; how to generate the glue that binds the
-class into Python. The new class must derive from &gr_block; or
-one of it&apos;s subclasses.</para>
-
-<para>Our first examples will derive directly from &gr_block;. Later
-we will look at some other subclasses that simplify the process for
-common cases.</para>
-
-</sect1><!-- end gr_block sect1 -->
-
-
-
-<!-- ================================================================ -->
-
-<sect1 id="autotools"><title>Autotools, Makefiles, and Directory Layout</title>
-
-<para>Before we dive into the code, &lets; talk a bit about the
-overall build environment and the directory structure that &well;
-be using.</para>
-
-<para>To reduce the amount of Makefile hacking that we have to do, and
-to facilitate portability across a variety of systems, we use the GNU
-<application>autoconf</application>,
-<application>automake</application>, and
-<application>libtool</application> tools. These are collectively
-referred to as the autotools, and once you get over the initial
-shock, they will become your friends. (The good news is that we
-provide boilerplate that can be used pretty much as-is.)</para>
-
-<variablelist>
-
-<varlistentry><term>automake</term>
-
-<listitem><para>automake and configure work together to generate GNU
-compliant Makefiles from a much higher level description contained in
-the corresponding Makefile.am file. <filename>Makefile.am</filename>
-specifies the libraries and programs to build and the source files
-that compose each. Automake reads <filename>Makefile.am</filename>
-and produces <filename>Makefile.in</filename>. Configure reads
-<filename>Makefile.in</filename> and produces
-<filename>Makefile</filename>. The resulting Makefile contains a
-zillion rules that do the right right thing to build, check and
-install your code. It is not uncommon for the the resulting
-<filename>Makefile</filename> to be 5 or 6 times larger than
-<filename>Makefile.am</filename>.</para>
-
-</listitem>
-</varlistentry>
-
-<varlistentry><term>autoconf</term>
-<listitem><para>autoconf reads <filename>configure.ac</filename>
-and produces the <filename>configure</filename> shell
-script. <filename>configure</filename> automatically tests for
-features of the underlying system and sets a bunch of variables and
-defines that can be used in the Makefiles and your C++ code to
-conditionalize the build. If features are required but not found,
-configure will output an error message and stop.</para>
-</listitem>
-</varlistentry>
-
-<varlistentry><term>libtool</term>
-<listitem><para>libtool works behind the scenes and provides the magic
-to construct shared libraries on a wide variety of systems.</para>
-</listitem>
-</varlistentry>
-
-</variablelist>
-
-<para><xref linkend="dir-layout"/> shows the directory layout and
-common files &well; be using. After renaming the
-<replaceable>topdir</replaceable> directory, use it in your projects
-too. We'll talk about particular files as they come up later.</para>
-
-
-<table id="dir-layout"><title>Directory Layout</title>
-<tgroup cols="2">
-
-<thead><row>
-<entry>File/Dir Name</entry>
-<entry>Comment</entry>
-</row>
-</thead>
-
-<tbody>
-
-<row>
-<entry><replaceable>topdir</replaceable>/Makefile.am</entry>
-<entry>Top level Makefile.am</entry>
-</row>
-<row>
-<entry><replaceable>topdir</replaceable>/Makefile.common</entry>
-<entry>Common fragment included in sub-Makefiles</entry>
-</row>
-<row>
-<entry><replaceable>topdir</replaceable>/bootstrap</entry>
-<entry>Runs autoconf, automake, libtool first time through</entry>
-</row>
-<row>
-<entry><replaceable>topdir</replaceable>/config</entry>
-<entry>Directory of m4 macros used by configure.ac</entry>
-</row>
-<row>
-<entry><replaceable>topdir</replaceable>/configure.ac</entry>
-<entry>Input to autoconf</entry>
-</row>
-<row>
-<entry><replaceable>topdir</replaceable>/src</entry>
-</row>
-<row>
-<entry><replaceable>topdir</replaceable>/src/lib</entry>
-<entry>C++ code goes here</entry>
-</row>
-<row>
-<entry><replaceable>topdir</replaceable>/src/lib/Makefile.am</entry>
-</row>
-<row>
-<entry><replaceable>topdir</replaceable>/src/python</entry>
-<entry>Python code goes here</entry>
-</row>
-<row>
-<entry><replaceable>topdir</replaceable>/src/python/Makefile.am</entry>
-</row>
-<row>
-<entry><replaceable>topdir</replaceable>/src/python/run_tests</entry>
-<entry>Script to run tests in the build tree</entry>
-</row>
-
-</tbody>
-</tgroup>
-</table>
-
-</sect1>
-
-<!-- ================================================================ -->
-
-<sect1 id="naming"><title>Naming Conventions</title>
-
-<para>&gnuradio; uses a set of naming conventions to assist in
-comprehending the code base and gluing C++ and Python together.
-Please follow them.</para>
-
-<sect2 id="camel-case"><title><emphasis>Death to CamelCaseNames!</emphasis></title>
-
-<para>We've returned to a kinder, gentler era. We're now using the
-&quot;STL style&quot; naming convention with a couple of modifications
-since we're not using namespaces.</para>
-
-<para>With the exception of macros and other constant values, all
-identifiers shall be lower case with <literal>words_separated_like_this</literal>.</para>
-
-<para>Macros and constant values (e.g., enumerated values,
-<literal>static const int FOO = 23</literal>) shall be in <literal>UPPER_CASE</literal>.</para>
-
-</sect2>
-
-<sect2 id="global_names"><title>Global Names</title>
-
-<para>All globally visible names (types, functions, variables, consts, etc)
-shall begin with a "package prefix", followed by an underscore. The bulk of
-the code in GNU Radio belongs to the "gr" package, hence
-names look like <literal>gr_open_file (...)</literal>.</para>
-
-<para>Large coherent bodies of code may use other package prefixes, but
-let's try to keep them to a well thought out list. See the list
-below.</para>
-
-</sect2>
-
-<sect2 id="package_prefixes"><title>Package Prefixes</title>
-
-<para>These are the current package prefixes:
-
-<variablelist>
-
-<varlistentry><term>gr_</term>
-<listitem><para>Almost everything.</para></listitem>
-</varlistentry>
-
-<varlistentry><term>gri_</term>
-<listitem><para>
-Implementation primitives. Sometimes we
-have both a gr_<replaceable>foo</replaceable> and a gri_<replaceable>foo</replaceable>. In that case,
-gr_<replaceable>foo</replaceable> would be derived from gr_block and gri_<replaceable>foo</replaceable>
-would be the low level guts of the function.</para></listitem>
-</varlistentry>
-
-<varlistentry><term>atsc_</term>
-<listitem><para>Code related to the Advanced Television Standards Committee HDTV implementation
-</para></listitem>
-</varlistentry>
-
-<varlistentry><term>usrp_</term>
-<listitem><para>Universal Software Radio Peripheral.</para></listitem>
-</varlistentry>
-
-<varlistentry><term>qa_</term>
-<listitem><para>Quality Assurance (Test code.)</para></listitem>
-</varlistentry>
-
-</variablelist>
-
-</para>
-</sect2>
-
-<sect2 id="class-data-members"><title>Class Data Members (instance variables)</title>
-
-<para>All class data members shall begin with d_<replaceable>foo</replaceable>.</para>
-
-<para>The big win is when you're staring at a block of code it's obvious
-which of the things being assigned to persist outside of the block.
-This also keeps you from having to be creative with parameter names
-for methods and constructors. You just use the same name as the
-instance variable, without the d_. </para>
-
-<literallayout>
-class gr_wonderfulness {
- std::string d_name;
- double d_wonderfulness_factor;
-
-public:
- gr_wonderfulness (std::string name, double wonderfulness_factor)
- : d_name (name), d_wonderfulness_factor (wonderfulness_factor)
- {
- ...
- }
- ...
-};
-</literallayout>
-
-</sect2>
-
-<sect2 id="static-data-members"><title>Class Static Data Members (class variables)</title>
-
-<para>
-All class static data members shall begin with s_<replaceable>foo</replaceable>.
-</para>
-
-</sect2>
-
-<sect2 id="file-names"><title>File Names</title>
-
-<para>Each significant class shall be contained in its own file. The
-declaration of class <classname>gr_foo</classname> shall be in
-<filename>gr_foo.h</filename> and the definition in
-<filename>gr_foo.cc</filename>.</para>
-</sect2>
-
-
-<sect2><title>Suffixes</title>
-
-<para>By convention, we encode the input and output types of signal
-processing blocks in their name using suffixes. The suffix is
-typically one or two characters long. Source and sinks have single
-character suffixes. Regular blocks that have both inputs and outputs
-have two character suffixes. The first character indicates the type
-of the input streams, the second indicates the type of the output
-streams. FIR filter blocks have a three character suffix, indicating
-the type of the inputs, outputs and taps, respectively.</para>
-
-<para>These are the suffix characters and their interpretations:
-<itemizedlist>
-<listitem><para>f - single precision floating point</para></listitem>
-<listitem><para>c - complex&lt;float&gt;</para></listitem>
-<listitem><para>s - short (16-bit integer)</para></listitem>
-<listitem><para>i - integer (32-bit integer)</para></listitem>
-</itemizedlist>
-</para>
-
-<para>In addition, for those cases where the block deals with streams
-of vectors, we use the character 'v' as the first character of the
-suffix. An example of this usage is
-<classname>gr_fft_vcc</classname>. The FFT block takes a vector of
-complex numbers on its input and produces a vector of complex
-numbers on its output.</para>
-
-</sect2>
-
-</sect1>
-
-
-
-
-<sect1 id="square"><title>First Block: &square;</title>
-
-<para>For our first example &well; create a block that computes
-the square of its single float input. This block will accept a single
-float input stream and produce a single float output stream.</para>
-
-<para>Following the naming conventions, &well; use
-<literal>howto</literal> as our package prefix, and the block will
-be called <classname>howto_square_ff</classname>.</para>
-
-<para>We are going to arrange that this block, as well as the others
-that we write in this article, end up in the
-<literal>gnuradio.howto</literal> Python module. This will allow us
-to access it from Python like this:
-<programlisting>
-from gnuradio import howto
-sqr = howto.square_ff ()
-</programlisting>
-</para>
-
-
-<sect2 id="test_driven"><title>Test Driven Programming</title>
-
-<para>We could just start banging out the C++ code, but being highly
-evolved modern programmers, &were; going to write the test code first.
-After all, we do have a good spec for the behavior: take a single
-stream of floats as the input and produce a single stream of floats as
-the output. The output should be the square of the input.</para>
-
-<para>How hard could this be? Turns out that this is easy! Check out
-<xref linkend="qa_howto_1.py"/>.</para>
-
-<example id="qa_howto_1.py">
-<title><filename>qa_howto.py</filename> (first version)</title>
-&qa_howto_1_listing;
-</example>
-
-<para>
-<classname>gr_unittest</classname> is an extension to the standard
-python module <classname>unittest</classname>.
-<classname>gr_unittest</classname> adds support for checking
-approximate equality of tuples of float and complex numbers.
-Unittest uses Python&apos;s reflection mechanism to find all methods that start with
-<methodname>test_</methodname> and runs them. Unittest wraps each call
-to <methodname>test_*</methodname> with matching calls to
-<methodname>setUp</methodname> and <methodname>tearDown</methodname>.
-See the python <ulink url="http://docs.python.org/lib/module-unittest.html">
-unittest</ulink> documentation for details.
-</para>
-
-<para>When we run the test,
-gr_unittest.main is going to invoke
-<methodname>setUp</methodname>,
-<methodname>test_001_square_ff</methodname>, and
-<methodname>tearDown</methodname>.</para>
-<para>
-<methodname>test_001_square_ff</methodname> builds a small graph that
-contains three nodes. gr.vector_source_f(src_data) will source the
-elements of src_data and then say that &its; finished. howto.square_ff is the block
-&were; testing. gr.vector_sink_f gathers the output of
-howto.square_ff.</para>
-
-<para>The <methodname>run</methodname> method runs the graph until all
-the blocks indicate they are finished. Finally, we check that the
-result of executing square_ff on src_data matches what we expect.
-</para>
-
-</sect2>
-
-<sect2 id="build_vs_install"><title>Build Tree vs. Install Tree</title>
-
-<para>The build tree is everything from <replaceable>topdir</replaceable>
-(the one containing configure.ac) down. The path to the install tree is
-<filename>
-<replaceable>prefix</replaceable>/lib/python<replaceable>version</replaceable>/site-packages</filename>,
-where <replaceable>prefix</replaceable> is the <literal>--prefix</literal>
-argument to configure (default <filename>/usr/local</filename>) and
-<replaceable>version</replaceable> is the installed version of
-python. A typical value is
-<filename>/usr/local/lib/python2.3/site-packages</filename>.</para>
-
-
-<para>We normally set our PYTHONPATH environment variable to point at
-the install tree, and do this in <filename>~/.bash_profile</filename>
-or <filename>~/.profile</filename>.
-This allows our python apps to access all the standard python
-libraries, plus our locally installed stuff like GNU Radio.</para>
-
-<para>We write our applications such that they access the code and
-libraries in the install tree. On the other hand, we want our test
-code to run on the build tree, where we can detect problems before
-installation.</para>
-
-</sect2>
-
-<sect2 id="make_check"><title>make check</title>
-
-
-<para>We use <command>make check</command> to run our tests.
-Make check invokes the <command>run_tests</command> shell script which
-sets up the PYTHONPATH environment variable so that
-our tests use the build tree versions of our code and libraries.
-It then runs all files
-which have names of the form <filename>qa_*.py</filename> and reports
-the overall success or failure.</para>
-
-<para>There is quite a bit of behind-the-scenes action required to use
-the non-installed versions of our code (look at
-<filename>runtest</filename> for a cheap thrill.)</para>
-
-<para>Finally, running <command>make check</command> in the python
-directory produces this result:
-<literallayout>
- [eb@bufo python]$ make check
- make check-TESTS
- make[1]: Entering directory `/home/eb/gr-build/gr-howto-write-a-block/src/python'
- Traceback (most recent call last):
- File "./qa_howto.py", line 24, in ?
- import howto
- ImportError: No module named howto
- Traceback (most recent call last):
- File "./qa_howto_1.py", line 24, in ?
- import howto
- ImportError: No module named howto
- FAIL: run_tests
- ===================
- 1 of 1 tests failed
- ===================
- make[1]: *** [check-TESTS] Error 1
- make[1]: Leaving directory `/home/eb/gr-build/gr-howto-write-a-block/src/python'
- make: *** [check-am] Error 2
- [eb@bufo python]$
-</literallayout>
-Excellent! Our test failed, just as we expected. The ImportError
-indicates that it can't find the module named
-<classname>howto</classname>. No surprise, since we haven't written it yet.
-</para>
-
-</sect2>
-
-<sect2><title>The C++ code</title>
-<para>Now that we've got a test case written that successfully fails,
-let's write the C++ code. As we mentioned earlier, all signal
-processing blocks are derived from <classname>gr_block</classname> or
-one of its subclasses. Let's take a look at
-<xref linkend="gr_block.h"/>.</para>
-
-<example id="gr_block.h">
-<title><filename>gr_block.h</filename></title>
-&gr_block_listing;
-</example>
-
-<para>A quick scan of <filename>gr_block.h</filename> reveals that
-since <methodname>general_work</methodname> is pure virtual, we
-definitely need to override that.
-<methodname>general_work</methodname> is the method that does the
-actual signal processing. For our squaring example we'll
-need to override <methodname>general_work</methodname> and provide a
-constructor and destructor and a bit of stuff to take advantage of
-the <ulink url="http://www.boost.org">boost</ulink>
-<ulink url="http://www.boost.org/libs/smart_ptr/smart_ptr.htm">
-<classname>shared_ptr</classname>s.</ulink>
-
-</para>
-
-
-<para><xref linkend="howto_square_ff.h"/>
-and <xref linkend="howto_square_ff.cc"/> are the header and c++
-source.</para>
-
-<example id="howto_square_ff.h">
-<title><filename>howto_square_ff.h</filename></title>
-&howto_square_ff_h_listing;
-</example>
-
-<example id="howto_square_ff.cc">
-<title><filename>howto_square_ff.cc</filename></title>
-&howto_square_ff_cc_listing;
-</example>
-
-<para>Now we need a Makefile.am to get all this to build.
-<xref linkend="src_lib_Makefile_1"/>
-is enough to build a shared library from our source file. We'll be
-adding additional rules to use &SWIG; in just a bit. If you haven't
-already, this is a good time to browse all the Makefile.am&apos;s in
-the build tree and get an idea for how it all hangs together.</para>
-
-<example id="src_lib_Makefile_1">
-<title><filename>src/lib/Makefile.am</filename> (no &SWIG;)</title>
-&src_lib_Makefile_1_am_listing;
-</example>
-
-</sect2>
-
-
-<!-- ==============================
-
-<sect2 id="io_sig"><title><classname>gr_io_signature</classname></title>
-<para></para>
-</sect2>
-
-<sect2 id="forecast"><title><methodname>forecast</methodname></title>
-<para></para>
-</sect2>
-
-<sect2 id="output_multiple">
-<title><methodname>set_output_multiple</methodname></title>
-<para></para>
-</sect2>
-
- ============================== -->
-
-
-<sect2 id="swig"><title>The &SWIG; .i file</title>
-
-<para>Now that we've got something that will compile, we need to write
-the &SWIG; .i file. This is a pared-down version of the .h file, plus
-a bit of magic that has python work with the boost shared_ptr&apos;s.
-To reduce code bloat, we only declare methods that &well; want to
-access from Python.</para>
-
-<para>We&apos;re going to call the .i file
-<filename>howto.i</filename>, and use it to hold the &SWIG;
-declarations for all classes from <literal>howto</literal> that will
-be accessible from python. It&apos;s quite small:
-&howto_1_i_listing;
-</para>
-
-</sect2>
-
-<sect2><title>Putting it all together</title>
-<para>
-Now we need to modify <filename>src/lib/Makefile.am</filename>
-to run &SWIG; and to add the glue it generates to the shared library.</para>
-
-<example id="src_lib_Makefile_2">
-<title><filename>src/lib/Makefile.am</filename> (with &SWIG;)</title>
-&src_lib_Makefile_2_am_listing;
-</example>
-
-<para><command>make</command> now builds everything successfully. We get a
-few warnings, but &thats; OK.</para>
-
-<para>Changing directories back to the python directory we try
-<command>make check</command> again:
-<literallayout>
- [eb@bufo python]$ make check
- make check-TESTS
- make[1]: Entering directory `/home/eb/gr-build/gr-howto-write-a-block/src/python'
- .
- ----------------------------------------------------------------------
- Ran 1 test in 0.004s
-
- OK
- PASS: run_tests
- ==================
- All 1 tests passed
- ==================
- make[1]: Leaving directory `/home/eb/gr-build/gr-howto-write-a-block/src/python'
- [eb@bufo python]$
-</literallayout>
-<emphasis>Victory! Our new block works!</emphasis>
-</para>
-
-</sect2>
-
-</sect1><!-- end First Block: square -->
-
-<sect1 id="additional_methods"><title>Additional gr_block methods</title>
-
-<para>In our <classname>howto_square_ff</classname> example above, we only
-had to override the <methodname>general_work</methodname> method to
-accomplish our goal. <classname>gr_block</classname> provides a few other
-methods that are sometimes useful.</para>
-
-<sect2 id="forecast"><title>forecast</title>
-
-<para>Looking at <methodname>general_work</methodname> you may
-have wondered how the system knows how much data it needs to
-ensure is valid in each of the input arrays. The
-<methodname>forecast</methodname> method provides this
-information.</para>
-
-<para>The default implementation of <methodname>forecast</methodname>
-says there is a 1:1 relationship between noutput_items and the
-requirements for each input stream. The size of the items is defined by
-<classname>gr_io_signature</classname>s in the constructor of
-<classname>gr_block</classname>. The sizes of the input and output items
-can of course differ; this still qualifies as a 1:1 relationship.
-<programlisting>
- // default implementation: 1:1
-
- void
- gr_block::forecast (int noutput_items,
- gr_vector_int &amp;ninput_items_required)
- {
- unsigned ninputs = ninput_items_required.size ();
- for (unsigned i = 0; i &lt; ninputs; i++)
- ninput_items_required[i] = noutput_items;
- }
-</programlisting>
-</para>
-
-<para>Although the 1:1 implementation worked for howto_square_ff, it
-wouldn&apos;t be appropriate for interpolators, decimators, or blocks
-with a more complicated relationship between noutput_items and the
-input requirements. That said, by deriving your classes from
-<classname>gr_sync_block</classname>,
-<classname>gr_sync_interpolator</classname> or
-<classname>gr_sync_decimator</classname> instead of
-<classname>gr_block</classname>, you can often avoid
-implementing <methodname>forecast</methodname>.</para>
-
-</sect2>
-
-<sect2 id="set_output_multiple"><title>set_output_multiple</title>
-
-<para>When implementing your <methodname>general_work</methodname>
-routine, &its; occasionally convenient to have the run time system
-ensure that you are only asked to produce a number of output items
-that is a multiple of some particular value. This might occur if your
-algorithm naturally applies to a fixed sized block of data.
-Call <methodname>set_output_multiple</methodname> in your constructor
-to specify this requirement. The default output multiple is 1.</para>
-
-</sect2>
-
-</sect1>
-
-
-<sect1 id="common_patterns">
-<title>Subclasses for common patterns</title>
-
-<para><classname>gr_block</classname> allows tremendous flexibility
-with regard to the consumption of input streams and the production of
-output streams. Adroit use of <methodname>forecast</methodname> and
-<methodname>consume</methodname> allows variable rate blocks to be
-built. It is possible to construct blocks that consume data at
-different rates on each input, and produce output at a rate that
-is a function of the contents of the input data.</para>
-
-<para>On the other hand, it is very common for signal processing
-blocks to have a fixed relationship between the input rate and the
-output rate. Many are 1:1, while others have 1:N or N:1
-relationships.</para>
-
-<para>Another common requirement is the need to examine more than one
-input sample to produce a single output sample. This is orthogonal to
-the relationship between input and output rate. For example, a
-non-decimating, non-interpolating FIR filter needs to examine N input
-samples for each output sample it produces, where N is the number of
-taps in the filter. However, it only consumes a single input sample
-to produce a single output. We call this concept "history", but you
-could also think of it as "look-ahead".</para>
-
-<sect2 id="gr_sync_block"><title><classname>gr_sync_block</classname></title>
-
-<para>
-<ulink url="http://www.gnu.org/software/gnuradio/doc/classgr__sync__block.html">
-<classname>gr_sync_block</classname></ulink>
-is derived from
-<ulink url="http://www.gnu.org/software/gnuradio/doc/classgr__block.html">
-<classname>gr_block</classname></ulink>
-and implements a 1:1 block with
-optional history. Given that we know the input to output rate,
-certain simplifications are possible. From the implementor&apos;s
-point-of-view, the primary change is that we define a
-<methodname>work</methodname> method instead of
-<methodname>general_work</methodname>. <methodname>work</methodname>
-has a slightly different calling sequence;
-It omits the unnecessary ninput_items parameter, and arranges for
-<methodname>consume_each</methodname> to be called on our
-behalf.</para>
-<programlisting>
- /*!
- * \brief Just like gr_block::general_work, only this arranges to
- * call consume_each for you.
- *
- * The user must override work to define the signal processing code
- */
- virtual int work (int noutput_items,
- gr_vector_const_void_star &amp;input_items,
- gr_vector_void_star &amp;output_items) = 0;
-</programlisting>
-
-<para>This gives us fewer things to worry about, and less code to
-write. If the block requires history greater than 1, call
-<methodname>set_history</methodname> in the constructor, or any time
-the requirement changes.</para>
-
-<para><classname>gr_sync_block</classname> provides a
-version of <methodname>forecast</methodname> that handles the
-history requirement.</para>
-
-</sect2>
-
-<sect2 id="gr_sync_decimator"><title><classname>gr_sync_decimator</classname></title>
-
-<para>
-<ulink url="http://www.gnu.org/software/gnuradio/doc/classgr__sync__decimator.html">
-<classname>gr_sync_decimator</classname></ulink>
-is derived from
-<ulink url="http://www.gnu.org/software/gnuradio/doc/classgr__sync__block.html">
-<classname>gr_sync_block</classname></ulink>
-and implements a N:1 block with optional history.
-</para>
-
-</sect2>
-
-<sect2 id="gr_sync_interpolator"><title><classname>gr_sync_interpolator</classname></title>
-
-<para>
-<ulink url="http://www.gnu.org/software/gnuradio/doc/classgr__sync__interpolator.html">
-<classname>gr_sync_interpolator</classname></ulink>
-is derived from
-<ulink url="http://www.gnu.org/software/gnuradio/doc/classgr__sync__block.html">
-<classname>gr_sync_block</classname></ulink>
-and implements a 1:N block with optional history.
-</para>
-
-</sect2>
-
-
-</sect1>
-
-<sect1 id="square2">
-<title>Second Block: <classname>howto_square2_ff</classname></title>
-
-<para>Given that we now know about
-<classname>gr_sync_block</classname>, the way
-<classname>howto_square_ff</classname> should really be implemented is
-by subclassing <classname>gr_sync_block</classname>.</para>
-
-<para>Here are the revised sources: <xref
-linkend="howto_square2_ff.h"/>,
-<xref linkend="howto_square2_ff.cc"/>.
-The accompanying files contain the additional test code.
-</para>
-
-<example id="howto_square2_ff.h">
-<title><filename>howto_square2_ff.h</filename></title>
-&howto_square2_ff_h_listing;
-</example>
-
-<example id="howto_square2_ff.cc">
-<title><filename>howto_square2_ff.cc</filename></title>
-&howto_square2_ff_cc_listing;
-</example>
-
-</sect1>
-
-<sect1 id="where_to"><title>Where to from Here?</title>
-
-<para>At this point, we&apos;ve got a basic overview of how the system
-goes together. For more insight, I suggest that you look at the code
-of the system. The doxygen generated <ulink
-url="http://www.gnu.org/software/gnuradio/doc/hierarchy.html"> class
-hierarchy</ulink> is a useful way to find things that might interest
-you.</para>
-
-</sect1>
-
-
-<sect1 id="tips"><title>Miscellaneous Tips</title>
-
-<sect2 id="sources_and_sinks"><title>Sources and Sinks</title>
-
-<para>Sources and sinks are derived from
-<classname>gr_sync_block</classname>. The only thing different about
-them is that sources have no inputs and sinks have no outputs. This
-is reflected in the <classname>gr_io_signature</classname>s that are
-passed to the <classname>gr_sync_block</classname> constructor.
-Take a look at <filename>gr_file_source.{h,cc}</filename> and
-<filename>gr_file_sink.{h,cc}</filename> for some very straight-forward examples.
-</para>
-
-</sect2>
-
-<sect2 id="debugging">
-<title>Debugging with <application>gdb</application></title>
-
-<para>If your block isn&apos;t working, and you can&apos;t sort it
-out through python test cases or a few printfs in the code, you may want to
-use <application>gdb</application> to debug it. The trick of course
-is that all of &gnuradio;, including your new block, is dynamically
-loaded into python for execution.</para>
-
-<para>Try this: In your python test code, after the relevant imports,
-print out the process id and wait for a keystroke. In another
-window run gdb and tell it to attach to the python process with the
-given process id. At this point you can set breakpoints or whatever
-in your code. Go back to the python window and hit Enter so
-it&apos;ll continue.</para>
-
-<programlisting>
- #!/usr/bin/env python
- from gnuradio import gr
- from gnuradio import my_buggy_module
-
- # insert this in your test code...
- import os
- print 'Blocked waiting for GDB attach (pid = %d)' % (os.getpid(),)
- raw_input ('Press Enter to continue: ')
- # remainder of your test code follows...
-</programlisting>
-
-<para>Another SNAFU you might run into is that gdb 6.2 isn&apos;t
-able to set breakpoints in the constructors or destructors generated
-by g++ 3.4. In this case, insert a call to the nop function
-gri_debugger_hook in the constructor and recompile. Load the code as
-before and set a break point on gri_debugger_hook.</para>
-
-</sect2>
-
-<sect2 id="oprofile">
-<title>Performance Measurement with <application>oprofile</application></title>
-<para>Oprofile is your friend.
-See <ulink url="http://oprofile.sourceforge.net">http://oprofile.sourceforge.net</ulink>.
-</para>
-</sect2>
-
-</sect1><!-- end tips -->
-
-<sect1 id="futures"><title>Coming Attractions</title>
-<para></para>
-
-<sect2 id="types"><title>Improved Type System</title>
-<para></para>
-</sect2>
-
-<sect2 id="hierarchy"><title>Hierarchical Blocks</title>
-<para></para>
-</sect2>
-
-</sect1><!-- end Coming Attractions -->
-
-</article>
diff --git a/gr-howto-write-a-block/limbo/doc/howto_1.i b/gr-howto-write-a-block/limbo/doc/howto_1.i
deleted file mode 100644
index 640d0897b..000000000
--- a/gr-howto-write-a-block/limbo/doc/howto_1.i
+++ /dev/null
@@ -1,29 +0,0 @@
-/* -*- c++ -*- */
-
-%include "exception.i"
-%import "gnuradio.i" // the common stuff
-
-%{
-#include "gnuradio_swig_bug_workaround.h" // mandatory bug fix
-#include "howto_square_ff.h"
-#include <stdexcept>
-%}
-
-// ----------------------------------------------------------------
-
-/*
- * First arg is the package prefix.
- * Second arg is the name of the class minus the prefix.
- *
- * This does some behind-the-scenes magic so we can
- * access howto_square_ff from python as howto.square_ff
- */
-GR_SWIG_BLOCK_MAGIC(howto,square_ff);
-
-howto_square_ff_sptr howto_make_square_ff ();
-
-class howto_square_ff : public gr_block
-{
-private:
- howto_square_ff ();
-};
diff --git a/gr-howto-write-a-block/limbo/doc/make_numbered_listing.py b/gr-howto-write-a-block/limbo/doc/make_numbered_listing.py
deleted file mode 100755
index 889c2d78d..000000000
--- a/gr-howto-write-a-block/limbo/doc/make_numbered_listing.py
+++ /dev/null
@@ -1,45 +0,0 @@
-#!/usr/bin/env python
-
-import sys
-import os, os.path
-from optparse import OptionParser
-
-def quote_line (line):
- line = line.replace ('&', '&amp;')
- line = line.replace ('<', '&lt;')
- line = line.replace ('>', '&gt;')
- line = line.replace ("'", '&apos;')
- line = line.replace ('"', '&quot;')
- return line
-
-def generate_listing (input_filename, title=None):
- inf = open (input_filename, "r")
- output_filename = os.path.basename (input_filename) + '.xml'
- outf = open (output_filename, "w")
- outf.write ('<?xml version="1.0" encoding="ISO-8859-1"?>\n')
- # outf.write ('<example id="%s">\n' % (input_filename,))
- # if not title:
- # title = input_filename
- # outf.write ('<title>')
- # outf.write (title)
- # outf.write ('</title>\n')
- outf.write ('<programlisting>\n');
-
- lineno = 0
- for line in inf:
- line = line.expandtabs (8)
- line = quote_line (line)
- lineno = lineno + 1
- outf.write ('%3d %s' % (lineno, line))
-
- outf.write ('</programlisting>\n')
- # outf.write ('</example>\n')
-
-
-def main ():
- for file in sys.argv[1:]:
- generate_listing (file)
-
-if __name__ == '__main__':
- main ()
-
diff --git a/gr-howto-write-a-block/limbo/doc/qa_howto_1.py b/gr-howto-write-a-block/limbo/doc/qa_howto_1.py
deleted file mode 100755
index 3173110f8..000000000
--- a/gr-howto-write-a-block/limbo/doc/qa_howto_1.py
+++ /dev/null
@@ -1,27 +0,0 @@
-#!/usr/bin/env python
-
-from gnuradio import gr, gr_unittest
-import howto
-
-class qa_howto (gr_unittest.TestCase):
-
- def setUp (self):
- self.tb = gr.top_block ()
-
- def tearDown (self):
- self.tb = None
-
- def test_001_square_ff (self):
- src_data = (-3, 4, -5.5, 2, 3)
- expected_result = (9, 16, 30.25, 4, 9)
- src = gr.vector_source_f (src_data)
- sqr = howto.square_ff ()
- dst = gr.vector_sink_f ()
- self.tb.connect (src, sqr)
- self.tb.connect (sqr, dst)
- self.tb.run ()
- result_data = dst.data ()
- self.assertFloatTuplesAlmostEqual (expected_result, result_data, 6)
-
-if __name__ == '__main__':
- gr_unittest.main ()
diff --git a/gr-howto-write-a-block/limbo/doc/src_lib_Makefile_1.am b/gr-howto-write-a-block/limbo/doc/src_lib_Makefile_1.am
deleted file mode 100644
index e97d70d1c..000000000
--- a/gr-howto-write-a-block/limbo/doc/src_lib_Makefile_1.am
+++ /dev/null
@@ -1,25 +0,0 @@
-include $(top_srcdir)/Makefile.common
-
-# Install this stuff so that it ends up as the gnuradio.howto module
-# This usually ends up at:
-# ${prefix}/lib/python${python_version}/site-packages/gnuradio
-
-ourpythondir = $(grpythondir)
-ourlibdir = $(grpyexecdir)
-
-INCLUDES = $(STD_DEFINES_AND_INCLUDES) $(PYTHON_CPPFLAGS) $(WITH_INCLUDES)
-
-ourlib_LTLIBRARIES = _howto.la
-
-# These are the source files that go into the shared library
-_howto_la_SOURCES = \
- howto_square_ff.cc
-
-# magic flags
-_howto_la_LDFLAGS = -module -avoid-version
-
-# These headers get installed in ${prefix}/include/gnuradio
-grinclude_HEADERS = \
- howto_square_ff.h
-
-MOSTLYCLEANFILES = $(BUILT_SOURCES) *.pyc
diff --git a/gr-howto-write-a-block/limbo/doc/src_lib_Makefile_2.am b/gr-howto-write-a-block/limbo/doc/src_lib_Makefile_2.am
deleted file mode 100644
index dca236e20..000000000
--- a/gr-howto-write-a-block/limbo/doc/src_lib_Makefile_2.am
+++ /dev/null
@@ -1,86 +0,0 @@
-#
-# Copyright 2004,2008 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
-
-# Install this stuff so that it ends up as the gnuradio.howto module
-# This usually ends up at:
-# ${prefix}/lib/python${python_version}/site-packages/gnuradio
-
-ourpythondir = $(grpythondir)
-ourlibdir = $(grpyexecdir)
-
-INCLUDES = $(STD_DEFINES_AND_INCLUDES) $(PYTHON_CPPFLAGS) $(WITH_INCLUDES)
-
-SWIGCPPPYTHONARGS = -noruntime -c++ -python $(PYTHON_CPPFLAGS) \
- -I$(swigincludedir) -I$(grincludedir) $(WITH_SWIG_INCLUDES)
-
-ALL_IFILES = \
- $(LOCAL_IFILES) \
- $(NON_LOCAL_IFILES)
-
-NON_LOCAL_IFILES = \
- $(GNURADIO_CORE_INCLUDEDIR)/swig/gnuradio.i
-
-
-LOCAL_IFILES = \
- howto.i
-
-# These files are built by SWIG. The first is the C++ glue.
-# The second is the python wrapper that loads the _howto shared library
-# and knows how to call our extensions.
-
-BUILT_SOURCES = \
- howto.cc \
- howto.py
-
-# This gets howto.py installed in the right place
-ourpython_PYTHON = \
- howto.py
-
-ourlib_LTLIBRARIES = _howto.la
-
-# These are the source files that go into the shared library
-_howto_la_SOURCES = \
- howto.cc \
- howto_square_ff.cc
-
-# magic flags
-_howto_la_LDFLAGS = -module -avoid-version
-
-# link the library against some comon swig runtime code and the
-# c++ standard library
-_howto_la_LIBADD = \
- -lgrswigrunpy \
- -lstdc++
-
-howto.cc howto.py: howto.i $(ALL_IFILES)
- $(SWIG) $(SWIGCPPPYTHONARGS) -module howto -o howto.cc $<
-
-# These headers get installed in ${prefix}/include/gnuradio
-grinclude_HEADERS = \
- howto_square_ff.h
-
-# These swig headers get installed in ${prefix}/include/gnuradio/swig
-swiginclude_HEADERS = \
- $(LOCAL_IFILES)
-
-MOSTLYCLEANFILES = $(BUILT_SOURCES) *.pyc
diff --git a/gr-howto-write-a-block/python/Makefile.am b/gr-howto-write-a-block/python/Makefile.am
index 79f44019d..4ef5fc964 100644
--- a/gr-howto-write-a-block/python/Makefile.am
+++ b/gr-howto-write-a-block/python/Makefile.am
@@ -21,12 +21,13 @@
include $(top_srcdir)/Makefile.common
-EXTRA_DIST = run_tests.in
-
+ourpythondir = $(grpythondir)/howto
-TESTS = \
- run_tests
+EXTRA_DIST = run_tests.in
+TESTS = run_tests
+ourpython_PYTHON = \
+ __init__.py
-noinst_PYTHON = \
+noinst_PYTHON = \
qa_howto.py
diff --git a/gr-howto-write-a-block/python/__init__.py b/gr-howto-write-a-block/python/__init__.py
new file mode 100644
index 000000000..d4a41c271
--- /dev/null
+++ b/gr-howto-write-a-block/python/__init__.py
@@ -0,0 +1,49 @@
+#
+# Copyright 2008,2009 Free Software Foundation, Inc.
+#
+# This application 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.
+#
+# This application 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.
+#
+
+# The presence of this file turns this directory into a Python package
+
+# ----------------------------------------------------------------
+# Temporary workaround for ticket:181 (swig+python problem)
+import sys
+_RTLD_GLOBAL = 0
+try:
+ from dl import RTLD_GLOBAL as _RTLD_GLOBAL
+except ImportError:
+ try:
+ from DLFCN import RTLD_GLOBAL as _RTLD_GLOBAL
+ except ImportError:
+ pass
+
+if _RTLD_GLOBAL != 0:
+ _dlopenflags = sys.getdlopenflags()
+ sys.setdlopenflags(_dlopenflags|_RTLD_GLOBAL)
+# ----------------------------------------------------------------
+
+
+# import swig generated symbols into the howto namespace
+from howto_swig import *
+
+# import any pure python here
+#
+
+# ----------------------------------------------------------------
+# Tail of workaround
+if _RTLD_GLOBAL != 0:
+ sys.setdlopenflags(_dlopenflags) # Restore original flags
+# ----------------------------------------------------------------
diff --git a/gr-howto-write-a-block/python/qa_howto.py b/gr-howto-write-a-block/python/qa_howto.py
index 0abe0e244..630f57bf4 100755
--- a/gr-howto-write-a-block/python/qa_howto.py
+++ b/gr-howto-write-a-block/python/qa_howto.py
@@ -21,7 +21,7 @@
#
from gnuradio import gr, gr_unittest
-import howto
+import howto_swig
class qa_howto (gr_unittest.TestCase):
@@ -35,7 +35,7 @@ class qa_howto (gr_unittest.TestCase):
src_data = (-3, 4, -5.5, 2, 3)
expected_result = (9, 16, 30.25, 4, 9)
src = gr.vector_source_f (src_data)
- sqr = howto.square_ff ()
+ sqr = howto_swig.square_ff ()
dst = gr.vector_sink_f ()
self.tb.connect (src, sqr)
self.tb.connect (sqr, dst)
@@ -47,7 +47,7 @@ class qa_howto (gr_unittest.TestCase):
src_data = (-3, 4, -5.5, 2, 3)
expected_result = (9, 16, 30.25, 4, 9)
src = gr.vector_source_f (src_data)
- sqr = howto.square2_ff ()
+ sqr = howto_swig.square2_ff ()
dst = gr.vector_sink_f ()
self.tb.connect (src, sqr)
self.tb.connect (sqr, dst)
diff --git a/gr-howto-write-a-block/swig/.gitignore b/gr-howto-write-a-block/swig/.gitignore
index 916527317..7f4c478d9 100644
--- a/gr-howto-write-a-block/swig/.gitignore
+++ b/gr-howto-write-a-block/swig/.gitignore
@@ -2,5 +2,5 @@
/.libs
/Makefile.in
/Makefile
-/howto.cc
-/howto.py
+/howto_swig.cc
+/howto_swig.py
diff --git a/gr-howto-write-a-block/swig/Makefile.am b/gr-howto-write-a-block/swig/Makefile.am
index 8c94f5041..fc40109d0 100644
--- a/gr-howto-write-a-block/swig/Makefile.am
+++ b/gr-howto-write-a-block/swig/Makefile.am
@@ -34,8 +34,7 @@ TOP_SWIG_IFILES = \
# import gnuradio.howto
# This ends up at:
# ${prefix}/lib/python${python_version}/site-packages/gnuradio
-howto_pythondir_category = \
- gnuradio
+howto_pythondir_category = gnuradio/howto
howto_la_swig_libadd = \
$(top_builddir)/lib/libgnuradio-howto.la
diff --git a/gr-howto-write-a-block/swig/Makefile.swig.gen b/gr-howto-write-a-block/swig/Makefile.swig.gen
index f76cc6371..c62e5aa3e 100644
--- a/gr-howto-write-a-block/swig/Makefile.swig.gen
+++ b/gr-howto-write-a-block/swig/Makefile.swig.gen
@@ -72,42 +72,42 @@ MOSTLYCLEANFILES += $(DEPDIR)/*.S*
## .h file is sometimes built, but not always ... so that one has to
## be added manually by the including Makefile.am .
-swig_built_sources += howto.py howto.cc
+swig_built_sources += howto_swig.py howto_swig.cc
## Various SWIG variables. These can be overloaded in the including
## Makefile.am by setting the variable value there, then including
## Makefile.swig .
howto_swiginclude_HEADERS = \
- howto.i \
+ howto.i \
$(howto_swiginclude_headers)
howto_pylib_LTLIBRARIES = \
- _howto.la
+ _howto_swig.la
-_howto_la_SOURCES = \
- howto.cc \
+_howto_swig_la_SOURCES = \
+ howto_swig.cc \
$(howto_la_swig_sources)
-_howto_la_LIBADD = \
+_howto_swig_la_LIBADD = \
$(STD_SWIG_LA_LIB_ADD) \
$(howto_la_swig_libadd)
-_howto_la_LDFLAGS = \
+_howto_swig_la_LDFLAGS = \
$(STD_SWIG_LA_LD_FLAGS) \
$(howto_la_swig_ldflags)
-_howto_la_CXXFLAGS = \
+_howto_swig_la_CXXFLAGS = \
$(STD_SWIG_CXX_FLAGS) \
$(howto_la_swig_cxxflags)
howto_python_PYTHON = \
- howto.py \
+ howto_swig.py \
$(howto_python)
## Entry rule for running SWIG
-howto.h howto.py howto.cc: howto.i
+howto.h howto_swig.py howto_swig.cc: howto.i
## This rule will get called only when MAKE decides that one of the
## targets needs to be created or re-created, because:
##
@@ -202,7 +202,7 @@ $(DEPDIR)/howto-generate-stamp:
##
if $(SWIG) $(STD_SWIG_PYTHON_ARGS) $(howto_swig_args) \
-MD -MF $(DEPDIR)/howto.Std \
- -module howto -o howto.cc $(WHAT); then \
+ -module howto_swig -o howto_swig.cc $(WHAT); then \
if test $(host_os) = mingw32; then \
$(RM) $(DEPDIR)/howto.Sd; \
$(SED) 's,\\\\,/,g' < $(DEPDIR)/howto.Std \