[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