02.05.2014 07:39, 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.
http://mailman.alsa-project.org/pipermail/alsa-devel/2014-March/073816.html
Do you mean sound card which cannot provide sample granularity need to use that flag or you want the driver to provide this granularity to application ?
I acknowledge that there was some confusion regarding the precise meaning of the flag (especially given three possible situations - accurate to just one period, accurate to better than one period but worse than one sample, accurate to one sample), and I am not the authority here.
My own opinion so far is that, if the card cannot provide sample-accurate position reports at arbitrary moments in time, then the SNDRV_PCM_INFO_BATCH flag needs to be set. Of course, the driver should not attempt to provide sample-accurate information if such information does not exist in the first place.
In addition, there seems to be some confusion here between the hardware periods (which are always 256 samples) and the period size in hw params. If I understand the other emails correctly, regardless of what the user set in hw_params, the reported position on ymfpci will be accurate to within 256 samples.
PulseAudio has the following consideration here: if the card cannot report the position accurately, we need to disable the timestamp-based scheduling, as this breaks module-combine-sink (or any successor of it), because it relies on very accurate estimations of the actual sample rate ratio between two non-identical cards.
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.
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.
Are there any different reqiurment bewteen VOIP and other application in addition to low latency ?
Voip does not really need stereo . The web cam Mic usually capture at 16000Hz mono while pulseaudio use same default rate for playback and capture
In practice, only the latency matters here, as PulseAudio will open the device at 48 kHz stereo anyway.
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?
http://mailman.alsa-project.org/pipermail/alsa-devel/2011-September/043715.h...
The author of the driver told me that
The period interrupts are not accurate at all. The ymfpci hardware internally uses fixed periods of 256 frames at 48 kHz. the driver reports a period interrupt when the next hardware interrupt at or after a period boundary occurs. The current position reported by the hardware is the position at the time of the last hardware interrupt
IMHO, this fits the purpose of the BATCH flag, but is precisely the middle case (possibly more accurate than one period, but definitely less accurate than one sample) which was disputed at http://mailman.alsa-project.org/pipermail/alsa-devel/2014-March/073816.html .
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.
To avoid further misunderstandings: I was speaking above about possible changes, not about the current behaviour. The answers below are for the current situation, which may be suboptimal.
Do you mean pulseaudio will use more periods instead of periods_min for those sound cards which cannot disable period wake-up ?
For cards that are not batch, it will attempt to set both the period size and the buffer size to something large (tsched_size, the default is 2s) and let the driver adjust that to something more sensible for the card. I think that in practice this means periods_min, although it is never mentioned explicitly in PulseAudio source.
For batch cards, the desired period (or, in PA speak, "fragment") time and the number of periods come from the config, of course subject to adjustments made by the ALSA library to fit the hardware requirements. The defaults are:
; default-fragments = 4 ; default-fragment-size-msec = 25
Do dynamic latency mean pulseaudio use 1ms and double the times until the sound card ?
If you are talking about the wakeup latency, the mechanism is indeed as you described (start with something small, increase if xruns or near-xruns appear, decrease if all runs well for some time), but the 1ms number is wrong. See the defines at the top of src/modules/alsa/alsa-sink.c for exact numbers.
It may also be obtained by double the number of periods and restrict hwbuf_unused in multiple of samples in a period instead of any arbituary number of sample ?
I don't understand here.
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.
/* FIXME? True value is 256/48 = 5.33333 ms */ err = snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_PERIOD_TIME, 5334, UINT_MAX); if (err < 0) return err; err = snd_pcm_hw_rule_noresample(runtime, 48000);
Do you mean when noresample is used, the period byte constraint should be used instead of period time to avoid rounding error ?
Yes. And maybe even constrain the period size to be a multiple of 256 samples in this case.
To obtain dynamic latency, you can just keep half of them or at least two periods full at any time
Yes if we talk about hardware periods (which are always 256 samples) and not about the period size which is settable through calling snd_pcm_hw_params_set_period_size_near() or something similar.