menu
 
バージョン
2024.1.5.8803

2024.1.5.8803

2023.1.13.8732

2022.1.19.8584

2021.1.14.8108

2019.2.15.7667

2019.1.11.7296

2018.1.11.6987

2017.2.10.6745

2017.1.9.6501

2016.2.6.6153

2015.1.9.5624


menu_open
Wwise SDK 2024.1.5
リスナーの統合

イントロダクション

リスナーは、ゲーム内のマイクの位置を表すゲームオブジェクトです。ゲームオブジェクトをリスナーとして指定することで、3Dサウンドを実際の3D環境を模倣するためにスピーカーに割り当てることができます。同様に、エミッタゲームオブジェクトは仮想スピーカーを表し、リスナーに割り当てられると、エミッタの位置情報がリスナーの座標系にマッピングされて3Dサウンドをレンダリングします。エミッターまたはリスナー(またはその両方)として機能するかどうかにかかわらず、Wwiseのゲームオブジェクトには、位置ベクトルである正面および上方向のベクトルだけでなく、変換も割り当てられます。サウンドが正しいスピーカーを通してレンダリングされるように、ゲームオブジェクトの変換を各フレームで更新する必要があります。

リスナーの登録

音を聞くには、少なくとも1つのゲームオブジェクトを登録してリスナとして割り当てる必要があります。ほかのすべてのゲームオブジェクトにリスナーを割り当てるために AK::SoundEngine::SetDefaultListeners を使うか、特定のゲームオブジェクトにリスナーを割り当て、 AK::SoundEngine::SetDefaultListeners を使用して設定されている内容を上書きするために AK::SoundEngine::SetListeners を使うことができます。ゲームオブジェクトを登録し、デフォルトのリスナーとして割り当てる方法は次のとおりです:

AkGameObjectID MY_DEFAULT_LISTENER = 0;
// Register the main listener.
AK::SoundEngine::RegisterGameObj(MY_DEFAULT_LISTENER, "My Default Listener");
// Set one listener as the default.
AK::SoundEngine::SetDefaultListeners(&MY_DEFAULT_LISTENER, 1);
// Register a game object for playing sounds
AkGameObjectID MY_EMITTER = 1;
AK::SoundEngine::RegisterGameObj(MY_EMITTER, "My Emitter");
// At this point "My Emitter" has 1 listener, "My Default Listener", because we designated it as the default listener.
AkGameObjectID MY_LISTENER_NO2 = 2;
AK::SoundEngine::RegisterGameObj(MY_LISTENER_NO2, "My Listener #2");
// If we want to change the listener for only "My Emitter", we do so as follows:
AK::SoundEngine::SetListeners(MY_EMITTER , &MY_LISTENER_NO2, 1);
// この時点で "My Emitter" には、リスナー "My Listener #2" があります。他のすべてのゲームオブジェクトには、引き続き、リスナーとして "My Default Listener" があります。

WwiseオーサリングツールのAdvanced ProfilerのEmitter-Listenerタブを調べることで、コードで割り当てられたエミッタ・リスナーの関連付けを調べることができます。単純なゲームは、すべてのゲームオブジェクトのデフォルトのリスナーとして1つのゲームオブジェクトを選択します。 ただし、複数のリスナーを使用して単一の出力デバイスに出力することは可能です。下記の Multiple Listeners In A Single Output Device 1つの出力デバイス内の複数のリスナー を参照してください。サブミックスの3D配置にリスナーを使用することも可能です。これを行うには、ゲームオブジェクトにリスナーを割り当てて、エミッタ・リスナーの関連付けによって接続されたゲームオブジェクトの有向グラフを作成するリスナーであるリスナーを割り当てる必要があります。

リスナーの位置情報を設定

AK::SoundEngine::SetPosition() 関数は、すべてのゲームオブジェクトと同様に、リスナーの位置を設定するために使用されます。これは、リスナーの位置または方向ベクターのいずれかが変更されるたびに実行される必要があります。

AkTransform listenerTransform;
(... set the position and orientation members of listenerTransform here...)
AK::SoundEngine::SetPosition( listenerPosition );

AkTransformクラスは、ゲームの3D空間におけるリスナーの位置と向きを定義する情報を保持します。リスナーの位置(Position)、OrientationFront、およびOrientationTopベクトルは、 AkTransform クラスのgetterとsetterを使用して、アクセスおよび設定できます。

