From d3ef3adfa6240cd8029a12b134865d08ce7cef4b Mon Sep 17 00:00:00 2001 From: Grazvydas Ignotas Date: Thu, 10 Jun 2010 23:34:51 +0300 Subject: [PATCH] ASoC: add start treshold to prevent underflows in some cases This is useful for apps that don't rely on audio blocking and feed fixed amount of samples over time period (like emulators). --- sound/soc/omap/omap-pcm.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/sound/soc/omap/omap-pcm.c b/sound/soc/omap/omap-pcm.c index acd68efb2b75..b411eb460d02 100644 --- a/sound/soc/omap/omap-pcm.c +++ b/sound/soc/omap/omap-pcm.c @@ -168,6 +168,31 @@ static int omap_pcm_prepare(struct snd_pcm_substream *substream) omap_enable_dma_irq(prtd->dma_ch, OMAP_DMA_FRAME_IRQ); + /* + * To handle realtime streaming sources properly, we need to be sure + * we have at least 2 periods of size larger than FIFO in the buffer + * to start playing without underflowing. This is because DMA is always + * ahead of playback by amount close to FIFO size and needs to have + * next period ready when previous one finishes transfering to FIFO. + */ + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK && + runtime->periods > 1) { + struct snd_soc_pcm_runtime *rtd = substream->private_data; + int *mcbsp_bus_id = rtd->dai->cpu_dai->private_data; + int fifo_samples = (*mcbsp_bus_id == 1) ? 1024 : 256; + int period_samples, period_frames; + + period_samples = bytes_to_samples(runtime, + snd_pcm_lib_period_bytes(substream)); + if (period_samples < fifo_samples + runtime->channels) + period_samples = fifo_samples + runtime->channels; + period_frames = bytes_to_frames(runtime, + samples_to_bytes(runtime, period_samples)) * 2; + + if (runtime->start_threshold < period_frames) + runtime->start_threshold = period_frames; + } + return 0; } -- 2.39.2