dsp_basics_03: oscillators
synthesis: the numerically controlled oscillator
We don't have to have an input signal to make sound with a computer. We can make up lists of numbers and send them to the sound card. This is digital synthesis.
Lets build a simple oscillator together. An oscillator needs to make some kind of repeating shape for us to recognize it as pitched. An oscillator that doesn't repeat will sounds like noise. The rate at which it repeats will determine the pitch.
A really simple one would just be a number that moves from 0 to 1 and then back again.
struct Phasor {
float phaseIncrement=0.00916666;
float phase = 0;
float next(){
phase += phaseIncrement;
if(phase>1){phase=phase-1;}
return phase;
}
};
Lets graph a few calls to the next function.
Its a sort of sawtooth wave! If we listen to the output of this we will notice that it sounds like crap. Its harsh and buzzy and not in a nice way. We can talk about why later. (It has to do with something called aliasing)
Lets make a sine wave instead. That might sound a bit better.
struct SineOscillator {
float phaseIncrement= 0.00916666;
float phase = 0;
float next(){
phase += phaseIncrement;
if(phase>1){phase=phase-1;}
return sin(2*PI*phase);
}
};
It makes a sine wave! It only plays the one note though... Lets add a function to change the frequency
struct SineOscillator {
float phaseIncrement= 0;
float phase = 0;
float next(){
phase += phaseIncrement;
if(phase>1){phase=phase-1;}
return sin(2*M_PI*phase);
}
void setFrequency(float frequency, float samplerate){
phaseIncrement = frequency/samplerate;
}
};