X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=simgear%2Fsound%2Fsoundmgr_openal.cxx;h=2cba97807b1924f1a38d48df5f250b5d36c02ea0;hb=f3c591469b12bb5ec9ad29181fda0faeee5ab144;hp=6066a560c32d1d22cc49679b387171fe0a8807d9;hpb=afb18ca75b90e5a2e0bf791ba2e38812128ab0a8;p=simgear.git diff --git a/simgear/sound/soundmgr_openal.cxx b/simgear/sound/soundmgr_openal.cxx index 6066a560..2cba9780 100644 --- a/simgear/sound/soundmgr_openal.cxx +++ b/simgear/sound/soundmgr_openal.cxx @@ -66,9 +66,10 @@ SGSoundMgr::SGSoundMgr() : _absolute_pos(SGVec3d::zeros()), _offset_pos(SGVec3d::zeros()), _base_pos(SGVec3d::zeros()), + _geod_pos(SGGeod::fromCart(SGVec3d::zeros())), _velocity(SGVec3d::zeros()), _orientation(SGQuatd::zeros()), - _devname(NULL) + _bad_doppler(false) { #if defined(ALUT_API_MAJOR_VERSION) && ALUT_API_MAJOR_VERSION >= 1 if (_alut_init == 0) { @@ -95,13 +96,16 @@ SGSoundMgr::~SGSoundMgr() { } // initialize the sound manager -void SGSoundMgr::init() { +void SGSoundMgr::init(const char *devname) { SG_LOG( SG_GENERAL, SG_INFO, "Initializing OpenAL sound manager" ); - ALCdevice *device = alcOpenDevice(_devname); - if ( testForError(device, "No default audio device available.") ) { - return; + ALCdevice *device = alcOpenDevice(devname); + if ( testForError(device, "Audio device not available, trying default") ) { + device = alcOpenDevice(NULL); + if (testForError(device, "Default Audio device not available.") ) { + return; + } } ALCcontext *context = alcCreateContext(device, NULL); @@ -154,6 +158,15 @@ void SGSoundMgr::init() { else break; } + string vendor = alGetString(AL_VENDOR); + string renderer = alGetString(AL_RENDERER); + if ( vendor != "OpenAL Community" || + (renderer != "Software" && renderer != "OpenAL Sample Implementation") + ) + { + _bad_doppler = true; + } + if (_free_sources.size() == 0) { SG_LOG(SG_GENERAL, SG_ALERT, "Unable to grab any OpenAL sources!"); } @@ -173,24 +186,40 @@ void SGSoundMgr::activate() { // stop the sound manager void SGSoundMgr::stop() { + + // first stop all sample groups + 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->stop(); + } + + // clear all OpenAL sources + for (unsigned int i=0; i<_free_sources.size(); i++) { + ALuint source = _free_sources[i]; + alDeleteSources( 1 , &source ); + } + _free_sources.clear(); + + // clear any OpenAL buffers before shutting down + 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.clear(); + if (_working) { _working = false; _active = false; - - // clear any OpenAL buffers before shutting down - 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.clear(); - _context = alcGetCurrentContext(); _device = alcGetContextsDevice(_context); alcDestroyContext(_context); alcCloseDevice(_device); + _context = NULL; } } @@ -200,7 +229,7 @@ void SGSoundMgr::suspend() { 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->suspend(); + sgrp->stop(); } _active = false; } @@ -244,6 +273,8 @@ void SGSoundMgr::unbind () // run the audio scheduler void SGSoundMgr::update( double dt ) { if (_active) { + alcSuspendContext(_context); + if (_changed) { update_pos_and_orientation(); } @@ -264,11 +295,24 @@ if (isNaN(_velocity.data())) printf("NaN in listener velocity\n"); alListenerf( AL_GAIN, _volume ); alListenerfv( AL_ORIENTATION, _at_up_vec ); // alListenerfv( AL_POSITION, toVec3f(_absolute_pos).data() ); - alListenerfv( AL_VELOCITY, _velocity.data() ); + + SGQuatd hlOr = SGQuatd::fromLonLat( _geod_pos ); + SGVec3d velocity = SGVec3d::zeros(); + if ( _velocity[0] || _velocity[1] || _velocity[2] ) { + velocity = hlOr.backTransform(_velocity*SG_FEET_TO_METER); + } + + if ( _bad_doppler ) { + velocity *= 100.0f; + } + + alListenerfv( AL_VELOCITY, toVec3f(velocity).data() ); // alDopplerVelocity(340.3); // TODO: altitude dependent testForALError("update"); _changed = false; } + + alcProcessContext(_context); } } @@ -538,6 +582,32 @@ bool SGSoundMgr::load(string &samplepath, void **dbuf, int *fmt, return true; } +vector SGSoundMgr::get_available_devices() +{ + vector devices; + const ALCchar *s; + + if (alcIsExtensionPresent(NULL, "ALC_enumerate_all_EXT") == AL_TRUE) { + s = alcGetString(NULL, ALC_ALL_DEVICES_SPECIFIER); + } else { + s = alcGetString(NULL, ALC_DEVICE_SPECIFIER); + } + + if (s) { + ALCchar *nptr, *ptr = (ALCchar *)s; + + nptr = ptr; + while (*(nptr += strlen(ptr)+1) != 0) + { + devices.push_back(ptr); + ptr = nptr; + } + devices.push_back(ptr); + } + + return devices; +} + bool SGSoundMgr::testForError(void *p, string s) {