/*---------------------------------------------------------------------------* Project: NintendoWare File: snd_SoundPlayer.h Copyright (C)2009-2010 Nintendo Co., Ltd./HAL Laboratory, Inc. All rights reserved. These coded instructions, statements, and computer programs contain proprietary information of Nintendo of America Inc. and/or Nintendo Company Ltd., and are protected by Federal copyright law. They may not be disclosed to third parties or copied or duplicated in any form, in whole or in part, without the prior written consent of Nintendo. $Revision: 27551 $ *---------------------------------------------------------------------------*/ /** * :include nw/snd/snd_SoundPlayer.h * * @file snd_SoundPlayer.h */ #ifndef NW_SND_SOUND_PLAYER_H_ #define NW_SND_SOUND_PLAYER_H_ #include #include #include namespace nw { namespace snd { //--------------------------------------------------------------------------- //! @brief サウンドを再生するためのプレイヤークラスです。 //! //! SoundPlayer クラスのインスタンスは //! @ref SoundArchivePlayer::GetSoundPlayer を呼び出して取得してください。 //! //! 一つの SoundPlayer で複数のサウンドを再生することができます。 //! 同時に再生できるサウンド数を設定することができ、 //! そのサウンド数を超えた場合には、 //! 各サウンドに設定されたプレイヤープライオリティを比較して、 //! もっとも優先度が低いサウンドが停止します。 //! //! @see SoundArchivePlayer クラス //! @see SoundArchivePlayer::GetSoundPlayer //! //! @date 2010/01/15 初版 //--------------------------------------------------------------------------- class SoundPlayer { public: //! @details :private typedef ut::LinkList< internal::PlayerHeap, offsetof(internal::PlayerHeap,m_Link) > PlayerHeapList; //! @details :private typedef ut::LinkList< internal::BasicSound, offsetof(internal::BasicSound,m_SoundPlayerPlayLink) > SoundList; //! @details :private typedef ut::LinkList< internal::BasicSound, offsetof(internal::BasicSound,m_SoundPlayerPriorityLink) > PriorityList; public: //---------------------------------------- //! @name コンストラクタ/デストラクタ //@{ //--------------------------------------------------------------------------- //! @brief コンストラクタです。 // //! @date 2010/01/15 初版 //--------------------------------------------------------------------------- SoundPlayer(); //--------------------------------------------------------------------------- //! @brief デストラクタです。 // //! @date 2010/01/15 初版 //--------------------------------------------------------------------------- ~SoundPlayer(); //@} //---------------------------------------- //! @name 更新 //@{ //--------------------------------------------------------------------------- //! @brief サウンドプレイヤーの更新処理を行います。 //! //! @ref SoundArchivePlayer クラスを使用している場合は、 //! この関数は @ref SoundArchivePlayer::Update から呼び出されます。 //! //! @see SoundArchivePlayer クラス //! @see SoundArchivePlayer::Update // //! @date 2010/01/15 初版 //--------------------------------------------------------------------------- void Update(); //@} //---------------------------------------- //! @name 再生制御 //@{ //--------------------------------------------------------------------------- //! @brief 全てのサウンドを停止します。 //! //! プレイヤーで再生中の全てのサウンドを停止します。 //! 各サウンドに対して、 //! ハンドルクラスを通して停止させたときと同様の処理を行います。 //! //! fadeFrames で指定したフレーム数をかけて、 //! フェードアウトさせることができます。 //! 0 を指定した場合は、フェードアウトを行いません。 //! ただし、シーケンスサウンドで発音中の音は、 //! エンベロープのリリースを発音し全ての減衰が完了した後に //! サウンドが停止します。 //! //! フェードアウトの音量制御は、フェードインと共有されます。 //! フェードアウトにかかるフレーム数は、 //! 最大音量から音が消えるまでにかかる変化速度を表しますので、 //! フェードイン中にフェードアウトを指定した時などは、 //! 指定したフレーム数よりも短い時間で //! フェードアウトが完了する可能性があります。 //! //! @param[in] fadeFrames フェードアウトにかけるフレーム数です。 // //! @date 2010/01/15 初版 //--------------------------------------------------------------------------- void StopAllSound( int fadeFrames ); //--------------------------------------------------------------------------- //! @brief 全てのサウンドを一時停止・再開します。 //! //! プレイヤーで再生中の全てのサウンドを一時停止または再開します。 //! 各サウンドに対して、 //! ハンドルクラスを通して一時停止・再開させたときと同様の処理を行います。 //! //! 一時停止・再開時のフェードは、再生開始時のフェードイン、 //! 停止時のフェードアウトとは独立してはたらきます。 //! //! @param[in] flag true なら一時停止、false なら再開。 //! @param[in] fadeFrames フェードイン・フェードアウトにかけるフレーム数。 // //! @date 2010/01/15 初版 //--------------------------------------------------------------------------- void PauseAllSound( bool flag, int fadeFrames ); //@} //---------------------------------------- //! @name パラメータ設定・取得 //@{ //--------------------------------------------------------------------------- //! @brief プレイヤーの音量を変更します。 //! //! プレイヤーの音量は、 //! プレイヤーで再生中の全てのサウンドに対して効果があります。 //! //! この関数で指定する値は、 //! サウンドに設定される他のどの音量パラメータとも独立して動作し、 //! それらは全て重ね合わされます。 //! //! 音量 volume は、0.0 以上の倍率で指定します。 //! すなわち、1.0 を指定すると音量に影響を与えません。 //! 0.0 を指定すると発音されなくなります。 //! デフォルト値は 1.0 です。 //! //! 他の音量パラメータと重ね合わされたあと、 //! 最終的な音量は 0.0 ~ 2.0 の範囲でクランプされます。 //! この関数で 2.0 を設定したとしても、 //! 元の音量の 2 倍にならない可能性があることに注意してください。 //! //! @param[in] volume プレイヤーの音量の倍率( 0.0 ~ )です。 //! //! @see GetVolume // //! @date 2010/01/15 初版 //--------------------------------------------------------------------------- void SetVolume( float volume ); //--------------------------------------------------------------------------- //! @brief プレイヤーの音量を取得します。 //! //! @return プレイヤーに設定されている現在の音量を返します。 //! //! @see SetVolume // //! @date 2010/01/15 初版 //--------------------------------------------------------------------------- float GetVolume() const { return m_Volume; } // ローパスフィルタのカットオフ周波数を変化させる //! @details :private void SetLpfFreq( float lpfFreq ); //! @details :private float GetLpfFreq() const { return m_LpfFreq; } // Biquadフィルタを設定する //! @details :private void SetBiquadFilter( int type, float value ); //! @details :private int GetBiquadFilterType() const { return m_BiquadType; } //! @details :private float GetBiquadFilterValue() const { return m_BiquadValue; } //--------------------------------------------------------------------------- //! @brief プレイヤーのメイン出力へのセンド量を変更します。 //! //! プレイヤーのメイン出力へのセンド量は、 //! プレイヤーで再生中の全てのサウンドに対して効果があります。 //! //! この関数で指定する値は、 //! サウンドに設定される他のどの音量パラメータとも独立して動作し、 //! それらはすべて重ね合わされます。 //! //! メインセンドは、メイン出力に送るサウンドの音量を調節するパラメータです。 //! 主に、エフェクトのドライ・ウェット成分のバランスを調整するために使用されます。 //! //! センド量 send は、相対変化の値を指定します。 //! すなわち、0.0 を指定するとセンド量を変更しません。 //! -1.0 を指定するとメインバスに最大のセンド量で送られていたサウンドが //! メインバスに送られないようになります。 デフォルト値は 0.0 です。 //! //! @param[in] send 0.0 を基準としたセンド量の相対変化の値です。 //! //! @see GetMainSend //! @see SetFxSend //! //! @date 2010/06/30 初版 //--------------------------------------------------------------------------- void SetMainSend( float send ); //--------------------------------------------------------------------------- //! @brief プレイヤーに設定されているメイン出力へのセンド量を取得します。 //! //! @return 現在のメイン出力へのセンド量を返します。 //! //! @see SetMainSend //! //! @date 2010/06/30 初版 //--------------------------------------------------------------------------- float GetMainSend() const { return m_MainSend; } //--------------------------------------------------------------------------- //! @brief プレイヤーのエフェクトへのセンド量を変更します。 //! //! プレイヤーのエフェクトへのセンド量は、 //! プレイヤーで再生中の全てのサウンドに対して効果があります。 //! //! この関数で指定する値は、 //! サウンドに設定される他のどの音量パラメータとも独立して動作し、 //! それらはすべて重ね合わされます。 //! //! センド量 send は、相対変化の値を指定します。 //! すなわち、0.0 を指定するとセンド量を変更しません。 //! 1.0 を指定すると AUX バスに送られていなかったサウンドが //! 最大のセンド量で送られるようになります。 デフォルト値は 0.0 です。 //! //! @param[in] bus センド量を設定する AUX バスです。 //! @param[in] send 0.0 を基準としたセンド量の相対変化の値です。 //! //! @see AuxBus //! @see GetFxSend //! @see SetMainSend //! //! @date 2010/06/30 初版 //--------------------------------------------------------------------------- void SetFxSend( AuxBus bus, float send ); //--------------------------------------------------------------------------- //! @brief プレイヤーに設定されているエフェクトへのセンド量を取得します。 //! //! @return 現在のエフェクトへのセンド量を返します。 //! //! @param[in] bus センド量を設定する AUX バスです。 //! //! @see AuxBus //! @see SetFxSend //! //! @date 2010/06/30 初版 //--------------------------------------------------------------------------- float GetFxSend( AuxBus bus ) const { return m_FxSend[ bus ]; } //--------------------------------------------------------------------------- //! @brief プレイヤーで現在再生中のサウンドの個数を取得します。 //! //! @return プレイヤーで再生中のサウンド数を返します。 //! //! @date 2010/06/30 初版 //--------------------------------------------------------------------------- int GetPlayingSoundCount() const { return static_cast( m_SoundList.GetSize()); } //--------------------------------------------------------------------------- //! @brief 同時に再生可能なサウンド数を設定します。 //! //! 設定したサウンド数を超えるサウンドを再生しようとすると、 //! 各サウンドに設定されたプレイヤープライオリティを比較して、 //! もっとも優先度が低いサウンドが停止します。 //! //! @ref SoundArchivePlayer クラスを使用する場合は、 //! サウンドアーカイブ中で指定されている同時再生数が初期化時に自動的に設定されます。 //! //! プレイヤーヒープを使用している場合、 //! この関数で指定できる同時再生数の上限値は、 //! セットアップ時に設定された同時再生数の値に制限されます。 //! 上限値を超える値を指定しても上限値に丸め込まれます。 //! //! @param[in] count 同時に再生可能なサウンド数です。 //! //! @see SoundArchivePlayer クラス //! @see GetPlayableSoundCount //! //! @date 2010/11/19 誤植修正 (desu→です) //! @date 2010/06/30 初版 //--------------------------------------------------------------------------- void SetPlayableSoundCount( int count ); //--------------------------------------------------------------------------- //! @brief プレイヤーで同時に再生可能なサウンド数を取得します。 //! //! @return プレイヤーで同時に再生可能なサウンド数を返します。 //! //! @see SetPlayableSoundCount //! //! @date 2010/06/30 初版 //--------------------------------------------------------------------------- int GetPlayableSoundCount() const { return m_PlayableCount; } //@} //---------------------------------------- //! @name その他 //@{ //--------------------------------------------------------------------------- //! @brief プレイヤーで再生中の全てのサウンドに対して処理を行います。 //! //! プレイヤーで再生中の全てのサウンドに対して、 //! //! function( nw::snd::SoundHandle& handle ) //! //! を呼び出します。 function には、 //! 再生中のサウンドに関連付けられたサウンドハンドル handle が渡されます。 //! これは一時的なハンドルですので、ハンドルを後で使用することはできません。 //! //! 関数 function は、サウンドの再生が古い順に呼び出されます。 //! reverse に true を指定すると、サウンドの再生が新しい順に呼び出されます。 //! //! function には関数ポインタ、または関数オブジェクトを渡します。 //! 関数ポインタを渡す例を以下に示します。 //! //! void ReportSoundId( nw::snd::SoundHandle& handle ) { //! NN_LOG( "%d\n", handle.GetId() ); //! } @n //! soundPlayer.ForEachSound( ReportSoundId ); //! //! @param[in] function 関数ポインタ、または関数オブジェクトです。 //! @param[in] reverse 処理順を逆にする場合は true を指定します。 //! //! @return 引数に指定された関数ポインタ、または関数オブジェクトを返します。 //! //! @see SoundHandle クラス //! @see ForEachSoundPriorityOrder //! //! @date 2010/10/15 誤植修正 (nw4r → nw, OSReport → NN_LOG) //! @date 2010/06/30 初版 //--------------------------------------------------------------------------- template< class Function > Function ForEachSound( Function function, bool reverse = false ); //--------------------------------------------------------------------------- //! @brief プレイヤーで再生中の全てのサウンドに対してプライオリティ順で処理を行います。 //! //! その他の動作仕様は @ref ForEachSound と同じです。 //! //! @param[in] function 関数ポインタ、または関数オブジェクトです。 //! @param[in] reverse 処理順を逆にする場合は true を指定します。 //! //! @return 引数に指定された関数ポインタ、または関数オブジェクトを返します。 //! //! @see SoundHandle クラス //! @see ForEachSound //! //! @date 2010/06/30 初版 //--------------------------------------------------------------------------- template< class Function > Function ForEachSoundPriorityOrder( Function function, bool reverse = false ); //@} //----------------------------------------------------------------------------- // internal functions //! @details :private void detail_SetPlayableSoundLimit( int limit ); // サウンドの登録 //! @details :private bool detail_CanPlaySound( int startPriority ); //! @details :private bool detail_AppendSound( internal::BasicSound* pSound ); //! @details :private void detail_RemoveSound( internal::BasicSound* pSound ); // プライオリティリスト //! @details :private void detail_SortPriorityList(); //! @details :private void detail_SortPriorityList( internal::BasicSound* pSound ); // プレイヤーヒープ //! @details :private void detail_AppendPlayerHeap( internal::PlayerHeap* pHeap ); //! @details :private void detail_RemovePlayerHeap( internal::PlayerHeap* pHeap ); //! @details :private internal::PlayerHeap* detail_AllocPlayerHeap( internal::BasicSound* pSound ); //! @details :private void detail_FreePlayerHeap( internal::BasicSound* pSound ); private: //----------------------------------------------------------------------------- // private functions internal::BasicSound* GetLowestPrioritySound() { return &m_PriorityList.GetFront(); } void InsertPriorityList( internal::BasicSound* pSound ); void RemovePriorityList( internal::BasicSound* pSound ); void RemoveSoundList( internal::BasicSound* pSound ); //----------------------------------------------------------------------------- // private variables SoundList m_SoundList; PriorityList m_PriorityList; PlayerHeapList m_PlayerHeapList; int m_PlayableCount; int m_PlayableLimit; float m_Volume; float m_LpfFreq; int m_BiquadType; float m_BiquadValue; float m_MainSend; float m_FxSend[ AUX_BUS_NUM ]; }; template< class Function > inline Function SoundPlayer::ForEachSound( Function function, bool reverse ) { if ( reverse ) { // 再生の新しい順 for ( SoundList::ReverseIterator itr = m_SoundList.GetBeginReverseIter(); itr != m_SoundList.GetEndReverseIter(); ) { SoundList::ReverseIterator curItr = itr; SoundHandle handle; handle.detail_AttachSoundAsTempHandle( &( *curItr ) ); function( handle ); if ( handle.IsAttachedSound() ) itr++; } } else { // 再生の古い順 for ( SoundList::Iterator itr = m_SoundList.GetBeginIter(); itr != m_SoundList.GetEndIter(); ) { SoundList::Iterator curItr = itr++; SoundHandle handle; handle.detail_AttachSoundAsTempHandle( &( *curItr ) ); function( handle ); } } return function; } template< class Function > Function SoundPlayer::ForEachSoundPriorityOrder( Function function, bool reverse ) { if ( reverse ) { // プライオリティの低い順 for ( PriorityList::Iterator itr = m_PriorityList.GetBeginIter(); itr != m_PriorityList.GetEndIter(); ) { PriorityList::Iterator curItr = itr++; SoundHandle handle; handle.detail_AttachSoundAsTempHandle( &( *curItr ) ); function( handle ); } } else { // プライオリティの高い順 for ( PriorityList::ReverseIterator itr = m_PriorityList.GetBeginReverseIter(); itr != m_PriorityList.GetEndReverseIter(); ) { PriorityList::ReverseIterator curItr = itr; SoundHandle handle; handle.detail_AttachSoundAsTempHandle( &( *curItr ) ); function( handle ); if ( handle.IsAttachedSound() ) itr++; } } return function; } } // namespace nw::snd } // namespace nw #endif /* NW_SND_SOUND_PLAYER_H_ */