diff options
Diffstat (limited to 'gr-howto-write-a-block')
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're"> - <!ENTITY well "we'll"> - <!ENTITY thats "that's"> - <!ENTITY its "it's"> - <!ENTITY lets "let's"> - <!ENTITY youre "you'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<float>), 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'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 -"STL style" 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<float></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: □</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'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'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's. -To reduce code bloat, we only declare methods that &well; want to -access from Python.</para> - -<para>We'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'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 &ninput_items_required) - { - unsigned ninputs = ninput_items_required.size (); - for (unsigned i = 0; i < ninputs; i++) - ninput_items_required[i] = noutput_items; - } -</programlisting> -</para> - -<para>Although the 1:1 implementation worked for howto_square_ff, it -wouldn'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'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 &input_items, - gr_vector_void_star &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'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't working, and you can'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'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'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 ('&', '&') - line = line.replace ('<', '<') - line = line.replace ('>', '>') - line = line.replace ("'", ''') - line = line.replace ('"', '"') - 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 \ |