weirdness trying to create a siren (or pitchbend)

DSP, Plugin and Host development discussion.
Post Reply New Topic
RELATED
PRODUCTS

Post

Hi, I'm running into a weird problem, and banging my head. I want to create something as simple as a siren VST that goes up and down in pitch, and much to my surprise, what I hear is not what I see and expect.

Here's my pseudo code:

Init()
{
basefreq=440;
freq=basefreq;
step=0;
direction=TRUE; // pitch going up or down
}

ProcessReplacing(input[], output[], samplecount)
{
for (i=0; i<samplecount; i++)
{
step=step+1;

if (freq<baseFreq/2) {direction=TRUE};
if (freq>baseFreq*2) {direction=FALSE};

if(direction==TRUE) {freq:=freq*1.001}
else {freq=freq/1.001;}

x=2*PI*step*freq/samplerate;

output=sin(x);
}
}

The pitch is supposed to go up and then down, but instead I can hear it go up when it's supposed to go down. I check the values of freq in the debugger, but what I'm hearing is very different from the frequencies I'm supposed to hear. Sometimes I even hear two voices.

If I put this line "if(direction==TRUE) {freq:=freq*1.001} else {freq=freq/1.001;}" out of the loop, so that the frequency changes only per buffer and not per sample, it does sound a bit like what's expected, but still with lots of artifacts and jitter.

Can somebody explain me what I am missing ? Can somebody point out what is the logic required to produce something as simple as a siren ?

Thanks.

Post

pureveg wrote: x=2*PI*step*freq/samplerate;

output=sin(x);


Your problem is that you're calculating the phase from the frequency here as if it was constant. Instead of calculating the current phase as "time*frequency" you need to integrate the phase (ie. accumulate it into a variable, instead of accumulating the step value which is useless), such that the phase of the current sample is the phase of the previous sample plus the phase-change at the current frequency.

Post

Thanks, I'll need to think about that.

Post

Try renaming step to phase, and then instead of:

Code: Select all

 step=step+1
 ...
 x=2*PI*step*freq/samplerate;
try:

Code: Select all

 phase=phase+freq/samplerate
 if phase>=1 then phase=phase-1
 ...
 x=2*PI*phase;
Further code rearrangements will then probably suggest themselves :)

Post Reply

Return to “DSP and Plugin Development”