[BUG?] Setting (start_threshold > stop_threshold) makes snd_pcm_writei(a_small_buffer) XRUN immediately

Geraldo Nascimento geraldogabriel at gmail.com
Sat Oct 2 06:45:33 CEST 2021


On Fri, Oct 01, 2021 at 10:01:34PM -0300, Geraldo Nascimento wrote:
> On Fri, Oct 01, 2021 at 08:33:23PM -0300, Geraldo Nascimento wrote:
> > On Sat, Oct 02, 2021 at 01:31:12AM +0800, Zhang Boyang wrote:
> > > Hello,
> > 
> > Hello, Zhang!
> > 
> > > 
> > >    I'm using ALSA to develop an audio-streaming application. I try to 
> > > use start_threshold and stop_threshold in combination with small 
> > > buffers. However, I think I probably found a bug about this.
> > >    I'm setting start_threshold=100 and stop_threshold=50. I'm also using 
> > > a buffer of 44 frames. When I call 
> > > snd_pcm_writei(the_small_44_frames_buffer), pcm state came to XRUN from 
> > > PREPARED directly. I think this is a bug because the stream hasn't 
> > > started. It's hard to say a xrun occurred while stream not started.
> > >    I'm wondering if this is a ALSA-bug or a misuse of ALSA. A simple bug 
> > > test program is attached.
> > 
> > No, I don't think it's a bug. You're bound to run into problems with a
> > period size of only 44 frames.
> > 
> > Moreover, working with the code you provided, I was able to get a RUNNING
> > state without XRUNs with a period size of 4410 frames (100 milliseconds of
> > audio) but I had to comment out snd_pcm_sw_params_set_stop_threshold() for
> > it to work or I'd have those instant XRUNs.
> > 
> > That's how snd_pcm_sw_params_set_stop_threshold() is supposed to work by
> > the way. It creates a XRUN once the threshold is hit.
> 
> Oh, and snd_pcm_sw_params_set_stop_threshold() is a little
> counter-intuitive. The threshold you give the function is compared to
> the available free space in the ring buffer, not the filled space.
> 
> That's why lowering the stop threshold makes XRUNs more likely...
> 
> Thanks,
> Geraldo Nascimento

Zhang,

I was able to make your code work in the end, even with 44 frames
writes, which is unadvisable since it eats too much CPU specially if
they are low-end like the ARM64 box I'm writing you from.

The trick was to use high values such as 500000. Lower values such as
250000 were enough to trigger XRUNs in my machine. Of course you can set
it to -1 and it will ignore XRUNs but that's a bit like setting it to
16777216 or 4096 * 4096 which is a hardcoded limit in alsa-lib, I
believe.

And plainly ignoring XRUNs may sound bad under load, believe me.

Thank you,
Geraldo Nascimento




More information about the Alsa-devel mailing list