On Wed, Oct 06, 2010 at 04:35:14PM +0200, Remco wrote:
> >> ... endless clicking noise intermixed with music ...
> 
> > sounds like the mp "delayed interrupt notification" issue that wreaks
> > havoc on audio.
> > 
> 
> I don't know if I'm telling anything new and whether this is useful.
> (my coding skills may be lacking as well)
> 
> I seem to be able to reproduce the following reliably:
> 
> When I create a producer/consumer loop using circular buffers where the
> producer (WAVE file) is much faster than the consumer (audio device), using
> polling to see whether there is work to do for either the producer or
> consumer:

Note that you can't poll() a file. It always returns POLLIN. So
there's no way to implement a true non-blocking program with a
poll()-based event loop; the program will always block for typically
around 50-100ms. This is not a problem as long as audio buffers are
large enough.

> - in blocking mode everything seems fine:
> 
> The producer fills the buffers, if it overruns it's paused. The consumer
> takes the buffers one at the time and when it's about to underrun it
> resumes the producer. This seems to produce uninterrupted sound just fine.
>

fine, this works because the producer manages to fill the buffer fast
enough, i.e. before the device buffer underruns. This is part of the
``my producer is fast'' hypothesis.

> - in non-blocking mode:
> 
> This basically follows the same procedure as with blocking mode. However, it
> appears that the audio device becomes available prematurely. (within a few
> ms independent of the amount of data that was written)
> e.g.: when I try to send the audio data in ~20ms chunks, I hear a lot of
> clicks, and the audio appears to be sped up somewhat.
> Increasing the length of the audio chunks (~2s) makes it sound like it is in
> fast forward. Just a few ms of each 2s buffer appear to be played before
> advancing to the next buffer skipping over the song really fast, playing
> only tiny fragments of the song.

sounds that fifo pointers are not correct, may by the return value of
write() (or sio_write() if you're using libsndio) are not taken into
account correctly.

> It doesn't necessarily seem to be related to sndio/aucat. I seem to get the
> same results with audio(4).
> 
> I was expecting the writes to the audio device to fail (EAGAIN) if the
> previous buffer isn't done playing yet. Basically I don't expect POLLOUT to
> be set until all software buffers have been drained and the data has been
> written to the device completely.

write(2) returns EAGAIN if the device buffer is full (no space
available) and POLLOUT is set as soon as there's some space available.
This behaviour is desirables. If all the data was processed by the
device it would underrun, and the sound would stutter.

What you describe is surprising since using a poll() and non-blocking
write() is somewhat equivalent to a blocking write.

-- Alexandre

Reply via email to