UE4+ADX2でサウンドエフェクターを作ってみる

# はじめに
アンリアルエンジン4とサウンドミドルウェア「ADX2 for UE4」を連携させ、
BGMに自由に変化をかけられるサウンドエフェクターとそのUIを作ります。

こんな感じになります↓
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">UE4アドカレ2の担当日なので、UE4+ADX2（サウンドミドルウェア）で作るオーディオエフェクターの実装について書きました。<br>動作例はこんな感じ↓<br>BGMにフィルターやピッチ、リバーブなどといったエフェクトをマウス操作でかけて遊べます。<a href="https://t.co/DLT3ElUZim">https://t.co/DLT3ElUZim</a> <a href="https://twitter.com/hashtag/UE4?src=hash&amp;ref_src=twsrc%5Etfw">#UE4</a> <a href="https://twitter.com/hashtag/ADX2?src=hash&amp;ref_src=twsrc%5Etfw">#ADX2</a> <a href="https://twitter.com/hashtag/UE4Study?src=hash&amp;ref_src=twsrc%5Etfw">#UE4Study</a> <a href="https://twitter.com/hashtag/Qiita?src=hash&amp;ref_src=twsrc%5Etfw">#Qiita</a> <a href="https://t.co/ua9ucZr7tr">pic.twitter.com/ua9ucZr7tr</a></p>&mdash; Sig @ゲーム開発 (@sleepyslowsheep) <a href="https://twitter.com/sleepyslowsheep/status/1340412300386160641?ref_src=twsrc%5Etfw">December 19, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>


当記事ではUE4.23+「ADX2 LE v2.10.05」を使用します。基本的にブループリントのみでの実装を想定しています。
ADX2はインディー向けの「LE版」であれば、無料で使用できます。
https://game.criware.jp/products/adx2-le/

# 前提
ADX2 for UE4の導入や基本的な使い方は以下の記事にあります。当記事だけでも実装はできるかと思いますが、必要に応じて参照してください。
ADX2 for UE4の導入で、一歩上のサウンド表現を（導入編）
https://qiita.com/SigRem/items/4250925f6d66a4fd287a
ADX2 for UE4の導入で、一歩上のサウンド表現を（実践編）
https://qiita.com/SigRem/items/c089b71c42e898980a46

# 実装

## AtomCraftでBGMとエフェクトを構成する

### マテリアルのインポート
音源を用意し、AtomCraftに「マテリアル」として取り込みます。
![A01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/9dfa5b8f-0993-e1ae-b70a-bc35fc5dcbba.png)

### キューの作成
新規にキューを作成します。「新規オブジェクト」→「キュー『ポリフォニック』の作成」を選びます。
![A02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/463f052b-1f30-147e-2f68-6809fe10a11c.png)
作成したキューにマテリアルをD&Dし、トラックを作ります。
![A03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/b1e81d4a-e29b-73e6-9c59-6ca5fce9582e.png)

### AISACコントロールの作成
サウンドにエフェクトをかける「AISACコントロール」を作成します。
トラックリストの空欄で右クリックし、「新規オブジェクト」→「AISACの作成」を選択します。
![A04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/8fef3b58-2e46-8447-16ab-c1dd807ee6e1.png)
ダイアログが出るので、ハイパスフィルター用の設定をします。
![A05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/03cc74d3-b5cc-732e-2cea-60431962c188.png)
「AISACグラフタイプ」を「バンドパス - Cof高域」にします。
![A06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/1326ef03-3aed-2d43-941c-bd9a8a44ceff.png)
AISACコントロールが作られますが、必要なAISACコントロールを一括で作成したいので、一旦下部の「タイムライン」タブをクリックして戻ります。
![A07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/1431f299-1773-c2d9-5803-2caad3d17e2d.png)
ローパスフィルター用のAISACコントロールとピッチ変更用のAISACコントロールを作成します。
![A08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/237c066d-4669-2da2-aea0-af6ae3290fac.png)
![A09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/efda51c7-c5ef-5ebb-34b2-0b0c6b578497.png)


### AISACコントロールの編集
作成したAISACコントロールのグラフを編集します。
コントロールポイントをつまみ、上下に動かしてシンプルな直線にします。
ハイパスでは半分まで下るように、
![A10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/d7450de1-6164-f7ab-8911-23e9b0ed2a2c.png)
ローパスでは半分まで上るように、
![A11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/6b2e7d21-e37f-ac62-9f90-470d247c1a95.png)
ピッチは「0.5」の値が真ん中にくるようなグラフにします。
![A12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/77f8bafd-f658-7f2a-7909-f7f0abe802dc.png)

ここまでできたら、上部のスライダーを動かして動作をチェックしてみましょう。

### バンドパスの編集
リバーブなどのエフェクトをかけるための「バンドパス」を作ります。
プロジェクトツリーの「DspBusSettings_0」をダブルクリックすると、ミキサーが表示されます。
![A13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/9f93bea0-3451-e426-4f07-0b21284466f3.png)
「MasterOut」の横の空欄で右クリックし、「DSPバスの追加」を選びます。
![A14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/be5ca723-23fd-2dfd-7c1a-33521ff2a33f.png)
「Atom Sound Renderer(ASR)」→「リバーブ」を選択します。
![A15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/4dfa1f00-37f0-177c-5376-f716e3805d6b.png)
インスペクターでリバーブのかかり方を調節できます。
![A16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/ec9307af-f273-2e76-1a00-a6e5ad486f41.png)
同じように「フェーザー」「コーラス」のバス、エフェクトを追加します。また、それぞれのバスをリネームしました。
![A17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/930541a2-4a16-078c-8199-267944738b9e.png)
好みのエフェクトを追加してもいいでしょう。
また、下部の「センド」に「MasterOut」を追加し、エフェクトがかかったサウンドがMasterに流れるようにします。
![A18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/57af739f-f2c0-cb36-a399-10727faf0525.png)

