diff --git a/src/Sound/fg_fx.cxx b/src/Sound/fg_fx.cxx index 2c7f5626d..0be353279 100644 --- a/src/Sound/fg_fx.cxx +++ b/src/Sound/fg_fx.cxx @@ -41,6 +41,8 @@ FGFX::FGFX () FGFX::~FGFX () { + for (unsigned int i = 0; i < _sound.size(); i++ ) + delete _sound[i]; } void diff --git a/src/Sound/fg_sound.cxx b/src/Sound/fg_sound.cxx index 6fe6d37a7..c7184d885 100644 --- a/src/Sound/fg_sound.cxx +++ b/src/Sound/fg_sound.cxx @@ -49,7 +49,7 @@ static double _fg_log(double v) { return (v < 1) ? 0 : log(v+1); }; // static double _fg_pow3(double v) { return pow(v, 3); }; static const struct { - string name; + char *name; double (*fn)(double); } __fg_snd_fn[] = { // {"lin", _fg_lin}, @@ -125,7 +125,6 @@ FGSound::init() SG_LOG( SG_GENERAL, SG_INFO, "Unknown sound type, default to 'level'"); } - #if 0 // // set position properties @@ -236,16 +235,11 @@ FGSound::init() // Initialize the sample // FGSoundMgr * mgr = globals->get_soundmgr(); - if (mgr->find(_name) == NULL) { + if ((_sample = mgr->find(_name)) == NULL) _sample = mgr->add(_name, _node->getStringValue("path")); - _sample->set_volume(v); - _sample->set_pitch(p); - } else { - _sample = mgr->find(_name); - _sample->set_volume(_sample->get_volume() + v); - _sample->set_pitch(_sample->get_pitch() + p); - } + _sample->set_volume(v); + _sample->set_pitch(p); } void @@ -280,10 +274,10 @@ FGSound::update (int dt) // If the state changes to false, stop playing. // if (!check) { - _active = false; - if (mgr->is_playing(_name)) { + if (_active) { SG_LOG(SG_GENERAL, SG_INFO, "Stopping sound: " << _name); - mgr->stop(_name); + _sample->stop( mgr->get_scheduler(), false ); + _active = false; } return; @@ -305,83 +299,84 @@ FGSound::update (int dt) // Check for state changes. // If the state changed, and the sound is still playing: stop playing. // - if (mgr->is_playing(_name)) { + if (_sample->is_playing()) { SG_LOG(SG_GENERAL, SG_INFO, "Stopping sound: " << _name); - mgr->stop(_name); + _sample->stop( mgr->get_scheduler() ); } if ( ((_type == FGSound::RAISE) && !check) || ((_type == FGSound::FALL) && check) ) return; + } - // - // Update the volume - // - int max = _volume.size(); + // + // Update the volume + // + int max = _volume.size(); - int i; - double volume = 1.0, volume_offset = 0.0; - for(i = 0; i < max; i++) { - double v = _volume[i].prop->getDoubleValue(); + int i; + double volume = 1.0, volume_offset = 0.0; + for(i = 0; i < max; i++) { + double v = _volume[i].prop->getDoubleValue(); - if (_volume[i].fn) - v = _volume[i].fn(v); + if (_volume[i].fn) + v = _volume[i].fn(v); - v *= _volume[i].factor; + v *= _volume[i].factor; - if (v > _volume[i].max) - v = _volume[i].max; - else - if (v < _volume[i].min) - v = 0; // v = _volume[i].min; + if (v > _volume[i].max) + v = _volume[i].max; + else + if (v < _volume[i].min) + v = 0; // v = _volume[i].min; - if (_volume[i].subtract) // Hack! - volume = _volume[i].offset - v; - else { - volume_offset += _volume[i].offset; - volume *= v; + if (_volume[i].subtract) // Hack! + volume = _volume[i].offset - v; + else { + volume_offset += _volume[i].offset; + volume *= v; + } } - } - // - // Update the pitch - // - max = _pitch.size(); - double pitch = 1.0, pitch_offset = 0.0; - for(i = 0; i < max; i++) { - double p = _pitch[i].prop->getDoubleValue(); + // + // Update the pitch + // + max = _pitch.size(); + double pitch = 1.0, pitch_offset = 0.0; + for(i = 0; i < max; i++) { + double p = _pitch[i].prop->getDoubleValue(); - if (_pitch[i].fn) - p = _pitch[i].fn(p); + if (_pitch[i].fn) + p = _pitch[i].fn(p); - p *= _pitch[i].factor; + p *= _pitch[i].factor; - if (p > _pitch[i].max) - p = _pitch[i].max; - else - if (p < _pitch[i].min) - p = _pitch[i].min; + if (p > _pitch[i].max) + p = _pitch[i].max; + else + if (p < _pitch[i].min) + p = _pitch[i].min; - if (_pitch[i].subtract) // Hack! - pitch = _pitch[i].offset - p; - else { - pitch_offset += _pitch[i].offset; - pitch *= p; + if (_pitch[i].subtract) // Hack! + pitch = _pitch[i].offset - p; + else { + pitch_offset += _pitch[i].offset; + pitch *= p; + } } - } - // - // Change sample state - // - _sample->set_pitch( pitch_offset + pitch ); - _sample->set_volume( volume_offset + volume ); + // + // Change sample state + // + _sample->set_pitch( pitch_offset + pitch ); + _sample->set_volume( volume_offset + volume ); // // Do we need to start playing the sample? // - if (_active && ((_type == FGSound::LEVEL) || (_type == FGSound::INVERTED))) - return; + if (_active && (_type == FGSound::LEVEL) || (_type == FGSound::INVERTED)) + return; // // This is needed for FGSound::FLIPFLOP and it works for @@ -397,6 +392,4 @@ FGSound::update (int dt) SG_LOG(SG_GENERAL, SG_INFO, "Starting audio playback for: " << _name); SG_LOG(SG_GENERAL, SG_BULK, "Playing " << ((_mode == ONCE) ? "once" : "looped")); - SG_LOG(SG_GENERAL, SG_BULK, "Initial volume: " << volume_offset); - SG_LOG(SG_GENERAL, SG_BULK, "Initial pitch: " << pitch_offset); } diff --git a/src/Sound/soundmgr.cxx b/src/Sound/soundmgr.cxx index eb51afac6..0580ae588 100644 --- a/src/Sound/soundmgr.cxx +++ b/src/Sound/soundmgr.cxx @@ -39,7 +39,11 @@ // // constructor -FGSimpleSound::FGSimpleSound( string file ) { +FGSimpleSound::FGSimpleSound( string file ) + : requests(0), + volume(1.0), + pitch(1.0) +{ SGPath slfile( globals->get_fg_root() ); slfile.append( file ); sample = new slSample ( (char *)slfile.c_str() ); @@ -49,7 +53,11 @@ 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 ) + : requests(0), + volume(1.0), + pitch(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 ); @@ -64,17 +72,34 @@ FGSimpleSound::~FGSimpleSound() { delete sample; } -void FGSimpleSound::play_once( slScheduler *sched ) { - sched->stopSample(sample); - sched->playSample(sample); +void FGSimpleSound::play( slScheduler *sched, bool looped ) { + + requests++; + if (requests > 1) + return; + + // sched->stopSample(sample); + 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::play_looped( slScheduler *sched ) { - sched->loopSample(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 ) { + + if (quick) + requests = 0; + else + if (--requests < 0) + requests = 0; + + if (requests > 0) + return; + + sched->stopSample( sample ); } // diff --git a/src/Sound/soundmgr.hxx b/src/Sound/soundmgr.hxx index d47e9730a..8a54ee457 100644 --- a/src/Sound/soundmgr.hxx +++ b/src/Sound/soundmgr.hxx @@ -57,7 +57,7 @@ private: slEnvelope *volume_envelope; double pitch; double volume; - int clients; + int requests; public: @@ -65,19 +65,12 @@ public: FGSimpleSound( unsigned char *buffer, int len ); ~FGSimpleSound(); - void play_once( slScheduler *sched ); - void play_looped( slScheduler *sched ); + void play( slScheduler *sched, bool looped ); + void stop( slScheduler *sched, bool quick = true ); - inline void play( slScheduler *sched, bool looped ) { - if (looped) play_looped( sched ); - else play_once( sched ); - } - inline void stop( slScheduler *sched ) { - sched->stopSample( sample ); - } - inline bool is_playing( ) { - return (sample->getPlayCount() > 0 ); - } + inline void play_once( slScheduler *sched ) { play( sched, false); } + inline void play_looped( slScheduler *sched ) { play( sched, true); } + inline bool is_playing( ) { return (requests > 0 ); } inline double get_pitch() const { return pitch; } inline void set_pitch( double p ) { diff --git a/tests/test-env-map.cxx b/tests/test-env-map.cxx index ef56255c7..ada7b37be 100644 --- a/tests/test-env-map.cxx +++ b/tests/test-env-map.cxx @@ -98,6 +98,8 @@ void init(void) glGenTextures(1, &texName); glBindTexture(GL_TEXTURE_2D, texName); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, TEXRES_X, TEXRES_Y, 0, GL_RGBA, GL_UNSIGNED_BYTE, env_map); @@ -149,6 +151,7 @@ void display() glEnable(GL_TEXTURE_GEN_S); glEnable(GL_TEXTURE_GEN_T); + /* glBegin(GL_QUADS); glNormal3f(0.0, 0.0, 1.0); glVertex3f(1.0, 1.0, 0.0); @@ -156,6 +159,13 @@ void display() glVertex3f(-1.0, -1.0, 0.0); glVertex3f(1.0, -1.0, 0.0); glEnd(); + */ + + glPointSize(48.0); + glBegin(GL_POINTS); + glNormal3f(0.0, 0.0, 1.0); + glVertex3f(0.0, 0.0, 0.0); + glEnd(); glDisable(GL_TEXTURE_GEN_S); glDisable(GL_TEXTURE_GEN_T);