All of lore.kernel.org
 help / color / mirror / Atom feed
* ALSA PulseAudio plugin: snd_pcm_rewindable() returns >0, but snd_pcm_rewind() is broken
@ 2011-10-24 13:28 Nikolay Nikolov
  2011-10-24 15:34 ` Pierre-Louis Bossart
       [not found] ` <4ea5858a.4a2acc0a.3bb5.5b58SMTPIN_ADDED@mx.google.com>
  0 siblings, 2 replies; 4+ messages in thread
From: Nikolay Nikolov @ 2011-10-24 13:28 UTC (permalink / raw)
  To: alsa-devel

Hi all,

I submitted a bug report for this here:
https://bugtrack.alsa-project.org/alsa-bug/view.php?id=5464
I got a comment, which said I should post this on the mailing list, so 
I'm doing this now:

I'm writing a program that tries to use the snd_pcm_rewind() function if 
it's available and I'm having serious trouble with the alsa-pulseaudio 
plugin.

I'm using the max buffer size, which is 1048576 frames (4MB buffer, 
16-bit stereo). The buffer is almost full when I try to rewind. I first 
call snd_pcm_rewindable() and it returns a greater than zero value. Then 
I call snd_pcm_rewind() with this value and it returns success, i.e. a 
positive value of frames actually rewound. I then call snd_pcm_writei 
with the number of frames rewound and I get a weird pause (several 
seconds) in the audio on the next poll. Audio then continues from the 
middle; the beginning of the audio that was rewritten immediately after 
rewind() has been dropped. Also, pulseaudio reports several times the 
following error:

protocol-native.c: Failed to push data into queue

After looking at the alsa-lib and alsa-plugins sources, it seems that 
snd_pcm_rewind() for ioplug devices only updates an internal pointer and 
doesn't notify pulseaudio, so on the next write we just try to push too 
much data to the pulseaudio stream. After googling a bit, I found this 
email from 17 Feb 2010 from Lennart Poettering, which says that 
snd_pcm_rewind() is broken for the alsa-pulseaudio plugin.

http://ns.spinics.net/lists/alsa-devel/msg31536.html


Also, this mail:

http://lists.freedesktop.org/archives/pulseaudio-bugs/2010-July/004051.html

says that snd_pcm_rewindable() should always return 0 frames on ioplug 
devices, and if that's not the case, then it's a bug in alsa.

So, if I'm getting this right, either snd_pcm_rewindable() should be 
fixed to return 0, or snd_pcm_rewind() should be fixed to work properly 
with the alsa-pulseaudio plugin.

Thanks,
Nikolay

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: ALSA PulseAudio plugin: snd_pcm_rewindable() returns >0, but snd_pcm_rewind() is broken
  2011-10-24 13:28 ALSA PulseAudio plugin: snd_pcm_rewindable() returns >0, but snd_pcm_rewind() is broken Nikolay Nikolov
@ 2011-10-24 15:34 ` Pierre-Louis Bossart
       [not found] ` <4ea5858a.4a2acc0a.3bb5.5b58SMTPIN_ADDED@mx.google.com>
  1 sibling, 0 replies; 4+ messages in thread
From: Pierre-Louis Bossart @ 2011-10-24 15:34 UTC (permalink / raw)
  To: 'Nikolay Nikolov', alsa-devel

> I'm using the max buffer size, which is 1048576 frames (4MB buffer,
> 16-bit stereo). The buffer is almost full when I try to rewind. I first
> call snd_pcm_rewindable() and it returns a greater than zero value.
> Then
> I call snd_pcm_rewind() with this value and it returns success, i.e. a
> positive value of frames actually rewound. I then call snd_pcm_writei
> with the number of frames rewound and I get a weird pause (several
> seconds) in the audio on the next poll. Audio then continues from the
> middle; the beginning of the audio that was rewritten immediately after
> rewind() has been dropped. 

