1 /*---------------------------------------------------------------------------*
2   Project:  NintendoWare
3   File:     snd_ExternalSoundPlayer.cpp
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: 17972 $
14  *---------------------------------------------------------------------------*/
15 
16 #include "precompiled.h"
17 
18 #include <nw/snd/snd_ExternalSoundPlayer.h>
19 
20 #include <nw/snd/snd_SoundThread.h>
21 #include <nw/snd/snd_SoundActor.h>
22 
23 namespace nw {
24 namespace snd {
25 namespace internal {
26 
27 /*---------------------------------------------------------------------------*
28   Name:         ExxternalSoundPlayer
29 
30   Description:  コンストラクタ
31 
32   Arguments:    None.
33 
34   Returns:      None.
35  *---------------------------------------------------------------------------*/
ExternalSoundPlayer()36 ExternalSoundPlayer::ExternalSoundPlayer()
37 : m_PlayableCount( 1 )
38 {
39 }
40 
41 /*---------------------------------------------------------------------------*
42   Name:         ExternalSoundPlayer
43 
44   Description:  デストラクタ
45 
46   Arguments:    None.
47 
48   Returns:      None.
49  *---------------------------------------------------------------------------*/
~ExternalSoundPlayer()50 ExternalSoundPlayer::~ExternalSoundPlayer()
51 {
52     for ( SoundList::Iterator itr = m_SoundList.GetBeginIter();
53           itr != m_SoundList.GetEndIter();
54         )
55     {
56         SoundList::Iterator curItr = itr++;
57         curItr->DetachExternalSoundPlayer( this );
58     }
59 }
60 
61 /*---------------------------------------------------------------------------*
62   Name:         StopAllSound
63 
64   Description:  全てのサウンドを停止する
65 
66   Arguments:    fadeFrames - フェードアウトフレーム数
67 
68   Returns:      None.
69  *---------------------------------------------------------------------------*/
StopAllSound(int fadeFrames)70 void ExternalSoundPlayer::StopAllSound( int fadeFrames )
71 {
72     for ( SoundList::Iterator itr = m_SoundList.GetBeginIter();
73           itr != m_SoundList.GetEndIter();
74         )
75     {
76         SoundList::Iterator curItr = itr++;
77         curItr->Stop( fadeFrames );
78     }
79 }
80 
81 /*---------------------------------------------------------------------------*
82   Name:         PauseAllSound
83 
84   Description:  全てのサウンドを一時停止または再開する
85 
86   Arguments:    flag       - 一時停止か再開か
87                 fadeFrames - フェードフレーム数
88 
89   Returns:      None.
90  *---------------------------------------------------------------------------*/
PauseAllSound(bool flag,int fadeFrames)91 void ExternalSoundPlayer::PauseAllSound( bool flag, int fadeFrames )
92 {
93     for ( SoundList::Iterator itr = m_SoundList.GetBeginIter();
94           itr != m_SoundList.GetEndIter();
95         )
96     {
97         SoundList::Iterator curItr = itr++;
98         curItr->Pause( flag, fadeFrames );
99     }
100 }
101 /*---------------------------------------------------------------------------*
102   Name:         DetachSoundActorAll
103 
104   Description:  全てのサウンドに対して、SoundActorを切り離す
105 
106   Arguments:    actor - サウンドアクター
107 
108   Returns:      None.
109  *---------------------------------------------------------------------------*/
DetachSoundActorAll(SoundActor * actor)110 void ExternalSoundPlayer::DetachSoundActorAll( SoundActor* actor )
111 {
112     for ( SoundList::Iterator itr = m_SoundList.GetBeginIter();
113           itr != m_SoundList.GetEndIter();
114         )
115     {
116         SoundList::Iterator curItr = itr++;
117         curItr->DetachSoundActor( actor );
118     }
119 }
120 
121 /*---------------------------------------------------------------------------*
122   Name:         AppendSound
123 
124   Description:  サウンドを登録する
125 
126   Arguments:    sound - サウンド
127 
128   Returns:      登録できたらtrue
129  *---------------------------------------------------------------------------*/
AppendSound(internal::BasicSound * sound)130 bool ExternalSoundPlayer::AppendSound( internal::BasicSound* sound )
131 {
132     NW_NULL_ASSERT( sound );
133 
134     int allocPriority = sound->CalcCurrentPlayerPriority();
135 
136     // 最大同時再生数のチェック
137     if ( GetPlayableSoundCount() == 0 ) return false;
138     while ( GetPlayingSoundCount() >= GetPlayableSoundCount() )
139     {
140         internal::BasicSound* dropSound = GetLowestPrioritySound();
141         if ( dropSound == NULL ) return false;
142         if ( allocPriority < dropSound->CalcCurrentPlayerPriority() ) return false;
143         dropSound->Finalize();
144     }
145 
146     m_SoundList.PushBack( sound );
147 
148     sound->AttachExternalSoundPlayer( this );
149 
150     return true;
151 }
152 
153 /*---------------------------------------------------------------------------*
154   Name:         SetPlayableSoundCount
155 
156   Description:  同時再生数を設定
157 
158   Arguments:    count - 同時再生数
159 
160   Returns:      None.
161  *---------------------------------------------------------------------------*/
SetPlayableSoundCount(int count)162 void ExternalSoundPlayer::SetPlayableSoundCount( int count )
163 {
164     m_PlayableCount = count;
165 
166     // 新しく設定された同時再生数を越えるサウンドを終了する
167     while ( GetPlayingSoundCount() > GetPlayableSoundCount() )
168     {
169         internal::BasicSound* dropSound = GetLowestPrioritySound();
170         NW_NULL_ASSERT( dropSound );
171         dropSound->Finalize();
172     }
173 }
174 
175 /*---------------------------------------------------------------------------*
176   Name:         RemoveSound
177 
178   Description:  サウンドをプレイヤーリストから削除する
179 
180   Arguments:    sound - シーケンスサウンド
181 
182   Returns:      None.
183  *---------------------------------------------------------------------------*/
RemoveSound(internal::BasicSound * sound)184 void ExternalSoundPlayer::RemoveSound( internal::BasicSound* sound )
185 {
186     // 再生リストから削除する
187     m_SoundList.Erase( sound );
188     sound->DetachExternalSoundPlayer( this );
189 }
190 
191 /*---------------------------------------------------------------------------*
192   Name:         detail_CanPlaySound
193 
194   Description:  指定したプライオリティのサウンドを再生できるかどうかを調べる
195 
196   Arguments:    startPriority - プライオリティ
197 
198   Returns:      再生可能ならtrue
199  *---------------------------------------------------------------------------*/
detail_CanPlaySound(int startPriority)200 bool ExternalSoundPlayer::detail_CanPlaySound( int startPriority )
201 {
202     // 最大同時再生数のチェック
203     if ( GetPlayableSoundCount() == 0 ) return false;
204     if ( GetPlayingSoundCount() >= GetPlayableSoundCount() )
205     {
206         internal::BasicSound* dropSound = GetLowestPrioritySound();
207         if ( dropSound == NULL ) return false;
208         if ( startPriority < dropSound->CalcCurrentPlayerPriority() ) return false;
209     }
210 
211     return true;
212 }
213 
214 /*---------------------------------------------------------------------------*
215   Name:         GetLowestPrioritySound
216 
217   Description:  サウンドリストからもっともプライオリティの低いサウンドを探す
218 
219   Arguments:    None.
220 
221   Returns:      プライオリティの低いサウンドへのポインタ
222  *---------------------------------------------------------------------------*/
GetLowestPrioritySound()223 internal::BasicSound* ExternalSoundPlayer::GetLowestPrioritySound()
224 {
225     // insert to priority list
226     int priority = internal::BasicSound::PRIORITY_MAX + 1;
227     internal::BasicSound* sound = NULL;
228     SoundList::Iterator itr = m_SoundList.GetBeginIter();
229     while ( itr != m_SoundList.GetEndIter() )
230     {
231         int itrPriority = itr->CalcCurrentPlayerPriority();
232         if ( priority > itrPriority )
233         {
234             sound = &*itr;
235             priority = itrPriority;
236         }
237         (void)++itr;
238     }
239     return sound;
240 }
241 
242 } // namespace nw::snd::internal
243 } // namespace nw::snd
244 } // namespace nw
245 
246