pxa2xx-pcm fix

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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>

--- 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

[Index of Archives]     [ALSA User]     [Linux Audio Users]     [Kernel Archive]     [Asterisk PBX]     [Photo Sharing]     [Linux Sound]     [Video 4 Linux]     [Gimp]     [Yosemite News]

  Powered by Linux