Hi, I have been having issues for a while now with PulseAudio running on an older Thinkpad X41. PulseAudio relies on snd_pcm_avail() to detect underflows and increases the timer watermark when they happen. There are actually no audible underflows though... So I instrumented both PulseAudio (enabling DEBUG_TIMING in the alsa-sink.c code) and the kernel (latest alsa-kernel git) by adding the following printk in pcm.h:
static inline snd_pcm_uframes_t snd_pcm_playback_avail(struct snd_pcm_runtime *runtime) { snd_pcm_sframes_t avail = runtime->status->hw_ptr + runtime->buffer_size - runtime->control->appl_ptr; if (avail < 0) avail += runtime->boundary; else if ((snd_pcm_uframes_t) avail >= runtime->boundary) avail -= runtime->boundary; //plb if(avail > runtime->buffer_size) { snd_printk(KERN_ERR "avail %d hw_ptr %d buffer %d appl_ptr %d \n", avail, runtime->status->hw_ptr, runtime->buffer_size, runtime->control->appl_ptr); } return avail; }
In my tests this error condition where avail is larger than the ring buffer happens fairly often. The dmesg log show messages such as [ 834.524479] ALSA include/sound/pcm.h:600: avail 16403 hw_ptr 24351 buffer 16384 appl_ptr 24332 [ 835.266937] ALSA include/sound/pcm.h:600: avail 16407 hw_ptr 55841 buffer 16384 appl_ptr 55818 and these messages are correlated with the times when PulseAudio detects underflows. The full log can be found at http://pastebin.com/f210aa108.
I believe the issue is the accuracy of the hw_ptr reported by snd_intel8x0_pcm_pointer. If indeed such a condition occurred, it should be flagged as underflow, shouldn't it? There's been some changes in this part of the code to avoid extremely large values, here the issue seems more subtle, the pointer is only slightly off in most cases. This does screw-up PulseAudio though, the timer watermark keeps increasing and low-latency isn't possible.
I'd be more than happy to run more experiments, however I have no idea what the hardware does to report the position of the hw pointer. Thanks for your feedback - Pierre