1 <?xml version="1.0" encoding="ISO-8859-1"?>
2 <!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
4 <!ENTITY gnuradio "<application>GNU Radio</application>">
5 <!ENTITY SWIG "<application>SWIG</application>">
6 <!ENTITY gr_block "<classname>gr_block</classname>">
7 <!ENTITY square "<classname>howto_square_ff</classname>">
9 <!ENTITY were "we're">
10 <!ENTITY well "we'll">
11 <!ENTITY thats "that's">
12 <!ENTITY its "it's">
13 <!ENTITY lets "let's">
14 <!ENTITY youre "you're">
16 <!ENTITY gr_block_listing SYSTEM "gr_block.h.xml">
17 <!ENTITY qa_howto_1_listing SYSTEM "qa_howto_1.py.xml">
18 <!ENTITY howto_square_ff_h_listing SYSTEM "howto_square_ff.h.xml">
19 <!ENTITY howto_square_ff_cc_listing SYSTEM "howto_square_ff.cc.xml">
20 <!ENTITY howto_square2_ff_h_listing SYSTEM "howto_square2_ff.h.xml">
21 <!ENTITY howto_square2_ff_cc_listing SYSTEM "howto_square2_ff.cc.xml">
22 <!ENTITY howto_1_i_listing SYSTEM "howto_1.i.xml">
23 <!ENTITY src_lib_Makefile_1_am_listing SYSTEM "src_lib_Makefile_1.am.xml">
24 <!ENTITY src_lib_Makefile_2_am_listing SYSTEM "src_lib_Makefile_2.am.xml">
31 <title>How to Write a Signal Processing Block</title>
33 <firstname>Eric</firstname>
34 <surname>Blossom</surname>
37 <email>eb@comsec.com</email>
44 <revnumber>0.1</revnumber>
45 <date>2005-01-20</date>
48 <revnumber>0.2</revnumber>
49 <date>2005-02-02</date>
50 <revremark>Updated for SWIG 1.3.24</revremark>
53 <revnumber>0.3</revnumber>
54 <date>2006-07-21</date>
55 <revremark>Clarification of 1:1 fixed rate vs item size</revremark>
62 <holder>Free Software Foundation, Inc.</holder>
65 <abstract><para>This article explains how to write signal
66 processing blocks for <application>GNU Radio</application>.
71 <sect1 id="prereqs"><title>Prerequisites</title>
72 <para>This article assumes that the reader has basic familiarity with
73 GNU Radio and has read and understood
74 <ulink url="http://www.gnu.org/software/gnuradio/doc/exploring-gnuradio.html">
75 <citetitle>Exploring GNU Radio</citetitle></ulink>.
78 <para>There is a tarball of files that accompany this article. It
79 includes the examples, DocBook source for the article and all the
80 Makefiles etc it takes to make it work. Grab it at <ulink
81 url="ftp://ftp.gnu.org/gnu/gnuradio">
82 ftp://ftp.gnu.org/gnu/gnuradio</ulink> or one of the mirrors. The
84 <filename>gr-howto-write-a-block-X.Y.tar.gz</filename>. Pick the one
85 with the highest version number.
86 See <ulink url="http://comsec.com/wiki?CvsAccess">
87 http://comsec.com/wiki?CvsAccess</ulink> for CVS Access.
93 <sect1 id="intro"><title>Introduction</title>
94 <para>&gnuradio; provides a framework for building software radios.
95 Waveforms -- signal processing applications -- are built using a
96 combination of Python code for high level organization, policy, GUI and
97 other non performance-critical functions, while performance critical
98 signal processing blocks are written in C++.</para>
100 <para>From the Python point of view, &gnuradio; provides a data flow
101 abstraction. The fundamental concepts are signal processing
102 blocks and the connections between them. This abstraction is
103 implemented by the Python <classname>gr.flow_graph</classname> class.
104 Each block has a set of input ports and output ports. Each port has
105 an associated data type. The most common port types are
106 <classname>float</classname> and <classname>gr_complex</classname>
107 (equivalent to std::complex<float>), though other types are used,
108 including those representing structures, arrays or other types of
109 packetized data.</para>
111 <para>From the high level point-of-view, infinite streams of data flow
112 through the ports. At the C++ level, streams are dealt with in
113 convenient sized pieces, represented as contiguous arrays of the
114 underlying type.</para>
118 <sect1 id="overview"><title>The View from 30,000 Feet</title>
120 <para>This article will walk through the construction of several
121 simple signal processing blocks, and explain the techniques and idioms
122 used. Later sections cover debugging signal processing blocks in the
123 mixed Python/C++ environment and performance measurement and
126 <para>The example blocks will be built in the style of all &gnuradio;
127 extensions. That is, they are built outside of the gnuradio-core build
128 tree, and are constructed as shared libraries that may be dynamically
129 loaded into Python using the "import" mechanism. &SWIG;, the
130 Simplified Wrapper and Interface Generator, is used to generate the
131 glue that allows our code to be used from Python.</para>
136 <sect1 id="gr_block"><title></title>
138 <para>The C++ class &gr_block; is the base of all signal processing
139 blocks in &gnuradio;. Writing a new signal processing block involves
140 creating 3 files: The .h and .cc files that define the new class and
141 the .i file that tells &SWIG; how to generate the glue that binds the
142 class into Python. The new class must derive from &gr_block; or
143 one of it's subclasses.</para>
145 <para>Our first examples will derive directly from &gr_block;. Later
146 we will look at some other subclasses that simplify the process for
149 </sect1><!-- end gr_block sect1 -->
153 <!-- ================================================================ -->
155 <sect1 id="autotools"><title>Autotools, Makefiles, and Directory Layout</title>
157 <para>Before we dive into the code, &lets; talk a bit about the
158 overall build environment and the directory structure that &well;
161 <para>To reduce the amount of Makefile hacking that we have to do, and
162 to facilitate portability across a variety of systems, we use the GNU
163 <application>autoconf</application>,
164 <application>automake</application>, and
165 <application>libtool</application> tools. These are collectively
166 referred to as the autotools, and once you get over the initial
167 shock, they will become your friends. (The good news is that we
168 provide boilerplate that can be used pretty much as-is.)</para>
172 <varlistentry><term>automake</term>
174 <listitem><para>automake and configure work together to generate GNU
175 compliant Makefiles from a much higher level description contained in
176 the corresponding Makefile.am file. <filename>Makefile.am</filename>
177 specifies the libraries and programs to build and the source files
178 that compose each. Automake reads <filename>Makefile.am</filename>
179 and produces <filename>Makefile.in</filename>. Configure reads
180 <filename>Makefile.in</filename> and produces
181 <filename>Makefile</filename>. The resulting Makefile contains a
182 zillion rules that do the right right thing to build, check and
183 install your code. It is not uncommon for the the resulting
184 <filename>Makefile</filename> to be 5 or 6 times larger than
185 <filename>Makefile.am</filename>.</para>
190 <varlistentry><term>autoconf</term>
191 <listitem><para>autoconf reads <filename>configure.ac</filename>
192 and produces the <filename>configure</filename> shell
193 script. <filename>configure</filename> automatically tests for
194 features of the underlying system and sets a bunch of variables and
195 defines that can be used in the Makefiles and your C++ code to
196 conditionalize the build. If features are required but not found,
197 configure will output an error message and stop.</para>
201 <varlistentry><term>libtool</term>
202 <listitem><para>libtool works behind the scenes and provides the magic
203 to construct shared libraries on a wide variety of systems.</para>
209 <para><xref linkend="dir-layout"/> shows the directory layout and
210 common files &well; be using. After renaming the
211 <replaceable>topdir</replaceable> directory, use it in your projects
212 too. We'll talk about particular files as they come up later.</para>
215 <table id="dir-layout"><title>Directory Layout</title>
219 <entry>File/Dir Name</entry>
220 <entry>Comment</entry>
227 <entry><replaceable>topdir</replaceable>/Makefile.am</entry>
228 <entry>Top level Makefile.am</entry>
231 <entry><replaceable>topdir</replaceable>/Makefile.common</entry>
232 <entry>Common fragment included in sub-Makefiles</entry>
235 <entry><replaceable>topdir</replaceable>/bootstrap</entry>
236 <entry>Runs autoconf, automake, libtool first time through</entry>
239 <entry><replaceable>topdir</replaceable>/config</entry>
240 <entry>Directory of m4 macros used by configure.ac</entry>
243 <entry><replaceable>topdir</replaceable>/configure.ac</entry>
244 <entry>Input to autoconf</entry>
247 <entry><replaceable>topdir</replaceable>/src</entry>
250 <entry><replaceable>topdir</replaceable>/src/lib</entry>
251 <entry>C++ code goes here</entry>
254 <entry><replaceable>topdir</replaceable>/src/lib/Makefile.am</entry>
257 <entry><replaceable>topdir</replaceable>/src/python</entry>
258 <entry>Python code goes here</entry>
261 <entry><replaceable>topdir</replaceable>/src/python/Makefile.am</entry>
264 <entry><replaceable>topdir</replaceable>/src/python/run_tests</entry>
265 <entry>Script to run tests in the build tree</entry>
274 <!-- ================================================================ -->
276 <sect1 id="naming"><title>Naming Conventions</title>
278 <para>&gnuradio; uses a set of naming conventions to assist in
279 comprehending the code base and gluing C++ and Python together.
280 Please follow them.</para>
282 <sect2 id="camel-case"><title><emphasis>Death to CamelCaseNames!</emphasis></title>
284 <para>We've returned to a kinder, gentler era. We're now using the
285 "STL style" naming convention with a couple of modifications
286 since we're not using namespaces.</para>
288 <para>With the exception of macros and other constant values, all
289 identifiers shall be lower case with <literal>words_separated_like_this</literal>.</para>
291 <para>Macros and constant values (e.g., enumerated values,
292 <literal>static const int FOO = 23</literal>) shall be in <literal>UPPER_CASE</literal>.</para>
296 <sect2 id="global_names"><title>Global Names</title>
298 <para>All globally visible names (types, functions, variables, consts, etc)
299 shall begin with a "package prefix", followed by an underscore. The bulk of
300 the code in GNU Radio belongs to the "gr" package, hence
301 names look like <literal>gr_open_file (...)</literal>.</para>
303 <para>Large coherent bodies of code may use other package prefixes, but
304 let's try to keep them to a well thought out list. See the list
309 <sect2 id="package_prefixes"><title>Package Prefixes</title>
311 <para>These are the current package prefixes:
315 <varlistentry><term>gr_</term>
316 <listitem><para>Almost everything.</para></listitem>
319 <varlistentry><term>gri_</term>
321 Implementation primitives. Sometimes we
322 have both a gr_<replaceable>foo</replaceable> and a gri_<replaceable>foo</replaceable>. In that case,
323 gr_<replaceable>foo</replaceable> would be derived from gr_block and gri_<replaceable>foo</replaceable>
324 would be the low level guts of the function.</para></listitem>
327 <varlistentry><term>atsc_</term>
328 <listitem><para>Code related to the Advanced Television Standards Committee HDTV implementation
332 <varlistentry><term>usrp_</term>
333 <listitem><para>Universal Software Radio Peripheral.</para></listitem>
336 <varlistentry><term>qa_</term>
337 <listitem><para>Quality Assurance (Test code.)</para></listitem>
345 <sect2 id="class-data-members"><title>Class Data Members (instance variables)</title>
347 <para>All class data members shall begin with d_<replaceable>foo</replaceable>.</para>
349 <para>The big win is when you're staring at a block of code it's obvious
350 which of the things being assigned to persist outside of the block.
351 This also keeps you from having to be creative with parameter names
352 for methods and constructors. You just use the same name as the
353 instance variable, without the d_. </para>
356 class gr_wonderfulness {
358 double d_wonderfulness_factor;
361 gr_wonderfulness (std::string name, double wonderfulness_factor)
362 : d_name (name), d_wonderfulness_factor (wonderfulness_factor)
372 <sect2 id="static-data-members"><title>Class Static Data Members (class variables)</title>
375 All class static data members shall begin with s_<replaceable>foo</replaceable>.
380 <sect2 id="file-names"><title>File Names</title>
382 <para>Each significant class shall be contained in its own file. The
383 declaration of class <classname>gr_foo</classname> shall be in
384 <filename>gr_foo.h</filename> and the definition in
385 <filename>gr_foo.cc</filename>.</para>
389 <sect2><title>Suffixes</title>
391 <para>By convention, we encode the input and output types of signal
392 processing blocks in their name using suffixes. The suffix is
393 typically one or two characters long. Source and sinks have single
394 character suffixes. Regular blocks that have both inputs and outputs
395 have two character suffixes. The first character indicates the type
396 of the input streams, the second indicates the type of the output
397 streams. FIR filter blocks have a three character suffix, indicating
398 the type of the inputs, outputs and taps, respectively.</para>
400 <para>These are the suffix characters and their interpretations:
402 <listitem><para>f - single precision floating point</para></listitem>
403 <listitem><para>c - complex<float></para></listitem>
404 <listitem><para>s - short (16-bit integer)</para></listitem>
405 <listitem><para>i - integer (32-bit integer)</para></listitem>
409 <para>In addition, for those cases where the block deals with streams
410 of vectors, we use the character 'v' as the first character of the
411 suffix. An example of this usage is
412 <classname>gr_fft_vcc</classname>. The FFT block takes a vector of
413 complex numbers on its input and produces a vector of complex
414 numbers on its output.</para>
423 <sect1 id="square"><title>First Block: □</title>
425 <para>For our first example &well; create a block that computes
426 the square of its single float input. This block will accept a single
427 float input stream and produce a single float output stream.</para>
429 <para>Following the naming conventions, &well; use
430 <literal>howto</literal> as our package prefix, and the block will
431 be called <classname>howto_square_ff</classname>.</para>
433 <para>We are going to arrange that this block, as well as the others
434 that we write in this article, end up in the
435 <literal>gnuradio.howto</literal> Python module. This will allow us
436 to access it from Python like this:
438 from gnuradio import howto
439 sqr = howto.square_ff ()
444 <sect2 id="test_driven"><title>Test Driven Programming</title>
446 <para>We could just start banging out the C++ code, but being highly
447 evolved modern programmers, &were; going to write the test code first.
448 After all, we do have a good spec for the behavior: take a single
449 stream of floats as the input and produce a single stream of floats as
450 the output. The output should be the square of the input.</para>
452 <para>How hard could this be? Turns out that this is easy! Check out
453 <xref linkend="qa_howto_1.py"/>.</para>
455 <example id="qa_howto_1.py">
456 <title><filename>qa_howto.py</filename> (first version)</title>
461 <classname>gr_unittest</classname> is an extension to the standard
462 python module <classname>unittest</classname>.
463 <classname>gr_unittest</classname> adds support for checking
464 approximate equality of tuples of float and complex numbers.
465 Unittest uses Python's reflection mechanism to find all methods that start with
466 <methodname>test_</methodname> and runs them. Unittest wraps each call
467 to <methodname>test_*</methodname> with matching calls to
468 <methodname>setUp</methodname> and <methodname>tearDown</methodname>.
469 See the python <ulink url="http://docs.python.org/lib/module-unittest.html">
470 unittest</ulink> documentation for details.
473 <para>When we run the test,
474 gr_unittest.main is going to invoke
475 <methodname>setUp</methodname>,
476 <methodname>test_001_square_ff</methodname>, and
477 <methodname>tearDown</methodname>.</para>
479 <methodname>test_001_square_ff</methodname> builds a small graph that
480 contains three nodes. gr.vector_source_f(src_data) will source the
481 elements of src_data and then say that &its; finished. howto.square_ff is the block
482 &were; testing. gr.vector_sink_f gathers the output of
483 howto.square_ff.</para>
485 <para>The <methodname>run</methodname> method runs the graph until all
486 the blocks indicate they are finished. Finally, we check that the
487 result of executing square_ff on src_data matches what we expect.
492 <sect2 id="build_vs_install"><title>Build Tree vs. Install Tree</title>
494 <para>The build tree is everything from <replaceable>topdir</replaceable>
495 (the one containing configure.ac) down. The path to the install tree is
497 <replaceable>prefix</replaceable>/lib/python<replaceable>version</replaceable>/site-packages</filename>,
498 where <replaceable>prefix</replaceable> is the <literal>--prefix</literal>
499 argument to configure (default <filename>/usr/local</filename>) and
500 <replaceable>version</replaceable> is the installed version of
501 python. A typical value is
502 <filename>/usr/local/lib/python2.3/site-packages</filename>.</para>
505 <para>We normally set our PYTHONPATH environment variable to point at
506 the install tree, and do this in <filename>~/.bash_profile</filename>
507 or <filename>~/.profile</filename>.
508 This allows our python apps to access all the standard python
509 libraries, plus our locally installed stuff like GNU Radio.</para>
511 <para>We write our applications such that they access the code and
512 libraries in the install tree. On the other hand, we want our test
513 code to run on the build tree, where we can detect problems before
518 <sect2 id="make_check"><title>make check</title>
521 <para>We use <command>make check</command> to run our tests.
522 Make check invokes the <command>run_tests</command> shell script which
523 sets up the PYTHONPATH environment variable so that
524 our tests use the build tree versions of our code and libraries.
525 It then runs all files
526 which have names of the form <filename>qa_*.py</filename> and reports
527 the overall success or failure.</para>
529 <para>There is quite a bit of behind-the-scenes action required to use
530 the non-installed versions of our code (look at
531 <filename>runtest</filename> for a cheap thrill.)</para>
533 <para>Finally, running <command>make check</command> in the python
534 directory produces this result:
536 [eb@bufo python]$ make check
538 make[1]: Entering directory `/home/eb/gr-build/gr-howto-write-a-block/src/python'
539 Traceback (most recent call last):
540 File "./qa_howto.py", line 24, in ?
542 ImportError: No module named howto
543 Traceback (most recent call last):
544 File "./qa_howto_1.py", line 24, in ?
546 ImportError: No module named howto
551 make[1]: *** [check-TESTS] Error 1
552 make[1]: Leaving directory `/home/eb/gr-build/gr-howto-write-a-block/src/python'
553 make: *** [check-am] Error 2
556 Excellent! Our test failed, just as we expected. The ImportError
557 indicates that it can't find the module named
558 <classname>howto</classname>. No surprise, since we haven't written it yet.
563 <sect2><title>The C++ code</title>
564 <para>Now that we've got a test case written that successfully fails,
565 let's write the C++ code. As we mentioned earlier, all signal
566 processing blocks are derived from <classname>gr_block</classname> or
567 one of its subclasses. Let's take a look at
568 <xref linkend="gr_block.h"/>.</para>
570 <example id="gr_block.h">
571 <title><filename>gr_block.h</filename></title>
575 <para>A quick scan of <filename>gr_block.h</filename> reveals that
576 since <methodname>general_work</methodname> is pure virtual, we
577 definitely need to override that.
578 <methodname>general_work</methodname> is the method that does the
579 actual signal processing. For our squaring example we'll
580 need to override <methodname>general_work</methodname> and provide a
581 constructor and destructor and a bit of stuff to take advantage of
582 the <ulink url="http://www.boost.org">boost</ulink>
583 <ulink url="http://www.boost.org/libs/smart_ptr/smart_ptr.htm">
584 <classname>shared_ptr</classname>s.</ulink>
589 <para><xref linkend="howto_square_ff.h"/>
590 and <xref linkend="howto_square_ff.cc"/> are the header and c++
593 <example id="howto_square_ff.h">
594 <title><filename>howto_square_ff.h</filename></title>
595 &howto_square_ff_h_listing;
598 <example id="howto_square_ff.cc">
599 <title><filename>howto_square_ff.cc</filename></title>
600 &howto_square_ff_cc_listing;
603 <para>Now we need a Makefile.am to get all this to build.
604 <xref linkend="src_lib_Makefile_1"/>
605 is enough to build a shared library from our source file. We'll be
606 adding additional rules to use &SWIG; in just a bit. If you haven't
607 already, this is a good time to browse all the Makefile.am's in
608 the build tree and get an idea for how it all hangs together.</para>
610 <example id="src_lib_Makefile_1">
611 <title><filename>src/lib/Makefile.am</filename> (no &SWIG;)</title>
612 &src_lib_Makefile_1_am_listing;
618 <!-- ==============================
620 <sect2 id="io_sig"><title><classname>gr_io_signature</classname></title>
624 <sect2 id="forecast"><title><methodname>forecast</methodname></title>
628 <sect2 id="output_multiple">
629 <title><methodname>set_output_multiple</methodname></title>
633 ============================== -->
636 <sect2 id="swig"><title>The &SWIG; .i file</title>
638 <para>Now that we've got something that will compile, we need to write
639 the &SWIG; .i file. This is a pared-down version of the .h file, plus
640 a bit of magic that has python work with the boost shared_ptr's.
641 To reduce code bloat, we only declare methods that &well; want to
642 access from Python.</para>
644 <para>We're going to call the .i file
645 <filename>howto.i</filename>, and use it to hold the &SWIG;
646 declarations for all classes from <literal>howto</literal> that will
647 be accessible from python. It's quite small:
653 <sect2><title>Putting it all together</title>
655 Now we need to modify <filename>src/lib/Makefile.am</filename>
656 to run &SWIG; and to add the glue it generates to the shared library.</para>
658 <example id="src_lib_Makefile_2">
659 <title><filename>src/lib/Makefile.am</filename> (with &SWIG;)</title>
660 &src_lib_Makefile_2_am_listing;
663 <para><command>make</command> now builds everything successfully. We get a
664 few warnings, but &thats; OK.</para>
666 <para>Changing directories back to the python directory we try
667 <command>make check</command> again:
669 [eb@bufo python]$ make check
671 make[1]: Entering directory `/home/eb/gr-build/gr-howto-write-a-block/src/python'
673 ----------------------------------------------------------------------
681 make[1]: Leaving directory `/home/eb/gr-build/gr-howto-write-a-block/src/python'
684 <emphasis>Victory! Our new block works!</emphasis>
689 </sect1><!-- end First Block: square -->
691 <sect1 id="additional_methods"><title>Additional gr_block methods</title>
693 <para>In our <classname>howto_square_ff</classname> example above, we only
694 had to override the <methodname>general_work</methodname> method to
695 accomplish our goal. <classname>gr_block</classname> provides a few other
696 methods that are sometimes useful.</para>
698 <sect2 id="forecast"><title>forecast</title>
700 <para>Looking at <methodname>general_work</methodname> you may
701 have wondered how the system knows how much data it needs to
702 ensure is valid in each of the input arrays. The
703 <methodname>forecast</methodname> method provides this
706 <para>The default implementation of <methodname>forecast</methodname>
707 says there is a 1:1 relationship between noutput_items and the
708 requirements for each input stream. The size of the items is defined by
709 <classname>gr_io_signature</classname>s in the constructor of
710 <classname>gr_block</classname>. The sizes of the input and output items
711 can of course differ; this still qualifies as a 1:1 relationship.
713 // default implementation: 1:1
716 gr_block::forecast (int noutput_items,
717 gr_vector_int &ninput_items_required)
719 unsigned ninputs = ninput_items_required.size ();
720 for (unsigned i = 0; i < ninputs; i++)
721 ninput_items_required[i] = noutput_items;
726 <para>Although the 1:1 implementation worked for howto_square_ff, it
727 wouldn't be appropriate for interpolators, decimators, or blocks
728 with a more complicated relationship between noutput_items and the
729 input requirements. That said, by deriving your classes from
730 <classname>gr_sync_block</classname>,
731 <classname>gr_sync_interpolator</classname> or
732 <classname>gr_sync_decimator</classname> instead of
733 <classname>gr_block</classname>, you can often avoid
734 implementing <methodname>forecast</methodname>.</para>
738 <sect2 id="set_output_multiple"><title>set_output_multiple</title>
740 <para>When implementing your <methodname>general_work</methodname>
741 routine, &its; occasionally convenient to have the run time system
742 ensure that you are only asked to produce a number of output items
743 that is a multiple of some particular value. This might occur if your
744 algorithm naturally applies to a fixed sized block of data.
745 Call <methodname>set_output_multiple</methodname> in your constructor
746 to specify this requirement. The default output multiple is 1.</para>
753 <sect1 id="common_patterns">
754 <title>Subclasses for common patterns</title>
756 <para><classname>gr_block</classname> allows tremendous flexibility
757 with regard to the consumption of input streams and the production of
758 output streams. Adroit use of <methodname>forecast</methodname> and
759 <methodname>consume</methodname> allows variable rate blocks to be
760 built. It is possible to construct blocks that consume data at
761 different rates on each input, and produce output at a rate that
762 is a function of the contents of the input data.</para>
764 <para>On the other hand, it is very common for signal processing
765 blocks to have a fixed relationship between the input rate and the
766 output rate. Many are 1:1, while others have 1:N or N:1
767 relationships.</para>
769 <para>Another common requirement is the need to examine more than one
770 input sample to produce a single output sample. This is orthogonal to
771 the relationship between input and output rate. For example, a
772 non-decimating, non-interpolating FIR filter needs to examine N input
773 samples for each output sample it produces, where N is the number of
774 taps in the filter. However, it only consumes a single input sample
775 to produce a single output. We call this concept "history", but you
776 could also think of it as "look-ahead".</para>
778 <sect2 id="gr_sync_block"><title><classname>gr_sync_block</classname></title>
781 <ulink url="http://www.gnu.org/software/gnuradio/doc/classgr__sync__block.html">
782 <classname>gr_sync_block</classname></ulink>
784 <ulink url="http://www.gnu.org/software/gnuradio/doc/classgr__block.html">
785 <classname>gr_block</classname></ulink>
786 and implements a 1:1 block with
787 optional history. Given that we know the input to output rate,
788 certain simplifications are possible. From the implementor's
789 point-of-view, the primary change is that we define a
790 <methodname>work</methodname> method instead of
791 <methodname>general_work</methodname>. <methodname>work</methodname>
792 has a slightly different calling sequence;
793 It omits the unnecessary ninput_items parameter, and arranges for
794 <methodname>consume_each</methodname> to be called on our
798 * \brief Just like gr_block::general_work, only this arranges to
799 * call consume_each for you.
801 * The user must override work to define the signal processing code
803 virtual int work (int noutput_items,
804 gr_vector_const_void_star &input_items,
805 gr_vector_void_star &output_items) = 0;
808 <para>This gives us fewer things to worry about, and less code to
809 write. If the block requires history greater than 1, call
810 <methodname>set_history</methodname> in the constructor, or any time
811 the requirement changes.</para>
813 <para><classname>gr_sync_block</classname> provides a
814 version of <methodname>forecast</methodname> that handles the
815 history requirement.</para>
819 <sect2 id="gr_sync_decimator"><title><classname>gr_sync_decimator</classname></title>
822 <ulink url="http://www.gnu.org/software/gnuradio/doc/classgr__sync__decimator.html">
823 <classname>gr_sync_decimator</classname></ulink>
825 <ulink url="http://www.gnu.org/software/gnuradio/doc/classgr__sync__block.html">
826 <classname>gr_sync_block</classname></ulink>
827 and implements a N:1 block with optional history.
832 <sect2 id="gr_sync_interpolator"><title><classname>gr_sync_interpolator</classname></title>
835 <ulink url="http://www.gnu.org/software/gnuradio/doc/classgr__sync__interpolator.html">
836 <classname>gr_sync_interpolator</classname></ulink>
838 <ulink url="http://www.gnu.org/software/gnuradio/doc/classgr__sync__block.html">
839 <classname>gr_sync_block</classname></ulink>
840 and implements a 1:N block with optional history.
849 <title>Second Block: <classname>howto_square2_ff</classname></title>
851 <para>Given that we now know about
852 <classname>gr_sync_block</classname>, the way
853 <classname>howto_square_ff</classname> should really be implemented is
854 by subclassing <classname>gr_sync_block</classname>.</para>
856 <para>Here are the revised sources: <xref
857 linkend="howto_square2_ff.h"/>,
858 <xref linkend="howto_square2_ff.cc"/>.
859 The accompanying files contain the additional test code.
862 <example id="howto_square2_ff.h">
863 <title><filename>howto_square2_ff.h</filename></title>
864 &howto_square2_ff_h_listing;
867 <example id="howto_square2_ff.cc">
868 <title><filename>howto_square2_ff.cc</filename></title>
869 &howto_square2_ff_cc_listing;
874 <sect1 id="where_to"><title>Where to from Here?</title>
876 <para>At this point, we've got a basic overview of how the system
877 goes together. For more insight, I suggest that you look at the code
878 of the system. The doxygen generated <ulink
879 url="http://www.gnu.org/software/gnuradio/doc/hierarchy.html"> class
880 hierarchy</ulink> is a useful way to find things that might interest
886 <sect1 id="tips"><title>Miscellaneous Tips</title>
888 <sect2 id="sources_and_sinks"><title>Sources and Sinks</title>
890 <para>Sources and sinks are derived from
891 <classname>gr_sync_block</classname>. The only thing different about
892 them is that sources have no inputs and sinks have no outputs. This
893 is reflected in the <classname>gr_io_signature</classname>s that are
894 passed to the <classname>gr_sync_block</classname> constructor.
895 Take a look at <filename>gr_file_source.{h,cc}</filename> and
896 <filename>gr_file_sink.{h,cc}</filename> for some very straight-forward examples.
901 <sect2 id="debugging">
902 <title>Debugging with <application>gdb</application></title>
904 <para>If your block isn't working, and you can't sort it
905 out through python test cases or a few printfs in the code, you may want to
906 use <application>gdb</application> to debug it. The trick of course
907 is that all of &gnuradio;, including your new block, is dynamically
908 loaded into python for execution.</para>
910 <para>Try this: In your python test code, after the relevant imports,
911 print out the process id and wait for a keystroke. In another
912 window run gdb and tell it to attach to the python process with the
913 given process id. At this point you can set breakpoints or whatever
914 in your code. Go back to the python window and hit Enter so
915 it'll continue.</para>
918 #!/usr/bin/env python
919 from gnuradio import gr
920 from gnuradio import my_buggy_module
922 # insert this in your test code...
924 print 'Blocked waiting for GDB attach (pid = %d)' % (os.getpid(),)
925 raw_input ('Press Enter to continue: ')
926 # remainder of your test code follows...
929 <para>Another SNAFU you might run into is that gdb 6.2 isn't
930 able to set breakpoints in the constructors or destructors generated
931 by g++ 3.4. In this case, insert a call to the nop function
932 gri_debugger_hook in the constructor and recompile. Load the code as
933 before and set a break point on gri_debugger_hook.</para>
937 <sect2 id="oprofile">
938 <title>Performance Measurement with <application>oprofile</application></title>
939 <para>Oprofile is your friend.
940 See <ulink url="http://oprofile.sourceforge.net">http://oprofile.sourceforge.net</ulink>.
944 </sect1><!-- end tips -->
946 <sect1 id="futures"><title>Coming Attractions</title>
949 <sect2 id="types"><title>Improved Type System</title>
953 <sect2 id="hierarchy"><title>Hierarchical Blocks</title>
957 </sect1><!-- end Coming Attractions -->