[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