1 /*---------------------------------------------------------------------------*
2 Project: NintendoWare
3 File: snd_SoundPlayer.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: 27551 $
14 *---------------------------------------------------------------------------*/
15
16 /**
17 * :include nw/snd/snd_SoundPlayer.h
18 *
19 * @file snd_SoundPlayer.h
20 */
21
22 #ifndef NW_SND_SOUND_PLAYER_H_
23 #define NW_SND_SOUND_PLAYER_H_
24
25 #include <nw/ut/ut_LinkList.h>
26 #include <nw/snd/snd_BasicSound.h>
27 #include <nw/snd/snd_PlayerHeap.h>
28
29 namespace nw {
30 namespace snd {
31
32
33 //---------------------------------------------------------------------------
34 //! @brief サウンドを再生するためのプレイヤークラスです。
35 //!
36 //! SoundPlayer クラスのインスタンスは
37 //! @ref SoundArchivePlayer::GetSoundPlayer を呼び出して取得してください。
38 //!
39 //! 一つの SoundPlayer で複数のサウンドを再生することができます。
40 //! 同時に再生できるサウンド数を設定することができ、
41 //! そのサウンド数を超えた場合には、
42 //! 各サウンドに設定されたプレイヤープライオリティを比較して、
43 //! もっとも優先度が低いサウンドが停止します。
44 //!
45 //! @see SoundArchivePlayer クラス
46 //! @see SoundArchivePlayer::GetSoundPlayer
47 //!
48 //! @date 2010/01/15 初版
49 //---------------------------------------------------------------------------
50 class SoundPlayer
51 {
52 public:
53 //! @details :private
54 typedef ut::LinkList<
55 internal::PlayerHeap,
56 offsetof(internal::PlayerHeap,m_Link)
57 > PlayerHeapList;
58
59 //! @details :private
60 typedef ut::LinkList<
61 internal::BasicSound,
62 offsetof(internal::BasicSound,m_SoundPlayerPlayLink)
63 > SoundList;
64
65 //! @details :private
66 typedef ut::LinkList<
67 internal::BasicSound,
68 offsetof(internal::BasicSound,m_SoundPlayerPriorityLink)
69 > PriorityList;
70
71 public:
72
73 //----------------------------------------
74 //! @name コンストラクタ/デストラクタ
75 //@{
76 //---------------------------------------------------------------------------
77 //! @brief コンストラクタです。
78 //
79 //! @date 2010/01/15 初版
80 //---------------------------------------------------------------------------
81 SoundPlayer();
82
83 //---------------------------------------------------------------------------
84 //! @brief デストラクタです。
85 //
86 //! @date 2010/01/15 初版
87 //---------------------------------------------------------------------------
88 ~SoundPlayer();
89 //@}
90
91 //----------------------------------------
92 //! @name 更新
93 //@{
94 //---------------------------------------------------------------------------
95 //! @brief サウンドプレイヤーの更新処理を行います。
96 //!
97 //! @ref SoundArchivePlayer クラスを使用している場合は、
98 //! この関数は @ref SoundArchivePlayer::Update から呼び出されます。
99 //!
100 //! @see SoundArchivePlayer クラス
101 //! @see SoundArchivePlayer::Update
102 //
103 //! @date 2010/01/15 初版
104 //---------------------------------------------------------------------------
105 void Update();
106 //@}
107
108 //----------------------------------------
109 //! @name 再生制御
110 //@{
111 //---------------------------------------------------------------------------
112 //! @brief 全てのサウンドを停止します。
113 //!
114 //! プレイヤーで再生中の全てのサウンドを停止します。
115 //! 各サウンドに対して、
116 //! ハンドルクラスを通して停止させたときと同様の処理を行います。
117 //!
118 //! fadeFrames で指定したフレーム数をかけて、
119 //! フェードアウトさせることができます。
120 //! 0 を指定した場合は、フェードアウトを行いません。
121 //! ただし、シーケンスサウンドで発音中の音は、
122 //! エンベロープのリリースを発音し全ての減衰が完了した後に
123 //! サウンドが停止します。
124 //!
125 //! フェードアウトの音量制御は、フェードインと共有されます。
126 //! フェードアウトにかかるフレーム数は、
127 //! 最大音量から音が消えるまでにかかる変化速度を表しますので、
128 //! フェードイン中にフェードアウトを指定した時などは、
129 //! 指定したフレーム数よりも短い時間で
130 //! フェードアウトが完了する可能性があります。
131 //!
132 //! @param[in] fadeFrames フェードアウトにかけるフレーム数です。
133 //
134 //! @date 2010/01/15 初版
135 //---------------------------------------------------------------------------
136 void StopAllSound( int fadeFrames );
137
138 //---------------------------------------------------------------------------
139 //! @brief 全てのサウンドを一時停止・再開します。
140 //!
141 //! プレイヤーで再生中の全てのサウンドを一時停止または再開します。
142 //! 各サウンドに対して、
143 //! ハンドルクラスを通して一時停止・再開させたときと同様の処理を行います。
144 //!
145 //! 一時停止・再開時のフェードは、再生開始時のフェードイン、
146 //! 停止時のフェードアウトとは独立してはたらきます。
147 //!
148 //! @param[in] flag true なら一時停止、false なら再開。
149 //! @param[in] fadeFrames フェードイン・フェードアウトにかけるフレーム数。
150 //
151 //! @date 2010/01/15 初版
152 //---------------------------------------------------------------------------
153 void PauseAllSound( bool flag, int fadeFrames );
154 //@}
155
156 //----------------------------------------
157 //! @name パラメータ設定・取得
158 //@{
159 //---------------------------------------------------------------------------
160 //! @brief プレイヤーの音量を変更します。
161 //!
162 //! プレイヤーの音量は、
163 //! プレイヤーで再生中の全てのサウンドに対して効果があります。
164 //!
165 //! この関数で指定する値は、
166 //! サウンドに設定される他のどの音量パラメータとも独立して動作し、
167 //! それらは全て重ね合わされます。
168 //!
169 //! 音量 volume は、0.0 以上の倍率で指定します。
170 //! すなわち、1.0 を指定すると音量に影響を与えません。
171 //! 0.0 を指定すると発音されなくなります。
172 //! デフォルト値は 1.0 です。
173 //!
174 //! 他の音量パラメータと重ね合わされたあと、
175 //! 最終的な音量は 0.0 ~ 2.0 の範囲でクランプされます。
176 //! この関数で 2.0 を設定したとしても、
177 //! 元の音量の 2 倍にならない可能性があることに注意してください。
178 //!
179 //! @param[in] volume プレイヤーの音量の倍率( 0.0 ~ )です。
180 //!
181 //! @see GetVolume
182 //
183 //! @date 2010/01/15 初版
184 //---------------------------------------------------------------------------
185 void SetVolume( float volume );
186 //---------------------------------------------------------------------------
187 //! @brief プレイヤーの音量を取得します。
188 //!
189 //! @return プレイヤーに設定されている現在の音量を返します。
190 //!
191 //! @see SetVolume
192 //
193 //! @date 2010/01/15 初版
194 //---------------------------------------------------------------------------
GetVolume()195 float GetVolume() const { return m_Volume; }
196
197 // ローパスフィルタのカットオフ周波数を変化させる
198 //! @details :private
199 void SetLpfFreq( float lpfFreq );
200 //! @details :private
GetLpfFreq()201 float GetLpfFreq() const { return m_LpfFreq; }
202
203 // Biquadフィルタを設定する
204 //! @details :private
205 void SetBiquadFilter( int type, float value );
206 //! @details :private
GetBiquadFilterType()207 int GetBiquadFilterType() const { return m_BiquadType; }
208 //! @details :private
GetBiquadFilterValue()209 float GetBiquadFilterValue() const { return m_BiquadValue; }
210
211 //---------------------------------------------------------------------------
212 //! @brief プレイヤーのメイン出力へのセンド量を変更します。
213 //!
214 //! プレイヤーのメイン出力へのセンド量は、
215 //! プレイヤーで再生中の全てのサウンドに対して効果があります。
216 //!
217 //! この関数で指定する値は、
218 //! サウンドに設定される他のどの音量パラメータとも独立して動作し、
219 //! それらはすべて重ね合わされます。
220 //!
221 //! メインセンドは、メイン出力に送るサウンドの音量を調節するパラメータです。
222 //! 主に、エフェクトのドライ・ウェット成分のバランスを調整するために使用されます。
223 //!
224 //! センド量 send は、相対変化の値を指定します。
225 //! すなわち、0.0 を指定するとセンド量を変更しません。
226 //! -1.0 を指定するとメインバスに最大のセンド量で送られていたサウンドが
227 //! メインバスに送られないようになります。 デフォルト値は 0.0 です。
228 //!
229 //! @param[in] send 0.0 を基準としたセンド量の相対変化の値です。
230 //!
231 //! @see GetMainSend
232 //! @see SetFxSend
233 //!
234 //! @date 2010/06/30 初版
235 //---------------------------------------------------------------------------
236 void SetMainSend( float send );
237
238 //---------------------------------------------------------------------------
239 //! @brief プレイヤーに設定されているメイン出力へのセンド量を取得します。
240 //!
241 //! @return 現在のメイン出力へのセンド量を返します。
242 //!
243 //! @see SetMainSend
244 //!
245 //! @date 2010/06/30 初版
246 //---------------------------------------------------------------------------
GetMainSend()247 float GetMainSend() const { return m_MainSend; }
248
249 //---------------------------------------------------------------------------
250 //! @brief プレイヤーのエフェクトへのセンド量を変更します。
251 //!
252 //! プレイヤーのエフェクトへのセンド量は、
253 //! プレイヤーで再生中の全てのサウンドに対して効果があります。
254 //!
255 //! この関数で指定する値は、
256 //! サウンドに設定される他のどの音量パラメータとも独立して動作し、
257 //! それらはすべて重ね合わされます。
258 //!
259 //! センド量 send は、相対変化の値を指定します。
260 //! すなわち、0.0 を指定するとセンド量を変更しません。
261 //! 1.0 を指定すると AUX バスに送られていなかったサウンドが
262 //! 最大のセンド量で送られるようになります。 デフォルト値は 0.0 です。
263 //!
264 //! @param[in] bus センド量を設定する AUX バスです。
265 //! @param[in] send 0.0 を基準としたセンド量の相対変化の値です。
266 //!
267 //! @see AuxBus
268 //! @see GetFxSend
269 //! @see SetMainSend
270 //!
271 //! @date 2010/06/30 初版
272 //---------------------------------------------------------------------------
273 void SetFxSend( AuxBus bus, float send );
274
275 //---------------------------------------------------------------------------
276 //! @brief プレイヤーに設定されているエフェクトへのセンド量を取得します。
277 //!
278 //! @return 現在のエフェクトへのセンド量を返します。
279 //!
280 //! @param[in] bus センド量を設定する AUX バスです。
281 //!
282 //! @see AuxBus
283 //! @see SetFxSend
284 //!
285 //! @date 2010/06/30 初版
286 //---------------------------------------------------------------------------
GetFxSend(AuxBus bus)287 float GetFxSend( AuxBus bus ) const { return m_FxSend[ bus ]; }
288
289
290 //---------------------------------------------------------------------------
291 //! @brief プレイヤーで現在再生中のサウンドの個数を取得します。
292 //!
293 //! @return プレイヤーで再生中のサウンド数を返します。
294 //!
295 //! @date 2010/06/30 初版
296 //---------------------------------------------------------------------------
GetPlayingSoundCount()297 int GetPlayingSoundCount() const { return static_cast<int>( m_SoundList.GetSize()); }
298
299 //---------------------------------------------------------------------------
300 //! @brief 同時に再生可能なサウンド数を設定します。
301 //!
302 //! 設定したサウンド数を超えるサウンドを再生しようとすると、
303 //! 各サウンドに設定されたプレイヤープライオリティを比較して、
304 //! もっとも優先度が低いサウンドが停止します。
305 //!
306 //! @ref SoundArchivePlayer クラスを使用する場合は、
307 //! サウンドアーカイブ中で指定されている同時再生数が初期化時に自動的に設定されます。
308 //!
309 //! プレイヤーヒープを使用している場合、
310 //! この関数で指定できる同時再生数の上限値は、
311 //! セットアップ時に設定された同時再生数の値に制限されます。
312 //! 上限値を超える値を指定しても上限値に丸め込まれます。
313 //!
314 //! @param[in] count 同時に再生可能なサウンド数です。
315 //!
316 //! @see SoundArchivePlayer クラス
317 //! @see GetPlayableSoundCount
318 //!
319 //! @date 2010/11/19 誤植修正 (desu→です)
320 //! @date 2010/06/30 初版
321 //---------------------------------------------------------------------------
322 void SetPlayableSoundCount( int count );
323
324 //---------------------------------------------------------------------------
325 //! @brief プレイヤーで同時に再生可能なサウンド数を取得します。
326 //!
327 //! @return プレイヤーで同時に再生可能なサウンド数を返します。
328 //!
329 //! @see SetPlayableSoundCount
330 //!
331 //! @date 2010/06/30 初版
332 //---------------------------------------------------------------------------
GetPlayableSoundCount()333 int GetPlayableSoundCount() const { return m_PlayableCount; }
334 //@}
335
336 //----------------------------------------
337 //! @name その他
338 //@{
339 //---------------------------------------------------------------------------
340 //! @brief プレイヤーで再生中の全てのサウンドに対して処理を行います。
341 //!
342 //! プレイヤーで再生中の全てのサウンドに対して、
343 //!
344 //! function( nw::snd::SoundHandle& handle )
345 //!
346 //! を呼び出します。 function には、
347 //! 再生中のサウンドに関連付けられたサウンドハンドル handle が渡されます。
348 //! これは一時的なハンドルですので、ハンドルを後で使用することはできません。
349 //!
350 //! 関数 function は、サウンドの再生が古い順に呼び出されます。
351 //! reverse に true を指定すると、サウンドの再生が新しい順に呼び出されます。
352 //!
353 //! function には関数ポインタ、または関数オブジェクトを渡します。
354 //! 関数ポインタを渡す例を以下に示します。
355 //!
356 //! void ReportSoundId( nw::snd::SoundHandle& handle ) {
357 //! NN_LOG( "%d\n", handle.GetId() );
358 //! } @n
359 //! soundPlayer.ForEachSound( ReportSoundId );
360 //!
361 //! @param[in] function 関数ポインタ、または関数オブジェクトです。
362 //! @param[in] reverse 処理順を逆にする場合は true を指定します。
363 //!
364 //! @return 引数に指定された関数ポインタ、または関数オブジェクトを返します。
365 //!
366 //! @see SoundHandle クラス
367 //! @see ForEachSoundPriorityOrder
368 //!
369 //! @date 2010/10/15 誤植修正 (nw4r → nw, OSReport → NN_LOG)
370 //! @date 2010/06/30 初版
371 //---------------------------------------------------------------------------
372 template< class Function >
373 Function ForEachSound( Function function, bool reverse = false );
374
375 //---------------------------------------------------------------------------
376 //! @brief プレイヤーで再生中の全てのサウンドに対してプライオリティ順で処理を行います。
377 //!
378 //! その他の動作仕様は @ref ForEachSound と同じです。
379 //!
380 //! @param[in] function 関数ポインタ、または関数オブジェクトです。
381 //! @param[in] reverse 処理順を逆にする場合は true を指定します。
382 //!
383 //! @return 引数に指定された関数ポインタ、または関数オブジェクトを返します。
384 //!
385 //! @see SoundHandle クラス
386 //! @see ForEachSound
387 //!
388 //! @date 2010/06/30 初版
389 //---------------------------------------------------------------------------
390 template< class Function >
391 Function ForEachSoundPriorityOrder( Function function, bool reverse = false );
392 //@}
393
394 //-----------------------------------------------------------------------------
395 // internal functions
396
397 //! @details :private
398 void detail_SetPlayableSoundLimit( int limit );
399
400 // サウンドの登録
401 //! @details :private
402 bool detail_CanPlaySound( int startPriority );
403 //! @details :private
404 bool detail_AppendSound( internal::BasicSound* pSound );
405 //! @details :private
406 void detail_RemoveSound( internal::BasicSound* pSound );
407
408 // プライオリティリスト
409 //! @details :private
410 void detail_SortPriorityList();
411 //! @details :private
412 void detail_SortPriorityList( internal::BasicSound* pSound );
413
414 // プレイヤーヒープ
415 //! @details :private
416 void detail_AppendPlayerHeap( internal::PlayerHeap* pHeap );
417 //! @details :private
418 void detail_RemovePlayerHeap( internal::PlayerHeap* pHeap );
419
420 //! @details :private
421 internal::PlayerHeap* detail_AllocPlayerHeap( internal::BasicSound* pSound );
422 //! @details :private
423 void detail_FreePlayerHeap( internal::BasicSound* pSound );
424
425 private:
426 //-----------------------------------------------------------------------------
427 // private functions
428
GetLowestPrioritySound()429 internal::BasicSound* GetLowestPrioritySound() { return &m_PriorityList.GetFront(); }
430 void InsertPriorityList( internal::BasicSound* pSound );
431 void RemovePriorityList( internal::BasicSound* pSound );
432 void RemoveSoundList( internal::BasicSound* pSound );
433
434 //-----------------------------------------------------------------------------
435 // private variables
436
437 SoundList m_SoundList;
438 PriorityList m_PriorityList;
439 PlayerHeapList m_PlayerHeapList;
440
441 int m_PlayableCount;
442 int m_PlayableLimit;
443
444 float m_Volume;
445 float m_LpfFreq;
446 int m_BiquadType;
447 float m_BiquadValue;
448 float m_MainSend;
449 float m_FxSend[ AUX_BUS_NUM ];
450 };
451
452
453 template< class Function >
ForEachSound(Function function,bool reverse)454 inline Function SoundPlayer::ForEachSound( Function function, bool reverse )
455 {
456 if ( reverse )
457 {
458 // 再生の新しい順
459 for ( SoundList::ReverseIterator itr = m_SoundList.GetBeginReverseIter();
460 itr != m_SoundList.GetEndReverseIter();
461 )
462 {
463 SoundList::ReverseIterator curItr = itr;
464 SoundHandle handle;
465 handle.detail_AttachSoundAsTempHandle( &( *curItr ) );
466 function( handle );
467 if ( handle.IsAttachedSound() ) itr++;
468 }
469 }
470 else
471 {
472 // 再生の古い順
473 for ( SoundList::Iterator itr = m_SoundList.GetBeginIter();
474 itr != m_SoundList.GetEndIter();
475 )
476 {
477 SoundList::Iterator curItr = itr++;
478 SoundHandle handle;
479 handle.detail_AttachSoundAsTempHandle( &( *curItr ) );
480 function( handle );
481 }
482 }
483 return function;
484 }
485
486 template< class Function >
ForEachSoundPriorityOrder(Function function,bool reverse)487 Function SoundPlayer::ForEachSoundPriorityOrder( Function function, bool reverse )
488 {
489 if ( reverse )
490 {
491 // プライオリティの低い順
492 for ( PriorityList::Iterator itr = m_PriorityList.GetBeginIter();
493 itr != m_PriorityList.GetEndIter();
494 )
495 {
496 PriorityList::Iterator curItr = itr++;
497 SoundHandle handle;
498 handle.detail_AttachSoundAsTempHandle( &( *curItr ) );
499 function( handle );
500 }
501 }
502 else
503 {
504 // プライオリティの高い順
505 for ( PriorityList::ReverseIterator itr = m_PriorityList.GetBeginReverseIter();
506 itr != m_PriorityList.GetEndReverseIter();
507 )
508 {
509 PriorityList::ReverseIterator curItr = itr;
510 SoundHandle handle;
511 handle.detail_AttachSoundAsTempHandle( &( *curItr ) );
512 function( handle );
513 if ( handle.IsAttachedSound() ) itr++;
514 }
515 }
516 return function;
517 }
518
519 } // namespace nw::snd
520 } // namespace nw
521
522
523 #endif /* NW_SND_SOUND_PLAYER_H_ */
524
525