I was updating a cart I was working on to use stat 46-56 instead of 16-26 and noticed that new bugs were introduced in the change. It looks like stat(16) updates immediately when a music() command is called, but stat(46) will sometimes show an erroneous value (e.g. -1) on the frame of the update.
The manual is not clear on this, but it is meant to behave like this. I will add a note about returning -1 even after a music() call, which is understandably surprising.
stat 46..56 return (a guess at) the current audible state. So immediately after issuing an SFX() or MUSIC() command, it won't be audible until after the host operating system's sound driver asks for some audio data from PICO-8 and starts playing it.
Perhaps stat 16..26 shouldn't be treated as 'legacy' because they do still serve a different and useful purpose: to give the current state of the mixer even though it is not audible yet.
Right - according to the manual as written, stat 46...56 was a drop-in replacement for stat 16...26. If it's a documentation bug, that's totally fine - I can work around that.
Edit: Is it safe to assume that stat 46...56 will reflect a music() call on the frame after that occurs?
Strictly speaking, it might /never/ reflect the music call if the host's sound driver is disabled or not working. It's an uncharacteristically low-level thing for PICO-8.
I think it might be wrong to return -1 here in the first place -- is that actually useful information? It is certainly confusing even after quickly reading [an amended version of] the manual, and requires annoying extra code to handle.
It might be nicer to defer to stat(16)..stat(26) behaviour when the mixer has some audio ready to go (immediately after a sfx() or music() call), but the sound driver hasn't yet started playing anything. I don't think anyone would care that e.g. stat(56) returns 0 for one or two more frames than expected, if they didn't know the reason for it. hrm..
(edit: fixed the stat numbers in that last paragraph)
So, the way I was using stat 16...26 was to program a visualizer synchronized to audio - my goal is to, as closely as possible, predict what the listener will be hearing and when they'll be hearing it so I can make animations happen synchronized with that. The current language in the manual about 46...56 offering "a higher resolution estimate of the currently audible state" makes it sound like I should be using these for that purpose.
I'm not sure what the benefit is of not anticipating changes to audio state from music() and sfx() commands, but for me making a visualizer, it's something I'd have to do a lot of work to get around.
Oh, yes -- that's exactly the kind of thing stat(46..56) is for.
To be clear, I'm only proposing to change the behaviour of 46..56 after music() has been called but before sound actually starts coming out of the speaker (usually about half a frame). Instead of returning -1, it should just return whatever is waiting in the mixer like 16..26 do. Once the music is playing and audible, it's business as usual.
Another reason to make the change is that it would act close enough to the 16..26 behaviour, so it /would/ be a straight drop-in replacement which is easier to grok. The small price to pay for this is (sometimes) losing a tiny tiny amount of information on a single frame after music() is called. e.g. syncing the first tick of music with the first frame of visuals -- pff!
Anyway, I hope this makes sense and I don't think anyone will object to removing the (seemingly) erroneous -1 results in 0.2.4c.
> To be clear, I'm only proposing to change the behaviour of 46..56 after music() has been called but before sound actually starts coming out of the speaker (usually about half a frame). Instead of returning -1, it should just return whatever is waiting in the mixer like 16..26 do. Once the music is playing and audible, it's business as usual.
That's exactly what I'd be trying to implement in software if this change didn't happen, so I'm very in favor of this - thank you!
[Please log in to post a comment]