On 2009-12-15 at 15:26:14 [+0100], Jérôme Duval <korli@xxxxxxxxxxxxxxxx> wrote: > 2009/12/15 Ingo Weinhold <ingo_weinhold@xxxxxx>: > >> Great it's working for you! I remember though reading that SDnLPIB > >> might still be of use on some ATI/VIA chipsets because the position > >> buffer is sometimes inaccurate. > > > > The LPIB is definitely more exact when it comes to the playing/recording > > position, which is why it should be used for the frames/time computation. > > The > > current method just leads to erratic performance times. I'll change that > > next. > > > > Regarding whether a buffer has been transferred via DMA, the DMA position > > is > > really the only safe information to use. I guess rounding the LPIB to the > > closer buffer would also work in practice. At least as long a chipset > > creator > > doesn't have the idea to prefetch more than half of the buffer. > > > >> Maybe this patch fixes the nVidia hda > >> problem with the workaround I introduced. > >> I'll check today if playback and recording are still working correctly > >> for > >> me. > > > > Yeah, please do. > > This doesn't work well for playback with your change. Ticks/crackles > occur regularly. Here are the position and lpib values: > KERN: hda: stream (id:1) position: 81888, lpib: 81664 > KERN: hda: stream (id:2) position: 98272, lpib: 98304 > KERN: hda: stream (id:1) position: 163808, lpib: 163584 > KERN: hda: stream (id:2) position: 49120, lpib: 49152 > > Interrupts should happen respectively at 81920 and 163840 for the > first stream (32 bits, 192kHz), 49152 and 98304 for the second stream > (24 bits, 96kHz). > For record, the lpib and interrupts are accurate, the position is not. > For playback, both position and lpib aren't accurate. > To have correct buffer cycles, and good playback and record, I had to > change to: > stream->buffer_cycle = 1 - position / bufferSize; > or > stream->buffer_cycle = ((position + (bufferSize >> 1)) / > bufferSize) % stream->num_buffers; > > Rounding the LPIB to find out the buffer cycle seems to way to go. Yeah, though I'd rather round the DMA position instead the LPIB, since the latter really doesn't have anything to do with the in-memory buffers (it's ahead for record and behind for playback, just as one would expect). The interesting question is though, whether the interrupt is indeed early or the DMA position has just not been updated. Your DMA positions seem to be exactly 32 bytes behind the actual buffer end for both streams. What I could imagine is that the DMA transfer hitting the buffer end is already done (respectively has at least transferred the last bytes of the buffer) and has thus correctly triggered the interrupt, but the transfer updating the DMA positions has not happened yet. That would at least be the harmless case where rounding up would work as expected. But if the interrupt is really triggered early we would unleash the thread waiting in buffer_exchange() early, risking that it overwrites the not yet transferred data. I'll be playing a bit more with the driver and the multi audio node and commit something more robust, when I'm satisfied with the result. > BTW which chipset do you own ? I have a GigaByte board with an Intel P55 Express chipset and Realtek ALC889 codec. CU, Ingo