NLSOUND::CAmbiantSource Class Reference

#include <ambiant_source.h>


Detailed Description

Stereo mix of a envsound, seen as a source (see CEnvSoundUser)

Plays a stereo mix made up of two channels for crossfading random ambiant sounds, plus a third channel for random sparse sounds.

Author:
Olivier Cado

Nevrax France

Date:
2001

Definition at line 50 of file ambiant_source.h.

Public Member Functions

 CAmbiantSource ()
 Constructor.

virtual void enable (bool toplay, float gain)
 Enable (play with high priority) and set general gain, or disable (stop and set low priority).

CSimpleSourcegetChannels ()
 Return the stereo channels (EDIT).

virtual void initPos (const NLMISC::CVector *posvector)
void setProperties (std::vector< TSoundId > &ambiantsounds, std::vector< TSoundId > &sparsesounds, uint32 crossfadeTimeMs=4000, uint32 sustainTimeMs=16000, uint32 sparseAvgPeriodMs=30000)
 Set properties (EDIT).

virtual void update ()
 Update.

virtual ~CAmbiantSource ()
 Destructor.


Static Public Member Functions

void init ()
 Static init (call at the very beginning).


Protected Member Functions

NLMISC::TTime calcPosInCycle (bool &crossfade, uint32 &leadchannel)
 Calc pos in cycle.

void calcRandomSparseSoundTime (TSoundId currentsparesound)
 Calculate the next time a sparse sound plays (set NULL for no current sound).

TSoundId getRandomSound (const std::vector< CSound * > &bank) const
 Select a random sound in a bank.


Private Attributes

std::vector< CSound * > _AmbiantSounds
uint32 _CrossfadeTime
NLMISC::TTime _NextSparseSoundTime
bool _Play
bool _RandomSoundChosen
uint32 _SparseAvgPeriod
std::vector< CSound * > _SparseSounds
NLMISC::TTime _StartTime
CSimpleSource _StereoChannels [3]
float _StereoGain
bool _Sustain
uint32 _SustainTime


Constructor & Destructor Documentation

NLSOUND::CAmbiantSource::CAmbiantSource  ) 
 

Constructor.

Definition at line 47 of file ambiant_source.cpp.

References _StereoChannels, AMBIANT_CH1, AMBIANT_CH2, NLSOUND::CSimpleSource::setLooping(), and uint32.

00047                                : _Play(false),
00048                                                                    _StereoGain(0.0f),
00049                                                                    _Sustain(false),
00050                                                                    _RandomSoundChosen(false),
00051                                                                    _NextSparseSoundTime(0),
00052                                                                    _CrossfadeTime(4000),
00053                                                                    _SustainTime(8000),
00054                                                                    _SparseAvgPeriod(20000)
00055 {
00056         _StereoChannels[AMBIANT_CH1].setLooping( true );
00057         _StereoChannels[AMBIANT_CH2].setLooping( true );
00058         //_StereoChannels[SPARSE_CH].setLooping( false );
00059 
00060         srand( (uint32)CTime::getLocalTime() );
00061 }

NLSOUND::CAmbiantSource::~CAmbiantSource  )  [virtual]
 

Destructor.

Definition at line 67 of file ambiant_source.cpp.

References _StereoChannels, AMBIANT_CH1, AMBIANT_CH2, and SPARSE_CH.

00068 {
00069         CAudioMixerUser::instance()->removeMySource( &_StereoChannels[AMBIANT_CH1] );
00070         CAudioMixerUser::instance()->removeMySource( &_StereoChannels[AMBIANT_CH2] );
00071         CAudioMixerUser::instance()->removeMySource( &_StereoChannels[SPARSE_CH] );
00072 
00073         // Delete sounds: now done in CAudioMixerUser::~CAudioMixerUser()
00074         /*vector<CSound*>::iterator ipsnds;
00075         for ( ipsnds=_AmbiantSounds.begin(); ipsnds!=_AmbiantSounds.end(); ++ipsnds )
00076         {
00077                 nldebug( "Deleting ambiant sound" );
00078                 delete (*ipsnds);
00079         }
00080         for ( ipsnds=_SparseSounds.begin(); ipsnds!=_SparseSounds.end(); ++ipsnds )
00081         {
00082                 nldebug( "Deleting sparse sound" );
00083                 delete (*ipsnds);
00084         }
00085         */
00086 }


Member Function Documentation

TTime NLSOUND::CAmbiantSource::calcPosInCycle bool &  crossfade,
uint32 leadchannel
[protected]
 

