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