At Mon, 8 Jan 2007 10:47:35 -0800, Andrew Johnson wrote: > > Hi All, > > It seems that there is a bug in the PXA ALSA drivers which causes an > earlier section of the circular audio buffer to be played erroneously at > the end of playback when using aplay. > > The bug occurs because runtime->period_size is not an integer multiple > of runtime->buffer_size. When a section of audio to be copied to the > buffer is less than a period size, aplay uses runtime->period size to > pad the section with zeros to ensure that the audio stream is an integer > multiple of runtime->period_size. This is important as ALSA can only > stop playback on the period boundary. > > Example: > > period_size = 32 > buffer_size = 90 > audio_size = 180 > > aplay pads the audio with zeros to be an integer multiple of period_size > so: > > audio_size(padded) = 192 > > This will fill the buffer twice with 12-bytes left over. Therefore, > the first period will have 12 bytes of silence and 20 bytes of data > from earlier in the audio stream. The ALSA core will not stop until > the entire buffer is empty, thus the 20-bytes of earlier data will be > played before stopping. The solution is to add a constraint to force > the > runtime->buffer_size to be an integer multiple of runtime->period_size. > I've appended a patch to do this. > > Kind Regards, > > Andrew > > PATCH FOLLOWS > > Signed-off-by: Andrew Johnson <ajohnson <at> intrinsyc.com> Thanks for the patch. The fix looks logical to me. However, the patch you embedded is broken (the line folded), and the change to pxa2xx_pcm_dma_irq() is wrong for recent kernels, too. (We may need a wrapper or a patch file for 2.6.18 or older...) Could you fix these and repost the patch, together with a short changelog to apply? Takashi > > --- a/alsa-kernel/sound/arm/pxa2xx-pcm.c 2007-01-08 > 10:37:34.000000000 -0800 > +++ b/alsa-kernel/sound/arm/pxa2xx-pcm.c 2007-01-05 > 17:59:27.000000000 -0800 > @@ -137,7 +137,7 @@ static int pxa2xx_pcm_trigger(struct snd > return ret; > } > > -static void pxa2xx_pcm_dma_irq(int dma_ch, void *dev_id) > +static void pxa2xx_pcm_dma_irq(int dma_ch, void *dev_id, struct pt_regs > *regs) > { > struct snd_pcm_substream *substream = dev_id; > struct pxa2xx_runtime_data *rtd = > substream->runtime->private_data; > @@ -213,6 +213,10 @@ static int pxa2xx_pcm_open(struct snd_pc > if (ret) > goto out; > > + ret = snd_pcm_hw_constraint_integer(runtime, > SNDRV_PCM_HW_PARAM_PERIODS); > + if (ret < 0) > + goto out; > + > ret = -ENOMEM; > rtd = kmalloc(sizeof(*rtd), GFP_KERNEL); > if (!rtd) > > --- a/alsa-kernel/sound/soc/pxa/pxa2xx-pcm.c 2007-01-08 > 10:37:34.000000000 -0800 > +++ b/alsa-kernel/sound/soc/pxa/pxa2xx-pcm.c 2007-01-05 > 18:10:47.000000000 -0800 > @@ -227,6 +227,11 @@ static int pxa2xx_pcm_open(struct snd_pc > if (ret) > goto out; > > + ret = snd_pcm_hw_constraint_integer(runtime, > + SNDRV_PCM_HW_PARAM_PERIODS); > + if (ret < 0) > + goto out; > + > prtd = kzalloc(sizeof(struct pxa2xx_runtime_data), GFP_KERNEL); > if (prtd == NULL) { > ret = -ENOMEM; > > ------------------------------------------------------------------------- > Take Surveys. Earn Cash. Influence the Future of IT > Join SourceForge.net's Techsay panel and you'll get the chance to share your > opinions on IT & business topics through brief surveys - and earn cash > http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV > _______________________________________________ > Alsa-devel mailing list > Alsa-devel@xxxxxxxxxxxxxxxxxxxxx > https://lists.sourceforge.net/lists/listinfo/alsa-devel > ------------------------------------------------------------------------- Take Surveys. Earn Cash. Influence the Future of IT Join SourceForge.net's Techsay panel and you'll get the chance to share your opinions on IT & business topics through brief surveys - and earn cash http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV _______________________________________________ Alsa-devel mailing list Alsa-devel@xxxxxxxxxxxxxxxxxxxxx https://lists.sourceforge.net/lists/listinfo/alsa-devel