* snd_pcm_drain and partial periods
[not found] <CA+7tXihfkZd6+UmnwJiyLgwo+6PoU9fWvzNhz7FKzy7DNgAWMw@mail.gmail.com>
@ 2011-11-23 23:44 ` Trent Piepho
2011-11-24 14:17 ` Clemens Ladisch
0 siblings, 1 reply; 6+ messages in thread
From: Trent Piepho @ 2011-11-23 23:44 UTC (permalink / raw)
To: alsa-devel
Say an application does not write a full multiple of the period size
with snd_pcm_writei(). It's playing a clip and the clip ends and it
doesn't happen to end on a multiple of 6000 frames or whatever the
period size is.
Now the application calls snd_pcm_drain() to wait for the clip to finish.
How does the driver know to stop when it gets to the end of the
supplied data? I don't see anywhere where this will get taken care
of. It seems like the driver will keep playing until it calls
snd_pcm_period_elapsed() at the end of the final period. Then the
alsa pcm layer will call the ->trigger() method and stop the stream.
Hopefully before the driver has started the next DMA for the next
period! The application only wrote data for part of the final
period, so the driver will have played past the end of the supplied
data.
I don't see any documentation that says you must always supply a
multiple of the period size with snd_pcm_write[in](). Nor about how
to deal with non-blocking mode and only part of the data getting
written.
I don't see any documentation for snd_pcm_drain() that says it will
keep playing until it finishes a period, even if the data runs out
before hand. "For playback wait for all pending frames to be played
and then stop the PCM." Seems pretty clear that only the pending
frames are played and not the rest of a period.
Yet the driver I'm working on definitely keeps playing to the end of
the period on drain. Could be a driver problem, but I don't see how
any other drivers do anything differently here.
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: snd_pcm_drain and partial periods
2011-11-23 23:44 ` snd_pcm_drain and partial periods Trent Piepho
@ 2011-11-24 14:17 ` Clemens Ladisch
2011-11-25 16:37 ` Trent Piepho
2011-11-28 1:16 ` Raymond Yau
0 siblings, 2 replies; 6+ messages in thread
From: Clemens Ladisch @ 2011-11-24 14:17 UTC (permalink / raw)
To: Trent Piepho; +Cc: alsa-devel
Trent Piepho wrote:
> Say an application does not write a full multiple of the period size
> with snd_pcm_writei(). It's playing a clip and the clip ends and it
> doesn't happen to end on a multiple of 6000 frames or whatever the
> period size is.
>
> Now the application calls snd_pcm_drain() to wait for the clip to finish.
>
> How does the driver know to stop when it gets to the end of the
> supplied data?
It doesn't.
> It seems like the driver will keep playing until it calls
> snd_pcm_period_elapsed() at the end of the final period. Then the
> alsa pcm layer will call the ->trigger() method and stop the stream.
Yes.
> Hopefully before the driver has started the next DMA for the next
> period!
Let's hope that the FIFOs are large enough so that the actual playback
hasn't yet reached the period boundary ...
> I don't see any documentation for snd_pcm_drain() that says it will
> keep playing until it finishes a period, even if the data runs out
> before hand. "For playback wait for all pending frames to be played
> and then stop the PCM." Seems pretty clear that only the pending
> frames are played and not the rest of a period.
ALSA will stop the device when it realizes that it has run out of data
(just like an underrun). This might happen before the period boundary
if there is some call to snd_pcm_status() or _delay() that reads the
current position (and if the hardware also supports reading the current
position).
It's racy and undocumented, but there's nothing a driver can do about
this.
Regards,
Clemens
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: snd_pcm_drain and partial periods
2011-11-24 14:17 ` Clemens Ladisch
@ 2011-11-25 16:37 ` Trent Piepho
2011-11-25 17:38 ` Clemens Ladisch
2011-11-28 1:16 ` Raymond Yau
1 sibling, 1 reply; 6+ messages in thread
From: Trent Piepho @ 2011-11-25 16:37 UTC (permalink / raw)
To: Clemens Ladisch; +Cc: alsa-devel
When the driver schedules the final period, couldn't it check if the
device is draining, and if so try to end playback at the right time.
Of course, it would need to be able to play less than a period of
audio do that.
What is the proper way the finish playing if snd_pcm_drain() will go
past the end of the audio?
On Thu, Nov 24, 2011 at 9:17 AM, Clemens Ladisch <clemens@ladisch.de> wrote:
> Trent Piepho wrote:
>> Say an application does not write a full multiple of the period size
>> with snd_pcm_writei(). It's playing a clip and the clip ends and it
>> doesn't happen to end on a multiple of 6000 frames or whatever the
>> period size is.
>>
>> Now the application calls snd_pcm_drain() to wait for the clip to finish.
>>
>> How does the driver know to stop when it gets to the end of the
>> supplied data?
>
> It doesn't.
>
>> It seems like the driver will keep playing until it calls
>> snd_pcm_period_elapsed() at the end of the final period. Then the
>> alsa pcm layer will call the ->trigger() method and stop the stream.
>
> Yes.
>
>> Hopefully before the driver has started the next DMA for the next
>> period!
>
> Let's hope that the FIFOs are large enough so that the actual playback
> hasn't yet reached the period boundary ...
>
>> I don't see any documentation for snd_pcm_drain() that says it will
>> keep playing until it finishes a period, even if the data runs out
>> before hand. "For playback wait for all pending frames to be played
>> and then stop the PCM." Seems pretty clear that only the pending
>> frames are played and not the rest of a period.
>
> ALSA will stop the device when it realizes that it has run out of data
> (just like an underrun). This might happen before the period boundary
> if there is some call to snd_pcm_status() or _delay() that reads the
> current position (and if the hardware also supports reading the current
> position).
>
>
> It's racy and undocumented, but there's nothing a driver can do about
> this.
>
>
> Regards,
> Clemens
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: snd_pcm_drain and partial periods
2011-11-25 16:37 ` Trent Piepho
@ 2011-11-25 17:38 ` Clemens Ladisch
2011-11-27 6:05 ` Trent Piepho
0 siblings, 1 reply; 6+ messages in thread
From: Clemens Ladisch @ 2011-11-25 17:38 UTC (permalink / raw)
To: Trent Piepho; +Cc: alsa-devel
Trent Piepho wrote:
> When the driver schedules the final period, couldn't it check if the
> device is draining, and if so try to end playback at the right time.
The ALSA framework was designed for cards where DMA doesn't need to
be scheduled continuously, so it is assumed that stopping happens
asynchronously.
You could try to check the PCM state, but it's possible that the call
to snd_pcm_drain() happens after you've scheduled the final period.
Regards,
Clemens
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: snd_pcm_drain and partial periods
2011-11-25 17:38 ` Clemens Ladisch
@ 2011-11-27 6:05 ` Trent Piepho
0 siblings, 0 replies; 6+ messages in thread
From: Trent Piepho @ 2011-11-27 6:05 UTC (permalink / raw)
Cc: alsa-devel
Interesting, what the correct way to stop playing then?
The ALSA core could pad the stream with silence up to the end of the
period when drain is called. It knows what the hw ptr value should be
at the next interrupt, which doesn't appear to be available to user
space.
On Fri, Nov 25, 2011 at 12:38 PM, Clemens Ladisch <clemens@ladisch.de> wrote:
> Trent Piepho wrote:
>> When the driver schedules the final period, couldn't it check if the
>> device is draining, and if so try to end playback at the right time.
>
> The ALSA framework was designed for cards where DMA doesn't need to
> be scheduled continuously, so it is assumed that stopping happens
> asynchronously.
>
> You could try to check the PCM state, but it's possible that the call
> to snd_pcm_drain() happens after you've scheduled the final period.
>
>
> Regards,
> Clemens
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: snd_pcm_drain and partial periods
2011-11-24 14:17 ` Clemens Ladisch
2011-11-25 16:37 ` Trent Piepho
@ 2011-11-28 1:16 ` Raymond Yau
1 sibling, 0 replies; 6+ messages in thread
From: Raymond Yau @ 2011-11-28 1:16 UTC (permalink / raw)
To: Clemens Ladisch, ALSA Development Mailing List
2011/11/24 Clemens Ladisch <clemens@ladisch.de>:
> Trent Piepho wrote:
>> Say an application does not write a full multiple of the period size
>> with snd_pcm_writei(). It's playing a clip and the clip ends and it
>> doesn't happen to end on a multiple of 6000 frames or whatever the
>> period size is.
>>
>> Now the application calls snd_pcm_drain() to wait for the clip to finish.
>>
>> How does the driver know to stop when it gets to the end of the
>> supplied data?
>
> It doesn't.
>
>> It seems like the driver will keep playing until it calls
>> snd_pcm_period_elapsed() at the end of the final period. Then the
>> alsa pcm layer will call the ->trigger() method and stop the stream.
>
> Yes.
>
>> Hopefully before the driver has started the next DMA for the next
>> period!
>
> Let's hope that the FIFOs are large enough so that the actual playback
> hasn't yet reached the period boundary ...
>
>> I don't see any documentation for snd_pcm_drain() that says it will
>> keep playing until it finishes a period, even if the data runs out
>> before hand. "For playback wait for all pending frames to be played
>> and then stop the PCM." Seems pretty clear that only the pending
>> frames are played and not the rest of a period.
>
> ALSA will stop the device when it realizes that it has run out of data
> (just like an underrun). This might happen before the period boundary
> if there is some call to snd_pcm_status() or _delay() that reads the
> current position (and if the hardware also supports reading the current
> position).
>
>
> It's racy and undocumented, but there's nothing a driver can do about
> this.
>
How about snd-usb-audio which one period consists of one or more urbs ?
if alsa stop the device at underrun
How can snd_pcm_recover() work as expected when usb-audio does not
provide accurate current position ?
The other cases are those hardware mixing sound cards (e.g. cs46xx,
ymfpci, au88x0 and emu10k1)
emu10k1 and au88x0 can provide current position
The period size of au88x0 and cs46xx are limited to power of two
ymfpci and emu10k1 has not limitation on period size but ymfpci 's dsp
mix at 1024 bytes
Does snd_pcm_recover() restart at the stop position or period boundary ?
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2011-11-28 1:16 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
[not found] <CA+7tXihfkZd6+UmnwJiyLgwo+6PoU9fWvzNhz7FKzy7DNgAWMw@mail.gmail.com>
2011-11-23 23:44 ` snd_pcm_drain and partial periods Trent Piepho
2011-11-24 14:17 ` Clemens Ladisch
2011-11-25 16:37 ` Trent Piepho
2011-11-25 17:38 ` Clemens Ladisch
2011-11-27 6:05 ` Trent Piepho
2011-11-28 1:16 ` Raymond Yau
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.