BonzomaticのFFTを丁寧に使う
https://gyazo.com/0878634f9dec3ce44d8b84a96d42aad6
生
ピンクノイズを流した状態で、素の texFFTSmoothed を流してみる code:glsl
float v = texture( texFFTSmoothed, uv.x ).x;
out_color += vec4( step( uv.y, v ) );
https://gyazo.com/95892a789595320efffd1026de7dbdfb
なんじゃこりゃ
振幅方向・周波数方向をそれぞれ対数にしてやらないと使い物にはならない
振幅方向
デシベルってやつを使います 慣れてるメトリクスでしょ $ L = 20 \log_{10} \left( \frac{V}{V_0} \right)
code:glsl
float v = texture( texFFTSmoothed, uv.x ).x;
v = 20.0 * log( v ) / LOG10;
v = linearstep( -60.0, 0.0, v );
out_color += vec4( step( uv.y, v ) );
https://gyazo.com/9d45316b5378d386fd57860fa371e1c0
だいぶマシ
周波数方向
$ \log_2(x') = {\rm lerp}(\log_2(x_0), \ \log_2(x_1), \ x)
$ x_0と$ x_1がどの周波数に対応するかは、端末のサンプルレート次第だと思います
以下のコードのように -9.0 から -1.0 を取る場合、
サンプルレートが48,000Hzなら、47Hzから12,000Hzまでが取れているはず
ジャンルによっては範囲を変えたいこともあると思うので注意
code:glsl
float x = exp2( mix( -9.0, -1.0, uv.x ) );
float v = texture( texFFTSmoothed, x ).x;
v = 20.0 * log( v ) / LOG10;
v = linearstep( -60.0, 0.0, v );
out_color += vec4( step( uv.y, v ) );
https://gyazo.com/50398f2556b39a813ca7035df042840b
いい感じだよ
+3dB/oct
ピンクノイズは、オクターブが1上がるごとに3dB振幅が下がっている
これを-3dB/octという
逆に+3dB/octの補正をかけてやれば、このグラフが平らになってくれる
下のコードでは、xが線形に8オクターブ上がっているので、
uvに比例して24dB上げてやる
code:glsl
float x = exp2( mix( -9.0, -1.0, uv.x ) );
float v = texture( texFFTSmoothed, x ).x;
v = 20.0 * log( v ) / LOG10;
v += 24.0 * uv.x;
v = linearstep( -60.0, 0.0, v );
out_color += vec4( step( uv.y, v ) );
https://gyazo.com/cc3f6fd4a26992738c804173b1cbc7b4
オケー
だいたいの音楽は-3dB/octみたいなミキシングになっているはず
ジャンルによってはベース強めにしてあったりとかするので、まあ目視で平らになるように調整するのが吉
関数
関数にパッケージングすると、以下のような感じ
デシベルで結果が返ってくるので、linearstep使っていい感じの値域を取り出して使ってね
code:glsl
float fetchFFT( float x ) {
float xt = exp2( mix( -9.0, -1.0, x ) );
float v = texture( texFFTSmoothed, xt ).x;
v = 20.0 * log( v ) / LOG10;
v += 24.0 * x;
return v;
}
texFFTIntegratedのほう
texFFTIntegrated も+3dB/octした~い
ただし、 texFFTIntegrated はVの積分値なので、デシベルで線形に掛け算とかできない!困った!
→ +3dB/octをVに変換してあげよう
$ V = V_0 \cdot 10^{L/20}
code:glsl
float fetchFFTInt( float x ) {
float xt = exp2( mix( -9.0, -1.0, x ) );
float v = texture( texFFTIntegrated, xt ).x;
v *= pow( 10.0, 24.0 * x / 20.0 );
return v;
}