FAQ: Difference between revisions

From GNU Radio
Jump to navigation Jump to search
mNo edit summary
(→‎Who runs GNU Radio?: fix broken link)
 
(43 intermediate revisions by 9 users not shown)
Line 1: Line 1:
= Frequently Asked Questions =
<b>Frequently Asked Questions</b>
 
Please add questions if appropriate, but make sure you've read the guidelines at the end of this page.


== Getting Started ==
== Getting Started ==
Line 9: Line 7:
Check out our page [[WhatIsGR|What is GNU Radio?]] for an introduction to what GNU Radio is and why you would want to use it.
Check out our page [[WhatIsGR|What is GNU Radio?]] for an introduction to what GNU Radio is and why you would want to use it.


=== How do I get GNU Radio? ===
=== How do I get / install GNU Radio? ===


We strongly encourage you to use your distro’s package manager. Debian/Ubuntu and Fedora/RedHat as well as many of the other popular Linux distros keep these packages well up to date. For Mac OS X, using Macports is strongly encouraged.
See [[InstallingGR|Installing GNU Radio]] for details.


See our [http://gnuradio.org/redmine/projects/gnuradio/wiki/InstallingGR installation page] for details of some of these install procedures or information about your specific system. If there’s a good reason that you need to keep yourself on the cutting edge of the GNU Radio development, you can use our [http://gnuradio.org/redmine/projects/pybombs/wiki PyBOMBS] install system on Debian and RedHat based Linux distros. Otherwise, you can try your hand with building directly from source.
=== Which operating systems are supported? ===


=== Which operating systems are supported? Does GNU Radio run on Windows or Mac OS X? What about 32, 64 Bits? ===
We develop and test on Linux, Mac OS and Windows. See [[InstallingGR|Installing GNU Radio]]!


We mostly develop under Linux, and we've gotten GNU Radio to run under most current Linux distros. The best support will be for the latest supported versions of Ubuntu (their Long Term Support versions) and Fedora. Other common distros like Debian are well-maintained and will generally work fine. For Redhat and CentOS, you may find yourself needing to install some dependencies by hand. We highly recommend the use of PyBOMBS with these distros.
Among these three operating systems, Linux is the one that most GNU Radio developers agree on. That does not depreciate the other two.


GNU Radio is also maintained on OS X. We have installation instructions and can help doing source builds on OS X. However, we highly recommend that you use the Macports installation of GNU Radio to make sure all of the dependencies are taken care of properly.
GNU Radio supports both 32- and 64-bit operating systems. Since it's a signal processing framework making heavy use of math functionality of modern processors, 32 bit platforms are becoming rarer; if you want to do high-rate signal processing, a 32 bit laptop might no longer be the platform of choice.
 
GNU Radio will build and run under Windows. However, we don’t have direct, maintained support for Windows and few of us can help you with Windows issues. We hope to have better support in the future, but in the meantime, there are plenty of people with various levels of success working under Windows that you can contact through the discuss-gnuradio Mailing List.
 
GNU Radio supports both 32- and 64-bit operating systems.
 
For processor support, we generally develop and build on Intel x86 architectures. These processors have the best support for features and speed. However, we are actively developing our support and capabilities on ARM processors, currently only those running the ARMv7 instruction set. Older ARM processors with ARMv6 support have been known to work, but we have no direct support for them. They tend to be severely underpowered for math and signal processing for any serious GNU Radio app. We will be developing support for ARMv8. We also have a [[Embedded|limited list of embedded devices and development kits]] that we are able to support.


=== What are the system requirements (minimum power, etc.)? ===
=== What are the system requirements (minimum power, etc.)? ===
Line 33: Line 25:
'''Hardware requirements''' basically depend on what you want to do. A modern PC/laptop computer is usually up to most tasks such as receiving broadcast signals, doing audio frequency processing, and many narrowband digital signals.
'''Hardware requirements''' basically depend on what you want to do. A modern PC/laptop computer is usually up to most tasks such as receiving broadcast signals, doing audio frequency processing, and many narrowband digital signals.


When dealing with telecommunication signals, however, sample rates of over 5 Msamples/s are not uncommon. The average embedded ARM platform is generally not up to that task. Even rather modern hardware often meets its limits when it comes to doing things in realtime; '''it all depends on your processing requirements''', GNU Radio is only the platform to perform these computationally intensive tasks.
When dealing with telecommunication signals, however, sample rates of over 5 Msamples/s are not uncommon. Even rather modern hardware often meets its limits when it comes to doing things in realtime; '''it all depends on your processing requirements''', GNU Radio is only the platform to perform these computationally intensive tasks.


=== How do I install GNU Radio? ===
=== I built GNU Radio from source, but some components seem to be missing. ===


See the [[InstallingGR|installation guide]]. Unless you have good reasons, make sure you are installing a [[ChangeSets|recent version]].
Missing components are usually seen because blocks are missing from GRC. This usually only happens when you did a source build. We generally recommend you don't build GNU Radio from source without an explicit need to do so; for almost all platforms, [[InstallingGR|installing GNU Radio]] from packages is much easier, less error prone and should be preferred.


=== I installed GNU Radio, but some components seem to be missing? ===
You can check the installed GNU Radio components by running <code>gnuradio-config-info --enabled-components</code> (Or, for a nicer formatting, <code>gnuradio-config-info --enabled-components | sed 's/;/\n/g'</code>).


Missing components are usually seen because blocks are missing from GRC. This usually only happens when you did a source build. After running cmake, you might see something like this at the end of CMake's output (this list is heavily cropped for simplicity, it is much longer in reality):
After running <code>cmake</code>, you might see something like this at the end of CMake's output (this list is heavily cropped for simplicity, it is much longer in reality):


<pre>-- ######################################################
<pre>
-- # Gnuradio enabled components                        
-- ######################################################
-- # Gnuradio enabled components
-- ######################################################
-- ######################################################
--  * testing-support
--  * python-support
--  * python-support
--  * testing-support
[…………]
--  * volk
--  * gr-vocoder
--  * doxygen
--  * * codec2
--   * gnuradio-runtime
--  * * freedv
--  * gr-blocks
--  * * gsm
--  * gnuradio-companion
--  * gr-fec
--  * gr-fft
--  * gr-filter
--  * [...]
--
-- ######################################################
-- ######################################################
-- # Gnuradio disabled components                      
-- # Gnuradio disabled components
-- ######################################################
-- ######################################################
--  * gr-ctrlport
--  * gr-ctrlport
--  * gr-dtv
--  * gr-dtv
--  * gr-atsc
--  * gr-atsc
--  * gr-wxgui</pre>
</pre>
If the components you are missing are listed under the 'disabled' components, there's your problem.<br />
 
There are two reasons why components are disabled:<br />
If the components you are missing are listed under the 'disabled' components, there's your problem.
- You disabled them yourself, e.g. by supplying a `-DENABLE_GR_DTV=OFF` switch to CMake.<br />
 
- The component was automatically enabled because CMake could not find certain dependencies.
There are two reasons why components are disabled:
 
* You disabled them yourself, e.g. by supplying a `-DENABLE_GR_DTV=OFF` switch to CMake.
* The component was automatically disabled because CMake could not find certain dependencies.


In both cases, you can read the CMake output to see what the reason is. If dependencies are missing, you might have to install developer packages for something (on Debian and Ubuntu systems, these are packages ending with -dev, on Fedora, they end with -devel). Consult the build manual for which dependencies are required.
In both cases, you can read the CMake output to see what the reason is. If dependencies are missing, you might have to install developer packages for something (on Debian and Ubuntu systems, these are packages ending with -dev, on Fedora, they end with -devel). Consult the build manual for which dependencies are required.


If you don't understand or know how to do this, consider installing precompiled binaries. Usually, they will pull in all the required dependencies.
If you don't understand or know how to do this, consider [[InstallingGR|installing precompiled binaries]]. Usually, they will pull in all the required dependencies.


=== Which Radio Hardware is supported? ===
=== Which Radio Hardware is supported? ===


There is a growing list of radio front ends for software radio uses. It is difficult to keep up with, and support for a particular radio front end in GNU Radio is generally left to the hardware manufacturer. The Ettus Research USRP product line, supported by UHD, is the exception since the USRP and GNU Radio have had a long history of developing and working together. For other hardware you are interested in, please check with the manufacturer and then ask on the discuss-gnuradio mailing list if you can't find the answer elsewhere.
There is a growing list of radio front ends for software radio uses. It is difficult to keep up with! The Ettus Research USRP product line, supported by UHD, is the exception since the USRP and GNU Radio have had a long history of developing and working together. For hardware that has a SoapySDR driver, GNU Radio offers a generic interface. See also [[Hardware]].


=== Can you suggest any reading material for DSP/SDR/Digital Comms? ===
=== Can you suggest any reading material for DSP/SDR/Digital Comms? ===
Line 82: Line 73:
We have a wiki page for this: [[SuggestedReading]]
We have a wiki page for this: [[SuggestedReading]]


<!-- Marker section 2 -->
== Using GNU Radio ==


-----
=== How do I start? What's the first thing to do after installation? ===


== About GNU Radio (Internal, Structure...) ==
Start with our [[Tutorials]] to learn your way around GNU Radio. They are divided into levels of user experience.


=== What is GNU Radio? ===
=== Where can I find a list of GNU Radio blocks? ===


Check out our page [[WhatIsGR|What is GNU Radio?]] for an introduction to what GNU Radio is and why you would want to use it.
All GNU Radio blocks are listed in [[:Category:Block_Docs|Block Docs]].


=== How is the GNU Radio source tree structured? ===
When using GNU Radio Companion, blocks are also listed in the ''Block Tree'' sidebar. You can use the search feature of GNU Radio Companion (a magnifying glass, and the search text box, both highlighted in green below) to find blocks by name:


The code layout was modified for 3.7, and we'll focus just on that. Basically, GNU Radio consists of the runtime scheduler and the main block class structure that lives in gnuradio-runtime. Outside of gnuradio-runtime are our &quot;top-level (or in-tree) components&quot; that consist mostly of blocks for building GNU Radio flow graphs as well as supporting code and quality assurance (QA) code for the blocks.
[[File:Highlight-search.png]]


The top level component structures are all the same, and only gnuradio-runtime looks different, though there are similar structural aspects to the code. A top-level component also shares the same basic structure as any Out of Tree (OOT) module we would create to build a project that works with GNU Radio (<code>gr_modtool</code> works for in-tree components as well as OOTs).
=== What does ''sample rate'' mean in GNU Radio? ===


blocks, flowgraph, top block
First off: You need to understand the general principle of "Sampling Rate" and the sampling theorem before you do anything with GNU Radio. See [[SuggestedReading]].


=== How is a GNU Radio application structured? ===
For a tutorial on sample rate, see the [[Sample_Rate_Tutorial|Sample Rate Tutorial]].


A GNU Radio program is structured as a <code>flowgraph</code> that consists of blocks. As mentioned, the blocks can be found in the GNU Radio top-level components or any OOT modules you’ve installed alongside GNU Radio. We first create a top_block that’s the physical object that contains the full flowgraph. Blocks are then connected together by connecting streaming outputs to inputs or connecting message ports together.
=== My flowgraph is too slow. What can I do to make it faster? My hardware signals underflows, overflows or dropped samples. ===


A must-read for everyone is our introduction to the [[TutorialsCoreConcepts|core concepts of GNU Radio]]. Also a good read is Tom's [http://www.trondeau.com/blog/2013/9/15/explaining-the-gnu-radio-scheduler.html explanation of the GNU Radio scheduler]
The most common answer to that question is: It's as fast as it ''can'' run. If your signal processing application really needs that much computing, you need more computational power.


=== What are &quot;items&quot; in a flowgraph? ===
There are, however, some cases where your problems can be helped:


(See also the [[TutorialsCoreConcepts|core concepts of GNU Radio]] tutorial).
# If your signal processing relies on a bandwidth that is substantially smaller than your nyquist bandwidth (in case of complex sampling: sampling rate, in case of real sampling: 0.5 * sampling rate) use a lower sampling rate as early as possible. Often, you could also tell your hardware to produce a lower sample rate.
# If your signal processing could as well be done offline (instead of in realtime), write your signal to file (using file_sink) and load it from there in another flowgraph (using file_source)


GNU Radio blocks work off a concept of &quot;items&quot;. We are tempted to think of signal processing applications in terms of &quot;samples&quot;, but this isn't expressive enough for all of the different situations we work with in GNU Radio. Sometimes, a block may be operating off samples, symbols, bits, bytes, packets, frames, or other types of data structures. We generalize this into the name <code>items</code>. Blocks process items. We have to know what those items mean to each block.
=== When do I use a Throttle block? ===


The block is generalized such that it either knows what type of item it deals with (like a multiply_cc block works explicitly off complex data streams) or we tell it what data type to use, like a file source or sink. The block is interested in two things. First, the data type itself if it’s doing operations directly on the data. The complex multiply block needs to know the data type of the stream because doing complex multiplies is very different than just floating point multiplies. In other situations, like the file sink and source blocks, they just need to know how many bytes to write or read from a file. They don’t care about the data structure, just the size of the data structure. So we can tell them the size, in bytes, of the item type. In the case of reading from a complex file, we give it the size of a complex item, which is 64 bits.
Almost never!


GNU Radio uses some convenient nomenclature for defining and using different items. For blocks that explicitly work off the data type, we suffix the block’s name with information about the data streams. Sources and sinks will typically have a single letter suffix while blocks with inputs and outputs usually use two letters. For sources, this letter describes the data type that the source will produce; for sinks, it’s the data type of the stream coming into it. For other blocks, the two letters tell us the input stream type and the output stream type. There are occasions when a block has three letters, for which we would look at the documentation for the block to describe what the third letter means. For filters, for example, it’s the data type of the taps used in the filter. Sometimes we use a ‘v’ in the suffix to let us know that this block works on vectors of items.
GNU Radio is written and designed for real-time streaming signal processing that interfaces with real hardware systems. A GNU Radio application attempts to source data from a hardware source and sink data to a hardware sink as quickly as possible. That means that we are rate limited by the hardware, which will either provide or allow us to push data between GNU Radio and the hardware system based on the rate of the hardware.


The list of item type suffixes is:<br />
For other cases, see [[Sample_Rate_Tutorial#When_there_is_no_hardware_block]].
c: complex (single-precision float)<br />
z: complex (double-precision float)<br />
f: single-precision float<br />
d: double-precision float<br />
i: integers (32 bits)<br />
s: shorts (16 bits)<br />
b: bits or bytes


The ‘b’ suffix can mean either packed bytes (a full byte or some number of defined bits used for data) or unpacked bytes (1 bit per byte, or in some cases multiple bits). Since the GNU Radio system only really cares about the number of bytes of an item, there is no other protection we can easily place on these blocks. It is up to the block to define and document whether it takes in packed or unpacked bytes.
=== What is the file format of a file_sink? How can I read files produced by a file sink? ===


For blocks that take in the item size as part of their constructor, GNU Radio defines some convenient constants for Python use that map to a sizeof(x) in C++.
See the relevant section in the [[File_Sink#Handling_File_Sink_data|File Sink block documentation]].


* gr.sizeof_gr_complex: sizeof(gr_complex)
== GNU Radio Companion ==
* gr.sizeof_float: sizeof(float)
* gr.sizeof_double: sizeof(double)
* gr.sizeof_int: sizeof(int)
* gr.sizeof_short: sizeof(short)
* gr.sizeof_char: sizeof(char)


=== Why use Python? It’s so slow! ===
For a tutorial on GRC, see the guided [[Tutorials]]; start with [[Your_First_Flowgraph|Your First Flowgraph]]!


It’s not really that bad. In fact, good Python programming practices are as good as and sometimes better than naive C/C++ programming. Working harder at the C++ code, however, is still going to be better, obviously.
<!-- Marker section 4 -->


More importantly, this isn’t the right question to ask. GNU Radio uses Python as a scripting language, not (usually) for runtime signal processing (see the question on Python blocks, too). All of GNU Radio blocks and the scheduler are written in C++. We export the interface into Python to allow us to use that as a scripting language to make it easy to put flowgraphs together. At runtime, Python gets out of the way unless you’ve programmed something yourself in Python, which is common for user interface, controls, and interaction, which are not in the main runtime path, anyways.
=== How can I take a picture of a Flow Graph ===


=== What is a Python Block? Can I write actual processing blocks in Python? ===
Please don't use your camera to take a picture of the screen! Instead, use the built-in "Screen Capture" functionality:


There is the concept of writing and using a block in pure Python, which we call Python blocks. There’s an interface between the Python domain and the runtime flow graph that allows us to write our blocks in pure Python and connect them up with other GNU Radio blocks. Using this feature can be nice for quick prototyping, demos, and debugging, but then we get into the real question of Python’s performance. Using good Python programming techniques such as relying on Numpy and Scipy routines will help a lot here. But even still, don’t expect a Python block to be your deployed runtime version of the code. You will, quite probably, eventually want to translate this block into a real C++ block. The exceptions are for slower parts of the graph, such as control, measurements, or even packet-level processing operating on chunks of bytes instead of samples. Measurements and profiling are your friend.

[[File:Screencap.png]]


=== What's the logic behind GNU Radio versions? ===
== About GNU Radio (Internal, Structure...) ==


We use a standard version numbering scheme in GNU Radio: Major.API.Minor.Patch. Please see the explanation on our [[ChangeSets]] page.
=== How is the GNU Radio source tree structured? ===


=== Why can't we do loops? ===
Basically, GNU Radio consists of the runtime scheduler and the main block class structure that lives in gnuradio-runtime. Outside of gnuradio-runtime are our top-level (or in-tree) components that consist mostly of blocks for building GNU Radio flow graphs as well as supporting code and quality assurance (QA) code for the blocks.


A lot of users come into the project looking to experiment, including building known algorithms like phase-locked loops (PLLs). GNU Radio comes with each of the blocks to build your own PLL in a flowgraph, like a multiplier, lowpass filter, and VCO. But you try to put it together and GNU Radio tells you it won’t work. That the flow graphs don’t allow you to do loops. Why? PLLs are fundamental to radio and signal processing! How can it be that I can’t build loops into a flow graph?
The top level component structures are all the same, and only gnuradio-runtime looks different, though there are similar structural aspects to the code. A top-level component also shares the same basic structure as any Out of Tree (OOT) module we would create to build a project that works with GNU Radio (<code>gr_modtool</code> works for in-tree components as well as OOTs).


You can’t perform loops in the flowgraph, but you can still do loops in GNU Radio. Let’s first explore why we can’t do loops in the way we might want. Data flow between blocks happens in chunks. While we might want to think of a continuous stream of samples going through a block, what really happens is a block is passed a large chunk of data from the previous block. This block processes this chunk of data in its work function and then passes it onto the next block. Data movement is a costly event, and so we want to minimize data movement to focus on data processing. To handle feedback, we must only process one sample at a time, otherwise, the feedback loop won’t work. Processing a single sample means maximizing the data movement overhead and is unworkable.
=== How is a GNU Radio application structured? ===


Instead, let’s look into a block to handle loops. Within a block, we can handle the data stream how we need to in order to look at the next sample. These algorithms like PLLs and other similar loops are common enough and fundamental enough that they probably belong in their own block, anyways. In fact, if you look at the list of GNU Radio blocks, you’ll see a number of these loops already written. You can look at these for examples on how to set yourself up to perform loops like this.
A GNU Radio program is structured as a <code>flowgraph</code> that consists of blocks. As mentioned, the blocks can be found in the GNU Radio top-level components and any OOT modules you've installed alongside GNU Radio. We first create a top_block that's the object that contains the full flowgraph. Blocks are then connected together by connecting streaming outputs to inputs or connecting message ports together.


Another way to handle loops is to use the asynchronous message passing interface. Messages can be sent from one block to any other block in the flow graph, in front or behind it in the data stream. Just remember that these messages are, as they are named, asynchronous. So the message doesn’t arrive at any specific time relative to the data stream. So this would not be the way to implement a PLL-type loop, but another control-level loop not directly tied to the data would work fine.
=== What are "items" in a flowgraph? ===


=== How does it compare to (other framework/thing) ===
GNU Radio blocks work off a concept of "items". We are tempted to think of signal processing applications in terms of "samples", but this isn't expressive enough for all of the different situations we work with in GNU Radio. Sometimes, a block may be operating off samples, symbols, bits, bytes, packets, frames, or other types of data structures. We generalize this into the name <code>items</code>. Blocks process items. We have to know what those items mean to each block.


Well, it’s the best!
The block is generalized such that it either knows what type of item it deals with (like a multiply_cc block works explicitly off complex data streams) or we tell it what data type to use, like a file source or sink. The block is interested in two things. First, the data type itself if it's doing operations directly on the data. The complex multiply block needs to know the data type of the stream because doing complex multiplies is very different than  floating point multiplies. In other situations, like the file sink and source blocks, they just need to know how many bytes to write or read from a file. They don't care about the data structure, just the size of the data structure. So we can tell them the size, in bytes, of the item type. In the case of reading from a complex file, we give it the size of a complex item, which is 64 bits.


Oh wait, you wanted a real answer... Well, it's free, it's fast, and it's the best.
=== Why use Python? It's so slow! ===


=== Which license does GNU Radio use? ===
It's not really that bad. In fact, good Python programming practices are as good as and sometimes better than naive C/C++ programming. Working harder at the C++ code, however, is still going to be better, obviously.


GNU Radio is licensed GPLv3 or later. All code in the GNU Radio project is copyrighted by the Free Software Foundation. If you have questions about working with the license in your organization, there is a lot of material out there. The [http://www.linuxfoundation.org/publications/compliance Linux Foundation has a webpage] dedicated to helping understand this issue.
More importantly, this isn't the right question to ask. GNU Radio uses Python as a scripting language, not (usually) for runtime signal processing (see the question on Python blocks, too). All of GNU Radio blocks and the scheduler are written in C++. We export the interface into Python to allow us to use that as a scripting language to make it easy to put flowgraphs together. At runtime, Python gets out of the way unless you've programmed something yourself in Python, which is common for user interface, controls, and interaction.


When developing your own project off GNU Radio, this code is obviously your own and not owned by the FSF. When contributing code to the core GNU Radio project, we need a copyright assignment for that code. Please read our [[Development]] wiki page for how to work with us in developing code and more information about the copyright assignment.
=== What is a Python Block? Can I write actual processing blocks in Python? ===


There is a facility to write and use a block in Python, which we call Python blocks. There's an interface between the Python domain and the runtime flow graph which allows us to write our blocks in Python and connect them to other GNU Radio blocks. Using this feature can be nice for quick prototyping, demos, and debugging. Using good Python programming techniques such as relying on Numpy and Scipy routines will help a lot here. But don't expect a Python block to be your deployed runtime version of the code unless the data rates are very low. You will probably want to translate this block into a C++ block. The exceptions are for slower parts of the graph, such as control, measurements, or even packet-level processing operating on chunks of bytes instead of samples. Measurements and profiling are your friend.


-----
=== What's the logic behind GNU Radio versions? ===


== The Community: Where you get help, advice and code ==
We use a standard version numbering scheme in GNU Radio: Major.API.Minor.Patch. Please see the explanation on our [[ChangeSets]] page.


=== Where do I get help? ===
=== Why can't we do loops? ===


The main ports of call for help are the [[MailingLists|mailing list]] and our IRC channel #gnuradio on Freenode. Other social medias, such as Google Plus, LinkedIn or Reddit are checked less regularly, and the core devs do not read these sites for support.
A lot of users come into the project looking to experiment, including building known algorithms like phase-locked loops (PLLs). GNU Radio comes with each of the blocks to build your own PLL in a flowgraph, like a multiplier, lowpass filter, and VCO. But you try to put it together and GNU Radio tells you it won't work. That the flow graphs don't allow you to do loops. Why? PLLs are fundamental to radio and signal processing! How can it be that I can't build loops into a flow graph?


When posting to the mailing list, make sure that you've read our guide on [[ReportingErrors|reporting errors and asking questions]]. This is very important, and will help you get a good answer faster.
You can't perform loops in the flowgraph, but you can still do loops in GNU Radio. Let's first explore why we can't do loops in the way we might want. Data flow between blocks happens in chunks. While we might want to think of a continuous stream of samples going through a block, what really happens is a block is passed a large chunk of data from the previous block. This block processes this chunk of data in its work function and then passes it onto the next block. Data movement is a costly event, and so we want to minimize data movement to focus on data processing. To handle feedback, we must only process one sample at a time, otherwise, the feedback loop won't work. Processing a single sample means maximizing the data movement overhead and is unworkable.


=== How do I ask a question (e.g., on the mailing list)? ===
Instead, let's look into a block to handle loops. Within a block, we can handle the data stream how we need to in order to look at the next sample. These algorithms like PLLs and other similar loops are common enough and fundamental enough that they probably belong in their own block, anyways. In fact, if you look at the list of GNU Radio blocks, you'll see a number of these loops already written. You can look at these for examples on how to set yourself up to perform loops like this.


The best place is to ask any and all questions on our Mailing List. [[ReportingErrors|Please read up on how to use the mailing list appropriately]] to help make sure we all make the best use of any inquiries. Please do not send private emails to the GNU Radio developers as we’ll just direct you back to the mailing list, anyways.
Another way to handle loops is to use the asynchronous message passing interface. Messages can be sent from one block to any other block in the flow graph, in front or behind it in the data stream. Just remember that these messages are, as they are named, asynchronous. So the message doesn't arrive at any specific time relative to the data stream. So this would not be the way to implement a PLL-type loop, but another control-level loop not directly tied to the data would work fine.


A secondary avenue to ask questions about GNU Radio is on the #gnuradio channel found on freenode. A number of members of the GNU Radio community hang out there and are available to answer questions.
=== Which license does GNU Radio use? ===


==== What if no one answers? ====
GNU Radio is licensed GPLv3 or later. All code in the GNU Radio project is copyrighted by the Free Software Foundation. If you have questions about working with the license in your organization, there is a lot of material out there. The [http://www.linuxfoundation.org/publications/compliance Linux Foundation has a webpage] dedicated to helping understand this issue.


If you've asked on the mailing list and haven't received an answer, wait a bit longer. We are all pretty busy people and it can often take us a few days to get through our emails. If you're lucky and someone with the answer is free or if the question is simple enough, you might get an answer quickly. But don’t worry if it's been a couple of days, and don't ask again too soon! Remember, you are asking others to do free work for you. Most of the time, someone will help you, but you have no claim on this.
When developing your own project off GNU Radio, this code is obviously your own and not owned by the FSF. When contributing code to the core GNU Radio project, we need a copyright assignment for that code. Please read our [[Development]] wiki page for how to work with us in developing code and more information about the copyright assignment.


Likewise on IRC, we are often away from keyboard (afk), and many in the same time zones, which might be very different from your own. Again, be patient.
<!-- Marker section 5 -->


=== How do I report a bug? ===
== Developing with GNU Radio ==


Questions belong on the mailing list, but when a legitimate bug has been identified, use the proper avenues of the [http://gnuradio.org/redmine/projects/gnuradio/issues gnuradio.org website's bug tracker]. You should sign in (and create an account if you don’t have one) and use the &quot;New Issue&quot; feature to add a new bug report. Following this path ensures that the bug report doesn't go unnoticed or lost in a flood of emails.
=== How can I add my own functionality to GNU Radio? ===


When reporting a new bug in this way, it's best if you can provide us with a good test case. The simplest possible program you can construct that exercises the bug. This will help us verify the bug and use it as a way to verify any bug fix we construct.
This depends. In most cases, you want to write your own module (an "out of tree" module, because it won't live inside the GNU Radio source code).  Have a look at the [[Creating_Python_OOT_with_gr-modtool|tutorial on how to do this]] (starts with Python-only; continues with C++). If you think your block is an important DSP component or something else that should be part of the GNU Radio core, have a look at the [[Development|contributor guide]].


Even more useful, however, is a patch! If you’ve discovered a bug or have a new code modification that you’ve developed a patch for, we’d love to see it. The best way to contribute code to us is through our git repo based on github. If you can base a patch off the repo, you can then issue a pull request to us to notify that something is ready for us to receive.
=== How does the history work? ===


[MOVE ALL OF THIS TO THE CONTRIBUTOR WIKI PAGE:<br />
The history is the number of items a block needs to calculate 1 output item. For a filter, this is equal to the number of taps.<br />
First, fork the gnu radio repo from github.com/gnuradio. Then figure out the right branch to base the patch off of. Most likely, this will be either maint or master:
For a simple differentiator (y(n) = x(n) - x(n-1)), the history equals 2. Obviously, the smallest value for the history is 1.


maint: our bug patch branch; this will become a bug release against the current version. These are for bugs only; no new features. Any patches made to this branch will also be applied to the master and next branch.<br />
In the work function, the number of items in your input buffer equals the number of input items plus the history minus one.<br />
master: this will become our next minor version release, the Z of an X.Y.Z version. This is where new code codes that’s more than just a bug patch.<br />
Here is an example for an accumulator that outputs the sum of the last N items:
next: in the X.Y.Z model, this is the staging area for the Y version increments, also called the API version. All code within a release version has the same compatible API. If you use code in the X.Y API release starting with minor release Z0, then all releases after Z0 in that API version are guaranteed to have the same API. We put stuff on the next branch when we have to break the API. We try to avoid this whenever possible since API releases are rare and so any code submitted here will not be released for a while.


When you’ve figured out the correct branch to use, check that out. Then create a branch off this with an appropriate name. Apply your fixes or changes to your new branch, commit them, and push to your github repo that your forked from us. Then you can use the pull request feature directly from github to notify us that something is ready.<br />
<syntaxhighlight lang="c++">
END]
for(unsigned int i = 0; i < noutput_items; ++i) {
    out[i] = 0;
    for (unsigned int k = 0; k < history(); ++k) {
        out[i] += in[i+k];
    }
}
</syntaxhighlight>


Keep in mind that a pull request is not a guaranteed merge on our part. We will vet the code for both correctness, usefulness, and [[Coding STYLE|style]], and we might push back requesting some changes. There will likely be a bit of back and forth on this, so don't be discouraged; we're just trying to make sure that the code always gets better.
As you can see, <code>noutput_items</code> items of out[] are written, whereas <code>noutput_items + history() - 1</code> items of in[] are read from.
 
—&gt; Merge info and/or link to main wiki page on contributing.
 
=== Who runs GNU Radio? ===
 
Read our [[Organization|organization page]].
 
 
-----
 
== Using GNU Radio ==
 
=== How do I start? What's the first thing to do after installation? ===
 
Start with our [[TutorialsSimulations|Simulation tutorial]] to learn your way around the GNU Radio Companion (GRC).
 
GRC is a graphical system that outputs a Python program. Python and GRC are the preferred methods of building GNU Radio applications. If you are unfamiliar with Python, there are many on-line resources to get you started. See the Python section on our [[SuggestedReading]] page. A good step-by-step tutorial is [http://www.diveintopython.net/ Dive into Python].
 
The [[TutorialsSimulations|simulations tutorial]] will walk you through the concepts of using GRC and interacting with GNU Radio applications. From there, go on to the tutorial on [[TutorialsWritePythonApplications|Writing Python Application]]. This will teach you how flowgraphs are actually structured in code. It also contains a ''lot'' of information about the entire GNU Radio system that you'll be interacting with.
 
We are actively working on a set of tutorials to improve upon these two that will get you more familiar with the system and code.
 
=== Where can I find a list of GNU Radio blocks? ===
 
All GNU Radio blocks are listed in the [http://gnuradio.org/doc/doxygen/modules.html GNU Radio manual] under the &quot;Modules&quot; section. They are sorted by category. A &quot;multiplier&quot; block, for example, would be listed under the category &quot;Math Operators&quot;. The manual also has a search feature you can use.
 
In GNU Radio Companion, blocks are also listed at the side in the ''Block Tree''. You can use the search feature of GNU Radio companion to find blocks by name by using Ctrl+f or '/' to open the search box.
 
=== What does ''sample rate'' mean in GNU Radio? ===
 
First off: You need to understand the general principle of &quot;Sampling Rate&quot; and the sampling theorem before you do anything with GNU Radio. See [[SuggestedReading]].
 
Sampling rates are a curious thing in software radio. There’s the real sampling rate related to hardware devices sampling a signal with some number of samples per second. This is related to physical hardware sampling a signal so many times per second and has a real, tangible meaning. This concept carries through to strongly-clocked systems, like FPGAs, where operations happen at a very specific time interval. However, on general purpose processing systems, like GNU Radio running on an x86 or ARM system, there is no strict relationship between the clocking of the signal and the operations per second. And so we have to think of sampling rates in two different contexts.
 
First, there’s the context of the real hardware sampling rates. This matters when we’re actually communicating with hardware systems, especially when we have multiple hardware systems involved. In this case, we have to think of the sampling rate as a matching problem when resampling. When meeting data streams between any hardware systems, we have to make sure that all resampling done leads to the same sampling rate when they meet. A common example of this is when we bring a radio signal in from a radio hardware at sample rate f_s, resample it through a few stages, let’s say 2 stages with rate changes <code>r_0</code> and <code>r_1</code>, and then play this out of an audio sink that's operating at sampling rate <code>f_k</code>. In this case, we need to make sure that <code>f_s * r_0 * r_1 = f_k</code>.
 
The other aspect of the sampling rate concept that we have to care about, even with no hardware or concern about actual time information, is in an information theoretic sense. Here, we’re talking about how many samples are required in relation to the amount of information in the signal. We’re talking here about the Nyquist rate, where we need to sample at twice the bandwidth of the signal. If we have any less, we can’t capture the full amount of information in the signal. At the same time, if we use a higher sampling rate, then we’re processing more symbols than we need to and wasting compute cycles.
 
The other thing to remember is the difference between samples per second, samples per symbol, and symbols per second, which only matter for digital communications, anyways.
 
=== My flowgraph is too slow. What can I do to make it faster? My hardware signals underflows, overflows or dropped samples. ===
 
The most common answer to that question is: It's as fast as it ''can'' run. If your signal processing application really needs that much computing, you need more computational power.
 
There are, however, some cases where your problems can be helped:
 
# If your signal processing relies on a bandwidth that is substantially smaller than your nyquist bandwidth (in case of complex sampling: sampling rate, in case of real sampling: 0.5 * sampling rate) use a lower sampling rate as early as possible. Often, you could also tell your hardware to produce a lower sample rate.
# If your signal processing could as well be done offline (instead of in realtime), write your signal to file (using file_sink) and load it from there in another flowgraph (using file_source)


=== When do I use a throttle block? ===
If the history has the value N, the first N-1 items are "old" items, i.e. they were available in the previous call to <code>work()</code> (when <code>work()</code> is called the first time, they are set to zero).


GNU Radio is written and designed for real-time streaming signal processing that interfaces with real hardware systems. A GNU Radio application attempts to source data from a hardware source and sink data to a hardware sink as quickly as possible. That means that we are rate limited by the hardware, which will either provide or allow us to push data between GNU Radio and the hardware system based on the rate of the hardware.
=== In my OOT Module, I'm trying to use a GNU Radio block or class but get an ImportError "undefined symbol". What do I do? ===


However, we also often want to prototype, develop, and simulate applications without connecting to real hardware. In this case, GNU Radio will not be rate limited by a hardware clock and run data as quickly as possible. The [http://gnuradio.org/doc/doxygen/classgr_1_1blocks_1_1throttle.html gr::blocks::throttle] block helps add a very crude rate-limiting system for these situations. It simply uses the OS’s clocking system to roughly estimate the sample rate given to it. OS clocks tend to be very rough, however, and you should not expect this rate-limiting block to provide anywhere near the actual sample rate. It is meant to slow down a flowgraph for visualization and testing purposes only.
Your program uses functionality from a library, the compiler knows how that the interface can be used (hence, ''building'' your software works) – but it doesn't know where this functionality comes from, so when you try to run a program ''using'' the functionality, your system rightfully complains "I can't find the implementation of this function!".


It is very important that you do not use a throttle block when interacting with real hardware. They will both try and rate limit the system, but since the throttle is a very bad clock, you will find yourself dealing with the two-clock problem and very bad things will result.
This happens when you don't ''link'' against the library containing the functionility. For GNU Radio, this most commonly happens because the linker wasn't told which GNU Radio components to use.


If still unclear, ask yourself these questions:
To fix that, two things need to be done:


* Does my flowgraph have a radio device connected (USRP, RTLSDR, ...)?
1. Tell the CMake build system that the target you're building has to be ''linked against'' all the necessary GNU Radio component libraries, and
* Does my flowgraph have an audio device connected?
2. Tell the CMake build system to look for these components.
* Is there a 'head' block in my flow graph?


If you've answered any of these questions with 'yes', you must '''not''' use a throttle block.
==== Linking Against GNU Radio Components ====


=== What is the file format of a file_sink? How can I read files produced by a file sink? ===
In your OOT's lib/CMakeLists.txt, find


All files are in pure binary format. Just bits. That’s it. A floating point data stream is saved as 32 bits in the file, one after the other. A complex signal has 32 bits for the real part and 32 bits for the imaginary part. Reading back a complex number means reading in 32 bits, saving that to the real part of a complex data structure, and then reading in the next 32 bits as the imaginary part of the data structure. And just keep reading the data.
<syntaxhighlight lang="cmake">
 
target_link_libraries(gnuradio-{your oot's name} gnuradio::gnuradio-runtime)
Take a look at the Octave and Python files in gr-utils for reading in data using Octave and Python’s Scipy module.
</syntaxhighlight>
 
The exception to the format is when using the metadata file format. These files are produced by the <code>File Meta Sink</code>: http://gnuradio.org/doc/doxygen/classgr_1_1blocks_1_1file_''meta''_sink.html block and read by the [http://gnuradio.org/doc/doxygen/classgr_1_1blocks_1_1file__meta__source.html File Meta Source] block. See the manual page on the [http://gnuradio.org/doc/doxygen/page_metadata.html metadata file format] for more information about how to deal with these files.
 
A one-line Python command to read the entire file into a numpy array is:
 
f = scipy.fromfile(open(&quot;filename&quot;), dtype=scipy.uint8)
 
Replace the dtype with <code>scipy.int16</code>, <code>scipy.int32</code>, <code>scipy.float32</code>, <code>scipy.complex64</code> or whatever type you were using.
 
=== How can I run my 3.6 (or older) code in GNU Radio 3.7 (or newer)? ===
 
We released version 3.7.0 in mid 2013, which represented a significant change in the API for our entire code base. This meant breaking a lot of existing projects and code. Mostly, from the user's side, these were semantic changes. We changed from using prefixes like <code>gr_</code> in front of everything to using namespaces. We also broke up the source code into multiple top-level components, moving a lot of what used to be in gnuradio-core into their own components, like gr-blocks and gr-analog. In C++, this move meant a change to using namespaces like <code>gr::blocks::</code> and <code>gr::analog::</code>. In Python, we now have modules in ‘gnuradio’ called ‘blocks’ and ‘analog’ that these blocks now blong to. This means that instead of pulling every block in from ‘gr.someblock’, we now pull them in from their respective module, like ‘blocks.someblock’ and ‘analog.someblock’.
 
The majority of the work in changing your pre-3.7 code to the new 3.7 API is mostly just changing these namespace or Python module names to the new names. Look at our wiki page [[Move_3-6_to_3-7]] for more details about how things have changed.
 
In GRC, starting with GNU Radio version 3.7.4 (CHECK MAYBE 3.7.3), when you open an old flow graph where the block locations have changed because you opened an old 3.6 flow graph in 3.7, instead of just removing the block from the canvas, we now show you the block outline with all of the properties preserved, making it much easier to replace those blocks with the new ones.
 
[Link to Nathan West's converter script for GRC]
 
 
-----
 
== Developing with GNU Radio ==
 
=== How can I add my own functionality to GNU Radio? ===
 
This depends. In most cases, you want to write your own module (an &quot;out of tree&quot; module, because it won't live inside the GNU Radio source code); have a look at the [[OutOfTreeModules|tutorial on how to do this]]. If you think your block is an important DSP component or something else that should be part of the GNU Radio core, have a look at the [[Development|contributor guide]].
 
=== How does the history work? ===
 
The history is the number of items a block needs to calculate 1 output item. For a filter, this is equal to the number of taps.<br />
For a simple differentiator (y(n) = x(n) - x(n-1)), the history equals 2. Obviously, the smallest value for the history is 1.


When you are in the work function, the number of items in your input buffer equals the number of input items plus the history minus one.<br />
If your library, for example, uses components from the <syntaxhighlight lang="c++" inline>gr::fft</syntaxhighlight> namespace, you'll want to add  <syntaxhighlight lang="cmake" inline>gnuradio::gnuradio-fft</syntaxhighlight>:
Here is an example for an accumulator that outputs the sum of the last N items:


<pre>for (int i = 0; i &lt; noutput_items; i++) {
<syntaxhighlight lang="cmake">
    out[i] = 0;
target_link_libraries(gnuradio-{your oot's name}
    for (int k = 0; k &lt; history(); k++) {
         gnuradio::gnuradio-runtime
         out[i] += in[i+k];
        gnuradio::gnuradio-fft
    }
        )
}</pre>
</syntaxhighlight>
As you can see, <code>noutput_items</code> items of out[] are written, whereas <code>noutput_items + history() - 1</code> items of in[] are read from.


If the history has the value N, the first N-1 items are &quot;old&quot; items, i.e. they were available in the previous call to <code>work()</code> (when <code>work()</code> is called the first time, they are set to zero).
==== Finding the Used GNU Radio Components ====


=== In my OOT Module, I'm trying to use a GNU Radio block or class but get an ImportError &quot;undefined symbol&quot;. What do I do? ===
If you tried to build the module now, CMake will complain: You ask to link against <syntaxhighlight lang="cmake" inline>gnuradio::gnuradio-fft</syntaxhighlight>, but it has no idea where that should come from. So, in the OOT's root directory's CMakeLists.txt, find the line


You need to tell your OOT module to link against the right set of GNU Radio libraries. Instructions are found in our [[OutOfTreeModulesConfig]] page.
<syntaxhighlight lang="cmake">
find_package(Gnuradio "{version of GNU Radio}" REQUIRED)
</syntaxhighlight>


Basically, an OOT module is only told to link against RUNTIME, or libgnuradio-runtime.so. If you're using a class or block from another GNU Radio component, you'll need to add that component for proper linking. In your CMakeLists.txt file in the top-level directory of the OOT project, make sure to add whatever components you might need with this line:
and amend it like this:


set(GR_REQUIRED_COMPONENTS RUNTIME <YOUR COMPONENTS>)


Such as PMT, BLOCKS, FILTER, FFT, ANALOG, DIGITAL, etc.
<syntaxhighlight lang="cmake">
find_package(Gnuradio "{version of GNU Radio}" REQUIRED COMPONENTS
        fft
        )
</syntaxhighlight>


=== How can I reconfigure a flow graph? How do I use lock(), unlock()? ===
=== How can I reconfigure a flow graph? How do I use lock(), unlock()? ===
Line 353: Line 263:
from gnuradio import gr
from gnuradio import gr
from gnuradio import blocks
from gnuradio import blocks


def main():
def main():
     tb = gr.top_block()
     tb = gr.top_block()
     src1 = blocks.vector_source_f(range(16), repeat=True)
     src1 = blocks.vector_source_f(list(range(16)), repeat=True)
     throttle = blocks.throttle(gr.sizeof_float, 1e6)
     throttle = blocks.throttle(gr.sizeof_float, 1e6)
     sink = blocks.file_sink(gr.sizeof_float, 'out.dat')
     sink = blocks.file_sink(gr.sizeof_float, 'out.dat')
Line 362: Line 273:
     tb.start()
     tb.start()
     time.sleep(1)
     time.sleep(1)
     print "Locking flowgraph..."
     print("Locking flowgraph...")
     tb.lock()
     tb.lock()
     tb.disconnect(src1)
     tb.disconnect(src1)
     src2 = blocks.null_source(gr.sizeof_float)
     src2 = blocks.null_source(gr.sizeof_float)
     tb.connect(src2, throttle)
     tb.connect(src2, throttle)
     print "Unlocking flowgraph..."
     print("Unlocking flowgraph...")
     tb.unlock()
     tb.unlock()
     time.sleep(2)
     time.sleep(2)
     tb.stop()
     tb.stop()
     tb.wait()
     tb.wait()


if __name__ == "__main__":
if __name__ == "__main__":
     main()</syntaxhighlight>
     main()
</syntaxhighlight>
 
Note that this is not meant for sample-precision timing, but rather for situations where time does not really matter.
Note that this is not meant for sample-precision timing, but rather for situations where time does not really matter.


Line 384: Line 298:
from gnuradio import gr
from gnuradio import gr
from gnuradio import blocks
from gnuradio import blocks
import my_awesome_oot_module as myoot # This is your custom module
import my_awesome_oot_module as myoot # This is your custom module
 


def main():
def main():
     tb = gr.top_block()
     tb = gr.top_block()
     src1 = blocks.vector_source_f(range(16), repeat=True)
     src1 = blocks.vector_source_f(list(range(16)), repeat=True)
     src2 = blocks.null_source(gr.sizeof_float)
     src2 = blocks.null_source(gr.sizeof_float)
     switch = myoot.switch() # This is your custom block
     switch = myoot.switch() # This is your custom block
     throttle = blocks.throttle(gr.sizeof_float, 1e6)
     throttle = blocks.throttle(gr.sizeof_float, 1e6)
     sink = blocks.file_sink(gr.sizeof_float, 'out.dat')
     sink = blocks.file_sink(gr.sizeof_float, 'out.dat')
Line 399: Line 314:
     tb.stop()
     tb.stop()
     tb.wait()
     tb.wait()


if __name__ == "__main__":
if __name__ == "__main__":
     main()</syntaxhighlight>
     main()
There are many blocks that react to input data, or incoming tags.
</syntaxhighlight>
 
 
-----
 
== GNU Radio Companion ==
 
=== How do I change the canvas size? ===
 
It's in the 'Options' block of your flow graph.


<!-- Marker section 6 -->


-----
== Signal Processing ==
 
== Signal Processing and Radio-Related Questions ==
 
=== I have a really &quot;stupid&quot; radio question... ===
 
You might go and read a number of the books and other suggested reading materials. You might then have gone through our list of tutorials. Maybe you’ve even been working in radio and communications for years. And yet, still, you have a question that you think is simple or even &quot;stupid&quot;. Well, we all have those questions and we could all benefit from good, open discussions of those questions.
 
Our IRC Channel and mailing list are good places to ask your questions. We don't like answering them in private, however, because even questions you might think are stupid means that others will have them. Answering them and keeping them in the public forum of our list makes a big difference in our understanding of communications.
 
On that last note, then, if you have a question, please first look to see if it’s been addressed already on our mailing list. Google and Bing are great at finding our mailing list threads, and we have the archive completely open and available, too.


=== Which concepts do I need to know to start using GNU Radio? ===
=== Which concepts do I need to know to start using GNU Radio? ===
Line 442: Line 340:
There are often two issues here. One is windowing and the other is scaling. The basic flowgraph is:
There are often two issues here. One is windowing and the other is scaling. The basic flowgraph is:


<code>source --&gt; stream_to_vector --&gt; forward FFT --&gt; reverse FFT --&gt; vector_to_stream --&gt; sink</code>
<code>source --> stream_to_vector --> forward FFT --> reverse FFT --> vector_to_stream --> sink</code>


The windowing problem is related to the fact that we use a default window in the FFT. If you're just doing the transform to be followed by an inverse transform, you don't want to window the signal because you're changing the results of the FFT. Make sure to remove the window. You can pass an empty Python list as <code>[]</code> to the window parameter in the FFT options, or you can use a <code>fft.window.rectangular(fftlen)</code>, which is just a vector of 1's. Now we're just doing the pure Fourier transform.
The windowing problem is related to the fact that we use a default window in the FFT. If you're just doing the transform to be followed by an inverse transform, you don't want to window the signal because you're changing the results of the FFT. Make sure to remove the window. You can pass an empty Python list as <code>[]</code> to the window parameter in the FFT options, or you can use a <code>fft.window.rectangular(fftlen)</code>, which is just a vector of 1's. Now we're just doing the pure Fourier transform.
Line 448: Line 346:
The scaling issue is related to how the FFT algorithm computes the results. There is an internal scaling effect of <code>fftlen</code> (the length of your FFT). So the output of your forward FFT is <code>fftlen</code> times the input. We can scale this down here if we wanted to:
The scaling issue is related to how the FFT algorithm computes the results. There is an internal scaling effect of <code>fftlen</code> (the length of your FFT). So the output of your forward FFT is <code>fftlen</code> times the input. We can scale this down here if we wanted to:


<code>... forward FFT --&gt; multiply_const_cc(fftlen*[1.0/fftlen,]) --&gt; reverse FFT ...</code>
<code>... forward FFT --> multiply_const_cc(fftlen*[1.0/fftlen,]) --> reverse FFT ...</code>


Or you can wait until you're done with the IFFT to rescale:
Or you can wait until you're done with the IFFT to rescale:


<code>... forward FFT --&gt; reverse FFT --&gt; vector_to_stream --&gt; multiply_const_cc(1.0/fftlen) ...</code>
<code>... forward FFT --> reverse FFT --> vector_to_stream --> multiply_const_cc(1.0/fftlen) ...</code>


Note that in the first case, we have to pass a vector of <code>fftlen</code> constants with the scaling value (1.0/fftlen) because we're working with vectors at this point. Waiting until after the <code>vector_to_stream</code> block, we only need the single scalar that is multiplied against every value. It's still the same number of multiplications in the end.
Note that in the first case, we have to pass a vector of <code>fftlen</code> constants with the scaling value (1.0/fftlen) because we're working with vectors at this point. Waiting until after the <code>vector_to_stream</code> block, we only need the single scalar that is multiplied against every value. It's still the same number of multiplications in the end.
Line 460: Line 358:
=== How do I know the exact voltage/power of my received input signal? ===
=== How do I know the exact voltage/power of my received input signal? ===


GNU Radio processes samples coming from hardware that are mostly-linearly-proportional to the instantaneous voltage seen at the antenna terminal. But unless GNU Radio enforced a very-strict hardware interface in which those samples are rigorously calibrated to some standard amplitude by the hardware, there's no way know anything about absolute antenna voltages, only relative ones.
GNU Radio processes samples coming from hardware that are mostly-linearly-proportional to the instantaneous voltage seen at the antenna terminal. But unless GNU Radio enforced a very-strict hardware interface in which those samples are rigorously calibrated to some standard amplitude by the hardware, there's no way to know anything about absolute antenna voltages, only relative ones.


A typical receiver chain has many stages of gain and loss, filtering, decimation, etc. This will produce a lot of uncertainty about the exact proportionality between the samples that Gnu Radio processes (typically float-point values in the range {-1.0,+1.0}) and the actual voltage as seen at the antenna port.
A typical receiver chain has many stages of gain and loss, filtering, decimation, etc. This will produce a lot of uncertainty about the exact proportionality between the samples that Gnu Radio processes (typically float-point values in the range {-1.0,+1.0}) and the actual voltage as seen at the antenna port.
Line 468: Line 366:
=== Why doesn't my signal match the textbook? ===
=== Why doesn't my signal match the textbook? ===


Matt Ettus [https://www.youtube.com/watch?v=wqKNUXDdIvU did a talk on this]. Good stuff.
Matt Ettus [https://www.youtube.com/watch?v=wqKNUXDdIvU did a good talk on this].
 
 
-----


<!-- Marker section 7 -->
== Applications ==
== Applications ==


=== I have a receiver with acoustic output, and keep getting aUaUaU errors? ===
=== I have a receiver with an audio sink, and keep getting aUaUaU errors? ===


First of all, those <pre>aU</pre> things are called 'audio underruns'.
First of all, those <pre>aUaU</pre> things are called 'audio underruns'.


If your flow graph looks like this:
If your flow graph looks like this:
Line 483: Line 379:
  Radio Hardware -> Demodulator -> Audio Sink
  Radio Hardware -> Demodulator -> Audio Sink


...and you see those errors, it's most likely a "2-clock-problem". The issue is, you have 2 pieces of hardware with a hardware clock, and there's no way to perfectly align them. There's many failure modes here, but a very obvious one is this: Imagine the radio clock is ever so slightly slower than advertised, and the audio clock is faster. Then, invariably, at some point, there will be not enough data to feed into the audio sink and it will underrun. Also, remember that GNU Radio shuffles data in chunks, so there may be enough data, but not in the precise moment when the audio sink needs it.
...and you see those errors, it's most likely a "2-clock-problem". The issue is, you have 2 pieces of hardware with a clock, and there's no way to perfectly align them. There are many failure modes here, but a very obvious one is this: Imagine the radio clock is ever so slightly slower than advertised, and the audio clock is faster. Then, invariably, at some point, there will be not enough data to feed into the audio sink and it will underrun. Also, remember that GNU Radio shuffles data in chunks, so there may be enough data, but not in the precise moment when the audio sink needs it.


There's no trivial fix to this, but a simple workaround is to feed the audio sink data with a slightly higher rate than it's set to.
A simple workaround is to set the Audio Sink parameter "Ok to Block" to "No". Beyond that, refer to [[ALSAPulseAudio#Working_with_ALSA_and_Pulse_Audio]].


=== My application segfaults immediately. It used to work, and I didn't change it. What the? ===
=== My application segfaults immediately. It used to work, and I didn't change it. What happened? ===


Most often, you updated some underlying component (e.g. UHD, gr-osmosdr, etc.) without<br />
Most often, you updated some underlying component (e.g. UHD, gr-osmosdr, etc.) without<br />
Line 495: Line 391:
start with that, then GNU Radio, then all of the OOTs.
start with that, then GNU Radio, then all of the OOTs.


== The Community: Where you get help, advice and code ==
=== Where can I get help? ===
Help can be found in a number of places, such as:
* the search box in [https://wiki.gnuradio.org/ GNU Radio Wiki]
* search engines such as Google
* search the [https://lists.gnu.org/archive/html/discuss-gnuradio discuss-gnuradio mailing list]
* join the Matrix discussion channel:
** server: https://chat.gnuradio.org
** room: #gnuradio:gnuradio.org


-----
=== How do I ask a question on the mailing list? ===


'''Notes on adding answers to this FAQ:'''
When posting to the mailing list, make sure that you've read our guide on [[ReportingErrors|reporting errors and asking questions]]. This is very important, and will help you get a good answer faster.
 
Please do not send private emails to the GNU Radio developers as they will just direct you back to the mailing list.
 
=== What if no one answers? ===
 
If you've asked on the mailing list and haven't received an answer, wait a bit longer. We are all pretty busy people and it can often take us a few days to get through our emails. If you're lucky and someone with the answer is free or if the question is simple enough, you might get an answer quickly. But don't worry if it's been a couple of days, and don't ask again too soon! Remember, you are asking others to do free work for you. Most of the time, someone will help you, but you have no claim on this.
 
Likewise on IRC, we are often away from our keyboard, and many might be in different time zones from your own. Again, be patient.
 
=== I have a really "stupid" question... ===
 
You might have read a number of the books and other suggested reading materials. You might then have gone through our list of tutorials. Maybe you've even been working in radio and communications for years. And yet you have a question that you think is simple or even "stupid". Well, we all have those questions and we could all benefit from good, open discussions of those questions.
 
Our IRC Channel and mailing list are good places to ask your questions. We don't like answering them in private, however, because even for  questions you might think are stupid, others will have them too. Answering them in the public forum of our list makes them available for others to search later.
 
=== How do I report a bug? ===
 
See [[ReportingErrors|Reporting Errors]].
 
=== Who runs GNU Radio? ===


* Please stick to simple English and a neutral tone.
See [https://www.gnuradio.org/org/organization/ Organization & Leadership] on the project homepage.
* The order of sections should be in order 'advancedness', so the more beginner you are, the more likely your questions are at the front.
* Obviously, we'd like to avoid duplication. If there's a page explaining the answer, please link to that.
* Questions should be posed very explicitly, so people can search for a keyword or two and still find the correct question.
* Most readers will be beginners, so try to not confuse them. Don't make unstated assumptions. Link to other resources if you think something needs to be explained.
* There can be a section for advanced stuff, as long as the items are really relevant for some users. I'd rather have an advanced section here than another page with 'Tips and Tricks'.

Latest revision as of 15:30, 17 November 2023

Frequently Asked Questions

Getting Started

What is GNU Radio?

Check out our page What is GNU Radio? for an introduction to what GNU Radio is and why you would want to use it.

How do I get / install GNU Radio?

See Installing GNU Radio for details.

Which operating systems are supported?

We develop and test on Linux, Mac OS and Windows. See Installing GNU Radio!

Among these three operating systems, Linux is the one that most GNU Radio developers agree on. That does not depreciate the other two.

GNU Radio supports both 32- and 64-bit operating systems. Since it's a signal processing framework making heavy use of math functionality of modern processors, 32 bit platforms are becoming rarer; if you want to do high-rate signal processing, a 32 bit laptop might no longer be the platform of choice.

What are the system requirements (minimum power, etc.)?

GNU Radio in its core is C++ with lots of user functionality relying on Python. So basically, as long as there is a feasible compiler for your platform, it can work.

Hardware requirements basically depend on what you want to do. A modern PC/laptop computer is usually up to most tasks such as receiving broadcast signals, doing audio frequency processing, and many narrowband digital signals.

When dealing with telecommunication signals, however, sample rates of over 5 Msamples/s are not uncommon. Even rather modern hardware often meets its limits when it comes to doing things in realtime; it all depends on your processing requirements, GNU Radio is only the platform to perform these computationally intensive tasks.

I built GNU Radio from source, but some components seem to be missing.

Missing components are usually seen because blocks are missing from GRC. This usually only happens when you did a source build. We generally recommend you don't build GNU Radio from source without an explicit need to do so; for almost all platforms, installing GNU Radio from packages is much easier, less error prone and should be preferred.

You can check the installed GNU Radio components by running gnuradio-config-info --enabled-components (Or, for a nicer formatting, gnuradio-config-info --enabled-components | sed 's/;/\n/g').

After running cmake, you might see something like this at the end of CMake's output (this list is heavily cropped for simplicity, it is much longer in reality):

-- ######################################################
-- # Gnuradio enabled components
-- ######################################################
--   * testing-support
--   * python-support
[…………]
--   * gr-vocoder
--   * * codec2
--   * * freedv
--   * * gsm
-- ######################################################
-- # Gnuradio disabled components
-- ######################################################
--   * gr-ctrlport
--   * gr-dtv
--   * gr-atsc

If the components you are missing are listed under the 'disabled' components, there's your problem.

There are two reasons why components are disabled:

  • You disabled them yourself, e.g. by supplying a `-DENABLE_GR_DTV=OFF` switch to CMake.
  • The component was automatically disabled because CMake could not find certain dependencies.

In both cases, you can read the CMake output to see what the reason is. If dependencies are missing, you might have to install developer packages for something (on Debian and Ubuntu systems, these are packages ending with -dev, on Fedora, they end with -devel). Consult the build manual for which dependencies are required.

If you don't understand or know how to do this, consider installing precompiled binaries. Usually, they will pull in all the required dependencies.

Which Radio Hardware is supported?

There is a growing list of radio front ends for software radio uses. It is difficult to keep up with! The Ettus Research USRP product line, supported by UHD, is the exception since the USRP and GNU Radio have had a long history of developing and working together. For hardware that has a SoapySDR driver, GNU Radio offers a generic interface. See also Hardware.

Can you suggest any reading material for DSP/SDR/Digital Comms?

We have a wiki page for this: SuggestedReading

Using GNU Radio

How do I start? What's the first thing to do after installation?

Start with our Tutorials to learn your way around GNU Radio. They are divided into levels of user experience.

Where can I find a list of GNU Radio blocks?

All GNU Radio blocks are listed in Block Docs.

When using GNU Radio Companion, blocks are also listed in the Block Tree sidebar. You can use the search feature of GNU Radio Companion (a magnifying glass, and the search text box, both highlighted in green below) to find blocks by name:

Highlight-search.png

What does sample rate mean in GNU Radio?

First off: You need to understand the general principle of "Sampling Rate" and the sampling theorem before you do anything with GNU Radio. See SuggestedReading.

For a tutorial on sample rate, see the Sample Rate Tutorial.

My flowgraph is too slow. What can I do to make it faster? My hardware signals underflows, overflows or dropped samples.

The most common answer to that question is: It's as fast as it can run. If your signal processing application really needs that much computing, you need more computational power.

There are, however, some cases where your problems can be helped:

  1. If your signal processing relies on a bandwidth that is substantially smaller than your nyquist bandwidth (in case of complex sampling: sampling rate, in case of real sampling: 0.5 * sampling rate) use a lower sampling rate as early as possible. Often, you could also tell your hardware to produce a lower sample rate.
  2. If your signal processing could as well be done offline (instead of in realtime), write your signal to file (using file_sink) and load it from there in another flowgraph (using file_source)

When do I use a Throttle block?

Almost never!

GNU Radio is written and designed for real-time streaming signal processing that interfaces with real hardware systems. A GNU Radio application attempts to source data from a hardware source and sink data to a hardware sink as quickly as possible. That means that we are rate limited by the hardware, which will either provide or allow us to push data between GNU Radio and the hardware system based on the rate of the hardware.

For other cases, see Sample_Rate_Tutorial#When_there_is_no_hardware_block.

What is the file format of a file_sink? How can I read files produced by a file sink?

See the relevant section in the File Sink block documentation.

GNU Radio Companion

For a tutorial on GRC, see the guided Tutorials; start with Your First Flowgraph!


How can I take a picture of a Flow Graph

Please don't use your camera to take a picture of the screen! Instead, use the built-in "Screen Capture" functionality:

Screencap.png

About GNU Radio (Internal, Structure...)

How is the GNU Radio source tree structured?

Basically, GNU Radio consists of the runtime scheduler and the main block class structure that lives in gnuradio-runtime. Outside of gnuradio-runtime are our top-level (or in-tree) components that consist mostly of blocks for building GNU Radio flow graphs as well as supporting code and quality assurance (QA) code for the blocks.

The top level component structures are all the same, and only gnuradio-runtime looks different, though there are similar structural aspects to the code. A top-level component also shares the same basic structure as any Out of Tree (OOT) module we would create to build a project that works with GNU Radio (gr_modtool works for in-tree components as well as OOTs).

How is a GNU Radio application structured?

A GNU Radio program is structured as a flowgraph that consists of blocks. As mentioned, the blocks can be found in the GNU Radio top-level components and any OOT modules you've installed alongside GNU Radio. We first create a top_block that's the object that contains the full flowgraph. Blocks are then connected together by connecting streaming outputs to inputs or connecting message ports together.

What are "items" in a flowgraph?

GNU Radio blocks work off a concept of "items". We are tempted to think of signal processing applications in terms of "samples", but this isn't expressive enough for all of the different situations we work with in GNU Radio. Sometimes, a block may be operating off samples, symbols, bits, bytes, packets, frames, or other types of data structures. We generalize this into the name items. Blocks process items. We have to know what those items mean to each block.

The block is generalized such that it either knows what type of item it deals with (like a multiply_cc block works explicitly off complex data streams) or we tell it what data type to use, like a file source or sink. The block is interested in two things. First, the data type itself if it's doing operations directly on the data. The complex multiply block needs to know the data type of the stream because doing complex multiplies is very different than floating point multiplies. In other situations, like the file sink and source blocks, they just need to know how many bytes to write or read from a file. They don't care about the data structure, just the size of the data structure. So we can tell them the size, in bytes, of the item type. In the case of reading from a complex file, we give it the size of a complex item, which is 64 bits.

Why use Python? It's so slow!

It's not really that bad. In fact, good Python programming practices are as good as and sometimes better than naive C/C++ programming. Working harder at the C++ code, however, is still going to be better, obviously.

More importantly, this isn't the right question to ask. GNU Radio uses Python as a scripting language, not (usually) for runtime signal processing (see the question on Python blocks, too). All of GNU Radio blocks and the scheduler are written in C++. We export the interface into Python to allow us to use that as a scripting language to make it easy to put flowgraphs together. At runtime, Python gets out of the way unless you've programmed something yourself in Python, which is common for user interface, controls, and interaction.

What is a Python Block? Can I write actual processing blocks in Python?

There is a facility to write and use a block in Python, which we call Python blocks. There's an interface between the Python domain and the runtime flow graph which allows us to write our blocks in Python and connect them to other GNU Radio blocks. Using this feature can be nice for quick prototyping, demos, and debugging. Using good Python programming techniques such as relying on Numpy and Scipy routines will help a lot here. But don't expect a Python block to be your deployed runtime version of the code unless the data rates are very low. You will probably want to translate this block into a C++ block. The exceptions are for slower parts of the graph, such as control, measurements, or even packet-level processing operating on chunks of bytes instead of samples. Measurements and profiling are your friend.

What's the logic behind GNU Radio versions?

We use a standard version numbering scheme in GNU Radio: Major.API.Minor.Patch. Please see the explanation on our ChangeSets page.

Why can't we do loops?

A lot of users come into the project looking to experiment, including building known algorithms like phase-locked loops (PLLs). GNU Radio comes with each of the blocks to build your own PLL in a flowgraph, like a multiplier, lowpass filter, and VCO. But you try to put it together and GNU Radio tells you it won't work. That the flow graphs don't allow you to do loops. Why? PLLs are fundamental to radio and signal processing! How can it be that I can't build loops into a flow graph?

You can't perform loops in the flowgraph, but you can still do loops in GNU Radio. Let's first explore why we can't do loops in the way we might want. Data flow between blocks happens in chunks. While we might want to think of a continuous stream of samples going through a block, what really happens is a block is passed a large chunk of data from the previous block. This block processes this chunk of data in its work function and then passes it onto the next block. Data movement is a costly event, and so we want to minimize data movement to focus on data processing. To handle feedback, we must only process one sample at a time, otherwise, the feedback loop won't work. Processing a single sample means maximizing the data movement overhead and is unworkable.

Instead, let's look into a block to handle loops. Within a block, we can handle the data stream how we need to in order to look at the next sample. These algorithms like PLLs and other similar loops are common enough and fundamental enough that they probably belong in their own block, anyways. In fact, if you look at the list of GNU Radio blocks, you'll see a number of these loops already written. You can look at these for examples on how to set yourself up to perform loops like this.

Another way to handle loops is to use the asynchronous message passing interface. Messages can be sent from one block to any other block in the flow graph, in front or behind it in the data stream. Just remember that these messages are, as they are named, asynchronous. So the message doesn't arrive at any specific time relative to the data stream. So this would not be the way to implement a PLL-type loop, but another control-level loop not directly tied to the data would work fine.

Which license does GNU Radio use?

GNU Radio is licensed GPLv3 or later. All code in the GNU Radio project is copyrighted by the Free Software Foundation. If you have questions about working with the license in your organization, there is a lot of material out there. The Linux Foundation has a webpage dedicated to helping understand this issue.

When developing your own project off GNU Radio, this code is obviously your own and not owned by the FSF. When contributing code to the core GNU Radio project, we need a copyright assignment for that code. Please read our Development wiki page for how to work with us in developing code and more information about the copyright assignment.


Developing with GNU Radio

How can I add my own functionality to GNU Radio?

This depends. In most cases, you want to write your own module (an "out of tree" module, because it won't live inside the GNU Radio source code). Have a look at the tutorial on how to do this (starts with Python-only; continues with C++). If you think your block is an important DSP component or something else that should be part of the GNU Radio core, have a look at the contributor guide.

How does the history work?

The history is the number of items a block needs to calculate 1 output item. For a filter, this is equal to the number of taps.
For a simple differentiator (y(n) = x(n) - x(n-1)), the history equals 2. Obviously, the smallest value for the history is 1.

In the work function, the number of items in your input buffer equals the number of input items plus the history minus one.
Here is an example for an accumulator that outputs the sum of the last N items:

for(unsigned int i = 0; i < noutput_items; ++i) {
    out[i] = 0;
    for (unsigned int k = 0; k < history(); ++k) {
        out[i] += in[i+k];
    }
}

As you can see, noutput_items items of out[] are written, whereas noutput_items + history() - 1 items of in[] are read from.

If the history has the value N, the first N-1 items are "old" items, i.e. they were available in the previous call to work() (when work() is called the first time, they are set to zero).

In my OOT Module, I'm trying to use a GNU Radio block or class but get an ImportError "undefined symbol". What do I do?

Your program uses functionality from a library, the compiler knows how that the interface can be used (hence, building your software works) – but it doesn't know where this functionality comes from, so when you try to run a program using the functionality, your system rightfully complains "I can't find the implementation of this function!".

This happens when you don't link against the library containing the functionility. For GNU Radio, this most commonly happens because the linker wasn't told which GNU Radio components to use.

To fix that, two things need to be done:

1. Tell the CMake build system that the target you're building has to be linked against all the necessary GNU Radio component libraries, and 2. Tell the CMake build system to look for these components.

Linking Against GNU Radio Components

In your OOT's lib/CMakeLists.txt, find

target_link_libraries(gnuradio-{your oot's name} gnuradio::gnuradio-runtime)

If your library, for example, uses components from the gr::fft namespace, you'll want to add gnuradio::gnuradio-fft:

target_link_libraries(gnuradio-{your oot's name}
        gnuradio::gnuradio-runtime
        gnuradio::gnuradio-fft
        )

Finding the Used GNU Radio Components

If you tried to build the module now, CMake will complain: You ask to link against gnuradio::gnuradio-fft, but it has no idea where that should come from. So, in the OOT's root directory's CMakeLists.txt, find the line

find_package(Gnuradio "{version of GNU Radio}" REQUIRED)

and amend it like this:


find_package(Gnuradio "{version of GNU Radio}" REQUIRED COMPONENTS
        fft
        )

How can I reconfigure a flow graph? How do I use lock(), unlock()?

A running flow graph is static, and can't be changed. There are two ways to implement reconfigurability:

  • Use lock() / unlock()
  • Create blocks that react dynamically

Using lock() and unlock(), you will actually stop the flow graph, and can then disconnect and re-connect blocks. In the following example, the flow graph will run for a second, the stop the execution (lock), disconnect the source, connect a different one, and resume. The resulting file will first have data from the vector source, then lots of zeros.

#!/usr/bin/env python
import time
from gnuradio import gr
from gnuradio import blocks


def main():
    tb = gr.top_block()
    src1 = blocks.vector_source_f(list(range(16)), repeat=True)
    throttle = blocks.throttle(gr.sizeof_float, 1e6)
    sink = blocks.file_sink(gr.sizeof_float, 'out.dat')
    tb.connect(src1, throttle, sink)
    tb.start()
    time.sleep(1)
    print("Locking flowgraph...")
    tb.lock()
    tb.disconnect(src1)
    src2 = blocks.null_source(gr.sizeof_float)
    tb.connect(src2, throttle)
    print("Unlocking flowgraph...")
    tb.unlock()
    time.sleep(2)
    tb.stop()
    tb.wait()


if __name__ == "__main__":
    main()

Note that this is not meant for sample-precision timing, but rather for situations where time does not really matter.

If sample-timing is an issue, use general blocks to react to certain events. In the following example, we assume that you have written a general block which stops reading from the first sink at a given time, and then seamlessly switches over to the second input:

#!/usr/bin/env python
import time
from gnuradio import gr
from gnuradio import blocks
import my_awesome_oot_module as myoot  # This is your custom module


def main():
    tb = gr.top_block()
    src1 = blocks.vector_source_f(list(range(16)), repeat=True)
    src2 = blocks.null_source(gr.sizeof_float)
    switch = myoot.switch()  # This is your custom block
    throttle = blocks.throttle(gr.sizeof_float, 1e6)
    sink = blocks.file_sink(gr.sizeof_float, 'out.dat')
    tb.connect(src1, switch, throttle, sink)
    tb.connect(src2, (switch, 1))
    tb.start()
    time.sleep(2)
    tb.stop()
    tb.wait()


if __name__ == "__main__":
    main()


Signal Processing

Which concepts do I need to know to start using GNU Radio?

Here's some concepts you will have to understand to fully unlock all the capabilities of GNU Radio:

  • Sampling rates / sampling theorem
  • (Equivalent) complex baseband, Complex Numbers, Negative Frequency
  • Digital signal processing (e.g. FIR filters)
  • Wireless Communications
  • Frequency/Phase/Timing Offsets

The SuggestedReading page has many good pointers to guide you into the basics.

I'm trying to perform an FFT followed by an IFFT, why doesn't my output match my input?

There are often two issues here. One is windowing and the other is scaling. The basic flowgraph is:

source --> stream_to_vector --> forward FFT --> reverse FFT --> vector_to_stream --> sink

The windowing problem is related to the fact that we use a default window in the FFT. If you're just doing the transform to be followed by an inverse transform, you don't want to window the signal because you're changing the results of the FFT. Make sure to remove the window. You can pass an empty Python list as [] to the window parameter in the FFT options, or you can use a fft.window.rectangular(fftlen), which is just a vector of 1's. Now we're just doing the pure Fourier transform.

The scaling issue is related to how the FFT algorithm computes the results. There is an internal scaling effect of fftlen (the length of your FFT). So the output of your forward FFT is fftlen times the input. We can scale this down here if we wanted to:

... forward FFT --> multiply_const_cc(fftlen*[1.0/fftlen,]) --> reverse FFT ...

Or you can wait until you're done with the IFFT to rescale:

... forward FFT --> reverse FFT --> vector_to_stream --> multiply_const_cc(1.0/fftlen) ...

Note that in the first case, we have to pass a vector of fftlen constants with the scaling value (1.0/fftlen) because we're working with vectors at this point. Waiting until after the vector_to_stream block, we only need the single scalar that is multiplied against every value. It's still the same number of multiplications in the end.

We can solve both problems at once, by setting a rectangular window that includes the scaling to [1.0/fftlen,] * fftlen.

How do I know the exact voltage/power of my received input signal?

GNU Radio processes samples coming from hardware that are mostly-linearly-proportional to the instantaneous voltage seen at the antenna terminal. But unless GNU Radio enforced a very-strict hardware interface in which those samples are rigorously calibrated to some standard amplitude by the hardware, there's no way to know anything about absolute antenna voltages, only relative ones.

A typical receiver chain has many stages of gain and loss, filtering, decimation, etc. This will produce a lot of uncertainty about the exact proportionality between the samples that Gnu Radio processes (typically float-point values in the range {-1.0,+1.0}) and the actual voltage as seen at the antenna port.

What this means is that you must manually calibrate, over your expected operating conditions, if absolute power measurements are important to your application. This is typically accomplished use a calibrated noise source, or calibrated laboratory signal generator combined with calibrated attenuators so that you can measure at multiple points in the calibration curve.

Why doesn't my signal match the textbook?

Matt Ettus did a good talk on this.

Applications

I have a receiver with an audio sink, and keep getting aUaUaU errors?

First of all, those

aUaU

things are called 'audio underruns'.

If your flow graph looks like this:

Radio Hardware -> Demodulator -> Audio Sink

...and you see those errors, it's most likely a "2-clock-problem". The issue is, you have 2 pieces of hardware with a clock, and there's no way to perfectly align them. There are many failure modes here, but a very obvious one is this: Imagine the radio clock is ever so slightly slower than advertised, and the audio clock is faster. Then, invariably, at some point, there will be not enough data to feed into the audio sink and it will underrun. Also, remember that GNU Radio shuffles data in chunks, so there may be enough data, but not in the precise moment when the audio sink needs it.

A simple workaround is to set the Audio Sink parameter "Ok to Block" to "No". Beyond that, refer to ALSAPulseAudio#Working_with_ALSA_and_Pulse_Audio.

My application segfaults immediately. It used to work, and I didn't change it. What happened?

Most often, you updated some underlying component (e.g. UHD, gr-osmosdr, etc.) without
recompiling GNU Radio. If ABI breaks, segfaults are the expected behaviour.

If you can't track down the offending module, re-link them all. If you are using UHD from source,
start with that, then GNU Radio, then all of the OOTs.

The Community: Where you get help, advice and code

Where can I get help?

Help can be found in a number of places, such as:

How do I ask a question on the mailing list?

When posting to the mailing list, make sure that you've read our guide on reporting errors and asking questions. This is very important, and will help you get a good answer faster.

Please do not send private emails to the GNU Radio developers as they will just direct you back to the mailing list.

What if no one answers?

If you've asked on the mailing list and haven't received an answer, wait a bit longer. We are all pretty busy people and it can often take us a few days to get through our emails. If you're lucky and someone with the answer is free or if the question is simple enough, you might get an answer quickly. But don't worry if it's been a couple of days, and don't ask again too soon! Remember, you are asking others to do free work for you. Most of the time, someone will help you, but you have no claim on this.

Likewise on IRC, we are often away from our keyboard, and many might be in different time zones from your own. Again, be patient.

I have a really "stupid" question...

You might have read a number of the books and other suggested reading materials. You might then have gone through our list of tutorials. Maybe you've even been working in radio and communications for years. And yet you have a question that you think is simple or even "stupid". Well, we all have those questions and we could all benefit from good, open discussions of those questions.

Our IRC Channel and mailing list are good places to ask your questions. We don't like answering them in private, however, because even for questions you might think are stupid, others will have them too. Answering them in the public forum of our list makes them available for others to search later.

How do I report a bug?

See Reporting Errors.

Who runs GNU Radio?

See Organization & Leadership on the project homepage.