STS Question

I’m in the process of debugging some OSX audio issue(s). I’ve fixed
a few bugs in the OSX audio module (and also OSX/Darwin for USRP),
that might occur in unusual circumstances. But I’m still seeing the
same issue: when using an audio source, I get audio overruns -
meaning that the audio data is coming in too fast - when the FG I’m
using has any significant processing, e.g. 2 or 3 FIR filtering
operations. I’m using a Core 2 Duo iMac @ 2.16 GHz, and the CPU
utilization is ~50% of 1 processor, so I doubt that the issue is not
enough CPU time.

This issue can be repeated, with enough waiting, when using any scope
or not, so it’s not in the scope or message queue.

I’ve fixed the obvious multi-thread mutex protection issues in the
OSX audio module such that the audio source keeps generating data no
matter overflow or not, so I doubt that the OSX audio module is an
issue any longer.

Thus I started reviewing “gr_single_threaded_scheduler::main_loop()”
from gr_single_threaded_scheduler.cc. Starting on line 165, the code
reads
+++++++++++++++
if (d->source_p ()){
// Invoke sources as a last resort. As long as the previous pass
// made progress, don’t call a source.

   if (made_progress_last_pass){

LOG(*d_log << " Skipping source\n");
goto next_block;
}
+++++++++++++++
I enabled debugging in the OSX audio module and logging in the
scheduler (and moved logging to std::cerr, so-as to get both outputs
in the same stream) and can thus review/“see” the data flow in from
the audio source and through the FG.

With that code in place (not commented out), reviewing the debugging
output, the audio module is slowly accumulating extra data in its
buffers, which eventually leads to an overflow. What seems to be
happening is that, because the scheduler is making progress with each
pass - just a little bit here and there-, and thus
“made_progress_last_pass” is ‘true’, the scheduler is not getting
source data often enough to avoid the overflow. The scheduler “pipe”
bursts with new audio data, then trickles until nothing further can
be processed, which for some reason takes a “long” time, then bursts
again and repeats.

If I comment the “if (made_progress_last_pass){” part out, recompile
and reinstall, then I can run the exact same programs without audio
overruns. Reviewing the log, the data is coming in as fast as it is
being processed - no more, no less. The audio buffers never hold the
data long enough to overflow. The scheduler “pipe” bursts with new
audio data, then reduces to a trickle for a bit until new audio data
is available, then bursts again. The “burst” and “trickle” pattern
repeats much like with the code in place, but “much faster”.

Since the source is what regulates the FG throughput (and/or a
throttle, if needed), IMHO the source should be allowed to enter data
into the scheduler “pipe” as often as it needs to. This would seem
to keep the scheduler’s pipes “more full” than the current
implementation, reducing the chances of data overflow or underrun.

I have not tested this to see if it happens on Linux or Windows.

Thoughts? Questions? - MLD

On Fri, Aug 17, 2007 at 12:11:35PM -0400, Michael D. wrote:

This issue can be repeated, with enough waiting, when using any scope
or not, so it’s not in the scope or message queue.

What’s your test case?

Is there a USRP involved? If so, then you have the “two clocks”
problem.

  // Invoke sources as a last resort.  As long as the previous pass

the audio source and through the FG.
again and repeats.
What’s downstream in your flow graph?

throttle, if needed), IMHO the source should be allowed to enter data
into the scheduler “pipe” as often as it needs to. This would seem
to keep the scheduler’s pipes “more full” than the current
implementation, reducing the chances of data overflow or underrun.

The reason that sources are called as a last resort is to avoid
stalling the pipeline while there is still progress that can be
made. Removing the check for made_progress_last_pass will break
existing code.

I have not tested this to see if it happens on Linux or Windows.

Thoughts? Questions? - MLD

Build some very simple test cases and start with them. E.g.,

audio.source_c -> file.sink
audio.source_c -> gr.add_const_ff -> file.sink

I suspect that there is still some problem in the audio source.
When work is called, does it return as much data as it can?

Eric