[alsa-devel] Breakage in pcm_lib.c
Jon Smirl
jonsmirl at gmail.com
Sun Apr 26 03:48:55 CEST 2009
This appears to be a bug in this code...
if (delta < 0) {
delta += runtime->period_size * runtime->periods;
it was adding, buffer_size. But buffer_size is not correct when the
periods don't evenly fit into the buffer
if (delta < 0) {
hw_ptr_error(substream,
"Unexpected hw_pointer value "
"(stream=%i, pos=%ld, intr_ptr=%ld)\n",
substream->stream, (long)pos,
(long)hw_ptr_interrupt);
/* rebase to interrupt position */
hw_base = new_hw_ptr = hw_ptr_interrupt;
/* align hw_base to buffer_size */
hw_base -= hw_base % runtime->buffer_size;
delta = 0;
} else {
hw_base += runtime->period_size * runtime->periods;
same here
if (hw_base >= runtime->boundary)
hw_base = 0;
new_hw_ptr = hw_base + pos;
}
}
I have my hardware working again with this fix plus an estimator
function for how far the DMA hardware is into the buffer...
static snd_pcm_uframes_t
psc_dma_pcm_pointer(struct snd_pcm_substream *substream)
{
struct snd_pcm_runtime *runtime = substream->runtime;
struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct psc_dma *psc_dma = rtd->dai->cpu_dai->private_data;
struct psc_dma_stream *s;
dma_addr_t count;
snd_pcm_uframes_t frames;
int delta;
if (substream->pstr->stream == SNDRV_PCM_STREAM_CAPTURE)
s = &psc_dma->capture;
else
s = &psc_dma->playback;
count = s->period_current_pt - s->period_start;
delta = jiffies - s->jiffies; /* s->jiffies recorded at DMA
interrrupt at end of buffer */
delta = delta * runtime->rate / HZ;
frames = bytes_to_frames(substream->runtime, count);
printk("psc_dma_pcm_pointer pos %ld %d\n", frames, delta);
return frames + delta;
}
--
Jon Smirl
jonsmirl at gmail.com
More information about the Alsa-devel
mailing list