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