[alsa-devel] my driver can't reproduce continuously

Kuninori Morimoto morimoto.kuninori at renesas.com
Fri Jul 24 10:56:01 CEST 2009


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


More information about the Alsa-devel mailing list