<div dir="ltr">Hello Spencer,<div><br></div><div>You should avoid underflows and overflows. Those are errors and should never be allowed to happen. If you don&#39;t have any signal then just write silence (zeros) to keep the stream from underflowing. Or, if you don&#39;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.</div><div><br></div><div>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&#39;t block waiting for user events because then you will underflow the audio.</div><div><br></div><div>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?</div><div><br></div><div>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.</div><div><br></div><div>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.</div><div><br></div><div>Phil Burk</div><div><br></div><div><br></div><div><br></div></div><div class="gmail_extra"><br><div class="gmail_quote">On Sat, Mar 19, 2016 at 8:46 PM, Spencer Russell <span dir="ltr">&lt;<a href="mailto:sfr@media.mit.edu" target="_blank">sfr@media.mit.edu</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">I’m working on the Julia PortAudio package, so<br>
1. Not thread-safe<br>
2. event-loop concurrency<br>
3. unbounded pause times due to JIT and GC<br>
<br>
The abstraction I present to users of my library is a stream read/write API, so I have two options:<br>
<br>
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.<br>
<br>
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).<br>
<br>
So I guess the question probably comes down to:<br>
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”.<br>
<br>
If the underflow is passed to the Host API, in practice are there APIs in the wild that react poorly, or is it OK?<br>
<br>
Thanks,<br>
-s<br>
_______________________________________________<br>
Portaudio mailing list<br>
<a href="mailto:Portaudio@lists.columbia.edu">Portaudio@lists.columbia.edu</a><br>
<a href="https://lists.columbia.edu/mailman/listinfo/portaudio" rel="noreferrer" target="_blank">https://lists.columbia.edu/mailman/listinfo/portaudio</a></blockquote></div><br></div>