[Portaudio] Do I need to care about overflow/underflow when using the read/write API?

Phil Burk philburk at mobileer.com
Sun Mar 20 00:36:43 EDT 2016


Hello Spencer,

You should avoid underflows and overflows. Those are errors and should
never be allowed to happen. If you don't have any signal then just write
silence (zeros) to keep the stream from underflowing. Or, if you don't plan
on doing any audio for a few minutes then you could just shut down the
stream and restart it when you are ready.

Regarding event loops ... if you are doing the audio in the event loop then
you should only block on the audio read or write and then just poll the
user event loop to see if there are any events to process. Don't block
waiting for user events because then you will underflow the audio.

How important is latency in your app? Does it have to be low latency, like
a game or drum pad? Or can it be high latency, like a song player?

Another approach is to run the audio synthesis in a callback and then just
send custom commands to your synthesis task through an atomic ring buffer.
See pa_ringbuffer.c. That is what I usually do.

Also not that if you are doing both audio input and output then you should
start with the input empty and the output full. That way if the app gets
hung up the input will fill and the output will drain symmetrically.

Phil Burk




On Sat, Mar 19, 2016 at 8:46 PM, Spencer Russell <sfr at media.mit.edu> wrote:

> I’m working on the Julia PortAudio package, so
> 1. Not thread-safe
> 2. event-loop concurrency
> 3. unbounded pause times due to JIT and GC
>
> The abstraction I present to users of my library is a stream read/write
> API, so I have two options:
>
> 1. I could have a background task (in the event loop) running with in/out
> ringbuffers that is polling PortAudio and feeding it whenever there’s
> space/data available, feeding with zeros if my Julia-side ringbuffer is
> empty. The idea here is to avoid overflow/underflow on the portaudio side,
> but it’s still not guaranteed. The issue here is that I’d want the
> portaudio buffer to be large to cover pauses (several seconds), but then
> when my user calls `write(sink, audiobuffer)`, they’re going to experience
> the buffer-length of delay before they hear the audio.
>
> 2. I could Only read/write to PortAudio in my library’s read/write
> methods, so in between reads and writes I expect to be an an
> overflow/underflow condition most of the time. Then when the user calls
> `write` it starts writing into PortAudio until we’ve written all the data,
> then we stop. This is nice because it avoids having a polling task all the
> time (it’ll still poll during reads/writes).
>
> So I guess the question probably comes down to:
> When PortAudio experiences an underflow, does it feed zeros to the
> underlying Host API, or does the Host API “know” about the underflow? Based
> on my experience lurking on this list I’m guessing the answer is “it
> depends on the host API”.
>
> If the underflow is passed to the Host API, in practice are there APIs in
> the wild that react poorly, or is it OK?
>
> Thanks,
> -s
> _______________________________________________
> Portaudio mailing list
> Portaudio at lists.columbia.edu
> https://lists.columbia.edu/mailman/listinfo/portaudio
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.columbia.edu/pipermail/portaudio/attachments/20160319/fbf474ee/attachment.html>


More information about the Portaudio mailing list