0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Unreal Engine 5.8で環境音から突発音の左右を推定する――35/35検知、左右97.14%

0
Last updated at Posted at 2026-07-25

こんにちは、皆さん。

人は雑踏の中でも、突然鳴った音へすぐ注意を向けられます。ゲーム内のagentにも同じ入口を持たせるなら、個々の音源情報を直接読むのではなく、耳に届いた音だけから「何か鳴った」「左から聞こえた」と判断できると面白そうです。

さて、今日はUnreal Engine 5.8の連続環境音に40 msの突発音を混ぜ、HRTF処理後のstereo PCMだけから検知、左右推定、候補音の抽出を行います。短い固定listener demoでは35 eventをすべて検知し、左右は34/35、**97.14%**正解しました。検知latencyは20〜60 ms、中央値20 msでした。

ただし、これは移動可能なlistenerを追加する前の短いdemo結果です。5分間のnegative試験と抽出品質のSI-SDR測定はまだ完了していません。

Unreal Engine 5.8で動くMixedAudioAttention。中央のblock pawn、6つの音源、左右の波形とspectrogramを表示している

Unreal Engineのbinaural audio

Unreal Engine 5は2022年4月に正式公開されたreal-time 3D engineです。現在のAudio Mixerは、音源の再生だけでなく、procedural synthesis、submix、DSP、C++ APIを備えています。今回は2026年のUnreal Engine 5.8を使いました。

Resonance AudioはGoogleが2017年11月に公開したspatial audio SDKです。音源の方向を、左右の耳へ届く時間差、音量差、周波数特性の差として表すHRTF(Head-Related Transfer Function)処理を行えます。

今回の設定はBINAURAL_HIGHです。Unreal Engine 5.8のResonance Audio設定では、third-order Ambisonicsを使うhigh quality modeとして説明されています。結果はheadphone向けの左右2 channel音声になります。

ライセンス

対象 ライセンス
Unreal Engine 5.8 Unreal Engine EULA
Resonance Audioの公開SDK Apache License 2.0

Unreal EngineはOSSではなく、利用と配布にはEULAの条件が適用されます。Resonance Audioの公開sourceはApache License 2.0ですが、Unreal Engineに同梱されたpluginやEngine codeを扱う場合は、Epicの配布条件も確認してください。

今回検証する内容

環境音とtargetを混ぜ、listenerへ届いた後のMain Output Submixを48 kHz stereoで取得します。analyzerへ渡すのはこのPCMだけです。音源actorの位置や発音状態を検知器へ直接入力しません。

  • 帯域別energy riseと全帯域RMS riseで、環境音中の40 ms burstを低遅延に検知できるか
  • 変化した時間周波数binのGCC-PHATとILDから、音が左か右かを推定できるか
  • 検出時刻と推定方向から作ったsoft maskで、候補clipを再合成できるか

完全なC++ code、設定、Automation Test、集計JSONは、kiarina/labsのunreal-mixed-audio-attention labで公開しています。

検証環境の再現

macOSへUnreal Engine 5.8、対応するXcode、miseを用意し、UE_ROOTへEngineのroot directoryを指定します。projectはC++でbuildするため、Editorで開いている場合は先に閉じてください。

git clone --depth 1 --filter=blob:none --sparse \
  https://github.com/kiarina/labs.git
cd labs
git sparse-checkout set .gitignore .mise/tasks Makefile mise.toml \
  2026/07/25/unreal-mixed-audio-attention

export UE_ROOT=/path/to/UE_5.8
mise -C 2026/07/25/unreal-mixed-audio-attention run
mise -C 2026/07/25/unreal-mixed-audio-attention run test
mise -C 2026/07/25/unreal-mixed-audio-attention run editor

最初のmise ... runはEditor targetのbuildとproject構造の検証を行います。testはsignal生成、左右推定、SI-SDR関数のAutomation Testです。editorで通常の5秒calibration demoを開きます。

PIEを開始したら、W/Sで前後、A/Dで左右へ移動し、mouseでcameraと頭部listenerを回転できます。水色のENV球または橙色のBURST球へ接触すると、その音源のon/offが切り替わります。操作をEditorへ戻すkeyはShift+F1です。

音が判断へ変わるまで

処理の流れは次のとおりです。

2つの連続環境音 + 4方向の40 ms target
  -> Resonance Audio / HRTF
  -> 48 kHz stereo Main Output Submix
  -> 5秒ring buffer
  -> 1024-point STFT、480 sample hop
       ├─ onset: 8帯域energy rise + 全帯域RMS rise
       ├─ side: 200–1500 Hz masked GCC-PHAT + 1.5–8 kHz ILD
       └─ extract: 時刻と方向からsoft maskを生成
  -> raw / extracted stereo WAV + run JSON + HUD

STFTは短い時間ごとに音を周波数へ分解する処理です。1024 sampleは48 kHzで約21.3 ms、hopの480 sampleは10 msに相当します。

1. 突発音を検知する

左右を合成したspectrogramを8帯域に分け、直前からenergyがどれだけ増えたかを見ます。全帯域RMSの増加も別経路で計算し、大きい方をonset scoreにします。

初版では3帯域のriseを平均しましたが、狭い帯域のburstが他の帯域に薄められました。最大帯域riseを採る経路へ変更すると、短い音へ反応しやすくなりました。thresholdはcalibration中のscore中央値とMADから決めます。

2. 左右を推定する

GCC-PHATは左右の波形の時間差を相互相関から探す方法です。今回は200〜1500 Hzのうち、onsetで変化したbinだけを使います。

