Platform: macOS 13
SDK version: 2.5
(Running on Playdate Simulator)
I've been poking and prodding the PDSynth, PDSynthInstrument, and SoundSequence APIs trying to learn the ins and outs of creating music on the Playdate. Most recently I was trying to figure out how to properly release notes that are playing in a SoundSequence. What I'm finding though is that I can't make use of the note's release phase in all the cases I would want to.
Here's the code I'm using to set up music SoundSequence:
AudioSample *sample1;
PDSynth *synth1;
PDSynthInstrument *inst1;
SoundSequence *seq1;
sample1 = pd->sound->sample->load("audio/7000_tone-instrument");
synth1 = pd->sound->synth->newSynth();
pd->sound->synth->setSample(synth1, sample1, 2064, 4266);
pd->sound->synth->setReleaseTime(synth1, 0.2);
inst1 = pd->sound->instrument->newInstrument();
pd->sound->instrument->addVoice(inst1, synth1, 0, 128, 0);
pd->sound->channel->addSource(pd->sound->getDefaultChannel(), (SoundSource *)inst1);
seq1 = pd->sound->sequence->newSequence();
SequenceTrack *track1 = pd->sound->sequence->addTrack(seq1);
pd->sound->track->setInstrument(track1, inst1);
pd->sound->sequence->setTempo(seq1, 4);
If I play a note like this:
pd->sound->track->addNoteEvent(track1, 0, 2, NOTE_C4, 0.5f);
pd->sound->sequence->play(seq1, NULL, NULL);
...then the note plays for two steps and then releases, fading out in 0.2 seconds as defined by the PDSynth's ADSR envelope.
However, if I queue up a note like this:
pd->sound->track->addNoteEvent(track1, 0, 0xFFFF, NOTE_C4, 0.5f); // Using absurdly long duration
pd->sound->sequence->play(seq1, NULL, NULL);
and then stop the note using any of the following:
pd->sound->synth->noteOff(synth1, 0);
pd->sound->instrument->noteOff(inst1, NOTE_C4, 0);
pd->sound->instrument->allNotesOff(inst1, 0);
pd->sound->sequence->allNotesOff(seq1);
The note doesn't fade out using the ADSR envelope, but rather stops looping and plays through until the end of the sample. Similarly, if I queue an explicit "note off" in the sequence like so (assuming this is the correct way to do so -- there's no mention of it in the C documentation):
pd->sound->track->addNoteEvent(track1, 0, 0xFFFF, NOTE_C4, 0.5f);
pd->sound->track->addNoteEvent(track1, 2, 0, NOTE_C4, 0.0f);
pd->sound->sequence->play(seq1, NULL, NULL);
then I get the same seemingly wrong result, since I would expect all of the different ways of producing a "note off" would have the same effect, which is to use the PDSynth's ADSR envelope rather than just playing to the end of the sample. Unless perhaps there's something I'm subtly doing wrong here?
I've attached the sample I used to produce this behavior in case you want to try it out. It's a simple looping tone, but I added a little blip of a triangle wave to the end of the sample so that it's obvious when it plays to the end rather than fades out.
7000_tone-instrument.wav.zip (89.6 KB)