info注釈: OrientationFront (前方向)ベクターは、リスナーの顔の向きを定義します。これは、リスナーの頭の傾斜を定義するOrientationTop(上部方向)ベクターに対して直角であるべきです。リスナーが人間であれば、OrientationFront ベクターがリスナーの鼻の向き(顔から外へ向かっている)となり、OrientationTop ベクターはそれに対して直角関係にあり、リスナーの目の間、額を越えて、さらに上昇します。

Wwiseサウンドエンジンで、X、Y および Z軸がどのように定義されるかについての詳細は X-Y-Z座標系 を参照してください。

方向ベクターは、オーディオが適切にレンダリングされるように定義されなければなりません。それらはゼロベクトルではなく、単位ベクトルである必要があります。また、直角にする必要があります。

info注釈: リスナーの位置は、フレームごとに最大で1度更新されます。AK::SoundEngine::SetPosition() 関数への複数の呼び出しが行われても、 AK::SoundEngine::RenderAudio() の呼び出し時には、最後の値のみが考慮されます。
check_circleTip: 例えば、左のスピーカーから聞こえるはずの音が右のスピーカーで聞こえるなど、予想外のサウンドレンダリングが発生している場合、 AK::SoundEngine::SetPosition() 関数を介してサウンドエンジンに提供されるリスナーの位置情報を確認してください。その場合、既知の一定のリスナー位置を設定して、レンダリングが適切であるか確認し、X、Yおよび Z軸に発生している混同を排除することができます。この詳細については、X-Y-Z座標系 を参照してください。

TPP(三人称視点)ゲームでListenerを使用する

TPP(三人称視点)を使用するゲームやシミュレーションにオーディオを実装する際にListener Game Objectの配置に迷うことがあり、カメラの位置を提案する人もいれば、プレイヤーがコントロールするキャラクターの位置を好む人もいます。位置は異なるものの、カメラもプレイヤーがコントロールするキャラクターも、ある意味「あなた」つまりプレイヤーです。Distance ProbeをメインカメラのListenerに関連付けることで、サウンドの計算において、両方の位置がそれぞれ独自の形で考慮されます。このアプローチを理解するには、シミュレーションのさまざまな側面を分析する必要があります。

パンニングと空間化

ほとんどのシナリオにおいてパンニングと空間化は、Wwiseのスプレッドとフォーカスを含め、カメラの位置と向きに基づく必要があります。最終的なスピーカー配列(物理的または仮想バイノーラルのいずれでも)に対して、シミュレーション中のカメラとサウンドの相対的な向きがずれていると、没入感が損なわれます。例えばカメラが直接サウンドに向けられている場合、サウンドは中央のスピーカーチャンネルから来るべきです。カメラの左側のサウンドであれば左のスピーカー、ほかも同様です。

この目的を果たすには、Listener Game Objectをアクティブなカメラに配置し、Listenerの向きを合わせて更新する必要があります。

距離に基づく減衰

一般的に3Dサウンドの減衰はEmitterとListener Game Object間の距離に基づき、距離をサウンドの減衰カーブに適用することでボリューム、ハイパスフィルタ値、ローパスフィルタ値が決定されます。その結果、近くのサウンドほどエクスペリエンスにおける重要性が増し、音が大きくなります。

一方TPPゲームで注目されるのは、カメラ自体ではなく、プレイヤーがコントロールするキャラクターです。そのためサウンドがEmitterとカメラ間ではなく、Emitterとプレイヤーキャラクター間の距離に応じて減衰することで、没入感がさらに高まります。

その理由を理解するには、距離減衰がカメラの位置に基づくと期待通りにボリュームが変動しないようなシナリオを想定してみるとよいでしょう。トーチで照らされた廊下を進むプレイヤーキャラクターをカメラが追うTPPゲームがあるとします。各トーチが発するサウンドは強度が低く、急減します。カメラを回転し、反対方向に向けるには、カメラがキャラクターの周りを回る必要があります。その過程で、カメラが1つ以上のトーチの近くを通るため、サウンドは大きくなり再び小さくなります。プレイヤーキャラクターは動いていないため、シーン内のトーチの相対的な重要性は変化していないにもかかわらず、ボリュームの変動はそれ以外を示唆しています。

