On Fri, Sep 03, 2010 at 10:09:01PM -0400, Marcus D. Leech wrote:
I’ve got a flow-graph with a throttled random byte source, which is a
test input for a modulator:
The source is throttled to the byte rate required to produce the correct
number of symbols/second (4800).
The throttle block was written so that the GUI elements could be
tested without an inherently rate limiting source being in the graph.
It is not designed to precisely rate limit anything. For any use
other than that, you’re asking for trouble. Think about it: what
definitely of time to you use? Over what period of time do you
average, etc, etc.
- \brief throttle flow of samples such that the average rate does not
- \ingroup misc_blk
- input: one stream of itemsize; output: one stream of itemsize
- N.B. this should only be used in GUI apps where there is no other
- rate limiting block. It is not intended nor effective at precisely
- controlling the rate of samples. That should be controlled by a
- source or sink tied to sample clock. E.g., a USRP or audio card.
What I’ve noticed is that this graph only runs in “fits and starts”,
rather than continuously. I assume this has something to
do with the Gnu Radio buffering and internal scheduler.
In the case of a “real” flow-graph, taking real data in at
4800symbols/second, going to a real USRP transmitter, will it still
run in “fits and starts” or will it “do the right thing”??
It will do the right thing, assuming that all blocks “do the right
thing” and compute as much output as they are asked to.
I realize that buffering is an important part of Gnu Radio, but how do
you actually send low-rate data in something approaching
You don’t send it at the right rate, you let the sink (or source)
handle the timing issues.
Note that NONE of GNU Radio has any idea of the actual sample rate.
There are some places where sample rates are used (e.g.,
gr.sig_source), but they are there as a convenience so that people
don’t have to continually puzzle over normalized frequencies.
However, this may give the impression that “sample_rate” actually
means something in the real world, and it doesn’t — with the exception
of i/o devices connected to a sample clock.
I at first thought this was due to the throttle block, so I replaced it
with an external (via a FIFO) source that produced random bytes
at a 1200-bytes/second rate (2 bits/symbol), and it behaves exactly
the same as a a throttled random source–the graph seems to run in
“fits and starts”.
The display may appear to run in “fits and starts” because the
internal decimation rate of the sink may be too high for the throttled
data rate that you’re sending. It may take a long time to get enough
data for the FFT sink to display anything. Or there could be bugs in
E.g., the GL fft sink has at least a bug or two related to the
mis-specification of python’s ‘/’ operator. If you use integers,
1/3 == 0, but 1.0/3 = .3333 The bug I’m thinking of shows up as a
by zero in the persistence code when the ftt sink is invoked with its
default parameters (sample_rate = 1, fft_rate = 15). There may also
be problems with mapping the user provided fft_rate into the
decimation factor of the keep_one_in_n block. Not sure about that
one, but this is a place where it’s possible to ask for ill-specified
behavior. E.g., if I say that the fft_rate is 15, and my sample rate
is 1, do I expect interpolation by 15???
See Python PEP-238 for background on the divide issue and the use of
from future import division
to debork the behavior of ‘/’, and possibly help fix the sinks.
If you want to see the details of what the scheduler is doing,
#define ENABLE_LOGGING 0
#define ENABLE_LOGGING 1
at the top of gr_block_executor.cc It will then create a separate ASCII
log file for each block. They’re named “sst-NNN.log”. The first line
of each log identifies the block.
Hope this helps!