summaryrefslogtreecommitdiff
path: root/docs/doxygen
diff options
context:
space:
mode:
Diffstat (limited to 'docs/doxygen')
-rw-r--r--docs/doxygen/Doxyfile.in2
-rw-r--r--docs/doxygen/other/ctrlport.dox280
-rw-r--r--docs/doxygen/other/main_page.dox40
-rw-r--r--docs/doxygen/other/metadata.dox43
-rw-r--r--docs/doxygen/other/msg_passing.dox16
-rw-r--r--docs/doxygen/other/pfb_intro.dox14
-rw-r--r--docs/doxygen/other/pmt.dox186
7 files changed, 433 insertions, 148 deletions
diff --git a/docs/doxygen/Doxyfile.in b/docs/doxygen/Doxyfile.in
index 536661996b..86cf2fc96f 100644
--- a/docs/doxygen/Doxyfile.in
+++ b/docs/doxygen/Doxyfile.in
@@ -634,7 +634,7 @@ EXCLUDE = @abs_top_builddir@/docs/doxygen/html \
@abs_top_srcdir@/cmake \
@abs_top_srcdir@/gr-qtgui/lib \
@abs_top_srcdir@/gr-howto-write-a-block \
- @abs_top_srcdir@/gr-utils/src/python/modtool/gr-newmod
+ @abs_top_srcdir@/gr-utils/python/modtool/gr-newmod
# The EXCLUDE_SYMLINKS tag can be used select whether or not files or
# directories that are symbolic links (a Unix filesystem feature) are excluded
diff --git a/docs/doxygen/other/ctrlport.dox b/docs/doxygen/other/ctrlport.dox
new file mode 100644
index 0000000000..69f467b288
--- /dev/null
+++ b/docs/doxygen/other/ctrlport.dox
@@ -0,0 +1,280 @@
+/*! \page page_ctrlport ControlPort
+
+\section Introduction
+
+This is the gr-ctroport package. It is a tool to create distributed
+contol applications for GNU Radio. It provides blocks that can be
+connected to an output stream to plot the signal remotely. It also
+provides an API that allows blocks to export variables that can be
+set, monitored, and plotted remotely.
+
+The Python namespace is in gnuradio.ctrlport, which would be normally
+imported as:
+
+\code
+ from gnuradio import ctrlport
+\endcode
+
+
+See the Doxygen documentation for details about the blocks available
+in this package. A quick listing of the details can be found in Python
+after importing by using:
+
+\code
+ help(ctrlport)
+\endcode
+
+\section Dependencies
+
+ControlPort requires ZeroC's ICE and associated
+libraries/headers/programs. ICE is generally installed into the
+standard paths if using a software repo (like apt-get, yum, etc.). If
+installed by hand, GNU Radio assumes ICE is installed into
+/opt/Ice-3.4.2. If this is not the case, you can tell GNU Radio where
+to find ICE by passing to cmake the following:
+
+ -DICE_MANUAL_INSTALL_PATH=\<your path here\>
+
+\section conf Configuration
+
+ControlPort is configured using two files. The first is the GNU Radio
+preferences configuration while the second file is specific to the
+type of transport engine used. Since we are focusing on using ICE, the
+configuration file is the ICE configuration file and format.
+
+The GNU Radio preferences file allows you to enable or disable
+ControlPort. If enabled and a configuration file is used, this file
+also specifies the location of the configuration file.
+
+\code
+ [ControlPort]
+ on = True
+ config = ctrlport.conf
+\endcode
+
+The 'ctrlport.conf' holds specific properties related to the transport
+engine. If using ICE, more information can be found here:
+http://doc.zeroc.com/display/Ice/Properties+and+Configuration
+
+An example ICE config file is installed with GNU Radio to show how to
+change the exposed endpoint of ControlPort. This file is installed
+as ${prefix}/etc/gnuradio/ctrlport.conf.example.
+
+
+\section using Using ControlPort to Export Variables
+
+The ability to export variables from a block is inherited from
+gr_block. Then, when the flowgraph is started, the function
+<b>setup_rpc()</b> is called in turn for each block. If the block
+defines and exports variables using <b>setup_rpc()</b>, then they are
+now all available over ControlPort.
+
+The new block simply declares that it is overloading
+<b>setup_rpc()</b> in its header file. In the source file, it defines
+any setter and/or getting for a variable it wants.
+
+Say we have a class <b>gr::blocks::foo</b> that has variables <b>a</b>
+and <b>b</b> that we want to export. Specifically, we want to be able
+to read the values of both <b>a</b> and <b>b</b> and also set the
+value of <b>b</b>. The class <b>gr::blocks::foo</b> has setters and
+getters all set up. So our class declaration looks something like:
+
+\code
+namespace gr {
+ namespace blocks {
+
+ class foo_impl : public foo
+ {
+ private:
+ float d_a, d_b;
+
+ public:
+ foo_impl(float a, float b);
+ ~foo_impl();
+
+ float a() const { return d_a; }
+ float b() const { return d_a; }
+ void set_a(float a) { d_a = a; }
+ void set_b(float b) { d_b = b; }
+ void setup_rpc();
+ int work(int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+ };
+
+ } /* namespace blocks */
+} /* namespace gr */
+\endcode
+
+The source code then sets up the class and fills in
+<b>setup_rpc()</b>.
+
+\code
+namespace gr {
+ namespace blocks {
+
+ foo_impl::foo_impl(float a, float b):
+ gr_sync_bloc(....),
+ d_a(a), d_b(b)
+ { }
+
+ foo_impl::~foo_impl()
+ { }
+
+ void
+ foo_impl::setup_rpc()
+ {
+#ifdef GR_CTRLPORT
+ add_rpc_variable(
+ rpcbasic_sptr(new rpcbasic_register_get<foo, float>(
+ alias(), "a",
+ &foo::a,
+ pmt::mp(-2.0f), pmt::mp(2.0f), pmt::mp(0.0f),
+ "", "Get value of a", RPC_PRIVLVL_MIN,
+ DISPTIME | DISPOPTSTRIP)));
+
+ add_rpc_variable(
+ rpcbasic_sptr(new rpcbasic_register_get<foo, float>(
+ alias(), "b",
+ &foo::b,
+ pmt::mp(0.0f), pmt::mp(20.0f), pmt::mp(10.0f),
+ "", "Get value of b", RPC_PRIVLVL_MIN,
+ DISPTIME | DISPOPTSTRIP)));
+
+ add_rpc_variable(
+ rpcbasic_sptr(new rpcbasic_register_set<foo, float>(
+ alias(), "b",
+ &foo::set_b,
+ pmt::mp(0.0f), pmt::mp(20.0f), pmt::mp(10.0f),
+ "", "Set value of b", RPC_PRIVLVL_MIN,
+ DISPNULL)));
+#endif /* GR_CTRLPORT */
+ }
+
+ int
+ foo_impl::work(int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+ { .... }
+
+ } /* namespace blocks */
+} /* namespace gr */
+\endcode
+
+In the above example, we're ignoring some of the basic semantics of
+the class as a GNU Radio block and focus just on the call to set up
+the get and set functions over ControlPort. Each block has a function
+that allows us to add a new ControlPort interface object to a list,
+the <b>add_rpc_variable</b>. We don't care about that list anymore;
+that's for ControlPort to worry about. We just add new variables,
+either setters or getters.
+
+Without dissecting every piece of the above calls, notice that we use
+the public class, <b>gr::blocks::foo</b> as the class, not the
+implementation class. We also use the block's alias, which GNU Radio
+uses as a database entry to connect a block by name to the pointer in
+memory. This allows ControlPort to know where the object in memory is
+at any given time to access the setters and getters.
+
+The three PMTs specified are simply an expected minimum, maximum, and
+default value. None of these are strictly enforced and only serve as
+guides. The RPC_PRIVLVL_MIN is currently a placeholder for a
+privilege level setting. In many cases, reading <b>b</b> might be
+fine for everyone, but we want strong restrictions on who has the
+ability to set <b>b</b>.
+
+And finally, we can specify display options to hint at the right way
+to display this variable when remotely plotting it. More on that in
+the following section.
+
+Finally, note that we put \#ifdefs around the code. We always want
+<b>setup_rpc</b> to be there and callable, but if ControlPort was not
+built for GNU Radio, we cannot register any variables with it. This is
+just a nicety to allow us to set up our code for use with ControlPort
+without requiring it.
+
+
+\subsection alt_reg Alternative Registers
+
+If using the concept above, <b>setup_rpc</b> automatically gets called
+when the flowgraph is started. In most instances, this is all we ever
+need since there's nothing interesting going on until then. However,
+if not using a gr_block or needing access before we run the flowgraph,
+the above method won't work (it comes down to when the block's alias
+has meaning).
+
+There are alternate variable registration functions for the sets and
+gets. These take the form:
+
+\code
+ rpcbasic_register_get(const std::string& name,
+ const char* functionbase,
+ T* obj,
+ Tfrom (T::*function)(),
+ const pmt::pmt_t &min, const pmt::pmt_t &max, const pmt::pmt_t &def,
+ const char* units_ = "",
+ const char* desc_ = "",
+ priv_lvl_t minpriv_ = RPC_PRIVLVL_MIN,
+ DisplayType display_ = DISPNULL)
+
+ rpcbasic_register_set(const std::string& name,
+ const char* functionbase,
+ T* obj,
+ void (T::*function)(Tto),
+ const pmt::pmt_t &min, const pmt::pmt_t &max, const pmt::pmt_t &def,
+ const char* units_ = "",
+ const char* desc_ = "",
+ priv_lvl_t minpriv_ = RPC_PRIVLVL_MIN,
+ DisplayType display_ = DISPNULL)
+\endcode
+
+The only thing different about the above code is that instead of
+taking a single 'alias()' name, which provides us access to the
+objects pointer, we instead provide a unique name
+(<b>fucntionbase</b>) and a pointer to the object itself
+(<b>obj</b>). These are templated functions, so the class T is known
+from that.
+
+If using this method, the recommended way is to create a new function
+(not <b>setup_rpc</b>), register the variable using
+<b>add_rpc_variable</b> but with the different <b>register_get/set</b>
+shown here, and then call this function either in the object's
+constructor or make it a public member function to be called when you
+need it.
+
+
+\section disp Display Options
+
+When exporting a new RPC variable over ControlPort, one argument is a
+display options mask. These options are useful to a remote client to
+tell identify activities like default plotters and initial
+conditions. The gr-ctrlport-monitor application uses this heavily in
+determining how to plot ControlPort variables.
+
+The options mask is just a 32-bit value with options OR'd
+together. Certain options are only appropriate for certain types of
+plots. Options on plots where that option is not available will
+simply be ignored.
+
+The main caveat to be aware of is that the DISPXY plot type is
+specific to complex values. Therefore, DISPOPTCPLX is assumed.
+
+These options are specified in rpccallbackregister_base.h and are
+exposed through SWIG to live in the \b gr namespace.
+
+<b>Plot Types</b>
+\li <b>DISPNULL:</b> Nothing specified.
+\li <b>DISPTIME:</b> Time-domain plot.
+\li <b>DISPXY:</b> XY or constellation plot (complex only).
+\li <b>DISPPSD:</b> PSD plot.
+\li <b>DISPSPEC:</b> Spectrogram plot.
+\li <b>DISPRAST:</b> Time raster plot (non-complex only)
+
+<b>Plot Options</b>
+\li <b>DISPOPTCPLX:</b> Signal is complex.
+\li <b>DISPOPTLOG:</b> Start plot in semilog-y mode (time domain only).
+\li <b>DISPOPTSTEM:</b> Start plot in stem mode (time domain only).
+\li <b>DISPOPTSTRIP:</b> Run plot as a stripchart (time domain only).
+\li <b>DISPOPTSCATTER:</b> Do scatter plot instead of lines (XY plot only).
+
+*/
diff --git a/docs/doxygen/other/main_page.dox b/docs/doxygen/other/main_page.dox
index 8895cd552d..f9e335061c 100644
--- a/docs/doxygen/other/main_page.dox
+++ b/docs/doxygen/other/main_page.dox
@@ -69,7 +69,7 @@ done. A single source and sink are used with a FIR filter between
them.
\code
- from gnuradio import gr, filter
+ from gnuradio import gr, filter, analog
class my_topblock(gr.top_block):
def __init__(self):
@@ -78,7 +78,7 @@ them.
amp = 1
taps = filter.firdes.low_pass(1, 1, 0.1, 0.01)
- self.src = gr.noise_source_c(gr.GR_GAUSSIAN, amp)
+ self.src = analog.noise_source_c(gr.GR_GAUSSIAN, amp)
self.flt = filter.fir_filter_ccf(1, taps)
self.snk = gr.null_sink(gr.sizeof_gr_complex)
@@ -202,7 +202,7 @@ buffer, which may be different than what was initially specified.
It is possible to reconfigure the flowgraph at runtime. The
reconfiguration is meant for changes in the flowgraph structure, not
individual parameter settings of the blocks. For example, changing the
-constant in a gr_add_const_cc block can be done while the flowgraph is
+constant in a gr::blocks::add_const_cc block can be done while the flowgraph is
running using the 'set_k(k)' method.
Reconfiguration is done by locking the flowgraph, which stops it from
@@ -210,23 +210,24 @@ running and processing data, performing the reconfiguration, and then
restarting the graph by unlocking it.
The following example code shows a graph that first adds two
-gr_noise_source_c blocks and then replaces the gr_add_cc block with a
-gr_sub_cc block to then subtract the sources.
+gr::analog::noise_source_c blocks and then replaces the
+gr::blocks::add_cc block with a gr::blocks::sub_cc block to then
+subtract the sources.
\code
-from gnuradio import gr
+from gnuradio import gr, analog, blocks
import time
class mytb(gr.top_block):
def __init__(self):
gr.top_block.__init__(self)
- self.src0 = gr.noise_source_c(gr.GR_GAUSSIAN, 1)
- self.src1 = gr.noise_source_c(gr.GR_GAUSSIAN, 1)
- self.add = gr.add_cc()
- self.sub = gr.sub_cc()
+ self.src0 = analog.noise_source_c(analog.GR_GAUSSIAN, 1)
+ self.src1 = analog.noise_source_c(analog.GR_GAUSSIAN, 1)
+ self.add = blocks.add_cc()
+ self.sub = blocks.sub_cc()
self.head = gr.head(gr.sizeof_gr_complex, 1000000)
- self.snk = gr.file_sink(gr.sizeof_gr_complex, "output.32fc")
+ self.snk = blocks.file_sink(gr.sizeof_gr_complex, "output.32fc")
self.connect(self.src0, (self.add,0))
self.connect(self.src1, (self.add,1))
@@ -269,19 +270,19 @@ The following example expands the previous example but sets and resets
the max noutput_items both locally and globally.
\code
-from gnuradio import gr
+from gnuradio import gr, analog, blocks
import time
class mytb(gr.top_block):
def __init__(self):
gr.top_block.__init__(self)
- self.src0 = gr.noise_source_c(gr.GR_GAUSSIAN, 1)
- self.src1 = gr.noise_source_c(gr.GR_GAUSSIAN, 1)
- self.add = gr.add_cc()
- self.sub = gr.sub_cc()
+ self.src0 = analog.noise_source_c(analog.GR_GAUSSIAN, 1)
+ self.src1 = analog.noise_source_c(analog.GR_GAUSSIAN, 1)
+ self.add = blocks.add_cc()
+ self.sub = blocks.sub_cc()
self.head = gr.head(gr.sizeof_gr_complex, 1000000)
- self.snk = gr.file_sink(gr.sizeof_gr_complex, "output.32fc")
+ self.snk = blocks.file_sink(gr.sizeof_gr_complex, "output.32fc")
self.connect(self.src0, (self.add,0))
self.connect(self.src1, (self.add,1))
@@ -326,8 +327,9 @@ The \ref volk_guide page provides an overview of how to incorporate
and use Volk in GNU Radio blocks.
Many blocks have already been converted to use Volk in their calls, so
-they can also serve as examples. See the gr_complex_to_xxx.h file for
-examples of various blocks that make use of Volk.
+they can also serve as examples. See the
+gr::blocks::complex_to_<type>.h files for examples of various blocks
+that make use of Volk.
\section prefs Configuration / Preference Files
diff --git a/docs/doxygen/other/metadata.dox b/docs/doxygen/other/metadata.dox
index b527b21008..76553c696a 100644
--- a/docs/doxygen/other/metadata.dox
+++ b/docs/doxygen/other/metadata.dox
@@ -106,7 +106,7 @@ interface.
The file metadata consists of a static mandatory header and a dynamic
optional extras header. Each header is a separate PMT
dictionary. Headers are created by building a PMT dictionary
-(pmt::pmt_make_dict) of key:value pairs, then the dictionary is
+(pmt::make_dict) of key:value pairs, then the dictionary is
serialized into a string to be written to file. The header is always
the same length that is predetermined by the version of the header
(this must be known already). The header will then indicate if there
@@ -117,27 +117,26 @@ we use PMT operators. For example, we create a simplified version of
the header in C++ like this:
\code
- using namespace pmt;
const char METADATA_VERSION = 0x0;
- pmt_t header;
- header = pmt_make_dict();
- header = pmt_dict_add(header, mp("version"), mp(METADATA_VERSION));
- header = pmt_dict_add(header, mp("rx_rate"), mp(samp_rate));
- std::string hdr_str = pmt_serialize_str(header);
+ pmt::pmt_t header;
+ header = pmt::make_dict();
+ header = pmt::dict_add(header, pmt::mp("version"), pmt::mp(METADATA_VERSION));
+ header = pmt::dict_add(header, pmt::mp("rx_rate"), pmt::mp(samp_rate));
+ std::string hdr_str = pmt::serialize_str(header);
\endcode
-The call to pmt::pmt_dict_add adds a new key:value pair to the
+The call to pmt::dict_add adds a new key:value pair to the
dictionary. Notice that it both takes and returns the 'header'
variable. This is because we are actually creating a new dictionary
with this function, so we just assign it to the same variable.
The 'mp' functions are convenience functions provided by the PMT
library. They interpret the data type of the value being inserted and
-call the correct 'pmt_from_xxx' function. For more direct control over
+call the correct 'pmt::from_xxx' function. For more direct control over
the data type, see PMT functions in pmt.h, such as
-pmt::pmt_from_uint64 or pmt::pmt_from_double.
+pmt::from_uint64 or pmt::from_double.
-We finish this off by using pmt::pmt_serialize_str to convert the PMT
+We finish this off by using pmt::serialize_str to convert the PMT
dictionary into a specialized string format that makes it easy to
write to a file.
@@ -153,10 +152,10 @@ Assuming that 'std::string str' contains the full string as read from
a file, we can access the dictionary in C++ like this:
\code
- pmt_t hdr = pmt_deserialize_str(str);
- if(pmt_dict_has_key(hdr, pmt_string_to_symbol("strt"))) {
- pmt_t r = pmt_dict_ref(hdr, pmt_string_to_symbol("strt"), PMT_NIL);
- uint64_t seg_start = pmt_to_uint64(r);
+ pmt::pmt_t hdr = pmt::deserialize_str(str);
+ if(pmt::dict_has_key(hdr, pmt::string_to_symbol("strt"))) {
+ pmt::pmt_t r = pmt::dict_ref(hdr, pmt::string_to_symbol("strt"), pmt::PMT_NIL);
+ uint64_t seg_start = pmt::to_uint64(r);
uint64_t extra_len = seg_start - METADATA_HEADER_SIZE;
}
\endcode
@@ -221,7 +220,7 @@ a PMT dictionary of key:value pairs. The extras header can contain
anything and can grow while a program is running.
We can insert extra data into the header at the beginning if we
-wish. All we need to do is use the pmt::pmt_dict_add function to insert
+wish. All we need to do is use the pmt::dict_add function to insert
our hand-made metadata. This can be useful to add our own markers and
information.
@@ -239,7 +238,7 @@ When reading out data from the extras, we do not necessarily know the
data type of the PMT value. The key is always a PMT symbol, but the
value can be any other PMT type. There are PMT functions that allow us
to query the PMT to test if it is a particular type. We also have the
-ability to do pmt::pmt_print on any PMT object to print it to
+ability to do pmt::print on any PMT object to print it to
screen. Before converting from a PMT to it's natural data type, it is
necessary to know the data type.
@@ -313,12 +312,12 @@ encoded as a vector of uint16 with [day, month, year].
from gruel import pmt
from gnuradio import blocks
- key = pmt.pmt_intern("date")
- val = pmt.pmt_init_u16vector(3, [13,12,2012])
+ key = pmt.intern("date")
+ val = pmt.init_u16vector(3, [13,12,2012])
- extras = pmt.pmt_make_dict()
- extras = pmt.pmt_dict_add(extras, key, val)
- extras_str = pmt.pmt_serialize_str(extras)
+ extras = pmt.make_dict()
+ extras = pmt.dict_add(extras, key, val)
+ extras_str = pmt.serialize_str(extras)
self.sink = blocks.file_meta_sink(gr.sizeof_gr_complex,
"/tmp/metadat_file.out",
samp_rate, 1,
diff --git a/docs/doxygen/other/msg_passing.dox b/docs/doxygen/other/msg_passing.dox
index aea0ac94ae..7035f291e4 100644
--- a/docs/doxygen/other/msg_passing.dox
+++ b/docs/doxygen/other/msg_passing.dox
@@ -83,7 +83,7 @@ received by \b dbg on port \a print. Note here how we are just using
strings to define the ports, not PMT symbols. This is a convenience to
the user to be able to more easily type in the port names (for
reference, you can create a PMT symbol in Python using the
-pmt::pmt_intern function as pmt.pmt_intern("string")).
+pmt::intern function as pmt.intern("string")).
Users can also query blocks for the names of their input and output
ports using the following API calls:
@@ -157,13 +157,13 @@ void
gr_message_debug::print(pmt::pmt_t msg)
{
std::cout << "***** MESSAGE DEBUG PRINT ********\n";
- pmt::pmt_print(msg);
+ pmt::print(msg);
std::cout << "**********************************\n";
}
\endcode
The function simply takes in the PMT message and prints it. The method
-pmt::pmt_print is a function in the PMT library to print the
+pmt::print is a function in the PMT library to print the
PMT in a friendly, (mostly) pretty manner.
The gr_tagged_stream_to_pdu block only defines a single
@@ -196,11 +196,11 @@ gr_tagged_stream_to_pdu::send_message function that is shown below.
void
gr_tagged_stream_to_pdu::send_meassage()
{
- if(pmt::pmt_length(d_pdu_vector) != d_pdu_length) {
+ if(pmt::length(d_pdu_vector) != d_pdu_length) {
throw std::runtime_error("msg length not correct");
}
- pmt::pmt_t msg = pmt::pmt_cons(d_pdu_meta,
+ pmt::pmt_t msg = pmt::cons(d_pdu_meta,
d_pdu_vector);
message_port_pub(pdu_port_id, msg);
@@ -247,9 +247,9 @@ flowgraph. These PDUs could come from another block or flowgraph, but
here, we will create and insert them by hand.
\code
- port = pmt.pmt_intern("pdus")
- msg = pmt.pmt_cons(pmt.PMT_NIL,
- pmt.pmt_make_u8vector(16, 0xFF))
+ port = pmt.intern("pdus")
+ msg = pmt.cons(pmt.PMT_NIL,
+ pmt.make_u8vector(16, 0xFF))
src.to_basic_block()._post(port, msg)
\endcode
diff --git a/docs/doxygen/other/pfb_intro.dox b/docs/doxygen/other/pfb_intro.dox
index 01d08b0fad..1ef0c38f6d 100644
--- a/docs/doxygen/other/pfb_intro.dox
+++ b/docs/doxygen/other/pfb_intro.dox
@@ -30,9 +30,9 @@ filter that is then split up between the \p N channels of the PFB.
self._fs = 9000 # input sample rate
self._M = 9 # Number of channels to channelize
- self._taps = gr.firdes.low_pass_2(1, self._fs, 475.50, 50,
- attenuation_dB=100,
- window=gr.firdes.WIN_BLACKMAN_hARRIS)
+ self._taps = filter.firdes.low_pass_2(1, self._fs, 475.50, 50,
+ attenuation_dB=100,
+ window=filter.firdes.WIN_BLACKMAN_hARRIS)
\endcode
In this example, the signal into the channelizer is sampled at 9 ksps
@@ -64,9 +64,9 @@ defined to use a sample rate of \p filter_size times the signal's
sampling rate.
A helpful wrapper for the arbitrary resampler is found in
-<b>gnuradio-core/src/python/gnuradio/blks2impl/pfb_arb_resampler.py</b>,
-which is exposed in Python as <b>blks2.pfb_arb_resampler_ccf</b> and
-<b>blks2.pfb_arb_resampler_fff</b>. This block is set up so that the
+<b>gr-filter/python/pfb.py</b>,
+which is exposed in Python as <b>filter.pfb.arb_resampler_ccf</b> and
+<b>filter.pfb.arb_resampler_fff</b>. This block is set up so that the
user only needs to pass it the real number \p rate as the resampling
rate. With just this information, this hierarchical block
automatically creates a filter that fully passes the signal bandwidth
@@ -91,6 +91,6 @@ channels.
NOTE: you need the Scipy and Matplotlib Python modules installed to
run this example.
-\include gnuradio-core/src/examples/pfb/channelize.py
+\include gr-filter/examples/channelize.py
*/
diff --git a/docs/doxygen/other/pmt.dox b/docs/doxygen/other/pmt.dox
index 61b73bca13..ba97863a08 100644
--- a/docs/doxygen/other/pmt.dox
+++ b/docs/doxygen/other/pmt.dox
@@ -66,25 +66,25 @@ underneath is still a C++ typed object, and so the right type of
set/get function must be used for the data type.
Typically, a PMT object can be made from a scalar item using a call
-like "pmt::pmt_from_<type>". Similarly, when getting data out of a
-PMT, we use a call like "pmt::pmt_to_<type>". For example:
+like "pmt::from_<type>". Similarly, when getting data out of a
+PMT, we use a call like "pmt::to_<type>". For example:
\code
double a = 1.2345;
-pmt::pmt_t pmt_a = pmt::pmt_from_double(a);
-double b = pmt::pmt_to_double(pmt_a);
+pmt::pmt_t pmt_a = pmt::from_double(a);
+double b = pmt::to_double(pmt_a);
int c = 12345;
-pmt::pmt_t pmt_c = pmt::pmt_from_long(c);
-int d = pmt::pmt_to_long(pmt_c);
+pmt::pmt_t pmt_c = pmt::from_long(c);
+int d = pmt::to_long(pmt_c);
\endcode
As a side-note, making a PMT from a complex number is not obvious:
\code
std::complex<double> a(1.2, 3.4);
-pmt::pmt_t pmt_a = pmt::pmt_make_rectangular(a.real(), b.imag());
-std::complex<double> b = pmt::pmt_to_complex(pmt_a);
+pmt::pmt_t pmt_a = pmt::make_rectangular(a.real(), b.imag());
+std::complex<double> b = pmt::to_complex(pmt_a);
\endcode
Pairs, dictionaries, and vectors have different constructors and ways
@@ -100,17 +100,17 @@ new symbol from a string, if that string already exists in the hash
table, the constructor will return a reference to the existing PMT.
We create strings with the following functions, where the second
-function, pmt::pmt_intern, is simply an alias of the first.
+function, pmt::intern, is simply an alias of the first.
\code
-pmt::pmt_t str0 = pmt::pmt_string_to_symbol(std::string("some string"));
-pmt::pmt_t str1 = pmt::pmt_intern(std::string("some string"));
+pmt::pmt_t str0 = pmt::string_to_symbol(std::string("some string"));
+pmt::pmt_t str1 = pmt::intern(std::string("some string"));
\endcode
The string can be retrieved using the inverse function:
\code
-std::string s = pmt::pmt_symbol_to_string(str0);
+std::string s = pmt::symbol_to_string(str0);
\endcode
@@ -118,28 +118,28 @@ std::string s = pmt::pmt_symbol_to_string(str0);
The PMT library comes with a number of functions to test and compare
PMT objects. In general, for any PMT data type, there is an equivalent
-"pmt::pmt_is_<type>". We can use these to test the PMT before trying
+"pmt::is_<type>". We can use these to test the PMT before trying
to access the data inside. Expanding our examples above, we have:
\code
-pmt::pmt_t str0 = pmt::pmt_string_to_symbol(std::string("some string"));
-if(pmt::pmt_is_symbol(str0))
- std::string s = pmt::pmt_symbol_to_string(str0);
+pmt::pmt_t str0 = pmt::string_to_symbol(std::string("some string"));
+if(pmt::is_symbol(str0))
+ std::string s = pmt::symbol_to_string(str0);
double a = 1.2345;
-pmt::pmt_t pmt_a = pmt::pmt_from_double(a);
-if(pmt::pmt_is_double(pmt_a))
- double b = pmt::pmt_to_double(pmt_a);
+pmt::pmt_t pmt_a = pmt::from_double(a);
+if(pmt::is_double(pmt_a))
+ double b = pmt::to_double(pmt_a);
int c = 12345;
-pmt::pmt_t pmt_c = pmt::pmt_from_long(c);
-if(pmt::pmt_is_long(pmt_a))
- int d = pmt::pmt_to_long(pmt_c);
+pmt::pmt_t pmt_c = pmt::from_long(c);
+if(pmt::is_long(pmt_a))
+ int d = pmt::to_long(pmt_c);
\\ This will fail the test. Otherwise, trying to coerce \b pmt_c as a
\\ double when internally it is a long will result in an exception.
-if(pmt::pmt_is_double(pmt_a))
- double d = pmt::pmt_to_double(pmt_c);
+if(pmt::is_double(pmt_a))
+ double d = pmt::to_double(pmt_c);
\endcode
@@ -156,15 +156,15 @@ returned dictionary is a new PMT with the changes made there.
The following is a list of PMT dictionary functions. Click through to
get more information on what each does.
-- bool pmt::pmt_is_dict(const pmt_t &obj)
-- pmt_t pmt::pmt_make_dict()
-- pmt_t pmt::pmt_dict_add(const pmt_t &dict, const pmt_t &key, const pmt_t &value)
-- pmt_t pmt::pmt_dict_delete(const pmt_t &dict, const pmt_t &key)
-- bool pmt::pmt_dict_has_key(const pmt_t &dict, const pmt_t &key)
-- pmt_t pmt::pmt_dict_ref(const pmt_t &dict, const pmt_t &key, const pmt_t &not_found)
-- pmt_t pmt::pmt_dict_items(pmt_t dict)
-- pmt_t pmt::pmt_dict_keys(pmt_t dict)
-- pmt_t pmt::pmt_dict_values(pmt_t dict)
+- bool pmt::is_dict(const pmt_t &obj)
+- pmt_t pmt::make_dict()
+- pmt_t pmt::dict_add(const pmt_t &dict, const pmt_t &key, const pmt_t &value)
+- pmt_t pmt::dict_delete(const pmt_t &dict, const pmt_t &key)
+- bool pmt::dict_has_key(const pmt_t &dict, const pmt_t &key)
+- pmt_t pmt::dict_ref(const pmt_t &dict, const pmt_t &key, const pmt_t &not_found)
+- pmt_t pmt::dict_items(pmt_t dict)
+- pmt_t pmt::dict_keys(pmt_t dict)
+- pmt_t pmt::dict_values(pmt_t dict)
This example does some basic manipulations of PMT dictionaries in
Python. Notice that we pass the dictionary \a a and return the results
@@ -175,39 +175,39 @@ variables small.
\code
from gruel import pmt
-key0 = pmt.pmt_intern("int")
-val0 = pmt.pmt_from_long(123)
-val1 = pmt.pmt_from_long(234)
+key0 = pmt.intern("int")
+val0 = pmt.from_long(123)
+val1 = pmt.from_long(234)
-key1 = pmt.pmt_intern("double")
-val2 = pmt.pmt_from_double(5.4321)
+key1 = pmt.tern("double")
+val2 = pmt.om_double(5.4321)
# Make an empty dictionary
-a = pmt.pmt_make_dict()
+a = pmt.make_dict()
# Add a key:value pair to the dictionary
-a = pmt.pmt_dict_add(a, key0, val0)
-pmt.pmt_print(a)
+a = pmt.dict_add(a, key0, val0)
+print a
# Add a new value to the same key;
# new dict will still have one item with new value
-a = pmt.pmt_dict_add(a, key0, val1)
-pmt.pmt_print(a)
+a = pmt.dict_add(a, key0, val1)
+print a
# Add a new key:value pair
-a = pmt.pmt_dict_add(a, key1, val2)
-pmt.pmt_print(a)
+a = pmt.dict_add(a, key1, val2)
+print a
# Test if we have a key, then delete it
-print pmt.pmt_dict_has_key(a, key1)
-a = pmt.pmt_dict_delete(a, key1)
-print pmt.pmt_dict_has_key(a, key1)
+print pmt.dict_has_key(a, key1)
+a = pmt.dict_delete(a, key1)
+print pmt.dict_has_key(a, key1)
-ref = pmt.pmt_dict_ref(a, key0, pmt.PMT_NIL)
-pmt.pmt_print(ref)
+ref = pmt.dict_ref(a, key0, pmt.PMT_NIL)
+print ref
# The following should never print
-if(pmt.pmt_dict_has_key(a, key0) and pmt.pmt_eq(ref, pmt.PMT_NIL)):
+if(pmt.dict_has_key(a, key0) and pmt.eq(ref, pmt.PMT_NIL)):
print "Trouble! We have key0, but it returned PMT_NIL"
\endcode
@@ -232,29 +232,29 @@ both signed and unsigned.
Vectors have a well-defined interface that allows us to make, set,
get, and fill them. We can also get the length of a vector with
-pmt::pmt_length.
+pmt::length.
For standard vectors, these functions look like:
-- bool pmt::pmt_is_vector(pmt_t x)
-- pmt_t pmt::pmt_make_vector(size_t k, pmt_t fill)
-- pmt_t pmt::pmt_vector_ref(pmt_t vector, size_t k)
-- void pmt::pmt_vector_set(pmt_t vector, size_t k, pmt_t obj)
-- void pmt::pmt_vector_fill(pmt_t vector, pmt_t fill)
+- bool pmt::is_vector(pmt_t x)
+- pmt_t pmt::make_vector(size_t k, pmt_t fill)
+- pmt_t pmt::vector_ref(pmt_t vector, size_t k)
+- void pmt::vector_set(pmt_t vector, size_t k, pmt_t obj)
+- void pmt::vector_fill(pmt_t vector, pmt_t fill)
Uniform vectors have the same types of functions, but they are data
type-dependent. The following list tries to explain them where you
substitute the specific data type prefix for \a dtype (prefixes being:
u8, u16, u32, u64, s8, s16, s32, s64, f32, f64, c32, c64).
-- bool pmt::pmt_is_(dtype)vector(pmt_t x)
-- pmt_t pmt::pmt_make_(dtype)vector(size_t k, (dtype) fill)
-- pmt_t pmt::pmt_init_(dtype)vector(size_t k, const (dtype*) data)
-- pmt_t pmt::pmt_init_(dtype)vector(size_t k, const std::vector<dtype> data)
-- pmt_t pmt::pmt_(dtype)vector_ref(pmt_t vector, size_t k)
-- void pmt::pmt_(dtype)vector_set(pmt_t vector, size_t k, (dtype) x)
-- const dtype* pmt::pmt_(dtype)vector_elements(pmt_t vector, size_t &len)
-- dtype* pmt::pmt_(dtype)vector_writable_elements(pmt_t vector, size_t &len)
+- bool pmt::is_(dtype)vector(pmt_t x)
+- pmt_t pmt::make_(dtype)vector(size_t k, (dtype) fill)
+- pmt_t pmt::init_(dtype)vector(size_t k, const (dtype*) data)
+- pmt_t pmt::init_(dtype)vector(size_t k, const std::vector<dtype> data)
+- pmt_t pmt::(dtype)vector_ref(pmt_t vector, size_t k)
+- void pmt::(dtype)vector_set(pmt_t vector, size_t k, (dtype) x)
+- const dtype* pmt::(dtype)vector_elements(pmt_t vector, size_t &len)
+- dtype* pmt::(dtype)vector_writable_elements(pmt_t vector, size_t &len)
\b Note: We break the contract with vectors. The 'set' functions
actually change the data underneath. It is important to keep track of
@@ -276,12 +276,12 @@ Pairs are inspired by LISP 'cons' data types, so you will find the
language here comes from LISP. A pair is just a pair of PMT
objects. They are manipulated using the following functions:
-- bool pmt::pmt_is_pair (const pmt_t &obj): Return true if obj is a pair, else false
-- pmt_t pmt::pmt_cons(const pmt_t &x, const pmt_t &y): construct new pair
-- pmt_t pmt::pmt_car(const pmt_t &pair): get the car of the pair (first object)
-- pmt_t pmt::pmt_cdr(const pmt_t &pair): get the cdr of the pair (second object)
-- void pmt::pmt_set_car(pmt_t pair, pmt_t value): Stores value in the car field
-- void pmt::pmt_set_cdr(pmt_t pair, pmt_t value): Stores value in the cdr field
+- bool pmt::is_pair(const pmt_t &obj): Return true if obj is a pair, else false
+- pmt_t pmt::cons(const pmt_t &x, const pmt_t &y): construct new pair
+- pmt_t pmt::car(const pmt_t &pair): get the car of the pair (first object)
+- pmt_t pmt::cdr(const pmt_t &pair): get the cdr of the pair (second object)
+- void pmt::set_car(pmt_t pair, pmt_t value): Stores value in the car field
+- void pmt::set_cdr(pmt_t pair, pmt_t value): Stores value in the cdr field
\section serdes Serializing and Deserializing
@@ -293,10 +293,10 @@ string and then methods to deserialize the string buffer or string
back into a PMT. We use this extensively in the metadata files (see
\ref page_metadata).
-- bool pmt::pmt_serialize(pmt_t obj, std::streambuf &sink)
-- std::string pmt::pmt_serialize_str(pmt_t obj)
-- pmt_t pmt::pmt_deserialize(std::streambuf &source)
-- pmt_t pmt::pmt_deserialize_str(std::string str)
+- bool pmt::serialize(pmt_t obj, std::streambuf &sink)
+- std::string pmt::serialize_str(pmt_t obj)
+- pmt_t pmt::deserialize(std::streambuf &source)
+- pmt_t pmt::deserialize_str(std::string str)
For example, we will serialize the data above to make it into a string
ready to be written to a file and then deserialize it back to its
@@ -305,26 +305,26 @@ original PMT.
\code
from gruel import pmt
-key0 = pmt.pmt_intern("int")
-val0 = pmt.pmt_from_long(123)
+key0 = pmt.intern("int")
+val0 = pmt.from_long(123)
-key1 = pmt.pmt_intern("double")
-val1 = pmt.pmt_from_double(5.4321)
+key1 = pmt.intern("double")
+val1 = pmt.from_double(5.4321)
# Make an empty dictionary
-a = pmt.pmt_make_dict()
+a = pmt.make_dict()
# Add a key:value pair to the dictionary
-a = pmt.pmt_dict_add(a, key0, val0)
-a = pmt.pmt_dict_add(a, key1, val1)
+a = pmt.dict_add(a, key0, val0)
+a = pmt.dict_add(a, key1, val1)
-pmt.pmt_print(a)
+print a
-ser_str = pmt.pmt_serialize_str(a)
+ser_str = pmt.serialize_str(a)
print ser_str
-b = pmt.pmt_deserialize_str(ser_str)
-pmt.pmt_print(b)
+b = pmt.deserialize_str(ser_str)
+print b
\endcode
@@ -335,13 +335,17 @@ string. This is only done here as a test.
\section printing Printing
-We have used the pmt::pmt_print function in these examples to nicely
-print the contents of a PMT. Another way to print the contents is
-using the overloaded "<<" operator with a stream buffer object. In
-C++, we can inline print the contents of a PMT like:
+In Python, the __repr__ function of a PMT object is overloaded to call
+'pmt::write_string'. This means that any time we call a formatted
+printing operation on a PMT object, the PMT library will properly
+format the object for display.
+
+In C++, we can use the 'pmt::print(object)' function or print the
+contents is using the overloaded "<<" operator with a stream buffer
+object. In C++, we can inline print the contents of a PMT like:
\code
-pmt::pmt_t a pmt::pmt_from_double(1.0);
+pmt::pmt_t a pmt::from_double(1.0);
std::cout << "The PMT a contains " << a << std::endl;
\endcode