00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #ifdef HAVE_CONFIG_H
00027 # include <simgear_config.h>
00028 #endif
00029
00030 #include <simgear/compiler.h>
00031
00032 #if defined(__APPLE__)
00033 # include <OpenAL/al.h>
00034 # include <OpenAL/alc.h>
00035 #else
00036 # include <AL/al.h>
00037 # include <AL/alc.h>
00038 #endif
00039
00040 #if defined (__APPLE__)
00041 # ifdef __GNUC__
00042 # if ( __GNUC__ >= 3 ) && ( __GNUC_MINOR__ >= 3 )
00043
00044 inline int (isnan)(double r) { return !(r <= 0 || r >= 0); }
00045 # else
00046
00047
00048
00049 extern "C" int isnan (double);
00050 extern "C" int isinf (double);
00051 # endif
00052 # else
00053
00054
00055 # endif
00056 #endif
00057
00058 #if defined (__FreeBSD__)
00059 # if __FreeBSD_version < 500000
00060 extern "C" {
00061 inline int isnan(double r) { return !(r <= 0 || r >= 0); }
00062 }
00063 # endif
00064 #endif
00065
00066 #if defined (__CYGWIN__)
00067 #include <ieeefp.h>
00068 #endif
00069
00070
00071 #include <iostream>
00072
00073 #include <simgear/debug/logstream.hxx>
00074 #include <simgear/misc/sg_path.hxx>
00075
00076 #include "soundmgr_openal.hxx"
00077
00078 #if defined(__MINGW32__)
00079 #define isnan(x) _isnan(x)
00080 #endif
00081
00082
00083
00084
00085
00086
00087 SGSoundMgr::SGSoundMgr() {
00088
00089 SG_LOG( SG_GENERAL, SG_INFO, "Initializing OpenAL sound manager" );
00090
00091
00092 #if defined(ALUT_API_MAJOR_VERSION) && ALUT_API_MAJOR_VERSION >= 1
00093 if (!alutInit(NULL, NULL))
00094 {
00095 ALenum error = alutGetError ();
00096 SG_LOG( SG_GENERAL, SG_ALERT, "Audio initialization failed!" );
00097 SG_LOG( SG_GENERAL, SG_ALERT, " "+string(alutGetErrorString(error)));
00098 working = false;
00099 context = 0;
00100 }
00101 else
00102 {
00103 working = true;
00104 context = alcGetCurrentContext();
00105 }
00106 #else
00107 if ( (dev = alcOpenDevice( NULL )) != NULL
00108 && ( context = alcCreateContext( dev, NULL )) != NULL ) {
00109 working = true;
00110 alcMakeContextCurrent( context );
00111 } else {
00112 working = false;
00113 context = 0;
00114 SG_LOG( SG_GENERAL, SG_ALERT, "Audio initialization failed!" );
00115 }
00116 #endif
00117
00118 listener_pos[0] = 0.0;
00119 listener_pos[1] = 0.0;
00120 listener_pos[2] = 0.0;
00121
00122 listener_vel[0] = 0.0;
00123 listener_vel[1] = 0.0;
00124 listener_vel[2] = 0.0;
00125
00126 listener_ori[0] = 0.0;
00127 listener_ori[1] = 0.0;
00128 listener_ori[2] = -1.0;
00129 listener_ori[3] = 0.0;
00130 listener_ori[4] = 1.0;
00131 listener_ori[5] = 0.0;
00132
00133 alListenerf( AL_GAIN, 0.0f );
00134 alListenerfv( AL_POSITION, listener_pos );
00135 alListenerfv( AL_VELOCITY, listener_vel );
00136 alListenerfv( AL_ORIENTATION, listener_ori );
00137 alGetError();
00138 if ( alGetError() != AL_NO_ERROR) {
00139 SG_LOG( SG_GENERAL, SG_ALERT,
00140 "Oops AL error after audio initialization!" );
00141 }
00142
00143
00144 alDopplerFactor(1.0);
00145 alDopplerVelocity(340.0);
00146 }
00147
00148
00149
00150 SGSoundMgr::~SGSoundMgr() {
00151
00152 #if defined(ALUT_API_MAJOR_VERSION) && ALUT_API_MAJOR_VERSION >= 1
00153 alutExit ();
00154 #else
00155 if (context)
00156 alcDestroyContext( context );
00157 #endif
00158 }
00159
00160
00161
00162 void SGSoundMgr::init() {
00163
00164
00165
00166 samples.clear();
00167 }
00168
00169
00170 void SGSoundMgr::bind ()
00171 {
00172
00173 }
00174
00175
00176 void SGSoundMgr::unbind ()
00177 {
00178
00179 }
00180
00181
00182
00183 void SGSoundMgr::update( double dt ) {
00184 }
00185
00186
00187 void
00188 SGSoundMgr::pause ()
00189 {
00190 if (context) {
00191 alcSuspendContext( context );
00192 if ( alGetError() != AL_NO_ERROR) {
00193 SG_LOG( SG_GENERAL, SG_ALERT,
00194 "Oops AL error after soundmgr pause()!" );
00195 }
00196 }
00197 }
00198
00199
00200 void
00201 SGSoundMgr::resume ()
00202 {
00203 if (context) {
00204 alcProcessContext( context );
00205 if ( alGetError() != AL_NO_ERROR) {
00206 SG_LOG( SG_GENERAL, SG_ALERT,
00207 "Oops AL error after soundmgr resume()!" );
00208 }
00209 }
00210 }
00211
00212
00213
00214 bool SGSoundMgr::add( SGSoundSample *sound, const string& refname ) {
00215
00216 sample_map_iterator sample_it = samples.find( refname );
00217 if ( sample_it != samples.end() ) {
00218
00219 return false;
00220 }
00221
00222 samples[refname] = sound;
00223
00224 return true;
00225 }
00226
00227
00228
00229 bool SGSoundMgr::remove( const string &refname ) {
00230
00231 sample_map_iterator sample_it = samples.find( refname );
00232 if ( sample_it != samples.end() ) {
00233
00234
00235 samples.erase( sample_it );
00236
00237
00238 return true;
00239 } else {
00240
00241 return false;
00242 }
00243 }
00244
00245
00246
00247 bool SGSoundMgr::exists( const string &refname ) {
00248 sample_map_iterator sample_it = samples.find( refname );
00249 if ( sample_it != samples.end() ) {
00250 return true;
00251 } else {
00252 return false;
00253 }
00254 }
00255
00256
00257
00258
00259 SGSoundSample *SGSoundMgr::find( const string &refname ) {
00260 sample_map_iterator sample_it = samples.find( refname );
00261 if ( sample_it != samples.end() ) {
00262 return sample_it->second;
00263 } else {
00264 return NULL;
00265 }
00266 }
00267
00268
00269
00270
00271 bool SGSoundMgr::play_looped( const string &refname ) {
00272 SGSoundSample *sample;
00273
00274 if ( (sample = find( refname )) == NULL ) {
00275 return false;
00276 } else {
00277 sample->play( true );
00278 return true;
00279 }
00280 }
00281
00282
00283
00284 bool SGSoundMgr::play_once( const string& refname ) {
00285 SGSoundSample *sample;
00286
00287 if ( (sample = find( refname )) == NULL ) {
00288 return false;
00289 } else {
00290 sample->play( false );
00291 return true;
00292 }
00293 }
00294
00295
00296
00297 bool SGSoundMgr::is_playing( const string& refname ) {
00298 SGSoundSample *sample;
00299
00300 if ( (sample = find( refname )) == NULL ) {
00301 return false;
00302 } else {
00303 return ( sample->is_playing() );
00304 }
00305 }
00306
00307
00308
00309 bool SGSoundMgr::stop( const string& refname ) {
00310 SGSoundSample *sample;
00311
00312 if ( (sample = find( refname )) == NULL ) {
00313 return false;
00314 } else {
00315 sample->stop();
00316 return true;
00317 }
00318 }
00319
00320
00321
00322 void SGSoundMgr::set_source_pos_all( ALfloat *pos ) {
00323 if ( isnan(pos[0]) || isnan(pos[1]) || isnan(pos[2]) ) {
00324
00325 return;
00326 }
00327
00328 sample_map_iterator sample_current = samples.begin();
00329 sample_map_iterator sample_end = samples.end();
00330 for ( ; sample_current != sample_end; ++sample_current ) {
00331 SGSoundSample *sample = sample_current->second;
00332 sample->set_source_pos( pos );
00333 }
00334 }
00335
00336
00337
00338 void SGSoundMgr::set_source_vel_all( ALfloat *vel ) {
00339 if ( isnan(vel[0]) || isnan(vel[1]) || isnan(vel[2]) ) {
00340
00341 return;
00342 }
00343
00344 sample_map_iterator sample_current = samples.begin();
00345 sample_map_iterator sample_end = samples.end();
00346 for ( ; sample_current != sample_end; ++sample_current ) {
00347 SGSoundSample *sample = sample_current->second;
00348 sample->set_source_vel( vel, listener_vel );
00349 }
00350 }