プレイヤーキャラクターまでの距離に基づいてサウンドを減衰させるという目的を果たすには、Game Objectをプレイヤーキャラクターの位置に配置し、メインのListenerのDistance Probeに指定する必要があります。

Distance Probe

Distance Probeは、Listener Game Objectの指定カウンターパートとして選択できるGame Objectです。ListenerにDistance Probeをアサインすると、Listenerに送られる全ての音に適用する減衰距離が、Distance ProbeからEmitter Game Objectまでの距離に基づきます。

パンニング、スペーシャリゼーション、スプレッド、そしてフォーカスは、Distance Probeがアサインされたかどうかに関わらず、必ずListener Game Objectのポジションとオリエンテーションに基づきます。

また:

  • 各Listener Game Objectは、0個または1個のGame ObjectをDistance Probeとして設定できます。
  • 1つのGame Objectを、複数のListenerのDistance Probeに設定できます。
  • Listenerを、自分自身のDistance Probeにアサインすることは、Distance Probeをnone(なし)に設定するのと同じです。

Distance ProbeをListener Game Objectにアサインするには AK::SoundEngine::SetDistanceProbe APIを使用します。

Distance Probeのプロファイリング

Advanced ProfilerのListenersタブに、すべてのアサイン済みのDistance Probeが表示されます。下図は AK::SoundEngine::SetDistanceProbe APIを使用して「Distance Probe」という名前のゲームオブジェクトが「Listener L」にアサインされたことを示しています。

Distance Probeは、Game Object 3D Viewerにアイコンで表示されます。便宜上、Game Object 3D ViewerにおけるDistance Probeの可視性はListenerの可視性に紐づけられ、Listenerに適用されるすべてのフィルタがDistance Probeにも適用されます。

実装に関する補足事項

TPPエクスペリエンスでは、Distance Probeをプレイヤーキャラクターの正確な位置に配置する必要はありません。ポジショニングを自由に試しながら求める結果を達成しましょう。例えば、カメラとキャラクター間でDistance Probeのポジショニングをさまざまな比率で試すことができます。この比率を、キャラクターの位置とカメラの位置の間に挿入できる調整可能な値として、デザイナーに公開することもできます。 カットシーンやシネマティックな場面では、Distance Probeを移動したり、オフにしたり、あるいは別のGame Objectに移行したいかもしれません。Distance Probeを固定する必要はありません。

Distance ProbeがSpatial Audio Listenerにアサインされている時のさまざまなSpatial Audio機能の動作については Third-Person Perspective and Spatial Audio をご参照ください。

Multiple Listeners In A Single Output Device 1つの出力デバイス内の複数のリスナー

ゲーム内での視野が1つのみのシングルプレイヤーゲームでは、リスナーは1つで十分です。しかしながら、同じシステム上で複数のプレイヤーがプレイできるゲームや、同時に複数の視点が表示される場合には、それぞれの視点にオーディオが適切にレンダリングされるよう、各視点ごとにリスナーが必要になります。

複数リスナーの実装に伴う主な難点は、サウンドソースの位置づけが、実際にプレイヤーが見ているものと調和しない場合があるということです。ほとんどのケースでは、複数プレイヤー向けの3D環境を再現するために単一のスピーカーセットのみを使用するゲームでこのような問題が発生します。

この問題を簡単に表現したのが以下の図です。リスナー0 には左のスピーカー、リスナー1 には右のスピーカーからソースが聞こえるように想定されているので、どのスピーカーでソースが再生されるべきかを知るのは非常に困難です。

異なるスピーカーで同じソースを聞く2つのリスナー

Wwiseのリスナーに上限はなく、デフォルトで全てのリスナーがメインアウトプットデバイスにミキシングされますが、以下は例外です。

次のセクションでは、すべてのリスナーが同じ出力デバイスに統合されるケースについて説明し、Wwiseサウンドエンジンを使用してプログラマーがこれらのリスナーを操作して期待される動作を実現する方法について説明します。

info注釈: 複数リスナーに関連する操作は、SDK を介したゲームプログラマーによる実装によってのみ可能です。Wwise オーサリングアプリケーションには、複数リスナーのためにソースのゲーム内ポジショニングを管理する特別なオプションはありません。

