]> git.mxchange.org Git - simgear.git/blobdiff - simgear/sound/soundmgr_openal.cxx
Compile time fixes needed to build SimGear on recent cygwin versions.
[simgear.git] / simgear / sound / soundmgr_openal.cxx
index 7920022538740f0eab48f0b88ffd256f322d693f..d29b7fb1ae01d404df063dfd961c2f5f9bfea336 100644 (file)
@@ -5,7 +5,7 @@
 //
 // C++-ified by Curtis Olson, started March 2001.
 //
-// Copyright (C) 2001  Curtis L. Olson - curt@flightgear.org
+// Copyright (C) 2001  Curtis L. Olson - http://www.flightgear.org/~curt
 //
 // This program is free software; you can redistribute it and/or
 // modify it under the terms of the GNU General Public License as
 //
 // You should have received a copy of the GNU General Public License
 // along with this program; if not, write to the Free Software
-// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 //
 // $Id$
 
-#include <iostream>
+#ifdef HAVE_CONFIG_H
+#  include <simgear_config.h>
+#endif
+
+#include <simgear/compiler.h>
 
 #if defined(__APPLE__)
 # include <OpenAL/al.h>
-# include <OpenAL/alut.h>
 # include <OpenAL/alc.h>
 #else
 # include <AL/al.h>
-# include <AL/alut.h>
 # include <AL/alc.h>
 #endif
 
+#if defined (__APPLE__)
+#  ifdef __GNUC__
+#    if ( __GNUC__ >= 3 ) && ( __GNUC_MINOR__ >= 3 )
+//  #        include <math.h>
+inline int (isnan)(double r) { return !(r <= 0 || r >= 0); }
+#    else
+    // any C++ header file undefines isinf and isnan
+    // so this should be included before <iostream>
+    // the functions are STILL in libm (libSystem on mac os x)
+extern "C" int isnan (double);
+extern "C" int isinf (double);
+#    endif
+#  else
+//    inline int (isinf)(double r) { return isinf(r); }
+//    inline int (isnan)(double r) { return isnan(r); }
+#  endif
+#endif
+
+#if defined (__FreeBSD__)
+#  if __FreeBSD_version < 500000
+     extern "C" {
+       inline int isnan(double r) { return !(r <= 0 || r >= 0); }
+     }
+#  endif
+#endif
+
+#if defined (__CYGWIN__)
+#include <ieeefp.h>
+#endif
+
+
+#include STL_IOSTREAM
+
 #include <simgear/debug/logstream.hxx>
 #include <simgear/misc/sg_path.hxx>
 
 #include "soundmgr_openal.hxx"
 
