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: 25149 $
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 同時に再生可能なサウンド数desu。
315 //!
316 //! @see SoundArchivePlayer クラス
317 //! @see GetPlayableSoundCount
318 //!
319 //! @date 2010/06/30 初版
320 //---------------------------------------------------------------------------
321 void SetPlayableSoundCount( int count );
322
323 //---------------------------------------------------------------------------
324 //! @brief プレイヤーで同時に再生可能なサウンド数を取得します。
325 //!
326 //! @return プレイヤーで同時に再生可能なサウンド数を返します。
327 //!
328 //! @see SetPlayableSoundCount
329 //!
330 //! @date 2010/06/30 初版
331 //---------------------------------------------------------------------------
GetPlayableSoundCount()332 int GetPlayableSoundCount() const { return m_PlayableCount; }
333 //@}
334
335 //----------------------------------------
336 //! @name その他
337 //@{
338 //---------------------------------------------------------------------------
339 //! @brief プレイヤーで再生中の全てのサウンドに対して処理を行います。
340 //!
341 //! プレイヤーで再生中の全てのサウンドに対して、
342 //!
343 //! function( nw4r::snd::SoundHandle& handle )
344 //!
345 //! を呼び出します。 function には、
346 //! 再生中のサウンドに関連付けられたサウンドハンドル handle が渡されます。
347 //! これは一時的なハンドルですので、ハンドルを後で使用することはできません。
348 //!
349 //! 関数 function は、サウンドの再生が古い順に呼び出されます。
350 //! reverse に true を指定すると、サウンドの再生が新しい順に呼び出されます。
351 //!
352 //! function には関数ポインタ、または関数オブジェクトを渡します。
353 //! 関数ポインタを渡す例を以下に示します。
354 //!
355 //! void ReportSoundId( nw::snd::SoundHandle& handle ) {
356 //! NN_LOG( "%d\n", handle.GetId() );
357 //! } @n
358 //! soundPlayer.ForEachSound( ReportSoundId );
359 //!
360 //! @param[in] function 関数ポインタ、または関数オブジェクトです。
361 //! @param[in] reverse 処理順を逆にする場合は true を指定します。
362 //!
363 //! @return 引数に指定された関数ポインタ、または関数オブジェクトを返します。
364 //!
365 //! @see SoundHandle クラス
366 //! @see ForEachSoundPriorityOrder
367 //!
368 //! @date 2010/10/15 誤植修正 (nw4r → nw, OSReport → NN_LOG)
369 //! @date 2010/06/30 初版
370 //---------------------------------------------------------------------------
371 template< class Function >
372 Function ForEachSound( Function function, bool reverse = false );
373
374 //---------------------------------------------------------------------------
375 //! @brief プレイヤーで再生中の全てのサウンドに対してプライオリティ順で処理を行います。
376 //!
377 //! その他の動作仕様は @ref ForEachSound と同じです。
378 //!
379 //! @param[in] function 関数ポインタ、または関数オブジェクトです。
380 //! @param[in] reverse 処理順を逆にする場合は true を指定します。
381 //!
382 //! @return 引数に指定された関数ポインタ、または関数オブジェクトを返します。
383 //!
384 //! @see SoundHandle クラス
385 //! @see ForEachSound
386 //!
387 //! @date 2010/06/30 初版
388 //---------------------------------------------------------------------------
389 template< class Function >
390 Function ForEachSoundPriorityOrder( Function function, bool reverse = false );
391 //@}
392
393 //-----------------------------------------------------------------------------
394 // internal functions
395
396 //! @details :private
397 void detail_SetPlayableSoundLimit( int limit );
398
399 // サウンドの登録
400 //! @details :private
401 bool detail_CanPlaySound( int startPriority );
402 //! @details :private
403 bool detail_AppendSound( internal::BasicSound* pSound );
404 //! @details :private
405 void detail_RemoveSound( internal::BasicSound* pSound );
406
407 // プライオリティリスト
408 //! @details :private
409 void detail_SortPriorityList();
410 //! @details :private
411 void detail_SortPriorityList( internal::BasicSound* pSound );
412
413 // プレイヤーヒープ
414 //! @details :private
415 void detail_AppendPlayerHeap( internal::PlayerHeap* pHeap );
416 //! @details :private
417 void detail_RemovePlayerHeap( internal::PlayerHeap* pHeap );
418
419 //! @details :private
420 internal::PlayerHeap* detail_AllocPlayerHeap( internal::BasicSound* pSound );
421 //! @details :private
422 void detail_FreePlayerHeap( internal::BasicSound* pSound );
423
424 private:
425 //-----------------------------------------------------------------------------
426 // private functions
427
GetLowestPrioritySound()428 internal::BasicSound* GetLowestPrioritySound() { return &m_PriorityList.GetFront(); }
429 void InsertPriorityList( internal::BasicSound* pSound );
430 void RemovePriorityList( internal::BasicSound* pSound );
431 void RemoveSoundList( internal::BasicSound* pSound );
432
433 //-----------------------------------------------------------------------------
434 // private variables
435
436 SoundList m_SoundList;
437 PriorityList m_PriorityList;
438 PlayerHeapList m_PlayerHeapList;
439
440 int m_PlayableCount;
441 int m_PlayableLimit;
442
443 float m_Volume;
444 float m_LpfFreq;
445 int m_BiquadType;
446 float m_BiquadValue;
447 float m_MainSend;
448 float m_FxSend[ AUX_BUS_NUM ];
449 };
450
451
452 template< class Function >
ForEachSound(Function function,bool reverse)453 inline Function SoundPlayer::ForEachSound( Function function, bool reverse )
454 {
455 if ( reverse )
456 {
457 // 再生の新しい順
458 for ( SoundList::ReverseIterator itr = m_SoundList.GetBeginReverseIter();
459 itr != m_SoundList.GetEndReverseIter();
460 )
461 {
462 SoundList::ReverseIterator curItr = itr;
463 SoundHandle handle;
464 handle.detail_AttachSoundAsTempHandle( &( *curItr ) );
465 function( handle );
466 if ( handle.IsAttachedSound() ) itr++;
467 }
468 }
469 else
470 {
471 // 再生の古い順
472 for ( SoundList::Iterator itr = m_SoundList.GetBeginIter();
473 itr != m_SoundList.GetEndIter();
474 )
475 {
476 SoundList::Iterator curItr = itr++;
477 SoundHandle handle;
478 handle.detail_AttachSoundAsTempHandle( &( *curItr ) );
479 function( handle );
480 }
481 }
482 return function;
483 }
484
485 template< class Function >
ForEachSoundPriorityOrder(Function function,bool reverse)486 Function SoundPlayer::ForEachSoundPriorityOrder( Function function, bool reverse )
487 {
488 if ( reverse )
489 {
490 // プライオリティの低い順
491 for ( PriorityList::Iterator itr = m_PriorityList.GetBeginIter();
492 itr != m_PriorityList.GetEndIter();
493 )
494 {
495 PriorityList::Iterator curItr = itr++;
496 SoundHandle handle;
497 handle.detail_AttachSoundAsTempHandle( &( *curItr ) );
498 function( handle );
499 }
500 }
501 else
502 {
503 // プライオリティの高い順
504 for ( PriorityList::ReverseIterator itr = m_PriorityList.GetBeginReverseIter();
505 itr != m_PriorityList.GetEndReverseIter();
506 )
507 {
508 PriorityList::ReverseIterator curItr = itr;
509 SoundHandle handle;
510 handle.detail_AttachSoundAsTempHandle( &( *curItr ) );
511 function( handle );
512 if ( handle.IsAttachedSound() ) itr++;
513 }
514 }
515 return function;
516 }
517
518 } // namespace nw::snd
519 } // namespace nw
520
521
522 #endif /* NW_SND_SOUND_PLAYER_H_ */
523
524