オーディオ ミキサーの概要

ゲーム内サウンドの再生に使用するオーディオ システムの概要。

Windows
MacOS
Linux

オーディオ ミキサーは、独自のモジュールで動作するマルチプラットフォーム対応のオーディオ レンダラです。これにより同等の機能をすべてのプラットフォームで実現し、従来のオーディオ エンジン機能のほとんどに下位互換性を提供して、UE4 の機能を新しい分野に拡張します。このドキュメントでは、オーディオ ミキサーの構造について全体像を説明し、詳細な議論のための参照ポイントを提供します。

背景と目的

オーディオ レンダリング

オーディオ レンダリングは、音源をデコードして混合し (デジタル/アナログ コンバータまたは DAC と呼ばれる) オーディオ ハードウェア エンドポイントに供給して、最終的に 1 つ以上のスピーカーで再生するプロセスです。オーディオ レンダラのアーキテクチャと機能セットは大きく異なりますが、双方向性とリアルタイムのパフォーマンス特性が鍵となるゲームの場合、リアルタイム デコード、サウンド パラメータの動的な消費と処理、リアルタイムのサンプルレート変換、さらに音源ごとのデジタル信号処理 (DSP) エフェクト、空間化、サブミックス、リバーブのようなポストミックス DSP エフェクトなど、その他さまざまなオーディオ レンダリング機能をサポートする必要があります。

プラットフォーム レベルの特長:オーディオ レンダリング API

通常はそれぞれのハードウェア プラットフォームが、フル機能で高レベルのオーディオ レンダリング用 C++ API を少なくとも 1 つ提供します。複数のオプションを提供するプラットフォームもあります。多くの場合、こうした API はプラットフォーム固有のコーデックとエンコーダ、そしてデコーダ API を提供します。また多くのプラットフォームは、実行時のパフォーマンスを改善するハードウェア デコーダを提供します。コーデックに加えて、プラットフォーム オーディオ API は、ボリューム コントロール、ピッチ コントロール (リアルタイム サンプルレート変換)、空間化、DSP 処理など、オーディオ エンジンに必要な他の機能をすべて提供します。

ゲーム レベルの特長:ゲームプレイ API

ゲーム エンジンには、こうしたプラットフォーム レベルの仕様を元にした追加の機能が記述されています。例としてこうした機能は、(ブループリントなどの) スクリプト エンジンや (オーディオ コンポーネント、アンビエント アクタ、オーディオ ボリュームなどの) ゲーム固有のコンポーネントとシステムにフックしたり、(サウンド並列処理など) どのサウンドを (サウンドクラス、サウンドミックス、サウンドキューなど) どのパラメータで実際に再生するか決定するために、多くの作業を行う場合があります。

プラットフォーム固有のオーディオ レンダリング API に伴う課題

このパラダイムは、サポート対象のプラットフォームの数が少なく、新しいプラットフォームを立ち上げるリード タイムが長い場合は適切に機能します。しかし、多数のプラットフォームをサポートする UE4 の場合、それぞれのプラットフォーム固有の API の差異を処理して、プラットフォーム固有のバグを潰し、プラットフォーム機能の同等性を追求するうちに、オーディオ エンジンの開発時間が容易に独占されてしまいます。これは新しいランタイム機能や開発ツールを作成するコストです。

このパラダイムで機能の同等性は不可能であるため、どのプラットフォームでどの機能が動作するかについて品質保証チームとサウンド デザイナーと連携する、機能サポート基盤を作成して維持する必要があります。これに関して、すべての機能がすべてのプラットフォームで動作するとは限らず、ドキュメントの提供とサポートは困難です。すべての機能がすべてのプラットフォームで動作せず、既存の機能がプラットフォームによって異なるサウンドになる場合、複数のプラットフォームに対して出荷することを意図としたゲームを混在させることは困難です。

したがって、オーディオ レンダリング レベルの機能を新しく作成する場合はプラットフォームごとに異なる実装をする必要があり、そうしない場合はプラットフォームの不整合問題が増加します。同様に、最適化やバグ修正は複製を必要とし、そうでない場合は特定のプラットフォームに固有です。

つまりほとんどの場合、低レベルの新機能、最適化、バグ修正は、事実上不可能です。プラットフォーム API にパフォーマンスの問題や既知のバグが存在する場合、その多くはプラットフォームの開発元と協力せずには修正する手段がありません。そのため、ほとんどのバグ修正は工夫や回避策で構成されています。新しい機能が利用できる場合でも、それらは限られたプラットフォームのプラグイン API に追いやられ、プラットフォームが異なると動作しません。

