(Forgive me for posting yet another audio related thread as I continue to poke and prod all over the Playdate's C audio API!)
I've been playing around with setting a channel's volume or assigning it a volume modulator as part of my in-progress music engine. When audio is playing, making small adjustments to volume doesn't produce much in the way of audio artifacts. But large changes, especially changing a channel's volume between 0 and 1, generally results in a pop.
Here's some code to put in your update callback that demonstrates the issue by flipping a channel's volume between 0 and 1 every second:
static uint32_t lastTime = 0;
static SoundChannel *channel = NULL;
uint32_t currentTime = pd->sound->getCurrentTime();
if (!channel) {
channel = pd->sound->channel->newChannel();
PDSynth *synth = pd->sound->synth->newSynth();
pd->sound->synth->setWaveform(synth, kWaveformSine);
pd->sound->channel->addSource(channel, (SoundSource *)synth);
pd->sound->synth->playMIDINote(synth, NOTE_C4, 0.5, -1.0, 0);
}
if ((currentTime / 44100) != (lastTime / 44100)) {
pd->sound->channel->setVolume(channel, 1.0f - pd->sound->channel->getVolume(channel));
}
lastTime = currentTime;
I gather this happens because volume changes apply instantaneously, creating sharp discontinuities in the audio waveform. A better method would be to have the adjustment happen gradually over a very short interval. Just a basic linear adjustment over thirty samples (or around 0.7 milliseconds) is enough to avoid a pop. Because volume modulators only have a resolution of 256 samples that doesn't provide the ability to make large volume changes without creating popping artifacts.
I figure this counts as a feature request rather than a bug report because this part of the API is working as intended, and what I'm requesting would be an enhancement. That said, I think a case could be made for having what I'm suggesting simply be the way setVolume / volume modulators work, since generally speaking popping artifacts like that are always going to sound bad.
This thread is probably related: Clicks and pops when using amplitude LFO on a synth