1 | /** |
---|
2 | * SoundManager.cpp |
---|
3 | * |
---|
4 | * Original Code : Van Stokes, Jr. (http://www.EvilMasterMindsInc.com) - Aug 05 |
---|
5 | * Modified Code : Steven Gay - mec3@bluewin.ch - Septembre 2005 |
---|
6 | * |
---|
7 | */ |
---|
8 | #include "SoundManager.h" |
---|
9 | |
---|
10 | SoundManager* SoundManager::mSoundManager = NULL; |
---|
11 | |
---|
12 | /****************************************************************************/ |
---|
13 | SoundManager::SoundManager( void ) |
---|
14 | { |
---|
15 | mSoundManager = this; |
---|
16 | |
---|
17 | isInitialised = false; |
---|
18 | isSoundOn = false; |
---|
19 | mSoundDevice = 0; |
---|
20 | mSoundContext = 0; |
---|
21 | |
---|
22 | mAudioPath = ""; |
---|
23 | |
---|
24 | // EAX related |
---|
25 | isEAXPresent = false; |
---|
26 | |
---|
27 | // Initial position of the listener |
---|
28 | position[0] = 0.0; |
---|
29 | position[1] = 0.0; |
---|
30 | position[2] = 0.0; |
---|
31 | |
---|
32 | // Initial velocity of the listener |
---|
33 | velocity[0] = 0.0; |
---|
34 | velocity[1] = 0.0; |
---|
35 | velocity[2] = 0.0; |
---|
36 | |
---|
37 | // Initial orientation of the listener = direction + direction up |
---|
38 | orientation[0] = 0.0; |
---|
39 | orientation[1] = 0.0; |
---|
40 | orientation[2] = -1.0; |
---|
41 | orientation[3] = 0.0; |
---|
42 | orientation[4] = 1.0; |
---|
43 | orientation[5] = 0.0; |
---|
44 | |
---|
45 | // Needed because of hardware limitation |
---|
46 | mAudioBuffersInUseCount = 0; |
---|
47 | mAudioSourcesInUseCount = 0; |
---|
48 | |
---|
49 | for ( int i=0; i < MAX_AUDIO_SOURCES; i++ ) |
---|
50 | { |
---|
51 | mAudioSources[i] = 0; |
---|
52 | mAudioSourceInUse[i] = false; |
---|
53 | } |
---|
54 | |
---|
55 | for ( int i=0; i < MAX_AUDIO_BUFFERS; i++ ) |
---|
56 | { |
---|
57 | mAudioBuffers[i] = 0; |
---|
58 | strcpy( mAudioBufferFileName[i], "--" ); |
---|
59 | mAudioBufferInUse[i] = false; |
---|
60 | } |
---|
61 | |
---|
62 | printf("SoudManager Created.\n"); |
---|
63 | } |
---|
64 | |
---|
65 | /****************************************************************************/ |
---|
66 | SoundManager::~SoundManager( void ) |
---|
67 | { |
---|
68 | // Delete the sources and buffers |
---|
69 | alDeleteSources( MAX_AUDIO_SOURCES, mAudioSources ); |
---|
70 | alDeleteBuffers( MAX_AUDIO_BUFFERS, mAudioBuffers ); |
---|
71 | |
---|
72 | // Destroy the sound context and device |
---|
73 | mSoundContext = alcGetCurrentContext(); |
---|
74 | mSoundDevice = alcGetContextsDevice( mSoundContext ); |
---|
75 | alcMakeContextCurrent( NULL ); |
---|
76 | alcDestroyContext( mSoundContext ); |
---|
77 | if ( mSoundDevice) |
---|
78 | alcCloseDevice( mSoundDevice ); |
---|
79 | |
---|
80 | alutExit(); |
---|
81 | |
---|
82 | printf("SoudManager Destroyed.\n"); |
---|
83 | } |
---|
84 | |
---|
85 | /****************************************************************************/ |
---|
86 | void SoundManager::selfDestruct( void ) |
---|
87 | { |
---|
88 | if ( getSingletonPtr() ) delete getSingletonPtr(); |
---|
89 | } |
---|
90 | |
---|
91 | /****************************************************************************/ |
---|
92 | SoundManager* SoundManager::createManager( void ) |
---|
93 | { |
---|
94 | if (mSoundManager == 0) |
---|
95 | mSoundManager = new SoundManager(); |
---|
96 | return mSoundManager; |
---|
97 | } |
---|
98 | |
---|
99 | /****************************************************************************/ |
---|
100 | bool SoundManager::init( void ) |
---|
101 | { |
---|
102 | // It's an error to initialise twice OpenAl |
---|
103 | if ( isInitialised ) return true; |
---|
104 | |
---|
105 | // Open an audio device |
---|
106 | mSoundDevice = alcOpenDevice( NULL ); // TODO ((ALubyte*) "DirectSound3D"); |
---|
107 | // mSoundDevice = alcOpenDevice( "DirectSound3D" ); |
---|
108 | |
---|
109 | // Check for errors |
---|
110 | if ( !mSoundDevice ) |
---|
111 | { |
---|
112 | printf( "SoundManager::init error : No sound device.\n"); |
---|
113 | return false; |
---|
114 | } |
---|
115 | |
---|
116 | mSoundContext = alcCreateContext( mSoundDevice, NULL ); |
---|
117 | // if ( checkAlError() || !mSoundContext ) // TODO seems not to work! why ? |
---|
118 | if ( !mSoundContext ) |
---|
119 | { |
---|
120 | printf( "SoundManager::init error : No sound context.\n"); |
---|
121 | return false; |
---|
122 | } |
---|
123 | |
---|
124 | // Make the context current and active |
---|
125 | alcMakeContextCurrent( mSoundContext ); |
---|
126 | if ( checkALError( "Init()" ) ) |
---|
127 | { |
---|
128 | printf( "SoundManager::init error : could not make sound context current and active.\n"); |
---|
129 | return false; |
---|
130 | } |
---|
131 | |
---|
132 | // Check for EAX 2.0 support and |
---|
133 | // Retrieves function entry addresses to API ARB extensions, in this case, |
---|
134 | // for the EAX extension. See Appendix 1 (Extensions) of |
---|
135 | // http://www.openal.org/openal_webstf/specs/OpenAL1-1Spec_html/al11spec7.html |
---|
136 | // |
---|
137 | // TODO EAX fct not used anywhere in the code ... !!! |
---|
138 | isEAXPresent = alIsExtensionPresent( "EAX2.0" ); |
---|
139 | if ( isEAXPresent ) |
---|
140 | { |
---|
141 | printf( "EAX 2.0 Extension available\n" ); |
---|
142 | |
---|
143 | #ifdef _USEEAX |
---|
144 | eaxSet = (EAXSet) alGetProcAddress( "EAXSet" ); |
---|
145 | if ( eaxSet == NULL ) |
---|
146 | isEAXPresent = false; |
---|
147 | |
---|
148 | eaxGet = (EAXGet) alGetProcAddress( "EAXGet" ); |
---|
149 | if ( eaxGet == NULL ) |
---|
150 | isEAXPresent = false; |
---|
151 | |
---|
152 | if ( !isEAXPresent ) |
---|
153 | checkALError( "Failed to get the EAX extension functions adresses.\n" ); |
---|
154 | #else |
---|
155 | isEAXPresent = false; |
---|
156 | printf( "... but not used.\n" ); |
---|
157 | #endif // _USEEAX |
---|
158 | |
---|
159 | } |
---|
160 | |
---|
161 | // Test if Ogg Vorbis extension is present |
---|
162 | isOggExtensionPresent(); |
---|
163 | |
---|
164 | // Create the Audio Buffers |
---|
165 | alGenBuffers( MAX_AUDIO_BUFFERS, mAudioBuffers ); |
---|
166 | if (checkALError("init::alGenBuffers:") ) |
---|
167 | return false; |
---|
168 | |
---|
169 | // Generate Sources |
---|
170 | alGenSources( MAX_AUDIO_SOURCES, mAudioSources ); |
---|
171 | if (checkALError( "init::alGenSources :") ) |
---|
172 | return false; |
---|
173 | |
---|
174 | |
---|
175 | // Setup the initial listener parameters |
---|
176 | // -> location |
---|
177 | alListenerfv( AL_POSITION, position ); |
---|
178 | |
---|
179 | // -> velocity |
---|
180 | alListenerfv( AL_VELOCITY, velocity ); |
---|
181 | |
---|
182 | // -> orientation |
---|
183 | alListenerfv( AL_ORIENTATION, orientation ); |
---|
184 | |
---|
185 | // Gain |
---|
186 | alListenerf( AL_GAIN, 1.0 ); |
---|
187 | |
---|
188 | // Initialise Doppler |
---|
189 | alDopplerFactor( 1.0 ); // 1.2 = exaggerate the pitch shift by 20% |
---|
190 | alDopplerVelocity( 343.0f ); // m/s this may need to be scaled at some point |
---|
191 | |
---|
192 | // Ok |
---|
193 | isInitialised = true; |
---|
194 | isSoundOn = true; |
---|
195 | |
---|
196 | printf( "SoundManager initialised.\n\n"); |
---|
197 | |
---|
198 | return true; |
---|
199 | } |
---|
200 | |
---|
201 | /****************************************************************************/ |
---|
202 | bool SoundManager::checkALError( void ) |
---|
203 | { |
---|
204 | ALenum errCode; |
---|
205 | if ( ( errCode = alGetError() ) != AL_NO_ERROR ) |
---|
206 | { |
---|
207 | std::string err = "ERROR SoundManager:: "; |
---|
208 | err += (char*) alGetString( errCode ); |
---|
209 | |
---|
210 | printf( "%s\n", err.c_str()); |
---|
211 | return true; |
---|
212 | } |
---|
213 | return false; |
---|
214 | } |
---|
215 | |
---|
216 | /****************************************************************************/ |
---|
217 | std::string SoundManager::listAvailableDevices( void ) |
---|
218 | { |
---|
219 | std::string str = "Sound Devices available : "; |
---|
220 | |
---|
221 | if ( alcIsExtensionPresent( NULL, "ALC_ENUMERATION_EXT" ) == AL_TRUE ) |
---|
222 | { |
---|
223 | str = "List of Devices : "; |
---|
224 | str += (char*) alcGetString( NULL, ALC_DEVICE_SPECIFIER ); |
---|
225 | str += "\n"; |
---|
226 | } |
---|
227 | else |
---|
228 | str += " ... eunmeration error.\n"; |
---|
229 | |
---|
230 | return str; |
---|
231 | } |
---|
232 | |
---|
233 | /****************************************************************************/ |
---|
234 | bool SoundManager::checkALError( std::string pMsg ) |
---|
235 | { |
---|
236 | ALenum error = 0; |
---|
237 | |
---|
238 | if ( (error = alGetError()) == AL_NO_ERROR ) |
---|
239 | return false; |
---|
240 | |
---|
241 | char mStr[256]; |
---|
242 | switch ( error ) |
---|
243 | { |
---|
244 | case AL_INVALID_NAME: |
---|
245 | sprintf(mStr,"ERROR SoundManager::%s Invalid Name", pMsg.c_str()); |
---|
246 | break; |
---|
247 | case AL_INVALID_ENUM: |
---|
248 | sprintf(mStr,"ERROR SoundManager::%s Invalid Enum", pMsg.c_str()); |
---|
249 | break; |
---|
250 | case AL_INVALID_VALUE: |
---|
251 | sprintf(mStr,"ERROR SoundManager::%s Invalid Value", pMsg.c_str()); |
---|
252 | break; |
---|
253 | case AL_INVALID_OPERATION: |
---|
254 | sprintf(mStr,"ERROR SoundManager::%s Invalid Operation", pMsg.c_str()); |
---|
255 | break; |
---|
256 | case AL_OUT_OF_MEMORY: |
---|
257 | sprintf(mStr,"ERROR SoundManager::%s Out Of Memory", pMsg.c_str()); |
---|
258 | break; |
---|
259 | default: |
---|
260 | sprintf(mStr,"ERROR SoundManager::%s Unknown error (%i) case in testALError()", pMsg.c_str(), error); |
---|
261 | break; |
---|
262 | }; |
---|
263 | |
---|
264 | printf( "%s\n", mStr ); |
---|
265 | |
---|
266 | return true; |
---|
267 | } |
---|
268 | |
---|
269 | /*****************************************************************************/ |
---|
270 | void SoundManager::testSound( const char* wavFile ) |
---|
271 | { |
---|
272 | ALuint buffer; |
---|
273 | ALuint source; |
---|
274 | ALenum format; |
---|
275 | ALsizei size; |
---|
276 | ALvoid* data; |
---|
277 | ALsizei freq; |
---|
278 | ALboolean loop; |
---|
279 | alGenBuffers( 1, &buffer ); |
---|
280 | if ( checkALError( "testSound()" ) ) |
---|
281 | return; |
---|
282 | |
---|
283 | // This is the same for alutLoadWAVMemory |
---|
284 | #ifndef MACINTOSH_AL |
---|
285 | alutLoadWAVFile( (ALbyte*) wavFile, &format, &data, &size, &freq, &loop ); |
---|
286 | #else |
---|
287 | alutLoadWAVFile( (ALbyte*) wavFile, &format, &data, &size, &freq ); |
---|
288 | #endif |
---|
289 | |
---|
290 | alBufferData( buffer, format, data, size, freq ); |
---|
291 | |
---|
292 | alutUnloadWAV( format, data, size, freq ); |
---|
293 | alGenSources( 1, &source ); |
---|
294 | alSourcei( source, AL_BUFFER, buffer ); |
---|
295 | alSourcef( source, AL_PITCH, 1.0f ); |
---|
296 | alSourcef( source, AL_GAIN, 1.0f ); |
---|
297 | |
---|
298 | #ifndef MACINTOSH_AL |
---|
299 | alSourcei( source, AL_LOOPING, loop ); |
---|
300 | #else |
---|
301 | alSourcei( source, AL_LOOPING, false ); // TODO ! But how to get from file? |
---|
302 | #endif |
---|
303 | |
---|
304 | alSourcePlay( source ); |
---|
305 | |
---|
306 | //Or else we risk to destroy the manager too quickly to here anything ! |
---|
307 | for (int i=0;i<50000; i++) {printf(".");}; |
---|
308 | } |
---|
309 | |
---|
310 | // Attempts to aquire an empty audio source and assign it back to the caller |
---|
311 | // via AudioSourceID. This will lock the source |
---|
312 | /*****************************************************************************/ |
---|
313 | bool SoundManager::loadAudio( std::string filename, unsigned int *audioId, |
---|
314 | bool loop ) |
---|
315 | { |
---|
316 | if ( filename.empty() || filename.length() > MAX_FILENAME_LENGTH ) |
---|
317 | return false; |
---|
318 | |
---|
319 | if ( mAudioSourcesInUseCount == MAX_AUDIO_SOURCES ) |
---|
320 | return false; // out of Audio Source slots! |
---|
321 | |
---|
322 | int bufferID = -1; // Identity of the Sound Buffer to use |
---|
323 | int sourceID = -1; // Identity of the Source Buffer to use |
---|
324 | |
---|
325 | alGetError(); // Clear Error Code |
---|
326 | |
---|
327 | // Check and see if the pSoundFile is already loaded into a buffer |
---|
328 | bufferID = locateAudioBuffer( filename ); |
---|
329 | if ( bufferID < 0 ) |
---|
330 | { |
---|
331 | // The sound file isn't loaded in a buffer, lets attempt to load it on the fly |
---|
332 | bufferID = loadAudioInToSystem( filename ); |
---|
333 | if ( bufferID < 0 ) return false; // failed! |
---|
334 | } |
---|
335 | |
---|
336 | // If you are here, the sound the requester wants to reference is in a buffer. |
---|
337 | // Now, we need to find a free Audio Source slot in the sound system |
---|
338 | sourceID = 0; |
---|
339 | |
---|
340 | while ( mAudioSourceInUse[ sourceID ] == true ) sourceID++; |
---|
341 | |
---|
342 | // When you are here, 'mSourceID' now represents a free Audio Source slot |
---|
343 | // The free slot may not be at the end of the array but in the middle of it. |
---|
344 | *audioId = sourceID; // return the Audio Source ID to the caller |
---|
345 | mAudioSourceInUse[ sourceID ] = true; // mark this Source slot as in use |
---|
346 | mAudioSourcesInUseCount++; // bump the 'in use' counter |
---|
347 | |
---|
348 | // Now inform OpenAL of the sound assignment and attach the audio buffer |
---|
349 | // to the audio source |
---|
350 | alSourcei( mAudioSources[sourceID], AL_BUFFER, mAudioBuffers[bufferID] ); |
---|
351 | |
---|
352 | // Steven : Not in the original code !!!!! |
---|
353 | alSourcei( mAudioSources[sourceID], AL_LOOPING, loop ); |
---|
354 | |
---|
355 | if ( checkALError( "loadSource()::alSourcei" ) ) |
---|
356 | return false; |
---|
357 | |
---|
358 | return true; |
---|
359 | } |
---|
360 | |
---|
361 | // Function to check and see if the pSoundFile is already loaded into a buffer |
---|
362 | /*****************************************************************************/ |
---|
363 | int SoundManager::locateAudioBuffer( std::string filename ) |
---|
364 | { |
---|
365 | for ( unsigned int b = 0; b < MAX_AUDIO_BUFFERS; b++ ) |
---|
366 | { |
---|
367 | if ( filename == mAudioBufferFileName[b] ) return (int) b; // TODO Careful : converts unsigned to int! |
---|
368 | } |
---|
369 | return -1; // not found |
---|
370 | } |
---|
371 | |
---|
372 | // Function to load a sound file into an AudioBuffer |
---|
373 | /*****************************************************************************/ |
---|
374 | int SoundManager::loadAudioInToSystem( std::string filename ) |
---|
375 | { |
---|
376 | if ( filename.empty() ) |
---|
377 | return -1; |
---|
378 | |
---|
379 | // Make sure we have audio buffers available |
---|
380 | if ( mAudioBuffersInUseCount == MAX_AUDIO_BUFFERS ) return -1; |
---|
381 | |
---|
382 | // Find a free Audio Buffer slot |
---|
383 | int bufferID = 0; // Identity of the Sound Buffer to use |
---|
384 | |
---|
385 | while ( mAudioBufferInUse[ bufferID ] == true ) bufferID++; |
---|
386 | |
---|
387 | // load .wav, .ogg or .au |
---|
388 | if ( filename.find( ".wav", 0 ) != std::string::npos ) |
---|
389 | { |
---|
390 | printf(" ---> found Wav\n"); |
---|
391 | // When you are here, bufferID now represents a free Audio Buffer slot |
---|
392 | // Attempt to load the SoundFile into the buffer |
---|
393 | if ( !loadWAV( filename, mAudioBuffers[ bufferID ] ) ) return -1; |
---|
394 | } |
---|
395 | else if ( filename.find( ".ogg", 0 ) != std::string::npos ) |
---|
396 | { |
---|
397 | printf(" ---> found ogg\n"); |
---|
398 | // TODO if ( !loadOGG( filename, mAudioBuffers[mBufferID]) ) return -1; |
---|
399 | } |
---|
400 | else if ( filename.find( ".au", 0 ) != std::string::npos ) |
---|
401 | { |
---|
402 | printf(" ---> found au\n"); |
---|
403 | // TODO if ( !loadAU( filename, mAudioBuffers[mBufferID]) ) return -1; |
---|
404 | } |
---|
405 | |
---|
406 | // Successful load of the file into the Audio Buffer. |
---|
407 | mAudioBufferInUse[ bufferID ] = true; // Buffer now in use |
---|
408 | |
---|
409 | strcpy( mAudioBufferFileName[ bufferID ], filename.c_str() ); // save the file descriptor |
---|
410 | |
---|
411 | mAudioBuffersInUseCount++; // bump the 'in use' counter |
---|
412 | |
---|
413 | return bufferID; |
---|
414 | } |
---|
415 | |
---|
416 | // Function to load a wave file and assigned it to a buffer |
---|
417 | /****************************************************************************/ |
---|
418 | bool SoundManager::loadWAV( std::string filename, ALuint pDestAudioBuffer ) |
---|
419 | { |
---|
420 | ALenum format; //for the buffer format |
---|
421 | ALsizei size; //the bit depth |
---|
422 | ALsizei freq; //for the frequency of the buffer |
---|
423 | ALboolean loop; //looped |
---|
424 | ALvoid* data; //data for the buffer |
---|
425 | |
---|
426 | std::string mFullPath = mAudioPath; |
---|
427 | |
---|
428 | alGetError(); // Clear Error Code |
---|
429 | |
---|
430 | // Load in the WAV file from disk |
---|
431 | //mFullPath += "\\"; |
---|
432 | mFullPath += filename; |
---|
433 | |
---|
434 | #ifndef MACINTOSH_AL |
---|
435 | alutLoadWAVFile( (ALbyte*)mFullPath.c_str(), &format, &data, &size, &freq, &loop); |
---|
436 | #else |
---|
437 | alutLoadWAVFile( (ALbyte*)mFullPath.c_str(), &format, &data, &size, &freq); |
---|
438 | #endif |
---|
439 | |
---|
440 | if ( checkALError("loadWAV::alutLoadWAVFile: ") ) |
---|
441 | return false; |
---|
442 | |
---|
443 | // Copy the new WAV data into the buffer |
---|
444 | alBufferData(pDestAudioBuffer, format, data, size, freq); |
---|
445 | if ( checkALError("loadWAV::alBufferData: ") ) |
---|
446 | return false; |
---|
447 | |
---|
448 | // Unload the WAV file |
---|
449 | alutUnloadWAV(format, data, size, freq); |
---|
450 | if ( checkALError("loadWAV::alutUnloadWAV: ") ) |
---|
451 | return false; |
---|
452 | |
---|
453 | return true; |
---|
454 | } |
---|
455 | |
---|
456 | /****************************************************************************/ |
---|
457 | bool SoundManager::playAudio( unsigned int audioID, bool forceRestart ) |
---|
458 | { |
---|
459 | // Make sure the audio source ident is valid and usable |
---|
460 | if ( audioID >= MAX_AUDIO_SOURCES || !mAudioSourceInUse[audioID]) |
---|
461 | return false; |
---|
462 | |
---|
463 | int sourceAudioState = 0; |
---|
464 | |
---|
465 | alGetError(); |
---|
466 | |
---|
467 | // Are we currently playing the audio source? |
---|
468 | alGetSourcei( mAudioSources[audioID], AL_SOURCE_STATE, &sourceAudioState ); |
---|
469 | |
---|
470 | if ( sourceAudioState == AL_PLAYING ) |
---|
471 | { |
---|
472 | if ( forceRestart ) |
---|
473 | stopAudio( audioID ); |
---|
474 | else |
---|
475 | return false; // Not forced, so we don't do anything |
---|
476 | } |
---|
477 | |
---|
478 | alSourcePlay( mAudioSources[ audioID ] ); |
---|
479 | if ( checkALError( "playAudio::alSourcePlay: ") ) |
---|
480 | return false; |
---|
481 | |
---|
482 | return true; |
---|
483 | } |
---|
484 | |
---|
485 | /****************************************************************************/ |
---|
486 | bool SoundManager::pauseAudio( unsigned int audioID ) |
---|
487 | { |
---|
488 | // Make sure the audio source ident is valid and usable |
---|
489 | if ( audioID >= MAX_AUDIO_SOURCES || !mAudioSourceInUse[audioID] ) |
---|
490 | return false; |
---|
491 | |
---|
492 | alGetError(); |
---|
493 | |
---|
494 | alSourcePause( mAudioSources[audioID] ); |
---|
495 | |
---|
496 | if ( checkALError( "pauseAudio::alSourceStop ") ) |
---|
497 | return false; |
---|
498 | |
---|
499 | return true; |
---|
500 | } |
---|
501 | |
---|
502 | /****************************************************************************/ |
---|
503 | bool SoundManager::pauseAllAudio( void ) |
---|
504 | { |
---|
505 | if ( mAudioSourcesInUseCount >= MAX_AUDIO_SOURCES ) |
---|
506 | return false; |
---|
507 | |
---|
508 | alGetError(); |
---|
509 | |
---|
510 | alSourcePausev( mAudioSourcesInUseCount, mAudioSources ); |
---|
511 | |
---|
512 | if ( checkALError( "pauseAllAudio::alSourceStop ") ) |
---|
513 | return false; |
---|
514 | |
---|
515 | return true; |
---|
516 | } |
---|
517 | |
---|
518 | // We could use playAudio instead ! |
---|
519 | /****************************************************************************/ |
---|
520 | bool SoundManager::resumeAudio( unsigned int audioID ) |
---|
521 | { |
---|
522 | // Make sure the audio source ident is valid and usable |
---|
523 | if ( audioID >= MAX_AUDIO_SOURCES || !mAudioSourceInUse[audioID] ) |
---|
524 | return false; |
---|
525 | |
---|
526 | alGetError(); |
---|
527 | |
---|
528 | // If the sound was paused the sound will resume, else it will play from |
---|
529 | // the beginning ! |
---|
530 | // TODO No check for forced restart. Verify if it is what you want ? |
---|
531 | alSourcePlay( mAudioSources[ audioID ] ); |
---|
532 | |
---|
533 | if ( checkALError( "resumeAudio::alSourceStop ") ) |
---|
534 | return false; |
---|
535 | |
---|
536 | return true; |
---|
537 | } |
---|
538 | |
---|
539 | /****************************************************************************/ |
---|
540 | bool SoundManager::resumeAllAudio( void ) |
---|
541 | { |
---|
542 | if ( mAudioSourcesInUseCount >= MAX_AUDIO_SOURCES ) |
---|
543 | return false; |
---|
544 | |
---|
545 | alGetError(); |
---|
546 | |
---|
547 | int sourceAudioState = 0; |
---|
548 | |
---|
549 | for ( int i=0; i<mAudioSourcesInUseCount; i++ ) |
---|
550 | { |
---|
551 | // Are we currently playing the audio source? |
---|
552 | alGetSourcei( mAudioSources[i], AL_SOURCE_STATE, &sourceAudioState ); |
---|
553 | |
---|
554 | if ( sourceAudioState == AL_PAUSED ) |
---|
555 | { |
---|
556 | resumeAudio( i ); |
---|
557 | } |
---|
558 | } |
---|
559 | |
---|
560 | if ( checkALError( "resumeAllAudio::alSourceStop ") ) |
---|
561 | return false; |
---|
562 | |
---|
563 | return true; |
---|
564 | } |
---|
565 | |
---|
566 | /****************************************************************************/ |
---|
567 | bool SoundManager::stopAudio( unsigned int audioID ) |
---|
568 | { |
---|
569 | // Make sure the audio source ident is valid and usable |
---|
570 | if ( audioID >= MAX_AUDIO_SOURCES || !mAudioSourceInUse[audioID] ) |
---|
571 | return false; |
---|
572 | |
---|
573 | alGetError(); |
---|
574 | |
---|
575 | alSourceStop( mAudioSources[audioID] ); |
---|
576 | |
---|
577 | if ( checkALError( "stopAudio::alSourceStop ") ) |
---|
578 | return false; |
---|
579 | |
---|
580 | return true; |
---|
581 | } |
---|
582 | |
---|
583 | /****************************************************************************/ |
---|
584 | bool SoundManager::stopAllAudio( void ) |
---|
585 | { |
---|
586 | if ( mAudioSourcesInUseCount >= MAX_AUDIO_SOURCES ) |
---|
587 | return false; |
---|
588 | |
---|
589 | alGetError(); |
---|
590 | |
---|
591 | for ( int i=0; i<mAudioSourcesInUseCount; i++ ) |
---|
592 | { |
---|
593 | stopAudio( i ); |
---|
594 | } |
---|
595 | |
---|
596 | if ( checkALError( "stopAllAudio::alSourceStop ") ) |
---|
597 | return false; |
---|
598 | |
---|
599 | return true; |
---|
600 | } |
---|
601 | |
---|
602 | /****************************************************************************/ |
---|
603 | bool SoundManager::releaseAudio( unsigned int audioID ) |
---|
604 | { |
---|
605 | if ( audioID >= MAX_AUDIO_SOURCES ) |
---|
606 | return false; |
---|
607 | alSourceStop( mAudioSources[audioID] ); |
---|
608 | mAudioSourceInUse[ audioID ] = false; |
---|
609 | mAudioSourcesInUseCount--; |
---|
610 | return true; |
---|
611 | } |
---|
612 | |
---|
613 | /****************************************************************************/ |
---|
614 | bool SoundManager::setSound( unsigned int audioID, Vector3 position, |
---|
615 | Vector3 velocity, Vector3 direction, float maxDistance, |
---|
616 | bool playNow, bool forceRestart, float minGain ) |
---|
617 | { |
---|
618 | if ( audioID >= MAX_AUDIO_SOURCES || !mAudioSourceInUse[ audioID ] ) |
---|
619 | return false; |
---|
620 | |
---|
621 | // Set the position |
---|
622 | ALfloat pos[] = { position.x, position.y, position.z }; |
---|
623 | |
---|
624 | alSourcefv( mAudioSources[ audioID ], AL_POSITION, pos ); |
---|
625 | |
---|
626 | if ( checkALError( "setSound::alSourcefv:AL_POSITION" ) ) |
---|
627 | return false; |
---|
628 | |
---|
629 | // Set the veclocity |
---|
630 | ALfloat vel[] = { velocity.x, velocity.y, velocity.z }; |
---|
631 | |
---|
632 | alSourcefv( mAudioSources[ audioID ], AL_VELOCITY, vel ); |
---|
633 | |
---|
634 | if ( checkALError( "setSound::alSourcefv:AL_VELOCITY" ) ) |
---|
635 | return false; |
---|
636 | |
---|
637 | // Set the direction |
---|
638 | ALfloat dir[] = { velocity.x, velocity.y, velocity.z }; |
---|
639 | |
---|
640 | alSourcefv( mAudioSources[ audioID ], AL_DIRECTION, dir ); |
---|
641 | |
---|
642 | if ( checkALError( "setSound::alSourcefv:AL_DIRECTION" ) ) |
---|
643 | return false; |
---|
644 | |
---|
645 | // Set the max audible distance |
---|
646 | alSourcef( mAudioSources[ audioID ], AL_MAX_DISTANCE, maxDistance ); |
---|
647 | |
---|
648 | // Set the MIN_GAIN ( IMPORTANT - if not set, nothing audible! ) |
---|
649 | alSourcef( mAudioSources[ audioID ], AL_MIN_GAIN, minGain ); |
---|
650 | |
---|
651 | // Set the max gain |
---|
652 | alSourcef( mAudioSources[ audioID ], AL_MAX_GAIN, 1.0f ); // TODO as parameter ? global ? |
---|
653 | |
---|
654 | // Set the rollof factor |
---|
655 | alSourcef( mAudioSources[ audioID ], AL_ROLLOFF_FACTOR, 1.0f ); // TODO as parameter ? |
---|
656 | |
---|
657 | // Do we play the sound now ? |
---|
658 | if ( playNow ) return playAudio( audioID, forceRestart ); // TODO bof... not in this fct |
---|
659 | |
---|
660 | return true; |
---|
661 | } |
---|
662 | |
---|
663 | /****************************************************************************/ |
---|
664 | bool SoundManager::setSoundPosition( unsigned int audioID, Vector3 position ) |
---|
665 | { |
---|
666 | if ( audioID >= MAX_AUDIO_SOURCES || !mAudioSourceInUse[ audioID ] ) |
---|
667 | return false; |
---|
668 | |
---|
669 | // Set the position |
---|
670 | ALfloat pos[] = { position.x, position.y, position.z }; |
---|
671 | |
---|
672 | alSourcefv( mAudioSources[ audioID ], AL_POSITION, pos ); |
---|
673 | |
---|
674 | if ( checkALError( "setSound::alSourcefv:AL_POSITION" ) ) |
---|
675 | return false; |
---|
676 | |
---|
677 | return true; |
---|
678 | } |
---|
679 | |
---|
680 | /****************************************************************************/ |
---|
681 | bool SoundManager::setSoundPosition( unsigned int audioID, Vector3 position, |
---|
682 | Vector3 velocity, Vector3 direction ) |
---|
683 | { |
---|
684 | if ( audioID >= MAX_AUDIO_SOURCES || !mAudioSourceInUse[ audioID ] ) |
---|
685 | return false; |
---|
686 | |
---|
687 | // Set the position |
---|
688 | ALfloat pos[] = { position.x, position.y, position.z }; |
---|
689 | |
---|
690 | alSourcefv( mAudioSources[ audioID ], AL_POSITION, pos ); |
---|
691 | |
---|
692 | if ( checkALError( "setSound::alSourcefv:AL_POSITION" ) ) |
---|
693 | return false; |
---|
694 | |
---|
695 | // Set the veclocity |
---|
696 | ALfloat vel[] = { velocity.x, velocity.y, velocity.z }; |
---|
697 | |
---|
698 | alSourcefv( mAudioSources[ audioID ], AL_VELOCITY, vel ); |
---|
699 | |
---|
700 | if ( checkALError( "setSound::alSourcefv:AL_VELOCITY" ) ) |
---|
701 | return false; |
---|
702 | |
---|
703 | // Set the direction |
---|
704 | ALfloat dir[] = { velocity.x, velocity.y, velocity.z }; |
---|
705 | |
---|
706 | alSourcefv( mAudioSources[ audioID ], AL_DIRECTION, dir ); |
---|
707 | |
---|
708 | if ( checkALError( "setSound::alSourcefv:AL_DIRECTION" ) ) |
---|
709 | return false; |
---|
710 | |
---|
711 | return true; |
---|
712 | } |
---|
713 | |
---|
714 | /****************************************************************************/ |
---|
715 | bool SoundManager::setListenerPosition( Vector3 position, Vector3 velocity, |
---|
716 | Quaternion orientation ) |
---|
717 | { |
---|
718 | Vector3 axis; |
---|
719 | |
---|
720 | // Set the position |
---|
721 | ALfloat pos[] = { position.x, position.y, position.z }; |
---|
722 | |
---|
723 | alListenerfv( AL_POSITION, pos ); |
---|
724 | |
---|
725 | if ( checkALError( "setListenerPosition::alListenerfv:AL_POSITION" ) ) |
---|
726 | return false; |
---|
727 | |
---|
728 | // Set the veclocity |
---|
729 | ALfloat vel[] = { velocity.x, velocity.y, velocity.z }; |
---|
730 | |
---|
731 | alListenerfv( AL_VELOCITY, vel ); |
---|
732 | |
---|
733 | if ( checkALError( "setListenerPosition::alListenerfv:AL_VELOCITY" ) ) |
---|
734 | return false; |
---|
735 | |
---|
736 | // Orientation of the listener : look at then look up |
---|
737 | axis = Vector3::ZERO; |
---|
738 | axis.x = orientation.getYaw().valueRadians(); |
---|
739 | axis.y = orientation.getPitch().valueRadians(); |
---|
740 | axis.z = orientation.getRoll().valueRadians(); |
---|
741 | |
---|
742 | // Set the direction |
---|
743 | ALfloat dir[] = { axis.x, axis.y, axis.z }; |
---|
744 | |
---|
745 | alListenerfv( AL_ORIENTATION, dir ); |
---|
746 | |
---|
747 | if ( checkALError( "setListenerPosition::alListenerfv:AL_DIRECTION" ) ) |
---|
748 | return false; |
---|
749 | |
---|
750 | // TODO as parameters ? |
---|
751 | alListenerf( AL_MAX_DISTANCE, 10000.0f ); |
---|
752 | alListenerf( AL_MIN_GAIN, 0.0f ); |
---|
753 | alListenerf( AL_MAX_GAIN, 1.0f ); |
---|
754 | alListenerf( AL_GAIN, 1.0f ); |
---|
755 | |
---|
756 | return true; |
---|
757 | } |
---|
758 | |
---|
759 | /****************************************************************************/ |
---|
760 | bool SoundManager::isOggExtensionPresent( void ) |
---|
761 | { |
---|
762 | if ( alIsExtensionPresent( "AL_EXT_vorbis" ) != AL_TRUE ) |
---|
763 | { |
---|
764 | printf( "ERROR: SoundManager::isOggExtensionPresent : Ogg Vorbis extension not availablee!\n" ); |
---|
765 | bOggExtensionPresent = false; |
---|
766 | return false; |
---|
767 | } |
---|
768 | return true; |
---|
769 | } |
---|
770 | |
---|
771 | // Function to load a wave file and assigned it to a buffer |
---|
772 | // This code was taken from the plugin found on this forum : |
---|
773 | // http://www.ogre3d.org/phpBB2/viewtopic.php?t=7234 |
---|
774 | // |
---|
775 | // TODO I didn't integrate it fow now .. because I don't need it now :-) |
---|
776 | // |
---|
777 | /****************************************************************************/ |
---|
778 | bool SoundManager::loadOGG( std::string filename, ALuint pDestAudioBuffer ) |
---|
779 | { |
---|
780 | if ( !bOggExtensionPresent ) |
---|
781 | { |
---|
782 | printf( "SoundManager::loadOgg() : OGG extension not present... useless to load an ogg audio!\n"); |
---|
783 | return false; |
---|
784 | } |
---|
785 | |
---|
786 | printf( " TODO SoundManager::loadOgg() : not implemented.\n" ); |
---|
787 | |
---|
788 | /* |
---|
789 | ALbyte *data; |
---|
790 | ALsizei freq = 0; |
---|
791 | void *ovdata; |
---|
792 | unsigned int g_ovSize; |
---|
793 | ALuint tempBuffers[4]; |
---|
794 | |
---|
795 | alGenSources(1, &mSourceID); |
---|
796 | if ( checkALError() ) return false; |
---|
797 | |
---|
798 | alGenBuffers( 4, tempBuffers ); // 4 ?? |
---|
799 | |
---|
800 | alSourceStop( mSourceID ); |
---|
801 | if ( checkALError() ) return false; |
---|
802 | |
---|
803 | alSourcei( mSourceID, AL_BUFFER, 0 ); |
---|
804 | |
---|
805 | FILE *fp = fopen ( filename.c_str(), "rb" ); |
---|
806 | if ( fp == NULL ) |
---|
807 | { |
---|
808 | printf( "Failed to open %d\n", filename ); |
---|
809 | retrun false; |
---|
810 | } |
---|
811 | |
---|
812 | alGetError(); |
---|
813 | |
---|
814 | struct stat sbuf; |
---|
815 | |
---|
816 | if (stat( filename.c_str(), %sbuf) != -1) |
---|
817 | { |
---|
818 | g_ovSize = sbuf.st_size; |
---|
819 | ovdata = malloc( g_ovSize ); |
---|
820 | } |
---|
821 | |
---|
822 | int actual; |
---|
823 | data = (ALbyte*) malloc((g_ovSize / 4) + 1)); |
---|
824 | |
---|
825 | if (data != 0) |
---|
826 | { |
---|
827 | for (int i=0; i<4; i++) |
---|
828 | { |
---|
829 | actual = fread(data, 1, ((g_ovSize / 4) + 1), fp); |
---|
830 | // #define AL_FORMAT_VORBIS_EXT 0x10003 |
---|
831 | alBufferData( tempBuffers[i], AL_FORMAT_VORBIS_EXT, data, actual, 0); |
---|
832 | } |
---|
833 | |
---|
834 | alSourceQueueBuffers( mSourceID, 4, tempBuffers ); |
---|
835 | |
---|
836 | alSourcef( mSourceID, AL_GAIN, 1.0f ); |
---|
837 | |
---|
838 | if ( checkALError() ) return false; |
---|
839 | |
---|
840 | free( (void*) data); |
---|
841 | } |
---|
842 | else |
---|
843 | { |
---|
844 | printf( "ERROR: SoundManager:loadOgg() failed memory allocation.\n"); |
---|
845 | } |
---|
846 | |
---|
847 | fclose( fp ); |
---|
848 | |
---|
849 | isVorbis = true; // !!! TODO this should be used in |
---|
850 | // an update() fct if the Vorbis is looped ! |
---|
851 | |
---|
852 | */ |
---|
853 | |
---|
854 | return true; |
---|
855 | } |
---|
856 | |
---|
857 | /****************************************************************************/ |
---|
858 | bool SoundManager::loadDefaultSounds( std::string filename ) |
---|
859 | { |
---|
860 | FILE *myfile; |
---|
861 | unsigned linecount=0; |
---|
862 | char key[255], buff[512]; |
---|
863 | |
---|
864 | if ( (myfile = fopen( filename.c_str() ,"r") )==NULL ) |
---|
865 | { |
---|
866 | sprintf(buff, "---> Can't Open File: %s\n", filename.c_str() ); |
---|
867 | printf( "SoundManager::loadDefaultSounds : %s\n", buff ); |
---|
868 | return false; |
---|
869 | } |
---|
870 | |
---|
871 | fseek(myfile,0L,SEEK_SET); // Make sure we are at the begining of the file |
---|
872 | |
---|
873 | while (!feof(myfile)) |
---|
874 | { |
---|
875 | fgets(buff,sizeof(buff),myfile); // Read a line from the file. |
---|
876 | linecount++; |
---|
877 | |
---|
878 | if (strncmp(buff,"#",1) && // Is this a comment line? |
---|
879 | strncmp(buff,"",1) && |
---|
880 | strncmp(buff,"/",1)) |
---|
881 | { |
---|
882 | // We have some data, attempt to load it |
---|
883 | strcpy(key,buff); |
---|
884 | trimTrailingSpace(key); |
---|
885 | |
---|
886 | // First, make sure it isn't already loaded |
---|
887 | if ( locateAudioBuffer( key ) < 0 ) |
---|
888 | { |
---|
889 | // Nope, its not already loaded |
---|
890 | if ( loadAudioInToSystem( key ) < 0 ) |
---|
891 | { |
---|
892 | sprintf(buff,"Can't load audio file: %s\n",key); |
---|
893 | printf( "SoundManager::loadDefaultSounds() : %s\n", buff ); |
---|
894 | } |
---|
895 | } |
---|
896 | } |
---|
897 | } |
---|
898 | |
---|
899 | // Were done |
---|
900 | fclose(myfile); |
---|
901 | return true; |
---|
902 | } |
---|
903 | |
---|
904 | // Function to trim the trailing crap from a string. |
---|
905 | /****************************************************************************/ |
---|
906 | void SoundManager::trimTrailingSpace( char *s ) |
---|
907 | { |
---|
908 | char *p; |
---|
909 | p = s; |
---|
910 | if (p == NULL) return; |
---|
911 | for (unsigned i=0;i < (strlen(s)+1);i++) |
---|
912 | { |
---|
913 | if (__iscsym(*p) == 0 && *p != '.' && *p != '-') |
---|
914 | { |
---|
915 | *p='\0'; |
---|
916 | break; |
---|
917 | } |
---|
918 | p++; |
---|
919 | } |
---|
920 | } |
---|