新しいプラットフォームに対してそのプラットフォーム固有のオーディオ API を実装するには、膨大な作業量と長い開発リードタイムを必要とします。場合によっては、最新のプラットフォームではフル機能のオーディオ API を利用できない可能性もあります。このような場合は、そのプラットフォームがリソースを投資して独自のオーディオ レンダリング API を作成するまで、そのプラットフォーム上ではオーディオ レンダリングを利用できないでしょう。

あらゆるゲーム エンジン向けに有効な手段の 1 つは、サードパーティが UE4 用に新しい機能と拡張を追加できることです。しかしプラットフォーム API の複雑な集合体と、それ自体がプラグイン拡張機能をサポートするさまざまな方法では、すべてをラップする共通の API を作成することはほとんど不可能です。

オーディオ ミキサーが解決策

こうしたすべての問題に対する解決策が、単一マルチプラットフォームのオーディオ レンダリング API、すなわちオーディオ ミキサーです。オーディオ ミキサーにはプラットフォームすべてに共通のコードベースが 1 つ存在するため、機能の同等性をはるかに簡単に実現できます。プログラマーが新しい機能を一度実装すれば、すべてのプラットフォームで動作することが期待できるため、開発時間が最適化されます。また、テスト、ドキュメント、サウンド デザイナーの実装とミキシングも簡素化されます。避けられない特定のケースのサブセットを除き、異なるプラットフォーム間で同じように聞こえ、同じように動作します。

新しいプラットフォームを迅速にサポートします。多くの場合、必要なのはわずか数日、数百行のコードだけです。オーディオ エンジン プラグインのインターフェースが非常に記述しやすくなるだけでなく、イノベーションの主要な手段になります。さらに、バグ修正やコードの最適化の恩恵をすべてのプラットフォームが受けます。

しかし、プラットフォーム固有の課題は依然として残ります。各プラットフォームが持つ CPU やメモリの機能、ハードウェア サポート オプションは異なるためです。それでも CPU やメモリが不足している場合、オーディオ ミキサーは (機能の無効化や品質を下げることなどで) CPU 負荷や、(クック時のメモリ プルーニング、自動ダウンサンプリング、ダウンクオリティ エンコーディングで) メモリ負荷を自動的に軽減する機能を活用できます。サウンド デザイナーとオーディオ プログラマーは、オーディオ ミキサーを調整して特定のプラットフォームの固有のパフォーマンスとメモリ ターゲットを達成できます。

オーディオ ミキサーと呼ばれる理由

オーディオ ミキシングオーディオ レンダリング を言い換えた言葉です。ほとんどの場合、UE4 では レンダリング という言葉をグラフィックスについて使用するため、新しいオーディオ レンダラを オーディオ ミキサー と呼ぶことにしました。しかし、ミキシング という言葉のあいまいさのために、この決定がオーディオのコミュニティや他の関係者を混乱させている可能性があります。特にボリューム (ラウドネス) ミキシングの操作と混同することが考えられます。

UE4 オーディオ ミキサー は、本質的にハードウェア ミキシング コンソールと同じことを行います。すなわちサブミキシングやマスターエフェクト プロセッサなど、さまざまなパラメーターとエフェクト プロセッサで処理した後に音源を追加します。

オーディオ ミキサーのアーキテクチャ

プラットフォーム レイヤー

オーディオ ミキサーには、プラットフォーム固有の最小限の API レイヤーがあります。このプラットフォーム API は、さまざまなプラットフォームのオーディオ ハードウェアへのアクセスに必要な詳細をすべてラップします。また、このレイヤーはハードウェア機能のクエリを処理し、必要に応じてハードウェアの状態変更も処理して、マルチ プラットフォーム オーディオ ミキサーを設定してオーディオをハードウェアに供給します。

一部のプラットフォームでは、状態の中断、アプリの中断、デバイスの交換など、プラットフォーム固有のさまざまな微妙な差違を処理するには追加のコードが必要です。他には、ハードウェア アクセラレーションによるデコードなど、プラットフォーム固有の拡張機能を活用するためのサポートが追加されました。これらの場合、プラットフォーム固有のコードがさらにたくさん必要になる場合があります。このプラットフォーム固有のレイヤーは、さまざまなコーデック用にランタイム デコーダを作成するなど、UE4 の残りのプラットフォーム固有の機能もいくつか処理していることに注意が必要です。

