Hi,
The buffering code in winealsa & wineoss is still very complex and I've had a hard time following it. Because of the complexity, it's potentially error-prone. Here's an error:
Consider this sequence of calls: BufferSize 100 GetBuffer(80) Release(80) pcm_write(50) => offs = 50, held = 30 (80-50) GetBuffer(30) (max 70) =>LOCKED_WRAPPED (because pos 80 + 30 is > 100) Release(30) => wrap_buffer 20 at end & 10 at beginning => offs = 50, held = 60 (note offs+held > 100) GetBuffer(10) (max 40) =>LOCKED_NORMAL (fits into primary) Release(10) =>computes buffer = offs+held = 50+60 = 110 > 100! =>illegal memory access
An easy fix would be to correct buffer = This->local_buffer + + (This->lcl_offs_frames + This->held_frames) * This->fmt->nBlockAlign; into (offs+held %buffer_size)
However are we sure that's all?
I'd love to see the code as understandable as winecoreaudio (although I know there need be more state variables to handle the two buffers).
Precisely because winecoreaudio is more readable I was able to fix the Get/ReleaseBuffer ordering issue, while ALSA and OSS are still waiting (waiting too for another patch to have GetCurrentPadding simply return held_frames on top of it).
IOW, the winecoreaudio driver is the best of the three, receiving fixes written easily, while ALSA and OSS are lagging behind because it's tedious to patch them correctly.
Regards, Jörg Höhle