LemonteaのUnity部屋

LemonteaのUnity部屋

Unityの使い方とかです~

Unity GetSpectrumDataで音程で上下動するキューブ

こんにちは。レモンティーです。

今回は、BGMの音程に合わせて上下運動するキューブを
AudioSourceのGetSpectrumDataをつかって
作りたいと思います。

とはいったものの
私はそっち系の知識が0で、
フーリエ変換、窓関数、チャンネル、アウトプットサンプルレートなどの
基本となる単語の意味すら全くわからなくて
ググりながらやったので
めちゃ大胆に間違った事を書いているかもしれません。
発覚したらそのとき訂正します

やることは、
キューブのy座標を0.5秒に一回更新
その座標は、その時一番強く鳴ってる音の周波数(高さ)
という感じです。


周波数は、
AudioSourceのGetSpectrumDataを元に求めます。

これは
GetSpectrumData(float samples, int channel, FFTWindow window);
のように使うと
引数に入れたfloat型の配列にデータを入れてくれるものです。

データが帰ってきた配列には、
各周波数の音の強さが入っています。

ある瞬間になっている音には
様々な周波数の音が入ってるので
各周波数の音がどれくらいの強さか教えてくれているわけです。

しかし、周波数は連続した値なので
全てについて答えることは不可能です

帰ってきた配列には、飛び飛びの周波数ごとの
強さが入っています。

例えば、
AudioSettings.outputSampleRateをA
引数の配列Sampleの要素数をBとすると、

Sample[i]には
周波数 i*A/2B Hzの音の強さ
が入った状態でかえってくるみたいです。

要は、最小単位A/2Bの整数倍の周波数の音の強さだけ
調べてくれるということです

ここで注意しなければならないのは、

Bは
2のべき乗で
範囲は64~8192(両端含む)

でなければならないということです。

↑を満たしていれば自由です。


さて、これを使って一番つよい音の高さを求めるには
Sample[i]が最大になるiについて
i*A/2Bをすればいいことになります。

私の場合、Aはデフォルトで44100Hzで、
配列の要素数は1024でやったので

周波数f = i * 44100/2048 ですが
キューブのy座標にはでかいので1/100して使います
(だったらもうiに比例してればなんでもよさそうですけどね笑)

これをコルーチンで0.5秒に一回計算すれば
冒頭でいったやることは実現したことになります

それでは実行してみます

youtu.be


…………

…これは残念なできですね笑

しかし、曲の終わり際とか、明らかに大きい音のときは
それっぽい動きをしています。

つまり、根本的に違うと言うよりは
背後の音の方が強いと判定されたときに
しっくりこない動きをしているのかもしれません。

まだ改善の希望はありそうです笑

今回はこれで終ります。



Audio関連
(こっちは普通に目的達成してます)
sawalemounity.hatenablog.com
sawalemounity.hatenablog.com