From f31fa16bb897725b559d4d09f5eeb721694bee39 Mon Sep 17 00:00:00 2001 From: oneup03 Date: Sun, 1 Nov 2026 01:05:11 -0500 Subject: [PATCH] Play queued buffers in order across the buffer id wrap libctru numbers a channel's wave buffers 1 to 65535 and then from 1 again. dequeue() played the lowest id next, so at the wrap the last buffers numbered before it stayed in the queue for good while the new, lower ids played ahead of them. With those slots taken, later adds beyond the free slots were dropped while libctru counted them played: a channel fed without pause (a game's output stream, 60 buffers a second) ran about a quarter fast from 18 minutes in. The ids are now compared as a signed 16-bit distance. Co-Authored-By: Claude Opus 5.5 --- firmware/voice.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/firmware/voice.c b/firmware/voice.c index 53f5b14..d7b8d78 100644 --- a/firmware/voice.c +++ b/firmware/voice.c @@ -149,14 +149,15 @@ static void adpcm_decode(voice_t *v, u16 n, s16 *dst) v->adpcm_nibble = nib; } -// lowest buffer id plays next; looping buffers requeue +// earliest buffer id plays next; looping buffers requeue. +// ids wrap (libctru counts 1..65535, then 1 again): compared as a distance static int dequeue(voice_t *v) { u16 i, best = 0; if (!v->queued) return 0; for (i = 1; i < v->queued; i++) - if (v->queue[i].id < v->queue[best].id) + if ((s16)(v->queue[i].id - v->queue[best].id) < 0) best = i; v->current = v->queue[best]; for (i = best; i + 1 < v->queued; i++)