At Tue, 24 Feb 2009 19:46:05 +0100, Lennart Poettering wrote:
On Tue, 24.02.09 17:27, Takashi Iwai (tiwai@suse.de) wrote:
Moreover I can now reproduce the same issue on snd-intel8x0, albeit it takes more than a couple of minutes to make snd_pcm_avail() return bogus data.
Somehow I get the feeling the problem is not so much the inaccuracy of the pointer the kernel reports but in what alsa-libs does ith it.
Hrm... both cases the pointer calculation is relatively simple, and for "hw" PCM, the avail calculation is also very straightforward. So, my first suspect is about the pointer calculation. But, of course we should check all possibilities.
Can you give a small testcase?
Ok, here's a little test case:
http://git.0pointer.de/?p=pulseaudio.git;a=blob_plain;f=src/tests/alsa-time-...
Finally have time to go back to this issue again now.
With your test case, indeed I get abort(), too. However, checking through the code, you set stop_threshold to the boundary size like:
r = snd_pcm_sw_params_get_boundary(swparams, &boundary); r = snd_pcm_sw_params_set_stop_threshold(pcm, swparams, boundary);
This means essentially you are disabling the XRUN detection in the driver and keep it free-running. So, no wonder avail gets over buffer_size. It's actually an XRUN condition, but just ignored due to this setup. (Usually, stop_threshould == buffer_size.)
Yes, threshold is set to boundary. But that's intended. Remember that the original purpose of the tool is to graph _avail() and _delay() against the time. For that I want to make sure the that timing stays stable no matter what.
In reality this setting should not matter at all, because most machines should be fast enough to keep the buffer filled even if we write one sample at a time as it is done in the example.
Not really. If you feed the output to a terminal, it's damn slow. That's why I got XRUN.
The problems exposed in all the test data posted here for the various sound cards are not normal normal buffer underruns.
Well, basically "avail >= buffer_size" means the underrun per definition. The state isn't changed and kept as RUNNING just because of the stop_threshold value.
In summary: just ignore the setting of the stop threshold. It is not related to the problems exposed here.
FWIW, when I run the program and feed the output to /dev/null, I don't get abort() after minutes. It happened soon only when it runs on a terminal. So, the condition appears very likely as an XRUN.
So, try to set stop_threshold to buffer_size once, and check whether you get any different result. Let's check another possibility if it really isn't the case.
Takashi