LemonteaのUnity部屋

UnityとかC#のおはなしです~

Unity GetSpectrumDataを使う

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

今回は、
AudioSourceのGetSpectrumDataをつかってみたいと思います。

GetSpectrumDataというのは、その名の通り
ある瞬間のBGMのスペクトラムデータを取得できるものです。

これでなにをするかというと…
BGMの音程にあわせて上下移動するキューブをつくってみます。





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

やることは、

・キューブのy座標を0.5秒に一回更新
・その座標は、その時一番強く鳴ってる音の周波数(高さ)が大きいほど高くする

という感じです。


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

これは

GetSpectrumData(float[] samples, int channel, FFTWindow window);

のように使うと
引数に入れたfloat型の配列にデータを入れてくれるものです。

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

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

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

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

例えば、Sample[i]には
AudioSettings.outputSampleRateをA
引数の配列Sample[]の要素数をBとすると、
「周波数 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


…………

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

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

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

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

ーーーーーー
後にGetSpectrumDataでレベルメータのようなものを
つくった記事がこちらです
sawalemounity.hatenablog.com

ーーーーーー

それでは今回はこれでおしまいです。


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