[alsa-devel] xrun on sdp340 with small buffers
I use the sdp3430 machine driver for my board, which connects twl4030 codec and OMAP McBSP/DMA drivers. Everything works fine, I can play audio files (using aplay).
However, I tried to force 'aplay' to use a different buffer size and period count, and it misbehaves. My experiment was setting buffer time to 10ms and periods to 4, and play a 8kHz sample file; this only generates underrun messages. Under that configuration, for 8kHz, it means a buffer size of 320B (16-bits, stereo) divided into 4 periods of 80B each. omap-pcm driver will report interrupts each 80B, as it uses a single DMA transfer for the buffer and generates interrupts each frame.
I enabled the SND_PCM_XRUN_DEBUG option in the kernel and set xrun_debug proc-entry to 1. And this is what I get:
# aplay audio_8000.wav --buffer-time=10000 --period-time=2500 Playing WAVE 'audio_8000.wav' : Signed 16 bit Little Endian, Rate 8000 Hz, Stereo Unexpected hw_pointer value [1] (stream = 0, delta: -67, max jitter = 80): wrong interrupt acknowledge? Unexpected hw_pointer value [1] (stream = 0, delta: -6, max jitter = 80): wrong interrupt acknowledge?
What I understand it reports is that when an interrupt happens, the position of the transfer queried (using a dma get_pos) is lower than the position it (at least) should be. Let's say if in the third period (80B/period) of the buffer I should get at least a position greater than 240, and the position returned by query is -67B behind. Is my understanding correct? If so, does that mean the issue is with the DMA mechanism?
Don't know if it's worth to say that adding the xrun_debung only prints some debug messages and then playback works. But disabling the debug shows only underrun messages.
-Misa
On Fri, 27 Mar 2009 05:02:29 +0100 "ext Lopez Cruz, Misael" x0052729@ti.com wrote:
I use the sdp3430 machine driver for my board, which connects twl4030 codec and OMAP McBSP/DMA drivers. Everything works fine, I can play audio files (using aplay).
However, I tried to force 'aplay' to use a different buffer size and period count, and it misbehaves. My experiment was setting buffer time to 10ms and periods to 4, and play a 8kHz sample file; this only generates underrun messages. Under that configuration, for 8kHz, it means a buffer size of 320B (16-bits, stereo) divided into 4 periods of 80B each. omap-pcm driver will report interrupts each 80B, as it uses a single DMA transfer for the buffer and generates interrupts each frame.
Am I right that SDP3430 is using McBSP2 for audio codec? We had similar issues sometime ago and I obviously forgot to report it here... grr.
But shortly:
McBSP2 in OMAP3 has 1 ksample (1k x 32 bit) internal FIFO. During initial playback startup, this FIFO is keeping the DMA request active until the FIFO is full.
So now if ALSA buffer size is smaller, DMA is looping around it while filling up the HW FIFO, generating burst of interrupts as well and SW doesn't have any change to fill enough data.
Hmm. We better to have a patch setting constraint for minimum buffer size in case McBSP2 in OMAP3.
Hi
I think we should use something like this in case of McBSP2 in OMAP3. McBSP2 has 4 kB internal audio buffer and it's causing underruns in playback startup if ALSA buffer is smaller than that because DMA is looping around the buffer while filling up the HW FIFO.
Signed-off-by: Jarkko Nikula jarkko.nikula@nokia.com --- sound/soc/omap/omap-mcbsp.c | 11 +++++++++++ 1 files changed, 11 insertions(+), 0 deletions(-)
diff --git a/sound/soc/omap/omap-mcbsp.c b/sound/soc/omap/omap-mcbsp.c index d6882be..9c09b94 100644 --- a/sound/soc/omap/omap-mcbsp.c +++ b/sound/soc/omap/omap-mcbsp.c @@ -146,6 +146,17 @@ static int omap_mcbsp_dai_startup(struct snd_pcm_substream *substream, struct omap_mcbsp_data *mcbsp_data = to_mcbsp(cpu_dai->private_data); int err = 0;
+ if (cpu_is_omap343x() && mcbsp_data->bus_id == 1) { + /* + * McBSP2 in OMAP3 has 1024 * 32-bit internal audio buffer. + * Set constraint for minimum buffer size to the same than FIFO + * size in order to avoid underruns in playback startup because + * HW is keeping the DMA request active until FIFO is filled. + */ + snd_pcm_hw_constraint_minmax(substream->runtime, + SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 4096, UINT_MAX); + } + if (!cpu_dai->active) err = omap_mcbsp_request(mcbsp_data->bus_id);
On Fri, Mar 27, 2009 at 03:32:00PM +0200, Jarkko Nikula wrote:
I think we should use something like this in case of McBSP2 in OMAP3. McBSP2 has 4 kB internal audio buffer and it's causing underruns in playback startup if ALSA buffer is smaller than that because DMA is looping around the buffer while filling up the HW FIFO.
Applied, thanks (with your explanation from the previous message pasted into the commit message for the benefit of anyone going through logs).
participants (3)
-
Jarkko Nikula
-
Lopez Cruz, Misael
-
Mark Brown