バッファ生成

プラットフォームによって、ハードウェアにオーディオを供給する方法は異なります。たとえば、あるプラットフォーム API はオーディオをハードウェアのキューに プッシュ する仕様なので、クライアント アプリはオーディオをキューに供給し続ける必要があります。一方、他の API はコールバック ベースなので、ハードウェアがさらにオーディオを必要とするときはクライアントのコードを呼び出します。どちらの場合でも、オーディオ ミキサーがマルチバッファ スキームを採用しているため、ハードウェアが現在のバッファ (リッスンしているバッファなど) をレンダリングしている間に今後のオーディオ バッファを生成します。

オーディオ ミキサーが次のオーディオ バッファをレンダリングするのに長い時間がかかりバッファ キューが 枯渇 する場合 (プッシュ API の場合)、もしくは API のコールバック時に使用できるオーディオがない場合 (コールバック API の場合)、再生に音飛びが生じます。これは Underrun (アンダーラン)Starvation (枯渇) と呼ばれ、非常に不快に聞こえるので必ず避けてください。アンダーランは突然オーディオ ストリームに不連続を引き起こし、突発的なノイズとして認識されます。これは短いアンダーランのポップ、細切れに連続発生するアンダーランのスタッタ、または長く続くアンダーランによるオーディオの大きな抜け落ちのいずれかです。振幅の突然の変化がオーディオ レシーバやスピーカーの損傷を引き起こす可能性もあります。ほとんどの場合、アンダーランの原因は、オーディオ ミキサーが割り当て時間内に過剰な処理を行ったことによる CPU の飽和です。別の場合としては、(非同期のデコードや合成を行う) UE4 タスク グラフのブロック、または他の問題を示している可能性があります。また、オーディオのクリック ノイズやポップ ノイズの原因がアンダーランかオーバーランかを区別するのは困難な場合があります。

逆の例として、前もってオーディオを過剰に生成している可能性もあります。こうした場合はゲーム イベントがリアルタイムからどんどん遅延し、レイテンシーとして認識されます。極端な場合は オーバーラン と呼ばれ、これも避けるべきものです。したがって、リアルタイム オーディオ エンジンは、アンダーランとオーバーランの間でバランスをとる必要があります。アンダーランは何としても回避すべきですが、認識できるしきい値を下回るオーバーランは、アンダーランを防ぐためにある程度は必要です。

適切なバランスを見つけるのが困難な場合があり、また多くの場合はプラットフォームに依存します。そのためオーディオ ミキサーは、オーディオ バッファー レンダリングごとにレンダリングするオーディオ バッファ サイズ、現在聞こえているバッファの前にレンダリングすべきバッファ数を、サウンド デザイナーやオーディオ プログラマーがプラットフォームごとに選択できるように設計されています。

オーディオ ミキサーのスレッド化モデル

オーディオ ミキサーは独自のスレッドを作成して、実際のオーディオ レンダリングを行います。これを オーディオ レンダリング スレッド と呼びます。このスレッドは オーディオ スレッド と異なり、DSP ソースの生成とミキシングの作業をすべて行うスレッドです。

オーディオ スレッド は、再生するサウンドとそのパラメータ (サウンド キュー、サウンド クラス、サウンド ミックス、減衰などの処理) の決定作業を行うスレッドです。このオーディオ スレッドは、オーディオ ミキサーと従来のプラットフォーム固有のオーディオ エンジンの間で、ほぼ同様です。しかし現在、オーディオスレッドには UObject とガベージ コレクションの処理方法に複雑な部分があります。オーディオ スレッドは UObject を持つため、ガベージ コレクション中にフェンスされて停止します。実行中、これらの UObject は読み取り専用ですが、エディタではこれらの UObject に書き込み可能であるため、このオーディオ スレッドは使用しません。

コールバック ベースのプラットフォーム API には、実際のプラットフォーム ハードウェア コールバックが発生するハードウェア スレッドもあります。このハードウェアが所有するスレッド コールバックは、ほぼ常にレンダリングされたバッファから取り出され、これはオーディオ レンダリング スレッドからキューに入れられ、実際の作業はほとんど行いません。

最後に、オーディオ エンジンは UE4 タスク グラフから非同期タスクを利用して、デコードとプロシージャルなオーディオ (合成など) の生成を行います。

