#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(). |
1.3.6