Dear All
Underrun means that the driver is consuming data more quickly than aplay is able to provide it. This may mean that there's some system performance problem or it may be due to your driver is consuming data more quickly than it should and causing problems further up the stack.
I would like to ask about size of period, buffer.
In my environment, each data size are follows.
runtime->buffer_size = 8192 runtime->period_size = 2048 runtime->periods = 4 buffer_len = frames_to_bytes(runtime, runtime->buffer_size) = 32768 period_len = frames_to_bytes(runtime, runtime->period_size) = 8192
After sending period_len byte (=8192 byte = 2048 frame) I call snd_pcm_period_esapsed(). after that snd_pcm_update_hw_ptr_interrupt() is called. Is this correct ?
Then, runtime->hw_ptr_base will be updated In this function. How is this hw_ptr_base renewed ?
My stupid driver return -EPIPE on snd_pcm_update_hw_ptr_post So, I added following stupid debug printk
----------------------------------------------------- diff --git a/sound/core/pcm_lib.c b/sound/core/pcm_lib.c index 68d161a..01a41d3 100644 --- a/sound/core/pcm_lib.c +++ b/sound/core/pcm_lib.c @@ -199,6 +199,10 @@ static int snd_pcm_update_hw_ptr_post(struct snd_pcm_substr avail = snd_pcm_capture_avail(runtime); if (avail > runtime->avail_max) runtime->avail_max = avail; + printk("hw_prt_base = %d, hw_prt = %d, appl_prt = %d\n", + runtime->hw_ptr_base, + runtime->status->hw_ptr, + runtime->control->appl_ptr); if (avail >= runtime->stop_threshold) { if (substream->runtime->status->state == SNDRV_PCM_STATE_DRAININ snd_pcm_drain_done(substream); -----------------------------------------------------
The output is
----------------------------------------------------- hw_prt_base = 0, hw_prt = 127, appl_prt = 8192 hw_prt_base = 0, hw_prt = 255, appl_prt = 8319 hw_prt_base = 0, hw_prt = 383, appl_prt = 8447 hw_prt_base = 0, hw_prt = 533, appl_prt = 8575 hw_prt_base = 0, hw_prt = 661, appl_prt = 8725 hw_prt_base = 0, hw_prt = 789, appl_prt = 8853 hw_prt_base = 0, hw_prt = 938, appl_prt = 8981 hw_prt_base = 0, hw_prt = 1066, appl_prt = 9130 hw_prt_base = 0, hw_prt = 1194, appl_prt = 9258 hw_prt_base = 0, hw_prt = 1322, appl_prt = 9386 hw_prt_base = 0, hw_prt = 1472, appl_prt = 9514 hw_prt_base = 0, hw_prt = 1600, appl_prt = 9664 hw_prt_base = 0, hw_prt = 1728, appl_prt = 9792 hw_prt_base = 0, hw_prt = 1856, appl_prt = 9920 hw_prt_base = 0, hw_prt = 1984, appl_prt = 10048 hw_prt_base = 8192, hw_prt = 8256, appl_prt = 10176 <== ** hw_prt_base = 8192, hw_prt = 8192, appl_prt = 10176 hw_prt_base = 8192, hw_prt = 8384, appl_prt = 10240 hw_prt_base = 8192, hw_prt = 8512, appl_prt = 12288 hw_prt_base = 16384, hw_prt = 16384, appl_prt = 14336 <== hw_prt > appl_prt underrun!!! (at least 0.000 ms long) <== underrun -----------------------------------------------------
I think hw_prt_base mean "frame", not "byte". Because pointer function return value use bytes_to_frames(), and that value is used to new_hw_prt. Is it correct ?
why hw_prt_base update size is 8192 = buffer_size ?
please check hw_prt near <== **. ---------------------- hw_prt_base = 0, hw_prt = 1856 hw_prt_base = 0, hw_prt = 1984 hw_prt_base = 8192, hw_prt = 8256 <== ** hw_prt_base = 8192, hw_prt = 8192 ----------------------
I can uderstand if update size is 2048 = period_size.
Is my understanding wrong ?? my kernel is between 2.6.30 and 2.6.31-rc1
Best regards -- Kuninori Morimoto