[alsa-devel] Problems with rate plugin and writing sizes other than the period size
This is a problem I've been able to duplicate on multiple systems with different hardware.
If one sets up rate conversion, from 22050 Hz to 48000 Hz, which is a non-integer ratio, then a hw params with two periods doesn't work if you write greater than the period size. An audio underrun occurs after each period.
Tracing with both strace and inside the driver reveals what's going on. The first snd_pcm_writei() goes through and the driver receives the appropriate number of rate converted frames. On the next snd_pcm_writei() alsa-lib calls poll() to wait for space to be available in the buffer. avail_min is set to one period, and there is less than one period left in the buffer, since the first write wrote more than one period. Eventually avail is greater than avail_min and poll returns. So far as expected. Now here's the problem, rather than writing a period alsa-lib just calls poll() again. Which returns immediately since there is still greater than avail_min available space in the buffer. And this continues, with alsa-lib in a tight loop calling poll() and poll() returning immediately, until the buffer empties and underflow occurs.
If the number of periods is increased the same thing happens, without the underflow each period. Alsa-lib will wait until there are TWO empty periods in the buffer, in a tight loop calling poll() which returns immediately while avail is greater avail_min and less than two periods worth. It's basically like the avail_min setting has been changed to period_size*2 as far as alsa-lib is concerned, so of course two periods will always cause underruns. More than two work without certain underruns, but alsa-lib is sitting in a tight loop because it keeps calling poll() even though avail > avail_min.
Anyone know what's going on here? Seems like a bug in alsa-lib, but I find it hard to believe no one would have noticed this before.
participants (1)
-
Trent Piepho