1 /*---------------------------------------------------------------------------*
2   Project:  NintendoWare
3   File:     snd_Sound3DManager.h
4 
5   Copyright (C)2009-2011 Nintendo/HAL Laboratory, Inc.  All rights reserved.
6 
7   These coded instructions, statements, and computer programs contain proprietary
8   information of Nintendo and/or its licensed developers and are protected by
9   national and international copyright laws. They may not be disclosed to third
10   parties or copied or duplicated in any form, in whole or in part, without the
11   prior written consent of Nintendo.
12 
13   The content herein is highly confidential and should be handled accordingly.
14 
15   $Revision: $
16  *---------------------------------------------------------------------------*/
17 
18 /**
19  * :include nw/snd/snd_Sound3DManager.h
20  *
21  * @file snd_Sound3DManager.h
22  */
23 
24 #ifndef NW_SND_SOUND_3D_MANAGER_H_
25 #define NW_SND_SOUND_3D_MANAGER_H_
26 
27 #include <nw/math/math_Types.h>     // nw::math::VEC3
28 #include <nw/ut/ut_LinkList.h>
29 #include <nw/snd/snd_BasicSound.h>
30 #include <nw/snd/snd_InstancePool.h>
31 #include <nw/snd/snd_Sound3DListener.h>
32 
33 namespace nw {
34 namespace snd {
35 
36 /* ========================================================================
37         typename declaration
38    ======================================================================== */
39 
40 class SoundArchive;
41 class Sound3DManager;
42 class Sound3DEngine;
43 
44 /* ========================================================================
45         struct difinition
46    ======================================================================== */
47 
48 //---------------------------------------------------------------------------
49 //! @brief    3Dサウンドのパラメータです。
50 //!
51 //!           このパラメータを用いて 3D サウンドの計算を行います。
52 //!
53 //!           ctrlFlag, decayCurve, decayRatio, dopplerFactor, soundUserParam
54 //!           は SoundMaker で各サウンドに設定した値が入ります。
55 //!
56 //!           actorUserParam は、@ref Sound3DActor::SetUserParam で設定された値です。
57 //!
58 //!           dopplerFactor は、ドップラー効果のかかりり具合を表します。
59 //!           0 のときは音が変化せず、値が大きくなるほど変化が大きくなります。
60 //!
61 //! @see Sound3DEngine::UpdateAmbientParam
62 //! @see Sound3DActor::SetUserParam
63 //! @see DecayCurve
64 //! @see nw::math::VEC3
65 //!
66 //! @date 2010/03/12 初版
67 //---------------------------------------------------------------------------
68 struct Sound3DParam
69 {
70     //! 3D サウンドアクターの現在位置です。
71     math::VEC3 position;
72 
73     //! 3D サウンドアクターの速度です。
74     math::VEC3 velocity;
75 
76     //! パラメータのコントロールフラグです。サウンドライブラリ内部で使用されます。
77     u32 ctrlFlag;
78 
79     //! アクターに設定されたユーザーパラメータです。
80     u32 actorUserParam;
81 
82     //! サウンドに設定されたユーザーパラメータです。
83     u32 soundUserParam;
84 
85     //! アクターとリスナーが音量減衰の単位距離分だけ離れているときの音量の減衰率です。
86     f32 decayRatio;
87 
88     //! 音量減衰カーブの種類です。@ref DecayCurve の値を設定します。
89     u8  decayCurve;
90 
91     //! ドップラーファクターです。
92     u8  dopplerFactor;
93 
94     //---------------------------------------------------------------------------
95     //! @brief    コンストラクタです。
96     //!
97     //! @date 2010/03/12 初版
98     //---------------------------------------------------------------------------
99     Sound3DParam();
100 };
101 
102 /* ========================================================================
103         class difinition
104    ======================================================================== */
105 
106 namespace internal {
107 
108 class ISound3DEngine
109 {
110 public:
~ISound3DEngine()111     virtual ~ISound3DEngine() {}
112 
113     virtual void UpdateAmbientParam(
114         const Sound3DManager* manager,
115         const Sound3DParam* actorParam,
116         u32 soundId,
117         SoundAmbientParam* param
118     ) = 0;
119 
120     virtual int GetAmbientPriority(
121         const Sound3DManager* manager,
122         const Sound3DParam* actorParam,
123         u32 soundId
124     ) = 0;
125 };
126 
127 }
128 
129 //---------------------------------------------------------------------------
130 //! @brief    3D サウンドのパラメータ演算と管理を行うクラスです。
131 //!
132 //!           @ref nw::snd::Sound3DListener クラスと
133 //!           @ref nw::snd::Sound3DActor クラスの情報を用いて、
134 //!           サウンドのパラメータ演算を行います。
135 //!
136 //! @see Sound3DListener クラス
137 //! @see Sound3DActor クラス
138 //!
139 //! @date 2010/02/25 初版
140 //---------------------------------------------------------------------------
141 class Sound3DManager
142 : public internal::BasicSound::AmbientParamUpdateCallback,
143   public internal::BasicSound::AmbientArgAllocatorCallback
144 {
145 public:
146     //! @details :private
147     typedef internal::InstancePool<Sound3DParam> Sound3DParamPool;
148 
149     //---------------------------------------------------------------------------
150     //! @brief    3D サウンドリスナーのリストを表す型です。
151     //!
152     //! @see Sound3DListener クラス
153     //! @see ut::LinkList クラス
154     //!
155     //! @date 2010/03/12 初版
156     //---------------------------------------------------------------------------
157     typedef ut::LinkList< Sound3DListener, offsetof(Sound3DListener,m_LinkNode)> ListenerList;
158 
159     /* ------------------------------------------------------------------------
160             class member
161        ------------------------------------------------------------------------ */
162 public:
163 
164     //! @name コンストラクタ
165     //@{
166     //---------------------------------------------------------------------------
167     //! @brief    コンストラクタです。
168     //!
169     //!           初期化時はプライオリティ最大減少量を 32 に設定します。
170     //!
171     //! @date 2010/02/25 初版
172     //---------------------------------------------------------------------------
173     Sound3DManager();
174     //@}
175 
176     //! @name 初期化
177     //@{
178     //---------------------------------------------------------------------------
179     //! @brief    初期化に必要なメモリのサイズを取得します。
180     //!
181     //! @param[in] archive    初期化のための情報取得に使用するサウンドアーカイブです。
182     //!
183     //! @return   初期化に必要なメモリのサイズを返します。
184     //!
185     //! @see Initialize
186     //!
187     //! @date 2010/02/25 初版
188     //---------------------------------------------------------------------------
189     size_t GetRequiredMemSize( const SoundArchive* archive );
190 
191     //---------------------------------------------------------------------------
192     //! @brief    3D サウンドマネージャーの初期化を行います。
193     //!
194     //!           3D サウンドマネージャーを使用する前に初期化を行う必要があります。
195     //!           3D サウンドを再生する際に、
196     //!           3D マネージャでセットアップされたメモリ領域を利用します。
197     //!
198     //!           3D サウンドマネージャーが必要とするメモリのサイズは
199     //!           @ref nw::snd::Sound3DManager::GetRequiredMemSize
200     //!           で取得することができます。
201     //!
202     //! @param[in] archive  3D サウンドマネージャーで使用するサウンドアーカイブです。
203     //! @param[in] buffer   バッファへのポインタです。
204     //! @param[in] size     バッファサイズです。
205     //!
206     //! @return   初期化に成功したら true を、失敗したら false を返します。
207     //!
208     //! @see GetRequiredMemSize
209     //!
210     //! @date 2010/02/25 初版
211     //---------------------------------------------------------------------------
212     bool Initialize(
213         const SoundArchive* archive,
214         void* buffer,
215         size_t size
216     );
217 
218     //! @details :private
219     bool InitializeWithMoreSoundArchive( const SoundArchive* archive );
220 
221     //---------------------------------------------------------------------------
222     //! @brief    3D サウンドデータマネージャを破棄します。
223     //!
224     //! @see Initialize
225     //!
226     //! @date 2010/10/12 初版
227     //---------------------------------------------------------------------------
228     bool Finalize();
229     //@}
230 
231     //! @name 3D サウンドリスナー
232     //@{
233     //---------------------------------------------------------------------------
234     //! @brief    3D サウンドリスナーを登録します。
235     //!
236     //!           3D サウンドを鳴らすためには 3D サウンドマネージャーに
237     //!           3D サウンドリスナーを登録する必要があります。
238     //!
239     //!           3D サウンドリスナーは複数登録することができます。
240     //!           複数のリスナーを登録した場合の詳細は、
241     //!           プログラマーガイドの「マルチリスナー」を参照してください。
242     //!
243     //!           ただし、ひとつの 3D サウンドリスナーを複数の
244     //!           3D サウンドマネージャーに登録することはできません。
245     //!           また、ひとつの 3D サウンドリスナーをひとつの
246     //!           3D サウンドマネージャーに複数回登録することもできません。
247     //!
248     //! @param[in] listener   登録する 3D サウンドリスナーへのポインタです。
249     //!
250     //! @see Sound3DListener クラス
251     //! @see RemoveListener
252     //!
253     //! @date 2010/02/25 初版
254     //---------------------------------------------------------------------------
AddListener(Sound3DListener * listener)255     void AddListener( Sound3DListener* listener ) { m_ListenerList.PushBack( listener ); }
256 
257     //---------------------------------------------------------------------------
258     //! @brief    指定した登録済みの 3D サウンドリスナーを登録解除します。
259     //!
260     //! @param[in] listener   登録を削除する 3D サウンドリスナーへのポインタです。
261     //!
262     //! @see Sound3DListener クラス
263     //! @see AddListener
264     //!
265     //! @date 2010/03/12 初版
266     //---------------------------------------------------------------------------
RemoveListener(Sound3DListener * listener)267     void RemoveListener( Sound3DListener* listener ) { m_ListenerList.Erase( listener ); }
268 
269     //---------------------------------------------------------------------------
270     //! @brief    登録されている 3D サウンドリスナーのリストを取得します。
271     //!
272     //!           取得したリスト内の 3D サウンドリスナーの並び順は、
273     //!           @ref AddListener  で 3D サウンドマネージャーに登録された順番です。
274     //!
275     //! @return   3D サウンドリスナーのリストを返します。
276     //!
277     //! @see Sound3DListener クラス
278     //! @see AddListener
279     //! @see RemoveListener
280     //!
281     //! @date 2010/03/12 初版
282     //---------------------------------------------------------------------------
GetListenerList()283     const ListenerList& GetListenerList() const { return m_ListenerList; }
284     //@}
285 
286     //! @name 3D サウンドエンジン
287     //@{
288     //---------------------------------------------------------------------------
289     //! @brief    3D サウンドエンジンを登録します。
290     //!
291     //!           3D サウンドエンジンは、3D サウンドのパラメータの計算処理が定義されたクラスです。
292     //!           初期状態では、サウンドライブラリで用意されているデフォルトのエンジンクラスが
293     //!           登録されていますので、この関数を呼び出さなくても
294     //!           3D サウンドを使用することができます。
295     //!
296     //!           カスタマイズした 3D サウンドエンジンクラスを使用したい場合には、
297     //!           この関数を呼び出して 3D サウンドエンジンを登録してください。
298     //!
299     //! @param[in] engine 登録する 3D サウンドエンジンへのポインタです。
300     //!
301     //! @see Sound3DEngine クラス
302     //!
303     //! @date 2010/03/12 初版
304     //---------------------------------------------------------------------------
305     void SetEngine( Sound3DEngine* engine );
306     //@}
307 
308     //! @name パラメータ
309     //@{
310     //---------------------------------------------------------------------------
311     //! @brief    最大プライオリティ減少量を設定します。
312     //!
313     //!           3D サウンドのプライオリティは、音量の減衰に比例して減少します。
314     //!           この関数は音量が 0 になったときのプライオリティの減少値を設定します。
315     //!
316     //! @param[in] maxPriorityReduction   最大プライオリティ減少量です。
317     //!
318     //! @see GetMaxPriorityReduction
319     //!
320     //! @date 2010/03/12 初版
321     //---------------------------------------------------------------------------
SetMaxPriorityReduction(int maxPriorityReduction)322     void SetMaxPriorityReduction( int maxPriorityReduction )
323     {
324         m_MaxPriorityReduction = maxPriorityReduction;
325     }
326 
327     //---------------------------------------------------------------------------
328     //! @brief    現在設定されている最大プライオリティ減少量を取得します。
329     //!
330     //! @return   現在設定されている最大プライオリティ減少量を返します。
331     //!
332     //! @see SetMaxPriorityReduction
333     //!
334     //! @date 2010/03/12 初版
335     //---------------------------------------------------------------------------
GetMaxPriorityReduction()336     int GetMaxPriorityReduction() const
337     {
338         return m_MaxPriorityReduction;
339     }
340 
341     //---------------------------------------------------------------------------
342     //! @brief    3D サウンドで設定されるパンの変化幅を設定します。
343     //!
344     //!           panRange に 1.0 を指定すると、定位の変化が最大になります。
345     //!           1.0 より小さくすると、定位の変化幅を抑えることが出来ます。
346     //!
347     //!           panRange の初期値は 0.9 です。
348     //!
349     //! @param[in] panRange   パンの変化幅 ( 0.0 ~ 1.0 ) です。
350     //!
351     //! @see GetPanRange
352     //!
353     //! @date 2010/03/12 初版
354     //---------------------------------------------------------------------------
SetPanRange(f32 panRange)355     void SetPanRange( f32 panRange ) { m_PanRange = panRange; }
356 
357     //---------------------------------------------------------------------------
358     //! @brief    現在設定されているパンの変化幅を取得します。
359     //!
360     //! @return   現在設定されているパンの変化幅を返します。
361     //!
362     //! @see SetPanRange
363     //!
364     //! @date 2010/03/12 初版
365     //---------------------------------------------------------------------------
GetPanRange()366     f32 GetPanRange() const { return m_PanRange; }
367 
368     //---------------------------------------------------------------------------
369     //! @brief    3D サウンドで設定される音速を設定します。
370     //!
371     //!           設定した音速は、ドップラー効果による音程変化の計算に使用されます。
372     //!
373     //!           設定する値の単位は 1 フレーム当たりの音の速さです。
374     //!           音速は約 340m / 秒ですので、3D 空間の座標の単位系が 1.0f で 1m である場合、
375     //!           60 フレームで動作しているとすると、340.0f / 60 が設定すべき値になります。
376     //!
377     //!           音速に 0.0f を設定すると、ドップラー効果が発生しなくなります。
378     //!           デフォルト値は 0.0f です。
379     //!
380     //! @param[in] sonicVelocity  音速です。
381     //!
382     //! @see GetSonicVelocity
383     //!
384     //! @date 2010/03/12 初版
385     //---------------------------------------------------------------------------
SetSonicVelocity(f32 sonicVelocity)386     void SetSonicVelocity( f32 sonicVelocity ) { m_SonicVelocity = sonicVelocity; }
387 
388     //---------------------------------------------------------------------------
389     //! @brief    現在設定されている音速を取得します。
390     //!
391     //! @return   現在設定されている音速を返します。
392     //!
393     //! @see SetSonicVelocity
394     //!
395     //! @date 2010/03/12 初版
396     //---------------------------------------------------------------------------
GetSonicVelocity()397     f32 GetSonicVelocity() const { return m_SonicVelocity; }
398 
399     //---------------------------------------------------------------------------
400     //! @brief  3D サウンドで設定される biquad フィルタの種類を設定します。
401     //!
402     //!         biquad フィルタは複数の箇所での設定が重ね合わされず、
403     //!         以下の優先度に従って設定されます。
404     //!         優先度が高い箇所でパラメータの設定がされた場合、
405     //!         それより下位の設定は上書きされます。
406     //!
407     //!         (1) サウンドハンドルでの設定 @n
408     //!         (2) サウンドプレーヤーでの設定 @n
409     //!         (3) アンビエントパラメータ構造体での設定 @n
410     //!         (4) シーケンスデータでの設定
411     //!
412     //!         フィルタの種類 type は @ref BiquadFilterType の値を使用します。
413     //!         プリセットで用意されているフィルタの種類の他、
414     //!         ユーザーが登録したフィルタを選択することができます。
415     //!
416     //!         type には 0 ~ BIQUAD_FILTER_TYPE_USER_MAX の値を設定します。
417     //!         上記の範囲外の値を入れると、アサートで停止します
418     //!         (Debug/Development 版のみ。Release 版は無視され値が設定されますが、
419     //!         正常な動作は保証されません)。
420     //!
421     //! @param[in] type   biquad フィルタの種類。
422     //!
423     //! @see BiquadFilterType
424     //! @see GetBiquadFilterType
425     //!
426     //! @date 2010/11/30 初版
427     //---------------------------------------------------------------------------
428     void SetBiquadFilterType( int type );
429 
430         // TODO: 以下、要修正。RVL と比べて軽い実装になっている?
431         // biquad フィルタは従来の LPF に比べ 3 倍強の DSP 負荷がかかります。
432         // これは、AUX バス1本分のミキサーの負荷とほぼ同等です。
433 
434     //---------------------------------------------------------------------------
435     //! @brief    現在設定されている biquad フィルタの種類を取得します。
436     //!
437     //! @return   現在設定されている biquad フィルタの種類を返します。
438     //!
439     //! @see BiquadFilterType
440     //! @see SetBiquadFilterType
441     //!
442     //! @date 2010/11/30 初版
443     //---------------------------------------------------------------------------
GetBiquadFilterType()444     int GetBiquadFilterType() const { return m_BiquadFilterType; }
445     //@}
446 
447 private:
448     virtual void detail_UpdateAmbientParam(
449         const void* arg,
450         u32 soundId,
451         SoundAmbientParam* param
452     );
453     virtual int detail_GetAmbientPriority(
454         const void* arg,
455         u32 soundId
456     );
457     virtual void* detail_AllocAmbientArg( size_t argSize );
458     virtual void detail_FreeAmbientArg(
459         void* arg,
460         const internal::BasicSound* sound
461     );
462 
463     Sound3DParamPool m_ParamPool;
464     ListenerList m_ListenerList;
465     internal::ISound3DEngine* m_pSound3DEngine;
466 
467     s32 m_MaxPriorityReduction;
468     f32 m_PanRange;
469     f32 m_SonicVelocity;
470     s32 m_BiquadFilterType;
471 
472     void* m_pSoundParamPoolBuffer;
473     size_t m_SoundParamPoolBufferSize;
474     s32 m_FreeMemSizeAfterCheking;
475     bool m_IsInitialized;
476 };
477 
478 } // namespace nw::snd
479 } // namespace nw
480 
481 
482 #endif /* NW_SND_SOUND_3D_MANAGER_H_ */
483 
484