+
+ SG_LOG( SG_GENERAL, SG_INFO, "Initializing OpenAL sound manager" );
+
+ ALCdevice *device = alcOpenDevice(_devname);
+ if ( testForError(device, "No default audio device available.") ) {
+ return;
+ }
+
+ ALCcontext *context = alcCreateContext(device, NULL);
+ if ( testForError(context, "Unable to create a valid context.") ) {
+ alcCloseDevice (device);
+ return;
+ }
+
+ if ( !alcMakeContextCurrent(context) ) {
+ testForALCError("context initialization");
+ alcDestroyContext (context);
+ alcCloseDevice (device);
+ return;
+ }
+
+ _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 );
+ alListenerfv( AL_ORIENTATION, _at_up_vec );
+ alListenerfv( AL_POSITION, SGVec3f::zeros().data() );
+ alListenerfv( AL_VELOCITY, SGVec3f::zeros().data() );
+
+ 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);
+ }
+
+ testForALError("listener initialization");
+
+ // get a free source one at a time
+ // if an error is returned no more (hardware) sources are available
+ for (unsigned int i=0; i<MAX_SOURCES; i++) {
+ ALuint source;
+ ALenum error;
+
+ alGetError();
+ alGenSources(1, &source);
+ error = alGetError();
+ if ( error == AL_NO_ERROR ) {
+ _free_sources.push_back( source );
+ }
+ else break;
+ }
+
+ if (_free_sources.size() == 0) {
+ SG_LOG(SG_GENERAL, SG_ALERT, "Unable to grab any OpenAL sources!");
+ }
+}
+
+// suspend the sound manager
+void SGSoundMgr::stop() {
+ if (_working) {
+ _working = false;
+
+ // clear any OpenAL buffers before shutting down
+ buffer_map_iterator buffers_current;
+ while(_buffers.size()){
+ buffers_current = _buffers.begin();
+ refUint ref = buffers_current->second;
+ ALuint buffer = ref.id;
+ alDeleteBuffers(1, &buffer);
+ _buffers.erase( buffers_current );
+ }
+
+ _context = alcGetCurrentContext();
+ _device = alcGetContextsDevice(_context);
+ alcMakeContextCurrent(NULL);
+ alcDestroyContext(_context);
+ alcCloseDevice(_device);
+ }
+}
+
+void SGSoundMgr::suspend() {
+ 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 ) {
+ SGSampleGroup *sgrp = sample_grp_current->second;
+ sgrp->suspend();
+ }
+ }