2

三角形とのこぎり波を計算する必要がありますが、モデルと処理できるデータのために少し複雑です (ただし、混乱しているだけかもしれません)。

正弦波を計算することはできますが、実際にはフレーム カウンターを使用していません。私がしているtheta_incrementことは、次にサンプルを計算する必要があるときに使用できる変数を計算することです。これは次のように機能します。

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

現在のフレーム/サンプルの値をメンバーtheta_increment内に保存しnote.thetaたので、次のサンプルに使用できます。

note.theta += theta_increment;

のこぎりや三角形を計算する方法について、たくさんの例を見てきましたが、わかりません。(私は自由に使える上記のデータしか持っていません)これは私の最後の試みですが、うまくいかず、たくさんの不具合が発生しています:

value = 1.0f - (2.0f * ((float)note.theta / (float)44100));
4

2 に答える 2

4

次のような値を生成するループがある場合:

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

次に、これらの関数をさまざまなタイプのウェーブに使用できます。

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

基本的な考え方は、各サイクルで 0.0 から 1.0 になる値 (pos) が必要だということです。その後、これを好きなように形作ることができます。

正弦波の場合、sin() 関数が機能します。2*PI を掛けて、0.0 から 1.0 の範囲を 0.0 から 2*PI の範囲に変換するだけです。

ノコギリ波の場合、0.0 ~ 1.0 の範囲を -1.0 ~ 1.0 の範囲に変換するだけです。2 を掛けて 1 を引くと、そのようになります。

三角波の場合、絶対値関数を使用して方向を急激に変化させることができます。まず、-0.5 を引いて、0.0 から 1.0 の範囲を -0.5 から 0.5 の範囲にマッピングします。これを絶対値を取って0.5~0.0~0.5の形にします。これを 4 倍して 2.0 から 0.0 から 2.0 の形状に変換します。そして最後にそれを 1 から引くと、-1.0 から 1.0 から -1.0 の形になります。

于 2012-08-18T14:41:39.780 に答える
2

ノコギリ波は次のように計算できます。

value = x - floor(x);

三角形は次のように計算できます。

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

ここで、x はnote.thetaです。

于 2012-08-18T14:32:39.430 に答える