Source:tell on queueable sources
Posted: Thu Dec 26, 2024 1:14 pm
I'm trying to make a <2 frame latency audio buffering system, but I'm running into a problem.
My idea was to aim for one buffer per frame, preparing the next buffer's size with just enough data as for it to finish at about when the current frame is predicted to end, plus some extra time to account for frame time variations. To do that:
- I measure the last frame's duration, and assume that the next frame will take approximately the same time (I'm aware this may cause issues if there are micro-stutters, that's not the problem).
- I try to check how many samples are still left to play in the current buffer, in order to account for that time.
The second part is where I'm having issues. The number of samples left to play should equal the playing buffer's size minus the current play position, as reported by Source:tell("samples"). But it turns out that Source:tell is returning 0 every time, and that's screwing up the method, because it always thinks there's still one whole buffer (i.e. about one frame) worth of time to play.
Is that how Source:tell() is supposed to work? The docs say that "[w]ith the queueable source type, this method returns a value based only on the currently playing buffer". That doesn't mean it returns 0, right?
I can think of an alternative, using fixed-length short buffers as quantized time marks, where the number of buffers left in the queue will tell me the approximate duration left to play, but that seems like a somewhat dirty approach, and the limit is 64 buffers total, which makes things a little bit difficult.
My idea was to aim for one buffer per frame, preparing the next buffer's size with just enough data as for it to finish at about when the current frame is predicted to end, plus some extra time to account for frame time variations. To do that:
- I measure the last frame's duration, and assume that the next frame will take approximately the same time (I'm aware this may cause issues if there are micro-stutters, that's not the problem).
- I try to check how many samples are still left to play in the current buffer, in order to account for that time.
The second part is where I'm having issues. The number of samples left to play should equal the playing buffer's size minus the current play position, as reported by Source:tell("samples"). But it turns out that Source:tell is returning 0 every time, and that's screwing up the method, because it always thinks there's still one whole buffer (i.e. about one frame) worth of time to play.
Is that how Source:tell() is supposed to work? The docs say that "[w]ith the queueable source type, this method returns a value based only on the currently playing buffer". That doesn't mean it returns 0, right?
I can think of an alternative, using fixed-length short buffers as quantized time marks, where the number of buffers left in the queue will tell me the approximate duration left to play, but that seems like a somewhat dirty approach, and the limit is 64 buffers total, which makes things a little bit difficult.