バージョン

menu_open
Wwise SDK 2023.1.3
リスナーの統合

イントロダクション

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

リスナーの登録

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

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を使用して、アクセスおよび設定できます。

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

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

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

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

Working with Listeners in Third-Person Perspective Games

When implementing audio in a game or simulation that uses a third-person perspective (TPP), it’s not always obvious where to place the Listener Game Object; some would suggest the position of the camera, while others would suggest the position of the character controlled by the player. Despite having different positions, both the camera and the character controlled by the player are in some ways “you”, the player. Associating a Distance Probe with the main camera Listener allows both of these positions to contribute to sound computations, each in their own way. To understand this approach, it’s necessary to analyze the various aspects of the simulation.

Panning and Spatialization

In almost all scenarios, panning and spatialization, including spread and focus in Wwise, should be based on the camera’s position and orientation. Any disconnect between the camera and the relative orientation of the sounds in the simulation, with respect to the final speaker array (whether physical or virtual binaural), results in a loss of immersion. For example, if the camera is looking directly at a sound, then that sound should come from the center speaker channel. A sound to the left of the camera should come from the left speaker(s), and so on.

To achieve this goal, the Listener Game Object must be placed on the active camera, and the orientation of the Listener must be updated to match.

Distance-Based Attenuation

A 3D sound is typically attenuated according to the distance between the Emitter and the Listener Game Objects, applied to the sound’s attenuation curve to get volume, high-pass and low-pass filter values. The result is that closer sounds, which are more important to the experience, are louder.

In a TPP game, however, the focus of attention is not the camera itself, but is instead the character that the player controls. For this reason, a greater sense of immersion is experienced when sounds attenuate according to the distance between the Emitter and the player character, instead of between the Emitter and the camera.

To understand why this is so, it’s helpful to consider a scenario where we get undesirable volume fluctuations when distance attenuation is based on the position of the camera. Picture a TPP game where a camera is following the player character down a hallway lit with torches. Each torch emits a low-intensity sound with a sharp falloff. To turn the camera around and face the other direction, it’s necessary to orbit the camera around the character. In doing so, the camera passes closely to one or more of the torches, getting louder and then quieter again. The player character hasn’t moved, the relative importance of the torches in the scene hasn’t changed, and yet the volume fluctuations suggest otherwise.

To achieve the goal of having sounds attenuate based on the distance to the player character, a Game Object must be placed at the position of the player character and designated as the Distance Probe for the main Listener.

Distance Probe

A Distance Probe is a Game Object that is an optional, designated counterpart to a Listener Game Object. ListenerにDistance Probeをアサインすると、Listenerに送られる全ての音に適用する減衰距離が、Distance ProbeからEmitter Game Objectまでの距離に基づきます。

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

また:

  • Each Listener Game Object may have zero or one Game Object set as the Distance Probe.
  • A single Game Object may be the Distance Probe for multiple Listeners.
  • Listenerを、自分自身のDistance Probeにアサインすることは、Distance Probeをnone(なし)に設定するのと同じです。

A Distance Probe is assigned to a Listener Game Object using the AK::SoundEngine::SetDistanceProbe API.

Profiling the Distance Probe

All assigned Distance Probes are visible in the Listeners tab of the Advanced Profiler. The following image shows that a game object named “Distance Probe” has been assigned to “Listener L” using the AK::SoundEngine::SetDistanceProbe API.

The Distance Probe shows up as an icon in the Game Object 3D Viewer. Note that for convenience, the visibility of the Distance Probe in the Game Object 3D Viewer is bound to the visibility of the Listener; all filters that apply to the Listener also apply to the Distance Probe.

Additional Implementation Notes

You are not required to place the Distance Probe at the exact location of the player character in TPP experiences. Feel free to experiment with positioning to achieve the desired results. Some suggestions include: Experiment with positioning the Distance Probe at various ratios between the camera and the character. This ratio could be exposed to designers as an adjustable value to interpolate between the character position and the camera position. During cutscenes and cinematic moments, it may be necessary to move, switch off, or transfer the Distance Probe to a different Game Object. The Distance Probe need not be static.

For detail on how the various Spatial Audio features operate when a Distance Probe is assigned to the Spatial Audio Listener, refer to Third-Person Perspective and Spatial Audio.

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

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

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

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

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

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

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

注釈: 複数リスナーに関連する操作は、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:142
AKRESULT
Standard function call result.
Definition: AkTypes.h:213
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:613

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

サポートは必要ですか?

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

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

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

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

Wwiseからはじめよう