## weirdness trying to create a siren (or pitchbend)

DSP, Plug-in and Host development discussion.
pureveg
KVRer
3 posts since 17 May, 2009
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.

mystran
KVRAF
5032 posts since 12 Feb, 2006 from Helsinki, Finland
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.
If you'd like Signaldust to return, please ask Katinka Tuisku to resign.

pureveg
KVRer
3 posts since 17 May, 2009
Thanks, I'll need to think about that.

kryptonaut
KVRian
728 posts since 25 Apr, 2011
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