複数リスナー:ソースのキャプチャ

各リスナーはミキシンググラフを生成します。ソースがアクティブになっている各リスナーに対して相対的にソースごとの距離とコーン減衰が個別計算されます。

ボリューム減衰の管理

複数のリスナーがソースを取得する場合、ソースはそれぞれのリスナーに対応するそれぞれのバスのインスタンスで順番に混合されます。それが混合されるにつれて、減衰量はそれぞれのリスナーに対して独立して適用されます。

LPF 減衰管理

減衰量とは対照的に、減衰LPFおよびHPFは、ソースに直接適応されます。 したがって、Wwiseは、特定のソースのすべてのエミッタ・リスナーの関連付けに基づいて単一の値を選択する必要があります。各ソースに適用する最終のローパスフィルタをサウンドエンジンが計算する方法は以下のとおりです:

  1. 該当ソースがアクティブになっている各リスナーに対して:
    1. ソースと該当リスナー間の距離に基づいて LPF を計算する
    2. ソースと該当リスナーのなす角度に基づいて LPF を計算する
    3. 2つの値のうち最も高いほうを保持する
  2. 全てのリスナーの中で最も低い値を取得し、オブジェクトの LPF(正則値とRTPC)を追加する

次の表で説明されている例では、リスナー0 の値は max( 10, 40 ) = 40、リスナー1 の値は max( 50, 10 ) = 50 です。2つのうち最も低いのは40で、これがオブジェクトの値5に追加され、最終的な値が45になります:

リスナー 0
リスナー 1
オブジェクト
ソースの
最終 LPF
コーン LPF
半径 LPF
コーン LPF
半径 LPF
10 40 50 10 5 45

ボリュームオフセットと空間化

3D Spatialization では、音とリスナーの位置関係に基づいて、複数のスピーカーに音がパンニングされます。

しかし、2人のプレイヤーによって分割画面でゲームがプレイされる場合、各リスナーに対するサウンドの位置に基づいた、通常通りのスピーカーへのサウンドポジショニングを完全に回避して、リスナー1(1人目のプレイヤー)を左のスピーカー、リスナー2(2人目のプレイヤー)を右のスピーカーで聞こえるようにしたいかもしれません。

ゲームプログラマーは、Wwiseを介して特定のリスナー向けの空間化を無効にし、各チャンネルに対するカスタムのボリュームオフセットを必要に応じて設定することにより、該当リスナーにキャプチャされたサウンドがどのように各スピーカーから聞こえるかを指定することが可能で、更に制御力および柔軟性のある操作をすることができます。

これらの設定は、 AK::SoundEngine::SetListenerSpatialization() 関数を呼び出すことにより、各リスナーごとに変更可能です:

AkGameObjectID in_uListenerID, // Listener game object ID
bool in_bSpatialized, // Spatialization toggle (True : enable spatialization, False : disable spatialization)
AkChannelConfig in_channelConfig, // Channel configuration associated with volumes in_pVolumeOffsets. Ignored if in_pVolumeOffsets is NULL.
AK::SpeakerVolumes::VectorPtr in_pVolumeOffsets = NULL // Per-speaker volume offset, in dB. See AkSpeakerVolumes.h for how to manipulate this vector.
) = 0;

最初のパラメータは、リスナーのIDです。2つ目のパラメータは、該当リスナーに対する空間化を有効にするために True 、無効にするには False に設定される必要があります。最後のパラメータは、そのリスナーの各チャンネルのデシベル減衰を含む構造体への任意のポインタです。 in_bSpatializedFalse の場合、各チャンネルの音量が設定されます(デフォルトは 0 dBです)。 in_bSpatializedTrue の場合、デフォルトの3D spatializationで計算されたボリュームが、チャンネル毎に決めららた一定量だけ、オフセットされます。

ボリュームベクターはチャンネル構成 in_channelConfig にひも付けられています。 in_channelConfig が 5.1 を意味する場合には、ボリュームベクターは6の値である必要があります。AK::SpeakerVolumes::Vector ネームスペースで定義された機能を使用して、これを処理します。チャンネルの順番は、常に最後にあるLFEを除き、AkSpeakerConfig.hで定義されたチャンネルマスクビットに対応します。

2人のプレイヤーが分割画面を使用する例には、以下のコードを使用できます:

