Calculate saw and triangle wave from specific data

試著忘記壹切 提交于 2019-12-05 05:33:32

问题


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

回答1:


If you have a loop generating your values like this:

for (size_t frame=0; frame!=n_frames; ++frame) {
  float pos = fmod(frequency*frame/sample_rate,1.0);
  value[frame] = xFunc(pos)*fixedAmplitude;
}

Then you can use these functions for different types of waves:

float sinFunc(float pos)
{
  return sin(pos*2*M_PI);
}

float sawFunc(float pos)
{
  return pos*2-1;
}

float triangleFunc(float pos)
{
  return 1-fabs(pos-0.5)*4;
}

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.




回答2:


A sawtooth wave could be calculated like this:

value = x - floor(x);

A triangle could be calculated like this:

value = 1.0 - fabs(fmod(x,2.0) - 1.0);

where x is note.theta.



来源:https://stackoverflow.com/questions/12019304/calculate-saw-and-triangle-wave-from-specific-data

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!