音源の生成

オーディオ ミキサー レンダリング自体の最初の段階は、ソースの生成です。ソースを生成するために、オーディオ ミキサーはゲームとオーディオ スレッドから送信されたパラメータを受け取ります。これらのパラメータは再生する音源とそのパラメータ (ボリューム、ピッチ、位置など) を定義します。

ここで ソース という言葉を使用するのは、そのソース用に生成するオーディオが、圧縮オーディオ アセット (サウンド ファイルなど)、プロシージャルな生成 (合成、メディアのデコード、VOIP、マイク キャプチャなど)、他の混合ソースからのソース派生 (ソース バス など) に由来するためです。それぞれの場合で、異なる方法を使用してソース データを生成します。

エンコードされた音源

エンコードされた音源 (ogg-vorbis、opus、atrac9、xma2、adpcm など) の場合、非同期タスクを使用してオーディオを非圧縮 32 ビットの float バッファにデコードします。そして、この 32 ビットの float バッファは、ソースのサンプル レートからオーディオ ミキサーのサンプル レートに、サンプル レート変換 (SRC) されます。この SRC プロセスは、その音源に適用されている可能性がある ピッチ スケール をすべて考慮して、そして 1 回だけ SRC を実行します。

たとえば、音源が 32 kHz でエンコードされサウンド デザイナーが音源をピッチ アップするピッチ スケールが 1.2 かつ、オーディオ ミキサーが 48 kHz でオーディオをレンダリングしている場合の SRC は次のサンプルレート比を使用します。

SampleRateRatio = (48 kHz/32 kHz) * 1.2

SampleRateRatio = 1.8

これはすなわち、オーディオをデコードした後、音源を 1.8 だけピッチアップすることを意味します。

プロシージャルな (生成した) 音源

プロシージャルな音源の場合、オーディオは、クライアント コードにコールバックして次の 32 ビット float バッファを生成する、抽象インターフェースを介して生成されます。クライアント コードはこのコールバックに任意のオーディオを供給することが可能で、理論的にはオーディオは任意のソースをとることができます。UE4 では、リアルタイム合成の実行、メディア ソース (減衰、オクルージョン、リアルタイム エフェクトを含む 3D ビデオからのオーディオ再生など) からのオーディオのレンダリング、VOIP からのオーディオ再生に、これを使用します。

また、これはサード パーティのプラグインが、オーディオ エンジンを拡張する数ある方法の 1 つです。プロシージャルな音源はプラグインで定義することが可能で、完全に独立したサウンド エンジンなど任意の他のソースから、オーディオ ミキサーに音源を供給できます。

混合ソース

オーディオ ミキサーは音源を混合して他のソースを作成することもサポートしています。こうした混合ソースを ソース バス と呼びます。ソース バスは他のソースと同様に扱われ、空間化、距離による減衰、ボリューム ミキシング、ソースエフェクト処理など、他のソースが持つほとんどの機能をサポートします。これらの機能には便利なアプリケーションが多数あります。たとえば、新しい空間的場所への音源の動的ルーティング (ラジオ放送など)、空間化エフェクト処理 (位置に基づいたリバーブ処理など)、ディレイタイプの空間エフェクト (シーン内の特定のオブジェクトからの反響音など) があります。

音源の DSP エフェクト処理

一度音源からオーディオを生成すると、その出力は一連の オーディオ DSP エフェクト を介して供給されます。すべての音源が自動的に利用できるビルトイン エフェクトがいくつかあります。こうした DSP エフェクトはハイパス フィルタとローパス フィルタであり、さまざまな高レベル機能に使用します。

サウンドの減衰設定 により、サウンドデザイナーは、ハイパスとローパスの機能のフィルタ頻度カットオフをマップして、リスナーからの距離の関数としてそれぞれの音源に適用できます。

このソースごとのフィルタを利用するもう 1 つの機能は、ビルトインの オクルージョン システム です。オクルージョンを有効化した場合、サウンドが (非同期レイ トレースで決定する) オクルージョン ジオメトリの背後で遮られると、サウンド デザイナーが定義したローパス フィルタを自動的に適用します。最後に、サウンド ミックスとサウンド クラスが、サウンドにソースごとのローパス フィルタを適用できます。

