X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=src%2FSound%2Fsoundmgr.cxx;h=b303a11cdcfe8acf06b38fd16d24df29969c31d7;hb=198b88ca9b4a4b123b2e9ccdc85ea17eeaea70c6;hp=aa4b6f4f0d8c4acc846c2006850dfa164823e2f8;hpb=d8b6786d20a6762b31ccdfded78b1b5da9ac56e3;p=flightgear.git diff --git a/src/Sound/soundmgr.cxx b/src/Sound/soundmgr.cxx index aa4b6f4f0..b303a11cd 100644 --- a/src/Sound/soundmgr.cxx +++ b/src/Sound/soundmgr.cxx @@ -34,8 +34,15 @@ #define FG_SOUND_SAFETY_MULT 3 #define FG_MAX_SOUND_SAFETY ( 1.0 / FG_SOUND_SAFETY_MULT ) +// +// SimpleSound +// + // constructor -FGSimpleSound::FGSimpleSound( string file ) { +FGSimpleSound::FGSimpleSound( string file ) + : pitch(1.0), + volume(1.0) +{ SGPath slfile( globals->get_fg_root() ); slfile.append( file ); sample = new slSample ( (char *)slfile.c_str() ); @@ -45,7 +52,10 @@ FGSimpleSound::FGSimpleSound( string file ) { volume_envelope->setStep ( 0, 0.01, 1.0 ); } -FGSimpleSound::FGSimpleSound( unsigned char *buffer, int len ) { +FGSimpleSound::FGSimpleSound( unsigned char *buffer, int len ) + : pitch(1.0), + volume(1.0) +{ sample = new slSample ( buffer, len ); pitch_envelope = new slEnvelope( 1, SL_SAMPLE_ONE_SHOT ); volume_envelope = new slEnvelope( 1, SL_SAMPLE_ONE_SHOT ); @@ -60,6 +70,32 @@ FGSimpleSound::~FGSimpleSound() { delete sample; } +void FGSimpleSound::play( slScheduler *sched, bool looped ) { + + // make sure sound isn't already playing + if ( sample->getPlayCount() > 0 ) { + sched->stopSample(sample); + // return; + } + + if ( looped ) { + sched->loopSample(sample); + } else { + sched->playSample(sample); + } + + sched->addSampleEnvelope(sample, 0, 0, pitch_envelope, SL_PITCH_ENVELOPE); + sched->addSampleEnvelope(sample, 0, 1, volume_envelope, SL_VOLUME_ENVELOPE); +} + +void FGSimpleSound::stop( slScheduler *sched, bool quick ) { + + sched->stopSample( sample ); +} + +// +// Sound Manager +// // constructor FGSoundMgr::FGSoundMgr() { @@ -89,6 +125,8 @@ FGSoundMgr::~FGSoundMgr() { sample_map_iterator sample_end = samples.end(); for ( ; sample_current != sample_end; ++sample_current ) { sample_ref *sr = sample_current->second; + + audio_sched->stopSample(sr->sample); delete sr->sample; delete sr; } @@ -100,6 +138,9 @@ FGSoundMgr::~FGSoundMgr() { sound_map_iterator sound_end = sounds.end(); for ( ; sound_current != sound_end; ++sound_current ) { FGSimpleSound *s = sound_current->second; + + audio_sched->stopSample(s->get_sample()); + delete s->get_sample(); delete s; } @@ -110,7 +151,6 @@ FGSoundMgr::~FGSoundMgr() { // initialize the sound manager void FGSoundMgr::init() { - last.stamp(); safety = FG_MAX_SOUND_SAFETY; // audio_mixer -> setMasterVolume ( 80 ) ; /* 80% of max volume. */ @@ -124,6 +164,8 @@ void FGSoundMgr::init() { sample_map_iterator sample_end = samples.end(); for ( ; sample_current != sample_end; ++sample_current ) { sample_ref *sr = sample_current->second; + + audio_sched->stopSample(sr->sample); delete sr->sample; delete sr; } @@ -136,6 +178,8 @@ void FGSoundMgr::init() { sound_map_iterator sound_end = sounds.end(); for ( ; sound_current != sound_end; ++sound_current ) { FGSimpleSound *s = sound_current->second; + + audio_sched->stopSample(s->get_sample()); delete s->get_sample(); delete s; } @@ -143,11 +187,13 @@ void FGSoundMgr::init() { } + void FGSoundMgr::bind () { // no properties yet } + void FGSoundMgr::unbind () { // no properties yet @@ -155,17 +201,11 @@ void FGSoundMgr::unbind () // run the audio scheduler -void FGSoundMgr::update(int dt) { - SGTimeStamp current; - current.stamp(); - - double elapsed = (double)(current - last) / 1000000.0; - last = current; - - if ( elapsed > safety ) { - safety = elapsed; +void FGSoundMgr::update( double dt ) { + if ( dt > safety ) { + safety = dt; } else { - safety = safety * 0.99 + elapsed * 0.01; + safety = safety * 0.99 + dt * 0.01; } if ( safety > FG_MAX_SOUND_SAFETY ) { safety = FG_MAX_SOUND_SAFETY; @@ -178,12 +218,35 @@ void FGSoundMgr::update(int dt) { } +void +FGSoundMgr::pause () +{ + audio_sched->pauseSample(0, 0); +} + + +void +FGSoundMgr::resume () +{ + audio_sched->resumeSample(0, 0); +} + + // add a sound effect, return true if successful bool FGSoundMgr::add( FGSimpleSound *sound, const string& refname ) { - sample_map_iterator it = samples.find(refname); - if (it != samples.end()) - return false; + sound_map_iterator sound_it = sounds.find( refname ); + if ( sound_it != sounds.end() ) { + // sound already exists + return false; + } + + sample_map_iterator sample_it = samples.find( refname ); + if ( sample_it != samples.end() ) { + // this sound has existed in the past and it's sample is still + // here, delete the sample so we can replace it. + samples.erase( sample_it ); + } sample_ref *sr = new sample_ref; @@ -196,11 +259,12 @@ bool FGSoundMgr::add( FGSimpleSound *sound, const string& refname ) { return true; } + // add a sound from a file, return the sample if successful, else return NULL FGSimpleSound *FGSoundMgr::add( const string& refname, const string &file ) { FGSimpleSound *sound; - if (file == (string)"") + if (file.empty()) return NULL; sample_map_iterator it = samples.find(file); @@ -227,6 +291,7 @@ FGSimpleSound *FGSoundMgr::add( const string& refname, const string &file ) { return sound; } + // remove a sound effect, return true if successful bool FGSoundMgr::remove( const string& refname ) { @@ -261,9 +326,11 @@ bool FGSoundMgr::remove( const string& refname ) { // delete sample; sounds.erase( it ); + // cout << "sndmgr: removed -> " << refname << endl; return true; - } else { - return false; + } else { + // cout << "sndmgr: failed remove -> " << refname << endl; + return false; } } @@ -285,7 +352,7 @@ FGSimpleSound *FGSoundMgr::find( const string& refname ) { sound_map_iterator it = sounds.find( refname ); if ( it != sounds.end() ) { return it->second; - } else { + } else { return NULL; } } @@ -294,66 +361,46 @@ FGSimpleSound *FGSoundMgr::find( const string& refname ) { // tell the scheduler to play the indexed sample in a continuous // loop bool FGSoundMgr::play_looped( const string& refname ) { - sound_map_iterator it = sounds.find( refname ); - if ( it != sounds.end() ) { - FGSimpleSound *sample = it->second; - audio_sched->loopSample( sample->get_sample() ); - audio_sched->addSampleEnvelope( sample->get_sample(), 0, 0, - sample->get_pitch_envelope(), - SL_PITCH_ENVELOPE ); - audio_sched->addSampleEnvelope( sample->get_sample(), 0, 1, - sample->get_volume_envelope(), - SL_VOLUME_ENVELOPE ); - - return true; - } else { - return false; - } + FGSimpleSound *sample; + + if ((sample = find( refname )) == NULL) + return false; + + sample->play(audio_sched, true); + return true; } // tell the scheduler to play the indexed sample once bool FGSoundMgr::play_once( const string& refname ) { - sound_map_iterator it = sounds.find( refname ); - if ( it != sounds.end() ) { - FGSimpleSound *sample = it->second; - audio_sched->stopSample( sample->get_sample() ); - audio_sched->playSample( sample->get_sample() ); - audio_sched->addSampleEnvelope( sample->get_sample(), 0, 0, - sample->get_pitch_envelope(), - SL_PITCH_ENVELOPE ); - audio_sched->addSampleEnvelope( sample->get_sample(), 0, 1, - sample->get_volume_envelope(), - SL_VOLUME_ENVELOPE ); - - return true; - } else { - return false; - } + FGSimpleSound *sample; + + if ((sample = find( refname )) == NULL) + return false; + + sample->play(audio_sched, false); + return true; } // return true of the specified sound is currently being played bool FGSoundMgr::is_playing( const string& refname ) { - sound_map_iterator it = sounds.find( refname ); - if ( it != sounds.end() ) { - FGSimpleSound *sample = it->second; - return (sample->get_sample()->getPlayCount() > 0 ); - return true; - } else { - return false; - } + FGSimpleSound *sample; + + if ((sample = find( refname )) == NULL) + return false; + + return (sample->get_sample()->getPlayCount() > 0 ); } // immediate stop playing the sound bool FGSoundMgr::stop( const string& refname ) { - sound_map_iterator it = sounds.find( refname ); - if ( it != sounds.end() ) { - FGSimpleSound *sample = it->second; - audio_sched->stopSample( sample->get_sample() ); - return true; - } else { - return false; - } + FGSimpleSound *sample; + + if ((sample = find( refname )) == NULL) + return false; + + audio_sched->stopSample( sample->get_sample() ); + return true; }