From 76e82a2cbc7c2d64f0678f8c9ffce4543593030b Mon Sep 17 00:00:00 2001 From: Erik Hofman Date: Fri, 27 May 2016 14:40:49 +0200 Subject: [PATCH] Move all OpenAL function calls from SampleMgr to soundMgr --- simgear/sound/CMakeLists.txt | 4 +- simgear/sound/openal_test2.cxx | 2 +- simgear/sound/openal_test3.cxx | 2 +- simgear/sound/readwav.cxx | 2 +- .../sound/{sample_openal.cxx => sample.cxx} | 6 +- .../sound/{sample_openal.hxx => sample.hxx} | 2 +- simgear/sound/sample_group.cxx | 131 ++------------ simgear/sound/sample_group.hxx | 2 +- simgear/sound/soundmgr_openal.cxx | 163 ++++++++++++++++-- simgear/sound/soundmgr_openal.hxx | 60 ++++++- simgear/sound/soundmgr_openal_private.hxx | 4 + simgear/sound/xmlsound.cxx | 2 +- 12 files changed, 237 insertions(+), 143 deletions(-) rename simgear/sound/{sample_openal.cxx => sample.cxx} (98%) rename simgear/sound/{sample_openal.hxx => sample.hxx} (99%) diff --git a/simgear/sound/CMakeLists.txt b/simgear/sound/CMakeLists.txt index c2538938..cd52e6d1 100644 --- a/simgear/sound/CMakeLists.txt +++ b/simgear/sound/CMakeLists.txt @@ -1,16 +1,16 @@ include (SimGearComponent) set(HEADERS + sample.hxx sample_group.hxx - sample_openal.hxx soundmgr_openal.hxx xmlsound.hxx readwav.hxx ) set(SOURCES + sample.cxx sample_group.cxx - sample_openal.cxx soundmgr_openal.cxx xmlsound.cxx readwav.cxx diff --git a/simgear/sound/openal_test2.cxx b/simgear/sound/openal_test2.cxx index 43bd464d..260eea97 100644 --- a/simgear/sound/openal_test2.cxx +++ b/simgear/sound/openal_test2.cxx @@ -12,7 +12,7 @@ #include "soundmgr_openal.hxx" #include "sample_group.hxx" -#include "sample_openal.hxx" +#include "sample.hxx" int main( int argc, char *argv[] ) { diff --git a/simgear/sound/openal_test3.cxx b/simgear/sound/openal_test3.cxx index bbf5b089..e93aa272 100644 --- a/simgear/sound/openal_test3.cxx +++ b/simgear/sound/openal_test3.cxx @@ -11,7 +11,7 @@ #include "soundmgr_openal.hxx" #include "sample_group.hxx" -#include "sample_openal.hxx" +#include "sample.hxx" int main( int argc, char *argv[] ) { SGSampleGroup *sgr; diff --git a/simgear/sound/readwav.cxx b/simgear/sound/readwav.cxx index 30429bd2..4f96d883 100644 --- a/simgear/sound/readwav.cxx +++ b/simgear/sound/readwav.cxx @@ -30,7 +30,7 @@ #include #include -#include "sample_openal.hxx" +#include "sample.hxx" namespace { diff --git a/simgear/sound/sample_openal.cxx b/simgear/sound/sample.cxx similarity index 98% rename from simgear/sound/sample_openal.cxx rename to simgear/sound/sample.cxx index 0c613d52..2a02e82a 100644 --- a/simgear/sound/sample_openal.cxx +++ b/simgear/sound/sample.cxx @@ -1,4 +1,4 @@ -// sample_openal.cxx -- Audio sample encapsulation class +// sample.cxx -- Audio sample encapsulation class // // Written by Curtis Olson, started April 2004. // Modified to match the new SoundSystem by Erik Hofman, October 2009 @@ -35,9 +35,9 @@ #include #include -#include "soundmgr_openal.hxx" -#include "sample_openal.hxx" #include "soundmgr_openal_private.hxx" +#include "soundmgr_openal.hxx" +#include "sample.hxx" #define AL_FALSE 0 diff --git a/simgear/sound/sample_openal.hxx b/simgear/sound/sample.hxx similarity index 99% rename from simgear/sound/sample_openal.hxx rename to simgear/sound/sample.hxx index 91e2b2ac..408c5fcc 100644 --- a/simgear/sound/sample_openal.hxx +++ b/simgear/sound/sample.hxx @@ -1,4 +1,4 @@ -// sample_openal.hxx -- Audio sample encapsulation class +// sample.hxx -- Audio sample encapsulation class // // Written by Curtis Olson, started April 2004. // Modified to match the new SoundSystem by Erik Hofman, October 2009 diff --git a/simgear/sound/sample_group.cxx b/simgear/sound/sample_group.cxx index dbbb22ab..d4f77bff 100644 --- a/simgear/sound/sample_group.cxx +++ b/simgear/sound/sample_group.cxx @@ -24,7 +24,6 @@ # include #endif -#include #include #include #include @@ -78,42 +77,15 @@ SGSampleGroup::~SGSampleGroup () _smgr = 0; } -static bool is_sample_stopped(SGSoundSample *sample) -{ -#ifdef ENABLE_SOUND - assert(sample->is_valid_source()); - unsigned int source = sample->get_source(); - int result; - alGetSourcei( source, AL_SOURCE_STATE, &result ); - return (result == AL_STOPPED); -#else - return true; -#endif -} - void SGSampleGroup::cleanup_removed_samples() { // Delete any OpenAL buffers that might still be in use. unsigned int size = _removed_samples.size(); for (unsigned int i=0; iis_valid_source() ) { - int source = sample->get_source(); - - if ( sample->is_looping() && !stopped) { -#ifdef ENABLE_SOUND - alSourceStop( source ); -#endif - stopped = is_sample_stopped(sample); - } - - if ( stopped ) { - sample->no_valid_source(); - _smgr->release_source( source ); - } - } + _smgr->sample_stop(sample); + bool stopped = _smgr->is_sample_stopped(sample); if ( stopped ) { sample->stop(); @@ -132,52 +104,16 @@ void SGSampleGroup::cleanup_removed_samples() void SGSampleGroup::start_playing_sample(SGSoundSample *sample) { -#ifdef ENABLE_SOUND - // - // a request to start playing a sound has been filed. - // - ALuint source = _smgr->request_source(); - if (alIsSource(source) == AL_FALSE ) { - return; - } - - sample->set_source( source ); + _smgr->sample_init( sample ); update_sample_config( sample ); - ALboolean looping = sample->is_looping() ? AL_TRUE : AL_FALSE; - - if ( !sample->is_queue() ) - { - ALuint buffer = _smgr->request_buffer(sample); - if (buffer == SGSoundMgr::FAILED_BUFFER || - buffer == SGSoundMgr::NO_BUFFER) - { - _smgr->release_source(source); - return; - } - - // start playing the sample - buffer = sample->get_buffer(); - if ( alIsBuffer(buffer) == AL_TRUE ) - { - alSourcei( source, AL_BUFFER, buffer ); - testForALError("assign buffer to source"); - } else - SG_LOG( SG_SOUND, SG_ALERT, "No such buffer!"); - } - - alSourcef( source, AL_ROLLOFF_FACTOR, 0.3 ); - alSourcei( source, AL_LOOPING, looping ); - alSourcei( source, AL_SOURCE_RELATIVE, AL_FALSE ); - alSourcePlay( source ); - testForALError("sample play"); -#endif + _smgr->sample_play( sample ); } void SGSampleGroup::check_playing_sample(SGSoundSample *sample) { // check if the sound has stopped by itself - if (is_sample_stopped(sample)) { + if (_smgr->is_sample_stopped(sample)) { // sample is stopped because it wasn't looping sample->stop(); sample->no_valid_source(); @@ -291,23 +227,7 @@ SGSampleGroup::stop () sample_map_iterator sample_end = _samples.end(); for ( ; sample_current != sample_end; ++sample_current ) { SGSoundSample *sample = sample_current->second; - - if ( sample->is_valid_source() ) { -#ifdef ENABLE_SOUND - ALint source = sample->get_source(); - if ( sample->is_playing() ) { - alSourceStop( source ); - testForALError("stop"); - } - _smgr->release_source( source ); -#endif - sample->no_valid_source(); - } - - if ( sample->is_valid_buffer() ) { - _smgr->release_buffer( sample ); - sample->no_valid_buffer(); - } + _smgr->sample_destroy( sample ); } } @@ -322,9 +242,7 @@ SGSampleGroup::suspend () for ( ; sample_current != sample_end; ++sample_current ) { #ifdef ENABLE_SOUND SGSoundSample *sample = sample_current->second; - if ( sample->is_valid_source() && sample->is_playing() ) { - alSourcePause( sample->get_source() ); - } + _smgr->sample_suspend( sample ); #endif } testForALError("suspend"); @@ -341,9 +259,7 @@ SGSampleGroup::resume () sample_map_iterator sample_end = _samples.end(); for ( ; sample_current != sample_end; ++sample_current ) { SGSoundSample *sample = sample_current->second; - if ( sample->is_valid_source() && sample->is_playing() ) { - alSourcePlay( sample->get_source() ); - } + _smgr->sample_resume( sample ); } testForALError("resume"); #endif @@ -469,27 +385,7 @@ void SGSampleGroup::update_sample_config( SGSoundSample *sample ) if (isNaN(velocity.data())) printf("NaN in source velocity\n"); #endif - unsigned int source = sample->get_source(); - alSourcefv( source, AL_POSITION, toVec3f(position).data() ); - alSourcefv( source, AL_VELOCITY, velocity.data() ); - alSourcefv( source, AL_DIRECTION, orientation.data() ); - testForALError("position and orientation"); - - alSourcef( source, AL_PITCH, sample->get_pitch() ); - alSourcef( source, AL_GAIN, sample->get_volume() ); - testForALError("pitch and gain"); - - if ( sample->has_static_data_changed() ) { - alSourcef( source, AL_CONE_INNER_ANGLE, sample->get_innerangle() ); - alSourcef( source, AL_CONE_OUTER_ANGLE, sample->get_outerangle() ); - alSourcef( source, AL_CONE_OUTER_GAIN, sample->get_outergain() ); - testForALError("audio cone"); - - alSourcef( source, AL_MAX_DISTANCE, sample->get_max_dist() ); - alSourcef( source, AL_REFERENCE_DISTANCE, - sample->get_reference_dist() ); - testForALError("distance rolloff"); - } + _smgr->update_sample_config( sample, position, orientation, velocity ); #endif } @@ -504,14 +400,7 @@ bool SGSampleGroup::testForError(void *p, std::string s) bool SGSampleGroup::testForALError(std::string s) { -#ifdef SG_C - ALenum error = alGetError(); - if (error != AL_NO_ERROR) { - SG_LOG( SG_SOUND, SG_ALERT, "AL Error (" << _refname << "): " - << alGetString(error) << " at " << s); - return true; - } -#endif + _smgr->testForError(s, _refname); return false; } diff --git a/simgear/sound/sample_group.hxx b/simgear/sound/sample_group.hxx index 4d307dd9..30fcebbe 100644 --- a/simgear/sound/sample_group.hxx +++ b/simgear/sound/sample_group.hxx @@ -36,7 +36,7 @@ #include #include -#include "sample_openal.hxx" +#include "sample.hxx" typedef std::map < std::string, SGSharedPtr > sample_map; diff --git a/simgear/sound/soundmgr_openal.cxx b/simgear/sound/soundmgr_openal.cxx index a931cd0d..68147b0b 100644 --- a/simgear/sound/soundmgr_openal.cxx +++ b/simgear/sound/soundmgr_openal.cxx @@ -32,6 +32,7 @@ #include #include #include +#include #include @@ -215,7 +216,7 @@ void SGSoundMgr::init() // AL_ROLLOFF_FACTOR * (distance - AL_REFERENCE_DISTANCE)); alDistanceModel(AL_INVERSE_DISTANCE_CLAMPED); - testForALError("listener initialization"); + testForError("listener initialization"); // get a free source one at a time // if an error is returned no more (hardware) sources are available @@ -296,7 +297,7 @@ void SGSoundMgr::stop() // clear all OpenAL sources BOOST_FOREACH(ALuint source, d->_free_sources) { alDeleteSources( 1 , &source ); - testForALError("SGSoundMgr::stop: delete sources"); + testForError("SGSoundMgr::stop: delete sources"); } d->_free_sources.clear(); @@ -307,7 +308,7 @@ void SGSoundMgr::stop() refUint ref = buffers_current->second; ALuint buffer = ref.id; alDeleteBuffers(1, &buffer); - testForALError("SGSoundMgr::stop: delete buffers"); + testForError("SGSoundMgr::stop: delete buffers"); } d->_buffers.clear(); @@ -396,7 +397,7 @@ if (isNaN(_velocity.data())) printf("NaN in listener velocity\n"); alListenerfv( AL_VELOCITY, toVec3f(velocity).data() ); // alDopplerVelocity(340.3); // TODO: altitude dependent - testForALError("update"); + testForError("update"); _changed = false; } @@ -509,7 +510,7 @@ void SGSoundMgr::release_source( unsigned int source ) } alSourcei( source, AL_BUFFER, 0 ); // detach the associated buffer - testForALError("release_source"); + testForError("release_source"); #endif d->_free_sources.push_back( source ); d->_sources_in_use.erase( it ); @@ -559,7 +560,7 @@ unsigned int SGSoundMgr::request_buffer(SGSoundSample *sample) // create an OpenAL buffer handle alGenBuffers(1, &buffer); - if ( !testForALError("generate buffer") ) { + if ( !testForError("generate buffer") ) { // Copy data to the internal OpenAL buffer ALenum format = AL_NONE; @@ -571,7 +572,7 @@ unsigned int SGSoundMgr::request_buffer(SGSoundSample *sample) ALsizei freq = sample->get_frequency(); alBufferData( buffer, format, sample_data, size, freq ); - if ( !testForALError("buffer add data") ) { + if ( !testForError("buffer add data") ) { sample->set_buffer(buffer); d->_buffers[sample_name] = refUint(buffer); } @@ -605,11 +606,153 @@ void SGSoundMgr::release_buffer(SGSoundSample *sample) alDeleteBuffers(1, &buffer); #endif d->_buffers.erase( buffer_it ); - testForALError("release buffer"); + testForError("release buffer"); } } } +void SGSoundMgr::sample_suspend( SGSoundSample *sample ) +{ + if ( sample->is_valid_source() && sample->is_playing() ) { + alSourcePause( sample->get_source() ); + } +} + +void SGSoundMgr::sample_resume( SGSoundSample *sample ) +{ + if ( sample->is_valid_source() && sample->is_playing() ) { + alSourcePlay( sample->get_source() ); + } +} + +void SGSoundMgr::sample_init( SGSoundSample *sample ) +{ +#ifdef ENABLE_SOUND + // + // a request to start playing a sound has been filed. + // + ALuint source = request_source(); + if (alIsSource(source) == AL_FALSE ) { + return; + } + + sample->set_source( source ); +#endif +} + +void SGSoundMgr::sample_play( SGSoundSample *sample ) +{ +#ifdef ENABLE_SOUND + ALboolean looping = sample->is_looping() ? AL_TRUE : AL_FALSE; + ALint source = sample->get_source(); + + if ( !sample->is_queue() ) + { + ALuint buffer = request_buffer(sample); + if (buffer == SGSoundMgr::FAILED_BUFFER || + buffer == SGSoundMgr::NO_BUFFER) + { + release_source(source); + return; + } + + // start playing the sample + buffer = sample->get_buffer(); + if ( alIsBuffer(buffer) == AL_TRUE ) + { + alSourcei( source, AL_BUFFER, buffer ); + testForError("assign buffer to source"); + } else + SG_LOG( SG_SOUND, SG_ALERT, "No such buffer!"); + } + + alSourcef( source, AL_ROLLOFF_FACTOR, 0.3 ); + alSourcei( source, AL_LOOPING, looping ); + alSourcei( source, AL_SOURCE_RELATIVE, AL_FALSE ); + alSourcePlay( source ); + testForError("sample play"); +#endif +} + +void SGSoundMgr::sample_stop( SGSoundSample *sample ) +{ + if ( sample->is_valid_source() ) { + int source = sample->get_source(); + + bool stopped = is_sample_stopped(sample); + if ( sample->is_looping() && !stopped) { +#ifdef ENABLE_SOUND + alSourceStop( source ); +#endif + stopped = is_sample_stopped(sample); + } + + if ( stopped ) { + sample->no_valid_source(); + release_source( source ); + } + } +} + +void SGSoundMgr::sample_destroy( SGSoundSample *sample ) +{ + if ( sample->is_valid_source() ) { +#ifdef ENABLE_SOUND + ALint source = sample->get_source(); + if ( sample->is_playing() ) { + alSourceStop( source ); + testForError("stop"); + } + release_source( source ); +#endif + sample->no_valid_source(); + } + + if ( sample->is_valid_buffer() ) { + release_buffer( sample ); + sample->no_valid_buffer(); + } +} + +bool SGSoundMgr::is_sample_stopped(SGSoundSample *sample) +{ +#ifdef ENABLE_SOUND + assert(sample->is_valid_source()); + unsigned int source = sample->get_source(); + int result; + alGetSourcei( source, AL_SOURCE_STATE, &result ); + return (result == AL_STOPPED); +#else + return true; +#endif +} + +void SGSoundMgr::update_sample_config( SGSoundSample *sample, SGVec3d& position, SGVec3f& orientation, SGVec3f& velocity ) +{ + unsigned int source = sample->get_source(); + alSourcefv( source, AL_POSITION, toVec3f(position).data() ); + alSourcefv( source, AL_VELOCITY, velocity.data() ); + alSourcefv( source, AL_DIRECTION, orientation.data() ); + testForError("position and orientation"); + + alSourcef( source, AL_PITCH, sample->get_pitch() ); + alSourcef( source, AL_GAIN, sample->get_volume() ); + testForError("pitch and gain"); + + if ( sample->has_static_data_changed() ) { + alSourcef( source, AL_CONE_INNER_ANGLE, sample->get_innerangle() ); + alSourcef( source, AL_CONE_OUTER_ANGLE, sample->get_outerangle() ); + alSourcef( source, AL_CONE_OUTER_GAIN, sample->get_outergain() ); + testForError("audio cone"); + + alSourcef( source, AL_MAX_DISTANCE, sample->get_max_dist() ); + alSourcef( source, AL_REFERENCE_DISTANCE, + sample->get_reference_dist() ); + testForError("distance rolloff"); + } +} + + bool SGSoundMgr::load( const std::string &samplepath, void **dbuf, int *fmt, @@ -683,12 +826,12 @@ bool SGSoundMgr::testForError(void *p, std::string s) } -bool SGSoundMgr::testForALError(std::string s) +bool SGSoundMgr::testForError(std::string s, std::string name) { #ifdef ENABLE_SOUND ALenum error = alGetError(); if (error != AL_NO_ERROR) { - SG_LOG( SG_SOUND, SG_ALERT, "AL Error (sound manager): " + SG_LOG( SG_SOUND, SG_ALERT, "AL Error (" << name << "): " << alGetString(error) << " at " << s); return true; } diff --git a/simgear/sound/soundmgr_openal.hxx b/simgear/sound/soundmgr_openal.hxx index 19897e32..60f07367 100644 --- a/simgear/sound/soundmgr_openal.hxx +++ b/simgear/sound/soundmgr_openal.hxx @@ -225,6 +225,63 @@ public: */ void release_buffer( SGSoundSample *sample ); + /** + * Initialize sample for playback. + * + * @param sample Pointer to an audio sample to initialize. + */ + void sample_init( SGSoundSample *sample ); + + /** + * Stop and destroy a sample + * + * @param sample Pointer to an audio sample to destroy. + */ + void sample_destroy( SGSoundSample *sample ); + + /** + * Start playback of a sample + * + * @param sample Pointer to an audio sample to start playing. + */ + void sample_play( SGSoundSample *sample ); + + /** + * Stop a sample + * + * @param sample Pointer to an audio sample to stop. + */ + void sample_stop( SGSoundSample *sample ); + + /** + * Suspend playback of a sample + * + * @param sample Pointer to an audio sample to suspend. + */ + void sample_suspend( SGSoundSample *sample ); + + /** + * Resume playback of a sample + * + * @param sample Pointer to an audio sample to resume. + */ + void sample_resume( SGSoundSample *sample ); + + /** + * Check if a sample is stopped, or still playing + * + * @param sample Pointer to an audio sample to test. + * @return true if the sample is stopped. + */ + bool is_sample_stopped( SGSoundSample *sample ); + + /** + * Update all status and 3d parameters of a sample. + * + * @param sample Pointer to an audio sample to update. + */ + void update_sample_config( SGSoundSample *sample, SGVec3d& position, SGVec3f& orientation, SGVec3f& velocity ); + /** * Test if the position of the sound manager has changed. * The value will be set to false upon the next call to update_late() @@ -268,6 +325,8 @@ public: const std::string& get_vendor() { return _vendor; } const std::string& get_renderer() { return _renderer; } + bool testForError(std::string s, std::string name = "sound manager"); + static const char* subsystemName() { return "sound"; }; private: class SoundManagerPrivate; @@ -290,7 +349,6 @@ private: std::string _vendor; std::string _device_name; - bool testForALError(std::string s); bool testForALCError(std::string s); bool testForError(void *p, std::string s); diff --git a/simgear/sound/soundmgr_openal_private.hxx b/simgear/sound/soundmgr_openal_private.hxx index 8fb0c796..6bc3591f 100644 --- a/simgear/sound/soundmgr_openal_private.hxx +++ b/simgear/sound/soundmgr_openal_private.hxx @@ -47,6 +47,10 @@ # include #endif +#include + +class SGSampleGroup; + struct refUint { unsigned int refctr; ALuint id; diff --git a/simgear/sound/xmlsound.cxx b/simgear/sound/xmlsound.cxx index fb3e7d73..36907f5b 100644 --- a/simgear/sound/xmlsound.cxx +++ b/simgear/sound/xmlsound.cxx @@ -40,7 +40,7 @@ #include #include "sample_group.hxx" -#include "sample_openal.hxx" +#include "sample.hxx" using std::string; -- 2.39.5