--/--/-- (--) --:--
スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。


2016/07/02 (Sat) 20:57
[C言語] LFOの周波数の値を対数スケールで動かしたいときの覚え書き

フィルター系エフェクターにLFOから値を与えてやりたいとき, 周波数の値を線形推移させると,
低音域をあっさり通過してなんかショボいかかり具合になりがちです.

というわけで多くの場合, 周波数は対数のスケールで値を動かしていくわけですが,
実際にどうやってその値を出すのかは調べても出てこなかったので, 半分自分用のメモとして書き残しときます.


例えば,
  float型変数now: LFOの現在値(0.0f~1.0f)
  float型変数freq_min, freq_max: 周波数の最小値, 最大値
とした場合,

  float base = 10.0f; // 底
float min = logf(freq_min) / logf(base); // 対数における最小
float max = logf(freq_max) / logf(base); // 対数における最大
float freq = powf(base, min + (max - min) * now); // 計算結果

で求めたい周波数freqが求められます(※math.hのincludeが必要).
今回は周波数の推移を想定しているので, 最小値に0を指定できない点に注意して下さい.



この方法で推移させると線形変化させた時に比べ低周波数の領域をゆっくり推移し,
人間の聴覚上ではまっすぐ変化したように感じさせることができます.



<追記> 上だと使いにくそうなので関数の形も載せておきます(ご自由にお使い下さい).
float getFreq(float now, float freq_min, float freq_max, float base) {
  float min = logf(freq_min);
  float max = logf(freq_max);
  return powf(base, (min + (max - min) * now) / logf(base));
}

サンプルプログラム(0.0~1.0の値を与えると10.0~5000.0の値を返します):
#include <stdio.h>
#include <math.h>

float getFreq(float now, float freq_min, float freq_max, float base) {
  float min = logf(freq_min) / logf(base);
  float max = logf(freq_max) / logf(base);
  return powf(base, min + (max - min) * now);
}

int main(){
  float now, result;
  while (1){
    printf("■0.0~1.0の値を入力: ");
    scanf("%f", &now);
    if ((now<0.0f) || (now>1.0f)) break;
    result = getFreq(now, 10.0f, 5000.0f, 10.0f);
    printf("結果: %.5f\n", result);
  }
  return 0;
}

サンプルプログラムの実行例:
サンプルプログラムの実行例

ご覧の通り, 小さい値を推移することがわかります.
1.0の結果で4999.99805となるように, 対数を経由するために計算に誤差が生じます.
計算精度が必要な場合はdouble型を使用して下さい.

double型を使用したサンプルプログラム:
#include <stdio.h>
#include <math.h>

double getFreq(double now, double freq_min, double freq_max, double base) {
  double min = log(freq_min);
  double max = log(freq_max);
  return pow(base, (min + (max - min) * now) / log(base));
}

int main(){
  double now, result;
  while (1){
    printf("■0.0~1.0の値を入力: ");
    scanf("%lf", &now);
    if ((now<0.0) || (now>1.0)) break;
    result = getFreq(now, 10.0, 5000.0, 10.0);
    printf("結果: %.5f\n", result);
  }
  return 0;
}

double型使用時の実行例:
double型使用時の実行例



<< [K-Shoot MANIA v1.60] ユーザー定義エフェクトの作成方法 | ホーム | K-Shoot Editor v1.60 beta1 (ベータ版) >>

コメント

コメントの投稿


管理者にだけ表示を許可する

 ホーム 


上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。