Calc pos in cycle.

Definition at line 212 of file ambiant_source.cpp.

References _CrossfadeTime, _SustainTime, and uint32.

Referenced by enable(), and update().

00213 {
00214         TTime pos = CTime::getLocalTime();
00215         uint32 cycletime = _CrossfadeTime + _SustainTime;
00216         pos = pos % (cycletime*2);
00217 
00218         // Calc which channel will be the lead one
00219         if ( pos < cycletime )
00220         {
00221                 leadchannel = 0;
00222         }
00223         else
00224         {
00225                 leadchannel = 1;
00226                 pos = pos - (cycletime);
00227         }
00228 
00229         // Calc if the pos is in the first part (crossfade) or in the other part (sustain)
00230         crossfade = ( pos < _CrossfadeTime );
00231         
00232         return pos;
00233 }

void NLSOUND::CAmbiantSource::calcRandomSparseSoundTime TSoundId  currentsparesound  )  [protected]
 

Calculate the next time a sparse sound plays (set NULL for no current sound).

Definition at line 353 of file ambiant_source.cpp.

References _NextSparseSoundTime, _SparseAvgPeriod, NLSOUND::CSound::getDuration(), nldebug, NLSOUND::TSoundId, uint, and uint32.

Referenced by enable(), and update().

00354 {
00355         uint32 delay = (uint)((float)rand() * (float)(_SparseAvgPeriod*2) / (float)RAND_MAX);
00356 
00357         // Check the next sound will play after the current one
00358         if ( currentsparesound != NULL )
00359         {
00360                 uint32 soundlength = currentsparesound->getDuration();
00361                 if ( delay <= soundlength )
00362                 {
00363                         delay = soundlength+1;
00364                 }
00365         }
00366 
00367         nldebug( "AM: EnvSound: Next sparse sound will play in %u ms", delay );
00368         _NextSparseSoundTime = CTime::getLocalTime() + delay;
00369 }

void NLSOUND::CAmbiantSource::enable bool  toplay,
float  gain
[virtual]
 

Enable (play with high priority) and set general gain, or disable (stop and set low priority).

Definition at line 130 of file ambiant_source.cpp.

References _AmbiantSounds, _Play, _StereoChannels, _StereoGain, AMBIANT_CH1, calcPosInCycle(), calcRandomSparseSoundTime(), NLSOUND::CSimpleSource::getSound(), NLSOUND::HighPri, NLSOUND::LowPri, nldebug, NLSOUND::CSimpleSource::play(), NLSOUND::CSourceCommon::setPriority(), SPARSE_CH, NLSOUND::CSimpleSource::stop(), and uint32.

00131 {
00132         // Calc position in cycle
00133         bool crossfade;
00134         uint32 leadchannel;
00135         if ( _AmbiantSounds.size() > 1 )
00136         {
00137                 calcPosInCycle( crossfade, leadchannel );
00138         }
00139         else
00140         {
00141                 crossfade = false;
00142                 leadchannel = AMBIANT_CH1;
00143         }
00144 
00145         // Enable/disable
00146         if ( toplay )
00147         {
00148                 _StereoGain = gain;
00149 
00150                 if ( ! _Play )
00151                 {
00152                         // Start lead channel
00153                         if ( _StereoChannels[leadchannel].getSound() != NULL )
00154                         {
00155                                 nldebug( "AM: Envsound: Switch on channel %u", leadchannel );
00156                                 _StereoChannels[leadchannel].setPriority( HighPri ) ;
00157                                 _StereoChannels[leadchannel].play();
00158                         }
00159 
00160                         // If crossfading, start back channel
00161                         if ( crossfade && (_StereoChannels[1-leadchannel].getSound() != NULL) )
00162                         {
00163                                 nldebug( "AM: Envsound: Switch on channel %u", 1-leadchannel );
00164                                 _StereoChannels[1-leadchannel].setPriority( HighPri ) ;
00165                                 _StereoChannels[1-leadchannel].play();
00166                         }
00167 
00168                         // Calc when the next spare sound will play
00169                         calcRandomSparseSoundTime( NULL );
00170 
00171                         _Play = true;
00172                 }
00173                 // The SPARSE_CH is added only when needed
00174         }
00175         else
00176         {
00177                 if ( _Play )
00178                 {
00179                         // Stop lead channel
00180                         if ( _StereoChannels[leadchannel].getSound() != NULL )
00181                         {
00182                                 nldebug( "AM: Envsound: Switch off channel %u", leadchannel );
00183                                 _StereoChannels[leadchannel].stop();
00184                                 _StereoChannels[leadchannel].setPriority( LowPri );
00185                         }
00186 
00187                         // If crossfading, stop back channel
00188                         if ( crossfade && (_StereoChannels[1-leadchannel].getSound() != NULL) )
00189                         {
00190                                 nldebug( "AM: Envsound: Switch off channel %u", 1-leadchannel );
00191                                 _StereoChannels[1-leadchannel].stop();
00192                                 _StereoChannels[1-leadchannel].setPriority( LowPri );
00193                         }
00194 
00195                         // Stop spare channel, anyway
00196                         if ( _StereoChannels[SPARSE_CH].getSound() != NULL )
00197                         {
00198                                 nldebug( "AM: Envsound: Switch off sparse channel" );
00199                                 _StereoChannels[SPARSE_CH].stop();
00200                                 _StereoChannels[SPARSE_CH].setPriority( LowPri );
00201                         }
00202 
00203                         _Play = false;
00204                 }
00205         }
00206 }

