00001
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #error "Deprecated"
00027
00028 #include "stdsound.h"
00029
00030 #include "ambiant_source.h"
00031 #include "sound.h"
00032
00033 using namespace NLMISC;
00034 using namespace std;
00035
00036
00037 namespace NLSOUND {
00038
00039
00040
00041 #define ENVSOUND_DONT_DUPLICATE_AMBIANT
00042
00043
00044
00045
00046
00047 CAmbiantSource::CAmbiantSource() : _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
00059
00060 srand( (uint32)CTime::getLocalTime() );
00061 }
00062
00063
00064
00065
00066
00067 CAmbiantSource::~CAmbiantSource()
00068 {
00069 CAudioMixerUser::instance()->removeMySource( &_StereoChannels[AMBIANT_CH1] );
00070 CAudioMixerUser::instance()->removeMySource( &_StereoChannels[AMBIANT_CH2] );
00071 CAudioMixerUser::instance()->removeMySource( &_StereoChannels[SPARSE_CH] );
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086 }
00087
00088
00089
00090
00091
00092 void CAmbiantSource::initPos( const CVector *posvector )
00093 {
00094
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
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 }
00125
00126
00127
00128
00129
00130 void CAmbiantSource::enable( bool toplay, float gain )
00131 {
00132
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
00146 if ( toplay )
00147 {
00148 _StereoGain = gain;
00149
00150 if ( ! _Play )
00151 {
00152
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
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
00169 calcRandomSparseSoundTime( NULL );
00170
00171 _Play = true;
00172 }
00173
00174 }
00175 else
00176 {
00177 if ( _Play )
00178 {
00179
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
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
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 }
00207
00208
00209
00210
00211
00212 TTime CAmbiantSource::calcPosInCycle( bool& crossfade, uint32& leadchannel )
00213 {
00214 TTime pos = CTime::getLocalTime();
00215 uint32 cycletime = _CrossfadeTime + _SustainTime;
00216 pos = pos % (cycletime*2);
00217
00218
00219 if ( pos < cycletime )
00220 {
00221 leadchannel = 0;
00222 }
00223 else
00224 {
00225 leadchannel = 1;
00226 pos = pos - (cycletime);
00227 }
00228
00229
00230 crossfade = ( pos < _CrossfadeTime );
00231
00232 return pos;
00233 }
00234
00235
00236
00237
00238
00239 void CAmbiantSource::update()
00240 {
00241 if ( (!_Play) || (_StereoGain==0.0f) )
00242 {
00243 return;
00244 }
00245
00246
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
00258 crossfade = false;
00259 leadchannel = AMBIANT_CH1;
00260 _Sustain = true;
00261 }
00262
00263
00264 if ( crossfade )
00265 {
00266
00267 float ratio = (float)posInCycle / (float)_CrossfadeTime;
00268 _StereoChannels[leadchannel].setRelativeGain( ratio*_StereoGain );
00269 _StereoChannels[backchannel].setRelativeGain( (1.0f - ratio)*_StereoGain );
00270
00271
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
00283 _StereoChannels[leadchannel].setRelativeGain( _StereoGain );
00284
00285
00286 if ( ! _Sustain )
00287 {
00288 _Sustain = true;
00289 TSoundId nextsound = getRandomSound( _AmbiantSounds );
00290 #ifdef ENVSOUND_DONT_DUPLICATE_AMBIANT
00291 nlassert( _AmbiantSounds.size() > 1 );
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();
00301 _StereoChannels[backchannel].setSound( nextsound );
00302 }
00303 }
00304
00305
00306 if ( ! _SparseSounds.empty() )
00307 {
00308
00309 _StereoChannels[SPARSE_CH].setRelativeGain( _StereoGain );
00310
00311
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
00327 calcRandomSparseSoundTime( nextsound );
00328 }
00329 }
00330 }
00331
00332
00333
00334
00335
00336 TSoundId CAmbiantSource::getRandomSound( const std::vector<CSound*>& bank ) const
00337 {
00338 nlassert( ! bank.empty() );
00339
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 }
00346
00347
00348
00349
00350
00351
00352
00353 void CAmbiantSource::calcRandomSparseSoundTime( TSoundId currentsparesound )
00354 {
00355 uint32 delay = (uint)((float)rand() * (float)(_SparseAvgPeriod*2) / (float)RAND_MAX);
00356
00357
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 }
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406 void CAmbiantSource::setProperties( std::vector<TSoundId>& ambiantsounds,
00407 std::vector<TSoundId>& sparsesounds,
00408 uint32 crossfadeTimeMs, uint32 sustainTimeMs,
00409 uint32 sparseAvgPeriodMs )
00410 {
00411 _AmbiantSounds = ambiantsounds;
00412 _SparseSounds = sparsesounds;
00413 _CrossfadeTime = crossfadeTimeMs;
00414 _SustainTime = sustainTimeMs;
00415 _SparseAvgPeriod = sparseAvgPeriodMs;
00416 }
00417
00418
00419 }