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