CSimpleSource* NLSOUND::CAmbiantSource::getChannels  )  [inline]
 

Return the stereo channels (EDIT).

Definition at line 79 of file ambiant_source.h.

References _StereoChannels.

00079 { return _StereoChannels; }

TSoundId NLSOUND::CAmbiantSource::getRandomSound const std::vector< CSound * > &  bank  )  const [protected]
 

Select a random sound in a bank.

Definition at line 336 of file ambiant_source.cpp.

References nlassert, nldebug, r, NLSOUND::TSoundId, and uint32.

Referenced by initPos(), and update().

00337 {
00338         nlassert( ! bank.empty() );
00339         // Note: does not work with a very big size (rand()*bank.size() would overflow)
00340         uint32 r = rand()*bank.size()/(RAND_MAX+1);
00341         nlassert( r < bank.size() );
00342         nldebug( "AM: EnvSound: Prepared random sound number %u of %u", r, bank.size()-1 );
00343 
00344         return bank[r];
00345 }

void NLSOUND::CAmbiantSource::init void   )  [inline, static]
 

Static init (call at the very beginning).

Definition at line 59 of file ambiant_source.h.

00060         {               
00061                 //NLMISC_REGISTER_CLASS(CAmbiantSource);                        
00062         }

void NLSOUND::CAmbiantSource::initPos const NLMISC::CVector posvector  )  [virtual]
 

Init. You can pass a position vector to link to (if the playable has stereo source(s)) When reading from a stream, call init() *after* serial().

Definition at line 92 of file ambiant_source.cpp.

References _AmbiantSounds, _SparseSounds, _StereoChannels, AMBIANT_CH1, AMBIANT_CH2, getRandomSound(), NLSOUND::LowPri, NLSOUND::CSourceCommon::set3DPositionVector(), NLSOUND::CSimpleSource::setGain(), NLSOUND::CSourceCommon::setPriority(), and SPARSE_CH.

00093 {
00094         // Initialize ambiant sound channels
00095         if ( ! _AmbiantSounds.empty()  )
00096         {
00097                 _StereoChannels[AMBIANT_CH1].set3DPositionVector( posvector );
00098                 _StereoChannels[AMBIANT_CH1].setSound( getRandomSound( _AmbiantSounds ) );
00099                 _StereoChannels[AMBIANT_CH1].setGain( 0.0f );
00100                 _StereoChannels[AMBIANT_CH1].setPriority( LowPri);
00101                 CAudioMixerUser::instance()->addSource( &_StereoChannels[AMBIANT_CH1] );
00102                 CAudioMixerUser::instance()->giveTrack( &_StereoChannels[AMBIANT_CH1] );
00103                 
00104                 if ( _AmbiantSounds.size() > 1 )
00105                 {
00106                         _StereoChannels[AMBIANT_CH2].set3DPositionVector( posvector );
00107                         _StereoChannels[AMBIANT_CH2].setSound( getRandomSound( _AmbiantSounds ) );
00108                         _StereoChannels[AMBIANT_CH2].setGain( 0.0f );
00109                         _StereoChannels[AMBIANT_CH2].setPriority( LowPri);
00110                         CAudioMixerUser::instance()->addSource( &_StereoChannels[AMBIANT_CH2] );
00111                         CAudioMixerUser::instance()->giveTrack( &_StereoChannels[AMBIANT_CH2] );
00112                 }
00113         }
00114 
00115         // Initialize sparse sounds channel
00116         if ( ! _SparseSounds.empty() )
00117         {
00118                 _StereoChannels[SPARSE_CH].set3DPositionVector( posvector );
00119                 _StereoChannels[SPARSE_CH].setPriority( LowPri );
00120                 _StereoChannels[SPARSE_CH].setSound( getRandomSound( _SparseSounds ) );
00121                 CAudioMixerUser::instance()->addSource( &_StereoChannels[SPARSE_CH] );
00122                 CAudioMixerUser::instance()->giveTrack( &_StereoChannels[SPARSE_CH] );
00123         }
00124 }

