1 /*---------------------------------------------------------------------------*
2   Project:  NintendoWare
3   File:     snd_SoundActor.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_SoundActor.h
18  *
19  * @file snd_SoundActor.h
20  */
21 
22 #ifndef NW_SND_SOUND_ACTOR_H_
23 #define NW_SND_SOUND_ACTOR_H_
24 
25 #include <nw/snd/snd_SoundStartable.h>
26 #include <nw/snd/snd_ExternalSoundPlayer.h>
27 #include <nw/snd/snd_BasicSound.h>          // SoundActorParam
28 
29 namespace nw {
30 namespace snd {
31 
32 class SoundHandle;
33 class SoundArchivePlayer;
34 
35 //---------------------------------------------------------------------------
36 //! @brief    複数のサウンドをまとめて再生管理するためのクラスです。
37 //!
38 //!           サウンドアクターは、
39 //!           ゲーム内でキャラクターやモデル等に関連付けて使用されることが想定されています。
40 //!           例えばキャラクタの移動にあわせて、
41 //!           そのキャラクタに関連付けられたサウンドアクターの音の定位を変更する、
42 //!           といった使い方が可能です。
43 //!
44 //!           サウンドアクターに設定するパラメータは、
45 //!           そのサウンドアクターで再生する全てのサウンドに対して効果があります。
46 //!
47 //!           サウンドアクターは内部に 4 つのアクタープレイヤーを持っています。
48 //!           このアクタープレイヤーごとに同時に再生できるサウンド数を制限することができます。
49 //!           設定したサウンド数を超えた場合には、
50 //!           各サウンドに設定されたプレイヤープライオリティを比較して、
51 //!           もっとも優先度が低いサウンドが停止します。
52 //!           同時に再生可能なサウンド数の初期値は下記のように設定されています。
53 //!
54 //!           ・アクタープレイヤー 0 番は無制限 \n
55 //!           ・その他は 1
56 //!
57 //!           サウンドがどのアクタープレイヤーで再生されるかは、
58 //!           サウンドデータに設定されています。
59 //!           この情報は再生時に @ref nw::snd::SoundStartable::StartInfo を用いて、
60 //!           上書きすることができます。
61 //!
62 //! @see SoundStartable クラス
63 //!
64 //! @date 2010/04/08 文言の微調整
65 //! @date 2010/02/23 初版
66 //---------------------------------------------------------------------------
67 class SoundActor : public SoundStartable
68 {
69     typedef internal::ExternalSoundPlayer ActorPlayer;
70 
71   public:
72     //---------------------------------------------------------------------------
73     //! @brief    アクタープレイヤーの保持数です。
74     //!
75     //! @date 2010/02/23 初版
76     //---------------------------------------------------------------------------
77     static const int ACTOR_PLAYER_COUNT = 4;
78 
79     //----------------------------------------
80     //! @name コンストラクタ/デストラクタ
81     //@{
82     //---------------------------------------------------------------------------
83     //! @brief    コンストラクタです。
84     //!
85     //!           初期化時には、プレイヤーの音量が 1.0、ピッチが 1.0、パンが 0.0、
86     //!           同時に再生可能なサウンド数が 1 に設定されます。
87     //!
88     //!           引数付きのコンストラクタの場合は、
89     //!           @ref Initialize を呼ぶ必要はありません
90     //!           (呼んでも問題ありません)。
91     //!
92     //! @param[in] soundArchivePlayer 再生に使用するサウンドアーカイブプレイヤーです。
93     //!
94     //! @see Initialize
95     //!
96     //! @date 2010/03/05 Initialize に関する注意を追記
97     //! @date 2010/02/23 初版
98     //---------------------------------------------------------------------------
99     SoundActor( SoundArchivePlayer& soundArchivePlayer );
100 
101     //---------------------------------------------------------------------------
102     //! @brief    コンストラクタです。
103     //!
104     //!           初期化時には、プレイヤーの音量が 1.0、ピッチが 1.0、パンが 0.0、
105     //!           同時に再生可能なサウンド数が 1 に設定されます。
106     //!
107     //!           引数なしのコンストラクタは、@ref Initialize を呼ぶ必要があります。
108     //!
109     //! @see Initialize
110     //!
111     //! @date 2010/03/05 初版
112     //---------------------------------------------------------------------------
113     SoundActor();
114 
115     //---------------------------------------------------------------------------
116     //! @brief    デストラクタです。
117     //!
118     //!           内部で、@ref Finalize を呼んでいます。
119     //!
120     //! @see Finalize
121     //!
122     //! @date 2010/03/05 Finalize を呼ぶ旨、追記
123     //! @date 2010/02/23 初版
124     //---------------------------------------------------------------------------
125     virtual ~SoundActor();
126     //@}
127 
128     //----------------------------------------
129     //! @name 初期化
130     //@{
131     //---------------------------------------------------------------------------
132     //! @brief    サウンドアクターを初期化します。
133     //!
134     //!           サウンドアクターを使用する前に、初期化を行う必要があります。
135     //!           ただし、引数付きコンストラクタを呼んでいる場合は、
136     //!           呼ぶ必要はありません (呼んでも問題ありません)。
137     //!
138     //!           Sound3DActor の初期化には、本関数ではなく、
139     //!           @ref SoundArchivePlayer と @ref Sound3DManager を引数に取る、
140     //!           @ref Sound3DActor::Initialize を呼ぶ必要があります。
141     //!
142     //!           同じ SoundActor インスタンスを再利用するには、
143     //!           あらかじめ @ref Finalize 関数を呼んでから、
144     //!           再度、本関数を呼び出してください。
145     //!
146     //! @param[in] soundArchivePlayer 再生に使用するサウンドアーカイブプレイヤーです。
147     //!
148     //! @see SoundArchivePlayer クラス
149     //! @see SoundActor()
150     //! @see Finalize
151     //!
152     //! @date 2010/04/27 再利用に関する記述を追記
153     //! @date 2010/03/12 参照に SoundArchivePlayer クラス、Finalize を追加
154     //! @date 2010/03/05 初版
155     //---------------------------------------------------------------------------
156     void Initialize( SoundArchivePlayer& soundArchivePlayer );
157 
158     //---------------------------------------------------------------------------
159     //! @brief    サウンドアクターを破棄します。
160     //!
161     //!           デストラクタの中で呼ばれますが、
162     //!           明示的に呼んでも問題ありません。
163     //!
164     //!           同じ SoundActor インスタンスを再利用するには、
165     //!           本関数を呼んだ後、再度 @ref Initialize 関数を呼び出してください。
166     //!
167     //! @see ~SoundActor
168     //! @see Initialize
169     //!
170     //! @date 2010/04/27 再利用に関する記述を追記
171     //! @date 2010/03/12 参照に Initialize を追加
172     //! @date 2010/03/05 初版
173     //---------------------------------------------------------------------------
174     void Finalize();
175     //@}
176 
177     //----------------------------------------
178     //! @name 再生
179     //@{
180   public:
181     //---------------------------------------------------------------------------
182     //! @brief    アクターで再生中の全てのサウンドを停止します。
183     //!
184     //!           各サウンドに対して、ハンドルクラスを通して停止させたときと同様の処理を行います。
185     //!
186     //!           fadeFrames で指定したフレーム数をかけてフェードアウトさせることができます。
187     //!           0 を指定した場合は、フェードアウトを行いません。
188     //!           ただし、シーケンスサウンドで発音中の音は、
189     //!           エンベロープのリリースを発音し全ての減衰が完了した後にサウンドが停止します。
190     //!
191     //!           フェードアウトの音量制御は、フェードインと共有されます。
192     //!           フェードアウトにかかるフレーム数は、
193     //!           最大音量から音が消えるまでにかかる変化速度を表しますので、
194     //!           フェードイン中にフェードアウトを指定した時などは、
195     //!           指定したフレーム数よりも短い時間でフェードアウトが完了する可能性があります。
196     //!
197     //! @param[in] fadeFrames フェードアウトにかけるフレーム数です。
198     //!
199     //! @date 2010/02/23 初版
200     //---------------------------------------------------------------------------
201     void StopAllSound( int fadeFrames );
202 
203     //---------------------------------------------------------------------------
204     //! @brief    アクターで再生中の全てのサウンドを一時停止・再開します。
205     //!
206     //!           各サウンドに対して、ハンドルクラスを通して一時停止・
207     //!           再開させたときと同様の処理を行います。
208     //!
209     //!           一時停止・再開時のフェードは、再生開始時のフェードイン、
210     //!           停止時のフェードアウトとは独立してはたらきます。
211     //!
212     //! @param[in] flag   true なら一時停止、false なら再開します。
213     //! @param[in] fadeFrames     フェードイン・フェードアウトにかけるフレーム数です。
214     //!
215     //! @date 2010/02/23 初版
216     //---------------------------------------------------------------------------
217     void PauseAllSound( bool flag, int fadeFrames );
218 
219   protected:
220     //---------------------------------------------------------------------------
221     //! @brief    サウンドを再生する際に呼び出される仮想関数です。
222     //!
223     //!           この関数をオーバーライドすることにより、
224     //!           サウンドを再生するときの処理をカスタマイズすることができます。
225     //!
226     //!           setupArg は @ref SoundActor::SetupSound を呼び出す際に、
227     //!           そのまま引数として渡します。
228     //!
229     //! @param[in] handle     再生するサウンドと関連付けられるハンドルです。
230     //! @param[in] soundId    再生するサウンドの ID です。
231     //! @param[in] startInfo  詳細な再生パラメータです。
232     //! @param[in] setupArg   セットアップ時に使用されるパラメータです。
233     //!
234     //! @return   再生処理の結果を @ref SoundStartable::StartResult 型で返します。
235     //!
236     //! @see SoundHandle クラス
237     //! @see SoundStartable::StartResult
238     //! @see SoundStartable::StartInfo
239     //!
240     //! @date 2010/02/23 初版
241     //---------------------------------------------------------------------------
242     virtual SoundStartable::StartResult SetupSound(
243         SoundHandle* handle,
244         u32 soundId,
245         const SoundStartable::StartInfo* startInfo,
246         void* setupArg
247     );
248     //@}
249     // TODO: 継承する場合のサンプルコードが書けない。
250 
251   public:
252     //----------------------------------------
253     //! @name パラメータ設定・取得
254     //@{
255 
256     //---------------------------------------------------------------------------
257     //! @brief    アクターの音量を変更します。
258     //!
259     //!           アクターの音量は、アクターで再生する全てのサウンドに対して効果があります。
260     //!
261     //!           この関数で指定する値は、他のどの音量パラメータとも独立して動作し、
262     //!           それらは全て重ね合わされます。
263     //!
264     //!           音量 volume は、0.0 から 1.0 の倍率で指定します。
265     //!           すなわち、1.0 を指定すると音量に影響を与えません。
266     //!           0.0 を指定すると発音されなくなります。デフォルト値は 1.0 です。
267     //!
268     //! @param[in] volume 変更する音量の倍率 ( 0.0 ~ 1.0 ) です。
269     //!
270     //! @see GetVolume
271     //!
272     //! @date 2010/02/23 初版
273     //---------------------------------------------------------------------------
SetVolume(f32 volume)274     void SetVolume( f32 volume ) { m_ActorParam.volume = volume; }
275 
276     //---------------------------------------------------------------------------
277     //! @brief    アクターに設定されている音量を取得します。
278     //!
279     //! @return   現在の音量を返します。
280     //!
281     //! @see SetVolume
282     //!
283     //! @date 2010/02/23 初版
284     //---------------------------------------------------------------------------
GetVolume()285     f32 GetVolume() const { return m_ActorParam.volume; }
286 
287     //---------------------------------------------------------------------------
288     //! @brief    アクターの音程を変更します。
289     //!
290     //!           アクターの音程は、アクターで再生する全てのサウンドに対して効果があります。
291     //!
292     //!           この関数で指定する値は、他のどの音程パラメータとも独立して動作し、
293     //!           それらは全て重ね合わされます。
294     //!
295     //!           音程 pitch は、周波数の比率で指定します。
296     //!           すなわち、1.0 を指定すると音程に影響を与えません。
297     //!           2.0 を指定すると再生される周波数が 2 倍になり、1 オクターブ高い音程になります。
298     //!           0.5 を指定すると 1 オクターブ低い音程になります。
299     //!           デフォルト値は 1.0 です。
300     //!
301     //! @param[in] pitch 変更する音程の周波数比率です。
302     //!
303     //! @see GetPitch
304     //!
305     //! @date 2010/02/23 初版
306     //---------------------------------------------------------------------------
SetPitch(f32 pitch)307     void SetPitch( f32 pitch ) { m_ActorParam.pitch = pitch; }
308 
309     //---------------------------------------------------------------------------
310     //! @brief    アクターに設定されている音程を取得します。
311     //!
312     //! @return   現在の音程を返します。
313     //!
314     //! @see SetPitch
315     //!
316     //! @date 2010/02/23 初版
317     //---------------------------------------------------------------------------
GetPitch()318     f32 GetPitch() const { return m_ActorParam.pitch; }
319 
320     //---------------------------------------------------------------------------
321     //! @brief    アクターのパン ( 左右の定位 ) を変更します。
322     //!
323     //!           アクターのパンは、アクターで再生する全てのサウンドに対して効果があります。
324     //!
325     //!           この関数で指定する値は、他のどのパンパラメータとも独立して動作し、
326     //!           それらは全て重ね合わされます。
327     //!
328     //!           pan は、定位の相対変化の値を設定します。
329     //!           0.0 を指定するとデータで設定されたパンの値から変化しません。
330     //!           1.0 を指定すると中央に定位していた音が右端に定位するようになり、
331     //!           -1.0 を指定すると中央に定位していた音が左端に定位するようになります。
332     //!           デフォルト値は 0.0 です。
333     //!
334     //! @param[in] pan 0.0 を基準としたパンの相対変化の値です。
335     //!
336     //! @see GetPan
337     //!
338     //! @date 2010/02/23 初版
339     //---------------------------------------------------------------------------
SetPan(f32 pan)340     void SetPan( f32 pan ) { m_ActorParam.pan = pan; }
341 
342     //---------------------------------------------------------------------------
343     //! @brief    アクターに設定されているパンを取得します。
344     //!
345     //! @return   現在のパンを返します。
346     //!
347     //! @see SetPan
348     //!
349     //! @date 2010/02/23 初版
350     //---------------------------------------------------------------------------
GetPan()351     f32 GetPan() const { return m_ActorParam.pan; }
352 
353     //---------------------------------------------------------------------------
354     //! @brief    アクタープレイヤーで現在再生中のサウンドの個数を取得します。
355     //!
356     //! @param[in] actorPlayerId アクタープレイヤー番号です。
357     //!
358     //! @return   アクタープレイヤーで再生中のサウンド数を返します。
359     //!
360     //! @date 2010/02/23 初版
361     //---------------------------------------------------------------------------
362     int GetPlayingSoundCount( int actorPlayerId ) const;
363 
364     //---------------------------------------------------------------------------
365     //! @brief    同時に再生可能なサウンド数を設定します。
366     //!
367     //!           サウンドアクターは、アクター内に 4 個のアクタープレイヤーを持っています。
368     //!           このアクタープレイヤーごとに、同時に再生可能なサウンド数制限を設定することができます。
369     //!           この設定は、サウンドプレイヤーで設定されている同時再生サウンド数とは別に、
370     //!           独立してはたらきます。
371     //!
372     //!           設定したサウンド数を超えるサウンドを再生しようとすると、
373     //!           各サウンドに設定されたプレイヤープライオリティを比較して、
374     //!           もっとも優先度が低いサウンドが停止します。
375     //!
376     //!           初期値はアクタープレイヤー 0 番は無制限で、その他は 1 に設定されています。
377     //!
378     //! @param[in] actorPlayerId  アクタープレイヤー番号です。
379     //! @param[in] count          同時に再生可能なサウンド数です。
380     //!
381     //! @see GetPlayableSoundCount
382     //!
383     //! @date 2010/02/23 初版
384     //---------------------------------------------------------------------------
385     void SetPlayableSoundCount( int actorPlayerId, int count );
386 
387     //---------------------------------------------------------------------------
388     //! @brief    アクタープレイヤーで同時に再生可能なサウンド数を取得します。
389     //!
390     //! @param[in] actorPlayerId  アクタープレイヤー番号です。
391     //!
392     //! @return   アクタープレイヤーで同時に再生可能なサウンド数を返します。
393     //!
394     //! @see SetPlayableSoundCount
395     //!
396     //! @date 2010/02/23 初版
397     //---------------------------------------------------------------------------
398     int GetPlayableSoundCount( int actorPlayerId ) const;
399     //@}
400 
401     //----------------------------------------
402     //! @name その他
403     //@{
404     //---------------------------------------------------------------------------
405     //! @brief    アクターで再生中の全てのサウンドに対して処理を行います。
406     //!
407     //!           アクターで再生中の全てのサウンドに対して、
408     //!           function( nw::snd::SoundHandle& handle )
409     //!           を呼び出します。
410     //!
411     //!           function には、再生中のサウンドに関連付けられたサウンドハンドル
412     //!           handle が渡されます。これは一時的なハンドルですので、
413     //!           ハンドルを後で使用することはできません。
414     //!
415     //!           関数 function は、サウンドの再生が古い順に呼び出されます。
416     //!           reverse に true を指定すると、サウンドの再生が新しい順に呼び出されます。
417     //!
418     //!           function には関数ポインタ、または関数オブジェクトを渡します。
419     //!
420     //! @tparam Function 関数ポインタ、または関数オブジェクトの型です。
421     //!
422     //! @param[in] function   関数ポインタ、または関数オブジェクトです。
423     //! @param[in] reverse    処理順を逆にする場合は true を指定します。
424     //!
425     //! @return   引数に指定された関数ポインタ、または関数オブジェクトです。
426     //!
427     //! @date 2010/02/23 初版
428     //---------------------------------------------------------------------------
429     template< class Function >
430     Function ForEachSound( Function function, bool reverse = false );
431     //@}
432 
433 
434     //-----------------------------------------------------------------------------
435     //  internal functions
436 
437     //! @details :private
detail_GetActorPlayer(int actorPlayerId)438     ActorPlayer* detail_GetActorPlayer( int actorPlayerId ) {
439         if ( actorPlayerId < 0 || ACTOR_PLAYER_COUNT <= actorPlayerId ) return NULL;
440         return &m_ActorPlayer[actorPlayerId];
441     }
442 
443     //! @details :private
detail_GetActorParam()444     const internal::SoundActorParam& detail_GetActorParam() const { return m_ActorParam; }
445 
446     //! @details :private
447     virtual SoundStartable::StartResult detail_SetupSoundWithAmbientInfo(
448         SoundHandle* handle,
449         u32 soundId,
450         const SoundStartable::StartInfo* startInfo,
451         internal::BasicSound::AmbientInfo* ambientInfo,
452         void* setupArg
453     );
454 
455   private:
456     virtual SoundStartable::StartResult detail_SetupSound(
457         SoundHandle* handle,
458         u32 soundId,
459         bool holdFlag,
460         const SoundStartable::StartInfo* startInfo
461     );
462     virtual SoundArchive::ItemId detail_GetItemId( const char* pString );
463 
464     struct SetupInfo
465     {
466         bool holdFlag;
467     };
468 
469     SoundArchivePlayer* m_pSoundArchivePlayer;
470     ActorPlayer m_ActorPlayer[ ACTOR_PLAYER_COUNT ];
471     internal::SoundActorParam m_ActorParam;
472 
473     bool m_IsInitialized;
474     bool m_IsFinalized;
475 };
476 
477 template< class Function >
ForEachSound(Function function,bool reverse)478 inline Function SoundActor::ForEachSound( Function function, bool reverse )
479 {
480     for ( int actorPlayerIndex = 0; actorPlayerIndex < ACTOR_PLAYER_COUNT; actorPlayerIndex++ )
481     {
482         m_ActorPlayer[ actorPlayerIndex ].ForEachSound<Function>( function, reverse );
483     }
484 
485     return function;
486 }
487 
488 } // namespace nw::snd
489 } // namespace nw
490 
491 
492 #endif /* NW_SND_SOUND_ACTOR_H_ */
493 
494