On Sat, 25 Apr 2009, Jon Smirl wrote: > 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 Could you show real values what you're getting here with your driver? The buffer_size is always a wrap point. For example: buffer_size = 4096 period_size = 1536 hw_ptr_interrupt => 1536, 3072, 4608 For example, if we receive update_hw_interrupt for second period late when pos (.pointer callback) = 100 and hw_ptr_interrupt = 3072 (hw_base is 0 at the moment): new_hw_ptr = 100 hw_ptr_interrupt = 3072 delta = -2972 delta += buffer_size -> delta = 1124 - seems correct Appearently, your .pointer callback returns wrong values. > 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 hw_base is always aligned to buffer_size (start of ring buffer) > delta = jiffies - s->jiffies; /* s->jiffies recorded at DMA > interrrupt at end of buffer */ > delta = delta * runtime->rate / HZ; Using jiffies to correct stream position seems correct to me. Jaroslav ----- Jaroslav Kysela <perex@xxxxxxxx> Linux Kernel Sound Maintainer ALSA Project, Red Hat, Inc. _______________________________________________ Alsa-devel mailing list Alsa-devel@xxxxxxxxxxxxxxxx http://mailman.alsa-project.org/mailman/listinfo/alsa-devel