Oscillator changing pitch causing popping


(Thomas Cushman) #1

Hi everyone!

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 :slight_smile:

#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;
}

(Graeme Webb) #2

Hi Thomas,

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;
}