You want to avoid rewinding completely. Your audio hardware might have
prefetched data with the DMA subsystem. Rewinding completely might result in
an inconsistent configuration and possibly underflows. If you look at the
PulseAudio code, we've introduced some thresholds beyond which we don't
rewind (128 bytes or 1ms off the top of my head).
You might argue that snd_pcm_rewindable is broken, but it's somewhat
difficult to fix as the amount of prefetched data isn't modeled in the
driver and it's very much hardware-specific. Using a less aggressive
approach works fine on most hardware.
-Pierre

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: ALSA PulseAudio plugin: snd_pcm_rewindable() returns >0, but snd_pcm_rewind() is broken
       [not found] ` <4ea5858a.4a2acc0a.3bb5.5b58SMTPIN_ADDED@mx.google.com>
@ 2011-10-24 16:55   ` Nikolay Nikolov
  2011-10-24 23:00     ` Raymond Yau
  0 siblings, 1 reply; 4+ messages in thread
From: Nikolay Nikolov @ 2011-10-24 16:55 UTC (permalink / raw)
  To: alsa-devel

On 10/24/2011 06:34 PM, Pierre-Louis Bossart wrote:
> You want to avoid rewinding completely. Your audio hardware might have
> prefetched data with the DMA subsystem. Rewinding completely might result in
> an inconsistent configuration and possibly underflows. If you look at the
> PulseAudio code, we've introduced some thresholds beyond which we don't
> rewind (128 bytes or 1ms off the top of my head).
> You might argue that snd_pcm_rewindable is broken, but it's somewhat
> difficult to fix as the amount of prefetched data isn't modeled in the
> driver and it's very much hardware-specific. Using a less aggressive
> approach works fine on most hardware.
> -Pierre
Yes, I figured this out while experimenting with real hw alsa devices 
and that's why I actually rewind snd_pcm_rewindable() minus some 
threshold, that can be configured. However with the alsa pulseaudio 
plugin, rewinding seems to be broken completely, even with a very large 
threshold.

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: ALSA PulseAudio plugin: snd_pcm_rewindable() returns >0, but snd_pcm_rewind() is broken
  2011-10-24 16:55   ` Nikolay Nikolov
@ 2011-10-24 23:00     ` Raymond Yau
  0 siblings, 0 replies; 4+ messages in thread
From: Raymond Yau @ 2011-10-24 23:00 UTC (permalink / raw)
  To: ALSA Development Mailing List

2011/10/25 Nikolay Nikolov <nickysn@gmail.com>:
> On 10/24/2011 06:34 PM, Pierre-Louis Bossart wrote:
>> You want to avoid rewinding completely. Your audio hardware might have
>> prefetched data with the DMA subsystem. Rewinding completely might result in
>> an inconsistent configuration and possibly underflows. If you look at the
>> PulseAudio code, we've introduced some thresholds beyond which we don't
>> rewind (128 bytes or 1ms off the top of my head).

This seem not enough for snd-ymfpci which update hw_ptr on 5.333 ms
intervals using its own timer interrupt (i.e. mininum 256 bytes period
size) at 48000Hz

http://thread.gmane.org/gmane.linux.alsa.devel/89157/focus=89167

This seem to be a design fault of alsa-pulse plugin which provide a
latency (minimum period size of 128 bytes) which is less than some of
the alsa sound drivers (e.g. snd-ymfpci, ...) and even PA server probe
those sound cards during initialisation but there is no negotiation
between PA server and client using alsa-pulse plugin

>> You might argue that snd_pcm_rewindable is broken, but it's somewhat
>> difficult to fix as the amount of prefetched data isn't modeled in the
>> driver and it's very much hardware-specific. Using a less aggressive
>> approach works fine on most hardware.
>> -Pierre

> Yes, I figured this out while experimenting with real hw alsa devices
> and that's why I actually rewind snd_pcm_rewindable() minus some
> threshold, that can be configured. However with the alsa pulseaudio
> plugin, rewinding seems to be broken completely, even with a very large
> threshold.

This is quite complicated when some of alsa driver (e.g.snd-ymfpci)
does not provide an accurate hw_ptr

I guess this may be the reason why aplay using 4 periods per buffer


For pulse plugin ,it will need to add two callback into
snd_pcm_ioplug_callback in alsa-lib/include/pcm_ioplug.h

	snd_pcm_sframes_t (*rewindable)(snd_pcm_ioplug_t *io);
	snd_pcm_sframes_t (*forwardwable)(snd_pcm_ioplug_t *io);

and alsa-lib/src/pcm_ioplug.c


static snd_pcm_sframes_t snd_pcm_ioplug_rewindable(snd_pcm_t *pcm)
{
	ioplug_priv_t *io = pcm->private_data;
+	if (io->data->callback->rewindable) {
+		return io->data->callback->rewindable(io->data);
	return snd_pcm_mmap_hw_avail(pcm);
}

static snd_pcm_sframes_t snd_pcm_ioplug_forwardable(snd_pcm_t *pcm)
{
	ioplug_priv_t *io = pcm->private_data;
+	if (io->data->callback->forwardable) {
+		return io->data->callback->forwardable(io->data);
	return snd_pcm_mmap_avail(pcm);
}

and add pulse_rewindable() and pulse_forwardable() to
alsa-plugin/pulse/pcm_pulse.c

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2011-10-24 23:00 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-10-24 13:28 ALSA PulseAudio plugin: snd_pcm_rewindable() returns >0, but snd_pcm_rewind() is broken Nikolay Nikolov
2011-10-24 15:34 ` Pierre-Louis Bossart
     [not found] ` <4ea5858a.4a2acc0a.3bb5.5b58SMTPIN_ADDED@mx.google.com>
2011-10-24 16:55   ` Nikolay Nikolov
2011-10-24 23:00     ` 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.