At Wed, 11 Jun 2008 21:24:20 +0100, Colin Guthrie wrote:
Takashi Iwai wrote:
At Mon, 9 Jun 2008 21:02:25 +0200, Lennart Poettering wrote:
Takashi, Jaroslav,
could you please explain what exactly snd_pcm_delay() returns?
Some applications (such as WINE) assume it is the time that would pass until we reach an underrun if we would stop writing any further data to the PCM device.
Other applications (such as most media players) use it for time synchronisation. i.e. assume that it is the time that passes until a sample I write to a PCM device now would take to be played.
As James already pointed, the correct answer is the latter. In the driver implementation level, snd_pcm_delay() simply returns the difference between appl_ptr and hw_ptr. It means how many samples are ahead on the buffer from the point currently being played.
However, if you stop feeding samples now, snd_pcm_delay() returns the least time XRUN occurs. So the first understanding isn't 100% wrong.
snip
The implementation of snd_pcm_delay() (at least in the driver level) purely depends on the accuracy of PCM pointer callback of each driver. So, if the driver returns more accurate hw_ptr via pointer callback, you'll get more accurate value of snd_pcm_delay(). In the worst case, it may be bigger up to one period size than the real delay.
I could be wrong here as I'm only going on discussions I've had with wine folks rather than poking at the code myself (I did look a while back but I've forgotten it all now!).
AFAIK, the way Wine uses snd_pcm_delay() is to check when a sample is fully played. e.g. they wait for the function to return 0.
It returns 0 or a negative value, or returns error EPIPE which means buffer underrun, dependong on the setup. XRUN detection can be disabled.
Anyway, use snd_pcm_delay() to determine the hwptr is correct. But, of course, this doesn't guarantee the accuracy of hwptr because its accuracy depends on the driver.
I think this was done due to the docs specifically say that it is the "difference between appl_ptr and hw_ptr" so it makes sense to assume this will return 0 when there is nothing waiting to be played. I would strongly recommend that you remove the implementation detail from the (supposedly high level) docs.
Why? I don't see your logic...
Takashi