At Thu, 22 Jan 2009 23:20:15 +0100, Lennart Poettering wrote:
On Wed, 21.01.09 01:39, Takashi Iwai (tiwai@suse.de) wrote:
The function should look like this:
snd_pcm_sframes_t snd_pcm_busy_for(snd_pcm_t *pcm);
I called the prototype "busy for" since effectively the value I am looking for is the time the card will be busy with the data it already has, and doesn't need any new data.
Isn't it snd_pcm_delay() that was originally designed for?
No. Let me summarize the meaning of snd_pcm_update_avail(), snd_pcm_delay() and my snd_pcm_busy_for() to opefully make clear where the differences are:
snd_pcm_update_avail() -- returns how many samples can be written right now without blocking.
snd_pcm_delay() -- returns how many samples will be played before the samples that are written now can be heard.
snd_pcm_busy_for() -- returns how many samples will be played before ALSA would enter an underrun situation if no further samples are written.
Well, in a ring-buffer model,
snd_pcm_busy_for = buffer_size - snd_pcm_update_avail
If a granularity matters (e.g. no accurate sample position update can be done), it would be
snd_pcm_busy_for = max{0, buffer_size - s_p_u_a - granularity}
The granularity is between 0 and period_size. The batch-mode is granularity = period_size.
snd_pcm_update_avail() and snd_pcm_busy_for() return metrics that are solely dependant on the size and metrics of the hardware buffer and its current indexes. snd_pcm_delay() also includes information about any extra latency that comes after the playback buffer.
Onle snd_pcm_update_avail()/snd_pcm_busy_for() are influenced by "fast starts" as done by the USB driver's double buffering and by block-based transfer.
Hmm, I am trying my best to explain why I want this function and what exactly it should do. Any chance I can convince you guys that this function really matters for timer-based audio scheduling?
I don't care much about the user-space API at this moment. My main concern is what kernel <-> user API is needed in addition or needed to be changed.
If it's a question how to pass the granularity to user-space, usually it's a constant value, and thus it can be put somewhere in the existing struct, or add a single ioctl.
OTOH, if it has to be implemented as a form of snd_pcm_busy_for(), the kernel needs the compuation like the above. That's my concern.
Did you check my previous patch?
You mean the one that makes snd_pcm_delay() for USB devices actually include the extra latency that comes after the playback buffer? No, I didn't check that one yet. It takes so much time to patch the kernel and test things... I'll try too finally do it this WE.
Hehe, changing API (should) take time, too :)
Takashi