[alsa-devel] On non-rewindability of resamplers

Alexander E. Patrakov patrakov at gmail.com
Tue Apr 29 19:17:28 CEST 2014


29.04.2014 22:01, Raymond Yau wrote:
>  >
>  >
>  > On most sound cards, PulseAudio uses timer-based scheduling and thus
> is not subject to any period-size limitations. As far as I can see,
> snd_ymfpci does not include SNDRV_PCM_INFO_BATCH, and thus will be used
> in this mode. In addition, it has an implementation of
> snd_ymfpci_playback_pointer that seems to look at the hardware, which is
> good. So effective period times less than 5 ms should work on this card.
>
> https://git.kernel.org/cgit/linux/kernel/git/tiwai/sound.git/log/?qt=grep&q=period+wakeup
>
> Is there any reason to use timer scheduling for the sound card which
> cannot disable period wake up ?

Yes (if "cannot disable period wakeups" is the only bad thing about the 
card, which the further text in your e-mail contradicts to). Key words: 
dynamic latency.

As you surely know, running with low latency has a high chance of 
underruns due to CPU spikes, so this should be avoided if reasonable. 
However, some applications (e.g. VoIP) require low latency. By ignoring 
period wakeups and relying on time-based scheduling, one can effectively 
change the period size on the fly, obtaining low latency only when it is 
needed.

> The sound cards are still wake up by period and the timer
>
> As the DSP of ymfpci can mix up to 32 voices of different sample rate,
> mono/stereo , u8/s16 .

Understood.

> The driver just setup the card's timer to increase the fake hw_ptr  on
> 5ms interval by (48000Hz * 5ms) 240 samples

And that's bad. As the precision of hw_ptr is only 5 ms (and not 1 
sample), the driver must set SNDRV_PCM_INFO_BATCH. This would indeed 
avoid rewinds in the current PulseAudio code.

However, I don't see any code that backs up your claim. Is that fake 
pointer increased in hardware (as opposed to in the kernel) with such 
bad granularity?

See snd_ymfpci_memalloc(): both chip->voices[voice].bank and 
chip->bank_playback[voice][bank] are assigned a pointer that is based on 
chip->work_ptr.area, which is itself obtained through 
snd_dma_alloc_pages. So all bank pointers definitely point into the 
DMA-able area.

Also, snd_ymfpci_playback_pointer is based on 
voice->bank[chip->active_bank].start only, and the same construction is 
used in the interrupt handler to obtain the current playback position. 
So it is definitely based on what the hardware wrote into the DMA-able 
area, and that's why I thought that the .pointer function is good. Does 
it write there only just before the interrupt, or every 256 samples 
independently on the period size, or on some other condition?

> Unlike most sound cards which  periods_min equal to 2,  the periods_min
> of snd_ymfpci is 3

OK, but I don't see why it is relevant. Surely we can set up as many 
periods as we want, if all we are going to do with period interrupts is 
to ignore them in userspace.

> As the fake hw_ptr increase by 240 samples on 5 ms interval,  I  think
> it is a bad idea to allow any application to perform rewind

It is a bad idea to rewind into the uncertain area that we don't know 
whether it is already playing or not. If we have 6 periods 5 ms each, 
and always keep 5 of them full by promptly reacting to the interrupt 
notifications, then surely we can rewind one of them without much risk. 
But indeed, a full rewind is impossible for a fake hw_ptr with such bad 
granularity.

-- 
Alexander E. Patrakov


More information about the Alsa-devel mailing list