On Thu, 2008-12-04 at 17:07 -0500, [email protected] wrote:
I am considering if I should create gnuradio blocks to detect DTMF,
AFSK, and other digital transmission modes that I currently detect
using multimon (http://www.baycom.org/~tom/ham/linux/multimon.html).
I have no USRP yet. I just use the audio from a VHF/UHF amateur radio
attached to my PC sound card.
This is fine. GNU Radio blocks that work on audio rate input from sound
cards don’t need changing to work with audio rate data produced from the
output of demodulators or other blocks that ultimately get their data
from something like the USRP.
Since I’m new to gnuradio, I’d appreciate anyone’s ideas on what
should be the inputs and outputs of these gnuradio blocks. Also,
does anyone think these blocks might be useful sometime to someone
other than myself?
Regarding DTMF detection, there already exists a tone-detection utility
that uses the Goertzel DFT optimization to detect the presence of a
particular frequency in the data. You could use eight instances of this
with appropriate combinatorial logic to output DTMF detection events.
(Actually, I think that is what multimon itself does, if I recall
But it depends on how you want to use these detection events.
Traditional GNU Radio flowgraphs terminate in some sort of data sink
that communicates with the outside world. If you’re simply trying to
replicate a multimon type text output, you can “printf” from your
detection block. If you want to interact with something non-GNU Radio,
like a GUI or some other logic, you need to consider how to signal the
start and stop of a detection event to this external code (see below).
I have years of professional experience developing softare in C and C++
as part of large projects, but I have no gnuradio experience (yet), except
for writing a simple example gnuradio application in Python and writing
a simple example gnuradio block in C++.
This is a great start.
Do these DTMF and AFSK detector blocks seem like they should be gnuradio
‘mblocks’ instead of gr-blocks?
This is one of those cases we have not done very well in addressing,
where the input data comes from the continuous data flow domain of an
audio card input source or the output of an RF demodulator, yet the
output needs to be a set of discrete events that interacts with the
Traditionally, the way we have handled this has been to convert the
events into some stream of data as a block output, then wire this to a
special I/O block called a message sink. The message sink maintains a
FIFO of fixed size items which have a thread-safe query mechanism to
retrieve items posted to the queue. It works, but is somewhat crude.
Code outside the GNU Radio flowgraph can make blocking or non-blocking
calls to retrieve items and generate events in some other domain.
For example, we use this mechanism in the graphical FFT displays. The
FFT vectors are created by the GNU Radio flowgraph, but the flowgraph
itself terminates in a message sink. A separate thread, created in
Python and not part of the GNU Radio flowgraph, queries the message
queue and posts wxPython window events to the display as the vectors
come in to the message sink and get added to the queue.
The gr-pager application works similarly, in that the flowgraph does the
FLEX pager decoding and generates a stream of decoded pages as vectors
and sends these to a message sink. A separate thread queries the
message sink and displays the pages to the screen sequentially.
So to your original question, the short-term answer is that you should
implement a C++ block in traditional gr-block format that outputs DTMF
digits sequentially. Wire it to a message sink in your flowgraph and
you can write code outside GNU Radio proper to query the queue and do
whatever you want with them.
The mblock library was supposed to be a way to address this, as it works
entirely in the message passing domain, yet as I stated in an earlier
email, the bridge between the streaming domain and mblock domain has
never been implemented in an acceptable way. We are now looking at
adding event passing to the traditional gr-block world such that blocks
can be written that accept and produce either message events or
streaming data. In that case you’d write a block that would take in
streaming audio data and generate DTMF symbol detection events.
Regarding AFSK, that is clearly a streaming block that would convert
audio samples into bits at a fixed input to output sample ratio. The
audio input would either come from a soundcard input source or from a
narrowband FM demodulator block (which already exists.) You’d probably
then write another block that does the deframing on the input bits and
generates a series of payload packets and ultimately sends these to a
message sink. This is similar to gr-pager that uses an MFSK demodulator
to get to bits and then a deframing sink that outputs individual pages.