00001
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include "stdsound.h"
00027
00028 #include "background_source.h"
00029
00030 using namespace std;
00031 using namespace NLMISC;
00032
00033 namespace NLSOUND
00034 {
00035
00037 const TTime ENV_CHK_INTERVAL = 3000;
00038
00039
00040 CBackgroundSource::CBackgroundSource(CBackgroundSound *backgroundSource, bool spawn, TSpawnEndCallback cb, void *cbUserParam)
00041 : CSourceCommon(backgroundSource, spawn, cb, cbUserParam)
00042 {
00043 _BackgroundSound = backgroundSource;
00044 }
00045
00046 CBackgroundSource::~CBackgroundSource()
00047 {
00048 if (_Playing)
00049 stop();
00050 }
00051
00052 void CBackgroundSource::setSound( TSoundId id, CSoundContext *context)
00053 {
00054 nlassert(false);
00055 }
00056
00057 TSoundId CBackgroundSource::getSound()
00058 {
00059 return NULL;
00060 }
00061
00062 void CBackgroundSource::setGain( float gain )
00063 {
00064 CSourceCommon::setGain(gain);
00065
00066 std::vector<TSubSource>::iterator first(_Sources.begin()), last(_Sources.end());
00067 for (; first != last; ++first)
00068 {
00069 if (first->Source != 0)
00070 first->Source->setRelativeGain(_Gain);
00071 }
00072 }
00073 void CBackgroundSource::setRelativeGain( float gain )
00074 {
00075 CSourceCommon::setRelativeGain(gain);
00076
00077 std::vector<TSubSource>::iterator first(_Sources.begin()), last(_Sources.end());
00078 for (; first != last; ++first)
00079 {
00080 if (first->Source != 0)
00081 first->Source->setRelativeGain(_Gain);
00082 }
00083 }
00084
00085 void CBackgroundSource::setPos( const NLMISC::CVector& pos )
00086 {
00087 CSourceCommon::setPos(pos);
00088
00089 std::vector<TSubSource>::iterator first(_Sources.begin()), last(_Sources.end());
00090 for (; first != last; ++first)
00091 {
00092 if (first->Source != 0)
00093 first->Source->setPos(pos);
00094 }
00095 }
00096
00097 void CBackgroundSource::setVelocity( const NLMISC::CVector& vel )
00098 {
00099 CSourceCommon::setVelocity(vel);
00100
00101 std::vector<TSubSource>::iterator first(_Sources.begin()), last(_Sources.end());
00102 for (; first != last; ++first)
00103 {
00104 if (first->Source != 0)
00105 first->Source->setVelocity(vel);
00106 }
00107 }
00108 void CBackgroundSource::setDirection( const NLMISC::CVector& dir )
00109 {
00110 CSourceCommon::setDirection(dir);
00111
00112 std::vector<TSubSource>::iterator first(_Sources.begin()), last(_Sources.end());
00113 for (; first != last; ++first)
00114 {
00115 if (first->Source != 0)
00116 first->Source->setDirection(dir);
00117 }
00118 }
00119
00120
00121
00122 void CBackgroundSource::play()
00123 {
00124 if (_Playing)
00125 stop();
00126
00127 CAudioMixerUser *mixer = CAudioMixerUser::instance();
00128
00129 const vector<CBackgroundSound::TSoundInfo> &sounds = _BackgroundSound->getSounds();
00130 vector<CBackgroundSound::TSoundInfo>::const_iterator first(sounds.begin()), last(sounds.end());
00131
00132 for (; first != last; ++first)
00133 {
00134 TSubSource subSource;
00135 subSource.Source = mixer->createSource(first->SoundName, false);
00136 subSource.Filter = first->Filter;
00137 subSource.FadeStart = 0;
00138 subSource.FilterFadeIn = first->FilterFadeIn;
00139 subSource.FilterFadeOut = first->FilterFadeOut;
00140
00141 if (subSource.Source && checkFilter(subSource.Filter))
00142 {
00143 subSource.Status = SUB_STATUS_PLAY;
00144 subSource.Source->setRelativeGain(_Gain);
00145 subSource.Source->setPos(_Position);
00146 subSource.Source->play();
00147 }
00148 else
00149 {
00150 subSource.Status = SUB_STATUS_STOP;
00151 }
00152
00153 _Sources.push_back(subSource);
00154 }
00155
00156 _LastCheck = NLMISC::CTime::getLocalTime();
00157
00158
00159 mixer->addEvent(this, _LastCheck+ENV_CHK_INTERVAL);
00160
00161 CSourceCommon::play();
00162 }
00163
00164 void CBackgroundSource::stop()
00165 {
00166 if (_Playing)
00167 {
00168 CAudioMixerUser *mixer = CAudioMixerUser::instance();
00169 mixer->unregisterUpdate(this);
00170 mixer->removeEvents(this);
00171
00172 while (!_Sources.empty())
00173 {
00174 TSubSource &subSource = _Sources.back();
00175 if (subSource.Source != NULL)
00176 {
00177
00178
00179 delete subSource.Source;
00180
00181 }
00182 _Sources.pop_back();
00183 }
00184 }
00185
00186 CSourceCommon::stop();
00187 }
00188
00189 void CBackgroundSource::onUpdate()
00190 {
00191
00192 CAudioMixerUser *mixer = CAudioMixerUser::instance();
00193 bool doFade = false;
00194 TTime now = NLMISC::CTime::getLocalTime();
00195 float gain;
00196
00197 vector<TSubSource>::iterator first(_Sources.begin()), last(_Sources.end());
00198 for (; first != last; ++first)
00199 {
00200 if (first->Source != NULL)
00201 {
00202 if (first->Status == SUB_STATUS_FADEIN)
00203 {
00204 if (first->FilterFadeIn > 0)
00205 gain = (now - first->FadeStart) / float(first->FilterFadeIn);
00206 else
00207 gain = 1.0f;
00208
00209 if (gain < 1.0f)
00210 {
00211 first->Source->setRelativeGain(gain);
00212 doFade = true;
00213 }
00214 else
00215 {
00216
00217 first->Source->setRelativeGain(1.0f * _Gain);
00218 first->Status = SUB_STATUS_PLAY;
00219 }
00220 }
00221 else if (first->Status == SUB_STATUS_FADEOUT)
00222 {
00223 if (first->FilterFadeOut > 0)
00224 gain = 1.0f - (now - first->FadeStart) / float(first->FilterFadeOut);
00225 else
00226 gain = 0.0f;
00227 if (gain > 0.0f)
00228 {
00229 first->Source->setRelativeGain(gain * _Gain);
00230 doFade = true;
00231 }
00232 else
00233 {
00234 first->Source->stop();
00235 first->Status = SUB_STATUS_STOP;
00236 }
00237 }
00238 }
00239 }
00240
00241
00242 if (!doFade)
00243 mixer->unregisterUpdate(this);
00244 }
00245
00246 void CBackgroundSource::onEvent()
00247 {
00248
00249 CAudioMixerUser *mixer = CAudioMixerUser::instance();
00250
00251 bool doFade = false;
00252 TTime now = NLMISC::CTime::getLocalTime();
00253
00254 vector<TSubSource>::iterator first(_Sources.begin()), last(_Sources.end());
00255 for (; first != last; ++first)
00256 {
00257 if (first->Source != NULL)
00258 {
00259 if (checkFilter(first->Filter))
00260 {
00261
00262 if (first->Status == SUB_STATUS_STOP)
00263 {
00264 first->Status = SUB_STATUS_FADEIN;
00265 first->Source->setRelativeGain(0.0f);
00266 first->Source->setPos(_Position);
00267 first->Source->play();
00268 first->FadeStart = now;
00269 doFade = true;
00270 }
00271 else if (first->Status == SUB_STATUS_FADEOUT)
00272 {
00273 first->Status = SUB_STATUS_FADEIN;
00274
00275 first->FadeStart = now - (first->FadeStart - first->FilterFadeOut);
00276 doFade = true;
00277 }
00278 }
00279 else
00280 {
00281
00282 if (first->Status == SUB_STATUS_PLAY)
00283 {
00284 first->Status = SUB_STATUS_FADEOUT;
00285 first->FadeStart = now;
00286 doFade = true;
00287 }
00288 else if (first->Status == SUB_STATUS_FADEIN)
00289 {
00290 first->Status = SUB_STATUS_FADEOUT;
00291
00292 first->FadeStart = now - (first->FadeStart - first->FilterFadeIn);
00293 doFade = true;
00294 }
00295 }
00296 }
00297 }
00298
00299 if (doFade)
00300 {
00301
00302 mixer->registerUpdate(this);
00303 }
00304
00305 _LastCheck = NLMISC::CTime::getLocalTime();
00306
00307
00308 mixer->addEvent(this, _LastCheck + ENV_CHK_INTERVAL);
00309 }
00310
00311
00312 bool CBackgroundSource::checkFilter(const UAudioMixer::TBackgroundFlags &filter)
00313 {
00314
00315 const UAudioMixer::TBackgroundFlags &bg = CAudioMixerUser::instance()->getBackgroundSoundManager()->getBackgroundFlags();
00316
00317 bool ok = true;
00318
00319 for (uint i=0; i<16; ++i)
00320 ok &= filter.Flags[i] || !bg.Flags[i];
00321
00322 return ok;
00323 }
00324
00325
00326 }