1 /*---------------------------------------------------------------------------*
2   Project:  NintendoWare
3   File:     snd_BasicSound.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: 31311 $
16  *---------------------------------------------------------------------------*/
17 /**
18  * :include nw/snd/snd_BasicSound.h
19  *
20  * @file snd_BasicSound.h
21  */
22 
23 #ifndef NW_SND_BASIC_SOUND_H_
24 #define NW_SND_BASIC_SOUND_H_
25 
26 #include <nn/types.h>
27 #include <nw/snd/snd_Global.h>
28 #include <nw/snd/snd_MoveValue.h>
29 #include <nw/ut/ut_RuntimeTypeInfo.h>
30 #include <nw/ut/ut_LinkList.h>
31 
32 namespace nw {
33 namespace snd {
34 
35 class SoundHandle;
36 class SoundPlayer;
37 class SoundActor;
38 
39 // ------------------------------------------------------------------------
40 // アンビエントパラメータ
41 
42 //! @details :private
43 struct SoundParam
44 {
45     f32 volume;
46     f32 pitch;
47     f32 pan;
48     f32 span;
49     f32 fxSend;
50     f32 lpf;
51     f32 biquadFilterValue;
52     int biquadFilterType;
53     int priority;
54     u32 userData;
55 
SoundParamSoundParam56     SoundParam()
57     : volume(1.0f),
58       pitch(1.0f),
59       pan(0.0f),
60       span(0.0f),
61       fxSend(0.0f),
62       lpf(0.0f),
63       biquadFilterValue(0.0f),
64       biquadFilterType(0),
65       priority(0),
66       userData(0)
67     {}
68 };
69 
70 //---------------------------------------------------------------------------
71 //! @brief  アンビエントパラメータ構造体です。
72 //!
73 //!         3D サウンドを使用している際には、
74 //!         前回計算された 3D サウンド計算結果を参照するため、そして、
75 //!         3D サウンドエンジンクラスの計算結果を格納するために用いられます。
76 //!         詳しくは、@ref Sound3DEngine::UpdateAmbientParam 関数のリファレンスをご参照ください。
77 //!
78 //!         biquad フィルタは複数の箇所での設定が重ね合わされず、
79 //!         以下の優先度に従って設定されます。
80 //!         優先度が高い箇所でパラメータの設定がされた場合、それより下位の設定は上書きされます。
81 //!
82 //!         ・サウンドハンドルでの設定 @n
83 //!         ・サウンドプレーヤーでの設定 @n
84 //!         ・当アンビエントパラメータ構造体での設定 @n
85 //!         ・シーケンスデータでの設定 @n
86 //!
87 //!         エフェクトセンド量 fxSend は「AUX バス A」へのセンド量として反映されます。
88 //!         「AUX バス B」へのセンド量は、
89 //!         SoundMaker 上、シーケンスデータ上、@ref SoundHandle::SetFxSend
90 //!         関数などで設定する必要があります。
91 //!
92 //! @see Sound3DEngine::UpdateAmbientParam
93 //! @see SoundHandle::SetFxSend
94 //!
95 //! @date 2010/12/17 span, fxsend, lpf, biquadFilterValue, biquadFilterType の説明を追加
96 //! @date 2010/04/08 高速化のため VoiceOutParam メンバを削除
97 //! @date 2010/03/12 初版
98 //---------------------------------------------------------------------------
99 struct SoundAmbientParam
100 {
101     //---------------------------------------------------------------------------
102     //! @brief  サウンドの音量の倍率です。0.0 を指定すると発音されません。
103     //---------------------------------------------------------------------------
104     f32 volume;
105 
106     //---------------------------------------------------------------------------
107     //! @brief  サウンドの音程の周波数比率です。
108     //!         1.0 を指定すると変化しません。
109     //!         2.0 を指定すると再生される周波数が 2 倍になり、1 オクターブ高い音程になります。
110     //---------------------------------------------------------------------------
111     f32 pitch;
112 
113     //---------------------------------------------------------------------------
114     //! @brief  サウンドのパン (左右の定位) の相対変化量です。
115     //!         0.0 を指定すると変化しません。
116     //!         1.0 を指定すると中央に定位していた音が右端に定位するようになり、
117     //!         -1.0 を指定すると中央に定位していた音が左端に定位するようになります。
118     //---------------------------------------------------------------------------
119     f32 pan;
120 
121     //---------------------------------------------------------------------------
122     //! @brief  サウンドのサラウンドパン(前後の定位)の相対変化量です。
123     //!         0.0 を指定すると変化しません。
124     //!         1.0 を指定すると最前方に定位していた音が中央に定位するようになり、
125     //!         2.0 を指定すると最前方に定位していた音が最後方に定位するようになります。
126     //!         前方へ定位を移動させたい場合は負の値を指定します。
127     //---------------------------------------------------------------------------
128     f32 span;
129 
130     //---------------------------------------------------------------------------
131     //! @brief  サウンドのエフェクトセンドの相対変化量です。
132     //!         0.0 を指定するとセンド量を変更しません。
133     //!         1.0 を指定すると AUX バスに送られていなかったサウンドが
134     //!         最大のセンド量で送られるようになります。
135     //---------------------------------------------------------------------------
136     f32 fxSend;
137 
138     //---------------------------------------------------------------------------
139     //! @brief  サウンドのローパスフィルタのカットオフの相対変化量です。
140     //!         0.0 を指定するとカットオフの値を変更しません。
141     //!         -1.0 を指定すると、フィルタがかかっていない状態から、
142     //!         最もフィルタがかかっている状態(カットオフ周波数が下がる方向)に変更します。
143     //---------------------------------------------------------------------------
144     f32 lpf;
145 
146     //---------------------------------------------------------------------------
147     //! @brief  サウンドの biquad フィルタのかかり具合を表す値です。
148     //!         値の意味はフィルタの係数の種類によって変化します。
149     //---------------------------------------------------------------------------
150     f32 biquadFilterValue;
151 
152     //---------------------------------------------------------------------------
153     //! @brief  サウンドの biquad フィルタの種類です。
154     //!         @ref BiquadFilterType の値を使用します。
155     //!         プリセットで用意されているフィルタの種類のほか、
156     //!         ユーザーが登録したフィルタの種類の値をとります。
157     //---------------------------------------------------------------------------
158     int biquadFilterType;
159 
160     //---------------------------------------------------------------------------
161     //! @brief  サウンドのプレイヤープライオリティの相対変化量です。
162     //!         もともとのプレイヤープライオリティに加算されます。
163     //---------------------------------------------------------------------------
164     int priority;
165 
166     //---------------------------------------------------------------------------
167     //! @brief  ユーザーが自由に利用できるパラメータです。
168     //!         サウンド再生時に 0 にリセットされます。
169     //---------------------------------------------------------------------------
170     u32 userData;
171 
172     //---------------------------------------------------------------------------
173     //! @brief    コンストラクタです。
174     //!
175     //! @date 2010/03/12 初版
176     //---------------------------------------------------------------------------
SoundAmbientParamSoundAmbientParam177     SoundAmbientParam()
178     : volume(1.0f),
179       pitch(1.0f),
180       pan(0.0f),
181       span(0.0f),
182       fxSend(0.0f),
183       lpf(0.0f),
184       biquadFilterValue(0.0f),
185       biquadFilterType(0),
186       priority(0),
187       userData(0)
188     {}
189 };
190 
191 namespace internal {
192 
193 struct SoundActorParam
194 {
195     f32 volume;
196     f32 pitch;
197     f32 pan;
198 
SoundActorParamSoundActorParam199     SoundActorParam(): volume(1.0f),pitch(1.0f),pan(0.0f) {}
ResetSoundActorParam200     void Reset()
201     {
202         volume = pitch = 1.0f;
203         pan = 0.0f;
204     }
205 };
206 
207 /* ========================================================================
208         typename declaration
209    ======================================================================== */
210 
211 namespace driver {
212 class BasicSoundPlayer;
213 }
214 
215 class PlayerHeap;
216 class ExternalSoundPlayer;
217 
218 /* ========================================================================
219         class definition
220    ======================================================================== */
221 
222 class BasicSound
223 {
224     friend class SoundHandle;
225 
226 public:
227     NW_UT_RUNTIME_TYPEINFO;      // ダウンキャスト用の実行時型情報を埋め込みます
228 
229     /* ------------------------------------------------------------------------
230             constant declaration
231        ------------------------------------------------------------------------ */
232 public:
233     static const int PRIORITY_MIN = 0;
234     static const int PRIORITY_MAX = 127;
235     static const u32 INVALID_ID = 0xffffffff;
236 
237     /* ------------------------------------------------------------------------
238             type definition
239        ------------------------------------------------------------------------ */
240 public:
241     class AmbientParamUpdateCallback;
242     class AmbientArgUpdateCallback;
243     class AmbientArgAllocatorCallback;
244 
245     struct AmbientInfo
246     {
247         AmbientParamUpdateCallback* paramUpdateCallback;
248         AmbientArgUpdateCallback* argUpdateCallback;
249         AmbientArgAllocatorCallback* argAllocatorCallback;
250         void* arg;
251         unsigned long argSize;
252     };
253 
254     enum PlayerState
255     {
256         PLAYER_STATE_INIT,
257         PLAYER_STATE_PREPARED,
258         PLAYER_STATE_PLAY,
259         PLAYER_STATE_STOP
260     };
261 
262     /* ------------------------------------------------------------------------
263             class member
264        ------------------------------------------------------------------------ */
265 public:
266     BasicSound();
~BasicSound()267     virtual ~BasicSound() {}
268     void Update();
269     void StartPrepared();
270     void Stop( int fadeFrames );
271     void Pause( bool flag, int fadeFrames );
272     void SetAutoStopCounter( int frames );
273     void FadeIn( int frames );
274 
275     virtual void Initialize();
276     virtual void Finalize();
277 
278     virtual bool IsPrepared() const = 0;
279     bool IsPause() const;
280 
281     //------------------------------------------------------------------
282     // パラメータ (Get 関数は、主にデバッグ用途)
283     void SetPriority( int priority, int ambientPriority );
284     void GetPriority( int* priority, int* ambientPriority ) const;
285 
286     void SetInitialVolume( f32 volume );
287     f32  GetInitialVolume() const;
288 
289     void SetVolume( f32 volume, int frames = 0 );
290     f32  GetVolume() const;
291 
292     void SetPitch( f32 pitch );
293     f32  GetPitch() const;
294 
295     void SetPan( f32 pan );
296     f32  GetPan() const;
297 
298     void SetLpfFreq( f32 lpfFreq );
299     f32  GetLpfFreq() const;
300 
301     void SetBiquadFilter( int type, f32 value );
302     void GetBiquadFilter( int* type, f32* value ) const;
303 
304     void SetSurroundPan( f32 pan );
305     f32  GetSurroundPan() const;
306 
307     void SetPlayerPriority( int priority );
308 
309     // 以下、コマンド化されているため、Get 関数は用意しない
310     void SetPanMode( PanMode panMode );
311     void SetPanCurve( PanCurve panCurve );
312     void SetFrontBypass( bool isFrontBypass );
313 
314     //------------------------------------------------------------------
315     // 出力パラメータ
316     void SetMainSend( f32 send );
317     f32  GetMainSend() const;
318 
319     void SetFxSend( AuxBus bus, f32 send );
320     f32  GetFxSend( AuxBus bus ) const;
321 
322     //------------------------------------------------------------------
323     // 情報取得
324     int GetRemainingFadeFrames() const;
325     int GetRemainingPauseFadeFrames() const;
GetPlayerPriority()326     int GetPlayerPriority() const { return m_Priority; } // for AnimSound
327 
328     //------------------------------------------------------------------
329     // その他のパラメータ
330     void SetId( u32 id );
GetId()331     u32 GetId() const { return m_Id; }
GetPlayFrameCount()332     unsigned long GetPlayFrameCount() const { return m_UpdateCounter; }
333 
334     //------------------------------------------------------------------
CalcCurrentPlayerPriority()335     int CalcCurrentPlayerPriority() const
336     {
337         return ut::Clamp(
338              static_cast<int>( m_Priority ) + static_cast<int>( m_AmbientParam.priority ),
339              PRIORITY_MIN,
340              PRIORITY_MAX
341         );
342     }
343 
344     // サウンドプレイヤー
GetSoundPlayer()345     SoundPlayer* GetSoundPlayer() { return m_pSoundPlayer; }
GetSoundPlayer()346     const SoundPlayer* GetSoundPlayer() const { return m_pSoundPlayer; }
347 
348     void AttachSoundPlayer( SoundPlayer* player );
349     void DetachSoundPlayer( SoundPlayer* player );
350 
351     void AttachSoundActor( SoundActor* actor );
352     void DetachSoundActor( SoundActor* actor );
353 
354     void AttachExternalSoundPlayer( ExternalSoundPlayer* extPlayer );
355     void DetachExternalSoundPlayer( ExternalSoundPlayer* extPlayer );
356 
357     // プレイヤーヒープ
358     void AttachPlayerHeap( PlayerHeap* pHeap );
359     void DetachPlayerHeap( PlayerHeap* pHeap );
GetPlayerHeap()360     PlayerHeap* GetPlayerHeap() { return m_pPlayerHeap; }
361 
362     // アンビエントパラメータ
363     void SetAmbientInfo( const AmbientInfo& info );
ClearAmbientArgUpdateCallback()364     void ClearAmbientArgUpdateCallback() { m_AmbientInfo.argUpdateCallback = NULL; }
ClearAmbientParamUpdateCallback()365     void ClearAmbientParamUpdateCallback() { m_AmbientInfo.paramUpdateCallback = NULL; }
ClearAmbientArgAllocatorCallback()366     void ClearAmbientArgAllocatorCallback() { m_AmbientInfo.argAllocatorCallback = NULL; }
GetAmbientParam()367     const SoundParam& GetAmbientParam() const { return m_AmbientParam; }
368     static int GetAmbientPriority( const AmbientInfo& ambientInfo, u32 soundId  );
369 
370     // ハンドル関数
371     bool IsAttachedGeneralHandle();
372     bool IsAttachedTempGeneralHandle();
373     virtual bool IsAttachedTempSpecialHandle() = 0;
374     void DetachGeneralHandle();
375     void DetachTempGeneralHandle();
376     virtual void DetachTempSpecialHandle() = 0;
377 
378 protected:
379     virtual driver::BasicSoundPlayer* GetBasicSoundPlayerHandle() = 0;
380 
OnUpdatePlayerPriority()381     virtual void OnUpdatePlayerPriority() {}
382 
383     virtual void UpdateMoveValue();
384     virtual void UpdateParam();
385 
IsStarted()386     bool IsStarted() const { return m_StartedFlag; } // for SeqSound
IsPlayerAvailable()387     bool IsPlayerAvailable() const { return m_PlayerAvailableFlag; }
388 
389 private:
390     //-----------------------------------------------------------------------------
391     // PauseState状態遷移
392     //
393     // state \ event | pause   | unpause   | fade-finish
394     // --------------+---------+-----------+--------------
395     // normal        | pausing |  -        |  -
396     // pausing       | pausing | unpausing | paused
397     // paused        |  -      | unpausing |  -
398     // unpausing     | pausing | unpausing | normal
399     //
400     enum PauseState
401     {
402         PAUSE_STATE_NORMAL,
403         PAUSE_STATE_PAUSING,
404         PAUSE_STATE_PAUSED,
405         PAUSE_STATE_UNPAUSING
406     };
407 
408     PlayerHeap* m_pPlayerHeap;
409     SoundHandle* m_pGeneralHandle;
410     SoundHandle* m_pTempGeneralHandle;
411     SoundPlayer* m_pSoundPlayer;
412     SoundActor* m_pSoundActor;
413     ExternalSoundPlayer* m_pExtSoundPlayer;
414 
415     AmbientInfo m_AmbientInfo;
416     SoundParam m_AmbientParam;
417     SoundActorParam m_ActorParam;
418 
419     MoveValue<f32, int> m_FadeVolume;
420     MoveValue<f32, int> m_PauseFadeVolume;
421 
422     bool m_InitializeFlag;
423     bool m_StartFlag;
424     bool m_StartedFlag;
425     bool m_AutoStopFlag;
426     bool m_FadeOutFlag;
427     bool m_PlayerAvailableFlag;
428 
429     PlayerState m_PlayerState;
430     PauseState m_PauseState;
431     bool m_UnPauseFlag;
432 
433     s32 m_AutoStopCounter;
434     u32 m_UpdateCounter;
435 
436     u8 m_Priority;
437     u8 m_BiquadFilterType;
438     u32 m_Id;
439 
440     MoveValue<f32, int> m_ExtMoveVolume;
441     f32 m_InitVolume;
442     f32 m_ExtPan;
443     f32 m_ExtPitch;
444     f32 m_LpfFreq;
445     f32 m_BiquadFilterValue;
446     f32 m_MainSend;
447     f32 m_FxSend[ AUX_BUS_NUM ];
448     f32 m_ExtSurroundPan;
449 
450 public:
451     ut::LinkListNode m_PriorityLink; // for SoundInstanceManager
452     ut::LinkListNode m_SoundPlayerPlayLink;
453     ut::LinkListNode m_SoundPlayerPriorityLink;
454     ut::LinkListNode m_ExtSoundPlayerPlayLink;
455 };
456 
457 
458 
459 class BasicSound::AmbientParamUpdateCallback
460 {
461 public:
~AmbientParamUpdateCallback()462     virtual ~AmbientParamUpdateCallback() {}
463     virtual void detail_UpdateAmbientParam(
464         const void* arg,
465         u32 soundId,
466         SoundAmbientParam* param
467     ) = 0;
468     virtual int detail_GetAmbientPriority(
469         const void* arg,
470         u32 soundId
471     ) = 0;
472 };
473 
474 class BasicSound::AmbientArgUpdateCallback
475 {
476 public:
~AmbientArgUpdateCallback()477     virtual ~AmbientArgUpdateCallback() {}
478     virtual void detail_UpdateAmbientArg(
479         void* arg,
480         const internal::BasicSound* sound
481     ) = 0;
482 };
483 
484 class BasicSound::AmbientArgAllocatorCallback
485 {
486 public:
~AmbientArgAllocatorCallback()487     virtual ~AmbientArgAllocatorCallback() {}
488     virtual void* detail_AllocAmbientArg( size_t argSize ) = 0;
489     virtual void detail_FreeAmbientArg(
490         void* arg,
491         const internal::BasicSound* sound
492     ) = 0;
493 };
494 
495 
496 } // namespace nw::snd::internal
497 } // namespace nw::snd
498 } // namespace nw
499 
500 
501 #endif /* NW_SND_BASIC_SOUND_H_ */
502 
503