Hello, i've playing with pico-8 for quite a long time and is great, i really like this piece of software
the issue: when i try to play two sounds at the same time using the sfx command, despite specifying different channels in the parameter, one sound cuts the other, for example:
sfx(0, 0, 0, 1) --plays only the first note from the first sfx page on channel 0 sfx(0, 1, 2, 1) --plays only the third note from the first sfx page on channel 1 |
the first sfx page:
(result: the sounds overlaps eachother, instead of mixing them despite being on different channels)
but if the second sound i'm trying to play comes from a different sfx page, the sounds mixes without any problem
sfx(0, 0, 0, 1) --plays only the first note from the first sfx page on channel 0 sfx(1, 1, 0, 1) --plays only the first note from the second sfx page on channel 1 |
the second sfx page:
(result: the two sounds are played at the same time, no overlap)
why is the channel parameter ignored in the first example? if is specified, it should play the note on the assigned channel and thus, mix the two sounds like in the second example, instead of overlaping them.
now, why i'm taking this approach? i'm trying to create a rhythm game, beatmania/djmax style, after sequencing the first two channels of a 2 minute song, is obvious that only one song with only one chart is going to be available to play.
instead, i'm trying to use the sfx pages as a keysound storage, and use tables to save the song info, and see if i can at least have 3 songs available with different charts and have a more precise bpm, since the game won't use much code/variables.
please let me know if this can be fixed or if it requires too much work, other approach i can use is with the peek/poke commands to patch the song in runtime and hijack the notes the user must press, this could work to add more charts but still would be only one song or have several songs with lots of repetitive note patterns.
Thanks in advance!
Just tested this, and you're right! Playing the same sfx on multiple channels doesn't work, even if you set length and starting index to different values. It seems to stop it from playing on any other channel first. Here's a cartridge that demonstrates the bug a bit better:
I can understand why this is happening (sometimes the same sound fires multiple times in one frame, and you don't want a huge amplitude boost when that happens, etc etc). But I think there's a good argument to be made here to play both copies, if sfx is called with a manual start index and length set.
For now, a quick workaround solution would be to use the P8SCII codes for audio ('\a'). If you read the manual for this, they can play any notes, instruments, effects, speed, length, and I think each one counts as a new sfx. Here's an example for your c1 note:
?"\asgl10i6c1",0,0 --play one note at speed 16: instrument 6, c1 |
thanks for the response, now that i see this '\a' code, it seems to be a better fit, i'm only missing playing on a specific channel, since i'm using the same "tracker" logic to assign the channel for each sound that will be played, this is to avoid unintended overlaps, maybe i will be able to virtually assign channels, but it would be better to have the sound system take care of that.
Thanks again!
I have come across this too.
There is also a 2016 BBS mention of what I presume is the same issue: Problem playing same sound on 2 channels
It does make some creative play with the sfx, along the lines of what ch32 has described, a little more difficult than I would have liked.
(I have a cart quite similar to Shy's, in regard to the information it feeds back. As Shy's cart has already been posted, a description of my cart should be enough. It attempts to play a chord of C-Maj from notes on the same SFX, and fails.)
+1 for Shy's statement:
"But I think there's a good argument to be made here to play both copies, if sfx is called with a manual start index and length set."
Workarounds
I'm aware of the workarounds as mentioned by shy on this thread and by Gadzooka on the thread I have linked to.
I have another workaround to add.
More, it's a workaround to try to use the SFX as a soundbank (with what I'm going to play back stored as a string) - I had originally tried with ascending notes by one instrument in each SFX, which failed when I wanted to play harmonies. To work around this bug, I rethought how I would construct my soundbanks.
In my own workaround I have put the same note, by eight different instruments, at four different octaves, into one SFX (32 notes total). So, the first SFX I have used has just the note C in it, played at four different octaves by eight different instruments. Then I have done this again for the remaining semitones, so 12 times in all. And this at 4 different speeds (ticks: 16,32,64,128) - for a total of 48 SFX used (4 speeds * 12 semitones).
The main limitation of my workaround is that for notes of the same length, even if they are played by a different instrument, they cannot be played at the same time if they are identically pitched or one or more octaves apart. But it allows me to play the harmonies I was going for.
Other limitations (such as only playing at one tempo) seem implementation specific. That is, I could write code which changes the tempo if I wanted, but have not.
Thoughts on a future workaround
I could work around this further (on another project, not my current one), for example by only poking notes (and the rest of the audio data) into SFX just ahead of when I am going to need them (which would greatly cut the number of SFX I need to use).
But my preference would be to have shy's suggestion implemented.
[Please log in to post a comment]