Provide a way to set a channel's volume without creating popping artifacts

(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

can you advise what format the audio is, whether you are using playSound or playMusic, and what the filesize is?

The issue happens regardless of format or method of playing the audio. The code I provided demonstrates the issue with just a basic sine wave.