summaryrefslogtreecommitdiff
path: root/docs/doxygen
diff options
context:
space:
mode:
authorMarc Lichtman <marcll@vt.edu>2018-11-02 00:53:52 -0400
committerMarc L <marcll@vt.edu>2019-06-07 12:45:14 -0400
commit73b074f121b0ab2ac38336916a60891c4d88d2cb (patch)
treede8f1782c897af3c278c224dcfbf96345c5c6f1d /docs/doxygen
parentb6f15c59e96aa83142c47aeacd64da793dd8ba31 (diff)
docs: moved usage manual to wiki
docs: first snapshot of wiki's usage manual
Diffstat (limited to 'docs/doxygen')
-rw-r--r--docs/doxygen/other/logger.dox247
-rw-r--r--docs/doxygen/other/metadata.dox350
-rw-r--r--docs/doxygen/other/msg_passing.dox381
-rw-r--r--docs/doxygen/other/ofdm.dox152
-rw-r--r--docs/doxygen/other/oot_config.dox87
-rw-r--r--docs/doxygen/other/operating_fg.dox287
-rw-r--r--docs/doxygen/other/packet_txrx.dox91
-rw-r--r--docs/doxygen/other/perf_counters.dox107
-rw-r--r--docs/doxygen/other/pfb_intro.dox167
-rw-r--r--docs/doxygen/other/pmt.dox506
-rw-r--r--docs/doxygen/other/prefs.dox96
-rw-r--r--docs/doxygen/other/python_blocks.dox163
-rw-r--r--docs/doxygen/other/stream_tags.dox245
-rw-r--r--docs/doxygen/other/tagged_stream_blocks.dox320
-rw-r--r--docs/doxygen/other/thread_affinity.dox132
-rw-r--r--docs/doxygen/other/usage.dox45
-rw-r--r--docs/doxygen/other/volk_guide.dox160
17 files changed, 20 insertions, 3516 deletions
diff --git a/docs/doxygen/other/logger.dox b/docs/doxygen/other/logger.dox
deleted file mode 100644
index 00387768c0..0000000000
--- a/docs/doxygen/other/logger.dox
+++ /dev/null
@@ -1,247 +0,0 @@
-# Copyright (C) 2017 Free Software Foundation, Inc.
-#
-# Permission is granted to copy, distribute and/or modify this document
-# under the terms of the GNU Free Documentation License, Version 1.3
-# or any later version published by the Free Software Foundation;
-# with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.
-# A copy of the license is included in the section entitled "GNU
-# Free Documentation License".
-
-/*! \page page_logger Logging
-
-\section logging Logging
-
-GNU Radio has a logging interface to enable various levels of logging
-information to be printed to the console or a file. The logger derives
-from log4cpp (http://log4cpp.sourceforge.net/) which is readily
-available in most Linux distributions. This is an optional dependency
-and GNU Radio will work without it.
-
-Logging is useful for blocks to print out certain amounts of data at
-different levels. These levels are:
-
-<pre>
- DEBUG < INFO < WARN < TRACE < ERROR < ALERT < CRIT < FATAL < EMERG
-</pre>
-
-
-The order here determines the level of output. These levels are
-hierarchical in that specifying any level also includes any level
-above it. For example, when using the INFO level, all INFO and
-higher messages are logged and DEBUG is ignored. A level NOTSET is provided
-to disable a logger.
-
-\subsection configfile Logging Configuration
-
-The logging configuration can be found in the gnuradio-runtime.conf file
-under the [LOG] section. This allows us fairly complete control over
-the logging facilities. The main configuration functions are to set up
-the level of the loggers and set the default output behavior of the
-loggers.
-
-There are two default loggers that all gr_block's have access to:
-d_logger and d_debug_logger. The first is a standard logger meant to
-output simple information about the block while it is running. The
-debug logger is meant for debugging purposes and is added to make it
-convenient to use a secondary logger that outputs to a different
-stream or file.
-
-The four main configure options are:
-
-<pre>
- log_level = debug
- debug_level = debug
- log_file = stdout
- debug_file = stderr
-</pre>
-
-This establishes the two loggers as having access to all levels of
-logging events (DEBUG through EMERG). They are also configured not to
-use files but instead output to the console. The standard logger will
-output to standard out while the debug logger outputs to standard
-error.
-
-Changing these last two lines to another value will create files that
-are used to store the log messages. All messages are appended to the
-file.
-
-When using either standard error or standard out, the messages for the
-two different loggers will look like:
-
-<pre>
- gr::log :\<level\>: \<block alias\> - \<message\>
- gr::debug :\<level\>: \<block alias\> - \<message\>
-</pre>
-
-When using a file, the only difference in the format is that the
-message prefix of "gr::log" or "gr::debug" is not used. Instead, the
-time in milliseconds from the start of the program is inserted.
-
-Remember that a local "~/.gnuradio/config.conf" file can be used to
-override any parameter in the global file (see \ref prefs for more
-details).
-
-To use these loggers inside of a GNU Radio block, we use the protected
-data members of d_logger and d_debug_logger of gr_block and pass them
-to our pre-defined macros:
-
-\code
- GR_LOG_<level>(<logger>, "<Message to print>");
-\endcode
-
-Where \<level\> is one of the levels as mentioned above, \<logger\> is
-either d_logger or d_debug_logger, and \<Message to print\> is the
-message we want to output. If we wanted to output an INFO level
-message to the standard logger and a WARN level message to the debug
-logger, it would look like this:
-
-\code
- GR_LOG_INFO(d_logger, "Some info about the block");
- GR_LOG_WARN(d_debug_logger, "Some warning about the block");
-\endcode
-
-When this is printed to wherever you are directing the output of the
-logger, it will look like:
-
-<pre>
- gr::log :INFO: <block's alias> - Some info about the block
- gr::debug :WARN: <block's alias> - Some warning about the block
-</pre>
-
-This provides us information about where the message came from, the
-level of the message, and the block that generated the message. We use
-the concept of the block's alias which by default (i.e., unless
-otherwise set by the user) includes the name of the block and a unique
-ID to distinguish it from other blocks of the same type.
-
-The various logging macros are defined in gr_logger.h. Here are some
-simple examples of using them:
-
-\code
- GR_LOG_DEBUG(LOG, "DEBUG message");
- GR_LOG_INFO(LOG, "INFO message");
- GR_LOG_NOTICE(LOG, "NOTICE message");
- GR_LOG_WARN(LOG, "WARNING message");
- GR_LOG_ERROR(LOG, "ERROR message");
- GR_LOG_CRIT(LOG, "CRIT message");
- GR_LOG_ALERT(LOG, "ALERT message");
- GR_LOG_FATAL(LOG, "FATAL message");
- GR_LOG_EMERG(LOG, "EMERG message");
-\endcode
-
-If the logger is not enabled, then these macros become nops and do
-nothing (and d_logger and d_debug_logger are NULL pointers). If
-logging is enabled but the log4cpp library is not found, then TRACE,
-INFO, and NOTICE levels go to stdout and the rest to stderr.
-
-
-\subsection adv_config Advanced Configuration Options
-
-If not using the simplified settings discussed above, where we can
-direct the logger messages to either a file or one of the standard
-outputs, we must use a more complicated configuration file. We do this
-by specifying the "log_config" option in the [LOG] section. The
-log4cpp documentation will provide more information on how
-configuration works and looks. Mostly, a default configuration script
-provided with GNU Radio can be used. After installation, the default
-configuration script is located at:
-
-<pre>
- $prefix/etc/gnuradio/gr_log_default.conf
-</pre>
-
-For the following examples, we will assume that our local
-"~/.gnuradio/config.conf" looks like this:
-
-\code
-[LOG]
-log_config = /opt/gr/etc/gnuadio/gr_log_default.conf
-log_level = debug
-debug_level = Off
-\endcode
-
-Inside of the default configuration file, we define the parameters
-for the two logger's, the standard logger the separate debug logger.
-
-If the levels of the two loggers are specified in our configuration
-file, as in the above example, these levels override any levels
-specified in the XML file. Here, we have turned on the standard logger
-(d_logger) to all levels and turned off the debug logger
-(d_debug_logger). So even if the debug logger is used in the code, it
-will not actually output any information. Conversely, any level of
-output passed to the standard logger will output because we have
-turned this value to the lowest level "debug."
-
-If both an XML configuration file is set and the "log_file" or
-"debug_file" options are set at the same time, both systems are
-actually used. So you can configure file access and the pattern
-through the XML file while also still outputting to stdout or stderr.
-
-
-\section advlog Advanced Usage
-
-The description above for using the logging facilities is specific to
-GNU Radio blocks. We have put the code necessary to access the
-debugger into the gr_block parent class to simplify access and make
-sure all blocks have the ability to quickly and easily use the logger.
-
-For non gr_block-based code, we have to get some information about the
-logger in order to properly access it. Each logger only exists once as
-a singleton in the system, but we need to get a pointer to the right
-logger and then set it up for our local use. The following code
-snippet shows how to do this to get access to the standard logger,
-which has a root of "gr_log." (access to the debug logger is similar
-except we would use "gr_log_debug." in the GR_LOG_GETLOGGER call):
-
-\code
- prefs *p = prefs::singleton();
- std::string log_file = p->get_string("LOG", "log_config", "");
- std::string log_level = p->get_string("LOG", "log_level", "off");
- GR_CONFIG_LOGGER(log_file);
- GR_LOG_GETLOGGER(LOG, "gr_log." + "my_logger_name");
- GR_LOG_SET_LEVEL(LOG, log_level);
-\endcode
-
-This creates a pointer called LOG (which is instantiated as a
-log4cpp:LoggerPtr in the macro) that we can now use locally as the
-input to our logging macros like 'GR_LOG_INFO(LOG, "message")'.
-
-\subsection using_logging Using Logging in Out of Tree Modules
-
-In order to use the logging interface in an out of tree module based on a
-gr_modtool template module, several CMake modifications are required.
-Without these changes, logging will be disabled.
-
-GrMiscUtils.cmake module must be included in the OOT module top level
-CMakeLists.Texts file, and the GR_LOGGING() function provided by GrMiscUtils
-must be called from the same top level CMakeLists.txt file. This will
-set the appropriate build environment and during that process, attempt
-to find the log4cpp package using the FindLog4Cpp.cmake module.
-This module is not included in the module by gr_modtool, but is part of
-the GNU Radio codebase and can be copied directly into the cmake/Modules/
-directory of the OOT module.
-
-Once these CMake changes are made, the GR logging interface will function
-as documented on this page.
-
-\section logPy Logging from Python
-
-The logging capability has been brought out python via swig. The configuration
-of the logger can be manipulated via the following calls:
-\code
- from gnuradio import gr
- gr.logger_config(filename,watch_period) # Configures the logger with conf file filename
- names = gr.logger_get_names() # Returns the names of all loggers
- gr.logger_reset_config() # Resets logger config by removing all appenders
-\endcode
-
-Once the logger is configured you can manipulate a logger via a wrapper class gr.logger().
-You can isntantiate this by the following. (Reference logger.h for list of methods)
-\code
- from gnuradio import gr
- log=gr.logger("nameOfLogger")
- log.debug("Log a debug message")
- log.set_level("INFO");
-
-\endcode
-*/
diff --git a/docs/doxygen/other/metadata.dox b/docs/doxygen/other/metadata.dox
deleted file mode 100644
index b58d2a6aee..0000000000
--- a/docs/doxygen/other/metadata.dox
+++ /dev/null
@@ -1,350 +0,0 @@
-# Copyright (C) 2017 Free Software Foundation, Inc.
-#
-# Permission is granted to copy, distribute and/or modify this document
-# under the terms of the GNU Free Documentation License, Version 1.3
-# or any later version published by the Free Software Foundation;
-# with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.
-# A copy of the license is included in the section entitled "GNU
-# Free Documentation License".
-
-/*! \page page_metadata Metadata Information
-
-\section metadata_introduction Introduction
-
-Metadata files have extra information in the form of headers that
-carry metadata about the samples in the file. Raw, binary files carry
-no extra information and must be handled delicately. Any changes in
-the system state such as a receiver's sample rate or frequency are
-not conveyed with the data in the file itself. Headers solve this problem.
-
-We write metadata files using gr::blocks::file_meta_sink and read metadata
-files using gr::blocks::file_meta_source.
-
-Metadata files have headers that carry information about a segment of
-data within the file. The header structure is described in detail in
-the next section. A metadata file always starts with a header that
-describes the basic structure of the data. It contains information
-about the item size, data type, if it's complex, the sample rate of
-the segment, the time stamp of the first sample of the segment, and
-information regarding the header size and segment size.
-
-The first static portion of the header file contains the following
-information.
-
-- version: (char) version number (usually set to METADATA_VERSION)
-- rx_rate: (double) Stream's sample rate
-- rx_time: (pmt::pmt_t pair - (uint64_t, double)) Time stamp (format from UHD)
-- size: (int) item size in bytes - reflects vector length if any
-- type: (int) data type (enum below)
-- cplx: (bool) true if data is complex
-- strt: (uint64_t) start of data relative to current header
-- bytes: (uint64_t) size of following data segment in bytes
-
-An optional extra section of the header stores information in any
-received tags. The two main tags associated with headers are:
-
-- rx_rate: the sample rate of the stream.
-- rx_time: the time stamp of the first item in the segment.
-
-These tags were inspired by the UHD tag format.
-
-The header gives enough information to process and handle the
-data. One cautionary note, though, is that the data type should never
-change within a file. There should be very little need for this, because
-GNU Radio blocks can only set the data type of their
-IO signatures in the constructor, so changes in the data type
-afterward will not be recognized.
-
-We also have an extra header segment that is optional. This can be
-loaded up at the beginning by the user specifying some extra metadata
-that should be transmitted along with the data. It also grows whenever
-it sees a stream tag, so the dictionary will contain any key:value
-pairs out of tags from the flowgraph.
-
-
-\subsection metadata_types Types of Metadata Files
-
-GNU Radio currently supports two types of metadata files:
-
-- inline: headers are inline with the data in the same file.
-- detached: headers are in a separate header file from the data.
-
-The inline method is the standard version. When a detached header is
-used, the headers are simply inserted back-to-back in the detached
-header file. The dat file, then, is the standard raw binary format
-with no interruptions in the data.
-
-
-\subsection metadata_updating Updating Headers
-
-While there is always a header that starts a metadata file, they are
-updated throughout as well. There are two events that trigger a new
-header. We define a segment as the unit of data associated with the
-last header.
-
-The first event that will trigger a new header is when enough samples
-have been written for the given segment. This number is defined as the
-maximum segment size and is a parameter we pass to the
-file_meta_sink. It defaults to 1 million items (items, not
-bytes). When that number of items is reached, a new header is
-generated and a new segment is started. This makes it easier for us to
-manipulate the data later and helps protect against catastrophic data
-loss.
-
-The second event to trigger a new segment is if a new tag is
-observed. If the tag is a standard tag in the header, the header value
-is updated, the header and current extras are written to file, and the
-segment begins again. If a tag from the extras is seen, the value
-associated with that tag is updated; and if a new tag is seen, a new
-key:value pair are added to the extras dictionary.
-
-When new tags are seen, we generate a new segment so that we make sure
-that all samples in that segment are defined by the header. If the
-sample rate changes, we create a new segment where all of the new
-samples are at that new rate. Also, in the case of UHD devices, if a
-segment loss is observed, it will generate a new timestamp as a tag of
-'rx_time'. We create a new file segment that reflects this change to
-keep the sample times exact.
-
-
-\subsection metadata_implementation Implementation
-
-Metadata files are created using gr::blocks::file_meta_sink. The
-default behavior is to create a single file with inline headers as
-metadata. An option can be set to switch to detached header mode.
-
-Metadata files are read into a flowgraph using
-gr::blocks::file_meta_source. This source reads a metadata file,
-inline by default with a settable option to use detached headers. The
-data from the segments is converted into a standard streaming
-output. The 'rx_rate' and 'rx_time' and all key:value pairs in the
-extra header are converted into tags and added to the stream tags
-interface.
-
-
-\section metadata_structure Structure
-
-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::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
-is extra data to be extracted as a separate serialized dictionary.
-
-To work with the PMTs for creating and extracting header information,
-we use PMT operators. For example, we create a simplified version of
-the header in C++ like this:
-
-\code
- const char METADATA_VERSION = 0x0;
- 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::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
-the data type, see PMT functions in pmt.h, such as
-pmt::from_uint64 or pmt::from_double.
-
-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.
-
-The header is always METADATA_HEADER_SIZE bytes long and a metadata
-file always starts with a header. So to extract the header from a
-file, we need to read in this many bytes from the beginning of the
-file and deserialize it. An important note about this is that the
-deserialize function must operate on a std::string. The serialized
-format of a dictionary contains null characters, so normal C character
-arrays (e.g., 'char *s') get confused.
-
-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::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
-
-This example first deserializes the string into a PMT dictionary
-again. This will throw an error if the string is malformed and cannot
-be deserialized correctly. We then want to get access to the item with
-key 'strt'. As the next subsection will show, this value indicates at
-which byte the data segment starts. We first check to make sure that
-this key exists in the dictionary. If not, our header does not contain
-the correct information and we might want to handle this as an error.
-
-Assuming the header is properly formatted, we then get the particular
-item referenced by the key 'strt'. This is a uint64_t, so we use the
-PMT function to extract and convert this value properly. We now know
-if we have an extra header in the file by looking at the difference
-between 'seg_start' and the static header size,
-METADATA_HEADER_SIZE. If the 'extra_len' is greater than 0, we know we
-have an extra header that we can process. Moreover, this also tells us
-the size of the serialized PMT dictionary in bytes, so we can easily
-read this many bytes from the file. We can then deserialize and parse
-this header just like the first.
-
-
-\subsection metadata_header Header Information
-
-The header is a PMT dictionary with a known structure. This structure
-may change, but we version the headers, so all headers of version X
-must be the same length and structure. As of now, we only have version
-0 headers, which look like the following:
-
-- version: (char) version number (usually set to METADATA_VERSION)
-- rx_rate: (double) Stream's sample rate
-- rx_time: (pmt::pmt_t pair - (uint64_t, double)) Time stamp (format from UHD)
-- size: (int) item size in bytes - reflects vector length if any.
-- type: (int) data type (enum below)
-- cplx: (bool) true if data is complex
-- strt: (uint64_t) start of data relative to current header
-- bytes: (uint64_t) size of following data segment in bytes
-
-The data types are indicated by an integer value from the following
-enumeration type:
-
-\code
-enum gr_file_types {
- GR_FILE_BYTE=0,
- GR_FILE_CHAR=0,
- GR_FILE_SHORT=1,
- GR_FILE_INT,
- GR_FILE_LONG,
- GR_FILE_LONG_LONG,
- GR_FILE_FLOAT,
- GR_FILE_DOUBLE,
-};
-\endcode
-
-\subsection metadata_extras Extras Information
-
-The extras section is an optional segment of the header. If 'strt' ==
-METADATA_HEADER_SIZE, then there is no extras. Otherwise, it is simply
-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::dict_add function to insert
-our hand-made metadata. This can be useful to add our own markers and
-information.
-
-The main role of the extras header, though, is as a container to hold
-any stream tags. When a stream tag is observed coming in, the tag's
-key and value are added to the dictionary. Like a standard dictionary,
-any time a key already exists, the value will be updated. If the key
-does not exist, a new entry is created and the new key:value pair are
-added together. So any new tags that the file metadata sink sees will
-add to the dictionary. It is therefore important to always check the
-'strt' value of the header to see if the length of the extras
-dictionary has changed at all.
-
-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::print on any PMT object to print it to
-screen. Before converting from a PMT to its natural data type, it is
-necessary to know the data type.
-
-
-\section metadata_utilities Utilities
-
-GNU Radio comes with a couple of utilities to help in debugging and
-manipulating metadata files. There is a general parser in Python that
-will convert the PMT header and extra header into Python
-dictionaries. This utility is:
-
-- gr-blocks/python/parse_file_metadata.py
-
-This program is installed into the Python directory under the
-'gnuradio' module, so it can be accessed with:
-
-\code
-from gnuradio.blocks import parse_file_metadata
-\endcode
-
-It defines HEADER_LENGTH as the static length of the metadata header
-size. It also has dictionaries that can be used to convert from the
-file type to a string (ftype_to_string) and one to convert from the
-file type to the size of the data type in bytes (ftype_to_size).
-
-The 'parse_header' takes in a PMT dictionary, parses it, and returns a
-Python dictionary. An optional 'VERBOSE' bool can be set to print the
-information to standard out.
-
-The 'parse_extra_dict' is similar in that it converts from a PMT
-dictionary to a Python dictionary. The values are kept in their PMT
-format since we do not necessarily know the native data type.
-
-A program called 'gr_read_file_metadata' is installed into the path
-and can be used to read out all header information from a metadata
-file. This program is just called with the file name as the first
-command-line argument. An option '-D' will handle detached header
-files where the file of headers is expected to be the file name of the
-data with '.hdr' appended to it.
-
-
-\section metadata_examples Examples
-
-Examples are located in:
-
-- gr-blocks/examples/metadata
-
-Currently, there are a few GRC example programs.
-
-- file_metadata_sink: create a metadata file from UHD samples.
-- file_metadata_source: read the metadata file as input to a simple graph.
-- file_metadata_vector_sink: create a metadata file from UHD samples.
-- file_metadata_vector_source: read the metadata file as input to a simple graph.
-
-The file sink example can be switched to use a signal source instead
-of a UHD source, but no extra tagged data is used in this mode.
-
-The file source example pushes the data stream to a new raw file while
-a tag debugger block prints out any tags observed in the metadata
-file. A QT GUI time sink is used to look at the signal as well.
-
-The versions with 'vector' in the name are similar except they use
-vectors of data.
-
-The following shows a simple way of creating extra metadata for a
-metadata file. This example is just showing how we can insert a date
-into the metadata to keep track of it later. The date in this case is
-encoded as a vector of uint16 with [day, month, year].
-
-\code
- import pmt
- from gnuradio import blocks
-
- key = pmt.intern("date")
- val = pmt.init_u16vector(3, [13,12,2012])
-
- 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,
- blocks.GR_FILE_FLOAT, True,
- 1000000, extra_str, False)
-
-\endcode
-
-*/
diff --git a/docs/doxygen/other/msg_passing.dox b/docs/doxygen/other/msg_passing.dox
deleted file mode 100644
index 14de7bae4c..0000000000
--- a/docs/doxygen/other/msg_passing.dox
+++ /dev/null
@@ -1,381 +0,0 @@
-# Copyright (C) 2017 Free Software Foundation, Inc.
-#
-# Permission is granted to copy, distribute and/or modify this document
-# under the terms of the GNU Free Documentation License, Version 1.3
-# or any later version published by the Free Software Foundation;
-# with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.
-# A copy of the license is included in the section entitled "GNU
-# Free Documentation License".
-
-/*! \page page_msg_passing Message Passing
-
-\section msg_passing_introduction Introduction
-
-GNU Radio was originally a streaming system with no other mechanism to
-pass data between blocks. Streams of data are a model that work well
-for samples, bits, etc., but are not really the right mechanism for
-control data, metadata, or packet structures (at least at
-some point in the processing chain).
-
-We solved part of this problem by introducing the tag stream (see \ref
-page_stream_tags). This is a parallel stream to the data
-streaming. The difference is that tags are designed to hold metadata
-and control information. Tags are specifically associated with a
-particular sample in the data stream and flow downstream alongside the
-data. This model allows other blocks to identify that an event or
-action has occurred or should occur on a particular item. The major
-limitation is that the tag stream is really only accessible inside a
-work function and only flows in one direction. Its benefit is that it
-is isosynchronous with the data.
-
-We want a more general message passing system for a couple of
-reasons. The first is to allow blocks downstream to communicate back
-to blocks upstream. The second is to allow an easier way for us to
-communicate back and forth between external applications and GNU
-Radio. GNU Radio's message passing interface handles these cases, although
-it does so on an asynchronous basis.
-
-The message passing interface heavily relies on Polymorphic Types
-(PMTs) in GNU Radio. For further information about these data
-structures, see the page \ref page_pmt.
-
-\section msg_passing_api Message Passing API
-
-The message passing interface is designed into the gr::basic_block,
-which is the parent class for all blocks in GNU Radio. Each block has
-a set of message queues to hold incoming messages and can post
-messages to the message queues of other blocks. The blocks also
-distinguish between input and output ports.
-
-A block has to declare its input and output message ports in its
-constructor. The message ports are described by a name, which is in
-practice a PMT symbol (<em>i.e.</em>, an interned string). The API calls
-to register a new port are:
-
-\code
- void message_port_register_in(pmt::pmt_t port_id)
- void message_port_register_out(pmt::pmt_t port_id)
-\endcode
-
-In Python:
-
-\code
- self.message_port_register_in(pmt.intern("port name"))
- self.message_port_register_out(pmt.intern("port name"))
-\endcode
-
-The ports are now identifiable by that port name. Other blocks who may
-want to post or receive messages on a port must subscribe to it. When
-a block has a message to send, they are published on a particular
-port using the following API:
-
-\code
- void message_port_pub(pmt::pmt_t port_id, pmt::pmt_t msg);
-\endcode
-
-In Python:
-
-\code
- self.message_port_pub(pmt.intern("port name"), <pmt message>)
-\endcode
-
-Subscribing is usually done in the form of connecting message ports
-as part of the flowgraph, as discussed later. Internally, when message
-ports are connected, the gr::basic_block::message_port_sub method is
-called.
-
-Any block that has a subscription to another block's output message
-port will receive the message when it is published. Internally, when a
-block publishes a message, it simply iterates through all blocks that
-have subscribed and uses the gr::basic_block::_post method to send the
-message to that block's message queue.
-
-
-\subsection msg_passing_msg_handler Message Handler Functions
-
-A subscriber block must declare a message handler function to process
-the messages that are posted to it. After using the
-gr::basic_block::message_port_register_in to declare a subscriber port, we
-must then bind this port to the message handler. For this, we use
-Boost's 'bind' function:
-
-\code
- set_msg_handler(pmt::pmt_t port_id,
- boost::bind(&block_class::message_handler_function, this, _1));
-\endcode
-
-In Python:
-
-\code
- self.set_msg_handler(pmt.intern("port name"), <msg handler function>)
-\endcode
-
-When a new message is pushed onto a port's message queue,
-it is this function that is used to process the message.
-The 'port_id' is the same PMT as used when registering the input
-port. The 'block_class::message_handler_function' is the member
-function of the class designated to handle messages to this port. The
-'this' and '_1' are standard ways of using the Boost bind function to
-pass the 'this' pointer as the first argument to the class (standard
-OOP practice) and the _1 is an indicator that the function expects 1
-additional argument. The prototype for all message handling functions
-is:
-
-\code
- void block_class::message_handler_function(pmt::pmt_t msg);
-\endcode
-
-In Python the equivalent function would be:
-
-\code
- def handle_msg(self, msg):
-\endcode
-
-We give examples of using this below.
-
-
-\subsection msg_passing_fg_connect Connecting Messages through the Flowgraph
-
-From the flowgraph level, we have instrumented a gr::hier_block2::msg_connect
-method to make it easy to subscribe blocks to other blocks'
-messages. Assume that the block \b src has an output message port named
-\a pdus and the block \b dbg has an input port named \a print. The message
-connection in the flowgraph (in Python) looks like the following:
-
-\code
- self.tb.msg_connect(src, "pdus", dbg, "print")
-\endcode
-
-All messages published by the \b src block on port \a pdus will be
-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::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:
-
-\code
- pmt::pmt_t message_ports_in();
- pmt::pmt_t message_ports_out();
-\endcode
-
-The return value for these are a PMT vector filled with PMT symbols,
-so PMT operators must be used to manipulate them.
-
-Each block has internal methods to handle posting and receiving of
-messages. The gr::basic_block::_post method takes in a message and
-places it into its queue. The publishing model uses the
-gr::basic_block::_post method of the blocks as the way to access the
-message queue. So the message queue of the right name will have a new
-message. Posting messages also has the benefit of waking up the
-block's thread if it is in a wait state. So if idle, as soon as a
-message is posted, it will wake up and call the message handler.
-
-
-\section msg_passing_posting Posting from External Sources
-
-An important feature of the message passing architecture
-is how it can be used to take in messages from an external source. We
-can call a block's gr::basic_block::_post method directly and pass it a
-message. So any block with an input message port can receive messages
-from the outside in this way.
-
-The following example uses a gr::blocks::pdu_to_tagged_stream block
-as the source block to a flowgraph. Its purpose is to wait for
-messages as PDUs posted to it and convert them to a normal stream. The
-payload will be sent on as a normal stream while the meta data will be
-decoded into tags and sent on the tagged stream.
-
-So if we have created a \b src block as a PDU to stream, it has a \a
-pdus input port, which is how we will inject PDU messages into the
-flowgraph. These PDUs could come from another block or flowgraph, but
-here, we will create and insert them by hand.
-
-\code
- port = pmt.intern("pdus")
- msg = pmt.cons(pmt.PMT_NIL, pmt.make_u8vector(16, 0xFF))
- src.to_basic_block()._post(port, msg)
-\endcode
-
-The PDU's metadata section is empty, hence the pmt::PMT_NIL
-object. The payload is now just a simple vector of 16 bytes of all
-1's. To post the message, we have to access the block's gr::basic_block
-class, which we do using the gr::basic_block::to_basic_block method and
-then call the gr::basic_block::_post method to pass the PDU to the
-right port.
-
-All of these mechanisms are explored and tested in the QA code of the
-file qa_pdu.py.
-
-There are some examples of using the message passing infrastructure
-through GRC in gr-blocks/examples/msg_passing.
-
-
-\section msg_passing_commands Using messages as commands
-
-One important use of messages is to send commands to blocks. Examples for this include:
-
-- gr::qtgui::freq_sink_c: The scaling of the frequency axis can be changed by messages
-- gr::uhd::usrp_source and gr::uhd::usrp_sink: Many transceiver-related settings can
- be manipulated through command messages, such as frequency, gain and LO offset
-- gr::digital::header_payload_demux, which receives an acknowledgement from a header parser
- block on how many payload items there are to process
-
-There is no special PMT type to encode commands, however, it is strongly recommended
-to use one of the following formats:
-
-- pmt::cons(KEY, VALUE): This format is useful for commands that take a single value.
- Think of KEY and VALUE as the argument name and value, respectively. For the case of
- the QT GUI Frequency Sink, KEY would be "freq" and VALUE would be the new center frequency
- in Hz.
-- pmt::dict((KEY1: VALUE1), (KEY2: VALUE2), ...): This is basically the same as the
- previous format, but you can provide multiple key/value pairs. This is particularly
- useful when a single command takes multiple arguments which can't be broken into
- multiple command messages (e.g., the USRP blocks might have both a timestamp and a
- center frequency in a command message, which are closely associated).
-
-In both cases, all KEYs should be pmt::symbols (i.e. strings). VALUEs can be
-whatever the block requires.
-
-It might be tempting to deviate from this format, e.g. the QT Frequency sink could
-simply take a float value as a command message, and it would still work fine.
-However, there are some very good reasons to stick to this format:
-
-- Interoperability: The more people use the standard format, the more likely it
- is that blocks from different sources can work together
-- Inspectability: A message debug block will display more useful information about
- a message if it's containing both a value and a key
-- Intuition: This format is pretty versatile and unlikely to create situations
- where it is not sufficient (especially considering that values are PMTs themselves).
- As a counterexample, using positional arguments (something like "the first argument
- is the frequency, the second the gain") is easily forgotten, or changed in one place
- and not another, etc.
-
-
-\section msg_passing_examples Code Examples
-
-The following is snippets of code from blocks currently in GNU Radio
-that take advantage of message passing. We will be using
-gr::blocks::message_debug and gr::blocks::tagged_stream_to_pdu below
-to show setting up both input and output message passing capabilities.
-
-The gr::blocks::message_debug block is used for debugging the message
-passing system. It describes three input message ports: \a print, \a
-store, and \a pdu_print. The \a print port simply prints out all
-messages to standard out while the \a store port keeps a list of all
-messages posted to it. The \a pdu_print port specially formats PDU
-messages for printing to standard out. The \a store port works in
-conjunction with a gr::blocks::message_debug::get_message(int i) call
-that allows us to retrieve message \p i afterward.
-
-The constructor of this block looks like this:
-
-\code
-{
- message_port_register_in(pmt::mp("print"));
- set_msg_handler(pmt::mp("print"),
- boost::bind(&message_debug_impl::print, this, _1));
-
- message_port_register_in(pmt::mp("store"));
- set_msg_handler(pmt::mp("store"),
- boost::bind(&message_debug_impl::store, this, _1));
-
- message_port_register_in(pmt::mp("print_pdu"));
- set_msg_handler(pmt::mp("print_pdu"),
- boost::bind(&message_debug_impl::print_pdu, this, _1));
-}
-\endcode
-
-The three message input ports are registered by their respective
-names. We then use the gr::basic_block::set_msg_handler function to
-identify this particular port name with a callback function. The
-Boost \a bind function (<a target="_blank"
-href="http://www.boost.org/doc/libs/1_52_0/libs/bind/bind.html">Boost::bind</a>)
-here binds the callback to a function of this block's class. So now
-the functions in the block's private implementation class,
-gr::blocks::message_debug_impl::print,
-gr::blocks::message_debug_impl::store, and
-gr::blocks::message_debug_impl::print_pdu, are assigned to handle
-messages passed to them. Below is the \a print function for reference.
-
-\code
-void
-message_debug_impl::print(pmt::pmt_t msg)
-{
- std::cout << "***** MESSAGE DEBUG PRINT ********\n";
- pmt::print(msg);
- std::cout << "**********************************\n";
-}
-\endcode
-
-The function simply takes in the PMT message and prints it. The method
-pmt::print is a function in the PMT library to print the
-PMT in a friendly and (mostly) pretty manner.
-
-The gr::blocks::tagged_stream_to_pdu block only defines a single
-output message port. In this case, its constructor contains the line:
-
-\code
-{
- message_port_register_out(pdu_port_id);
-}
-\endcode
-
-So we are only creating a single output port where \a pdu_port_id
-is defined in the file pdu.h as \a pdus.
-
-This block's purpose is to take in a stream of samples along with
-stream tags and construct a predefined PDU message from it. In GNU
-Radio, we define a PDU as a PMT pair of (metadata, data). The metadata
-describes the samples found in the data portion of the
-pair. Specifically, the metadata can contain the length of the data
-segment and any other information (sample rate, etc.). The PMT vectors
-know their own length, so the length value is not actually necessary
-unless useful for purposes down the line. The metadata is a PMT
-dictionary while the data segment is a PMT uniform vector of either
-bytes, floats, or complex values.
-
-In the end, when a PDU message is ready, the block calls its
-gr::blocks::tagged_stream_to_pdu_impl::send_message function that is
-shown below.
-
-\code
-void
-tagged_stream_to_pdu_impl::send_message()
-{
- if(pmt::length(d_pdu_vector) != d_pdu_length) {
- throw std::runtime_error("msg length not correct");
- }
-
- pmt::pmt_t msg = pmt::cons(d_pdu_meta,
- d_pdu_vector);
- message_port_pub(pdu_port_id, msg);
-
- d_pdu_meta = pmt::PMT_NIL;
- d_pdu_vector = pmt::PMT_NIL;
- d_pdu_length = 0;
- d_pdu_remain = 0;
- d_inpdu = false;
-}
-\endcode
-
-This function does a bit of checking to make sure the PDU is OK as
-well as some cleanup in the end. But it is the line where the message
-is published that is important to this discussion. Here, the block
-posts the PDU message to any subscribers by calling
-gr::basic_block::message_port_pub publishing method.
-
-There is similarly a gr::blocks::pdu_to_tagged_stream block that essentially
-does the opposite. It acts as a source to a flowgraph and waits for
-PDU messages to be posted to it on its input port \a pdus. It extracts
-the metadata and data and processes them. The metadata dictionary is
-split up into key:value pairs and stream tags are created out of
-them. The data is then converted into an output stream of items and
-passed along. The next section describes how PDUs can be passed into a
-flowgraph using the gr::blocks::pdu_to_tagged_stream block.
-
-For a Python block example, see \ref pyblocks_msgs.
-
-*/
diff --git a/docs/doxygen/other/ofdm.dox b/docs/doxygen/other/ofdm.dox
deleted file mode 100644
index 77d80a7441..0000000000
--- a/docs/doxygen/other/ofdm.dox
+++ /dev/null
@@ -1,152 +0,0 @@
-# Copyright (C) 2017 Free Software Foundation, Inc.
-#
-# Permission is granted to copy, distribute and/or modify this document
-# under the terms of the GNU Free Documentation License, Version 1.3
-# or any later version published by the Free Software Foundation;
-# with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.
-# A copy of the license is included in the section entitled "GNU
-# Free Documentation License".
-
-/*! \page page_ofdm OFDM
-
-\section ofdm_introduction Introduction
-
-GNU Radio provides some blocks to transmit and receive OFDM-modulated signals.
-In the following, we assume the reader is familiar with OFDM and how it works,
-for an introduction to OFDM refer to standard textbooks on digital communication.
-
-The blocks are designed in a very generic fashion. As a developer, this means that
-often, a desired functionality can be achieved by correct parametrization of the
-available blocks, but in some cases, custom blocks have to be included. The design
-of the OFDM components is such that adding own functionality is possible with
-very little friction.
-
-\ref page_packet_data has an example of how to use OFDM in a packet-based
-receiver.
-
-\section ofdm_conventions Conventions and Notations
-
-\subsection ofdm_fftshift FFT Shifting
-
-In all cases where OFDM symbols are passed between blocks, the default behaviour
-is to FFT-Shift these symbols, i.e. that the DC carrier is in the middle (to be
-precise, it is on carrier \f$\lfloor N/2 \rfloor\f$ where N is the FFT length and
-carrier indexing starts at 0).
-
-The reason for this convention is that some blocks require FFT-shifted ordering
-of the symbols to function (such as gr::digital::ofdm_chanest_vcvc), and for
-consistency's sake, this was chosen as a default for all blocks that pass OFDM
-symbols. Also, when viewing OFDM symbols, FFT-shifted symbols are in their
-natural order, i.e. as they appear in the pass band.
-
-\subsection ofdm_indexing Carrier Indexing
-
-Carriers are always index starting at the DC carrier, which has the index 0
-(you usually don't want to occupy this carrier). The carriers right of the
-DC carrier (the ones at higher frequencies) are indexed with 1 through N/2-1
-(N being the FFT length again).
-
-The carriers left of the DC carrier (with lower frequencies) can be indexed
--N/2 through -1 or N/2 through N-1. Carrier indices N-1 and -1 are thus
-equivalent. The advantage of using negative carrier indices is that the
-FFT length can be changed without changing the carrier indexing.
-
-\subsection ofdm_carrieralloc Carrier and Symbol Allocation
-
-Many blocks require knowledge of which carriers are allocated, and whether they
-carry data or pilot symbols. GNU Radio blocks uses three objects for this, typically
-called \p occupied_carriers (for the data symbols), \p pilot_carriers and
-\p pilot_symbols (for the pilot symbols).
-
-Every one of these objects is a vector of vectors. \p occupied_carriers and
-\p pilot_carriers identify the position within a frame where data and pilot
-symbols are stored, respectively.
-
-\p occupied_carriers[0] identifies which carriers are occupied on the first
-OFDM symbol, \p occupied_carriers[1] does the same on the second OFDM symbol etc.
-
-Here's an example:
-\code
- occupied_carriers = ((-2, -1, 1, 3), (-3, -1, 1, 2))
- pilot_carriers = ((-3, 2), (-2, 3))
-\endcode
-Every OFDM symbol carries 4 data symbols. On the first OFDM symbol, they are on carriers -2, -1, 1 and 3.
-Carriers -3 and 2 are not used, so they are where the pilot symbols can be placed.
-On the second OFDM symbol, the occupied carriers are -3, -1, 1 and 2. The pilot
-symbols must thus be placed elsewhere, and are put on carriers -2 and 3.
-
-If there are more symbols in the OFDM frame than the length of \p occupied_carriers
-or \p pilot_carriers, they wrap around (in this example, the third OFDM symbol
-uses the allocation in \p occupied_carriers[0]).
-
-But how are the pilot symbols set? This is a valid parametrization:
-\code
- pilot_symbols = ((-1, 1j), (1, -1j), (-1, 1j), (-1j, 1))
-\endcode
-
-The position of these symbols are thos in \p pilot_carriers. So on the first OFDM
-symbol, carrier -3 will transmit a -1, and carrier 2 will transmit a 1j.
-Note that \p pilot_symbols is longer than \p pilot_carriers in this example--
-this is valid, the symbols in \p pilot_symbols[2] will be mapped according
-to \p pilot_carriers[0].
-
-\section ofdm_detectsync Detection and Synchronisation
-
-Before anything happens, an OFDM frame must be detected, the beginning of OFDM
-symbols must be identified, and frequency offset must be estimated.
-
-\section ofdm_tx Transmitting
-
-\image html ofdm_tx_core.png "Core elements of an OFDM transmitter"
-
-This image shows a very simple example of a transmitter. It is assumed that the
-input is a stream of complex scalars with a length tag, i.e. the transmitter
-will work on one frame at a time.
-
-The first block is the carrier allocator (gr::digital::ofdm_carrier_allocator_cvc).
-This sorts the incoming complex scalars onto OFDM carriers, and also places the
-pilot symbols onto the correct positions.
-There is also the option to pass OFDM symbols which are prepended in front of every
-frame (i.e. preamble symbols). These can be used for detection, synchronisation
-and channel estimation.
-
-The carrier allocator outputs OFDM symbols (i.e. complex vectors of FFT length).
-These must be converted to time domain signals before continuing, which is why
-they are piped into an (I)FFT block. Note that because all the OFDM symbols are
-treated in the shifted form, the IFFT block must be shifting as well.
-
-Finally, the cyclic prefix is added to the OFDM symbols. The gr::digital::ofdm_cyclic_prefixer
-can also perform pulse shaping on the OFDM symbols (raised cosine flanks in the
-time domain).
-
-\section ofdm_rx Receiving
-
-On the receiver side, some more effort is necessary. The following flow graph
-assumes that the input starts at the beginning of an OFDM frame and is prepended
-with a Schmidl & Cox preamble for coarse frequency correction and channel
-estimation. Also assumed is that the fine frequency offset is already corrected
-and that the cyclic prefix has been removed. The latter can be achieved by a
-gr::digital::header_payload_demux, the former can be done using a
-gr::digital::ofdm_sync_sc_cc.
-
-\image html ofdm_rx_core.png "Core elements of an OFDM receiver"
-
-First, an FFT shifts the OFDM symbols into the frequency domain, where the signal
-processing is performed (the OFDM frame is thus in the memory in matrix form).
-It is passed to a block that uses the preambles to perform channel estimation
-and coarse frequency offset. Both of these values are added to the output stream
-as tags; the preambles are then removed from the stream and not propagated.
-
-Note that this block does not correct the OFDM frame. Both the coarse frequency
-offset correction and the equalizing (using the initial channel state estimate)
-are done in the following block, gr::digital::ofdm_frame_equalizer_vcvc.
-The interesting property about this block is that it uses a
-gr::digital::ofdm_equalizer_base derived object to perform the actual equalization.
-
-The last block in the frequency domain is the gr::digital::ofdm_serializer_vcc,
-which is the inverse block to the carrier allocator.
-It plucks the data symbols from the \p occupied_carriers and outputs them as a
-stream of complex scalars. These can then be directly converted to bits, or passed
-to a forward error correction decoder.
-
-*/
diff --git a/docs/doxygen/other/oot_config.dox b/docs/doxygen/other/oot_config.dox
deleted file mode 100644
index d07c7a2808..0000000000
--- a/docs/doxygen/other/oot_config.dox
+++ /dev/null
@@ -1,87 +0,0 @@
-# Copyright (C) 2017 Free Software Foundation, Inc.
-#
-# Permission is granted to copy, distribute and/or modify this document
-# under the terms of the GNU Free Documentation License, Version 1.3
-# or any later version published by the Free Software Foundation;
-# with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.
-# A copy of the license is included in the section entitled "GNU
-# Free Documentation License".
-
-/*! \page page_oot_config Out-of-Tree Configuration
-
-New as of 3.6.5.
-
-Using gr_modtool, each package comes with the ability to easily locate
-the gnuradio-runtime library using the 'find_package(GnuradioRuntime)'
-cmake command. This only locates the gnuradio-runtime library and
-include directory, which is enough for most simple projects.
-
-As projects become more complicated and start needing to rely on other
-GNU Radio components like gnuradio-blocks or gnuradio-filter, for
-example, and when they become dependent on certain API compatibility
-versions of GNU Radio, we need something more. And so we have
-introduced the GnuradioConfig.cmake file.
-
-When GNU Radio is installed, it also installs a GNU Radio-specific
-cmake config file that we can use for more advanced compatibility
-issues of our projects. This tool allows us to specific the API
-compatible version and a set of components that are required.
-
-Taking the above example, say we have built against version 3.6.5 with
-features that were introduced in this version and we need the blocks
-and filter components as well as the main core library. We fist set a
-cmake variable GR_REQUIRED_COMPONENTS to the components we need. We
-then use the 'find_package' command and also set a minimum required
-API compatible version. Since we are on the 3.6 API version, the
-minimum required version is "3.6.5". The code in the CMakeLists.txt
-file would look like this:
-
-\code
- set(GR_REQUIRED_COMPONENTS RUNTIME BLOCKS FILTER)
- find_package(Gnuradio 3.6.5)
-\endcode
-
-Note that the capitalization is important on both lines.
-
-If the installed version of GNU Radio is 3.6.4 or some other API
-version like 3.5 or 3.7, the Cmake configuration will fail with the
-version error. Likewise, if libgnuradio-filter was not installed as
-part of GNU Radio, the configuration will also fail.
-
-\section oot_config_path_page Install Path
-
-Cmake has to know where to find either the package config files or the
-GnuradioConfig.cmake script. The package config files are located in
-$prefix/lib/pkgconfig while all of the Cmake scripts from GNU Radio
-are installed into $prefix/lib/cmake/gnuradio.
-
-If the installed GNU Radio $prefix is '/usr' or '/usr/local', then
-everything should work fine. If the GNU Radio install $prefix is
-something else, then Cmake must be told where to find it. This can be
-done in a few ways:
-
-1. If you are installing the out-of-tree module into the same $prefix,
-then you would be setting '-DCMAKE_INSTALL_PREFIX' on the
-configuration command line. This is enough to tell Cmake where to look
-for the configuration files.
-
-2. Cmake will try to find the package config (*.pc) files. If it can,
-these files will instruct Cmake where to look for the rest of the
-configuration options. If this is not set, it can be set as:
-
-\code
- export PKG_CONFIG_PATH=$prefix/lib/pkgconfg:$PKG_CONFIG_PATH
-\endcode
-
-3. Set the CMAKE_PREFIX_PATH environmental variable to $prefix.
-
-\code
- export CMAKE_PREFIX_PATH=$prefix:$CMAKE_PREFIX_PATH
-\endcode
-
-
-With method 1, you will be installing your OOT project into the same
-$prefix as GNU Radio. With methods 2 and 3, you can install your
-component anywhere you like (using -DCMAKE_INSTALL_PREFIX).
-
-*/
diff --git a/docs/doxygen/other/operating_fg.dox b/docs/doxygen/other/operating_fg.dox
deleted file mode 100644
index 62cc56fd4e..0000000000
--- a/docs/doxygen/other/operating_fg.dox
+++ /dev/null
@@ -1,287 +0,0 @@
-# Copyright (C) 2017 Free Software Foundation, Inc.
-#
-# Permission is granted to copy, distribute and/or modify this document
-# under the terms of the GNU Free Documentation License, Version 1.3
-# or any later version published by the Free Software Foundation;
-# with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.
-# A copy of the license is included in the section entitled "GNU
-# Free Documentation License".
-
-/*! \page page_operating_fg Handling flow graphs
-
-\section flowgraph Operating a Flowgraph
-
-The basic data structure in GNU Radio is the flowgraph, which
-represents the connections of the blocks through which a continuous
-stream of samples flows. The concept of a flowgraph is an acyclic
-directional graph with one or more source blocks (to insert samples
-into the flowgraph), one or more sink blocks (to terminate or export
-samples from the flowgraph), and any signal processing blocks in
-between.
-
-A program must at least create a GNU Radio 'top_block', which
-represents the top-most structure of the flowgraph. The top blocks
-provide the overall control and hold methods such as 'start,' 'stop,'
-and 'wait'.
-
-The general construction of a GNU Radio application is to create a
-gr_top_block, instantiate the blocks, connect the blocks together, and
-then start the gr_top_block. The following program shows how this is
-done. A single source and sink are used with a FIR filter between
-them.
-
-\code
- from gnuradio import gr, blocks, filter, analog
-
- class my_topblock(gr.top_block):
- def __init__(self):
- gr.top_block.__init__(self)
-
- amp = 1
- taps = filter.firdes.low_pass(1, 1, 0.1, 0.01)
-
- self.src = analog.noise_source_c(analog.GR_GAUSSIAN, amp)
- self.flt = filter.fir_filter_ccf(1, taps)
- self.snk = blocks.null_sink(gr.sizeof_gr_complex)
-
- self.connect(self.src, self.flt, self.snk)
-
- if __name__ == "__main__":
- tb = my_topblock()
- tb.start()
- tb.wait()
-\endcode
-
-The 'tb.start()' starts the data flowing through the flowgraph while
-the 'tb.wait()' is the equivalent of a thread's 'join' operation and
-blocks until the gr_top_block is done.
-
-An alternative to using the 'start' and 'wait' methods, a 'run' method is
-also provided for convenience that is a blocking start call;
-equivalent to the above 'start' followed by a 'wait.'
-
-
-\subsection latency Latency and Throughput
-
-By default, GNU Radio runs a scheduler that attempts to optimize
-throughput. Using a dynamic scheduler, blocks in a flowgraph pass
-chunks of items from sources to sinks. The sizes of these chunks will
-vary depending on the speed of processing. For each block, the number
-of items it can process is dependent on how much space it has in its
-output buffer(s) and how many items are available on the input
-buffer(s).
-
-The consequence of this is that often a block may be called with a very
-large number of items to process (several thousand). In terms of
-speed, this is efficient since now the majority of the processing time
-is taken up with processing samples. Smaller chunks mean more calls
-into the scheduler to retrieve more data. The downside to this is that
-it can lead to large latency while a block is processing a large chunk
-of data.
-
-To combat this problem, the gr_top_block can be passed a limit on the
-number of output items a block will ever receive. A block may get less
-than this number, but never more, and so it serves as an upper limit
-to the latency any block will exhibit. By limiting the number of items
-per call to a block, though, we increase the overhead of the
-scheduler, and so reduce the overall efficiency of the application.
-
-To set the maximum number of output items, we pass a value into the
-'start' or 'run' method of the gr_top_block:
-
-\code
- tb.start(1000)
- tb.wait()
-or
- tb.run(1000)
-\endcode
-
-Using this method, we place a global restriction on the size of items
-to all blocks. Each block, though, has the ability to overwrite this
-with its own limit. Using the 'set_max_noutput_items(m)' method for an
-individual block will overwrite the global setting. For example, in
-the following code, the global setting is 1000 items max, except for
-the FIR filter, which can receive up to 2000 items.
-
-\code
- tb.flt.set_max_noutput_items(2000)
- tb.run(1000)
-\endcode
-
-In some situations, you might actually want to restrict the size of
-the buffer itself. This can help to prevent a buffer who is blocked
-for data from just increasing the amount of items in its buffer, which
-will then cause an increased latency for new samples. You can set the
-size of an output buffer for each output port for every block.
-
-WARNING: This is an advanced feature in GNU Radio and should not be
-used without a full understanding of this concept as explained below.
-
-To set the output buffer size of a block, you simply call:
-
-\code
- tb.blk0.set_max_output_buffer(2000)
- tb.blk1.set_max_output_buffer(1, 2000)
- tb.start()
- print tb.blk1.max_output_buffer(0)
- print tb.blk1.max_output_buffer(1)
-\endcode
-
-In the above example, all ports of blk0 are set to a buffer size of
-2000 in _items_ (not bytes), and blk1 only sets the size for output
-port 1, any and all other ports use the default. The third and fourth
-lines just print out the buffer sizes for ports 0 and 1 of blk1. This
-is done after start() is called because the values are updated based
-on what is actually allocated to the block's buffers.
-
-NOTES:
-
-1. Buffer length assignment is done once at runtime (i.e., when run()
-or start() is called). So to set the max buffer lengths, the
-set_max_output_buffer calls must be done before this.
-
-2. Once the flowgraph is started, the buffer lengths for a block are
-set and cannot be dynamically changed, even during a
-lock()/unlock(). If you need to change the buffer size, you will have
-to delete the block and rebuild it, and therefore must disconnect and
-reconnect the blocks.
-
-3. This can affect throughput. Large buffers are designed to improve
-the efficiency and speed of the program at the expense of
-latency. Limiting the size of the buffer may decrease performance.
-
-4. The real buffer size is actually based on a minimum granularity of
-the system. Typically, this is a page size, which is typically 4096
-bytes. This means that any buffer size that is specified with this
-command will get rounded up to the nearest granularity (e.g., page size).
-When calling max_output_buffer(port) after the flowgraph is
-started, you will get how many items were actually allocated in the
-buffer, which may be different than what was initially specified.
-
-
-\section reconfigure Reconfiguring Flowgraphs
-
-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::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
-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::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, analog, blocks
-import time
-
-class mytb(gr.top_block):
- def __init__(self):
- gr.top_block.__init__(self)
-
- 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 = blocks.head(gr.sizeof_gr_complex, 1000000)
- 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))
- self.connect(self.add, self.head)
- self.connect(self.head, self.snk)
-
-def main():
- tb = mytb()
- tb.start()
- time.sleep(0.01)
-
- # Stop flowgraph and disconnect the add block
- tb.lock()
- tb.disconnect(tb.add, tb.head)
- tb.disconnect(tb.src0, (tb.add,0))
- tb.disconnect(tb.src1, (tb.add,1))
-
- # Connect the sub block and restart
- tb.connect(tb.sub, tb.head)
- tb.connect(tb.src0, (tb.sub,0))
- tb.connect(tb.src1, (tb.sub,1))
- tb.unlock()
-
- tb.wait()
-
-if __name__ == "__main__":
- main()
-\endcode
-
-During reconfiguration, the maximum noutput_items value can be changed
-either globally using the 'set_max_noutput_items(m)' on the gr_top_block
-object or locally using the 'set_max_noutput_items(m)' on any given
-block object.
-
-A block also has a 'unset_max_noutput_items()' method that unsets the
-local max noutput_items value so that block reverts back to using the
-global value.
-
-The following example expands the previous example but sets and resets
-the max noutput_items both locally and globally.
-
-\code
-from gnuradio import gr, analog, blocks
-import time
-
-class mytb(gr.top_block):
- def __init__(self):
- gr.top_block.__init__(self)
-
- 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 = blocks.head(gr.sizeof_gr_complex, 1000000)
- 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))
- self.connect(self.add, self.head)
- self.connect(self.head, self.snk)
-
-def main():
- # Start the gr_top_block after setting some max noutput_items.
- tb = mytb()
- tb.src1.set_max_noutput_items(2000)
- tb.start(100)
- time.sleep(0.01)
-
- # Stop flowgraph and disconnect the add block
- tb.lock()
-
- tb.disconnect(tb.add, tb.head)
- tb.disconnect(tb.src0, (tb.add,0))
- tb.disconnect(tb.src1, (tb.add,1))
-
- # Connect the sub block
- tb.connect(tb.sub, tb.head)
- tb.connect(tb.src0, (tb.sub,0))
- tb.connect(tb.src1, (tb.sub,1))
-
- # Set new max_noutput_items for the gr_top_block
- # and unset the local value for src1
- tb.set_max_noutput_items(1000)
- tb.src1.unset_max_noutput_items()
- tb.unlock()
-
- tb.wait()
-
-if __name__ == "__main__":
- main()
-\endcode
-
-
-*/
-
diff --git a/docs/doxygen/other/packet_txrx.dox b/docs/doxygen/other/packet_txrx.dox
deleted file mode 100644
index 31417779c0..0000000000
--- a/docs/doxygen/other/packet_txrx.dox
+++ /dev/null
@@ -1,91 +0,0 @@
-# Copyright (C) 2017 Free Software Foundation, Inc.
-#
-# Permission is granted to copy, distribute and/or modify this document
-# under the terms of the GNU Free Documentation License, Version 1.3
-# or any later version published by the Free Software Foundation;
-# with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.
-# A copy of the license is included in the section entitled "GNU
-# Free Documentation License".
-
-/*! \page page_packet_data Packet Data Transmission
-
-\section packet_data_introduction Introduction
-
-In many cases, the PHY layer of a digital transceiver uses <em>packets</em>to break
-down the transmission (as opposed to continuously broadcasting data), and GNU Radio
-natively supports this kind of transmission. The basic mechanisms which allow this
-are the \ref page_msg_passing and the \ref page_tagged_stream_blocks.
-
-With the tools provided in GNU Radio, simple digital packet transmission schemes
-are easily implemented, allowing the creation of packet-based communication links
-and even -networks.
-
-\section packet_data_structure Structure of a packet
-
-Typically, a packet consists of the following elements:
-
-- A preamble. This is used for detection, synchronization (in time and frequency) and possibly initial channel state estimation.
-- A header. This is of fixed length and stores information about the packet, such as (most importantly) its length, but potentially other information, such as the packet number, its intended recipient etc.
-- The payload.
-- A checksum, typically a CRC value, to validate the packet contents.
-
-At the transmitter stage, these are modulated and prepared for transmission (a forward error correction code may also be applied). Because the transmitter knows the packet length, is a trivial matter to create the transmit frames using the tagged stream blocks.
-
-The receiver has to perform a multitude of things to obtain the packet again.
-Most importantly, it has to convert an infinite stream (coming from the receiver
-device, e.g. a UHD source block) into a packetized, tagged stream.
-
-\section packet_data_hpdemuxer The Header/Payload Demuxer and header parser
-
-The key element to return back to packetized state is the gr::digital::header_payload_demux.
-At its first input, it receives a continuous stream of sample data, coming from
-the receiver device. It discards all the incoming samples, until the beginning
-of a packet is signalled, either by a stream tag, or a trigger signal on its second input.
-
-Once such a beginning is detected, the demultiplexer copies the preamble and header
-to the first output (it must know the exact length of these elements). The header
-can then be demodulated with any suitable set of GNU Radio blocks.
-
-To turn the information stored in the demodulated header bits into metadata
-which can be understood by GNU Radio, a gr::digital::packet_headerparser_b block
-is used to turn the header data into a message, which is passed back to the
-header/payload demuxer. The latter then knows the length of the payload, and
-passes that out on the second output, along with all the metadata obtained
-in the header demodulation chain.
-
-The knowledge of the header structure (i.e. how to turn a sequence of bits into
-a payload length etc.) is stored in an object of type gr::digital::packet_header_default.
-This must be passed to the header parser block.
-
-\section packet_data_ofdm Packet receiver example: OFDM
-
-\image html example_ofdm_packet_rx.png "Example: OFDM Packet Receiver"
-
-The image above shows an example of a simple OFDM receiver. It has no forward error correction,
-and uses the simplest possible frame structure.
-
-The four elements of the packet receiver are highlighted. The first part is the packet detector
-and synchronizer. The samples piped into the header/payload demuxer are fine frequency corrected,
-and a trigger signal is sent to mark the beginning of the burst.
-
-Next, the header demodulation receiver chain is activated. The FFT shifts OFDM symbols to the
-frequency domain. The coarse frequency offset and initial channel state are estimated from the
-preamble and are added to the stream as tags. The OFDM symbol containing the header is passed
-to an equalizer, which also corrects the coarse frequency offset. A serializer picks the data
-symbols from the OFDM symbol and outputs them as a sequence of scalar complex values, which
-are then demodulated into bits (in this case BPSK is used).
-
-The bits are interpreted by the header parser, which uses a gr::digital::packet_header_ofdm
-object to interpret the bits (the latter is derived form gr::digital::packet_header_default).
-The result from the header parser is then fed back to the demuxer, which now knows the length of
-payload and outputs that as a tagged stream.
-
-The payload demodulation chain is the same as the header demodulation chain, only the
-channel estimator block is unnecessary as the channel state information is still available
-as metadata on the payload tagged stream.
-
-This flow graph, as well as the corresponding transmitter, can be found in
-gr-digital/examples/ofdm/rx_ofdm.grc and gr-digital/examples/ofdm/tx_ofdm.grc
-
-
-*/
diff --git a/docs/doxygen/other/perf_counters.dox b/docs/doxygen/other/perf_counters.dox
deleted file mode 100644
index 7562b11298..0000000000
--- a/docs/doxygen/other/perf_counters.dox
+++ /dev/null
@@ -1,107 +0,0 @@
-# Copyright (C) 2017 Free Software Foundation, Inc.
-#
-# Permission is granted to copy, distribute and/or modify this document
-# under the terms of the GNU Free Documentation License, Version 1.3
-# or any later version published by the Free Software Foundation;
-# with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.
-# A copy of the license is included in the section entitled "GNU
-# Free Documentation License".
-
-/*! \page page_perf_counters Performance Counters
-
-\section pc_introduction Introduction
-
-Each block can have a set of Performance Counters that the schedule
-keeps track of. These counters measure and store information about
-different performance metrics of their operation. The concept is
-fairly extensible, but currently, GNU Radio defines the following
-Performance Counters:
-
-\li noutput_items: number of items the block can produce.
-\li nproduced: the number of items the block produced.
-\li input_buffers_full: % of how full each input buffer is.
-\li output_buffers_full: % of how full each output buffer is.
-\li work_time: number of CPU ticks during the call to general_work().
-\li work_time_total: Accumulated sum of work_time.
-
-For each Performance Counter except the work_time_total, we can
-retrieve the instantaneous, average, and variance from the
-block. Access to these counters is done through a simple set of
-functions added to every block in the flowgraph:
-
-\code
- float pc_<name>[_<type>]();
-\endcode
-
-In the above, the \<name\> field is one of the counters in the above
-list of counters. The optional \<type\> suffix is either 'avg' to get
-the average value or 'var' to get the variance. Without a suffix, the
-function returns the most recent instantaneous value.
-
-We can also reset the Performance Counters back to zero to remove any
-history of the current average and variance calculations for a
-particular block.
-
-\code
- void reset_perf_counters();
-\endcode
-
-
-\section pc_config Compile-time and Run-time Configuration
-
-Because the Performance Counters are calculated during each call to
-work for every block, they increase the computational cost and memory
-overhead. The more blocks used, the more impact this may have. So
-while it turns out after some experimentation that the Performance
-Counters add very little overhead (less than 1% speed degradation for
-a 24-block flowgraph), we err on the side of minimizing overhead in
-the scheduler. To do so, we have added compile-time and run-time
-configuration of the use of Performance Counters.
-
-
-\subsection pc_config_compile Compile-time Config
-
-By default, GNU Radio will build without Performance Counters
-enabled. To enable Performance Counters, we pass the following flag to
-cmake:
-
-\code
- -DENABLE_PERFORMANCE_COUNTERS=True
-\endcode
-
-Note that this affects the GNU Radio block class and the scheduler
-itself. Out-of-tree projects will inherit directly from GNU Radio
-because of the inheritance with gr::block. Turning on Performance
-Counters for GNU Radio will require a recompilation of the OOT project
-but no extra configuration.
-
-
-\subsection pc_config_runtime Run-time Config
-
-Given the Performance Counters are enabled in GNU Radio at
-compile-time, we can still control if they are used or not at
-run-time. For this, we use the GNU Radio preferences file in the
-section [PerfCounters]. This section is installed into the
-gnuradio-runtime.conf file. As usual with the preferences, this
-section or any of the individual options can be overridden in the
-user's config.conf file or using a GR_CONF_ environmental variable
-(see \ref prefs for more details).
-
-The options for the [PerfCounters] section are:
-
-\li on: Turn counters on/off at run-time.
-\li export: Allow counters to be exported over ControlPort.
-\li clock: sets the type of clock used when calculating work_time
-('thread' or 'monotonic').
-
-
-\section pc_perfmonitor Performance Monitor
-
-See \ref perfmonitor for some details of using a ControlPort-based
-monitor application, gr-perf-monitorx, for visualizing the
-counters. This application is particularly useful in learning which
-blocks are the computationally complex blocks that could use extra
-optimization or work to improve their performance. It can also be used
-to understand the current 'health' of the application.
-
-*/
diff --git a/docs/doxygen/other/pfb_intro.dox b/docs/doxygen/other/pfb_intro.dox
deleted file mode 100644
index 66c9891d75..0000000000
--- a/docs/doxygen/other/pfb_intro.dox
+++ /dev/null
@@ -1,167 +0,0 @@
-# Copyright (C) 2017 Free Software Foundation, Inc.
-#
-# Permission is granted to copy, distribute and/or modify this document
-# under the terms of the GNU Free Documentation License, Version 1.3
-# or any later version published by the Free Software Foundation;
-# with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.
-# A copy of the license is included in the section entitled "GNU
-# Free Documentation License".
-
-/*! \page page_pfb Polyphase Filterbanks
-
-\section pfb_introduction Introduction
-
-Polyphase filterbanks (PFB) are a very powerful set of filtering tools
-that can efficiently perform many multi-rate signal processing
-tasks. GNU Radio has a set of polyphase filterbank blocks to be used
-in all sorts of applications.
-
-\section pfb_Usage
-
-See the documentation for the individual blocks for details about what
-they can do and how they should be used. Furthermore, there are
-examples for these blocks in <b>gr-filter/examples</b>.
-
-The main issue when using the PFB blocks is defining the prototype
-filter, which is passed to all of the blocks as a vector of \p
-taps. The taps from the prototype filter which get partitioned among
-the \p N channels of the channelizer.
-
-An example of creating a set of filter taps for a PFB channelizer is
-found on line 49 of <b>gr-filter/examples/channelizer.py</b>
-and reproduced below. Notice that the sample rate is the sample rate
-at the input to the channelizer while the bandwidth and transition
-width are defined for the channel bandwidths. This makes a fairly long
-filter that is then split up between the \p N channels of the PFB.
-
-\code
- self._fs = 9000 # input sample rate
- self._M = 9 # Number of channels to channelize
-
- 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
-(complex, so 9 kHz of bandwidth). The filter uses 9 channels, so each
-output channel will have a bandwidth and sample rate of 1 kHz. We want
-to pass most of the channel, so we define the channel bandwidth to be
-a low pass filter with a bandwidth of 475.5 Hz and a transition
-bandwidth of 50 Hz, but we have defined this using a sample rate of
-the original 9 kHz. The prototype filter has 819 taps to be divided up
-between the 9 channels, so each channel uses 91 taps. This is probably
-over-kill for a channelizer, and we could reduce the amount of taps
-per channel to a couple of dozen with no ill effects.
-
-The basic rule when defining a set of taps for a PFB block is to think
-about the filter running at the highest rate it will see while the
-bandwidth is defined for the size of the channels. In the channelizer
-case, the highest rate is defined as the rate of the incoming signal,
-but in other PFB blocks, this is not so obvious.
-
-Two very useful blocks to use are the arbitrary resampler and the
-clock synchronizer (for PAM signals). These PFBs are defined with a
-set number of filters based on the fidelity required from them, not
-the rate changes. By default, the \p filter_size is set to 32 for
-these blocks, which is a reasonable default for most tasks. Because
-the PFB uses this number of filters in the filterbank, the maximum
-rate of the bank is defined from this (see the theory of a polyphase
-interpolator for a justification of this). So the prototype filter is
-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>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
-being resampled but does not pass any out-of-band noise. See the code
-for this block for details of how the filter is constructed.
-
-Of course, a user can create his or her own taps and use them in the
-arbitrary resampler for more specific requirements. Some of the UHD
-examples (<b>gr-uhd/examples</b>) use this ability to create a
-received matched filter or channel filter that also resamples the
-signal.
-
-\section pfb_examples Examples
-
-The following is an example of the using the channelizer. It creates
-the appropriate filter to channelizer 9 channels out of an original
-signal that is 9000 Hz wide, so each output channel is now 1000
-Hz. The code then plots the PSD of the original signal to see the
-signals in the origina spectrum and then makes 9 plots for each of the
-channels.
-
-NOTE: you need the Matplotlib Python module installed to
-run this example.
-
-\include gr-filter/examples/channelize.py
-
-
-\section pfb_arb_resampler The PFB Arbitrary Resampler Kernel
-
-GNU Radio has a PFB arbitrary resampler block that can be used to
-resample a signal to any arbitrary and real resampling rate. The
-resampling feature is one that could easily be useful to other blocks,
-and so we have extracted the kernel of the resampler into its own
-class that can be used as such.
-
-The PFB arbitrary resampler is defined in pfb_arb_resampler.h and has
-the following constructor:
-
-\code
-namespace gr {
- namespace filter {
- namespace kernel {
-
- pfb_arb_resampler_XXX(float rate,
- const std::vector<float> &taps,
- unsigned int filter_size);
-
- } /* namespace kernel */
- } /* namespace filter */
-} /* namespace gr */
-\endcode
-
-Currently, only a 'ccf' and 'fff' version are defined. This kernel,
-like the block itself, takes in the resampling \p rate as a floating
-point number. The \p taps are passed as the baseband prototype filter,
-and the quantization error of the filter is determined by the \p
-filter_size parameter.
-
-The prototype taps are generated like all other PFB filter
-taps. Specifically, we construct them generally as a lowpass filter at
-the maximum rate of the filter. In the case of these resamplers, the
-maximum rate is actually the number of filters.
-
-A simple example follows. We construct a filter that will pass the
-entire passband of the original signal to be resampled. To make it
-easy, we work in normalized sample rates for this. The gain of the
-filter is set to filter_size to compensate for the upsampling, the
-sampling rate itself is also set to filter_size, which is assuming
-that the incoming signal is at a sampling rate of 1.0. We defined the
-passband to be 0.5 to pass the entire width of the original signal and
-set a transition band to 0.1. Note that this causes a bit of roll-off
-outside of the original passband and could lead to introducing some
-aliasing. More care should be taken to construct the passband and
-transition width of the filter for the given signal while keeping the
-total number of taps small. A stopband attenuation of 60 dB was used
-here, and again, this is a parameter we can adjust to alter the
-performance and size of the filter.
-
-\code
- firdes.low_pass_2(filter_size, filter_size, 0.5, 0.1, 60)
-\endcode
-
-As is typical with the PFB filters, a filter size of 32 is generally
-an appropriate trade-off of accuracy, performance, and memory. This
-should provide an error roughly equivalent to the quanization error of
-using 16-bit fixed point representation. Generally, increasing over 32
-provides some accuracy benefits without a huge increase in
-computational demands.
-
-*/
diff --git a/docs/doxygen/other/pmt.dox b/docs/doxygen/other/pmt.dox
deleted file mode 100644
index 1bc6cbecd4..0000000000
--- a/docs/doxygen/other/pmt.dox
+++ /dev/null
@@ -1,506 +0,0 @@
-# Copyright (C) 2017 Free Software Foundation, Inc.
-#
-# Permission is granted to copy, distribute and/or modify this document
-# under the terms of the GNU Free Documentation License, Version 1.3
-# or any later version published by the Free Software Foundation;
-# with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.
-# A copy of the license is included in the section entitled "GNU
-# Free Documentation License".
-
-/*! \page page_pmt Polymorphic Types
-
-\section pmt_introduction Introduction
-
-Polymorphic Types are opaque data types that are designed as generic
-containers of data that can be safely passed around between blocks and
-threads in GNU Radio. They are heavily used in the stream tags and
-message passing interfaces. The most complete list of PMT function is,
-of course, the source code, specifically the header file pmt.h. This
-manual page summarizes the most important features and points of PMTs.
-
-Let's dive straight into some Python code and see how we can use
-PMTs:
-
-\code
->>> import pmt
->>> P = pmt.from_long(23)
->>> type(P)
-<class 'pmt.pmt_swig.swig_int_ptr'>
->>> print P
-23
->>> P2 = pmt.from_complex(1j)
->>> type(P2)
-<class 'pmt.pmt_swig.swig_int_ptr'>
->>> print P2
-0+1i
->>> pmt.is_complex(P2)
-True
-\endcode
-
-First, the pmt module is imported. We assign two values (P and P2)
-with PMTs using the from_long() and from_complex() calls,
-respectively. As we can see, they are both of the same type! This
-means we can pass these variables to C++ through SWIG, and C++ can
-handle this type accordingly.
-
-The same code as above in C++ would look like this:
-
-\code
-#include <pmt/pmt.h>
-// [...]
-pmt::pmt_t P = pmt::from_long(23);
-std::cout << P << std::endl;
-pmt::pmt_t P2 = pmt::from_complex(gr_complex(0, 1)); // Alternatively: pmt::from_complex(0, 1)
-std::cout << P2 << std::endl;
-std::cout << pmt::is_complex(P2) << std::endl;
-\endcode
-
-Two things stand out in both Python and C++. First, we can simply print
-the contents of a PMT. How is this possible? Well, the PMTs have
-in-built capability to cast their value to a string (this is not
-possible with all types, though). Second, PMTs must obviously know
-their type, so we can query that, e.g. by calling the is_complex()
-method.
-
-When assigning a non-PMT value to a PMT, we can use the from_*
-methods, and use the to_* methods to convert back:
-
-\code
-pmt::pmt_t P_int = pmt::from_long(42);
-int i = pmt::to_long(P_int);
-pmt::pmt_t P_double = pmt::from_double(0.2);
-double d = pmt::to_double(P_double);
-\endcode
-
-String types play a bit of a special role in PMTs, as we will see
-later, and have their own converter:
-
-\code
-pmt::pmt_t P_str = pmt::string_to_symbol("spam");
-pmt::pmt_t P_str2 = pmt::intern("spam");
-std::string str = pmt::symbol_to_string(P_str);
-\endcode
-
-The pmt::intern is another way of saying pmt::string_to_symbol.
-
-In Python, we can make use of the dynamic typing, and there's actually a
-helper function to do these conversions (C++ also has a helper
-function for converting to PMTs called pmt::mp(), but it's less
-powerful, and not quite as useful, because types are always strictly
-known in C++):
-
-\code
-P_int = pmt.to_pmt(42)
-i = pmt.to_python(P_int)
-P_double = pmt.to_pmt(0.2)
-d = pmt.to_double(P_double)
-\endcode
-
-On a side note, there are three useful PMT constants, which can be
-used in both Python and C++ domains. In C++, these can be used as
-such:
-
-\code
-pmt::pmt_t P_true = pmt::PMT_T;
-pmt::pmt_t P_false = pmt::PMT_F;
-pmt::pmt_t P_nil = pmt::PMT_NIL;
-\endcode
-
-In Python:
-
-\code
-P_true = pmt.PMT_T
-P_false = pmt.PMT_F
-P_nil = pmt.PMT_NIL
-\endcode
-
-pmt.PMT_T and pmt.PMT_F are boolean PMT types.
-
-To be able to go back to C++ data types, we need to be able to find
-out the type from a PMT. The family of is_* methods helps us do that:
-
-\code
-double d;
-if (pmt::is_integer(P)) {
- d = (double) pmt::to_long(P);
-} else if (pmt::is_real(P)) {
- d = pmt::to_double(P);
-} else {
- // We really expected an integer or a double here, so we don't know what to do
- throw std::runtime_error("expected an integer!");
-}
-\endcode
-
-It is important to do type checking since we cannot unpack a PMT of
-the wrong data type.
-
-We can compare PMTs without knowing their type by using the
-pmt::equal() function:
-
-\code
-if (pmt::eq(P_int, P_double)) {
- std::cout << "Equal!" << std::endl; // This line will never be reached
-\endcode
-
-The rest of this page provides more depth into how to handle different
-data types with the PMT library.
-
-
-
-\section pmt_datatype PMT Data Type
-
-All PMTs are of the type pmt::pmt_t. This is an opaque container and
-PMT functions must be used to manipulate and even do things like
-compare PMTs. PMTs are also \a immutable (except PMT vectors). We
-never change the data in a PMT; instead, we create a new PMT with the
-new data. The main reason for this is thread safety. We can pass PMTs
-as tags and messages between blocks and each receives its own copy
-that we can read from. However, we can never write to this object, and
-so if multiple blocks have a reference to the same PMT, there is no
-possibility of thread-safety issues of one reading the PMT data while
-another is writing the data. If a block is trying to write new data to
-a PMT, it actually creates a new PMT to put the data into. Thus we
-allow easy access to data in the PMT format without worrying about
-mutex locking and unlocking while manipulating them.
-
-PMTs can represent the following:
-
-- Boolean values of true/false
-- Strings (as symbols)
-- Integers (long and uint64)
-- Floats (as doubles)
-- Complex (as two doubles)
-- Pairs
-- Tuples
-- Vectors (of PMTs)
-- Uniform vectors (of any standard data type)
-- Dictionaries (list of key:value pairs)
-- Any (contains a boost::any pointer to hold anything)
-
-The PMT library also defines a set of functions that operate directly
-on PMTs such as:
-
-- Equal/equivalence between PMTs
-- Length (of a tuple or vector)
-- Map (apply a function to all elements in the PMT)
-- Reverse
-- Get a PMT at a position in a list
-- Serialize and deserialize
-- Printing
-
-The constants in the PMT library are:
-
-- pmt::PMT_T - a PMT True
-- pmt::PMT_F - a PMT False
-- pmt::PMT_NIL - an empty PMT (think Python's 'None')
-
-\section pmt_insert Inserting and Extracting Data
-
-Use pmt.h for a complete guide to the list of functions used to create
-PMTs and get the data from a PMT. When using these functions, remember
-that while PMTs are opaque and designed to hold any data, the data
-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::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::from_double(a);
-double b = pmt::to_double(pmt_a);
-
-int c = 12345;
-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::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
-to manipulate them, and these are explained in their own sections.
-
-
-\section pmt_strings Strings
-
-PMTs have a way of representing short strings. These strings are
-actually stored as interned symbols in a hash table, so in other
-words, only one PMT object for a given string exists. If creating a
-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::intern, is simply an alias of the first.
-
-\code
-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::symbol_to_string(str0);
-\endcode
-
-
-\section pmt_tests Tests and Comparisons
-
-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::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::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::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::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::is_double(pmt_a))
- double d = pmt::to_double(pmt_c);
-
-\endcode
-
-
-\section pmt_dict Dictionaries
-
-PMT dictionaries are lists of key:value pairs. They have a
-well-defined interface for creating, adding, removing, and accessing
-items in the dictionary. Note that every operation that changes the
-dictionary both takes a PMT dictionary as an argument and returns a
-PMT dictionary. The dictionary used as an input is not changed and the
-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::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
-to \a a. This still creates a new dictionary and removes the local
-reference to the old dictionary. This just keeps our number of
-variables small.
-
-\code
-import pmt
-
-key0 = pmt.intern("int")
-val0 = pmt.from_long(123)
-val1 = pmt.from_long(234)
-
-key1 = pmt.intern("double")
-val2 = pmt.from_double(5.4321)
-
-# Make an empty dictionary
-a = pmt.make_dict()
-
-# Add a key:value pair to the dictionary
-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.dict_add(a, key0, val1)
-print a
-
-# Add a new key:value pair
-a = pmt.dict_add(a, key1, val2)
-print a
-
-# Test if we have a key, then delete it
-print pmt.dict_has_key(a, key1)
-a = pmt.dict_delete(a, key1)
-print pmt.dict_has_key(a, key1)
-
-ref = pmt.dict_ref(a, key0, pmt.PMT_NIL)
-print ref
-
-# The following should never print
-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
-
-\section pmt_vectors Vectors
-
-PMT vectors come in two forms: vectors of PMTs and vectors of uniform
-data. The standard PMT vector is a vector of PMTs, and each PMT can be
-of any internal type. On the other hand, uniform PMTs are of a
-specific data type which come in the form:
-
-- (u)int8
-- (u)int16
-- (u)int32
-- (u)int64
-- float32
-- float64
-- complex 32 (std::complex<float>)
-- complex 64 (std::complex<double>)
-
-That is, the standard sizes of integers, floats, and complex types of
-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::length.
-
-For standard vectors, these functions look like:
-
-- 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::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
-the implications of setting a new value as well as accessing the
-'vector_writable_elements' data. Since these are mostly standard data
-types, sets and gets are atomic, so it is unlikely to cause a great
-deal of harm. But it's only unlikely, not impossible. Best to use
-mutexes whenever manipulating data in a vector.
-
-
-\subsection pmt_blob BLOB
-
-A BLOB is a 'binary large object' type. In PMT's, this is actually
-just a thin wrapper around a u8vector.
-
-\section pmt_pairs Pairs
-
-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::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 pmt_serdes Serializing and Deserializing
-
-It is often important to hide the fact that we are working with PMTs
-to make them easier to transmit, store, write to file, etc. The PMT
-library has methods to serialize data into a string buffer or a
-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::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
-original PMT.
-
-\code
-import pmt
-
-key0 = pmt.intern("int")
-val0 = pmt.from_long(123)
-
-key1 = pmt.intern("double")
-val1 = pmt.from_double(5.4321)
-
-# Make an empty dictionary
-a = pmt.make_dict()
-
-# Add a key:value pair to the dictionary
-a = pmt.dict_add(a, key0, val0)
-a = pmt.dict_add(a, key1, val1)
-
-print a
-
-ser_str = pmt.serialize_str(a)
-print ser_str
-
-b = pmt.deserialize_str(ser_str)
-print b
-
-\endcode
-
-The line where we 'print ser_str' will print and parts will be
-readable, but the point of serializing is not to make a human-readable
-string. This is only done here as a test.
-
-
-\section pmt_printing Printing
-
-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::from_double(1.0);
-std::cout << "The PMT a contains " << a << std::endl;
-\endcode
-
-
-\section pmt_python Conversion between Python Objects and PMTs
-
-Although PMTs can be manipulated in Python using the Python versions
-of the C++ interfaces, there are some additional goodies that make it
-easier to work with PMTs in python. There are functions to automate
-the conversion between PMTs and Python types for booleans, strings,
-integers, longs, floats, complex numbers, dictionaries, lists, tuples
-and combinations thereof.
-
-Two functions capture most of this functionality:
-
-\code
-pmt.to_pmt # Converts a python object to a PMT.
-pmt.to_python # Converts a PMT into a python object.
-\endcode
-
-*/
diff --git a/docs/doxygen/other/prefs.dox b/docs/doxygen/other/prefs.dox
deleted file mode 100644
index d8c2782b1d..0000000000
--- a/docs/doxygen/other/prefs.dox
+++ /dev/null
@@ -1,96 +0,0 @@
-# Copyright (C) 2017 Free Software Foundation, Inc.
-#
-# Permission is granted to copy, distribute and/or modify this document
-# under the terms of the GNU Free Documentation License, Version 1.3
-# or any later version published by the Free Software Foundation;
-# with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.
-# A copy of the license is included in the section entitled "GNU
-# Free Documentation License".
-
-/*! \page page_prefs Configuration files
-
-\section prefs Configuration / Preference Files
-
-GNU Radio defines some of its basic behavior through a set of
-configuration files located in
-${prefix}/etc/gnuradio/conf.d. Different components have different
-files listed in here for the various properties. These will be read
-once when starting a GNU Radio application, so updates during runtime
-will not affect them.
-
-The configuration files use the following format:
-
-\code
-# Stuff from section 1
-[section1]
-var1 = value1
-var2 = value2 # value of 2
-
-# Stuff from section 2
-[section2]
-var3 = value3
-\endcode
-
-In this file, the hash mark ('#') indicates a comment and blank lines
-are ignored. Section labels are defined inside square brackets as a
-group distinguisher. All options must be associated with a section
-name. The options are listed one per line with the option name is
-given followed by an equals ('=') sign and then the value.
-
-All section and option names must not have white spaces. If a value
-must have white space, the it MUST be put inside quotes. Any quoted
-value will have its white space preserved and the quotes internally
-will be stripped. As an example, on Apple desktops, an output device
-of "Display Audio" is a possible output device and can be set as:
-
-\code
-[audio_osx]
-default_output_device = "Display Audio"
-\endcode
-
-The result will pass Display Audio to the audio setup.
-
-The value of an option can be a string or number and retrieved through
-a few different interfaces. There is a single preference object
-created when GNU Radio is launched. In Python, you can get this by
-making a new variable:
-
-\code
-p = gr.prefs()
-\endcode
-
-Similarly, in C++, we get a reference to the object by explicitly
-calling for the singleton of the object:
-
-\code
- prefs *p = prefs::singleton();
-\endcode
-
-The methods associated with this preferences object are (from class gr::prefs):
-
-\code
- bool has_section(string section)
- bool has_option(string section, string option)
- string get_string(string section, string option, string default_val)
- bool get_bool(string section, string option, bool default_val)
- long get_long(string section, string option, long default_val)
- double get_double(string section, string option, double default_val)
-\endcode
-
-When setting a Boolean value, we can use 0, 1, "True", "true",
-"False", "false", "On", "on", "Off", and "off".
-
-All configuration preferences in these files can also be overloaded by
-an environmental variable. The environmental variable is named based
-on the section and option name from the configuration file as:
-
-\code
- GR_CONF_<SECTION>_<OPTION> = <value>
-\endcode
-
-The "GR_CONF_" is a prefix to identify this as a GNU Radio
-configuration variable and the section and option names are in
-uppercase. The value is the same format that would be used in the
-config file itself.
-
-*/
diff --git a/docs/doxygen/other/python_blocks.dox b/docs/doxygen/other/python_blocks.dox
deleted file mode 100644
index 2381b0cad0..0000000000
--- a/docs/doxygen/other/python_blocks.dox
+++ /dev/null
@@ -1,163 +0,0 @@
-# Copyright (C) 2017 Free Software Foundation, Inc.
-#
-# Permission is granted to copy, distribute and/or modify this document
-# under the terms of the GNU Free Documentation License, Version 1.3
-# or any later version published by the Free Software Foundation;
-# with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.
-# A copy of the license is included in the section entitled "GNU
-# Free Documentation License".
-
-/*! \page page_python_blocks Python Blocks
-
-How to create blocks in Python
-
-\section pyblocks_streaming Streaming Data Blocks
-
-We create blocks in Python very much like we would in C++, just with
-more Python. Figure out which type of block you want to create:
-
-\li general block (gr.basic_block)
-\li synchronous block (gr.sync_block)
-\li decimator (gr.sync_decimator)
-\li interpolator (gr.sync_interpolator)
-
-The block class inherits from one of these base classes, and then in
-defining the parent class, we set the I/O signature. However, unlike
-in C++ where we use the gr::io_signature class, here we can just
-create a Python list of the I/O data sizes using numpy data types:
-
-\li numpy.int8
-\li numpy.int16
-\li numpy.int32
-\li numpy.float32
-\li numpy.float64
-
-Like a normal C++ version of the block, we then create and initialize
-any variables in the constructor, define any setters and getters, and
-create the work function. The prototype for the work function is quite
-simple:
-
-\code
-def work(self, input_items, output_items)
-\endcode
-
-The input_items and output_items are lists of lists. The input_items
-contains a vector of input samples for every input stream, and the
-output_items is a vector for each output stream where we can place
-items. Then length of output_items[0] is equivalent to the
-noutput_items concept we are so familiar with from the C++ blocks.
-
-Following is an example Python block that adds two input streams
-together. This block is used in the qa_block_gateway.py test code.
-
-\code
-class add_2_f32_1_f32(gr.sync_block):
- def __init__(self):
- gr.sync_block.__init__(
- self,
- name = "add 2 f32",
- in_sig = [numpy.float32, numpy.float32],
- out_sig = [numpy.float32],
- )
-
- def work(self, input_items, output_items):
- output_items[0][:] = input_items[0] + input_items[1]
- return len(output_items[0])
-\endcode
-
-The block defines two input floating point streams by setting in_sig
-to "[numpy.float32, numpy.float32]" and a single output float stream
-in out_sig of "[numpy.float32]."
-
-The work function then just adds the two input streams together. The
-streams are input_items[0] and input_items[1]. The block still returns
-the concept of noutput_items like we use in C++, only we get it here
-by getting len(output_items[0]). Because this is a sync_block, we also
-know that the size of the input_items for both streams is the same as
-the size of the output_items vector.
-
-
-
-\section pyblocks_tags Using Stream Tags
-
-Python blocks have access to the stream tag system like their C++
-counterparts. The interface is almost identical except they behave
-just a bit more like we would expect in Python.
-
-To add tags to the data stream, we use the add_item_tag function:
-
-\code
-def work(self, input_items, output_items):
- ....
- add_item_tag(which_output, abs_offset,
- key, value, srcid)
- ....
-\endcode
-
-The abs_offset is an integer of the sample that the tag is attached
-to, and key and value are both PMTs to set the key:value pair of the
-tag information, and the srcid is an optional PMT to define the source
-of the block that generate the tag.
-
-We then can get tags using either the get_tags_in_range or
-get_tags_in_window. Again, like their C++ counter parts, the
-get_tags_in_range uses the absolute item offset numbering (using
-nitems_read) while the get_tags_in_window uses relative offsets within
-the current window of items available to the work function. The main
-difference from the C++ function is that instead of having the first
-argument be a vector where the tags are stored, the Python version
-just returns a list of tags. We would use it like this:
-
-\code
-def work(self, input_items, output_items):
- ....
- tags = get_tags_in_window(which_input, rel_start, rel_end)
- ....
-\endcode
-
-
-
-\section pyblocks_msgs Using Message Passing
-
-Again, like their C++ counterparts, Python blocks can use the
-asynchronous message passing interface. We define output message
-handlers using:
-
-\code
-self.message_port_register_out(pmt.intern("<port name>"))
-\endcode
-
-We can then post messages to this using the message_port_pub function:
-
-\code
-self.message_port_pub(pmt.intern("<port name>"), <pmt message>)
-\endcode
-
-We then register input messages and handlers in similar ways:
-
-\code
-self.message_port_register_in(pmt.intern("<port name>"))
-self.set_msg_handler(pmt.intern("<port name>"), <msg handler function>)
-\endcode
-
-Putting this together below is a very simple example:
-
-\code
-class msg_block(gr.basic_block):
- def __init__(self):
- gr.basic_block.__init__(
- self,
- name="msg_block",
- in_sig=None,
- out_sig=None)
-
- self.message_port_register_out(pmt.intern('msg_out'))
- self.message_port_register_in(pmt.intern('msg_in'))
- self.set_msg_handler(pmt.intern('msg_in'), self.handle_msg)
-
- def handle_msg(self, msg):
- self.message_port_pub(pmt.intern('msg_out'),
- pmt.intern('message received!'))
-\endcode
-
-*/
diff --git a/docs/doxygen/other/stream_tags.dox b/docs/doxygen/other/stream_tags.dox
deleted file mode 100644
index 146218796e..0000000000
--- a/docs/doxygen/other/stream_tags.dox
+++ /dev/null
@@ -1,245 +0,0 @@
-# Copyright (C) 2017 Free Software Foundation, Inc.
-#
-# Permission is granted to copy, distribute and/or modify this document
-# under the terms of the GNU Free Documentation License, Version 1.3
-# or any later version published by the Free Software Foundation;
-# with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.
-# A copy of the license is included in the section entitled "GNU
-# Free Documentation License".
-
-/*! \page page_stream_tags Stream Tags
-
-\section stream_tags_introduction Introduction
-
-GNU Radio was originally a streaming system with no other mechanism to
-pass data between blocks. Streams of data are a model that work well
-for samples, bits, etc., but can lack for control and meta data.
-
-Part of this is solved using the existing message passing interface, which
-allows blocks to subscribe to messages published by any other block in
-the flowgraph (see \ref page_msg_passing). The main drawback to the
-message passing system is that is works asynchronously, meaning that
-there is no guarantee when a message may arrive relative to the data
-stream.
-
-Stream tags are an isosynchronous data stream that runs parallel to
-the main data stream. A stream \a tag is generated by a block's work
-function and from there on flows downstream alongside a particular sample,
-until it reaches a sink or is forced to stop propagating by another
-block.
-
-Stream tags are defined for a specific item in the data stream and are
-formed as a key:value pair. The \a key identifies what the \a value represents
-while the value holds the data that the tag contains. Both \a key and
-\a value are PMTs (\ref page_pmt) where the \a key is a PMT symbol while
-the \a value is any type of PMT and can therefore handle any data we wish
-to pass. An additional part of the tag is the \a srcid, which is a PMT
-symbol and is used to identify the block that created the tag (which
-is usually the block's alias).
-
-
-\section stream_tags_block_api_extensions API Extensions to the gr::block
-
-To enable the stream tags, we have extended the API of gr::block to
-understand \a absolute item numbers. In the data stream model, each
-block's work function is given a buffer in the data stream that is
-referenced from 0 to N-1. This is a \a relative offset into the data
-stream. The absolute reference starts from the beginning of the
-flowgraph and continues to count up with every item. Each input stream
-is associated with a concept of the 'number of items read' and each
-output stream has a 'number of items written'. These are retrieved during
-runtime using the two API calls:
-
-\code
-unsigned long int nitems_read(unsigned int which_input);
-unsigned long int nitems_written(unsigned int which_output);
-\endcode
-
-Each tag is associated with some item in this absolute time scale that
-is calculated using these functions.
-
-Like the rest of the data stream, the number of items read/written are
-only updated once during the call to work. So in a work function,
-nitems_read/written will refer to the state of the data stream at the
-start of the work function. We must therefore add to this value the
-current relative offset in the data stream. So if we are iterating \a
-i over all output items, we would write the stream tag to output ports
-at <em>nitems_written(0)+i</em> for the 0th output port.
-
-
-\section stream_tags_api Stream Tags API
-
-The stream tags API is split into two parts: adding tags to a stream,
-and getting tags from a stream.
-Note that the functions described below are only meant to be accessed
-within a call to general_work/work. While they can be called at other points
-in time by a block, the behavior outside of work is undefined without
-exact knowledge of the item counts in the buffers.
-
-
-\subsection stream_tags_add_item_tag Adding a Tag to a Stream
-
-We add a tag to a particular output stream of the block using:
-
-\li gr::block::add_item_tag: Adds an item tag to a particular output port
-using a gr::tag_t data type or by specifying the tag values.
-
-We can output them to multiple output streams if we want, but to do so
-means calling this function once for each port. This function can be
-provided with a gr::tag_t data type, or each value of the tag can be
-explicitly given.
-
-Again, a tag is defined as:
-
-\li offset: The offset, in absolute item time, of the tag in the data
-stream.
-\li key: the PMT symbol identifying the type of tag.
-\li value: the PMT holding the data of the tag.
-\li srcid: (optional) the PMT symbol identifying the block which
-created the tag.
-
-We can create a gr::tag_t structure to hold all of the above
-information of a tag, which is probably the easiest/best way to do
-it. The gr::tag_t struct is defined as having the same members as in
-the above list. To add a gr::tag_t tag to a stream, use the function:
-
-\code
- void add_item_tag(unsigned int which_output, const tag_t &tag);
-\endcode
-
-The secondary API allows us to create a tag by explicitly listing all
-of the tag information in the function call:
-
-\code
- void add_item_tag(unsigned int which_output,
- uint64_t abs_offset,
- const pmt::pmt_t &key,
- const pmt::pmt_t &value,
- const pmt::pmt_t &srcid=pmt::PMT_F);
-\endcode
-
-
-\subsection stream_tags_get_item_tags Getting tags from a Stream
-
-To get tags from a particular input stream, we have two
-functions we can use:
-
-\li gr::block::get_tags_in_range: Gets all tags from a particular
-input port between a certain range of items (in absolute item time).
-
-\li gr::block::get_tags_in_window: Gets all tags from a particular
-input port between a certain range of items (in relative item time
-within the work function).
-
-The difference between these functions is working in absolute item
-time versus relative item time. Both of these pass back vectors of
-gr::tag_t, and they both allow
-specifying a particular key (as a PMT symbol) to filter against
-(or the fifth argument can be left out to search for all keys).
-Filtering for a certain key reduces the effort inside the work function
-for getting the right tag's data.
-
-For example, this call just returns any tags between the given range of items:
-
-\code
- void get_tags_in_range(std::vector<tag_t> &v,
- unsigned int which_input,
- uint64_t abs_start,
- uint64_t abs_end);
-\endcode
-
-Adding a fifth argument to this function allows us to filter on the
-key \a key.
-
-\code
- void get_tags_in_range(std::vector<tag_t> &v,
- unsigned int which_input,
- uint64_t abs_start,
- uint64_t abs_end,
- const pmt::pmt_t &key);
-\endcode
-
-
-\section stream_tags_propagation Tag Propagation
-
-Tags are propagated downstream from block to block like the normal
-data streams. How tags are actually moved depends on a specific
-propagation policy. We defined three types of policies:
-
-\li All-to-All: all tags from any input port are replicated to all
-output ports
-\li One-to-One: tags from input port \a i are only copied to output
-port \a i (depends on num inputs = num outputs).
-\li Dont: Does not propagate tags. Tags are either stopped here or the
-work function recreates them in some manner.
-
-The default behavior of a block is the 'All-to-All' method of
-propagation.
-
-To set a different propagation policy, use the function:
-
-\code
- void set_tag_propagation_policy(tag_propagation_policy_t p);
-\endcode
-
-See the gr::block::tag_propagation_policy_t documentation for details
-on this enum type.
-
-
-\subsection stream_tags_rate_changes Tag Propagation through Rate Changes
-
-When a tag is propagated through a block that has a rate change, the
-item's offset in the data stream will change. The scheduler uses the
-block's gr::block::relative_rate concept to perform the update on the
-tag's offset value. The relative rate of a block determines the
-relationship between the input rate and output rate. Decimators that
-decimate by a factor of \a D have a relative rate of <em>1/D</em>.
-
-Synchronous blocks (gr::sync_block), decimators (gr::sync_decimator),
-and interpolators (gr::sync_interpolator) all have pre-defined and
-well-understood relative rates. A standard gr::block has a default
-relative rate of 1.0, but this must be set if it does not work this
-way. Often, we use a gr::block because we have no pre-conceived notion
-of the number of input to output items. If it is important to pass
-tags through these blocks that respect the change in item value, we
-would have to use the TPP_DONT tag propagation policy and handle the
-propagation internally.
-
-In no case is the value of the tag modified when propagating through a
-block. This becomes relevant when using \ref page_tagged_stream_blocks.
-
-\section stream_tags_issues Notes on How to Use Tags
-
-Tags can be very useful to an application, and their use is
-spreading. USRP sources generate tag information on the time, sample
-rate, and frequency of the board if anything changes. We have a meta
-data file source/sink (see \ref page_metadata) that use tags to store
-information about the data stream. But there are things to think about
-when using tags in a block.
-
-First, when tags are not being used, there is almost no effect on the
-scheduler. However, when we use tags, we add overhead by getting and
-extracting tags from a data stream. We also use overhead in
-propagating the tags. For each tag, each block must copy a vector of
-tags from the output port(s) of one block to the input port(s) of the
-next block(s). These copy operations can add up.
-
-The key is to minimize the use of tags. Use them when and only when
-necessary and try to provide some control over how tags are generated
-to control their frequency. A good example is the USRP source, which
-generates a time tag. If it generated a tag with every sample, we
-would have thousands of tags per second, which would add a significant
-amount of overhead. This is because if we started at time <em>t0</em> at
-sample rate <em>sr</em>, then after <em>N</em> samples, we know that
-we are now at time <em>t0 + N/sr</em>. So continuously producing new
-tags adds no information.
-
-The main issue we need to deal with in the above situation is when
-there is a discontinuity in the packets received from the USRP. Since
-we have no way of knowing in the flowgraph how many samples were
-potentially lost, we have lost track of the timing information. The
-USRP driver recognizes when packets have been dropped and uses this to
-queue another tag, which allows us to resync. Likewise, any point the
-sample rate or frequency changes, a new tag is issued.
-
-*/
diff --git a/docs/doxygen/other/tagged_stream_blocks.dox b/docs/doxygen/other/tagged_stream_blocks.dox
deleted file mode 100644
index 1a10483323..0000000000
--- a/docs/doxygen/other/tagged_stream_blocks.dox
+++ /dev/null
@@ -1,320 +0,0 @@
-# Copyright (C) 2017 Free Software Foundation, Inc.
-#
-# Permission is granted to copy, distribute and/or modify this document
-# under the terms of the GNU Free Documentation License, Version 1.3
-# or any later version published by the Free Software Foundation;
-# with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.
-# A copy of the license is included in the section entitled "GNU
-# Free Documentation License".
-
-/*! \page page_tagged_stream_blocks Tagged Stream Blocks
-
-\section tsb_introduction Introduction
-
-A tagged stream block is a block that works on streamed, but packetized input data.
-Think of packet data transmission: A data packet consists of N bytes. However, in
-traditional GNU Radio blocks, if we stream N bytes into a block, there's no way of
-knowing the packet boundary. This might be relevant: Perhaps the modulator has to
-prepend a synchronisation word before every packet, or append a CRC. So while some
-blocks don't care about packet boundaries, other blocks do: These are <em>tagged
-stream blocks</em>.
-
-These blocks are different from all the other GNU Radio block types (gr::block,
-gr::sync_block etc.) in that they are driven by the input: The PDU length tag tells the block how to
-operate, whereas other blocks are output-driven (the scheduler tries to fill up the output
-buffer are much as possible).
-
-\subsection tsb_howtheywork How do they work?
-
-As the name implies, tagged stream blocks use tags to identify PDU boundaries.
-On the first item of a streamed PDU, there \em must be a tag with a specific
-key, which stores the length of the PDU as a PMT integer. If anything else, or no tag,
-is on this first item, this will cause the flow graph to crash!
-
-The scheduler then takes care of everything. When the work function is called, it
-is guaranteed to contain exactly one complete PDU and enough space in the output buffer for
-the output.
-
-\subsection tsb_relatestootherblocks How do they relate to other block types (e.g. sync blocks)?
-
-Tagged stream blocks and sync blocks are really orthogonal concepts, and a block could be
-both (gr::digital::ofdm_frame_equalizer_vcvc is such a block). However, because the work
-function is defined differently in these block types, there is no way to derive a block
-from both gr::tagged_stream_block and gr::sync_block.
-
-If a block needs the tagged stream mechanism (i.e. knowing about PDU boundaries), it must be
-derived from gr::tagged_stream_block. If it's also a sync block, it is still possible to
-set gr::block::set_relative_rate(1.0) and/or the fixed rate functions.
-
-The way gr::tagged_stream_block works, it is still beneficial to specify a relative rate,
-if possible.
-
-
-\section tsb_creating Creating a tagged stream block
-
-To create a tagged stream block, the block must be derived from gr::tagged_stream_block.
-Here's a minimal example of how the header file could look:
-\code
-#include <gnuradio/digital/api.h>
-#include <gnuradio/tagged_stream_block.h>
-
-namespace gr {
- namespace digital {
-
- class DIGITAL_API crc32_bb : virtual public tagged_stream_block
- {
- public:
- typedef boost::shared_ptr<crc32_bb> sptr;
-
- static sptr make(bool check=false, const std::string& len_tag_key="packet_len");
- };
-
- } // namespace digital
-} // namespace gr
-
-\endcode
-
-It is very similar to any other block definition. Two things are stand out: First,
-gnuradio/tagged_stream_block.h is included to allow deriving from gr::tagged_stream_block.
-
-The other thing is in the make function: the second argument is a string containing
-the key of the length tags. This is not necessary (the block could get this information
-hard-coded), but the usual way is to allow the user to change this tag, but give a
-default value (in this case, \p packet_len).
-
-The implementation header (*_impl.h) also looks a bit different (again this is cropped to the relevant parts):
-\code
-#include <digital/crc32_bb.h>
-namespace gr {
- namespace digital {
-
- class crc32_bb_impl : public crc32_bb
- {
- public:
- crc32_bb_impl(bool check, const std::string& len_tag_key);
- ~crc32_bb_impl();
-
- int calculate_output_stream_length(const gr_vector_int &ninput_items);
- int work(int noutput_items,
- gr_vector_int &ninput_items,
- gr_vector_const_void_star &input_items,
- gr_vector_void_star &output_items);
- };
-
- } // namespace digital
-} // namespace gr
-\endcode
-
-First, the \p work function signature is new. The argument list looks like that from
-gr::block::general_work() (note: the arguments mean the same, too), but it's called
-\p work like with the other derived block types (such as gr::sync_block). Also, there's a new
-function: \p calculate_output_stream_length() is, in a sense, the opposite function to
-gr::block::forecast(). Given a number of input items, it calculates the required number of
-output items. Note how this relates to the fact that these blocks are input-driven.
-
-These two overrides (\p work() and \p calculate_output_stream_length() ) are what you need
-for most tagged stream blocks. There are cases when you don't need to override the latter
-because the default behaviour is enough, and other cases where you have to override more
-than these two functions. These are discussed in \ref tsb_adv_usage.
-
-Finally, this is part of the actual block implementation (heavily cropped again, to highlight the relevant parts):
-\code
-#include <gnuradio/io_signature.h>
-#include "crc32_bb_impl.h"
-
-namespace gr {
- namespace digital {
-
- crc32_bb::sptr crc32_bb::make(bool check, const std::string& len_tag_key)
- {
- return gnuradio::get_initial_sptr (new crc32_bb_impl(check, len_tag_key));
- }
-
- crc32_bb_impl::crc32_bb_impl(bool check, const std::string& len_tag_key)
- : tagged_stream_block("crc32_bb",
- io_signature::make(2, 1, sizeof (char)),
- io_signature::make(1, 1, sizeof (char)),
- len_tag_key),
- d_check(check)
- {
- }
-
- int
- crc32_bb_impl::calculate_output_stream_length(const gr_vector_int &ninput_items)
- {
- if (d_check) {
- return ninput_items[0] - 4;
- } else {
- return ninput_items[0] + 4;
- }
- }
-
- int
- crc32_bb_impl::work (int noutput_items,
- gr_vector_int &ninput_items,
- gr_vector_const_void_star &input_items,
- gr_vector_void_star &output_items)
- {
- const unsigned char *in = (const unsigned char *) input_items[0];
- unsigned char *out = (unsigned char *) output_items[0];
-
- // Do all the signal processing...
- // Don't call consume!
-
- return new_packet_length;
- }
-
- } // namespace digital
-} // namespace gr
-\endcode
-
-The make function is not different to any other block. The constructor calls
-gr::tagged_stream_block::tagged_stream_block() as expected, but note that it passes the
-key of the length tag to the parent constructor.
-
-The block in question is a CRC block, and it has two modes: It can check the CRC (which is
-then removed), or it can append a CRC to a sequence of bytes. The \p calculate_output_stream_length() function
-is thus very simple: depending on how the block is configured, the output is either 4 bytes
-longer or shorter than the input stream.
-
-The \p work() function looks very similar to any other work function. When writing the
-signal processing code, the following things must be kept in mind:
-- The work function is called for exactly one PDU, and no more (or less) may be processed
-- \p ninput_items contains the exact number of items in this PDU (at every port).
- These items \em will be consumed after \p work() exits.
-- Don't call \p consume() or \p consume_each() yourself! gr::tagged_stream_block will do that
- for you.
-- You can call \p produce() or \p produce_each(), if you're doing something complicated.
- Don't forget to return WORK_CALLED_PRODUCE in that case.
-
-
-\subsection tsb_note_on_tp A note on tag propagation
-
-Despite using tags for a special purpose, all tags that are not the length tag are treated
-exactly as before: use gr::block::set_tag_propagation_policy() in the constructor.
-
-In a lot of the cases, though, you will need to specify set_tag_propagation_policy(TPP_DONT)
-and manually handle the tag propagation in \p work(). This is because the unknown length of
-the PDUs at compile time prohibits us from setting a precise relative rate of the block,
-which is a requirement for automatic tag propagation.
-Only if the tagged stream block is also a sync block (including interpolators and decimators,
-i.e. blocks with an integer rate change), can automatic tag propagation be reliably used.
-
-It is a general rule of GNU Radio blocks that they "properly" propagate tags, whatever this
-means for a specific application.
-
-The CRC block seems to a very simple block, but it's already complicated enough to confuse
-the automatic tag propagation. For example, what happens to tags which are on the CRC? Do
-they get removed, or do they get moved to the last item before the CRC? Also, the input to
-output rate is different for every PDU length.
-
-In this case, it is necessary for the developer to define a tag propagation policy and
-implement it in \p work(). Also, it is good practice to specify that tag propagation policy
-in the blocks documentation.
-
-The actual length tags \em are treated differently, though. Most importantly, you don't have
-to write the new length tag yourself. The key for the output length tag is the same as that
-on the input, if you don't want this, you must override gr::tagged_stream_block::update_length_tags().
-
-
-\section tsb_connecting Connecting regular streaming blocks and tagged stream blocks
-
-From the scheduler's point of view, all blocks are equivalent, and as long as the I/O
-signatures are compatible, all of these blocks can be connected.
-
-However, it is important to note that tagged stream blocks expect correctly tagged
-streams, i.e. a length tag with a number of items at the beginning of every packet.
-If this is not the case, the <em>flow graph will crash</em>.
-The most common cases are discussed separately:
-
-Connecting a tagged stream block to a regular stream block: This is never a problem,
-since regular blocks don't care about the values of the tags.
-
-Connecting regular stream blocks to tagged stream blocks: This will usually not work.
-One solution is to use the gr::blocks:stream_to_tagged_stream adapter block. It will
-periodically add tags at regular intervals, making the input valid for the tagged stream
-block. Make sure to directly connect this block to the tagged stream block, or the
-packet size might be changed to a different value from the tag value.
-
-Mixing block types: This is possible if none of the regular stream blocks change
-the rate. The ofdm_tx and ofdm_rx hierarchical blocks do this.
-
-
-\section tsb_adv_usage Advanced Usage
-
-It is generally recommended to read the block documentation of gr::tagged_stream_block.
-
-A few special cases are described here:
-
-\subsection tsb_multiplelentags Multiple length tags
-
-In some cases, a single tag is not enough. One example is the OFDM receiver: one OFDM frame contains a certain number of OFDM symbols, and another number of bytes--these numbers are only
-very loosely related, and one cannot be calculated from the other.
-
-gr::digital::ofdm_serializer_vcc is such a block. It is driven by the number of OFDM frames,
-but the output is determined by the number of complex symbols. In order to use multiple length
-tag keys, it overrides gr::tagged_stream_block::update_length_tags().
-
-\subsection tsb_backtogrblock Falling back to gr::block behaviour
-
-If, at compile-time, it is uncertain whether or not a block should be a
-gr::tagged_stream_block, there is the possibility of falling back to gr::block behaviour.
-
-To do this, simple don't pass an empty string as length tag key. Instead of crashing,
-a tagged stream block will behave like a gr::block.
-
-This has some consequences: The work function must have all the elements of a
-gr::block::general_work() function, including calls to consume(). Because such a block must
-allow both modes of operation (PDUs with tags, and infinite-stream), the work function
-must check which mode is currently relevant. Checking if
-gr::tagged_stream_block::d_length_tag_key_str is empty is a good choice.
-
-gr::digital::ofdm_cyclic_prefixer implements this.
-
-\subsection tsb_otherwaysdetermineninput Other ways to determine the number of input items
-
-If the number of input items is not stored as a pmt::pmt_integer, but there is a way to determine
-it, gr::tagged_stream_block::parse_length_tags() can be overridden to figure out the length
-of the PDU.
-
-\section tsb_examples Examples
-
-\subsection tsb_CRC32 CRC32
-
-Block: gr::digital::crc32_bb
-
-This is a very simple block, and a good example to start with.
-
-\subsection tsb_ofdmeq OFDM Frame Equalizer
-
-Block: gr::digital::ofdm_frame_equalizer_vcvc
-
-This block would be a sync block if tagged stream blocks didn't exist. It also uses more
-than one tag to determine the output.
-
-\subsection tsb_muxer Tagged Stream Muxer
-
-Block: gr::blocks::tagged_stream_mux
-
-Use this to multiplex any number of tagged streams.
-
-\subsection tsb_ofdmprefixer Cyclic Prefixer (OFDM)
-
-Block: gr::digital::ofdm_cyclic_prefixer
-
-This block uses the gr::block behaviour fallback.
-
-\section tsb_troubleshooting Troubleshooting
-
-<b>My flow graph crashes with the error message "Missing length tag".</b>
-
-This means the input of a tagged stream block was not correctly tagged.
-The most common cause is when connecting a regular streaming block to a tagged
-stream block. You can check the log output for the item number and port where
-this happened.
-
-
-
-
-
-*/
diff --git a/docs/doxygen/other/thread_affinity.dox b/docs/doxygen/other/thread_affinity.dox
deleted file mode 100644
index 405477b8d3..0000000000
--- a/docs/doxygen/other/thread_affinity.dox
+++ /dev/null
@@ -1,132 +0,0 @@
-# Copyright (C) 2017 Free Software Foundation, Inc.
-#
-# Permission is granted to copy, distribute and/or modify this document
-# under the terms of the GNU Free Documentation License, Version 1.3
-# or any later version published by the Free Software Foundation;
-# with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.
-# A copy of the license is included in the section entitled "GNU
-# Free Documentation License".
-
-/*! \page page_affinity Block Thread Affinity and Priority
-
-\section affinity Block Thread Affinity
-
-In the thread-per-block scheduler, you can set the block's core
-affinity. Each block can be pinned to a group cores or be set back
-to use the standard kernel scheduler.
-
-The implementation is done by adding new functions to the threading
-section of the gnuradio-runtime library:
-
-\code
- gr::thread::gr_thread_t get_current_thread_id();
- void thread_bind_to_processor(unsigned int n);
- void thread_bind_to_processor(const std::vector<unsigned int> &mask);
- void thread_bind_to_processor(gr::thread::gr_thread_t thread, unsigned int n);
- void thread_bind_to_processor(gr::thread::gr_thread_t thread, const std::vector<unsigned int> &mask);
- void thread_unbind();
- void thread_unbind(gr::thread::gr_thread_t thread);
-\endcode
-
-The ability to set a thread's affinity to a core or groups of cores is
-not implemented in the Boost thread library, and so we have made our
-own portability library. In particular, the gr::thread::gr_thread_t type is
-defined as the thread type for the given system. The other functions
-are designed to be portable as well by calling the specific
-implementation for the thread affinity for a particular platform.
-
-There are functions to set a thread to a group of cores. If the thread
-is not given, the current thread is used. If a single number is
-passed, only that core is set (this is equivalent to a core mask with
-just a single value).
-
-Similarly, there are functions to unset the affinity. This practically
-implements the setting of the thread's affinity to all possible
-cores. Again, the function that does not take a thread argument unsets
-the affinity for the current thread.
-
-NOTE: Not available on OSX.
-
-
-\subsection affinity_api GNU Radio Block API
-
-Each block has two new data members:
-
-- threaded: a boolean value that is true if the block is attached to a
- thread.
-- thread: a gr::thread::gr_thread_t handle to the block's thread.
-
-A block can set and unset its affinity at any time using the
-following member functions:
-
-- gr::block::set_processor_affinity(const std::vector<int> &mask)
-- gr::block::unset_processor_affinity()
-
-Where \p mask is a vector of core numbers to set the thread's affinity
-to.
-
-The current core affinity can be retrieved using the member function:
-
-- gr::block::processor_affinity()
-
-When set before the flowgraph is started, the scheduler will set the
-thread's affinity when it is started. When already running, the
-block's affinity will be immediately set.
-
-
-\subsection affinity_api_hier Setting Affinity for a gr::hier_block2
-
-A hierarchical block (gr::hier_block2) also has a concept of setting
-the block thread affinity. Because the hierarchical block itself does
-no work and just encapsulates a set of blocks, setting the
-hierarchical block's affinity individually sets all blocks inside it
-to that affinity setting.
-
-The gr::hier_block2 class supports the same API interface to the block
-thread affinity:
-
-- gr::hier_block2::set_processor_affinity(const std::vector<int> &mask)
-- gr::hier_block2::unset_processor_affinity()
-- gr::hier_block2::processor_affinity()
-
-Setting and unsetting the affinity does so recursively for every block
-in the hierarchical block. It is of course possible to individually set
-the affinity to any block underneath the hierarchical block. However,
-in this case, note that when asking for the current affinity value
-using 'processor_affinity()', the code returns the current processor
-affinity value of only the first block.
-
-
-\subsection affinity_api_grc GRC Access
-
-GRC supports the setting of the thread core affinity in a block's
-options. Each block now has a field 'Core Affinity' that accepts a
-vector (list) of integers and sets the affinity after the block is
-constructed.
-
-Note that GRC does not provide a callback function for changing the
-thread core affinity while the flowgraph is running.
-
-
-
-\section priority_api Setting Thread Priority
-
-Similarly to setting the core affinity for a given block, we can also
-set the thread priority. This concept adds three new function calls to
-all blocks:
-
-\li gr::block::set_thread_priority(int priority): Sets the current thread priority.
-\li gr::block::active_thread_priority(): Gets the active priority for the thread.
-\li gr::block::thread_priority(): Gets the stored thread priority.
-
-The range of the thread priority might be system dependent, so look to
-your system/OS documentation. Linux specifies this range in
-\b sched_setscheduler as a value between 1 and 99 where 1 is the lowest
-priority and 99 is the highest. POSIX systems can retrieve these min
-and max values using \b sched_get_priority_min and \b
-sched_get_priority_max and may only allow 32 distinct values to be
-set.
-
-NOTE: Not available on Windows or OSX.
-
-*/
diff --git a/docs/doxygen/other/usage.dox b/docs/doxygen/other/usage.dox
index d0872c0a03..c02b88c3a0 100644
--- a/docs/doxygen/other/usage.dox
+++ b/docs/doxygen/other/usage.dox
@@ -1,4 +1,4 @@
-# Copyright (C) 2017 Free Software Foundation, Inc.
+# Copyright (C) 2018 Free Software Foundation, Inc.
#
# Permission is granted to copy, distribute and/or modify this document
# under the terms of the GNU Free Documentation License, Version 1.3
@@ -9,44 +9,39 @@
/*! \page page_usage Usage Manual
-Note: Once built, check out <a href="https://www.gnuradio.org/" target="_blank">gnuradio.org</a> for
-more tutorials on using the software system and examples.
+Note: The Usage Manual has been moved to the <a href="https://wiki.gnuradio.org" target="_blank">GNU Radio wiki</a>, along with all other documentation that is not specific to a block/class/function/etc.
-<b>Getting Started</b>
+For viewing offline, snapshots of these wiki pages are periodically exported and stored in gnuradio/docs/usage-manual/
+
+Here are links to the various Usage Manual pages (they are also linked on the home page of the wiki):
-\li \subpage build_guide - Installation notes, dependencies etc.
-\li \subpage page_exploring_gnuradio
-\li \subpage page_operating_fg
+<b>Getting Started</b>
+\li <a href="https://wiki.gnuradio.org/index.php/Handling_Flowgraphs" target="_blank">Handling Flowgraphs</a>
+\li <a href="https://wiki.gnuradio.org/index.php/GNURadioCompanion" target="_blank">GNU Radio Companion (GRC)</a>
<b>Metadata and Messages</b>
-\li \subpage page_pmt
-\li \subpage page_metadata
-\li \subpage page_msg_passing
-\li \subpage page_stream_tags
-\li \subpage page_tagged_stream_blocks
+\li <a href="https://wiki.gnuradio.org/index.php/Polymorphic_Types_(PMTs)" target="_blank">Polymorphic Types (PMTs)</a>
+\li <a href="https://wiki.gnuradio.org/index.php/Metadata_Information" target="_blank">Metadata Information</a>
+\li <a href="https://wiki.gnuradio.org/index.php/Message_Passing" target="_blank">Message Passing</a>
+\li <a href="https://wiki.gnuradio.org/index.php/Stream_Tags" target="_blank">Stream Tags</a>
+\li <a href="https://wiki.gnuradio.org/index.php/Tagged_Stream_Blocks" target="_blank">Tagged Stream Blocks</a>
<b>Advanced Development Topics</b>
-\li \subpage page_logger
-\li \subpage page_perf_counters
-\li \subpage page_affinity
-\li \subpage page_prefs
-\li \subpage page_python_blocks
+\li <a href="https://wiki.gnuradio.org/index.php/Logging" target="_blank">Logging</a>
+\li <a href="https://wiki.gnuradio.org/index.php/Performance_Counters" target="_blank">Performance Counters</a>
+\li <a href="https://wiki.gnuradio.org/index.php/Block_Thread_Affinity_and_Priority" target="_blank">Block Thread Affinity and Priority</a>
+\li <a href="https://wiki.gnuradio.org/index.php/Configuration_Files" target="_blank">Configuration Files</a>
+\li <a href="https://wiki.gnuradio.org/index.php/Types_of_Blocks" target="_blank">Types of Blocks</a>
<b>Signal Processing and Digital Communications</b>
-\li \subpage page_pfb
-\li \subpage page_ofdm
-\li \subpage page_packet_data
-
-<b>Out-of-tree Modules</b>
-
-\li \subpage page_oot_config
+\li <a href="https://wiki.gnuradio.org/index.php/Polyphase_Filterbanks" target="_blank">Polyphase Filterbanks</a>
<b>VOLK</b>
-\li \subpage volk_guide - How to incorporate and use VOLK in GNU Radio blocks
+\li <a href="https://wiki.gnuradio.org/index.php/VOLK_Guide" target="_blank">VOLK Guide</a>
*/
diff --git a/docs/doxygen/other/volk_guide.dox b/docs/doxygen/other/volk_guide.dox
deleted file mode 100644
index 1f8f128e4b..0000000000
--- a/docs/doxygen/other/volk_guide.dox
+++ /dev/null
@@ -1,160 +0,0 @@
-# Copyright (C) 2017 Free Software Foundation, Inc.
-#
-# Permission is granted to copy, distribute and/or modify this document
-# under the terms of the GNU Free Documentation License, Version 1.3
-# or any later version published by the Free Software Foundation;
-# with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.
-# A copy of the license is included in the section entitled "GNU
-# Free Documentation License".
-
-/*! \page volk_guide Instructions for using VOLK in GNU Radio
-
-Note: Many blocks have already been converted to use VOLK in their calls, so
-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 volk_intro Introduction
-
-VOLK is the Vector-Optimized Library of Kernels. It is a library that
-contains kernels of hand-written SIMD code for different mathematical
-operations. Since each SIMD architecture can be greatly different and
-no compiler has yet come along to handle vectorization properly or
-highly efficiently, VOLK approaches the problem differently. For each
-architecture or platform that a developer wishes to vectorize for, a
-new proto-kernel is added to VOLK. At runtime, VOLK will select the
-correct proto-kernel. In this way, the users of VOLK call a kernel for
-performing the operation that is platform/architecture agnostic. This
-allows us to write portable SIMD code.
-
-VOLK kernels are always defined with a 'generic' proto-kernel, which
-is written in plain C. With the generic kernel, the kernel becomes
-portable to any platform. Kernels are then extended by adding
-proto-kernels for new platforms in which they are desired.
-
-A good example of a VOLK kernel with multiple proto-kernels defined is
-the volk_32f_s32f_multiply_32f_a. This kernel implements a scalar
-multiplication of a vector of floating point numbers (each item in the
-vector is multiplied by the same value). This kernel has the following
-proto-kernels that are defined for 'generic,' 'avx,' 'sse,' and 'neon'
-
-\code
- void volk_32f_s32f_multiply_32f_a_generic
- void volk_32f_s32f_multiply_32f_a_sse
- void volk_32f_s32f_multiply_32f_a_avx
- void volk_32f_s32f_multiply_32f_a_neon
-\endcode
-
-These proto-kernels means that on platforms with AVX support, VOLK can
-select this option or the SSE option, depending on which is faster. If
-all else fails, VOLK can fall back on the generic proto-kernel, which
-will always work.
-
-See <a
-href="http://libvolk.org</a> for details on the VOLK naming scheme.
-
-
-\section volk_alignment Setting and Using Memory Alignment Information
-
-For VOLK to work as best as possible, we want to use memory-aligned
-SIMD calls, which means we have to have some way of knowing and
-controlling the alignment of the buffers passed to gr_block's work
-function. We set the alignment requirement for SIMD aligned memory
-calls with:
-
-\code
- const int alignment_multiple =
- volk_get_alignment() / output_item_size;
- set_alignment(std::max(1,alignment_multiple));
-\endcode
-
-The VOLK function 'volk_get_alignment' provides the alignment of the
-the machine architecture. We then base the alignment on the number of
-output items required to maintain the alignment, so we divide the
-number of alignment bytes by the number of bytes in an output items
-(sizeof(float), sizeof(gr_complex), etc.). This value is then set per
-block with the 'set_alignment' function.
-
-Because the scheduler tries to optimize throughput, the number of
-items available per call to work will change and depends on the
-availability of the read and write buffers. This means that it
-sometimes cannot produce a buffer that is properly memory
-aligned. This is an inevitable consequence of the scheduler
-system. Instead of requiring alignment, the scheduler enforces the
-alignment as much as possible, and when a buffer becomes unaligned,
-the scheduler will work to correct it as much as possible. If a
-block's buffers are unaligned, then, the scheduler sets a flag to
-indicate as much so that the block can then decide what best to
-do. The next section discusses the use of the aligned/unaligned
-information in a gr_block's work function.
-
-
-\section volk_work Calling VOLK kernels in Work()
-
-The buffers passed to work/general_work in a gr_block are not
-guaranteed to be aligned, but they will mostly be aligned whenever
-possible. When not aligned, the 'is_unaligned()' flag will be set so
-the scheduler knows to try to realign the buffers. We actually make
-calls to the VOLK dispatcher, which is mainly designed to check the
-buffer alignments and call the correct version of the kernel for
-us. From the user-level view of VOLK, calling the dispatcher allows us
-to ignore the concept of aligned versus unaligned. This looks like:
-
-\code
-int
-gr_some_block::work (int noutput_items,
- gr_vector_const_void_star &input_items,
- gr_vector_void_star &output_items)
-{
- const float *in = (const float *) input_items[0];
- float *out = (float *) output_items[0];
-
- // Call the dispatcher to check alignment and call the _a or _u
- // version of the kernel.
- volk_32f_something_32f(out, in, noutput_items);
-
- return noutput_items;
-}
-\endcode
-
-
-
-\section volk_tuning Tuning VOLK Performance
-
-VOLK comes with a profiler that will build a config file for the best
-SIMD architecture for your processor. Run volk_profile that is
-installed into $PREFIX/bin. This program tests all known VOLK kernels
-for each architecture supported by the processor. When finished, it
-will write to $HOME/.volk/volk_config the best architecture for the
-VOLK function. This file is read when using a function to know the
-best version of the function to execute.
-
-\subsection volk_hand_tuning Hand-Tuning Performance
-
-If you know a particular architecture works best for your processor,
-you can specify the particular architecture to use in the VOLK
-preferences file: $HOME/.volk/volk_config
-
-The file looks like:
-
-\code
- volk_<FUNCTION_NAME> <ARCHITECTURE>
-\endcode
-
-Where the "FUNCTION_NAME" is the particular function that you want to
-over-ride the default value and "ARCHITECTURE" is the VOLK SIMD
-architecture to use (generic, sse, sse2, sse3, avx, etc.). For
-example, the following config file tells VOLK to use SSE3 for the
-aligned and unaligned versions of a function that multiplies two
-complex streams together.
-
-\code
- volk_32fc_x2_multiply_32fc_a sse3
- volk_32fc_x2_multiply_32fc_u sse3
-\endcode
-
-\b Tip: if benchmarking GNU Radio blocks, it can be useful to have a
-volk_config file that sets all architectures to 'generic' as a way to
-test the vectorized versus non-vectorized implementations.
-
-*/