Okay, so after realizing that c0-e5 was 65 total notes, I did a little digging into this. The sfx format specifies that pitch is a number from 0-63, so why does e5 work when you press [p] in the editor, while octave 4 is selected? The sound is higher than d#5, too.
First, let's try some p8scii. In the console, print("\a0szd#5e5") cstore(0x3200,0x3200,68)
both plays a constant d#5d#5, and stores that in sfx 0. Then go to the sfx editor and select octave 4, and change it to d#5e5 via pressing [p], and press space to play back. Two different notes!
Now, go back to the console and do sfx(0)
. This gets the very weird behavior of d#5c1, almost like a default, but not the same default that \a has.
Then, go back to the editor and add a c1 directly below the e5, and press space for playback. Three notes. Then go back to the console and run sfx(0)
again. This time you get a weird fading blend between the two c1 notes, almost like pico-8 sees them as two separate pitch values internally.
Finally, save the cart, reboot, and reload. The e5 is saved as a d#5 on the cart, which means playback changes again!
This could all be fixed by removing the ability to add e5 in the sfx editor, but there are some inconsistencies still with how it's handled in p8scii (since e5-b5 become d#5, but all other notes out of range (i.e. e6) become c5).
Lots to tweak here. It was an interesting glimpse into the internal systems that do the actual audio playback.
haha, thanks for the detailed journey @shy. That illegal note is indeed handled very differently in different contexts, and the only way it can get into that state is via the sfx editor. So I've fixed that for 0.2.5, but I need to investigate some of these observations further because they are still surprising to me.
There used to be a similar bug in the display memory, where some gfx operations would produce illegal pixel values >= 16 which would appear the same (displayed as val & 0xf) but would behave in subtly different ways. pico-8 stores data in a form that can be manipulated most efficiently (e.g. one byte per pitch, one byte per pixel) and also for performance assumes they are legal values. So having bad data in there can propagate through the system in extremely spooky ways. e.g. peek() has stuff like this in it:
if ((addr & 1) == 0) // first byte of 16-bit note val = note->pitch | ((note->inst & 0x3) << 6); |
Yeah, I guessed it was all bytes in the backend. I didn't think about the implications to peek though, that must be quite a complex function!
This e5 bug doesn't seem to be fixed in 0.2.5? I can still press [p] in octave 4 and get an e5 in the editor, it still plays a higher note, etc. I just double checked I was on the newest version, and the console does say "Pico-8 0.2.5".
Zep doesn't always rebuild the online version right away when he makes changes. I assume he considers himself the beta tester for each new change and delays the release until it seems to be ok.
That being said, @zep, it would be good if you had said 0.2.5a or something, since 0.2.5 is technically already released here on the BBS. 😜
(Maybe name the BBS edu version 0.2.5RCx or beta or whatever for the time being?)
this is supposed to be fixed in 0.2.5, which was released as downloads, edu version and bbs version, so maybe the bug (or a variant of it) is still there.
[Please log in to post a comment]