オートワウの実装例
オートワウとはテンポに合わせてカットオフ周波数を変化させたフィルターを入力信号に適用するエフェクターです。
※オートワウは本やサイトによって説明が変わるようですが、ここではテンポに合わせてかかるワウをオートワウとすることとします。
パラメーターとして下記がよく利用されます。
パラメーター | 意味 | だいたいの範囲 |
---|---|---|
テンポ | ワウの周期 | 25~300BPM程度 |
深さ | ワウの深さ(周波数変化量) | 0~5程度 |
カットオフ周波数 | ワウで使用するフィルターのカットオフ周波数 | 200~5kHz程度 |
実装はカットオフ周波数をテンポに合わせて変化させたバンドパスフィルターを入力信号にかけます。
フィルタは「簡単なデジタルフィルタのサンプルコード」を使用しています。
あくまで実装例ですのでいい音質のものがほしい場合は、ご自身で試行錯誤いただくようお願いします。
【実装イメージ】
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
void autowah(float inL[], float inR[], float outL[], float outR[], int wavelength) { // inL[]、inR[]、outL[]、outR[]はそれぞれ入力信号と出力信号のバッファ(左右) // wavelenghtはバッファのサイズ、サンプリング周波数は44100Hzとする // エフェクターのパラメーター float tempo = 120.0f; // 同期するテンポ float depth = 3.5f; // ワウのかかり具合(変化量)。0.0~5.0程度 float freq = 800.0f; // ワウの周波数。50Hz~5kHz程度 // 内部変数 CMyFilter bandpassL, bandpassR; // フィルタークラス(https://www.utsbox.com/?page_id=728 より) float rate = 1.0f / ( 60.0f / tempo ) ; // テンポからワウの周期を求める。(とりあえず4分音符の周期にする。) float theta = 0; // ワウを周期的に掛けるためのcos関数の角度 θ。初期値は0 float speed = (2.0f * 3.14159265f * rate) / 44100.0f; // 揺らぎのスピード。角速度ωと同じ。 // 入力信号にエフェクトをかける for (int i = 0; i < wavelength; i++) { // 角度θに角速度を加える theta += speed; // cos関数の結果を0~1の間にする float a = (cos(theta) * 0.5f) + 0.5f; // ワウの周波数を計算 float tmpfreq = freq * (1.0f + a * depth); // バンドパスフィルタ設定(左右分) bandpassL.BandPass(tmpfreq, 1.0f); bandpassR.BandPass(tmpfreq, 1.0f); // 入力信号にフィルタをかけて出力する outL[i] = bandpassR.Process(inL[i]); outR[i] = bandpassR.Process(inR[i]); } } |
上記はあくまで実装例です。
バンドパスフィルタをローパスフィルタに変えたり、cos関数をノコギリ状の波形など 他の周期関数にすることでかかり方が変わってきます。
また、フィルタをかける前やかけた後に増幅したり飽和関数(tanh関数など)を適用してブーストしてみても面白いかもしれません。
質問はコメント欄や掲示板、Twitterでいただけばとおもいます。
他のエフェクター実装例はこちらにもあります。 → エフェクターの簡単な実装例
■掲示板
■Twitterアカウント:@vstcpp URL:https://twitter.com/vstcpp