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