summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--config/grc_gnuradio_examples.m43
-rw-r--r--configure.ac2
-rw-r--r--gnuradio-core/src/lib/runtime/Makefile.am20
-rw-r--r--gnuradio-core/src/lib/runtime/gr_basic_block.cc59
-rw-r--r--gnuradio-core/src/lib/runtime/gr_basic_block.h99
-rw-r--r--gnuradio-core/src/lib/runtime/gr_basic_block.i52
-rw-r--r--gnuradio-core/src/lib/runtime/gr_block.cc23
-rw-r--r--gnuradio-core/src/lib/runtime/gr_block.h66
-rw-r--r--gnuradio-core/src/lib/runtime/gr_block.i16
-rw-r--r--gnuradio-core/src/lib/runtime/gr_block_detail.cc3
-rw-r--r--gnuradio-core/src/lib/runtime/gr_block_detail.h28
-rw-r--r--gnuradio-core/src/lib/runtime/gr_hier_block2.cc63
-rw-r--r--gnuradio-core/src/lib/runtime/gr_hier_block2.h67
-rw-r--r--gnuradio-core/src/lib/runtime/gr_hier_block2.i52
-rw-r--r--gnuradio-core/src/lib/runtime/gr_hier_block2_detail.cc227
-rw-r--r--gnuradio-core/src/lib/runtime/gr_hier_block2_detail.h66
-rw-r--r--gnuradio-core/src/lib/runtime/gr_runtime.cc70
-rw-r--r--gnuradio-core/src/lib/runtime/gr_runtime.h49
-rw-r--r--gnuradio-core/src/lib/runtime/gr_runtime.i42
-rw-r--r--gnuradio-core/src/lib/runtime/gr_runtime_impl.cc130
-rw-r--r--gnuradio-core/src/lib/runtime/gr_runtime_impl.h74
-rw-r--r--gnuradio-core/src/lib/runtime/gr_runtime_types.h24
-rw-r--r--gnuradio-core/src/lib/runtime/gr_simple_flowgraph.cc67
-rw-r--r--gnuradio-core/src/lib/runtime/gr_simple_flowgraph.h52
-rw-r--r--gnuradio-core/src/lib/runtime/gr_simple_flowgraph.i45
-rw-r--r--gnuradio-core/src/lib/runtime/gr_simple_flowgraph_detail.cc471
-rw-r--r--gnuradio-core/src/lib/runtime/gr_simple_flowgraph_detail.h128
-rw-r--r--gnuradio-core/src/lib/runtime/qa_gr_block.cc1
-rw-r--r--gnuradio-core/src/lib/runtime/qa_gr_hier_block2.cc46
-rw-r--r--gnuradio-core/src/lib/runtime/qa_gr_hier_block2.h43
-rw-r--r--gnuradio-core/src/lib/runtime/qa_runtime.cc2
-rw-r--r--gnuradio-core/src/lib/runtime/runtime.i7
-rw-r--r--gnuradio-core/src/python/gnuradio/gr/Makefile.am2
-rw-r--r--gnuradio-core/src/python/gnuradio/gr/__init__.py2
-rw-r--r--gnuradio-core/src/python/gnuradio/gr/hier_block2.py40
-rwxr-xr-xgnuradio-core/src/python/gnuradio/gr/qa_hier_block2.py238
-rwxr-xr-xgnuradio-core/src/python/gnuradio/gr/qa_runtime.py31
-rwxr-xr-xgnuradio-core/src/python/gnuradio/gr/qa_simple_flowgraph.py142
-rw-r--r--gnuradio-examples/Makefile.am2
-rw-r--r--gnuradio-examples/c++/Makefile.am27
-rw-r--r--gnuradio-examples/c++/dialtone/Makefile.am48
-rw-r--r--gnuradio-examples/c++/dialtone/dialtone.cc45
-rw-r--r--gnuradio-examples/c++/dialtone/dialtone.h33
-rw-r--r--gnuradio-examples/c++/dialtone/main.cc38
-rw-r--r--gnuradio-examples/c++/hier/Makefile.am56
-rw-r--r--gnuradio-examples/c++/hier/dialtone.cc48
-rw-r--r--gnuradio-examples/c++/hier/dialtone.h33
-rw-r--r--gnuradio-examples/c++/hier/main.cc38
-rw-r--r--gnuradio-examples/c++/hier/output.cc41
-rw-r--r--gnuradio-examples/c++/hier/output.h33
-rw-r--r--gnuradio-examples/c++/hier/siggen.cc42
-rw-r--r--gnuradio-examples/c++/hier/siggen.h33
-rw-r--r--gnuradio-examples/c++/hier/sink.cc45
-rw-r--r--gnuradio-examples/c++/hier/sink.h33
-rw-r--r--gnuradio-examples/c++/hier/source.cc41
-rw-r--r--gnuradio-examples/c++/hier/source.h33
-rw-r--r--gnuradio-examples/python/audio/Makefile.am1
-rwxr-xr-xgnuradio-examples/python/audio/dial_tone2.py61
-rw-r--r--gr-audio-alsa/src/Makefile.am12
59 files changed, 3191 insertions, 104 deletions
diff --git a/config/grc_gnuradio_examples.m4 b/config/grc_gnuradio_examples.m4
index 5b987d617..4e95ea02b 100644
--- a/config/grc_gnuradio_examples.m4
+++ b/config/grc_gnuradio_examples.m4
@@ -22,6 +22,9 @@ AC_DEFUN([GRC_GNURADIO_EXAMPLES],[
AC_CONFIG_FILES([ \
gnuradio-examples/Makefile \
+ gnuradio-examples/c++/Makefile \
+ gnuradio-examples/c++/dialtone/Makefile \
+ gnuradio-examples/c++/hier/Makefile \
gnuradio-examples/python/Makefile \
gnuradio-examples/python/apps/hf_explorer/Makefile \
gnuradio-examples/python/apps/hf_radio/Makefile \
diff --git a/configure.ac b/configure.ac
index f3254a33f..bede23767 100644
--- a/configure.ac
+++ b/configure.ac
@@ -160,7 +160,6 @@ AC_ARG_ENABLE(
build_dirs="config"
GRC_GNURADIO_CORE
-GRC_GNURADIO_EXAMPLES
GRC_USRP
GRC_GR_USRP dnl this must come after GRC_USRP
GRC_GR_AUDIO_ALSA
@@ -184,6 +183,7 @@ GRC_MBLOCK dnl this must come after GRC_PMT
GRC_EZDOP
GRC_GR_EZDOP dnl this must come after GRC_EZDOP
GRC_GR_RDF
+GRC_GNURADIO_EXAMPLES dnl must come last
# Each component is now either to be built, was skipped, or failed dependencies
AC_SUBST([build_dirs], [$build_dirs])
diff --git a/gnuradio-core/src/lib/runtime/Makefile.am b/gnuradio-core/src/lib/runtime/Makefile.am
index 2c1ea7eff..47ae07a6b 100644
--- a/gnuradio-core/src/lib/runtime/Makefile.am
+++ b/gnuradio-core/src/lib/runtime/Makefile.am
@@ -30,8 +30,13 @@ libruntime_la_LIBADD = \
libruntime_la_SOURCES = \
+ gr_basic_block.cc \
+ gr_simple_flowgraph.cc \
+ gr_simple_flowgraph_detail.cc \
gr_block.cc \
gr_block_detail.cc \
+ gr_hier_block2.cc \
+ gr_hier_block2_detail.cc \
gr_buffer.cc \
gr_dispatcher.cc \
gr_error_handler.cc \
@@ -43,6 +48,8 @@ libruntime_la_SOURCES = \
gr_pagesize.cc \
gr_preferences.cc \
gr_realtime.cc \
+ gr_runtime.cc \
+ gr_runtime_impl.cc \
gr_single_threaded_scheduler.cc \
gr_tmp_path.cc \
gr_vmcircbuf.cc \
@@ -54,14 +61,20 @@ libruntime_la_SOURCES = \
libruntime_qa_la_SOURCES = \
qa_gr_block.cc \
+ qa_gr_hier_block2.cc \
qa_gr_buffer.cc \
qa_gr_io_signature.cc \
qa_gr_vmcircbuf.cc \
qa_runtime.cc
grinclude_HEADERS = \
+ gr_basic_block.h \
+ gr_simple_flowgraph.h \
+ gr_simple_flowgraph_detail.h \
gr_block.h \
gr_block_detail.h \
+ gr_hier_block2.h \
+ gr_hier_block2_detail.h \
gr_buffer.h \
gr_complex.h \
gr_dispatcher.h \
@@ -74,6 +87,8 @@ grinclude_HEADERS = \
gr_pagesize.h \
gr_preferences.h \
gr_realtime.h \
+ gr_runtime.h \
+ gr_runtime_impl.h \
gr_runtime_types.h \
gr_select_handler.h \
gr_single_threaded_scheduler.h \
@@ -88,14 +103,17 @@ noinst_HEADERS = \
gr_vmcircbuf_sysv_shm.h \
gr_vmcircbuf_createfilemapping.h \
qa_gr_block.h \
+ qa_gr_hier_block2.h \
qa_gr_buffer.h \
qa_gr_io_signature.h \
qa_gr_vmcircbuf.h \
qa_runtime.h
swiginclude_HEADERS = \
+ gr_basic_block.i \
gr_block.i \
gr_block_detail.i \
+ gr_hier_block2.i \
gr_buffer.i \
gr_dispatcher.i \
gr_error_handler.i \
@@ -104,6 +122,8 @@ swiginclude_HEADERS = \
gr_msg_handler.i \
gr_msg_queue.i \
gr_realtime.i \
+ gr_runtime.i \
+ gr_simple_flowgraph.i \
gr_single_threaded_scheduler.i \
gr_swig_block_magic.i \
runtime.i
diff --git a/gnuradio-core/src/lib/runtime/gr_basic_block.cc b/gnuradio-core/src/lib/runtime/gr_basic_block.cc
new file mode 100644
index 000000000..a5f1a4f83
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_basic_block.cc
@@ -0,0 +1,59 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006 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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_basic_block.h>
+#include <stdexcept>
+
+static long s_next_id = 0;
+static long s_ncurrently_allocated = 0;
+
+long
+gr_basic_block_ncurrently_allocated()
+{
+ return s_ncurrently_allocated;
+}
+
+gr_basic_block::gr_basic_block(const std::string &name,
+ gr_io_signature_sptr input_signature,
+ gr_io_signature_sptr output_signature)
+ : d_name(name),
+ d_input_signature(input_signature),
+ d_output_signature(output_signature),
+ d_unique_id(s_next_id++)
+{
+ s_ncurrently_allocated++;
+}
+
+gr_basic_block::~gr_basic_block()
+{
+ s_ncurrently_allocated--;
+}
+
+gr_basic_block_sptr
+gr_basic_block::basic_block()
+{
+ return shared_from_this();
+}
diff --git a/gnuradio-core/src/lib/runtime/gr_basic_block.h b/gnuradio-core/src/lib/runtime/gr_basic_block.h
new file mode 100644
index 000000000..583c3241d
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_basic_block.h
@@ -0,0 +1,99 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006 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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_BASIC_BLOCK_H
+#define INCLUDED_GR_BASIC_BLOCK_H
+
+#include <gr_runtime_types.h>
+#include <boost/enable_shared_from_this.hpp>
+#include <string>
+
+/*!
+ * \brief The abstract base class for all signal processing blocks.
+ * \ingroup block
+ *
+ * Basic blocks are the bare abstraction of an entity that has a name
+ * and a set of inputs and outputs. These are never instantiated
+ * directly; rather, this is the abstract parent class of both gr_hier_block,
+ * which is a recursive container, and gr_block, which implements actual
+ * signal processing functions.
+ */
+
+class gr_basic_block : public boost::enable_shared_from_this<gr_basic_block>
+{
+protected:
+ std::string d_name;
+ gr_io_signature_sptr d_input_signature;
+ gr_io_signature_sptr d_output_signature;
+ long d_unique_id;
+
+ //! Protected constructor prevents instantiation by non-derived classes
+ gr_basic_block(const std::string &name,
+ gr_io_signature_sptr input_signature,
+ gr_io_signature_sptr output_signature);
+
+ //! may only be called during constructor
+ void set_input_signature(gr_io_signature_sptr iosig) {
+ d_input_signature = iosig;
+ }
+
+ //! may only be called during constructor
+ void set_output_signature(gr_io_signature_sptr iosig) {
+ d_output_signature = iosig;
+ }
+
+public:
+ virtual ~gr_basic_block();
+ long unique_id() const { return d_unique_id; }
+ std::string name() const { return d_name; }
+ gr_io_signature_sptr input_signature() const { return d_input_signature; }
+ gr_io_signature_sptr output_signature() const { return d_output_signature; }
+ gr_basic_block_sptr basic_block(); // Needed for Python type coercion
+
+ /*!
+ * \brief Confirm that ninputs and noutputs is an acceptable combination.
+ *
+ * \param ninputs number of input streams connected
+ * \param noutputs number of output streams connected
+ *
+ * \returns true if this is a valid configuration for this block.
+ *
+ * This function is called by the runtime system whenever the
+ * topology changes. Most classes do not need to override this.
+ * This check is in addition to the constraints specified by the input
+ * and output gr_io_signatures.
+ */
+ virtual bool check_topology(int ninputs, int noutputs) { return true; }
+};
+
+typedef std::vector<gr_basic_block_sptr> gr_basic_block_vector_t;
+typedef std::vector<gr_basic_block_sptr>::iterator gr_basic_block_viter_t;
+
+long gr_basic_block_ncurrently_allocated();
+
+inline std::ostream &operator << (std::ostream &os, gr_basic_block_sptr basic_block)
+{
+ os << basic_block->name() << "(" << basic_block->unique_id() << ")";
+ return os;
+}
+
+#endif /* INCLUDED_GR_BASIC_BLOCK_H */
diff --git a/gnuradio-core/src/lib/runtime/gr_basic_block.i b/gnuradio-core/src/lib/runtime/gr_basic_block.i
new file mode 100644
index 000000000..33b895d43
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_basic_block.i
@@ -0,0 +1,52 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006 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 2, 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.
+ */
+
+class gr_basic_block;
+typedef boost::shared_ptr<gr_basic_block> gr_basic_block_sptr;
+%template(gr_basic_block_sptr) boost::shared_ptr<gr_basic_block>;
+
+// support vectors of these...
+namespace std {
+ %template(x_vector_gr_basic_block_sptr) vector<gr_basic_block_sptr>;
+};
+
+class gr_basic_block
+{
+protected:
+ gr_basic_block();
+
+public:
+ virtual ~gr_basic_block();
+ std::string name() const;
+ gr_io_signature_sptr input_signature() const;
+ gr_io_signature_sptr output_signature() const;
+ long unique_id() const;
+ gr_basic_block_sptr basic_block();
+ bool check_topology (int ninputs, int noutputs);
+};
+
+%rename(block_ncurrently_allocated) gr_basic_block_ncurrently_allocated;
+long gr_basic_block_ncurrently_allocated();
+
+%pythoncode %{
+gr_basic_block_sptr.__repr__ = lambda self: "<gr_basic_block %s (%d)>" % (self.name(), self.unique_id ())
+%}
diff --git a/gnuradio-core/src/lib/runtime/gr_block.cc b/gnuradio-core/src/lib/runtime/gr_block.cc
index 65e16045a..1b1d35756 100644
--- a/gnuradio-core/src/lib/runtime/gr_block.cc
+++ b/gnuradio-core/src/lib/runtime/gr_block.cc
@@ -27,34 +27,21 @@
#include <gr_block.h>
#include <gr_block_detail.h>
#include <stdexcept>
-
-static long s_next_id = 0;
-static long s_ncurrently_allocated = 0;
-
-long
-gr_block_ncurrently_allocated ()
-{
- return s_ncurrently_allocated;
-}
+#include <iostream>
gr_block::gr_block (const std::string &name,
gr_io_signature_sptr input_signature,
gr_io_signature_sptr output_signature)
- : d_name (name),
- d_input_signature (input_signature),
- d_output_signature (output_signature),
+ : gr_basic_block(name, input_signature, output_signature),
d_output_multiple (1),
d_relative_rate (1.0),
- d_unique_id (s_next_id++),
d_history(1),
d_fixed_rate(false)
{
- s_ncurrently_allocated++;
}
gr_block::~gr_block ()
{
- s_ncurrently_allocated--;
}
// stub implementation: 1:1
@@ -70,12 +57,6 @@ gr_block::forecast (int noutput_items, gr_vector_int &ninput_items_required)
// default implementation
bool
-gr_block::check_topology (int ninputs, int noutputs)
-{
- return true;
-}
-
-bool
gr_block::start()
{
return true;
diff --git a/gnuradio-core/src/lib/runtime/gr_block.h b/gnuradio-core/src/lib/runtime/gr_block.h
index 9723be108..247238bb0 100644
--- a/gnuradio-core/src/lib/runtime/gr_block.h
+++ b/gnuradio-core/src/lib/runtime/gr_block.h
@@ -23,13 +23,17 @@
#ifndef INCLUDED_GR_BLOCK_H
#define INCLUDED_GR_BLOCK_H
-#include <gr_runtime_types.h>
-#include <string>
+#include <gr_basic_block.h>
/*!
- * \brief The abstract base class for all signal processing blocks.
+ * \brief The abstract base class for all 'terminal' processing blocks.
* \ingroup block
*
+ * A signal processing flow is constructed by creating a tree of
+ * hierarchical blocks, which at any level may also contain terminal nodes
+ * that actually implement signal processing functions. This is the base
+ * class for all such leaf nodes.
+
* Blocks have a set of input streams and output streams. The
* input_signature and output_signature define the number of input
* streams and output streams respectively, and the type of the data
@@ -49,16 +53,11 @@
* It reads the input items and writes the output items.
*/
-class gr_block {
+class gr_block : public gr_basic_block {
public:
virtual ~gr_block ();
-
- std::string name () const { return d_name; }
- gr_io_signature_sptr input_signature () const { return d_input_signature; }
- gr_io_signature_sptr output_signature () const { return d_output_signature; }
- long unique_id () const { return d_unique_id; }
/*!
* Assume block computes y_i = f(x_i, x_i-1, x_i-2, x_i-3...)
@@ -114,21 +113,6 @@ class gr_block {
gr_vector_void_star &output_items) = 0;
/*!
- * \brief Confirm that ninputs and noutputs is an acceptable combination.
- *
- * \param ninputs number of input streams connected
- * \param noutputs number of output streams connected
- *
- * \returns true if this is a valid configuration for this block.
- *
- * This function is called by the runtime system whenever the
- * topology changes. Most classes do not need to override this.
- * This check is in addition to the constraints specified by the input
- * and output gr_io_signatures.
- */
- virtual bool check_topology (int ninputs, int noutputs);
-
- /*!
* \brief Called to enable drivers, etc for i/o devices.
*
* This allows a block to enable an associated driver to begin
@@ -205,32 +189,17 @@ class gr_block {
private:
- std::string d_name;
- gr_io_signature_sptr d_input_signature;
- gr_io_signature_sptr d_output_signature;
- int d_output_multiple;
- double d_relative_rate; // approx output_rate / input_rate
- gr_block_detail_sptr d_detail; // implementation details
- long d_unique_id; // convenient for debugging
- unsigned d_history;
- bool d_fixed_rate;
-
-
+ int d_output_multiple;
+ double d_relative_rate; // approx output_rate / input_rate
+ gr_block_detail_sptr d_detail; // implementation details
+ unsigned d_history;
+ bool d_fixed_rate;
+
protected:
gr_block (const std::string &name,
- gr_io_signature_sptr input_signature,
- gr_io_signature_sptr output_signature);
-
- //! may only be called during constructor
- void set_input_signature (gr_io_signature_sptr iosig){
- d_input_signature = iosig;
- }
-
- //! may only be called during constructor
- void set_output_signature (gr_io_signature_sptr iosig){
- d_output_signature = iosig;
- }
+ gr_io_signature_sptr input_signature,
+ gr_io_signature_sptr output_signature);
void set_fixed_rate(bool fixed_rate){ d_fixed_rate = fixed_rate; }
@@ -242,6 +211,7 @@ class gr_block {
void set_detail (gr_block_detail_sptr detail) { d_detail = detail; }
};
-long gr_block_ncurrently_allocated ();
+typedef std::vector<gr_block_sptr> gr_block_vector_t;
+typedef std::vector<gr_block_sptr>::iterator gr_block_viter_t;
#endif /* INCLUDED_GR_BLOCK_H */
diff --git a/gnuradio-core/src/lib/runtime/gr_block.i b/gnuradio-core/src/lib/runtime/gr_block.i
index 3bfd24367..5d0f5fb1b 100644
--- a/gnuradio-core/src/lib/runtime/gr_block.i
+++ b/gnuradio-core/src/lib/runtime/gr_block.i
@@ -20,6 +20,8 @@
* Boston, MA 02110-1301, USA.
*/
+%include <gr_basic_block.i>
+
class gr_block;
typedef boost::shared_ptr<gr_block> gr_block_sptr;
%template(gr_block_sptr) boost::shared_ptr<gr_block>;
@@ -29,26 +31,21 @@ namespace std {
%template(x_vector_gr_block_sptr) vector<gr_block_sptr>;
};
-class gr_block {
+class gr_block : public gr_basic_block {
protected:
gr_block (const std::string &name,
- gr_io_signature_sptr input_signature,
- gr_io_signature_sptr output_signature);
+ gr_io_signature_sptr input_signature,
+ gr_io_signature_sptr output_signature);
public:
virtual ~gr_block ();
- std::string name () const;
- gr_io_signature_sptr input_signature () const;
- gr_io_signature_sptr output_signature () const;
- long unique_id () const;
unsigned history () const;
int output_multiple () const;
double relative_rate () const;
- bool check_topology (int ninputs, int noutputs);
bool start();
bool stop();
@@ -57,9 +54,6 @@ class gr_block {
void set_detail (gr_block_detail_sptr detail) { d_detail = detail; }
};
-%rename(block_ncurrently_allocated) gr_block_ncurrently_allocated;
-long gr_block_ncurrently_allocated ();
-
%pythoncode %{
gr_block_sptr.__repr__ = lambda self: "<gr_block %s (%d)>" % (self.name(), self.unique_id ())
gr_block_sptr.block = lambda self: self
diff --git a/gnuradio-core/src/lib/runtime/gr_block_detail.cc b/gnuradio-core/src/lib/runtime/gr_block_detail.cc
index ed414d472..5feb180f7 100644
--- a/gnuradio-core/src/lib/runtime/gr_block_detail.cc
+++ b/gnuradio-core/src/lib/runtime/gr_block_detail.cc
@@ -38,7 +38,8 @@ gr_block_detail_ncurrently_allocated ()
gr_block_detail::gr_block_detail (unsigned int ninputs, unsigned int noutputs)
: d_ninputs (ninputs), d_noutputs (noutputs),
d_input (ninputs), d_output (noutputs),
- d_done (false)
+ d_done (false),
+ d_color (gr_block_detail::WHITE)
{
s_ncurrently_allocated++;
}
diff --git a/gnuradio-core/src/lib/runtime/gr_block_detail.h b/gnuradio-core/src/lib/runtime/gr_block_detail.h
index 8c4615919..d89b7fea1 100644
--- a/gnuradio-core/src/lib/runtime/gr_block_detail.h
+++ b/gnuradio-core/src/lib/runtime/gr_block_detail.h
@@ -1,19 +1,19 @@
/* -*- c++ -*- */
/*
* Copyright 2004 Free Software Foundation, Inc.
- *
+ *
* This file is part of GNU Radio
- *
+ *
* GNU Radio is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, 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 detail.
- *
+ *
* 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,
@@ -75,18 +75,26 @@ class gr_block_detail {
void produce_each (int how_many_items);
+ /*!
+ * \brief Allow the flowgraph to set for sorting and partitioning
+ */
+ enum vcolor { WHITE, GREY, BLACK };
+ void set_color(vcolor color) { d_color = color; }
+ vcolor color() const { return d_color; }
+
// ----------------------------------------------------------------------------
private:
- unsigned int d_ninputs;
- unsigned int d_noutputs;
+ unsigned int d_ninputs;
+ unsigned int d_noutputs;
std::vector<gr_buffer_reader_sptr> d_input;
- std::vector<gr_buffer_sptr> d_output;
- bool d_done;
-
+ std::vector<gr_buffer_sptr> d_output;
+ bool d_done;
+ vcolor d_color;
+
gr_block_detail (unsigned int ninputs, unsigned int noutputs);
- friend gr_block_detail_sptr
+ friend gr_block_detail_sptr
gr_make_block_detail (unsigned int ninputs, unsigned int noutputs);
};
diff --git a/gnuradio-core/src/lib/runtime/gr_hier_block2.cc b/gnuradio-core/src/lib/runtime/gr_hier_block2.cc
new file mode 100644
index 000000000..65dea95fb
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_hier_block2.cc
@@ -0,0 +1,63 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006 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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_hier_block2.h>
+#include <gr_io_signature.h>
+#include <gr_hier_block2_detail.h>
+#include <iostream>
+
+gr_hier_block2_sptr gr_make_hier_block2(const std::string &name,
+ gr_io_signature_sptr input_signature,
+ gr_io_signature_sptr output_signature)
+{
+ return gr_hier_block2_sptr(new gr_hier_block2(name, input_signature, output_signature));
+}
+
+gr_hier_block2::gr_hier_block2(const std::string &name,
+ gr_io_signature_sptr input_signature,
+ gr_io_signature_sptr output_signature)
+ : gr_basic_block(name, input_signature, output_signature),
+ d_detail(new gr_hier_block2_detail(this))
+{
+}
+
+gr_hier_block2::~gr_hier_block2()
+{
+ delete d_detail;
+}
+
+void
+gr_hier_block2::define_component(const std::string &name, gr_basic_block_sptr block)
+{
+ d_detail->define_component(name, block);
+}
+
+void
+gr_hier_block2::connect(const std::string &src_name, int src_port,
+ const std::string &dst_name, int dst_port)
+{
+ d_detail->connect(src_name, src_port, dst_name, dst_port);
+}
diff --git a/gnuradio-core/src/lib/runtime/gr_hier_block2.h b/gnuradio-core/src/lib/runtime/gr_hier_block2.h
new file mode 100644
index 000000000..9d2dd3569
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_hier_block2.h
@@ -0,0 +1,67 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006 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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+#ifndef INCLUDED_GR_HIER_BLOCK2_H
+#define INCLUDED_GR_HIER_BLOCK2_H
+
+#include <gr_basic_block.h>
+
+/*!
+ * \brief public constructor for gr_hier_block2
+ */
+gr_hier_block2_sptr gr_make_hier_block2(const std::string &name,
+ gr_io_signature_sptr input_signature,
+ gr_io_signature_sptr output_signature);
+
+class gr_hier_block2_detail;
+
+/*!
+ * \brief gr_hier_block2 - Hierarchical container class for gr_block's
+ *
+ */
+class gr_hier_block2 : public gr_basic_block
+{
+private:
+ friend class gr_hier_block2_detail;
+ friend class gr_runtime_impl;
+ friend gr_hier_block2_sptr gr_make_hier_block2(const std::string &name,
+ gr_io_signature_sptr input_signature,
+ gr_io_signature_sptr output_signature);
+
+ /*!
+ * \brief Private implementation details of gr_hier_block2
+ */
+ gr_hier_block2_detail *d_detail;
+
+protected:
+ gr_hier_block2(const std::string &name,
+ gr_io_signature_sptr input_signature,
+ gr_io_signature_sptr output_signature);
+
+public:
+ virtual ~gr_hier_block2();
+
+ void define_component(const std::string &name, gr_basic_block_sptr basic_block);
+ void connect(const std::string &src_name, int src_port,
+ const std::string &dst_name, int dst_port);
+};
+
+#endif /* INCLUDED_GR_HIER_BLOCK2_H */
diff --git a/gnuradio-core/src/lib/runtime/gr_hier_block2.i b/gnuradio-core/src/lib/runtime/gr_hier_block2.i
new file mode 100644
index 000000000..c5a676534
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_hier_block2.i
@@ -0,0 +1,52 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2005 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 2, 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 <gr_basic_block.i>
+
+class gr_hier_block2;
+typedef boost::shared_ptr<gr_hier_block2> gr_hier_block2_sptr;
+%template(gr_hier_block2_sptr) boost::shared_ptr<gr_hier_block2>;
+
+// Hack to have a Python shim implementation of gr.hier_block2
+// that instantiates one of these and passes through calls
+%rename(hier_block2_swig) gr_make_hier_block2;
+gr_hier_block2_sptr gr_make_hier_block2(const std::string name,
+ gr_io_signature_sptr input_signature,
+ gr_io_signature_sptr output_signature);
+
+class gr_hier_block2 : public gr_basic_block
+{
+private:
+ gr_hier_block2(const std::string name,
+ gr_io_signature_sptr input_signature,
+ gr_io_signature_sptr output_signature);
+
+public:
+ ~gr_hier_block2 ();
+
+ // Add a named block to the container
+ void define_component(const std::string &name, gr_basic_block_sptr basic_block)
+ throw (std::invalid_argument);
+ void connect(const std::string &src_name, int src_port,
+ const std::string &dst_name, int dst_port)
+ throw (std::invalid_argument);
+};
diff --git a/gnuradio-core/src/lib/runtime/gr_hier_block2_detail.cc b/gnuradio-core/src/lib/runtime/gr_hier_block2_detail.cc
new file mode 100644
index 000000000..545a64bfd
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_hier_block2_detail.cc
@@ -0,0 +1,227 @@
+/*
+ * Copyright 2006 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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_hier_block2_detail.h>
+#include <gr_simple_flowgraph.h>
+#include <gr_io_signature.h>
+#include <stdexcept>
+#include <iostream>
+
+gr_hier_block2_detail::gr_hier_block2_detail(gr_hier_block2 *owner) :
+d_owner(owner)
+{
+}
+
+gr_hier_block2_detail::~gr_hier_block2_detail()
+{
+ d_owner = 0; // Don't use delete, we didn't allocate
+}
+
+gr_basic_block_sptr
+gr_hier_block2_detail::lookup_block(const std::string &name)
+{
+ gr_hier_component_miter_t p = d_components.find(name);
+ if (p != d_components.end())
+ return p->second;
+ else
+ return gr_basic_block_sptr();
+}
+
+void
+gr_hier_block2_detail::define_component(const std::string &name, gr_basic_block_sptr block)
+{
+ if (!block)
+ throw std::invalid_argument("null block passed");
+
+ if (name == "self")
+ throw std::invalid_argument("name is reserved");
+
+ // TODO: reject names with '.' inside
+
+ if (!lookup_block(name))
+ d_components[name] = block;
+ else
+ throw std::invalid_argument("name already in use");
+}
+
+void
+gr_hier_block2_detail::connect(const std::string &src_name, int src_port,
+ const std::string &dst_name, int dst_port)
+{
+ gr_io_signature_sptr src_io_signature;
+ gr_io_signature_sptr dst_io_signature;
+
+ // Check against our *input_signature* if we're wiring from one of our external inputs
+ if (src_name == "self")
+ src_io_signature = d_owner->input_signature();
+ else {
+ gr_basic_block_sptr src_block = lookup_block(src_name);
+ if (!src_block)
+ throw std::invalid_argument("undefined src name");
+ src_io_signature = src_block->output_signature();
+ }
+
+ // Check against our *output_signature* if we're wiring to one of our external outputs
+ if (dst_name == "self")
+ dst_io_signature = d_owner->output_signature();
+ else {
+ gr_basic_block_sptr dst_block = lookup_block(dst_name);
+ if (!dst_block)
+ throw std::invalid_argument("undefined dst name");
+ dst_io_signature = dst_block->input_signature();
+ }
+
+ // Check port numbers are valid
+ check_valid_port(src_io_signature, src_port);
+ check_valid_port(dst_io_signature, dst_port);
+
+ // Check destination port not already in use
+ check_dst_not_used(dst_name, dst_port);
+
+ // Check endpoint types match
+ check_type_match(src_io_signature, src_port, dst_io_signature, dst_port);
+
+ d_edges.push_back(gr_make_edge(src_name, src_port, dst_name, dst_port));
+}
+
+void
+gr_hier_block2_detail::check_valid_port(gr_io_signature_sptr sig, int port)
+{
+ if (port < 0)
+ throw std::invalid_argument("port number must not be negative");
+
+ if (sig->max_streams() >= 0 && port >= sig->max_streams())
+ throw std::invalid_argument("port number exceeds max streams");
+}
+
+void
+gr_hier_block2_detail::check_dst_not_used(const std::string name, int port)
+{
+ for (gr_edge_viter_t p = d_edges.begin(); p != d_edges.end(); p++)
+ if ((*p)->dst_name() == name && (*p)->dst_port() == port)
+ throw std::invalid_argument("destination port in use");
+}
+
+void
+gr_hier_block2_detail::check_type_match(gr_io_signature_sptr src_sig, int src_port,
+ gr_io_signature_sptr dst_sig, int dst_port)
+{
+ if (src_sig->sizeof_stream_item(src_port) != dst_sig->sizeof_stream_item(dst_port))
+ throw std::invalid_argument("type mismatch");
+}
+
+std::string
+gr_hier_block2_detail::prepend_prefix(const std::string &prefix, const std::string &str)
+{
+ return prefix + ((prefix == "") ? "" : ".") + str;
+}
+
+gr_endpoint
+gr_hier_block2_detail::match_endpoint(const std::string &name, int port, bool is_input)
+{
+ for (gr_edge_viter_t p = d_edges.begin(); p != d_edges.end(); p++) {
+ if (is_input) {
+ if ((*p)->src_name() == name && (*p)->src_port() == port)
+ return resolve_endpoint((*p)->dst_name(), (*p)->dst_port(), "", !is_input);
+ }
+ else {
+ if ((*p)->dst_name() == name && (*p)->dst_port() == port)
+ return resolve_endpoint((*p)->src_name(), (*p)->src_port(), "", !is_input);
+ }
+ }
+
+ // Should never get here
+ throw std::runtime_error("unable to match endpoint");
+}
+
+gr_endpoint
+gr_hier_block2_detail::resolve_endpoint(const std::string &name, int port,
+ const std::string &prefix, bool is_input)
+{
+ gr_basic_block_sptr basic_block = lookup_block(name);
+
+ // Check if 'name' points to gr_block (leaf node)
+ gr_block_sptr block(boost::dynamic_pointer_cast<gr_block, gr_basic_block>(basic_block));
+ if (block)
+ return gr_endpoint(prepend_prefix(prefix, name), port);
+
+ // Check if 'name' points to hierarchical block
+ gr_hier_block2_sptr hier_block2(boost::dynamic_pointer_cast<gr_hier_block2, gr_basic_block>(basic_block));
+ if (hier_block2) {
+ std::string child_prefix = prepend_prefix(prefix, name);
+ gr_endpoint match(hier_block2->d_detail->match_endpoint("self", port, !is_input));
+ return gr_endpoint(prepend_prefix(child_prefix, match.name()), match.port());
+ }
+
+ // Shouldn't ever get here
+ throw std::runtime_error("unable to resolve endpoint");
+}
+
+void
+gr_hier_block2_detail::flatten(gr_simple_flowgraph_sptr sfg, const std::string &prefix)
+{
+ flatten_components(sfg, prefix);
+ flatten_edges(sfg, prefix);
+}
+
+void
+gr_hier_block2_detail::flatten_components(gr_simple_flowgraph_sptr sfg, const std::string &prefix)
+{
+ // Add my non-hierarchical components to the simple flowgraph, then recurse
+ for (gr_hier_component_miter_t p = d_components.begin(); p != d_components.end(); p++) {
+ std::string name = prepend_prefix(prefix, p->first);
+
+ gr_basic_block_sptr basic_block = p->second;
+ gr_block_sptr block(boost::dynamic_pointer_cast<gr_block, gr_basic_block>(basic_block));
+ if (block)
+ sfg->define_component(name, block);
+
+ gr_hier_block2_sptr hier_block2(boost::dynamic_pointer_cast<gr_hier_block2, gr_basic_block>(basic_block));
+ if (hier_block2)
+ hier_block2->d_detail->flatten_components(sfg, name);
+ }
+}
+
+void
+gr_hier_block2_detail::flatten_edges(gr_simple_flowgraph_sptr sfg, const std::string &prefix)
+{
+ // Add my edges to the flow graph, resolving references to actual endpoints
+ for (gr_edge_viter_t p = d_edges.begin(); p != d_edges.end(); p++) {
+ // Connections to self get resolved/added by parent if actually connected
+ if ((*p)->src_name() == "self" || (*p)->dst_name() == "self")
+ continue;
+
+ gr_endpoint src_endp = resolve_endpoint((*p)->src_name(), (*p)->src_port(), prefix, true);
+ gr_endpoint dst_endp = resolve_endpoint((*p)->dst_name(), (*p)->dst_port(), prefix, false);
+ sfg->connect(src_endp.name(), src_endp.port(), dst_endp.name(), dst_endp.port());
+ }
+
+ // Recurse hierarchical children
+ for (gr_hier_component_miter_t p = d_components.begin(); p != d_components.end(); p++) {
+ gr_hier_block2_sptr hier_block2(boost::dynamic_pointer_cast<gr_hier_block2, gr_basic_block>(p->second));
+ if (hier_block2)
+ hier_block2->d_detail->flatten_edges(sfg, prepend_prefix(prefix, p->first));
+ }
+}
diff --git a/gnuradio-core/src/lib/runtime/gr_hier_block2_detail.h b/gnuradio-core/src/lib/runtime/gr_hier_block2_detail.h
new file mode 100644
index 000000000..095bd40f5
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_hier_block2_detail.h
@@ -0,0 +1,66 @@
+/*
+ * Copyright 2006 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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+#ifndef INCLUDED_GR_HIER_BLOCK2_DETAIL_H
+#define INCLUDED_GR_HIER_BLOCK2_DETAIL_H
+
+#include <gr_hier_block2.h>
+#include <gr_simple_flowgraph_detail.h>
+#include <boost/utility.hpp>
+
+typedef std::map<std::string, gr_basic_block_sptr> gr_hier_component_map_t;
+typedef std::map<std::string, gr_basic_block_sptr>::iterator gr_hier_component_miter_t;
+
+class gr_hier_block2_detail : boost::noncopyable
+{
+private:
+ friend class gr_hier_block2;
+ friend class gr_runtime_impl;
+
+ // Constructor--it's private, only friends can instantiate
+ gr_hier_block2_detail(gr_hier_block2 *owner);
+
+ // Private implementation data
+ gr_hier_block2 *d_owner;
+ gr_hier_component_map_t d_components;
+ gr_edge_vector_t d_edges;
+
+ // Private implementation methods
+ void define_component(const std::string &name, gr_basic_block_sptr block);
+ gr_basic_block_sptr lookup_block(const std::string &name);
+ void connect(const std::string &src_name, int src_port,
+ const std::string &dst_name, int dst_port);
+ void check_valid_port(gr_io_signature_sptr sig, int port);
+ void check_dst_not_used(const std::string name, int port);
+ void check_type_match(gr_io_signature_sptr src_sig, int src_port,
+ gr_io_signature_sptr dst_sig, int dst_port);
+ std::string prepend_prefix(const std::string &prefix, const std::string &str);
+ void flatten(gr_simple_flowgraph_sptr sfg, const std::string &prefix = "");
+ void flatten_components(gr_simple_flowgraph_sptr sfg, const std::string &prefix);
+ void flatten_edges(gr_simple_flowgraph_sptr sfg, const std::string &prefix);
+ gr_endpoint match_endpoint(const std::string &name, int port, bool is_input);
+ gr_endpoint resolve_endpoint(const std::string &name, int port,
+ const std::string &prefix, bool is_input);
+
+public:
+ ~gr_hier_block2_detail();
+};
+
+#endif /* INCLUDED_GR_HIER_BLOCK2_DETAIL_H */
diff --git a/gnuradio-core/src/lib/runtime/gr_runtime.cc b/gnuradio-core/src/lib/runtime/gr_runtime.cc
new file mode 100644
index 000000000..926e87857
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_runtime.cc
@@ -0,0 +1,70 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006 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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_runtime.h>
+#include <gr_runtime_impl.h>
+#include <iostream>
+
+gr_runtime_sptr
+gr_make_runtime(gr_hier_block2_sptr top_block)
+{
+ return gr_runtime_sptr(new gr_runtime(top_block));
+}
+
+gr_runtime::gr_runtime(gr_hier_block2_sptr top_block)
+{
+ d_impl = new gr_runtime_impl(top_block);
+}
+
+gr_runtime::~gr_runtime()
+{
+ delete d_impl;
+}
+
+void
+gr_runtime::start()
+{
+ d_impl->start();
+}
+
+void
+gr_runtime::stop()
+{
+ d_impl->stop();
+}
+
+void
+gr_runtime::wait()
+{
+ d_impl->wait();
+}
+
+void
+gr_runtime::run()
+{
+ start();
+ wait();
+}
diff --git a/gnuradio-core/src/lib/runtime/gr_runtime.h b/gnuradio-core/src/lib/runtime/gr_runtime.h
new file mode 100644
index 000000000..fc58da456
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_runtime.h
@@ -0,0 +1,49 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006 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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_RUNTIME_H
+#define INCLUDED_GR_RUNTIME_H
+
+#include <gr_runtime_types.h>
+
+class gr_runtime_impl;
+
+gr_runtime_sptr gr_make_runtime(gr_hier_block2_sptr top_block);
+
+class gr_runtime
+{
+private:
+ gr_runtime(gr_hier_block2_sptr top_block);
+ friend gr_runtime_sptr gr_make_runtime(gr_hier_block2_sptr top_block);
+
+ gr_runtime_impl *d_impl;
+
+public:
+ ~gr_runtime();
+
+ void start();
+ void stop();
+ void wait();
+ void run();
+};
+
+#endif /* INCLUDED_GR_RUNTIME_H */
diff --git a/gnuradio-core/src/lib/runtime/gr_runtime.i b/gnuradio-core/src/lib/runtime/gr_runtime.i
new file mode 100644
index 000000000..496adff37
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_runtime.i
@@ -0,0 +1,42 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, 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.
+ */
+
+class gr_runtime;
+typedef boost::shared_ptr<gr_runtime> gr_runtime_sptr;
+%template(gr_runtime_sptr) boost::shared_ptr<gr_runtime>;
+
+%rename(runtime) gr_make_runtime;
+gr_runtime_sptr gr_make_runtime(gr_hier_block2_sptr top_block);
+
+class gr_runtime
+{
+protected:
+ gr_runtime(gr_hier_block2_sptr top_block);
+
+public:
+ void start()
+ throw (std::runtime_error);
+ void stop();
+ void wait();
+ void run()
+ throw (std::runtime_error);
+};
diff --git a/gnuradio-core/src/lib/runtime/gr_runtime_impl.cc b/gnuradio-core/src/lib/runtime/gr_runtime_impl.cc
new file mode 100644
index 000000000..2b104cd99
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_runtime_impl.cc
@@ -0,0 +1,130 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006 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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#define GR_RUNTIME_IMPL_DEBUG 0
+
+#include <gr_runtime_impl.h>
+#include <gr_simple_flowgraph.h>
+#include <gr_hier_block2.h>
+#include <gr_hier_block2_detail.h>
+#include <stdexcept>
+#include <iostream>
+
+gr_runtime_impl::gr_runtime_impl(gr_hier_block2_sptr top_block) :
+d_running(false),
+d_top_block(top_block),
+d_sfg(gr_make_simple_flowgraph()),
+d_graphs()
+{
+}
+
+gr_runtime_impl::~gr_runtime_impl()
+{
+}
+
+void
+gr_runtime_impl::start()
+{
+ if (d_running)
+ throw std::runtime_error("already running");
+ else
+ d_running = true;
+
+ d_sfg->d_detail->reset();
+ d_top_block->d_detail->flatten(d_sfg);
+ d_sfg->d_detail->validate();
+ d_sfg->d_detail->setup_connections();
+
+ d_graphs = d_sfg->d_detail->partition();
+ if (GR_RUNTIME_IMPL_DEBUG)
+ std::cout << "Flow graph has " << d_graphs.size()
+ << " sub-graphs." << std::endl;
+
+ d_threads.clear();
+ for (std::vector<gr_block_vector_t>::iterator p = d_graphs.begin();
+ p != d_graphs.end(); p++) {
+ gr_scheduler_thread_sptr thread = gr_make_scheduler_thread(*p);
+ thread->start();
+ d_threads.push_back(thread);
+ }
+}
+
+void
+gr_runtime_impl::stop()
+{
+ if (!d_running)
+ return;
+
+ for (gr_scheduler_thread_viter_t p = d_threads.begin();
+ p != d_threads.end(); p++)
+ (*p)->stop();
+
+ d_running = false;
+}
+
+void
+gr_runtime_impl::wait()
+{
+ for (gr_scheduler_thread_viter_t p = d_threads.begin();
+ p != d_threads.end(); p++) {
+ while(1) {
+ (*p)->join(NULL);
+ if (!(*p)->state() == omni_thread::STATE_TERMINATED)
+ break;
+ }
+ }
+}
+
+gr_scheduler_thread_sptr gr_make_scheduler_thread(gr_block_vector_t graph)
+{
+ return gr_scheduler_thread_sptr(new gr_scheduler_thread(graph));
+}
+
+gr_scheduler_thread::gr_scheduler_thread(gr_block_vector_t graph) :
+ omni_thread(NULL, PRIORITY_NORMAL),
+ d_sts(gr_make_single_threaded_scheduler(graph))
+{
+}
+
+gr_scheduler_thread::~gr_scheduler_thread()
+{
+}
+
+void gr_scheduler_thread::start()
+{
+ start_undetached();
+}
+
+void *gr_scheduler_thread::run_undetached(void *arg)
+{
+ d_sts->run();
+ return 0;
+}
+
+void gr_scheduler_thread::stop()
+{
+ d_sts->stop();
+}
diff --git a/gnuradio-core/src/lib/runtime/gr_runtime_impl.h b/gnuradio-core/src/lib/runtime/gr_runtime_impl.h
new file mode 100644
index 000000000..54977ef97
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_runtime_impl.h
@@ -0,0 +1,74 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006 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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_RUNTIME_IMPL_H
+#define INCLUDED_GR_RUNTIME_IMPL_H
+
+#include <gr_runtime_types.h>
+#include <gr_block.h>
+#include <omnithread.h>
+#include <gr_single_threaded_scheduler.h>
+
+class gr_scheduler_thread;
+typedef boost::shared_ptr<gr_scheduler_thread> gr_scheduler_thread_sptr;
+typedef std::vector<gr_scheduler_thread_sptr> gr_scheduler_thread_vector_t;
+typedef std::vector<gr_scheduler_thread_sptr>::iterator gr_scheduler_thread_viter_t;
+
+gr_scheduler_thread_sptr gr_make_scheduler_thread(gr_block_vector_t graph);
+
+class gr_scheduler_thread : public omni_thread
+{
+private:
+ gr_scheduler_thread(gr_block_vector_t graph);
+ friend gr_scheduler_thread_sptr gr_make_scheduler_thread(gr_block_vector_t graph);
+
+ gr_single_threaded_scheduler_sptr d_sts;
+
+public:
+ ~gr_scheduler_thread();
+ virtual void *run_undetached(void *arg);
+ void start();
+ void stop();
+};
+
+class gr_runtime_impl
+{
+private:
+ gr_runtime_impl(gr_hier_block2_sptr top_block);
+ friend class gr_runtime;
+
+ bool d_running;
+ gr_hier_block2_sptr d_top_block;
+ gr_simple_flowgraph_sptr d_sfg;
+ std::vector<gr_block_vector_t> d_graphs;
+ gr_scheduler_thread_vector_t d_threads;
+
+ void start();
+ void stop();
+ void wait();
+
+public:
+ ~gr_runtime_impl();
+
+};
+
+#endif /* INCLUDED_GR_RUNTIME_IMPL_H */
diff --git a/gnuradio-core/src/lib/runtime/gr_runtime_types.h b/gnuradio-core/src/lib/runtime/gr_runtime_types.h
index 55cbabe18..dfa0ce94f 100644
--- a/gnuradio-core/src/lib/runtime/gr_runtime_types.h
+++ b/gnuradio-core/src/lib/runtime/gr_runtime_types.h
@@ -20,8 +20,8 @@
* Boston, MA 02110-1301, USA.
*/
-#ifndef INCLUDED_GR_RUNTIME_H
-#define INCLUDED_GR_RUNTIME_H
+#ifndef INCLUDED_GR_RUNTIME_TYPES_H
+#define INCLUDED_GR_RUNTIME_TYPES_H
#include <gr_types.h>
@@ -29,16 +29,24 @@
* typedefs for smart pointers we use throughout the runtime system
*/
+class gr_basic_block;
class gr_block;
class gr_block_detail;
+class gr_hier_block2;
class gr_io_signature;
class gr_buffer;
class gr_buffer_reader;
+class gr_simple_flowgraph;
+class gr_runtime;
-typedef boost::shared_ptr<gr_block> gr_block_sptr;
-typedef boost::shared_ptr<gr_block_detail> gr_block_detail_sptr;
-typedef boost::shared_ptr<gr_io_signature> gr_io_signature_sptr;
-typedef boost::shared_ptr<gr_buffer> gr_buffer_sptr;
-typedef boost::shared_ptr<gr_buffer_reader> gr_buffer_reader_sptr;
+typedef boost::shared_ptr<gr_basic_block> gr_basic_block_sptr;
+typedef boost::shared_ptr<gr_block> gr_block_sptr;
+typedef boost::shared_ptr<gr_block_detail> gr_block_detail_sptr;
+typedef boost::shared_ptr<gr_hier_block2> gr_hier_block2_sptr;
+typedef boost::shared_ptr<gr_io_signature> gr_io_signature_sptr;
+typedef boost::shared_ptr<gr_buffer> gr_buffer_sptr;
+typedef boost::shared_ptr<gr_buffer_reader> gr_buffer_reader_sptr;
+typedef boost::shared_ptr<gr_runtime> gr_runtime_sptr;
+typedef boost::shared_ptr<gr_simple_flowgraph> gr_simple_flowgraph_sptr;
-#endif /* INCLUDED_GR_RUNTIME_H */
+#endif /* INCLUDED_GR_RUNTIME_TYPES_H */
diff --git a/gnuradio-core/src/lib/runtime/gr_simple_flowgraph.cc b/gnuradio-core/src/lib/runtime/gr_simple_flowgraph.cc
new file mode 100644
index 000000000..21aeb587c
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_simple_flowgraph.cc
@@ -0,0 +1,67 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006 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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_simple_flowgraph.h>
+#include <gr_simple_flowgraph_detail.h>
+#include <iostream>
+
+#define GR_SIMPLE_FLOWGRAPH_DEBUG 0
+
+gr_simple_flowgraph_sptr gr_make_simple_flowgraph()
+{
+ return gr_simple_flowgraph_sptr(new gr_simple_flowgraph());
+}
+
+gr_simple_flowgraph::gr_simple_flowgraph() :
+d_detail(new gr_simple_flowgraph_detail())
+{
+}
+
+gr_simple_flowgraph::~gr_simple_flowgraph()
+{
+ delete d_detail;
+}
+
+void
+gr_simple_flowgraph::define_component(const std::string &name, gr_block_sptr block)
+{
+ if (GR_SIMPLE_FLOWGRAPH_DEBUG)
+ std::cout << "Defining block " << block << " as " << name << std::endl;
+ d_detail->define_component(name, block);
+}
+
+void
+gr_simple_flowgraph::connect(const std::string &src_name, int src_port,
+ const std::string &dst_name, int dst_port)
+{
+ d_detail->connect(src_name, src_port, dst_name, dst_port);
+}
+
+void
+gr_simple_flowgraph::validate()
+{
+ d_detail->validate();
+}
diff --git a/gnuradio-core/src/lib/runtime/gr_simple_flowgraph.h b/gnuradio-core/src/lib/runtime/gr_simple_flowgraph.h
new file mode 100644
index 000000000..ca2c505e5
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_simple_flowgraph.h
@@ -0,0 +1,52 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006 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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_SIMPLE_FLOWGRAPH_H
+#define INCLUDED_GR_SIMPLE_FLOWGRAPH_H
+
+#include <gr_block.h>
+#include <boost/shared_ptr.hpp>
+#include <string>
+
+gr_simple_flowgraph_sptr gr_make_simple_flowgraph();
+
+class gr_simple_flowgraph_detail;
+
+class gr_simple_flowgraph
+{
+private:
+ friend class gr_runtime_impl;
+ friend gr_simple_flowgraph_sptr gr_make_simple_flowgraph();
+ gr_simple_flowgraph();
+
+ gr_simple_flowgraph_detail *d_detail;
+
+public:
+ ~gr_simple_flowgraph();
+
+ void define_component(const std::string &name, gr_block_sptr block);
+ void connect(const std::string &src, int src_port,
+ const std::string &dst, int dst_port);
+ void validate();
+};
+
+#endif /* INCLUDED_GR_SIMPLE_FLOWGRAPH_H */
diff --git a/gnuradio-core/src/lib/runtime/gr_simple_flowgraph.i b/gnuradio-core/src/lib/runtime/gr_simple_flowgraph.i
new file mode 100644
index 000000000..c3654fe50
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_simple_flowgraph.i
@@ -0,0 +1,45 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006 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 2, 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.
+ */
+
+class gr_simple_flowgraph;
+typedef boost::shared_ptr<gr_simple_flowgraph> gr_simple_flowgraph_sptr;
+%template(gr_simple_flowgraph_sptr) boost::shared_ptr<gr_simple_flowgraph>;
+%rename(simple_flowgraph) gr_make_simple_flowgraph;
+%ignore gr_simple_flowgraph;
+
+gr_simple_flowgraph_sptr gr_make_simple_flowgraph();
+
+class gr_simple_flowgraph
+{
+private:
+ gr_simple_flowgraph();
+
+public:
+ ~gr_simple_flowgraph();
+ void define_component(const std::string name, gr_block_sptr block)
+ throw (std::invalid_argument);
+ void connect(const std::string &src, int src_port,
+ const std::string &dst, int dst_port)
+ throw (std::invalid_argument);
+ void validate()
+ throw (std::runtime_error);
+};
diff --git a/gnuradio-core/src/lib/runtime/gr_simple_flowgraph_detail.cc b/gnuradio-core/src/lib/runtime/gr_simple_flowgraph_detail.cc
new file mode 100644
index 000000000..2698bc6d8
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_simple_flowgraph_detail.cc
@@ -0,0 +1,471 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006 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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_simple_flowgraph.h>
+#include <gr_simple_flowgraph_detail.h>
+#include <gr_io_signature.h>
+#include <gr_block_detail.h>
+#include <gr_buffer.h>
+#include <iostream>
+#include <stdexcept>
+
+#define GR_SIMPLE_FLOWGRAPH_DETAIL_DEBUG 0
+
+gr_edge_sptr
+gr_make_edge(const std::string &src_name, int src_port,
+ const std::string &dst_name, int dst_port)
+{
+ return gr_edge_sptr(new gr_edge(src_name, src_port, dst_name, dst_port));
+}
+
+gr_edge::gr_edge(const std::string &src_name, int src_port, const std::string &dst_name, int dst_port)
+ : d_src(src_name, src_port),
+ d_dst(dst_name, dst_port)
+{
+}
+
+gr_edge::~gr_edge()
+{
+}
+
+gr_simple_flowgraph_detail::gr_simple_flowgraph_detail() :
+d_components(),
+d_edges()
+{
+}
+
+gr_simple_flowgraph_detail::~gr_simple_flowgraph_detail()
+{
+}
+
+void
+gr_simple_flowgraph_detail::reset()
+{
+ // Boost shared pointers will deallocate as needed
+ d_edges.clear();
+ d_components.clear();
+}
+
+gr_block_sptr
+gr_simple_flowgraph_detail::lookup_block(const std::string &name)
+{
+ gr_component_miter_t p = d_components.find(name);
+ if (p != d_components.end())
+ return p->second;
+ else
+ return gr_block_sptr();
+}
+
+void
+gr_simple_flowgraph_detail::define_component(const std::string &name, gr_block_sptr block)
+{
+ if (!block)
+ throw std::invalid_argument("null block passed");
+
+ if (!lookup_block(name))
+ d_components[name] = block;
+ else
+ throw std::invalid_argument("name already in use");
+}
+
+void
+gr_simple_flowgraph_detail::connect(const std::string &src_name, int src_port,
+ const std::string &dst_name, int dst_port)
+{
+ gr_block_sptr src_block = lookup_block(src_name);
+ gr_block_sptr dst_block = lookup_block(dst_name);
+
+ if (GR_SIMPLE_FLOWGRAPH_DETAIL_DEBUG)
+ std::cout << "Connecting " << src_name << ":" << src_port << "->"
+ << dst_name << ":" << dst_port << std::endl;
+
+ if (!src_block)
+ throw std::invalid_argument("unknown src name");
+ if (!dst_block)
+ throw std::invalid_argument("unknown dst name");
+
+ check_valid_port(src_block->output_signature(), src_port);
+ check_valid_port(dst_block->input_signature(), dst_port);
+ check_dst_not_used(dst_name, dst_port);
+ check_type_match(src_block, src_port, dst_block, dst_port);
+
+ d_edges.push_back(gr_make_edge(src_name, src_port, dst_name, dst_port));
+}
+
+void
+gr_simple_flowgraph_detail::check_valid_port(gr_io_signature_sptr sig, int port)
+{
+ if (port < 0)
+ throw std::invalid_argument("negative port number");
+ if (sig->max_streams() >= 0 && port >= sig->max_streams())
+ throw std::invalid_argument("port number exceeds max");
+}
+
+void
+gr_simple_flowgraph_detail::check_dst_not_used(const std::string &name, int port)
+{
+ for (gr_edge_viter_t p = d_edges.begin(); p != d_edges.end(); p++)
+ if ((*p)->dst_name() == name && (*p)->dst_port() == port)
+ throw std::invalid_argument("dst already in use");
+}
+
+void
+gr_simple_flowgraph_detail::check_type_match(gr_block_sptr src_block, int src_port,
+ gr_block_sptr dst_block, int dst_port)
+{
+ int src_size = src_block->output_signature()->sizeof_stream_item(src_port);
+ int dst_size = dst_block->input_signature()->sizeof_stream_item(dst_port);
+
+ if (src_size != dst_size)
+ throw std::invalid_argument("type size mismatch");
+}
+
+void
+gr_simple_flowgraph_detail::validate()
+{
+ for (gr_component_miter_t p = d_components.begin(); p != d_components.end(); p++) {
+ std::vector<int> used_ports;
+ int ninputs, noutputs;
+
+ used_ports = calc_used_ports(p->first, true); // inputs
+ ninputs = used_ports.size();
+ check_contiguity(p->second, used_ports, true); // inputs
+
+ used_ports = calc_used_ports(p->first, false); // outputs
+ noutputs = used_ports.size();
+ check_contiguity(p->second, used_ports, false); // outputs
+
+ if (!(p->second->check_topology(ninputs, noutputs)))
+ throw std::runtime_error("check topology failed");
+ }
+}
+
+std::vector<int>
+gr_simple_flowgraph_detail::calc_used_ports(const std::string &name, bool check_inputs)
+{
+ if (GR_SIMPLE_FLOWGRAPH_DETAIL_DEBUG)
+ std::cout << "Calculating used " << (check_inputs ? "input " : "output ")
+ << "ports...";
+
+ std::vector<int> tmp, result;
+ std::insert_iterator<std::vector<int> > inserter(result, result.begin());
+
+ gr_edge_vector_t edges = calc_connections(name, check_inputs);
+
+ for (gr_edge_viter_t p = edges.begin(); p != edges.end(); p++) {
+ if (check_inputs == true)
+ tmp.push_back((*p)->dst_port());
+ else
+ tmp.push_back((*p)->src_port());
+ }
+
+ // remove duplicates
+ std::sort(tmp.begin(), tmp.end());
+ std::unique_copy(tmp.begin(), tmp.end(), inserter);
+
+ if (GR_SIMPLE_FLOWGRAPH_DETAIL_DEBUG)
+ std::cout << result.size() << std::endl;
+
+ return result;
+}
+
+gr_edge_vector_t
+gr_simple_flowgraph_detail::calc_connections(const std::string &name, bool check_inputs)
+{
+ gr_edge_vector_t result;
+
+ for (gr_edge_viter_t p = d_edges.begin(); p != d_edges.end(); p++) {
+ if (check_inputs) {
+ if ((*p)->dst_name() == name)
+ result.push_back(*p);
+ }
+ else {
+ if ((*p)->src_name() == name)
+ result.push_back(*p);
+ }
+ }
+
+ return result; // assumes no duplicates
+}
+
+void
+gr_simple_flowgraph_detail::check_contiguity(gr_block_sptr block,
+ const std::vector<int> &used_ports,
+ bool check_inputs)
+{
+ if (GR_SIMPLE_FLOWGRAPH_DETAIL_DEBUG)
+ std::cout << "Checking " << (check_inputs ? "input " : "output ")
+ << "contiguity...";
+
+ gr_io_signature_sptr sig =
+ check_inputs ? block->input_signature() : block->output_signature();
+
+ int nports = used_ports.size();
+ int min_ports = sig->min_streams();
+
+ if (nports == 0) {
+ if (min_ports == 0) {
+ if (GR_SIMPLE_FLOWGRAPH_DETAIL_DEBUG)
+ std::cout << "ok." << std::endl;
+ return;
+ }
+ else {
+ if (GR_SIMPLE_FLOWGRAPH_DETAIL_DEBUG)
+ std::cout << "needs " << min_ports << ", only has "
+ << nports << std::endl;
+
+ throw std::runtime_error("insufficient ports");
+ }
+ }
+
+ if (used_ports[nports-1]+1 != nports) {
+ for (int i = 0; i < nports; i++) {
+ if (used_ports[i] != i) {
+ if (GR_SIMPLE_FLOWGRAPH_DETAIL_DEBUG)
+ std::cout << "missing " << (check_inputs ? "input ":"output ")
+ << i << std::endl;
+
+ throw std::runtime_error("missing input assignment");
+ }
+ }
+ }
+
+ if (GR_SIMPLE_FLOWGRAPH_DETAIL_DEBUG)
+ std::cout << "ok." << std::endl;
+}
+
+void
+gr_simple_flowgraph_detail::setup_connections()
+{
+ // Assign block details to component blocks
+ for (gr_component_miter_t p = d_components.begin(); p != d_components.end(); p++) {
+ if (GR_SIMPLE_FLOWGRAPH_DETAIL_DEBUG)
+ std::cout << "Allocating output buffers for " << p->first << "..." << std::endl;
+
+ int ninputs = calc_used_ports(p->first, true).size();
+ int noutputs = calc_used_ports(p->first, false).size();
+ gr_block_detail_sptr detail = gr_make_block_detail(ninputs, noutputs);
+ for (int i = 0; i < noutputs; i++)
+ detail->set_output(i, allocate_buffer(p->first, i));
+ p->second->set_detail(detail);
+ }
+
+ // Connect inputs to outputs for each block
+ for(gr_component_miter_t p = d_components.begin(); p != d_components.end(); p++) {
+ // Get its detail and edges that feed into it
+ gr_block_detail_sptr detail = p->second->detail();
+ gr_edge_vector_t in_edges = calc_upstream_edges(p->first);
+
+ if (GR_SIMPLE_FLOWGRAPH_DETAIL_DEBUG)
+ if (in_edges.size() > 0)
+ std::cout << "Connecting inputs to " << p->first << "..." << std::endl;
+
+ // For each edge that feeds into it
+ for (gr_edge_viter_t e = in_edges.begin(); e != in_edges.end(); e++) {
+ // Set the input buffer on the destination port to the output
+ // buffer on the source port
+ int dst_port = (*e)->dst_port();
+ int src_port = (*e)->src_port();
+ gr_block_sptr src_block = lookup_block((*e)->src_name());
+ gr_buffer_sptr src_buffer = src_block->detail()->output(src_port);
+
+ if (GR_SIMPLE_FLOWGRAPH_DETAIL_DEBUG)
+ std::cout << "Setting input on " << (*e)->dst_name()
+ << ":" << dst_port << std::endl;
+
+ detail->set_input(dst_port, gr_buffer_add_reader(src_buffer, p->second->history()-1));
+ }
+ }
+}
+
+gr_buffer_sptr
+gr_simple_flowgraph_detail::allocate_buffer(const std::string &name, int port)
+{
+ gr_block_sptr block = lookup_block(name);
+ int item_size = block->output_signature()->sizeof_stream_item(port);
+ int nitems = s_fixed_buffer_size/item_size;
+
+ // Make sure there are at least twice the output_multiple no. of items
+ if (nitems < 2*block->output_multiple()) // Note: this means output_multiple()
+ nitems = 2*block->output_multiple(); // can't be changed by block dynamically
+
+ // If any downstream blocks are decimators and/or have a large output_multiple,
+ // ensure we have a buffer at least twice their decimation factor*output_multiple
+ gr_block_vector_t blocks = calc_downstream_blocks(name, port);
+ for (gr_block_viter_t p = blocks.begin(); p != blocks.end(); p++) {
+ int decimation = (int)(1.0/(*p)->relative_rate());
+ int multiple = (*p)->output_multiple();
+ int history = (*p)->history();
+ nitems = std::max(nitems, 2*(decimation*multiple+history));
+ }
+
+ if (GR_SIMPLE_FLOWGRAPH_DETAIL_DEBUG)
+ std::cout << "Allocating buffer for port " << port << " with "
+ << nitems << " items of size " << item_size << std::endl;
+
+ return gr_make_buffer(nitems, item_size);
+}
+
+gr_block_vector_t
+gr_simple_flowgraph_detail::calc_downstream_blocks(const std::string &name, int port)
+{
+ gr_block_vector_t tmp, result;
+ std::insert_iterator<gr_block_vector_t> inserter(result, result.begin());
+
+ for (gr_edge_viter_t p = d_edges.begin(); p != d_edges.end(); p++)
+ if ((*p)->src_name() == name && (*p)->src_port() == port)
+ tmp.push_back(lookup_block((*p)->dst_name()));
+
+ // Remove duplicates
+ sort(tmp.begin(), tmp.end());
+ unique_copy(tmp.begin(), tmp.end(), inserter);
+ return result;
+}
+
+gr_edge_vector_t
+gr_simple_flowgraph_detail::calc_upstream_edges(const std::string &name)
+{
+ gr_edge_vector_t result;
+
+ for (gr_edge_viter_t p = d_edges.begin(); p != d_edges.end(); p++)
+ if ((*p)->dst_name() == name)
+ result.push_back(*p);
+
+ return result; // Assume no duplicates
+}
+
+gr_block_vector_t
+gr_simple_flowgraph_detail::calc_used_blocks()
+{
+ std::vector<std::string> tmp, tmp_unique;
+ std::insert_iterator<std::vector<std::string> > inserter(tmp_unique, tmp_unique.begin());
+ gr_block_vector_t result;
+
+ for (gr_edge_viter_t p = d_edges.begin(); p != d_edges.end(); p++) {
+ tmp.push_back((*p)->src_name());
+ tmp.push_back((*p)->dst_name());
+ }
+
+ sort(tmp.begin(), tmp.end());
+ unique_copy(tmp.begin(), tmp.end(), inserter);
+
+ for (std::vector<std::string>::iterator p = tmp_unique.begin();
+ p != tmp_unique.end(); p++)
+ result.push_back(lookup_block(*p));
+
+ if (GR_SIMPLE_FLOWGRAPH_DETAIL_DEBUG)
+ std::cout << "Flowgraph uses " << result.size()
+ << " distinct blocks." << std::endl;
+
+ return result;
+}
+
+std::vector<gr_block_vector_t>
+gr_simple_flowgraph_detail::partition()
+{
+ std::vector<gr_block_vector_t> result;
+ gr_block_vector_t blocks = calc_used_blocks();
+ gr_block_vector_t graph;
+
+ while (blocks.size() > 0) {
+ graph = calc_reachable_blocks(blocks[0], blocks);
+ assert(graph.size());
+ result.push_back(topological_sort(graph));
+
+ for (gr_block_viter_t p = graph.begin(); p != graph.end(); p++)
+ blocks.erase(find(blocks.begin(), blocks.end(), *p));
+ }
+
+ return result;
+}
+
+gr_block_vector_t
+gr_simple_flowgraph_detail::calc_reachable_blocks(gr_block_sptr block, gr_block_vector_t &blocks)
+{
+ gr_block_vector_t result;
+
+ // Mark all blocks as unvisited
+ for (gr_block_viter_t p = blocks.begin(); p != blocks.end(); p++)
+ (*p)->detail()->set_color(gr_block_detail::WHITE);
+
+ // Recursively mark all reachable blocks
+ reachable_dfs_visit(block, blocks);
+
+ // Collect all the blocks that have been visited
+ for (gr_block_viter_t p = blocks.begin(); p != blocks.end(); p++)
+ if ((*p)->detail()->color() == gr_block_detail::BLACK)
+ result.push_back(*p);
+
+ return result;
+}
+
+// Recursively mark all reachable blocks from given block and block list
+void
+gr_simple_flowgraph_detail::reachable_dfs_visit(gr_block_sptr block, gr_block_vector_t &blocks)
+{
+ // Mark the current one as visited
+ block->detail()->set_color(gr_block_detail::BLACK);
+
+ // Recurse into adjacent vertices
+ gr_block_vector_t adjacent = calc_adjacent_blocks(block, blocks);
+
+ for (gr_block_viter_t p = adjacent.begin(); p != adjacent.end(); p++)
+ if ((*p)->detail()->color() == gr_block_detail::WHITE)
+ reachable_dfs_visit(*p, blocks);
+}
+
+// Return a list of block adjacent to a given block along any edge
+gr_block_vector_t
+gr_simple_flowgraph_detail::calc_adjacent_blocks(gr_block_sptr block, gr_block_vector_t &blocks)
+{
+ gr_block_vector_t tmp, result;
+ std::insert_iterator<gr_block_vector_t> inserter(result, result.begin());
+
+ // Find any blocks that are inputs or outputs
+ for (gr_edge_viter_t p = d_edges.begin(); p != d_edges.end(); p++) {
+ if (lookup_block((*p)->src_name()) == block)
+ tmp.push_back(lookup_block((*p)->dst_name()));
+ if (lookup_block((*p)->dst_name()) == block)
+ tmp.push_back(lookup_block((*p)->src_name()));
+ }
+
+ // Remove duplicates
+ sort(tmp.begin(), tmp.end());
+ unique_copy(tmp.begin(), tmp.end(), inserter);
+ return result;
+}
+
+gr_block_vector_t
+gr_simple_flowgraph_detail::topological_sort(gr_block_vector_t &blocks)
+{
+ gr_block_vector_t result;
+
+ // NOP for now
+ result = blocks;
+
+ return result;
+}
+
diff --git a/gnuradio-core/src/lib/runtime/gr_simple_flowgraph_detail.h b/gnuradio-core/src/lib/runtime/gr_simple_flowgraph_detail.h
new file mode 100644
index 000000000..368a0619f
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_simple_flowgraph_detail.h
@@ -0,0 +1,128 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006 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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_SIMPLE_FLOWGRAPH_DETAIL_H
+#define INCLUDED_GR_SIMPLE_FLOWGRAPH_DETAIL_H
+
+#include <gr_block.h>
+#include <map>
+
+#define GR_FIXED_BUFFER_SIZE (32*(1L<<10))
+
+typedef std::map<std::string, gr_block_sptr> gr_component_map_t;
+typedef std::map<std::string, gr_block_sptr>::iterator gr_component_miter_t;
+
+class gr_endpoint
+{
+private:
+ std::string d_name;
+ int d_port;
+
+public:
+ gr_endpoint(const std::string &name, int port) { d_name = name; d_port = port; }
+ const std::string &name() const { return d_name; }
+ int port() const { return d_port; }
+};
+
+class gr_edge;
+typedef boost::shared_ptr<gr_edge> gr_edge_sptr;
+gr_edge_sptr gr_make_edge(const std::string &src_name, int src_port,
+ const std::string &dst_name, int dst_port);
+
+class gr_edge
+{
+private:
+ friend gr_edge_sptr gr_make_edge(const std::string &src_name, int src_port,
+ const std::string &dst_name, int dst_port);
+ gr_edge(const std::string &name, int src_port,
+ const std::string &name, int dst_port);
+
+ gr_endpoint d_src;
+ gr_endpoint d_dst;
+
+public:
+ ~gr_edge();
+ const std::string src_name() const { return d_src.name(); }
+ const std::string dst_name() const { return d_dst.name(); }
+ int src_port() const { return d_src.port(); }
+ int dst_port() const { return d_dst.port(); }
+};
+
+typedef std::vector<gr_edge_sptr> gr_edge_vector_t;
+typedef std::vector<gr_edge_sptr>::iterator gr_edge_viter_t;
+
+class gr_simple_flowgraph_detail
+{
+private:
+ friend class gr_simple_flowgraph;
+ friend class gr_runtime_impl;
+
+ gr_simple_flowgraph_detail();
+
+ gr_component_map_t d_components;
+ gr_edge_vector_t d_edges;
+ static const unsigned int s_fixed_buffer_size = GR_FIXED_BUFFER_SIZE;
+
+ void reset();
+ void define_component(const std::string &name, gr_block_sptr block);
+ void connect(const std::string &src, int src_port,
+ const std::string &dst, int dst_port);
+ gr_block_sptr lookup_block(const std::string &name);
+ void check_valid_port(gr_io_signature_sptr sig, int port);
+ void check_dst_not_used(const std::string &name, int port);
+ void check_type_match(gr_block_sptr src_block, int src_port,
+ gr_block_sptr dst_block, int dst_port);
+ void validate();
+ gr_edge_vector_t calc_connections(const std::string &name, bool check_inputs); // false=use outputs
+ std::vector<int> calc_used_ports(const std::string &name, bool check_inputs);
+ void check_contiguity(gr_block_sptr block, const std::vector<int> &used_ports,
+ bool check_inputs);
+ void setup_connections();
+ gr_buffer_sptr allocate_buffer(const std::string &name, int port);
+ gr_block_vector_t calc_downstream_blocks(const std::string &name, int port);
+ gr_edge_vector_t calc_upstream_edges(const std::string &name);
+ gr_block_vector_t calc_used_blocks();
+ std::vector<gr_block_vector_t> partition();
+ gr_block_vector_t calc_reachable_blocks(gr_block_sptr block, gr_block_vector_t &blocks);
+ gr_block_vector_t topological_sort(gr_block_vector_t &blocks);
+ void reachable_dfs_visit(gr_block_sptr block, gr_block_vector_t &blocks);
+ gr_block_vector_t calc_adjacent_blocks(gr_block_sptr block, gr_block_vector_t &blocks);
+
+public:
+ ~gr_simple_flowgraph_detail();
+};
+
+inline std::ostream&
+operator <<(std::ostream& os, const gr_block_sptr p)
+{
+ os << "<gr_block " << p->name() << " (" << p->unique_id() << ")>";
+ return os;
+}
+
+inline std::ostream&
+operator <<(std::ostream &os, const gr_endpoint endp)
+{
+ os << endp.name() << ":" << endp.port();
+ return os;
+}
+
+#endif /* INCLUDED_GR_SIMPLE_FLOWGRAPH_H */
diff --git a/gnuradio-core/src/lib/runtime/qa_gr_block.cc b/gnuradio-core/src/lib/runtime/qa_gr_block.cc
index 4773a6eaa..630d72749 100644
--- a/gnuradio-core/src/lib/runtime/qa_gr_block.cc
+++ b/gnuradio-core/src/lib/runtime/qa_gr_block.cc
@@ -25,7 +25,6 @@
#endif
#include <qa_gr_block.h>
#include <gr_block.h>
-#include <gr_runtime_types.h>
#include <gr_io_signature.h>
#include <gr_null_sink.h>
#include <gr_null_source.h>
diff --git a/gnuradio-core/src/lib/runtime/qa_gr_hier_block2.cc b/gnuradio-core/src/lib/runtime/qa_gr_hier_block2.cc
new file mode 100644
index 000000000..766ea2f6b
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/qa_gr_hier_block2.cc
@@ -0,0 +1,46 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006 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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <qa_gr_hier_block2.h>
+#include <gr_hier_block2.h>
+#include <gr_io_signature.h>
+#include <gr_null_source.h>
+#include <gr_null_sink.h>
+
+void qa_gr_hier_block2::test_make()
+{
+ gr_hier_block2_sptr src1(gr_make_hier_block2("test",
+ gr_make_io_signature(1, 1, sizeof(int)),
+ gr_make_io_signature(1, 1, sizeof(int))));
+
+ CPPUNIT_ASSERT(src1);
+ CPPUNIT_ASSERT_EQUAL(std::string("test"), src1->name());
+ CPPUNIT_ASSERT_EQUAL(1, src1->input_signature()->max_streams());
+ CPPUNIT_ASSERT_EQUAL(1, src1->output_signature()->min_streams());
+ CPPUNIT_ASSERT_EQUAL(1, src1->output_signature()->max_streams());
+ CPPUNIT_ASSERT_EQUAL(sizeof(int),
+ src1->output_signature()->sizeof_stream_item(0));
+}
diff --git a/gnuradio-core/src/lib/runtime/qa_gr_hier_block2.h b/gnuradio-core/src/lib/runtime/qa_gr_hier_block2.h
new file mode 100644
index 000000000..a6bd8d97b
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/qa_gr_hier_block2.h
@@ -0,0 +1,43 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006 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 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_QA_GR_HIER_BLOCK2_H
+#define INCLUDED_QA_GR_HIER_BLOCK2_H
+
+#include <cppunit/extensions/HelperMacros.h>
+#include <cppunit/TestCase.h>
+#include <stdexcept>
+
+class qa_gr_hier_block2 : public CppUnit::TestCase
+{
+ CPPUNIT_TEST_SUITE(qa_gr_hier_block2);
+
+ CPPUNIT_TEST(test_make);
+
+ CPPUNIT_TEST_SUITE_END();
+
+private:
+ void test_make();
+ void test_derived();
+};
+
+#endif /* INCLUDED_QA_GR_HIER_BLOCK2_H */
diff --git a/gnuradio-core/src/lib/runtime/qa_runtime.cc b/gnuradio-core/src/lib/runtime/qa_runtime.cc
index 165a34703..ca0c71d3c 100644
--- a/gnuradio-core/src/lib/runtime/qa_runtime.cc
+++ b/gnuradio-core/src/lib/runtime/qa_runtime.cc
@@ -33,6 +33,7 @@
#include <qa_gr_vmcircbuf.h>
#include <qa_gr_io_signature.h>
#include <qa_gr_block.h>
+#include <qa_gr_hier_block2.h>
#include <qa_gr_buffer.h>
CppUnit::TestSuite *
@@ -43,6 +44,7 @@ qa_runtime::suite ()
s->addTest (qa_gr_vmcircbuf::suite ());
s->addTest (qa_gr_io_signature::suite ());
s->addTest (qa_gr_block::suite ());
+ s->addTest (qa_gr_hier_block2::suite ());
s->addTest (qa_gr_buffer::suite ());
return s;
diff --git a/gnuradio-core/src/lib/runtime/runtime.i b/gnuradio-core/src/lib/runtime/runtime.i
index f2fd36437..8e6c01f9a 100644
--- a/gnuradio-core/src/lib/runtime/runtime.i
+++ b/gnuradio-core/src/lib/runtime/runtime.i
@@ -26,6 +26,9 @@
#include <gr_buffer.h>
#include <gr_block.h>
#include <gr_block_detail.h>
+#include <gr_hier_block2.h>
+#include <gr_runtime.h>
+#include <gr_simple_flowgraph.h>
#include <gr_single_threaded_scheduler.h>
#include <gr_message.h>
#include <gr_msg_handler.h>
@@ -37,9 +40,12 @@
%include <gr_io_signature.i>
%include <gr_buffer.i>
+%include <gr_basic_block.i>
%include <gr_block.i>
%include <gr_block_detail.i>
+%include <gr_hier_block2.i>
%include <gr_swig_block_magic.i>
+%include <gr_simple_flowgraph.i>
%include <gr_single_threaded_scheduler.i>
%include <gr_message.i>
%include <gr_msg_handler.i>
@@ -47,3 +53,4 @@
%include <gr_dispatcher.i>
%include <gr_error_handler.i>
%include <gr_realtime.i>
+%include <gr_runtime.i>
diff --git a/gnuradio-core/src/python/gnuradio/gr/Makefile.am b/gnuradio-core/src/python/gnuradio/gr/Makefile.am
index fcf026146..6400b842f 100644
--- a/gnuradio-core/src/python/gnuradio/gr/Makefile.am
+++ b/gnuradio-core/src/python/gnuradio/gr/Makefile.am
@@ -39,6 +39,7 @@ grgrpython_PYTHON = \
gr_threading_23.py \
gr_threading_24.py \
hier_block.py \
+ hier_block2.py \
prefs.py \
scheduler.py
@@ -63,6 +64,7 @@ noinst_PYTHON = \
qa_fsk_stuff.py \
qa_goertzel.py \
qa_head.py \
+ qa_hier_block2.py \
qa_hilbert.py \
qa_iir.py \
qa_interleave.py \
diff --git a/gnuradio-core/src/python/gnuradio/gr/__init__.py b/gnuradio-core/src/python/gnuradio/gr/__init__.py
index 8adf7e308..d38804870 100644
--- a/gnuradio-core/src/python/gnuradio/gr/__init__.py
+++ b/gnuradio-core/src/python/gnuradio/gr/__init__.py
@@ -29,7 +29,7 @@ from basic_flow_graph import *
from flow_graph import *
from exceptions import *
from hier_block import *
-
+from hier_block2 import *
# create a couple of aliases
serial_to_parallel = stream_to_vector
diff --git a/gnuradio-core/src/python/gnuradio/gr/hier_block2.py b/gnuradio-core/src/python/gnuradio/gr/hier_block2.py
new file mode 100644
index 000000000..c44e6f071
--- /dev/null
+++ b/gnuradio-core/src/python/gnuradio/gr/hier_block2.py
@@ -0,0 +1,40 @@
+#
+# Copyright 2006 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 2, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+from gnuradio_swig_python import hier_block2_swig
+
+#
+# This hack forces a 'has-a' relationship to look like an 'is-a' one.
+#
+# It allows Python classes to subclass this one, while passing through
+# method calls to the C++ class shared pointer from SWIG.
+#
+# It also allows us to intercept method calls if needed
+#
+class hier_block2(object):
+ def __init__(self, name, input_signature, output_signature):
+ self._hb = hier_block2_swig(name, input_signature, output_signature)
+
+ def __getattr__(self, name):
+ return getattr(self._hb, name)
+
+ def define_component(self, name, comp):
+ return self._hb.define_component(name, comp.basic_block())
diff --git a/gnuradio-core/src/python/gnuradio/gr/qa_hier_block2.py b/gnuradio-core/src/python/gnuradio/gr/qa_hier_block2.py
new file mode 100755
index 000000000..9253b892a
--- /dev/null
+++ b/gnuradio-core/src/python/gnuradio/gr/qa_hier_block2.py
@@ -0,0 +1,238 @@
+#!/usr/bin/env python
+
+from gnuradio import gr, gr_unittest
+
+class test_hier_block2(gr_unittest.TestCase):
+
+ def setUp(self):
+ pass
+
+ def tearDown(self):
+ pass
+
+ def test_001_make(self):
+ hblock = gr.hier_block2("test_block",
+ gr.io_signature(1,1,gr.sizeof_int),
+ gr.io_signature(1,1,gr.sizeof_int))
+ self.assertEqual("test_block", hblock.name())
+ self.assertEqual(1, hblock.input_signature().max_streams())
+ self.assertEqual(1, hblock.output_signature().min_streams())
+ self.assertEqual(1, hblock.output_signature().max_streams())
+ self.assertEqual(gr.sizeof_int, hblock.output_signature().sizeof_stream_item(0))
+
+ def test_002_define_component(self):
+ hblock = gr.hier_block2("test_block",
+ gr.io_signature(1,1,gr.sizeof_int),
+ gr.io_signature(1,1,gr.sizeof_int))
+ hblock.define_component("src", gr.null_source(gr.sizeof_int))
+ hblock.define_component("dst", gr.null_sink(gr.sizeof_int))
+
+ def test_003_define_component_reserved_input(self):
+ hblock = gr.hier_block2("test_block",
+ gr.io_signature(1,1,gr.sizeof_int),
+ gr.io_signature(1,1,gr.sizeof_int))
+ self.assertRaises(ValueError,
+ lambda: hblock.define_component("self", gr.nop(gr.sizeof_int)))
+
+ def test_004_define_component_name_in_use(self):
+ hblock = gr.hier_block2("test_block",
+ gr.io_signature(1,1,gr.sizeof_int),
+ gr.io_signature(1,1,gr.sizeof_int))
+ hblock.define_component("src", gr.null_source(gr.sizeof_int))
+ self.assertRaises(ValueError,
+ lambda: hblock.define_component("src", gr.null_sink(gr.sizeof_int)))
+
+ def test_006_connect_internal(self):
+ hblock = gr.hier_block2("test_block",
+ gr.io_signature(1,1,gr.sizeof_int),
+ gr.io_signature(1,1,gr.sizeof_int))
+ hblock.define_component("nop1", gr.nop(gr.sizeof_int))
+ hblock.define_component("nop2", gr.nop(gr.sizeof_int))
+ hblock.connect("nop1", 0, "nop2", 0)
+
+ def test_007_connect_input(self):
+ hblock = gr.hier_block2("test_block",
+ gr.io_signature(1,1,gr.sizeof_int),
+ gr.io_signature(1,1,gr.sizeof_int))
+ hblock.define_component("nop1", gr.nop(gr.sizeof_int))
+ hblock.connect("self", 0, "nop1", 0)
+
+ def test_008_connect_output(self):
+ hblock = gr.hier_block2("test_block",
+ gr.io_signature(1,1,gr.sizeof_int),
+ gr.io_signature(1,1,gr.sizeof_int))
+ hblock.define_component("nop1", gr.nop(gr.sizeof_int))
+ hblock.connect("nop1", 0, "self", 0)
+
+ def test_009_connect_unknown_src(self):
+ hblock = gr.hier_block2("test_block",
+ gr.io_signature(1,1,gr.sizeof_int),
+ gr.io_signature(1,1,gr.sizeof_int))
+ nop1 = gr.nop(gr.sizeof_int)
+ hblock.define_component("nop1", nop1)
+ self.assertRaises(ValueError,
+ lambda: hblock.connect("nop2", 0, "self", 0))
+
+ def test_010_connect_unknown_dst(self):
+ hblock = gr.hier_block2("test_block",
+ gr.io_signature(1,1,gr.sizeof_int),
+ gr.io_signature(1,1,gr.sizeof_int))
+ hblock.define_component("nop1", gr.nop(gr.sizeof_int))
+ self.assertRaises(ValueError,
+ lambda: hblock.connect("self", 0, "nop2", 0))
+
+ def test_011_connect_invalid_src_port_neg(self):
+ hblock = gr.hier_block2("test_block",
+ gr.io_signature(1,1,gr.sizeof_int),
+ gr.io_signature(1,1,gr.sizeof_int))
+ hblock.define_component("nop1", gr.nop(gr.sizeof_int))
+ self.assertRaises(ValueError,
+ lambda: hblock.connect("self", -1, "nop1", 0))
+
+ def test_012_connect_invalid_src_port_exceeds(self):
+ hblock = gr.hier_block2("test_block",
+ gr.io_signature(1,1,gr.sizeof_int),
+ gr.io_signature(1,1,gr.sizeof_int))
+ hblock.define_component("nop1", gr.nop(gr.sizeof_int))
+ self.assertRaises(ValueError,
+ lambda: hblock.connect("self", 1, "nop1", 0))
+
+ def test_013_connect_invalid_dst_port_neg(self):
+ hblock = gr.hier_block2("test_block",
+ gr.io_signature(1,1,gr.sizeof_int),
+ gr.io_signature(1,1,gr.sizeof_int))
+ hblock.define_component("nop1", gr.nop(gr.sizeof_int))
+ self.assertRaises(ValueError,
+ lambda: hblock.connect("self", -1, "nop1", 0))
+
+ def test_014_connect_invalid_dst_port_exceeds(self):
+ hblock = gr.hier_block2("test_block",
+ gr.io_signature(1,1,gr.sizeof_int),
+ gr.io_signature(1,1,gr.sizeof_int))
+ hblock.define_component("nop1", gr.nop(gr.sizeof_int))
+ self.assertRaises(ValueError,
+ lambda: hblock.connect("self", 1, "nop1", 0))
+
+ def test_015_connect_dst_port_in_use(self):
+ hblock = gr.hier_block2("test_block",
+ gr.io_signature(1,1,gr.sizeof_int),
+ gr.io_signature(1,1,gr.sizeof_int))
+ nop1 = gr.nop(gr.sizeof_int)
+ hblock.define_component("nop1", nop1)
+ hblock.connect("nop1", 0, "self", 0);
+ self.assertRaises(ValueError,
+ lambda: hblock.connect("nop1", 0, "self", 0))
+
+ def test_016_connect_one_src_two_dst(self):
+ hblock = gr.hier_block2("test_block",
+ gr.io_signature(1,1,gr.sizeof_int),
+ gr.io_signature(1,1,gr.sizeof_int))
+ hblock.define_component("src", gr.null_source(gr.sizeof_int))
+ hblock.define_component("dst1", gr.null_sink(gr.sizeof_int))
+ hblock.define_component("dst2", gr.null_sink(gr.sizeof_int))
+ hblock.connect("src", 0, "dst1", 0)
+ hblock.connect("src", 0, "dst2", 0)
+
+ def test_017_connect_type_mismatch(self):
+ hblock = gr.hier_block2("test_block",
+ gr.io_signature(1,1,gr.sizeof_int),
+ gr.io_signature(1,1,gr.sizeof_int))
+ hblock.define_component("nop1", gr.nop(gr.sizeof_char))
+ self.assertRaises(ValueError,
+ lambda: hblock.connect("nop1", 0, "self", 0))
+
+ def test_018_check_topology(self):
+ hblock = gr.hier_block2("test_block",
+ gr.io_signature(0,0,gr.sizeof_int),
+ gr.io_signature(0,0,gr.sizeof_int))
+ hblock.check_topology(0, 0);
+ """
+ def test_019_validate(self):
+ hblock = gr.hier_block2("test_block",
+ gr.io_signature(0,0,gr.sizeof_int),
+ gr.io_signature(0,0,gr.sizeof_int))
+ runtime = gr.runtime(hblock)
+ runtime.validate()
+
+ def test_020_validate_1(self):
+ hblock = gr.hier_block2("test_block",
+ gr.io_signature(0,0,gr.sizeof_int),
+ gr.io_signature(0,0,gr.sizeof_int))
+ hblock.define_component("src", gr.null_source(gr.sizeof_int))
+ hblock.define_component("dst1", gr.null_sink(gr.sizeof_int))
+ hblock.define_component("dst2", gr.null_sink(gr.sizeof_int))
+ hblock.connect("src", 0, "dst1", 0)
+ hblock.connect("src", 0, "dst2", 0)
+ runtime = gr.runtime(hblock)
+ runtime.validate()
+
+ def test_021_validate_2(self):
+ hblock = gr.hier_block2("test_block",
+ gr.io_signature(0,0,gr.sizeof_int),
+ gr.io_signature(0,0,gr.sizeof_int))
+ hblock.define_component("src1", gr.null_source(gr.sizeof_int))
+ hblock.define_component("nop1", gr.nop(gr.sizeof_int))
+ hblock.define_component("dst1", gr.null_sink(gr.sizeof_int))
+ hblock.define_component("dst2", gr.null_sink(gr.sizeof_int))
+ hblock.connect("src1", 0, "nop1", 0)
+ hblock.connect("src1", 0, "nop1", 1)
+ hblock.connect("nop1", 0, "dst1", 0)
+ hblock.connect("nop1", 1, "dst2", 0)
+ runtime = gr.runtime(hblock)
+ runtime.validate()
+
+ def test_022_validate_3(self):
+ hblock = gr.hier_block2("test_block",
+ gr.io_signature(0,0,gr.sizeof_int),
+ gr.io_signature(0,0,gr.sizeof_int))
+ hblock.define_component("src1", gr.null_source(gr.sizeof_int))
+ hblock.define_component("nop1", gr.nop(gr.sizeof_int))
+ hblock.define_component("dst1", gr.null_sink(gr.sizeof_int))
+ hblock.define_component("dst2", gr.null_sink(gr.sizeof_int))
+ hblock.connect("src1", 0, "nop1", 0)
+ hblock.connect("src1", 0, "nop1", 2)
+ hblock.connect("nop1", 0, "dst1", 0)
+ hblock.connect("nop1", 1, "dst2", 0)
+ runtime = gr.runtime(hblock)
+ self.assertRaises(RuntimeError,
+ lambda: runtime.validate())
+
+ def test_023_validate_4(self):
+ hblock = gr.hier_block2("test_block",
+ gr.io_signature(0,0,gr.sizeof_int),
+ gr.io_signature(0,0,gr.sizeof_int))
+ hblock.define_component("src1", gr.null_source(gr.sizeof_int))
+ hblock.define_component("nop1", gr.nop(gr.sizeof_int))
+ hblock.define_component("dst1", gr.null_sink(gr.sizeof_int))
+ hblock.define_component("dst2", gr.null_sink(gr.sizeof_int))
+ hblock.connect("src1", 0, "nop1", 0)
+ hblock.connect("src1", 0, "nop1", 1)
+ hblock.connect("nop1", 0, "dst1", 0)
+ hblock.connect("nop1", 2, "dst2", 0)
+ runtime = gr.runtime(hblock)
+ self.assertRaises(RuntimeError,
+ lambda: runtime.validate())
+
+ def test_024_validate_5(self):
+ hblock = gr.hier_block2("test_block",
+ gr.io_signature(0,0,gr.sizeof_int),
+ gr.io_signature(0,0,gr.sizeof_int))
+ hblock.define_component("src1", gr.null_source(gr.sizeof_int))
+ hblock.define_component("nop1", gr.nop(gr.sizeof_int))
+ hblock.define_component("dst1", gr.null_sink(gr.sizeof_int))
+ hblock.define_component("dst2", gr.null_sink(gr.sizeof_int))
+ hblock.connect("src1", 0, "nop1", 0)
+ hblock.connect("src1", 0, "nop1", 1)
+ hblock.connect("nop1", 0, "dst1", 0)
+ hblock.connect("nop1", 1, "dst2", 0)
+ runtime = gr.runtime(hblock)
+ runtime.validate()
+ # Pending implementation of disconnect
+ # hblock.disconnect("src1", 0, "nop1", 1)
+ # runtime.validate()
+ # self.assertRaises(ValueError,
+ # lambda: hblock.disconnect("src1", 0, "nop1", 1))
+ """
+
+if __name__ == "__main__":
+ gr_unittest.main()
diff --git a/gnuradio-core/src/python/gnuradio/gr/qa_runtime.py b/gnuradio-core/src/python/gnuradio/gr/qa_runtime.py
new file mode 100755
index 000000000..3e7f4e5f9
--- /dev/null
+++ b/gnuradio-core/src/python/gnuradio/gr/qa_runtime.py
@@ -0,0 +1,31 @@
+#!/usr/bin/env python
+
+from gnuradio import gr, gr_unittest
+
+class test_runtime(gr_unittest.TestCase):
+
+ def setUp(self):
+ pass
+
+ def tearDown(self):
+ pass
+
+ """
+ def test_001_run(self):
+ hblock = gr.hier_block2("test_block",
+ gr.io_signature(0,0,0),
+ gr.io_signature(0,0,0))
+ runtime = gr.runtime(hblock)
+ runtime.run()
+
+ def test_002_run_twice(self):
+ hblock = gr.hier_block2("test_block",
+ gr.io_signature(0,0,0),
+ gr.io_signature(0,0,0))
+ runtime = gr.runtime(hblock)
+ runtime.run()
+ self.assertRaises(RuntimeError, lambda: runtime.run())
+ """
+
+if __name__ == "__main__":
+ gr_unittest.main()
diff --git a/gnuradio-core/src/python/gnuradio/gr/qa_simple_flowgraph.py b/gnuradio-core/src/python/gnuradio/gr/qa_simple_flowgraph.py
new file mode 100755
index 000000000..939f5855f
--- /dev/null
+++ b/gnuradio-core/src/python/gnuradio/gr/qa_simple_flowgraph.py
@@ -0,0 +1,142 @@
+#!/usr/bin/env python
+
+from gnuradio import gr, gr_unittest
+
+class test_simple_flowgraph(gr_unittest.TestCase):
+
+ def setUp(self):
+ pass
+
+ def tearDown(self):
+ pass
+
+ def test_001_define_component(self):
+ sfg = gr.simple_flowgraph()
+ sfg.define_component("src", gr.null_source(gr.sizeof_int))
+ sfg.define_component("dst", gr.null_sink(gr.sizeof_int))
+
+ def test_002_define_component_name_in_use(self):
+ sfg = gr.simple_flowgraph()
+ sfg.define_component("src", gr.null_source(gr.sizeof_int))
+ self.assertRaises(ValueError,
+ lambda: sfg.define_component("src", gr.null_sink(gr.sizeof_int)))
+
+ def test_003_connect(self):
+ sfg = gr.simple_flowgraph()
+ sfg.define_component("src", gr.null_source(gr.sizeof_int))
+ sfg.define_component("dst", gr.null_sink(gr.sizeof_int))
+ sfg.connect("src", 0, "dst", 0)
+
+ def test_004connect_unknown_src(self):
+ sfg = gr.simple_flowgraph()
+ sfg.define_component("dst", gr.null_sink(gr.sizeof_int))
+ self.assertRaises(ValueError,
+ lambda: sfg.connect("src", 0, "dst", 0))
+
+ def test_005_connect_unknown_dst(self):
+ sfg = gr.simple_flowgraph()
+ sfg.define_component("src", gr.null_source(gr.sizeof_int))
+ self.assertRaises(ValueError,
+ lambda: sfg.connect("src", 0, "dst", 0))
+
+ def test_006_connect_invalid_src_port_neg(self):
+ sfg = gr.simple_flowgraph()
+ sfg.define_component("src", gr.null_source(gr.sizeof_int))
+ sfg.define_component("dst", gr.null_sink(gr.sizeof_int))
+ self.assertRaises(ValueError,
+ lambda: sfg.connect("src", -1, "dst", 0))
+
+ def test_007_connect_invalid_src_port_exceeds(self):
+ sfg = gr.simple_flowgraph()
+ sfg.define_component("src", gr.null_source(gr.sizeof_int))
+ sfg.define_component("dst", gr.null_sink(gr.sizeof_int))
+ self.assertRaises(ValueError,
+ lambda: sfg.connect("src", 1, "dst", 0))
+
+ def test_008_connect_invalid_dst_port_neg(self):
+ sfg = gr.simple_flowgraph()
+ sfg.define_component("src", gr.null_source(gr.sizeof_int))
+ sfg.define_component("dst", gr.null_sink(gr.sizeof_int))
+ self.assertRaises(ValueError,
+ lambda: sfg.connect("src", 0, "dst", -1))
+
+ def test_009_connect_invalid_dst_port_exceeds(self):
+ sfg = gr.simple_flowgraph()
+ sfg.define_component("src", gr.null_source(gr.sizeof_int))
+ sfg.define_component("dst", gr.null_sink(gr.sizeof_int))
+ self.assertRaises(ValueError,
+ lambda: sfg.connect("src", 0, "dst", 1))
+
+ def test_010_connect_invalid_dst_port_in_use(self):
+ sfg = gr.simple_flowgraph()
+ sfg.define_component("src1", gr.null_source(gr.sizeof_int))
+ sfg.define_component("src2", gr.null_source(gr.sizeof_int))
+ sfg.define_component("dst", gr.null_sink(gr.sizeof_int))
+ sfg.connect("src1", 0, "dst", 0)
+ self.assertRaises(ValueError,
+ lambda: sfg.connect("src2", 0, "dst", 0))
+
+ def test_011_connect_one_src_two_dst(self):
+ sfg = gr.simple_flowgraph()
+ sfg.define_component("src", gr.null_source(gr.sizeof_int))
+ sfg.define_component("dst1", gr.null_sink(gr.sizeof_int))
+ sfg.define_component("dst2", gr.null_sink(gr.sizeof_int))
+ sfg.connect("src", 0, "dst1", 0)
+ sfg.connect("src", 0, "dst2", 0)
+
+ def test_012_connect_type_mismatch(self):
+ sfg = gr.simple_flowgraph()
+ sfg.define_component("src", gr.null_source(gr.sizeof_int))
+ sfg.define_component("dst", gr.null_sink(gr.sizeof_char))
+ self.assertRaises(ValueError,
+ lambda: sfg.connect("src", 0, "dst", 0))
+
+ def test_013_validate(self):
+ sfg = gr.simple_flowgraph()
+ sfg.define_component("src", gr.null_source(gr.sizeof_int))
+ sfg.define_component("dst1", gr.null_sink(gr.sizeof_int))
+ sfg.define_component("dst2", gr.null_sink(gr.sizeof_int))
+ sfg.connect("src", 0, "dst1", 0)
+ sfg.connect("src", 0, "dst2", 0)
+ sfg.validate()
+
+ def test_014_validate(self):
+ sfg = gr.simple_flowgraph()
+ sfg.define_component("src1", gr.null_source (gr.sizeof_int))
+ sfg.define_component("nop1", gr.nop (gr.sizeof_int))
+ sfg.define_component("dst1", gr.null_sink (gr.sizeof_int))
+ sfg.define_component("dst2", gr.null_sink (gr.sizeof_int))
+ sfg.connect("src1", 0, "nop1", 0)
+ sfg.connect("src1", 0, "nop1", 1)
+ sfg.connect("nop1", 0, "dst1", 0)
+ sfg.connect("nop1", 1, "dst2", 0)
+ sfg.validate ()
+
+ def test_015_validate(self):
+ sfg = gr.simple_flowgraph()
+ sfg.define_component("src1", gr.null_source (gr.sizeof_int))
+ sfg.define_component("nop1", gr.nop (gr.sizeof_int))
+ sfg.define_component("dst1", gr.null_sink (gr.sizeof_int))
+ sfg.define_component("dst2", gr.null_sink (gr.sizeof_int))
+ sfg.connect("src1", 0, "nop1", 0)
+ sfg.connect("src1", 0, "nop1", 2)
+ sfg.connect("nop1", 0, "dst1", 0)
+ sfg.connect("nop1", 1, "dst2", 0)
+ self.assertRaises(RuntimeError,
+ lambda: sfg.validate ())
+
+ def test_016_validate(self):
+ sfg = gr.simple_flowgraph()
+ sfg.define_component("src1", gr.null_source (gr.sizeof_int))
+ sfg.define_component("nop1", gr.nop (gr.sizeof_int))
+ sfg.define_component("dst1", gr.null_sink (gr.sizeof_int))
+ sfg.define_component("dst2", gr.null_sink (gr.sizeof_int))
+ sfg.connect("src1", 0, "nop1", 0)
+ sfg.connect("src1", 0, "nop1", 1)
+ sfg.connect("nop1", 0, "dst1", 0)
+ sfg.connect("nop1", 2, "dst2", 0)
+ self.assertRaises(RuntimeError,
+ lambda: sfg.validate ())
+
+if __name__ == "__main__":
+ gr_unittest.main()
diff --git a/gnuradio-examples/Makefile.am b/gnuradio-examples/Makefile.am
index ad8ca5b1a..6e720ebdd 100644
--- a/gnuradio-examples/Makefile.am
+++ b/gnuradio-examples/Makefile.am
@@ -21,4 +21,4 @@
include $(top_srcdir)/Makefile.common
-SUBDIRS = python
+SUBDIRS = python c++
diff --git a/gnuradio-examples/c++/Makefile.am b/gnuradio-examples/c++/Makefile.am
new file mode 100644
index 000000000..f25bbaa8f
--- /dev/null
+++ b/gnuradio-examples/c++/Makefile.am
@@ -0,0 +1,27 @@
+#
+# Copyright 2006 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 2, 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
+
+SUBDIRS = \
+ dialtone \
+ hier
+
diff --git a/gnuradio-examples/c++/dialtone/Makefile.am b/gnuradio-examples/c++/dialtone/Makefile.am
new file mode 100644
index 000000000..35e807381
--- /dev/null
+++ b/gnuradio-examples/c++/dialtone/Makefile.am
@@ -0,0 +1,48 @@
+#
+# Copyright 2006 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 2, 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
+
+# For compiling within the GNU Radio build tree
+INCLUDES=$(STD_DEFINES_AND_INCLUDES) \
+ -I$(top_srcdir)/gr-audio-alsa/src
+
+GR_AUDIO_ALSA_LIBS=$(top_builddir)/gr-audio-alsa/src/libgr_audio_alsa.la
+
+# For compiling outside the tree, these are the usual
+# INCLUDES = -I/usr/local/include -I/usr/local/include/gnuradio
+# GNURADIO_CORE_LIBS = -lgnuradio-core
+# GR_AUDIO_ALSA_LIBS = -lgr_audio_alsa
+
+noinst_PROGRAMS = dialtone
+
+noinst_HEADERS = \
+ dialtone.h
+
+dialtone_SOURCES = \
+ dialtone.cc \
+ main.cc
+
+dialtone_LDADD = \
+ $(GNURADIO_CORE_LIBS) \
+ $(GR_AUDIO_ALSA_LIBS)
+
+MOSTLYCLEANFILES = *~
diff --git a/gnuradio-examples/c++/dialtone/dialtone.cc b/gnuradio-examples/c++/dialtone/dialtone.cc
new file mode 100644
index 000000000..08ecccf75
--- /dev/null
+++ b/gnuradio-examples/c++/dialtone/dialtone.cc
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2006 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 2, 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 <dialtone.h>
+#include <gr_io_signature.h>
+#include <gr_sig_source_f.h>
+#include <audio_alsa_sink.h>
+
+// Shared pointer constructor
+dialtone_sptr make_dialtone()
+{
+ return dialtone_sptr(new dialtone());
+}
+
+// Hierarchical block constructor, with no inputs or outputs
+dialtone::dialtone() :
+gr_hier_block2("dialtone",
+ gr_make_io_signature(0,0,0),
+ gr_make_io_signature(0,0,0))
+{
+ define_component("source0", gr_make_sig_source_f(48000, GR_SIN_WAVE, 350, 0.5));
+ define_component("source1", gr_make_sig_source_f(48000, GR_SIN_WAVE, 440, 0.5));
+ define_component("sink", audio_alsa_make_sink(48000));
+
+ connect("source0", 0, "sink", 0);
+ connect("source1", 0, "sink", 1);
+}
diff --git a/gnuradio-examples/c++/dialtone/dialtone.h b/gnuradio-examples/c++/dialtone/dialtone.h
new file mode 100644
index 000000000..2beb46c50
--- /dev/null
+++ b/gnuradio-examples/c++/dialtone/dialtone.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2006 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 2, 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 <gr_hier_block2.h>
+
+class dialtone;
+typedef boost::shared_ptr<dialtone> dialtone_sptr;
+dialtone_sptr make_dialtone();
+
+class dialtone : public gr_hier_block2
+{
+private:
+ dialtone();
+ friend dialtone_sptr make_dialtone();
+};
diff --git a/gnuradio-examples/c++/dialtone/main.cc b/gnuradio-examples/c++/dialtone/main.cc
new file mode 100644
index 000000000..beefac3a5
--- /dev/null
+++ b/gnuradio-examples/c++/dialtone/main.cc
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2006 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 2, 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.
+ */
+
+// GNU Radio C++ application
+//
+// Instantiate a top block
+// Instantiate a runtime, passing it the top block
+// Tell the runtime to go...
+
+#include <dialtone.h>
+#include <gr_runtime.h>
+
+int main()
+{
+ dialtone_sptr top_block = make_dialtone();
+ gr_runtime_sptr runtime = gr_make_runtime(top_block);
+
+ runtime->run();
+ return 0;
+}
diff --git a/gnuradio-examples/c++/hier/Makefile.am b/gnuradio-examples/c++/hier/Makefile.am
new file mode 100644
index 000000000..f9d341eb7
--- /dev/null
+++ b/gnuradio-examples/c++/hier/Makefile.am
@@ -0,0 +1,56 @@
+#
+# Copyright 2006 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 2, 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
+
+# For compiling within the GNU Radio build tree
+INCLUDES=$(STD_DEFINES_AND_INCLUDES) \
+ -I$(top_srcdir)/gr-audio-alsa/src
+
+GR_AUDIO_ALSA_LIBS=$(top_builddir)/gr-audio-alsa/src/libgr_audio_alsa.la
+
+# For compiling outside the tree, these are the usual
+# INCLUDES = -I/usr/local/include -I/usr/local/include/gnuradio
+# GNURADIO_CORE_LIBS = -lgnuradio-core
+# GR_AUDIO_ALSA_LIBS = -lgr_audio_alsa
+
+noinst_PROGRAMS = dialtone
+
+noinst_HEADERS = \
+ dialtone.h \
+ sink.h \
+ source.h \
+ siggen.h \
+ output.h
+
+dialtone_SOURCES = \
+ dialtone.cc \
+ source.cc \
+ sink.cc \
+ siggen.cc \
+ output.cc \
+ main.cc
+
+dialtone_LDADD = \
+ $(GNURADIO_CORE_LIBS) \
+ $(GR_AUDIO_ALSA_LIBS)
+
+MOSTLYCLEANFILES = *~
diff --git a/gnuradio-examples/c++/hier/dialtone.cc b/gnuradio-examples/c++/hier/dialtone.cc
new file mode 100644
index 000000000..eb77cf27b
--- /dev/null
+++ b/gnuradio-examples/c++/hier/dialtone.cc
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2006 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 2, 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 <dialtone.h>
+#include <gr_io_signature.h>
+#include <source.h>
+#include <gr_kludge_copy.h>
+#include <sink.h>
+
+// Shared pointer constructor
+dialtone_sptr make_dialtone()
+{
+ return dialtone_sptr(new dialtone());
+}
+
+// Hierarchical block constructor, with no inputs or outputs
+dialtone::dialtone() :
+gr_hier_block2("dialtone",
+ gr_make_io_signature(0,0,0),
+ gr_make_io_signature(0,0,0))
+{
+ define_component("source", make_source());
+ define_component("copy", gr_make_kludge_copy(sizeof(float)));
+ define_component("sink", make_sink());
+
+ connect("source", 0, "copy", 0);
+ connect("source", 1, "copy", 1);
+ connect("copy", 0, "sink", 0);
+ connect("copy", 1, "sink", 1);
+}
diff --git a/gnuradio-examples/c++/hier/dialtone.h b/gnuradio-examples/c++/hier/dialtone.h
new file mode 100644
index 000000000..2beb46c50
--- /dev/null
+++ b/gnuradio-examples/c++/hier/dialtone.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2006 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 2, 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 <gr_hier_block2.h>
+
+class dialtone;
+typedef boost::shared_ptr<dialtone> dialtone_sptr;
+dialtone_sptr make_dialtone();
+
+class dialtone : public gr_hier_block2
+{
+private:
+ dialtone();
+ friend dialtone_sptr make_dialtone();
+};
diff --git a/gnuradio-examples/c++/hier/main.cc b/gnuradio-examples/c++/hier/main.cc
new file mode 100644
index 000000000..beefac3a5
--- /dev/null
+++ b/gnuradio-examples/c++/hier/main.cc
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2006 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 2, 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.
+ */
+
+// GNU Radio C++ application
+//
+// Instantiate a top block
+// Instantiate a runtime, passing it the top block
+// Tell the runtime to go...
+
+#include <dialtone.h>
+#include <gr_runtime.h>
+
+int main()
+{
+ dialtone_sptr top_block = make_dialtone();
+ gr_runtime_sptr runtime = gr_make_runtime(top_block);
+
+ runtime->run();
+ return 0;
+}
diff --git a/gnuradio-examples/c++/hier/output.cc b/gnuradio-examples/c++/hier/output.cc
new file mode 100644
index 000000000..88ee96e58
--- /dev/null
+++ b/gnuradio-examples/c++/hier/output.cc
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2006 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 2, 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 <output.h>
+#include <gr_io_signature.h>
+#include <audio_alsa_sink.h>
+
+// Shared pointer constructor
+output_sptr make_output()
+{
+ return output_sptr(new output());
+}
+
+output::output() :
+gr_hier_block2("output",
+ gr_make_io_signature(2,2,sizeof(float)),
+ gr_make_io_signature(0,0,0))
+{
+ define_component("audio", audio_alsa_make_sink(48000));
+
+ connect("self", 0, "audio", 0);
+ connect("self", 1, "audio", 1);
+}
diff --git a/gnuradio-examples/c++/hier/output.h b/gnuradio-examples/c++/hier/output.h
new file mode 100644
index 000000000..c2f5c99e4
--- /dev/null
+++ b/gnuradio-examples/c++/hier/output.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2006 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 2, 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 <gr_hier_block2.h>
+
+class output;
+typedef boost::shared_ptr<class output> output_sptr;
+output_sptr make_output();
+
+class output : public gr_hier_block2
+{
+private:
+ output();
+ friend output_sptr make_output();
+};
diff --git a/gnuradio-examples/c++/hier/siggen.cc b/gnuradio-examples/c++/hier/siggen.cc
new file mode 100644
index 000000000..f3b4f6733
--- /dev/null
+++ b/gnuradio-examples/c++/hier/siggen.cc
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2006 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 2, 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 <siggen.h>
+#include <gr_io_signature.h>
+#include <gr_sig_source_f.h>
+
+// Shared pointer constructor
+siggen_sptr make_siggen()
+{
+ return siggen_sptr(new siggen());
+}
+
+siggen::siggen() :
+gr_hier_block2("siggen",
+ gr_make_io_signature(0,0,0),
+ gr_make_io_signature(2,2,sizeof(float)))
+{
+ define_component("siggen0", gr_make_sig_source_f(48000, GR_SIN_WAVE, 350, 0.5));
+ define_component("siggen1", gr_make_sig_source_f(48000, GR_SIN_WAVE, 440, 0.5));
+
+ connect("siggen0", 0, "self", 0);
+ connect("siggen1", 0, "self", 1);
+}
diff --git a/gnuradio-examples/c++/hier/siggen.h b/gnuradio-examples/c++/hier/siggen.h
new file mode 100644
index 000000000..6169882c6
--- /dev/null
+++ b/gnuradio-examples/c++/hier/siggen.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2006 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 2, 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 <gr_hier_block2.h>
+
+class siggen;
+typedef boost::shared_ptr<class siggen> siggen_sptr;
+siggen_sptr make_siggen();
+
+class siggen : public gr_hier_block2
+{
+private:
+ siggen();
+ friend siggen_sptr make_siggen();
+};
diff --git a/gnuradio-examples/c++/hier/sink.cc b/gnuradio-examples/c++/hier/sink.cc
new file mode 100644
index 000000000..f073eb982
--- /dev/null
+++ b/gnuradio-examples/c++/hier/sink.cc
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2006 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 2, 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 <sink.h>
+#include <gr_io_signature.h>
+#include <gr_kludge_copy.h>
+#include <output.h>
+
+// Shared pointer constructor
+sink_sptr make_sink()
+{
+ return sink_sptr(new sink());
+}
+
+sink::sink() :
+gr_hier_block2("sink",
+ gr_make_io_signature(2,2,sizeof(float)),
+ gr_make_io_signature(0,0,0))
+{
+ define_component("copy", gr_make_kludge_copy(sizeof(float)));
+ define_component("output", make_output());
+
+ connect("self", 0, "copy", 0);
+ connect("self", 1, "copy", 1);
+ connect("copy", 0, "output", 0);
+ connect("copy", 1, "output", 1);
+}
diff --git a/gnuradio-examples/c++/hier/sink.h b/gnuradio-examples/c++/hier/sink.h
new file mode 100644
index 000000000..5428b59a6
--- /dev/null
+++ b/gnuradio-examples/c++/hier/sink.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2006 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 2, 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 <gr_hier_block2.h>
+
+class sink;
+typedef boost::shared_ptr<sink> sink_sptr;
+sink_sptr make_sink();
+
+class sink : public gr_hier_block2
+{
+private:
+ sink();
+ friend sink_sptr make_sink();
+};
diff --git a/gnuradio-examples/c++/hier/source.cc b/gnuradio-examples/c++/hier/source.cc
new file mode 100644
index 000000000..816f3aa2f
--- /dev/null
+++ b/gnuradio-examples/c++/hier/source.cc
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2006 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 2, 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 <source.h>
+#include <gr_io_signature.h>
+#include <siggen.h>
+
+// Shared pointer constructor
+source_sptr make_source()
+{
+ return source_sptr(new source());
+}
+
+source::source() :
+gr_hier_block2("source",
+ gr_make_io_signature(0,0,0),
+ gr_make_io_signature(2,2,sizeof(float)))
+{
+ define_component("siggen", make_siggen());
+
+ connect("siggen", 0, "self", 0);
+ connect("siggen", 1, "self", 1);
+}
diff --git a/gnuradio-examples/c++/hier/source.h b/gnuradio-examples/c++/hier/source.h
new file mode 100644
index 000000000..8057726c9
--- /dev/null
+++ b/gnuradio-examples/c++/hier/source.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2006 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 2, 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 <gr_hier_block2.h>
+
+class source;
+typedef boost::shared_ptr<source> source_sptr;
+source_sptr make_source();
+
+class source : public gr_hier_block2
+{
+private:
+ source();
+ friend source_sptr make_source();
+};
diff --git a/gnuradio-examples/python/audio/Makefile.am b/gnuradio-examples/python/audio/Makefile.am
index 0a1213c34..3f9b1626c 100644
--- a/gnuradio-examples/python/audio/Makefile.am
+++ b/gnuradio-examples/python/audio/Makefile.am
@@ -26,6 +26,7 @@ EXTRA_DIST = \
audio_to_file.py \
dial_squelch.py \
dial_tone.py \
+ dial_tone2.py \
dialtone_v.py \
mono_tone.py \
multi_tone.py \
diff --git a/gnuradio-examples/python/audio/dial_tone2.py b/gnuradio-examples/python/audio/dial_tone2.py
new file mode 100755
index 000000000..a91c6ff4d
--- /dev/null
+++ b/gnuradio-examples/python/audio/dial_tone2.py
@@ -0,0 +1,61 @@
+#!/usr/bin/env python
+#
+# Copyright 2004,2005,2006 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 2, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+from gnuradio import gr
+from gnuradio import audio
+from gnuradio.eng_option import eng_option
+from optparse import OptionParser
+
+class dial_tone(gr.hier_block2):
+ def __init__(self):
+ gr.hier_block2.__init__(self,
+ "dial_tone",
+ gr.io_signature(0,0,0),
+ gr.io_signature(0,0,0))
+
+ parser = OptionParser(option_class=eng_option)
+ parser.add_option("-O", "--audio-output", type="string", default="",
+ help="pcm output device name. E.g., hw:0,0 or /dev/dsp")
+ parser.add_option("-r", "--sample-rate", type="eng_float", default=48000,
+ help="set sample rate to RATE (48000)")
+ (options, args) = parser.parse_args ()
+ if len(args) != 0:
+ parser.print_help()
+ raise SystemExit, 1
+
+ sample_rate = int(options.sample_rate)
+ ampl = 0.1
+
+ self.define_component("source0", gr.sig_source_f (sample_rate, gr.GR_SIN_WAVE, 350, ampl))
+ self.define_component("source1", gr.sig_source_f (sample_rate, gr.GR_SIN_WAVE, 440, ampl))
+ self.define_component("dest", audio.sink(sample_rate, options.audio_output))
+ self.connect("source0", 0, "dest", 0)
+ self.connect("source1", 0, "dest", 1)
+
+if __name__ == '__main__':
+ top_block = dial_tone()
+ runtime = gr.runtime(top_block)
+
+ try:
+ runtime.run()
+ except KeyboardInterrupt:
+ runtime.stop()
diff --git a/gr-audio-alsa/src/Makefile.am b/gr-audio-alsa/src/Makefile.am
index 0f165a0dc..f9b69c78f 100644
--- a/gr-audio-alsa/src/Makefile.am
+++ b/gr-audio-alsa/src/Makefile.am
@@ -55,8 +55,12 @@ SWIGPYTHONARGS = $(SWIGPYTHONFLAGS) $(STD_DEFINES_AND_INCLUDES)
ourlib_LTLIBRARIES = _audio_alsa.la
+lib_LTLIBRARIES = libgr_audio_alsa.la
+
_audio_alsa_la_SOURCES = \
- audio_alsa.cc \
+ audio_alsa.cc
+
+libgr_audio_alsa_la_SOURCES = \
audio_alsa_sink.cc \
audio_alsa_source.cc \
gri_alsa.cc
@@ -76,10 +80,16 @@ _audio_alsa_la_LIBADD = \
$(PYTHON_LDFLAGS) \
$(GNURADIO_CORE_LIBS) \
$(ALSA_LIBS) \
+ libgr_audio_alsa.la \
-lstdc++
+libgr_audio_alsa_la_LIBADD = \
+ $(ALSA_LIBS)
+
_audio_alsa_la_LDFLAGS = $(NO_UNDEFINED) -module -avoid-version
+libgr_audio_alsa_la_LDFLAGS = $(NO_UNDEFINED) -avoid-version
+
audio_alsa.cc audio_alsa.py: $(LOCAL_IFILES) $(NON_LOCAL_IFILES)
$(SWIG) $(SWIGPYTHONARGS) -module audio_alsa -o audio_alsa.cc $(LOCAL_IFILES)