I’ve made myself a little program to generate 3 octaves of sine waves and play them ascending by half steps. Trouble is, every time I change notes, I get an annoying popping sound. What am I doing wrong? (please ignore my makeshift timer
#include "fmod.h"
#include "fmod.hpp"
#include <math.h>
#define twoToTheTwelfthRoot 1.059463094359295264562f
#define G2 98.00f
float freqLookup[36] = { 0 };
int timer = 0;
int iterator = 0;
FMOD::System *system;
FMOD::Channel *channel = 0;
FMOD::DSP *voice;
void *extradriverdata = 0;
int main(void)
{
//fill our lookup table
for (int i = 0; i < 36; ++i)
freqLookup[i] = G2 * powf(twoToTheTwelfthRoot, float(i));
//create/initialize the system
FMOD::System_Create(&system);
system->init(32, FMOD_INIT_NORMAL, extradriverdata);
while (true)
{
if (timer++ == 2500000)
{
//reset timer
timer = 0;
//clean up after ourselves
channel->setMute(true);
if(voice)
voice->release();
//create/play new note
system->createDSPByType(FMOD_DSP_TYPE_OSCILLATOR, &voice);
voice->setParameterFloat(FMOD_DSP_OSCILLATOR_RATE, freqLookup[iterator]);
system->playDSP(voice, 0, false, &channel);
channel->setVolume(0.75f);
if (iterator++ >= 35)
iterator = 0;
}
system->update();
}
return 0;
}
The problem is that you are destroying and recreating a new oscillator unit each time you change notes. Try creating the oscillator just once outside the loop. Then when you want to change notes, simply call DSP::setParameterFloat again. The new rate will take effect on the next mix, and there will be no pops or clicks.
#include "fmod.h"
#include "fmod.hpp"
#include <math.h>
#define twoToTheTwelfthRoot 1.059463094359295264562f
#define G2 98.00f
float freqLookup[36] = { 0 };
int timer = 0;
int iterator = 0;
FMOD::System *system;
FMOD::Channel *channel = 0;
FMOD::DSP *voice;
void *extradriverdata = 0;
int main(void)
{
//fill our lookup table
for (int i = 0; i < 36; ++i)
freqLookup[i] = G2 * powf(twoToTheTwelfthRoot, float(i));
//create/initialize the system
FMOD::System_Create(&system);
system->init(32, FMOD_INIT_NORMAL, extradriverdata);
//create/play sine wave
system->createDSPByType(FMOD_DSP_TYPE_OSCILLATOR, &voice);
voice->setParameterFloat(FMOD_DSP_OSCILLATOR_RATE, freqLookup[iterator]);
system->playDSP(voice, 0, false, &channel);
channel->setVolume(0.75f);
while (true)
{
if (timer++ == 2500000)
{
//reset timer
timer = 0;
//change notes
if (iterator++ >= 35)
iterator = 0;
voice->setParameterFloat(FMOD_DSP_OSCILLATOR_RATE, freqLookup[iterator]);
}
system->update();
}
//clean up oscillator
channel->stop();
voice->release();
//shutdown the system
system->release();
return 0;
}