+#if defined(__MINGW32__)
+#define isnan(x) _isnan(x)
+#endif
 
 //
 // Sound Manager
 // constructor
 SGSoundMgr::SGSoundMgr() {
 
-    SG_LOG( SG_GENERAL, SG_ALERT, "Initializing OpenAL sound manager" );
+    SG_LOG( SG_GENERAL, SG_INFO, "Initializing OpenAL sound manager" );
 
     // initialize OpenAL
-    alutInit( 0, NULL );
-    alGetError();
-    if ( alGetError() == AL_NO_ERROR) {
+#if defined(ALUT_API_MAJOR_VERSION) && ALUT_API_MAJOR_VERSION >= 1
+    if (!alutInit(NULL, NULL))
+    {
+        ALenum error = alutGetError ();
+        SG_LOG( SG_GENERAL, SG_ALERT, "Audio initialization failed!" );
+        SG_LOG( SG_GENERAL, SG_ALERT, "   "+string(alutGetErrorString(error)));
+        working = false;
+        context = 0;
+    }
+    else
+    {
         working = true;
+        context = alcGetCurrentContext();
+    }
+#else
+    if ( (dev = alcOpenDevice( NULL )) != NULL
+            && ( context = alcCreateContext( dev, NULL )) != NULL ) {
+        working = true;
+        alcMakeContextCurrent( context );
     } else {
         working = false;
+        context = 0;
        SG_LOG( SG_GENERAL, SG_ALERT, "Audio initialization failed!" );
     }
+#endif
 
     listener_pos[0] = 0.0;
     listener_pos[1] = 0.0;
@@ -75,6 +130,7 @@ SGSoundMgr::SGSoundMgr() {
     listener_ori[4] = 1.0;
     listener_ori[5] = 0.0;
 
+    alListenerf( AL_GAIN, 0.0f );
     alListenerfv( AL_POSITION, listener_pos );
     alListenerfv( AL_VELOCITY, listener_vel );
     alListenerfv( AL_ORIENTATION, listener_ori );
@@ -83,23 +139,22 @@ SGSoundMgr::SGSoundMgr() {
        SG_LOG( SG_GENERAL, SG_ALERT,
                 "Oops AL error after audio initialization!" );
     }
+
+    // exaggerate the ear candy?
+    alDopplerFactor(1.0);
+    alDopplerVelocity(340.0);  // speed of sound in meters per second.
 }
 
 // destructor
 
 SGSoundMgr::~SGSoundMgr() {
 
-    //
-    // Remove the samples from the sample manager.
-    //
-    sample_map_iterator sample_current = samples.begin();
-    sample_map_iterator sample_end = samples.end();
-    for ( ; sample_current != sample_end; ++sample_current ) {
-       SGSoundSample *sample = sample_current->second;
-       delete sample;
-    }
-
-    alutExit();
+#if defined(ALUT_API_MAJOR_VERSION) && ALUT_API_MAJOR_VERSION >= 1
+    alutExit ();
+#else
+    if (context)
+        alcDestroyContext( context );
+#endif
 }
 
 
@@ -108,12 +163,6 @@ void SGSoundMgr::init() {
     //
     // Remove the samples from the sample manager.
     //
-    sample_map_iterator sample_current = samples.begin();
-    sample_map_iterator sample_end = samples.end();
-    for ( ; sample_current != sample_end; ++sample_current ) {
-        SGSoundSample *sample = sample_current->second;
-        delete sample;
-    }
     samples.clear();
 }
 
@@ -138,11 +187,12 @@ void SGSoundMgr::update( double dt ) {
 void
 SGSoundMgr::pause ()
 {
-    ALCcontext *pCurContext = alcGetCurrentContext();
-    alcSuspendContext( pCurContext );
-    if ( alGetError() != AL_NO_ERROR) {
-       SG_LOG( SG_GENERAL, SG_ALERT,
-                "Oops AL error after soundmgr pause()!" );
+    if (context) {
+        alcSuspendContext( context );
+        if ( alGetError() != AL_NO_ERROR) {
+           SG_LOG( SG_GENERAL, SG_ALERT,
+                    "Oops AL error after soundmgr pause()!" );
+        }
     }
 }
 
@@ -150,11 +200,12 @@ SGSoundMgr::pause ()
 void
 SGSoundMgr::resume ()
 {
-    ALCcontext *pCurContext = alcGetCurrentContext();
-    alcProcessContext( pCurContext );
-    if ( alGetError() != AL_NO_ERROR) {
-       SG_LOG( SG_GENERAL, SG_ALERT,
-                "Oops AL error after soundmgr resume()!" );
+    if (context) {
+        alcProcessContext( context );
+        if ( alGetError() != AL_NO_ERROR) {
+           SG_LOG( SG_GENERAL, SG_ALERT,
+                    "Oops AL error after soundmgr resume()!" );
+        }
     }
 }
 
@@ -181,8 +232,6 @@ bool SGSoundMgr::remove( const string &refname ) {
     if ( sample_it != samples.end() ) {
        // first stop the sound from playing (so we don't bomb the
        // audio scheduler)
-       SGSoundSample *sample = sample_it->second;
-        delete sample;
         samples.erase( sample_it );
 
         // cout << "sndmgr: removed -> " << refname << endl;
@@ -267,3 +316,35 @@ bool SGSoundMgr::stop( const string& refname ) {
         return true;
     }
 }
+
+
+// set source position of all managed sounds
+void SGSoundMgr::set_source_pos_all( ALfloat *pos ) {
+    if ( isnan(pos[0]) || isnan(pos[1]) || isnan(pos[2]) ) {
+        // bail if a bad position is passed in
+        return;
+    }
+
+    sample_map_iterator sample_current = samples.begin();
+    sample_map_iterator sample_end = samples.end();
+    for ( ; sample_current != sample_end; ++sample_current ) {
+       SGSoundSample *sample = sample_current->second;
+        sample->set_source_pos( pos );
+    }
+}
+
+
+// set source velocity of all managed sounds
+void SGSoundMgr::set_source_vel_all( ALfloat *vel ) {
+    if ( isnan(vel[0]) || isnan(vel[1]) || isnan(vel[2]) ) {
+        // bail if a bad velocity is passed in
+        return;
+    }
+
+    sample_map_iterator sample_current = samples.begin();
+    sample_map_iterator sample_end = samples.end();
+    for ( ; sample_current != sample_end; ++sample_current ) {
+       SGSoundSample *sample = sample_current->second;
+        sample->set_source_vel( vel );
+    }
+}