/*---------------------------------------------------------------------------* Project: NintendoWare File: snd_SoundPlayer.cpp 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: 28902 $ *---------------------------------------------------------------------------*/ #include "precompiled.h" #include #include namespace nw { namespace snd { /* ======================================================================== public function ======================================================================== */ /*---------------------------------------------------------------------------* Name: SoundPlayer Description: コンストラクタ Arguments: None. Returns: None. *---------------------------------------------------------------------------*/ SoundPlayer::SoundPlayer() : m_PlayableCount( 1 ), m_PlayableLimit( INT_MAX ), m_Volume( 1.0f ), m_LpfFreq( 0.0f ), m_BiquadType( BIQUAD_FILTER_TYPE_NONE ), m_BiquadValue( 0.0f ), m_MainSend( 0.0f ) { for ( int i=0; iUpdate(); } // プライオリティリストを整列しなおす detail_SortPriorityList(); } /*---------------------------------------------------------------------------* Name: StopAllSound Description: 全てのサウンドを停止する Arguments: fadeFrames - フェードアウトフレーム数 Returns: None. *---------------------------------------------------------------------------*/ void SoundPlayer::StopAllSound( int fadeFrames ) { for ( SoundList::Iterator itr = m_SoundList.GetBeginIter(); itr != m_SoundList.GetEndIter(); ) { SoundList::Iterator curItr = itr++; curItr->Stop( fadeFrames ); } } /*---------------------------------------------------------------------------* Name: PauseAllSound Description: 全てのサウンドを一時停止または再開する Arguments: flag - 一時停止か再開か fadeFrames - フェードフレーム数 Returns: None. *---------------------------------------------------------------------------*/ void SoundPlayer::PauseAllSound( bool flag, int fadeFrames ) { for ( SoundList::Iterator itr = m_SoundList.GetBeginIter(); itr != m_SoundList.GetEndIter(); ) { SoundList::Iterator curItr = itr++; curItr->Pause( flag, fadeFrames ); } } /*---------------------------------------------------------------------------* Name: SetVolume Description: 音量を変更 Arguments: volume - 音量 Returns: None. *---------------------------------------------------------------------------*/ void SoundPlayer::SetVolume( float volume ) { NW_ASSERT( volume >= 0.0f ); if ( volume < 0.0f ) volume = 0.0f; m_Volume = volume; } /*---------------------------------------------------------------------------* Name: SetLpfFreq Description: ローパスフィルタの周波数変更 Arguments: lpfFreq - ローパスフィルタの周波数値 Returns: なし *---------------------------------------------------------------------------*/ void SoundPlayer::SetLpfFreq( float lpfFreq ) { m_LpfFreq = lpfFreq; } /*---------------------------------------------------------------------------* Name: SetBiquadFilter Description: Biquadフィルタの設定 Arguments: type - フィルタの種類 (0 - 127) value - フィルタの値 (0.0f - 1.0f) Returns: なし *---------------------------------------------------------------------------*/ void SoundPlayer::SetBiquadFilter( int type, float value ) { m_BiquadType = type; m_BiquadValue = value; } /*---------------------------------------------------------------------------* Name: SetMainSend Description: メインセンドバスに送る音量を変更する Arguments: send - 音量 Returns: None. *---------------------------------------------------------------------------*/ void SoundPlayer::SetMainSend( float send ) { m_MainSend = send; } /*---------------------------------------------------------------------------* Name: SetFxSend Description: エフェクトセンドバスに送る音量を変更する Arguments: bus - センドバス send - 音量 Returns: None. *---------------------------------------------------------------------------*/ void SoundPlayer::SetFxSend( AuxBus bus, float send ) { NW_MINMAXLT_ASSERT( bus, 0, AUX_BUS_NUM ); m_FxSend[bus] = send; } /*---------------------------------------------------------------------------* Name: RemoveSoundList Description: サウンドをプレイヤーリストから削除する Arguments: pSound - シーケンスサウンド Returns: None. *---------------------------------------------------------------------------*/ void SoundPlayer::RemoveSoundList( internal::BasicSound* pSound ) { // 再生リストから削除する m_SoundList.Erase( pSound ); pSound->DetachSoundPlayer( this ); } /*---------------------------------------------------------------------------* Name: InsertPriorityList Description: サウンドをプライオリティリストへ追加 Arguments: pSound - 追加するサウンド Returns: None. *---------------------------------------------------------------------------*/ void SoundPlayer::InsertPriorityList( internal::BasicSound* pSound ) { PriorityList::Iterator itr = m_PriorityList.GetBeginIter(); while ( itr != m_PriorityList.GetEndIter() ) { if ( pSound->CalcCurrentPlayerPriority() < itr->CalcCurrentPlayerPriority() ) break; (void)++itr; } m_PriorityList.Insert( itr, pSound ); } /*---------------------------------------------------------------------------* Name: RemovePriorityList Description: サウンドをプライオリティリストから削除 Arguments: pSound - 削除するサウンド Returns: None. *---------------------------------------------------------------------------*/ void SoundPlayer::RemovePriorityList( internal::BasicSound* pSound ) { m_PriorityList.Erase( pSound ); } /*---------------------------------------------------------------------------* Name: detail_SortPriorityList Description: 指定したサウンドのプライオリティ順序を並び替える Arguments: pSound - 並び替えるサウンド Returns: None. *---------------------------------------------------------------------------*/ void SoundPlayer::detail_SortPriorityList( internal::BasicSound* pSound ) { RemovePriorityList( pSound ); InsertPriorityList( pSound ); } /*---------------------------------------------------------------------------* Name: detail_SortPriorityList Description: 全サウンドのプライオリティ順序を並び替える Arguments: None. Returns: None. *---------------------------------------------------------------------------*/ void SoundPlayer::detail_SortPriorityList() { if ( m_PriorityList.GetSize() < 2 ) return; static const int TMP_NUM = internal::BasicSound::PRIORITY_MAX - internal::BasicSound::PRIORITY_MIN + 1; static PriorityList tmplist[ TMP_NUM ]; // notice: large stack #ifdef NW_DEBUG for ( int i=0; iCalcCurrentPlayerPriority(); // 最大同時再生数のチェック if ( GetPlayableSoundCount() == 0 ) return false; while ( GetPlayingSoundCount() >= GetPlayableSoundCount() ) { internal::BasicSound* dropSound = GetLowestPrioritySound(); if ( dropSound == NULL ) return false; if ( allocPriority < dropSound->CalcCurrentPlayerPriority() ) return false; dropSound->Finalize(); } // リストへ登録 m_SoundList.PushBack( pSound ); InsertPriorityList( pSound ); pSound->AttachSoundPlayer( this ); return true; } /*---------------------------------------------------------------------------* Name: detail_RemoveSound Description: サウンドをサウンドプレイヤーから削除する Arguments: pSound - 削除するサウンド Returns: None. *---------------------------------------------------------------------------*/ void SoundPlayer::detail_RemoveSound( internal::BasicSound* pSound ) { RemovePriorityList( pSound ); RemoveSoundList( pSound ); } /*---------------------------------------------------------------------------* Name: SetPlayableSoundCount Description: 同時再生数を設定 Arguments: count - 同時再生数 Returns: None. *---------------------------------------------------------------------------*/ void SoundPlayer::SetPlayableSoundCount( int count ) { NW_ASSERT( count >= 0 ); // プレイヤーヒープ使用時の上限 NW_WARNING( count <= m_PlayableLimit, "playable sound count is over limit." ); count = ut::Clamp( count, 0, m_PlayableLimit ); m_PlayableCount = count; // 新しく設定された同時再生数を越えるサウンドを終了する while ( GetPlayingSoundCount() > GetPlayableSoundCount() ) { internal::BasicSound* dropSound = GetLowestPrioritySound(); NW_NULL_ASSERT( dropSound ); dropSound->Finalize(); } } /*---------------------------------------------------------------------------* Name: detail_SetPlayableSoundLimit Description: Arguments: None. Returns: None. *---------------------------------------------------------------------------*/ void SoundPlayer::detail_SetPlayableSoundLimit( int limit ) { NW_ASSERT( limit >= 0 ); m_PlayableLimit = limit; } /*---------------------------------------------------------------------------* Name: detail_CanPlaySound Description: 指定したプライオリティのサウンドを再生できるかどうかを調べる Arguments: startPriority - プライオリティ Returns: 再生可能ならtrue *---------------------------------------------------------------------------*/ bool SoundPlayer::detail_CanPlaySound( int startPriority ) { // プレイヤー毎の最大同時再生数のチェック if ( GetPlayableSoundCount() == 0 ) return false; if ( GetPlayingSoundCount() >= GetPlayableSoundCount() ) { internal::BasicSound* dropSound = GetLowestPrioritySound(); if ( dropSound == NULL ) return false; if ( startPriority < dropSound->CalcCurrentPlayerPriority() ) return false; } return true; } /*---------------------------------------------------------------------------* Name: detail_AppendPlayerHeap Description: プレイヤーヒープを追加 Arguments: heap - 追加するプレイヤーヒープ Returns: None. *---------------------------------------------------------------------------*/ void SoundPlayer::detail_AppendPlayerHeap( internal::PlayerHeap* pHeap ) { NW_NULL_ASSERT( pHeap ); pHeap->AttachSoundPlayer( this ); m_PlayerHeapList.PushBack( pHeap ); } /*---------------------------------------------------------------------------* Name: detail_RemovePlayerHeap Description: プレイヤーヒープの削除 Arguments: heap - 削除するプレイヤーヒープ Returns: None. *---------------------------------------------------------------------------*/ void SoundPlayer::detail_RemovePlayerHeap( internal::PlayerHeap* pHeap ) { m_PlayerHeapList.Erase( pHeap ); } /*---------------------------------------------------------------------------* Name: detail_AllocPlayerHeap Description: プレイヤーヒープの確保 Arguments: sound - プレイヤーヒープを使用するサウンド Returns: 確保したヒープ *---------------------------------------------------------------------------*/ internal::PlayerHeap* SoundPlayer::detail_AllocPlayerHeap( internal::BasicSound* pSound ) { NW_NULL_ASSERT( pSound ); // プレイヤーヒープの確保 if ( m_PlayerHeapList.IsEmpty() ) return NULL; internal::PlayerHeap& playerHeap = m_PlayerHeapList.GetFront(); m_PlayerHeapList.PopFront(); // プレイヤーヒープとサウンドの結合 playerHeap.AttachSound( pSound ); pSound->AttachPlayerHeap( &playerHeap ); // NOTE: プレイヤーヒープ初期化 playerHeap.Clear() は、 // 各データロードタスクの Execute あたまで呼び出す return &playerHeap; } /*---------------------------------------------------------------------------* Name: detail_FreePlayerHeap Description: プレイヤーヒープの解放 Arguments: sound - プレイヤーヒープを解放するサウンド Returns: None. *---------------------------------------------------------------------------*/ void SoundPlayer::detail_FreePlayerHeap( internal::BasicSound* pSound ) { NW_NULL_ASSERT( pSound ); internal::PlayerHeap* pHeap = pSound->GetPlayerHeap(); if ( pHeap == NULL ) return; // プレイヤーヒープとサウンドの切断 pHeap->DetachSound( pSound ); pSound->DetachPlayerHeap( pHeap ); // プレイヤーヒープの解放 m_PlayerHeapList.PushBack( pHeap ); } } // namespace nw::snd } // namespace nw