### バスマップの作成
使用するバスを登録した「バスマップ」が必要なので作成していきます。
プロジェクトツリーの「バスマップ」から、「BusMap_Default」を選択します。もし別途使用したいバスマップがある場合、そちらを指定します。
![A19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/09734ee7-5c9a-ea35-9749-52d7102e391e.png)
インスペクターで、使用するバスを登録します。画像のようになっていればひとまずOKです。
![A20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/ea2bbada-0c00-239e-659e-e13db7c31c63.png)
キューにバスを設定します。
キューを選択し、インスペクターでバスマップを「BusMap_Default」または任意のバスマップに設定し、各バスセンドにチェックをつけ「MasterOut」以外の音量を0にします。
![A21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/4d1f7f95-440c-03b0-664d-be84a3fd19da.png)
これで初期状態ではエフェクトのかからないサウンドが再生されることになります。

### キューシートのビルド
ここまでできたら、キューシートをビルドし、UE4に持っていく準備をします。
![A22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/4c241595-ac9f-39d9-ce3e-1f001700ffda.png)
![A23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/659c728d-ba7b-9314-7df3-1b9cfb2ddd36.png)

## UE4でUI、エフェクターを構成する

### キューシートのインポート
ビルドしたキューシートをインポートします。
![B02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/ed902c58-cb2b-51ea-c953-a3848662f7a4.png)


### acfファイルの設定
ツールバーの「Edit」→「Project Settings」からプロジェクト設定を開きます。
![B03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/a41481f4-64ad-6e3c-1da5-ccfb49e78b69.png)
CriWareタブの「Atom Config」にインポートしたacfファイルを指定し、再起動します。
![B04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/8bccf536-4163-8789-8890-ca02946bb90d.png)

### キューの配置
コンテンツブラウザからレベル上にAtomキューをD&Dして配置します。
![B05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/7a6679fb-1ef3-69bc-8403-c8867a8a20cf.png)
DetailsパネルでAISACコントロールの初期値を設定します。ピッチだけは「0.5」が通常の再生になるため、設定しておきます。
![B06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/fa505616-fea1-28b2-9a76-7710711a3c2a.png)


### ウィジェットの作成
エフェクトを操作するためのUIを作成します。
例として、UMGでこんなUIを作ってみました。単純な画像とテキスト、スライダーの組み合わせです。
![B00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/9c4819db-8f04-6dc3-7362-8d03bb487aa1.png)
上部のパネル上でマウスを動かすと、X方向ではローパスフィルターが、Y方向ではハイパスフィルターがかかります。
![B01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/70357060-ccc5-b4ae-20df-e5001b35363d.png)
下部のスライダーはピッチと、各バスの音量を変更できるものです。

### ハイパス・ローパスフィルターの処理
ウィジェットのブループリントでフィルターの処理を作ります。
ウィジェットのブループリント内で、「Atom Sound」型の変数を作っておきます。
![B11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/070c3204-c52e-3693-4fb2-06bdcad3fdc2.png)

次の画像では、Tickごとに
①マウスがイメージの上に乗っているか判別し、
②ビューポート上のマウス位置を取得します。
③マウスのX軸をローパスフィルターに反映し、
④マウスのY軸をハイパスフィルターに反映します。
![B07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/664d8c5a-516a-8e1e-79f3-834df30a3601.png)
「GridOffset」はそれぞれフィルター用画像の位置が、「GirdSize」はフィルター用画像の大きさが代入されています。

### ピッチ・エフェクトスライダーの処理
各スライダーの値を「Set Bus Send Level」、「Set Bus Send Level Offset」に代入します。
Slider_Masterだけは初期値が1なので割合で指定できる「Set Bus Send Level」を、
他のスライダーは初期値が0なので、オフセット値で操作できる「Set Bus Send Level Offset」を使用します。
ピッチだけはAISACコントロールで管理しているので、「Set Aisac by Name」ノードを使っています。
![B08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/c0a8e287-dda1-55d5-2587-ccb58d829b1c.png)

これでUI処理の実装は完了です。


### ウィジェットの呼び出し
最後に、ゲーム内でUIを呼び出せるようにします。
レベルブループリントを開きます。
![B09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/247ac56a-e296-3921-a195-486551970c36.png)
レベル内でAtom Soundを選択しておき、グラフ内で右クリックしリファレンスノードを作成します。
![B12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/ab91483d-1a20-d2b1-3c2c-08d9e993b64a.png)
![B14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/a6465884-25cc-2d85-6652-5acff777d3b4.png)

「Create Widget」でウィジェットを呼び出し、ウィジェットブループリントが持つ変数「Atom Sound」にレベル内のAtom Soundを代入します。
「Set Viewport Mouse Capture Mode」「Show Mouse Cursor」を使ってマウスカーソルを操作可能にします。
![B10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/2955b76c-9852-eea6-627f-4579faba2736.png)

### 完成！
![B13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154452/f82cb09d-87ef-b7e1-5e24-1639606c95f8.png)

スライダーを動かしたり、グリッド内でマウスを動かして動作を確認してみましょう。
処理を分解してインタラクティブミュージック的な演出にしてもいいですし、そのデバッグ機能としても使えるかと思います。