« Return to Thread: PATCH: fix for a rare audio playback bug

Re: PATCH: fix for a rare audio playback bug

by Bernard Leach :: Rate this Message:

Reply to Author | View in Thread

Thanks for that, I've finally managed to get around to commiting it to
CVS.

Apologies for the delay.

cheers,
bern.

On Sun, 2006-03-26 at 10:35 -0800, Gobber Warts wrote:

> I've found a bug in the circular buffer management code. It is in the
> routine ipodaudio_write in the file
> linux/arch/armnommu/mach-ipod/audio.c. The bug is not in the ipod1-1
> and earlier kernels, but is present in ipod1-2 and all later kernels.
> The change that introduced the bug is CVS revision 1.9 to audio.c from
> Bernard:
> fixed circular buffer bugs to clean up audio output
>
> http://cvs.sourceforge.net/viewcvs.py/ipodlinux/linux/arch/armnommu/mach-ipod/audio.c?rev=1.9&view=markup
>
> It happens when a write *exactly* fills the buffer up to the end. This
> could be because there is exactly that amount of data to write, or
> because the read pointer is at the beginning of the audio buffer (ie.
> full). This causes the value *DMA_WRITE_OFF to point to one element
> past the end of the buffer. This is not a problem for the writing
> code, it will just wrap around to the beginning of the buffer when
> there is more data to write or more space to write into. However, the
> reading code looks like this:
>
>         while ( *r_off != *w_off ) {
>                 if ( (inl(0xc000251c) & 0x7800000) == 0 ) {
>                         outl(inl(0xc000251c)|(1<<9), 0xc000251c);
>                         return;
>                 }
>
>                 outl(((unsigned)dma_buf[*r_off]) << 16, 0xc0002540);
>                 if ( !stereo ) {
>                         outl(((unsigned)dma_buf[*r_off]) << 16,
> 0xc0002540);
>                 }
>
>                 *r_off = (*r_off + 1) % BUF_LEN;
>         }
>
> If the value of *w_off is outside the buffer (eg. one element past its
> end), then there is nothing to stop the read code from looping around
> the same set of samples in the buffer. Depending on the timing between
> the writer and reader, it could loop around one extra time or multiple
> times before a write re-establishes a valid write offset. The overall
> effect is one or more replays of the last ~0.25 seconds worth of audio
> (assuming 46KB buffer and CD format audio). I think that this doesn't
> happpen in practice because the writes are faster than the reads so
> the read pointer rarely catches up with the write pointer. I found an
> obscure way that I could get this to happen all the time giving a 0.25
> second stutter, so I'd appreciate if someone can commit the following
> fix for me.
>
> Cheers!
>
> Gobber Warts.
>
> ===================================================================
> RCS file: RCS/audio.c,v
> retrieving revision 1.1
> diff -c -r1.1 audio.c
> *** audio.c     2006/03/24 08:13:10     1.1
> --- audio.c     2006/03/24 09:26:42
> ***************
> *** 452,458 ****
>                                 rem -= cnt;
>                                 bufsp += cnt;
>
> !                               write_off_current += cnt;
>                         }
>
>                         /* room at start of buffer (and more data)? */
> --- 452,458 ----
>                                 rem -= cnt;
>                                 bufsp += cnt;
>
> !                               write_off_current = (write_off_current
> + cnt) % BUF_LEN;
>                         }
>
>                         /* room at start of buffer (and more data)? */




-------------------------------------------------------
This SF.Net email is sponsored by xPML, a groundbreaking scripting language
that extends applications into web and mobile media. Attend the live webcast
and join the prime developer group breaking into this new coding territory!
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=110944&bid=241720&dat=121642
_______________________________________________
iPodlinux-devel mailing list
iPodlinux-devel@...
https://lists.sourceforge.net/lists/listinfo/ipodlinux-devel

 « Return to Thread: PATCH: fix for a rare audio playback bug