I need to calculate a triangle and saw wave but it is a little complicate because of my model and the data I'm able to work with (but maybe I'm just confused).
I'm able to calculate my sine wave but I'm not really using a frame counter. What I do is, calculate a theta_increment
variable which I can use the next time I need to calculate a sample. This works like this:
float x = note.frequency / AppSettings::sampleRate;
float theta_increment = 2.0f * M_PI * x;
float value = 0;
if(waveType == SINE){
value = sin(note.theta) * fixedAmplitude;
}
Now that I have the value of the currend frame/sample I store theta_increment
inside my note.theta
member so I can use it for the next sample:
note.theta += theta_increment;
I've looked at tons of examples on how I should calculate a saw or a triangle but I can't figure it out. (I only have the data mentioned above at my disposal) This is my last attempt but it's not working and giving me tons of glitches:
value = 1.0f - (2.0f * ((float)note.theta / (float)44100));
A sawtooth wave could be calculated like this:
A triangle could be calculated like this:
where x is
note.theta
.If you have a loop generating your values like this:
Then you can use these functions for different types of waves:
The basic idea is that you want a value (pos) that goes from 0.0 to 1.0 over each cycle. You can then shape this however you want.
For a sine wave, the sin() function does the job, you just need to multiply by 2*PI to convert the 0.0 to 1.0 range into a 0.0 to 2*PI range.
For a sawtooth wave, you just need to convert the 0.0 to 1.0 range into a -1.0 to 1.0 range. Multiplying by two and subtracting one does that.
For a triangle wave, you can use the absolute value function to cause the sudden change in direction. First we map the 0.0 to 1.0 range into a -0.5 to 0.5 range by subtracting -0.5. Then we make this into a 0.5 to 0.0 to 0.5 shape by taking the absolute value. By multiplying by 4, we convert this into a 2.0 to 0.0 to 2.0 shape. And finally by subtracting it from one, we get a -1.0 to 1.0 to -1.0 shape.