オーディオエフェクトの話
目次
お疲れ様です。
システム開発室、松山です。
ふと、オーディオフィルターってあるけど、リバーブくらいしか使った事ないなと思いたち、
他のフィルター(エフェクト)について確認してみました。
Audio Filter
まずはどんなフィルターがあるか確認しましょう。
公式のドキュメントはこちら
Low Pass Filter
Low Pass なので、高い周波数をカットするフィルターです。
壁など遮蔽物の向こう側や、スピーカーの裏側など高周波が減衰した状態の聴こえ方になります。
High Pass Filter
Low Pass とは逆に、低い周波数をカットするフィルターです。
物理現象としては高周波数から減衰するはずなので、安いイヤホンなどで低い周波数が再生できない感じの聴こえ方でしょうか。
チャカチャカした感じの音になります。
Echo Filter
エコーですね。同じ音を減衰させながら繰り返してくれます。
カラオケボックスでエコーかけて歌ってるイメージです。
間隔を広げると、山彦みたいになるかもです。
Distortion Filter
ボリュームとは関係なしに音を大きくします。
低品質なので音割れみたいな感じに歪みます。
Reverb Filter
個人的には、一番使う機会が多いフィルターです。
ホールや地下道など、閉じた空間で反響した感じに聞こえます。
あと、マイクを通して聞こえてくる音声のようなイメージでしょうか。
設定できるパラメータが一番多く、素人の自分には調整仕切れない感があります。
Chorus Filter
合唱のような感じに、変調された音声を合わせて再生するフィルターです。
サンプルで試したのですが、何かうまく効いてくれませんでした。
知っている方いたら教えてください…
要件
いつものように、Unity でサンプルを作成して実際に試していきます。
① Audio Listener に各種フィルターを設定
② 各フィルターをチェックボックスで on / off できるようにする
③ Low Pass と High Pass フィルターは、スライダーで周波数を指定
④ bgm, se, ジングルをそれぞれ再生できるようにする
⑤ オーディオスペクトラム的なものを表示してみる
こんな感じ。
各フィルターのパラメータはデフォルト状態。
いくつかの音声を再生する UI を作るくらいです。
オーディオスペクトラムはそれっぽく動いてくれれば OK とします。
Audio Listener にフィルターを設定する
MainCamera の Component に Audio Listener があるので、その下に各フィルターを追加していきます。
Low / High Pass Filter 以外はチェックボックスで切り替えるので、デフォルトはオフにしておきます。
各フィルターをチェックボックスで on / off できるようにする
UI.Toggle を使って作成。(こんな感じ↓)
トリガー用のメソッドを用意して、
// Filter 用トグル public void OnClickToggleFilter(int no) { switch ((FilterNo)no) { case FilterNo.Chorus: fltChorus.enabled = tglChorus.isOn; break; case FilterNo.Distortion: fltDistortion.enabled = tglDistotion.isOn; break; case FilterNo.Echo: fltEcho.enabled = tglEcho.isOn; break; case FilterNo.Reverv: fltReverb.enabled = tglReverv.isOn; break; } }
OnValueChanged で設定してあげれば OK。
Low Pass と High Pass フィルターは、スライダーで周波数を指定
Low Pass と High Pass フィルターはスライダーで設定できるようにする。
ついでに、ボリュームとピッチも作ってしまう。
スライダーのj反映はこんな感じで。
① イベントリスナーを設定
// 低音通過 sldLoPass.onValueChanged.AddListener((value) => { setLoPass(value); });
② フィルターに値を設定
// 低域通過フィルター設定 private void setLoPass(float val) { var loPassHz = ExpHz(val); fltLoPass.cutoffFrequency = loPassHz; txtLoPass.text = string.Format("{0:#}", loPassHz); }
※ ExpHz で 0.0 〜 1.0 の値を、10 〜 22000 Hz に変換してます
float ExpHz(float logHz) { var t = Mathf.Log(LowHz) - Mathf.Log(HighHz); return Mathf.Exp(logHz * t) * 10f; }
bgm, se, jingle をそれぞれ再生できるようにする
UI.Button を使って、音声を再生できるようにします。
イベントリスナーを設定して、再生 / 停止を切り替えます。
AudioSource.Play(), Stop() を使用します。
// BGM 再生・停止 btnBgmPlay.onClick.AddListener(() => { if (!bgmSource.isPlaying) bgmSource.Play(); else bgmSource.Stop(); });
オーディオスペクトラム的なものを表示してみる
最後に波形データを表示してみます。
タイトル画像に出てるやつです。
AudioListener のGetSpectrumData() を使用します。
実装は、こちらを参考にさせていただきました。(感謝です)
スマホ実機でサウンドのスペクトル解析を見たい
GetSpectrumData() で取得したオーディオサンプルを、UI 表示用に 512 分割した周波数帯に分けます。
AudioListener.GetSpectrumData(spectrumData, 0, FFTWindow.Hanning); var outputF = AudioSettings.outputSampleRate; // 全binを初期化 for (int i=0; i<bins.Length; i++) { bins[i] = 0f; } var logMaxF = Mathf.Log(graphMaxFrequency); // 上のbinの周波数のlog var logMinF = Mathf.Log(graphMinFrequency); var logRange = logMaxF - logMinF; if (logRange <= 0f) { logRange = 8f; } // まず周波数分類 for (int i=0; i<spectrumData.Length; i++) { var f = outputF * 0.5f * (float)i / (float)spectrumData.Length; if (f == 0f) { f = float.Epsilon; } // 対数を取ってどのビンに入るか確定 float binValue = (float)bins.Length * (Mathf.Log(f) - logMinF) / logRange; int binIndex = Mathf.FloorToInt(binValue); if ((binIndex >= 0) && (binIndex < bins.Length)) { // そのビンにデータを加算 bins[binIndex] += spectrumData[i]; } }
各ブロックで表示するためのベースとなる Prefab を作成します。
Width : 3, Height:0 の UI.Image です。
これを画面左から順に並べ、値の大きさに合わせて高さを設定します。
// バーに反映 for(int i=0; i<BinCount; i++) { float v = bins[i]; float y = Mathf.Min(v * 8000f, 420f); Vector2 sd = new Vector2(BarWidth, y); spectrumBars[i].sizeDelta = sd; }
これで音声を再生すると波形データがそれっぽく表示されるようになると思います。
まとめ
一通りのオーディオフィルターを試してみました。
Chorus は上手く効いてくれませんでした(涙)
やはり、リバーブと Low Pass 以外は使いどころ難しい感じがします。
Unity には Audio Mixer もあるので、より細かい設定をしたい場合はこちらを使うと良いかもしれません。
正直、素人が手を出して良い領域ではない気がしますが…
それでは、今回のお話はこれまでになります。
今回も、Git に上げておきます。
何かの参考にでもなれば幸いです。
Unity サンプル
また、音声データは以下から使用させていただきました。
OtoLogic 様
音の森 様
最後に
私が所属するシステム開発のサービスサイト「SEKARAKU Lab(セカラク ラボ)」を開設しました。
ビヨンドは、サーバーの設計・構築から運用までをワンストップでお任せいただけますので、サーバーサイド開発でお困りの方はお気軽にお問い合わせください。
SEKARAKU Lab:[https://sekarakulab.beyondjapan.com/](https://sekarakulab.beyondjapan.com/)
ありがとうございます。