#include <ambiant_source.h>
Plays a stereo mix made up of two channels for crossfading random ambiant sounds, plus a third channel for random sparse sounds.
Nevrax France
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). | |
CSimpleSource * | getChannels () |
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.
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 } |
|
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 } |
|
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 } |
|
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 } |
|
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 } |
|
Return the stereo channels (EDIT).
Definition at line 79 of file ambiant_source.h. References _StereoChannels.
00079 { return _StereoChannels; } |
|
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 } |
|
Static init (call at the very beginning).
Definition at line 59 of file ambiant_source.h.
00060 {
00061 //NLMISC_REGISTER_CLASS(CAmbiantSource);
00062 }
|
|
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 } |
|
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 } |
|
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 } |
|
Definition at line 105 of file ambiant_source.h. Referenced by enable(), initPos(), setProperties(), and update(). |
|
Definition at line 114 of file ambiant_source.h. Referenced by calcPosInCycle(), setProperties(), and update(). |
|
Definition at line 111 of file ambiant_source.h. Referenced by calcRandomSparseSoundTime(), and update(). |
|
Definition at line 98 of file ambiant_source.h. |
|
Definition at line 110 of file ambiant_source.h. |
|
Definition at line 116 of file ambiant_source.h. Referenced by calcRandomSparseSoundTime(), and setProperties(). |
|
Definition at line 105 of file ambiant_source.h. Referenced by initPos(), setProperties(), and update(). |
|
Definition at line 108 of file ambiant_source.h. |
|
Definition at line 101 of file ambiant_source.h. Referenced by CAmbiantSource(), enable(), getChannels(), initPos(), update(), and ~CAmbiantSource(). |
|
Definition at line 102 of file ambiant_source.h. |
|
Definition at line 109 of file ambiant_source.h. Referenced by update(). |
|
Definition at line 115 of file ambiant_source.h. Referenced by calcPosInCycle(), and setProperties(). |