void NLSOUND::CAmbiantSource::setProperties std::vector< TSoundId > &  ambiantsounds,
std::vector< TSoundId > &  sparsesounds,
uint32  crossfadeTimeMs = 4000,
uint32  sustainTimeMs = 16000,
uint32  sparseAvgPeriodMs = 30000
 

Set properties (EDIT).

Definition at line 406 of file ambiant_source.cpp.

References _AmbiantSounds, _CrossfadeTime, _SparseAvgPeriod, _SparseSounds, _SustainTime, and uint32.

00410 {
00411         _AmbiantSounds = ambiantsounds;
00412         _SparseSounds = sparsesounds;
00413         _CrossfadeTime = crossfadeTimeMs;
00414         _SustainTime = sustainTimeMs;
00415         _SparseAvgPeriod = sparseAvgPeriodMs;
00416 }

void NLSOUND::CAmbiantSource::update  )  [virtual]
 

Update.

Definition at line 239 of file ambiant_source.cpp.

References _AmbiantSounds, _CrossfadeTime, _NextSparseSoundTime, _Play, _SparseSounds, _StereoChannels, _StereoGain, _Sustain, AMBIANT_CH1, calcPosInCycle(), calcRandomSparseSoundTime(), getRandomSound(), NLSOUND::CSimpleSource::getSound(), NLSOUND::CSimpleSource::getTrack(), NLSOUND::HighPri, NLSOUND::MidPri, nlassert, nldebug, NLSOUND::CSimpleSource::play(), NLSOUND::CSourceCommon::setPriority(), NLSOUND::CSimpleSource::setRelativeGain(), SPARSE_CH, NLSOUND::CSimpleSource::stop(), NLSOUND::TSoundId, and uint32.