自動ビルトイン フィルタ エフェクトに加えて、サウンドを ソース エフェクト チェーン と呼ばれる機能でフィードすることもできます。これは、ソース エフェクト プラグイン API を介して、ソースごとの連続した DSP エフェクトを定義するアセットであり、コーラス エフェクト、フランジャー、ディレイ、高度なフィルタ、リング モジュレーション、ビット クラッシュなど任意のエフェクトを作成できます。

サブミックス グラフ

ソースを生成した後、オーディオ ミキサーは サブミックス グラフ を処理します。サブミックス グラフの出力が、オーディオ ハードウェアで聞こえるオーディオです。

サブミックスに送信する

オーディオ エンジンを初期化すると、オーディオ エンジンに マスター サブミックス が作成されます。既定では、他のサブミックスがベース サブミックスとして指定されていない場合、すべての音源が、その ベース サブミックス としてこのサブミックスに自動的に指定されます。

ソースのベース サブミックスは、ソース出力を、減衰後、空間化後に最大音量で混合するサブミックスです。送信 サブミックスも任意の数だけ指定することができ、これは予備の DSP エフェクトを介して送信する前にソースを混合します。この送信サブミックスは、デジタル オーディオ ワークステーションやミキシング コンソールのリバーブなど、DSP エフェクトの予備チャンネルと類似しています。

前述のとおり、サブミックス ルーティングを指定していない音源が使用できるデフォルトのルーティングがあります。ただし、音源がオーディオをサブミックスに送信する場所を制御する方法は主に 2 つあります。1 つ目は、ベース サブミックスの指定です。このサブミックスはサウンドを最大音量で混合します。空白のままにすると、レガシー機能によって、オーディオを EQ サブミックスまたはマスター サブミックスのいずれかにルーティングします。

マスター サブミックス

マスター サブミックスに加えて、マスター エフェクト サブミックス を 2 つ作成し、このマスター サブミックスの子として追加します。この 2 つは マスター リバーブ サブミックスマスター イコライザー (EQ) サブミックス です。これらのマスター サブミックスは、主に UE4 のレガシー機能と下位互換を維持し、既存のプロジェクトでオーディオ ミキサーの交換に対応するために作成されました。ただし、これらはリバーブや EQ と相互作用するサウンド クラス、サウンド ミックス、オーディオ ボリューム、サウンド減衰に対してさまざまな高レベル機能をサポートする、基礎となるメカニズムです。

出力を生成する

マスター サブミックスは、サブミックス グラフのルート ノードです。このマスター サブミックスから生成したオーディオを取得することで、最終的な出力を生成します。

登録された音源を送信する量は、そのサブミックスで混合された音源のゲイン/減衰です。この混合バッファを、ハードウェアの出力チャネル構成に対して混合します。登録された音源を送信する量は、そのサブミックスで混合された音源のゲイン/減衰です。

この混合バッファを、ハードウェアの出力チャネル構成に対して混合します。たとえば、ステレオ出力の場合は 2 チャンネルのオーディオ バッファになり、7.1 オーディオの場合は 8 チャンネルのオーディオ バッファになります。

この混合したインターリーブ オーディオがサブミックスの DSP エフェクト チェーンを介して供給され、最終的な出力を生成します。

サブミックスの追加機能:分析、記録、リスニング

サブミックスは、オーディオ分析を行う理想的なオブジェクトです。現在、チャンネルごとにサブミックスから振幅エンベロープの値を取得するブループリント デリゲートを登録するメカニズムがあります。これは、オーディオとやり取りするビジュアリゼーションやゲームプレイの多くのシステムに役立ちます。また、ブループリントのサブミックスからスペクトル データを取得する、リアルタイム FFT デリゲートも用意されています。

さらにサブミックスには、出力を USoundWave オブジェクトやディスクの Raw PCM (.wav) ファイルに記録する機能もあります。

最後に、他のコード システムで登録できる C++ デリゲートが用意されており、任意のサブミックスから混合したオーディオを動的に取得できます。この機能は、インターネット ブロードキャスト (サーバーベースのゲーム ストリーミング) やサードパーティ プラグインの拡張機能など、多くの場面で便利に使用できます。

Tags
Select Skin
Light
Dark

Welcome to the new Unreal Engine 4 Documentation site!

We're working on lots of new features including a feedback system so you can tell us how we are doing. It's not quite ready for use in the wild yet, so head over to the Documentation Feedback forum to tell us about this page or call out any issues you are encountering in the meantime.

We'll be sure to let you know when the new system is up and running.

Post Feedback