高い周波数では頭による遮りが左右のlevel差として出やすいため、1.5〜8 kHzのILD(Interaural Level Difference)も投票へ加えます。GCC-PHATとILDが十分に一致しない場合は、無理に左右を決めずUnknownにします。

3. 候補clipを抽出する

eventの250 ms前から750 ms後まで、合計1秒を切り出します。event前の区間をbaselineにして、そこからenergyが増え、推定した側と整合するbinへ大きな重みを置くsoft maskを作ります。左右へ同じmaskを適用し、iSTFTで時間波形へ戻します。

左右へ同じmaskを使うのは、抽出によって新しい左右差を作らないためです。rawとextractedはPCM16 WAVとしてSaved/MixedAudioAttention/へ保存します。

実験空間と条件

内周3 mにseed固定の連続noiseを2音源、外周5 mにtargetを4音源配置しました。距離減衰は無効です。listenerが動いても、距離による音量差ではなく、頭部に対する相対方向の変化を観察します。

項目 条件
Engine Unreal Engine 5.8
OS / machine macOS 26.5.2 / Apple M4 Max
audio 48 kHz、stereo、Resonance Audio BINAURAL_HIGH
環境音 左右2つのseed固定continuous noise
target 40 ms chirp / seed固定noise burst
方位 -120 / -60 / +60 / +120°
要求SNR +12 / +6 / 0 / -6 dB
analyzer 1024-point Hann STFT、480-sample hop

通常demoは5秒calibration後、onになっているBURST音源を2秒ごとに巡回します。full modeは60秒calibration、300秒negative、2音種×4方位×4 SNR×5回の160 eventを予定した実装です。

画面中央のblock pawnがlistenerです。頭部位置へbinaural listenerを固定し、yawをcamera操作へ追従させています。HUD上段には現在の位置、向き、score、threshold、左右予測、confidence、lag、ILD、latencyを表示します。下段では左右2秒の波形、4秒のspectrogram、最新eventを同時に確認できます。

観測結果

2026年7月25日にUnreal MCPからPIEを起動し、block pawn追加前の固定listener demoを観測しました。

項目 観測値
matched detections 35 / 35
correct side 34 / 35(97.14%)
latency 20〜60 ms、中央値20 ms
unmatched detections 0
analyzer queue overrun 0

35回のtargetすべてに対応する検知があり、余分な検知はありませんでした。正解した左右は34回です。10 ms hopで処理する構成に対し、中央値20 ms、最大60 msで反応しました。

HUDでは、左右のstream波形、scrollするspectrogram、選択bin、検出線、最新eventのraw/extracted波形が同時に更新されました。WAVとrun JSONの生成も確認しました。

結果を簡単に読む

  1. 混ざった音だけから、短い異変と左右をかなり早く捉えられました。

    Engine内部の「どのactorが鳴ったか」を答えとして使わず、HRTF後の左右音声だけを解析しています。将来、recordingやvoice chatなど、音源metadataが得られない入力へ寄せやすい構成です。

  2. 35/35は有望ですが、false alarmの評価ではありません。

    今回のunmatched detections = 0は短いdemo中の値です。予定している5分間のnegative試験を実行していないため、「5分に1回以下」という暫定条件を満たしたとはいえません。

  3. WAVが作れたことと、音をきれいに分離できたことは別です。

    soft-maskでextracted WAVは生成できましたが、post-HRTFのtarget-only referenceがありません。SI-SDRを測っていないため、抽出品質の改善は未確認です。

試行中にわかったこと

Unreal Engine上のaudio処理では、signal algorithm以外にもいくつか詰まりやすい点がありました。

  • Resonance Audioはvolume補正だけでは、非focusのPIEでexternal-sendが無音になりました。PIE中だけVR focusとpause-on-focus-lossも補正し、EndPlayで元へ戻しました。
  • procedural環境音をtimerで少しずつqueueした初版は、約2秒で無音になりました。既知の実験時間分を開始時にqueueする方式へ変えました。
  • 通常のTArray<float>と非aligned設定では、UE 5.8のFFT factoryがnullを返しました。Audio::FAlignedFloatBufferと128-bit aligned設定へ変更しました。
  • audio callback内は、事前確保した5秒ring bufferへのcopyだけにしました。STFTなどの解析は専用workerで処理し、callbackを塞がない構成です。

制限

  • 集計値は固定listenerの短いdemoで、現在の移動可能block pawnを評価した結果ではない
  • 60秒calibrationと300秒negativeを含むfull modeは未実施
  • SNR別、音種別、方位別の内訳をまだ集計していない
  • post-HRTFのtarget-only referenceがなく、raw/extractedのSI-SDRは未測定
  • soft-mask WAVの生成だけでは、抽出品質を判断できない
  • 音種の識別、前後・上下の定位、遮蔽、残響を扱っていない
  • 一般化HRTFだけを使い、実耳録音や個人化HRTFで確認していない
  • macOS 26.5.2、Apple M4 Max、Unreal Engine 5.8の1環境だけで観測した
  • Main Outputへ、このproject以外の音が入らない前提である

検証後の感想

音源actorを参照すれば左右は簡単にわかります。それを使わず、実際にlistenerへ届いた混合音だけから35回すべてを拾い、34回の左右を当てられたのは良い感触でした。特に、画面を歩いて頭の向きを変えると、同じ音源でも左右音声と判断が変わるのをHUDで追えるため、algorithmの数字が空間内の感覚へつながります。

一方で、抽出WAVが目で確認できると成功したように感じますが、品質指標はまだ空欄です。そこを成功扱いしないことも、この検証では大切でした。低遅延の「音の注意」をNPCやinteractive agentへ渡すsensorとして、使い方を考えるのが楽しい仕組みです。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?