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: 22340 $
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     // パラメータ
281     void SetPriority( int priority, int ambientPriority );
282     void SetInitialVolume( f32 volume );
283     void SetVolume( f32 volume, int frames = 0 );
284     void SetPitch( f32 pitch );
285     void SetPan( f32 pan );
286     void SetLpfFreq( f32 lpfFreq );
287     void SetBiquadFilter( int type, f32 value );
288     void SetSurroundPan( f32 pan );
289     void SetPanMode( PanMode panMode );
290     void SetPanCurve( PanCurve panCurve );
291     void SetPlayerPriority( int priority );
292     void SetFrontBypass( bool isFrontBypass );
293 
294     //------------------------------------------------------------------
295     // 出力パラメータ
296     void SetMainSend( f32 send );
297     void SetFxSend( AuxBus bus, f32 send );
298 
299     //------------------------------------------------------------------
300     // 情報取得
301     int GetRemainingFadeFrames() const;
302     int GetRemainingPauseFadeFrames() const;
GetPlayerPriority()303     int GetPlayerPriority() const { return m_Priority; } // for AnimSound
304 
305     //------------------------------------------------------------------
306     // その他のパラメータ
307     void SetId( u32 id );
GetId()308     u32 GetId() const { return m_Id; }
GetPlayFrameCount()309     unsigned long GetPlayFrameCount() const { return m_UpdateCounter; }
310 
311     //------------------------------------------------------------------
CalcCurrentPlayerPriority()312     int CalcCurrentPlayerPriority() const
313     {
314         return ut::Clamp(
315              static_cast<int>( m_Priority ) + static_cast<int>( m_AmbientParam.priority ),
316              PRIORITY_MIN,
317              PRIORITY_MAX
318         );
319     }
320 
321     // サウンドプレイヤー
GetSoundPlayer()322     SoundPlayer* GetSoundPlayer() { return m_pSoundPlayer; }
GetSoundPlayer()323     const SoundPlayer* GetSoundPlayer() const { return m_pSoundPlayer; }
324 
325     void AttachSoundPlayer( SoundPlayer* player );
326     void DetachSoundPlayer( SoundPlayer* player );
327 
328     void AttachSoundActor( SoundActor* actor );
329     void DetachSoundActor( SoundActor* actor );
330 
331     void AttachExternalSoundPlayer( ExternalSoundPlayer* extPlayer );
332     void DetachExternalSoundPlayer( ExternalSoundPlayer* extPlayer );
333 
334     // プレイヤーヒープ
335     void AttachPlayerHeap( PlayerHeap* pHeap );
336     void DetachPlayerHeap( PlayerHeap* pHeap );
GetPlayerHeap()337     PlayerHeap* GetPlayerHeap() { return m_pPlayerHeap; }
338 
339     // アンビエントパラメータ
340     void SetAmbientInfo( const AmbientInfo& info );
ClearAmbientArgUpdateCallback()341     void ClearAmbientArgUpdateCallback() { m_AmbientInfo.argUpdateCallback = NULL; }
ClearAmbientParamUpdateCallback()342     void ClearAmbientParamUpdateCallback() { m_AmbientInfo.paramUpdateCallback = NULL; }
ClearAmbientArgAllocatorCallback()343     void ClearAmbientArgAllocatorCallback() { m_AmbientInfo.argAllocatorCallback = NULL; }
GetAmbientParam()344     const SoundParam& GetAmbientParam() const { return m_AmbientParam; }
345     static int GetAmbientPriority( const AmbientInfo& ambientInfo, u32 soundId  );
346 
347     // ハンドル関数
348     bool IsAttachedGeneralHandle();
349     bool IsAttachedTempGeneralHandle();
350     virtual bool IsAttachedTempSpecialHandle() = 0;
351     void DetachGeneralHandle();
352     void DetachTempGeneralHandle();
353     virtual void DetachTempSpecialHandle() = 0;
354 
355   protected:
356     virtual driver::BasicSoundPlayer* GetBasicSoundPlayerHandle() = 0;
357 
OnUpdatePlayerPriority()358     virtual void OnUpdatePlayerPriority() {}
359 
360     virtual void UpdateMoveValue();
361     virtual void UpdateParam();
362 
IsStarted()363     bool IsStarted() const { return m_StartedFlag; } // for SeqSound
IsPlayerAvailable()364     bool IsPlayerAvailable() const { return m_PlayerAvailableFlag; }
365 
366   private:
367     //-----------------------------------------------------------------------------
368     // PauseState状態遷移
369     //
370     // state \ event | pause   | unpause   | fade-finish
371     // --------------+---------+-----------+--------------
372     // normal        | pausing |  -        |  -
373     // pausing       | pausing | unpausing | paused
374     // paused        |  -      | unpausing |  -
375     // unpausing     | pausing | unpausing | normal
376     //
377     enum PauseState
378     {
379         PAUSE_STATE_NORMAL,
380         PAUSE_STATE_PAUSING,
381         PAUSE_STATE_PAUSED,
382         PAUSE_STATE_UNPAUSING
383     };
384 
385     PlayerHeap* m_pPlayerHeap;
386     SoundHandle* m_pGeneralHandle;
387     SoundHandle* m_pTempGeneralHandle;
388     SoundPlayer* m_pSoundPlayer;
389     SoundActor* m_pSoundActor;
390     ExternalSoundPlayer* m_pExtSoundPlayer;
391 
392     AmbientInfo m_AmbientInfo;
393     SoundParam m_AmbientParam;
394     SoundActorParam m_ActorParam;
395 
396     MoveValue<f32, int> m_FadeVolume;
397     MoveValue<f32, int> m_PauseFadeVolume;
398 
399     bool m_InitializeFlag;
400     bool m_StartFlag;
401     bool m_StartedFlag;
402     bool m_AutoStopFlag;
403     bool m_FadeOutFlag;
404     bool m_PlayerAvailableFlag;
405 
406     PlayerState m_PlayerState;
407     PauseState m_PauseState;
408     bool m_UnPauseFlag;
409 
410     s32 m_AutoStopCounter;
411     u32 m_UpdateCounter;
412 
413     u8 m_Priority;
414     u8 m_BiquadFilterType;
415     u32 m_Id;
416 
417     MoveValue<f32, int> m_ExtMoveVolume;
418     f32 m_InitVolume;
419     f32 m_ExtPan;
420     f32 m_ExtPitch;
421     f32 m_LpfFreq;
422     f32 m_BiquadFilterValue;
423     f32 m_MainSend;
424     f32 m_FxSend[ AUX_BUS_NUM ];
425     f32 m_ExtSurroundPan;
426 
427   public:
428     ut::LinkListNode m_PriorityLink; // for SoundInstanceManager
429     ut::LinkListNode m_SoundPlayerPlayLink;
430     ut::LinkListNode m_SoundPlayerPriorityLink;
431     ut::LinkListNode m_ExtSoundPlayerPlayLink;
432 };
433 
434 
435 
436 class BasicSound::AmbientParamUpdateCallback
437 {
438   public:
~AmbientParamUpdateCallback()439     virtual ~AmbientParamUpdateCallback() {}
440     virtual void detail_UpdateAmbientParam(
441         const void* arg,
442         u32 soundId,
443         SoundAmbientParam* param
444     ) = 0;
445     virtual int detail_GetAmbientPriority(
446         const void* arg,
447         u32 soundId
448     ) = 0;
449 };
450 
451 class BasicSound::AmbientArgUpdateCallback
452 {
453   public:
~AmbientArgUpdateCallback()454     virtual ~AmbientArgUpdateCallback() {}
455     virtual void detail_UpdateAmbientArg(
456         void* arg,
457         const internal::BasicSound* sound
458     ) = 0;
459 };
460 
461 class BasicSound::AmbientArgAllocatorCallback
462 {
463   public:
~AmbientArgAllocatorCallback()464     virtual ~AmbientArgAllocatorCallback() {}
465     virtual void* detail_AllocAmbientArg( size_t argSize ) = 0;
466     virtual void detail_FreeAmbientArg(
467         void* arg,
468         const internal::BasicSound* sound
469     ) = 0;
470 };
471 
472 
473 } // namespace nw::snd::internal
474 } // namespace nw::snd
475 } // namespace nw
476 
477 
478 #endif /* NW_SND_BASIC_SOUND_H_ */
479 
480