X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=simgear%2Fsound%2Fsoundmgr_openal.cxx;h=6066a560c32d1d22cc49679b387171fe0a8807d9;hb=afb18ca75b90e5a2e0bf791ba2e38812128ab0a8;hp=4ff36eee99597b16640a4432b01278188f1ec7a1;hpb=b3bc36b2534d05c37e5f687f8deccfc9f8659abe;p=simgear.git diff --git a/simgear/sound/soundmgr_openal.cxx b/simgear/sound/soundmgr_openal.cxx index 4ff36eee..6066a560 100644 --- a/simgear/sound/soundmgr_openal.cxx +++ b/simgear/sound/soundmgr_openal.cxx @@ -45,6 +45,7 @@ #include #include +extern bool isNaN(float *v); #define MAX_SOURCES 128 @@ -62,7 +63,9 @@ SGSoundMgr::SGSoundMgr() : _volume(0.0), _device(NULL), _context(NULL), - _position(SGVec3d::zeros()), + _absolute_pos(SGVec3d::zeros()), + _offset_pos(SGVec3d::zeros()), + _base_pos(SGVec3d::zeros()), _velocity(SGVec3d::zeros()), _orientation(SGQuatd::zeros()), _devname(NULL) @@ -114,13 +117,15 @@ void SGSoundMgr::init() { return; } + if (_context != NULL) + SG_LOG(SG_GENERAL, SG_ALERT, "context is already assigned"); _context = context; _working = true; _at_up_vec[0] = 0.0; _at_up_vec[1] = 0.0; _at_up_vec[2] = -1.0; _at_up_vec[3] = 0.0; _at_up_vec[4] = 1.0; _at_up_vec[5] = 0.0; - alListenerf( AL_GAIN, 0.2f ); + alListenerf( AL_GAIN, 0.0f ); alListenerfv( AL_ORIENTATION, _at_up_vec ); alListenerfv( AL_POSITION, SGVec3f::zeros().data() ); alListenerfv( AL_VELOCITY, SGVec3f::zeros().data() ); @@ -128,11 +133,9 @@ void SGSoundMgr::init() { alDopplerFactor(1.0); alDopplerVelocity(340.3); // speed of sound in meters per second. - if ( alIsExtensionPresent((const ALchar*)"EXT_exponent_distance") ) { - alDistanceModel(AL_EXPONENT_DISTANCE); - } else { - alDistanceModel(AL_INVERSE_DISTANCE); - } + // gain = AL_REFERENCE_DISTANCE / (AL_REFERENCE_DISTANCE + + // AL_ROLLOFF_FACTOR * (distance - AL_REFERENCE_DISTANCE)); + alDistanceModel(AL_INVERSE_DISTANCE_CLAMPED); testForALError("listener initialization"); @@ -154,12 +157,17 @@ void SGSoundMgr::init() { if (_free_sources.size() == 0) { SG_LOG(SG_GENERAL, SG_ALERT, "Unable to grab any OpenAL sources!"); } +} - sample_group_map_iterator sample_grp_current = _sample_groups.begin(); - sample_group_map_iterator sample_grp_end = _sample_groups.end(); - for ( ; sample_grp_current != sample_grp_end; ++sample_grp_current ) { - SGSampleGroup *sgrp = sample_grp_current->second; - sgrp->activate(); +void SGSoundMgr::activate() { + if ( _working ) { + _active = true; + sample_group_map_iterator sample_grp_current = _sample_groups.begin(); + sample_group_map_iterator sample_grp_end = _sample_groups.end(); + for ( ; sample_grp_current != sample_grp_end; ++sample_grp_current ) { + SGSampleGroup *sgrp = sample_grp_current->second; + sgrp->activate(); + } } } @@ -170,14 +178,14 @@ void SGSoundMgr::stop() { _active = false; // clear any OpenAL buffers before shutting down - buffer_map_iterator buffers_current; - while(_buffers.size()){ - buffers_current = _buffers.begin(); + buffer_map_iterator buffers_current = _buffers.begin(); + buffer_map_iterator buffers_end = _buffers.end(); + for ( ; buffers_current != buffers_end; ++buffers_current ) { refUint ref = buffers_current->second; ALuint buffer = ref.id; alDeleteBuffers(1, &buffer); - _buffers.erase( buffers_current ); } + _buffers.clear(); _context = alcGetCurrentContext(); _device = alcGetContextsDevice(_context); @@ -187,7 +195,7 @@ void SGSoundMgr::stop() { } void SGSoundMgr::suspend() { - if (_active) { + if (_working) { sample_group_map_iterator sample_grp_current = _sample_groups.begin(); sample_group_map_iterator sample_grp_end = _sample_groups.end(); for ( ; sample_grp_current != sample_grp_end; ++sample_grp_current ) { @@ -199,7 +207,7 @@ void SGSoundMgr::suspend() { } void SGSoundMgr::resume() { - if (!_active) { + if (_working) { sample_group_map_iterator sample_grp_current = _sample_groups.begin(); sample_group_map_iterator sample_grp_end = _sample_groups.end(); for ( ; sample_grp_current != sample_grp_end; ++sample_grp_current ) { @@ -225,7 +233,7 @@ void SGSoundMgr::unbind () // delete free sources for (unsigned int i=0; i<_free_sources.size(); i++) { - ALuint source = _free_sources.at( i ); + ALuint source = _free_sources[i]; alDeleteSources( 1 , &source ); } @@ -234,8 +242,12 @@ void SGSoundMgr::unbind () } // run the audio scheduler -void SGSoundMgr::update_late( double dt ) { +void SGSoundMgr::update( double dt ) { if (_active) { + if (_changed) { + update_pos_and_orientation(); + } + sample_group_map_iterator sample_grp_current = _sample_groups.begin(); sample_group_map_iterator sample_grp_end = _sample_groups.end(); for ( ; sample_grp_current != sample_grp_end; ++sample_grp_current ) { @@ -244,10 +256,15 @@ void SGSoundMgr::update_late( double dt ) { } if (_changed) { +#if 0 +if (isNaN(_at_up_vec)) printf("NaN in listener orientation\n"); +if (isNaN(toVec3f(_absolute_pos).data())) printf("NaN in listener position\n"); +if (isNaN(_velocity.data())) printf("NaN in listener velocity\n"); +#endif alListenerf( AL_GAIN, _volume ); alListenerfv( AL_ORIENTATION, _at_up_vec ); - alListenerfv( AL_POSITION, toVec3f(_position).data() ); - alListenerfv( AL_VELOCITY, toVec3f(_velocity).data() ); + // alListenerfv( AL_POSITION, toVec3f(_absolute_pos).data() ); + alListenerfv( AL_VELOCITY, _velocity.data() ); // alDopplerVelocity(340.3); // TODO: altitude dependent testForALError("update"); _changed = false; @@ -264,7 +281,7 @@ bool SGSoundMgr::add( SGSampleGroup *sgrp, const string& refname ) return false; } - if (_working) sgrp->activate(); + if (_active) sgrp->activate(); _sample_groups[refname] = sgrp; return true; @@ -280,7 +297,7 @@ bool SGSoundMgr::remove( const string &refname ) return false; } - _sample_groups.erase( refname ); + _sample_groups.erase( sample_grp_it ); return true; } @@ -306,6 +323,7 @@ SGSampleGroup *SGSoundMgr::find( const string &refname, bool create ) { // sample group was not found. if (create) { SGSampleGroup* sgrp = new SGSampleGroup(this, refname); + add( sgrp, refname ); return sgrp; } else @@ -324,32 +342,6 @@ void SGSoundMgr::set_volume( float v ) _changed = true; } -/** - * set the orientation of the listener (in opengl coordinates) - * - * Description: ORIENTATION is a pair of 3-tuples representing the - * 'at' direction vector and 'up' direction of the Object in - * Cartesian space. AL expects two vectors that are orthogonal to - * each other. These vectors are not expected to be normalized. If - * one or more vectors have zero length, implementation behavior - * is undefined. If the two vectors are linearly dependent, - * behavior is undefined. - */ -void SGSoundMgr::set_orientation( SGQuatd ori ) -{ - _orientation = ori; - - SGVec3d sgv_up = ori.rotate(SGVec3d::e2()); - SGVec3d sgv_at = ori.rotate(SGVec3d::e3()); - _at_up_vec[0] = sgv_at[0]; - _at_up_vec[1] = sgv_at[1]; - _at_up_vec[2] = sgv_at[2]; - _at_up_vec[3] = sgv_up[0]; - _at_up_vec[4] = sgv_up[1]; - _at_up_vec[5] = sgv_up[2]; - _changed = true; -} - // Get an unused source id // // The Sound Manager should keep track of the sources in use, the distance @@ -368,6 +360,8 @@ unsigned int SGSoundMgr::request_source() _free_sources.pop_back(); _sources_in_use.push_back(source); } + else + SG_LOG( SG_GENERAL, SG_INFO, "No more free sources available\n"); return source; } @@ -386,8 +380,9 @@ void SGSoundMgr::release_source( unsigned int source ) alSourceStop( source ); testForALError("release source"); - _free_sources.push_back(source); - _sources_in_use.erase(it, it+1); + alSourcei( source, AL_BUFFER, 0 ); + _free_sources.push_back( source ); + _sources_in_use.erase( it ); } } @@ -415,7 +410,7 @@ unsigned int SGSoundMgr::request_buffer(SGSoundSample *sample) void *data; load(sample_name, &data, &format, &size, &freq); - sample->set_data( (unsigned char *)data ); + sample->set_data( &data ); sample->set_frequency( freq ); sample->set_format( format ); sample->set_size( size ); @@ -435,7 +430,7 @@ unsigned int SGSoundMgr::request_buffer(SGSoundSample *sample) // If this sample was read from a file we have all the information // needed to read it again. For data buffers provided by the // program we don't; so don't delete it's data. - if (sample->is_file()) sample->free_data(); + if ( sample->is_file() ) sample->free_data(); if ( !testForALError("buffer add data") ) { sample->set_buffer(buffer); @@ -443,8 +438,9 @@ unsigned int SGSoundMgr::request_buffer(SGSoundSample *sample) } } } - else + else { buffer = sample->get_buffer(); +} return buffer; } @@ -452,7 +448,6 @@ unsigned int SGSoundMgr::request_buffer(SGSoundSample *sample) void SGSoundMgr::release_buffer(SGSoundSample *sample) { string sample_name = sample->get_sample_name(); - buffer_map_iterator buffer_it = _buffers.find( sample_name ); if ( buffer_it == _buffers.end() ) { // buffer was not found @@ -463,15 +458,44 @@ void SGSoundMgr::release_buffer(SGSoundSample *sample) buffer_it->second.refctr--; if (buffer_it->second.refctr == 0) { ALuint buffer = buffer_it->second.id; - _buffers.erase( buffer_it ); alDeleteBuffers(1, &buffer); + _buffers.erase( buffer_it ); testForALError("release buffer"); } } +void SGSoundMgr::update_pos_and_orientation() { + /** + * Description: ORIENTATION is a pair of 3-tuples representing the + * 'at' direction vector and 'up' direction of the Object in + * Cartesian space. AL expects two vectors that are orthogonal to + * each other. These vectors are not expected to be normalized. If + * one or more vectors have zero length, implementation behavior + * is undefined. If the two vectors are linearly dependent, + * behavior is undefined. + * + * This is in the same coordinate system as OpenGL; y=up, z=back, x=right. + */ + SGVec3d sgv_at = _orientation.backTransform(-SGVec3d::e3()); + SGVec3d sgv_up = _orientation.backTransform(SGVec3d::e2()); + _at_up_vec[0] = sgv_at[0]; + _at_up_vec[1] = sgv_at[1]; + _at_up_vec[2] = sgv_at[2]; + _at_up_vec[3] = sgv_up[0]; + _at_up_vec[4] = sgv_up[1]; + _at_up_vec[5] = sgv_up[2]; + + // static const SGQuatd q(-0.5, -0.5, 0.5, 0.5); + // SGQuatd hlOr = SGQuatd::fromLonLat(SGGeod::fromCart(_base_pos)); + // SGQuatd ec2body = hlOr*_orientation; + _absolute_pos = _base_pos; // + ec2body.backTransform( _offset_pos ); +} + bool SGSoundMgr::load(string &samplepath, void **dbuf, int *fmt, size_t *sz, int *frq ) { + if ( !_working ) return false; + ALenum format; ALsizei size; ALsizei freq; @@ -500,7 +524,7 @@ bool SGSoundMgr::load(string &samplepath, void **dbuf, int *fmt, ALenum error = alGetError(); if ( error != AL_NO_ERROR ) { string msg = "Failed to load wav file: "; - msg.append(alutGetErrorString(error)); + msg.append(alGetString(error)); throw sg_io_exception(msg.c_str(), sg_location(samplepath)); return false; }