00240 {
00241         if ( (!_Play) || (_StereoGain==0.0f) )
00242         {
00243                 return;
00244         }
00245 
00246         // Calc pos in cycle
00247         bool crossfade;
00248         uint32 leadchannel, backchannel=0;
00249         TTime posInCycle=0;
00250         if ( _AmbiantSounds.size() > 1 )
00251         {
00252                 posInCycle = calcPosInCycle( crossfade, leadchannel );
00253                 backchannel = 1 - leadchannel;
00254         }
00255         else
00256         {
00257                 // If there is less than 2 sounds, no crossfade, always sustain (a single sound must be looping)
00258                 crossfade = false;
00259                 leadchannel = AMBIANT_CH1;
00260                 _Sustain = true;
00261         }
00262         
00263         // Crossfade the first two sources
00264         if ( crossfade )
00265         {
00266                 // Attack
00267                 float ratio = (float)posInCycle / (float)_CrossfadeTime;
00268                 _StereoChannels[leadchannel].setRelativeGain( ratio*_StereoGain );
00269                 _StereoChannels[backchannel].setRelativeGain( (1.0f - ratio)*_StereoGain );
00270 
00271                 // Start next sound
00272                 if ( _Sustain )
00273                 {
00274                         nldebug( "AM: EnvSound: Beginning crossfade: channel #%u rising", leadchannel );
00275                         _StereoChannels[leadchannel].setPriority( HighPri ) ;
00276                         _StereoChannels[leadchannel].play();
00277                         _Sustain = false;
00278                 }
00279         }
00280         else
00281         {
00282                 // Set sustain gain (takes into account the possible changes to _StereoGain)
00283                 _StereoChannels[leadchannel].setRelativeGain( _StereoGain );
00284 
00285                 // Prepare next ambiant sound
00286                 if ( ! _Sustain )
00287                 {
00288                         _Sustain = true;
00289                         TSoundId nextsound = getRandomSound( _AmbiantSounds );
00290 #ifdef ENVSOUND_DONT_DUPLICATE_AMBIANT
00291                         nlassert( _AmbiantSounds.size() > 1 ); // or infinite loop
00292                         while ( nextsound == _StereoChannels[leadchannel].getSound() )
00293                         {
00294                                 nldebug( "AM: EnvSound: Avoiding ambiant sound duplication..." );
00295                                 nextsound = getRandomSound( _AmbiantSounds );
00296                         }
00297 #endif
00298                         nldebug( "AM: EnvSound: Sustain: channel #1" );
00299                         _StereoChannels[backchannel].setRelativeGain( 0.0f );
00300                         _StereoChannels[backchannel].stop(); // we don't set the priority to LowPri
00301                         _StereoChannels[backchannel].setSound( nextsound );
00302                 }
00303         }
00304 
00305         // Add a short random sound into the third source
00306         if ( ! _SparseSounds.empty() )
00307         {
00308                 // Set sustain gain (takes into account the possible changes to _StereoGain)
00309                 _StereoChannels[SPARSE_CH].setRelativeGain( _StereoGain );
00310 
00311                 // Start next sparse sound
00312                 TTime now = CTime::getLocalTime();
00313                 if ( now > _NextSparseSoundTime )
00314                 {
00315                         TSoundId nextsound = getRandomSound( _SparseSounds );
00316                         _StereoChannels[SPARSE_CH].stop();
00317                         _StereoChannels[SPARSE_CH].setSound( nextsound );
00318                         _StereoChannels[SPARSE_CH].setPriority( MidPri );
00319                         _StereoChannels[SPARSE_CH].play();
00320                         nldebug( "AM: EnvSound: Playing sparse sound" );
00321                         if ( _StereoChannels[SPARSE_CH].getTrack() == NULL )
00322                         {
00323                                 nldebug( "AM: Ensound: Switch on sparse channel" );
00324                                 nlassert( _StereoChannels[SPARSE_CH].getSound() != NULL );
00325                         }
00326                         // Does not leave the track
00327                         calcRandomSparseSoundTime( nextsound );
00328                 }
00329         }
00330 }


Field Documentation

std::vector<CSound*> NLSOUND::CAmbiantSource::_AmbiantSounds [private]
 

Definition at line 105 of file ambiant_source.h.

Referenced by enable(), initPos(), setProperties(), and update().

uint32 NLSOUND::CAmbiantSource::_CrossfadeTime [private]
 

Definition at line 114 of file ambiant_source.h.

Referenced by calcPosInCycle(), setProperties(), and update().

NLMISC::TTime NLSOUND::CAmbiantSource::_NextSparseSoundTime [private]
 

Definition at line 111 of file ambiant_source.h.

Referenced by calcRandomSparseSoundTime(), and update().

bool NLSOUND::CAmbiantSource::_Play [private]
 

Definition at line 98 of file ambiant_source.h.

Referenced by enable(), and update().

bool NLSOUND::CAmbiantSource::_RandomSoundChosen [private]
 

Definition at line 110 of file ambiant_source.h.

uint32 NLSOUND::CAmbiantSource::_SparseAvgPeriod [private]
 

Definition at line 116 of file ambiant_source.h.

Referenced by calcRandomSparseSoundTime(), and setProperties().

std::vector<CSound*> NLSOUND::CAmbiantSource::_SparseSounds [private]
 

Definition at line 105 of file ambiant_source.h.

Referenced by initPos(), setProperties(), and update().

NLMISC::TTime NLSOUND::CAmbiantSource::_StartTime [private]
 

Definition at line 108 of file ambiant_source.h.

CSimpleSource NLSOUND::CAmbiantSource::_StereoChannels[ 3 ] [private]
 

Definition at line 101 of file ambiant_source.h.

Referenced by CAmbiantSource(), enable(), getChannels(), initPos(), update(), and ~CAmbiantSource().

float NLSOUND::CAmbiantSource::_StereoGain [private]
 

Definition at line 102 of file ambiant_source.h.

Referenced by enable(), and update().

bool NLSOUND::CAmbiantSource::_Sustain [private]
 

Definition at line 109 of file ambiant_source.h.

Referenced by update().

uint32 NLSOUND::CAmbiantSource::_SustainTime [private]
 

Definition at line 115 of file ambiant_source.h.

Referenced by calcPosInCycle(), and setProperties().


The documentation for this class was generated from the following files:
Generated on Tue Mar 16 14:28:05 2004 for NeL by doxygen 1.3.6