# Home    # nevrax.com   
Nevrax
Nevrax.org
#News
#Mailing-list
#Documentation
#CVS
#Bugs
#License
Docs
 
Documentation  
Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages   Search  

background_source.cpp

Go to the documentation of this file.
00001 
00007 /* Copyright, 2001 Nevrax Ltd.
00008  *
00009  * This file is part of NEVRAX NEL.
00010  * NEVRAX NEL is free software; you can redistribute it and/or modify
00011  * it under the terms of the GNU General Public License as published by
00012  * the Free Software Foundation; either version 2, or (at your option)
00013  * any later version.
00014 
00015  * NEVRAX NEL is distributed in the hope that it will be useful, but
00016  * WITHOUT ANY WARRANTY; without even the implied warranty of
00017  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
00018  * General Public License for more details.
00019 
00020  * You should have received a copy of the GNU General Public License
00021  * along with NEVRAX NEL; see the file COPYING. If not, write to the
00022  * Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
00023  * MA 02111-1307, USA.
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         // Set an event for next env checking.
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 //                              subSource.Source->stop();
00178                                 //mixer->removeSource(subSource.Source);
00179                                 delete subSource.Source;
00180 
00181                         }
00182                         _Sources.pop_back();
00183                 }
00184         }
00185 
00186         CSourceCommon::stop();
00187 }
00188 
00189 void CBackgroundSource::onUpdate()
00190 {
00191         // this is called for fade in/out.
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                                         // fade end
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         // any fade to update ?
00242         if (!doFade)
00243                 mixer->unregisterUpdate(this);
00244 }
00245 
00246 void CBackgroundSource::onEvent()
00247 {
00248         // check all sounds and test for start or stop.
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                                 // source ok
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                                         // Replace fade start date to smoosly reverse the fade.
00275                                         first->FadeStart = now - (first->FadeStart - first->FilterFadeOut);
00276                                         doFade = true;
00277                                 }
00278                         }
00279                         else
00280                         {
00281                                 // source masked.
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                                         // Replace fade start date to smoosly reverse the fade.
00292                                         first->FadeStart = now - (first->FadeStart - first->FilterFadeIn);
00293                                         doFade = true;
00294                                 }
00295                         }
00296                 }
00297         }
00298 
00299         if (doFade)
00300         {
00301                 // register for fade in/out
00302                 mixer->registerUpdate(this);
00303         }
00304 
00305         _LastCheck = NLMISC::CTime::getLocalTime();
00306 
00307         // set the next event.
00308         mixer->addEvent(this, _LastCheck + ENV_CHK_INTERVAL);
00309 }
00310 
00311 
00312 bool CBackgroundSource::checkFilter(const UAudioMixer::TBackgroundFlags &filter)
00313 {
00314         // Get the current environnement from the bakgound sound manager.
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 } // NLSOUND