// すべてのエミッタのデフォルトリスナーとしてリスナー1と2を登録します。
// 代わりにAK::SoundEngine::SetListenersを使用して、どのエミッタからどのリスナーに放射するかを明確に選んで選択することができます。
AkGameObjectID listeners[2] = {1,2};
AK::SetDefaultListeners(listeners[0],2);
// Define speaker offsets using a 7.1 speaker setup (if platform supports it).
vVolumes[0] = 0.f; // Left
vVolumes[1] = -96.3f; // Right
vVolumes[2] = -6.f; // Center
vVolumes[3] = 0.f; // Rear left
vVolumes[4] = -96.3f; // Rear Right
vVolumes[5] = 0.f; // Side left
vVolumes[6] = -96.3f; // Side Right
vVolumes[7] = 0.f; // LFE
AK::SoundEngine::SetListenerSpatialization( listeners[0], false, cfg, vVolumes );
vVolumes[0] = -96.3f; // Left
vVolumes[1] = 0.f; // Right
vVolumes[2] = -6.f; // Center
vVolumes[3] = -96.3f; // Rear left
vVolumes[4] = 0.f; // Rear Right
vVolumes[5] = -96.3f; // Side left
vVolumes[6] = 0.f; // Side Right
vVolumes[7] = 0.f; // LFE
AK::SoundEngine::SetListenerSpatialization( listeners[1], false, cfg, vVolumes );

サウンドがルートされているバスに、そのユーザー定義のチャンネル構成につき、7.1と異なるチャンネル構成がされている場合には、サウンドに適用する前に、ベクターは内部的にダウンミックスされます。

通常の空間化に戻るには、以下を呼び出します:

// Enable regular spatialization on listeners 0 and 1

ボリュームパイプライン

次の図は、各スピーカーの最終音量を計算するために、各リスナーの各ソースで実行されるさまざまな操作を順番に示しています。

Wwise サウンドエンジンのボリュームパイプライン
参照
AKSOUNDENGINE_API AKRESULT SetDefaultListeners(const AkGameObjectID *in_pListenerObjs, AkUInt32 in_uNumListeners)
AkUInt32 uNumChannels
Number of channels.
AkUInt64 AkGameObjectID
Game object ID
Definition: AkTypes.h:60
AKRESULT
Standard function call result.
Definition: AkTypes.h:134
AKSOUNDENGINE_API AKRESULT RegisterGameObj(AkGameObjectID in_gameObjectID)
AkForceInline AkUInt32 GetRequiredSize(AkUInt32 in_uNumChannelsIn, AkUInt32 in_uNumChannelsOut)
Compute size (in bytes) required for given channel configurations.
#define NULL
Definition: AkTypes.h:46
AkReal32 * VectorPtr
Volume vector. Access each element with the standard bracket [] operator.
#define AkAlloca(_size_)
Stack allocations.
AKSOUNDENGINE_API AKRESULT SetListenerSpatialization(AkGameObjectID in_uListenerID, bool in_bSpatialized, AkChannelConfig in_channelConfig, AK::SpeakerVolumes::VectorPtr in_pVolumeOffsets=NULL)
#define AK_SPEAKER_SETUP_7_1
AKSOUNDENGINE_API AKRESULT SetListeners(AkGameObjectID in_emitterGameObj, const AkGameObjectID *in_pListenerGameObjs, AkUInt32 in_uNumListeners)
AKSOUNDENGINE_API AKRESULT SetPosition(AkGameObjectID in_GameObjectID, const AkSoundPosition &in_Position, AkSetPositionFlags in_eFlags=AkSetPositionFlags_Default)
AkForceInline void SetStandard(AkUInt32 in_uChannelMask)
Set channel config as a standard configuration specified with given channel mask.
uint32_t AkUInt32
Unsigned 32-bit integer
Position and orientation of objects in a "local" space
Definition: AkTypes.h:549

このページはお役に立ちましたか?

サポートは必要ですか?

ご質問や問題、ご不明点はございますか?お気軽にお問い合わせください。

サポートページをご確認ください

あなたのプロジェクトについて教えてください。ご不明な点はありませんか。

プロジェクトを登録していただくことで、ご利用開始のサポートをいたします。

Wwiseからはじめよう