Repository navigation
Conversation
4d2519b to
8e2d74b
Compare
rahmanih
left a comment
There was a problem hiding this comment.
fix to be applied here too.
What would be the appropriate way to fix it there? |
A zero-length isochronous OUT transfer (actual_length == 0) carries no audio data, but the read thread still recorded it as a frame: it wrote frame_length = 0 into the slot at transfer_pos, advanced transfer_pos and fired the frame_done callback. Because the frame FIFO uses frame_length == 0 as the sentinel for an empty slot, this made the slot indistinguishable from a free one. The consumer then read at access_pos, saw frame_length == 0, reported it as an underflow (UX_BUFFER_OVERFLOW) and did not advance access_pos. As a result transfer_pos moved forward while access_pos stayed put, permanently desyncing the producer/consumer positions. Skip zero-length packets entirely: leave transfer_pos in place, do not fire the callback, and re-issue the transfer at the same slot. This preserves the "frame_length == 0 means empty slot" invariant and keeps the transfer and access positions in sync.
House style puts the brace on its own line and comments the reason, and the change arrived with neither, plus a line of trailing whitespace. The comment records why the skip matters rather than what it does: a zero length frame is what marks a slot free, so logging one leaves a slot the reader never drains while the transfer position advances past it. No behaviour change. Assisted-by: Claude Code (Opus 5) <noreply@anthropic.com>
8e2d74b to
72b6b39
Compare
|
Thanks — this is a real fix and I have kept it. I pushed a second commit to your branch rather than asking you to redo it, and rebased onto current What changed is presentation only, no behaviour: the brace moved to its own line, a line of trailing whitespace went, and the reason is now recorded in a comment. The reason is worth stating because it is not obvious from the code: a frame length of zero is exactly what marks a slot free, so logging a zero-length packet leaves a slot the reader never drains while the transfer position advances past it. That is the bug, rather than merely a wasted slot. The rebase was needed for a reason unrelated to your change. The branch predated #274, which removed a byte order mark from Two things worth flagging, neither blocking. The skip also bypasses the There is no regression test. The device audio read thread needs the simulated device stack to drive, so this is not a quick one to add, and I would rather say so than let the absence pass unremarked. |
A zero-length isochronous OUT transfer (actual_length == 0) carries no audio data, but the read thread still recorded it as a frame: it wrote frame_length = 0 into the slot at transfer_pos, advanced transfer_pos and fired the frame_done callback.
Because the frame FIFO uses frame_length == 0 as the sentinel for an empty slot, this made the slot indistinguishable from a free one. The consumer then read at access_pos, saw frame_length == 0, reported it as an underflow (UX_BUFFER_OVERFLOW) and did not advance access_pos. As a result transfer_pos moved forward while access_pos stayed put, permanently desyncing the producer/consumer positions.
Skip zero-length packets entirely: leave transfer_pos in place, do not fire the callback, and re-issue the transfer at the same slot. This preserves the "frame_length == 0 means empty slot" invariant and keeps the transfer and access positions in sync.