Mercurial > almixer_isolated
comparison SDL_ALmixer.c @ 2:279d0427ef26
Overhaul prep for first public release.
author | Eric Wing <ewing . public |-at-| gmail . com> |
---|---|
date | Wed, 27 Oct 2010 16:52:44 -0700 |
parents | a8a8fe374984 |
children |
comparison
equal
deleted
inserted
replaced
1:a8a8fe374984 | 2:279d0427ef26 |
---|---|
5 * Eric Wing | 5 * Eric Wing |
6 */ | 6 */ |
7 | 7 |
8 #include "SDL_ALmixer.h" | 8 #include "SDL_ALmixer.h" |
9 | 9 |
10 #include "SDL.h" /* For SDL_GetTicks(), SDL_Delay */ | 10 #ifdef ALMIXER_COMPILE_WITHOUT_SDL |
11 #include "SDL_sound.h" | 11 #include "ALmixer_rwops.h" |
12 #include "SoundDecoder.h" | |
13 #else | |
14 #include "SDL_sound.h" | |
15 #endif | |
16 | |
12 #include "al.h" /* OpenAL */ | 17 #include "al.h" /* OpenAL */ |
13 #include "alc.h" /* For creating OpenAL contexts */ | 18 #include "alc.h" /* For creating OpenAL contexts */ |
14 | 19 |
15 #ifdef __APPLE__ | 20 #ifdef __APPLE__ |
16 /* For performance things like ALC_CONVERT_DATA_UPON_LOADING */ | 21 /* For performance things like ALC_CONVERT_DATA_UPON_LOADING */ |
17 /* Note: ALC_CONVERT_DATA_UPON_LOADING used to be in the alc.h header. | 22 /* Note: ALC_CONVERT_DATA_UPON_LOADING used to be in the alc.h header. |
18 * But in the Tiger OpenAL 1.1 release (10.4.7 and Xcode 2.4), the | 23 * But in the Tiger OpenAL 1.1 release (10.4.7 and Xcode 2.4), the |
19 * define was moved to a new header file and renamed to | 24 * define was moved to a new header file and renamed to |
20 * ALC_MAC_OSX_CONVERT_DATA_UPON_LOADING. | 25 * ALC_MAC_OSX_CONVERT_DATA_UPON_LOADING. |
21 */ | 26 */ |
22 #include <OpenAL/MacOSX_OALExtensions.h> | 27 /* |
28 #include <TargetConditionals.h> | |
29 #if (TARGET_OS_IPHONE == 1) || (TARGET_IPHONE_SIMULATOR == 1) | |
30 | |
31 #else | |
32 #include <OpenAL/MacOSX_OALExtensions.h> | |
33 #endif | |
34 */ | |
35 | |
23 #endif | 36 #endif |
24 | 37 |
25 /* For malloc, bsearch, qsort */ | 38 /* For malloc, bsearch, qsort */ |
26 #include <stdlib.h> | 39 #include <stdlib.h> |
27 | 40 |
42 * to work around the Nvidia problem of the | 55 * to work around the Nvidia problem of the |
43 * lack of a buffer query. | 56 * lack of a buffer query. |
44 */ | 57 */ |
45 #include "CircularQueue.h" | 58 #include "CircularQueue.h" |
46 | 59 |
60 #ifdef ENABLE_ALMIXER_THREADS | |
47 /* Needed for the Mutex locks (and threads if enabled) */ | 61 /* Needed for the Mutex locks (and threads if enabled) */ |
48 #include "SDL_thread.h" | 62 #ifdef ALMIXER_COMPILE_WITHOUT_SDL |
63 #include "SimpleMutex.h" | |
64 #include "SimpleThread.h" | |
65 typedef struct SimpleMutex SDL_mutex; | |
66 typedef struct SimpleThread SDL_Thread; | |
67 #define SDL_CreateMutex SimpleMutex_CreateMutex | |
68 #define SDL_DestroyMutex SimpleMutex_DestroyMutex | |
69 #define SDL_LockMutex SimpleMutex_LockMutex | |
70 #define SDL_UnlockMutex SimpleMutex_UnlockMutex | |
71 #define SDL_CreateThread SimpleThread_CreateThread | |
72 #define SDL_WaitThread SimpleThread_WaitThread | |
73 | |
74 #else | |
75 #include "SDL_thread.h" | |
76 #endif | |
77 #endif | |
49 | 78 |
50 /* Because of the API differences between the Loki | 79 /* Because of the API differences between the Loki |
51 * and Creative distributions, we need to know which | 80 * and Creative distributions, we need to know which |
52 * version to use. The LOKI distribution currently | 81 * version to use. The LOKI distribution currently |
53 * has AL_BYTE_LOKI defined in altypes.h which | 82 * has AL_BYTE_LOKI defined in altypes.h which |
57 * identify the Creative dist. | 86 * identify the Creative dist. |
58 * I'm not sure if or how the Nvidia distribution differs | 87 * I'm not sure if or how the Nvidia distribution differs |
59 * from the Creative distribution. So for | 88 * from the Creative distribution. So for |
60 * now, the Nvidia distribution gets lumped with the | 89 * now, the Nvidia distribution gets lumped with the |
61 * Creative dist and I hope nothing will break. | 90 * Creative dist and I hope nothing will break. |
62 * My aluGetErrorString may be the most vulnerable. | 91 * My alGetString may be the most vulnerable. |
63 */ | 92 */ |
64 #ifdef AL_BYTE_LOKI | 93 #ifdef AL_BYTE_LOKI |
65 #define USING_LOKI_AL_DIST | 94 #define USING_LOKI_AL_DIST |
66 /* This is a short term fix to get around the | 95 /* This is a short term fix to get around the |
67 * queuing problem with non-power of two buffer sizes. | 96 * queuing problem with non-power of two buffer sizes. |
169 */ | 198 */ |
170 #define NUMBER_OF_START_UP_BUFFERS 2 | 199 #define NUMBER_OF_START_UP_BUFFERS 2 |
171 #endif | 200 #endif |
172 /************ END REMOVE ME (Don't need anymore) ********/ | 201 /************ END REMOVE ME (Don't need anymore) ********/ |
173 | 202 |
174 static SDL_bool ALmixer_Initialized = 0; | 203 #ifdef ALMIXER_COMPILE_WITHOUT_SDL |
204 #include "tErrorLib.h" | |
205 static TErrorPool* s_ALmixerErrorPool = NULL; | |
206 #endif | |
207 | |
208 static ALboolean ALmixer_Initialized = 0; | |
175 /* This should be set correctly by Init */ | 209 /* This should be set correctly by Init */ |
176 static Uint32 ALmixer_Frequency_global = ALMIXER_DEFAULT_FREQUENCY; | 210 static ALuint ALmixer_Frequency_global = ALMIXER_DEFAULT_FREQUENCY; |
177 | 211 |
178 /* Will be initialized in Init */ | 212 /* Will be initialized in Init */ |
179 static Sint32 Number_of_Channels_global = 0; | 213 static ALint Number_of_Channels_global = 0; |
180 static Sint32 Number_of_Reserve_Channels_global = 0; | 214 static ALint Number_of_Reserve_Channels_global = 0; |
181 static Uint32 Is_Playing_global = 0; | 215 static ALuint Is_Playing_global = 0; |
182 | 216 |
217 #ifdef ENABLE_ALMIXER_THREADS | |
183 /* This is for a simple lock system. It is not meant to be good, | 218 /* This is for a simple lock system. It is not meant to be good, |
184 * but just sufficient to minimize/avoid threading issues | 219 * but just sufficient to minimize/avoid threading issues |
185 */ | 220 */ |
186 static SDL_mutex* simple_lock; | 221 static SDL_mutex* s_simpleLock; |
187 | |
188 #ifdef ENABLE_ALMIXER_THREADS | |
189 static SDL_Thread* Stream_Thread_global = NULL; | 222 static SDL_Thread* Stream_Thread_global = NULL; |
190 #endif | 223 #endif |
224 | |
225 | |
226 #ifdef __APPLE__ | |
227 static ALvoid Internal_alcMacOSXMixerOutputRate(const ALdouble sample_rate) | |
228 { | |
229 static void (*alcMacOSXMixerOutputRateProcPtr)(const ALdouble) = NULL; | |
230 | |
231 if(NULL == alcMacOSXMixerOutputRateProcPtr) | |
232 { | |
233 alcMacOSXMixerOutputRateProcPtr = alGetProcAddress((const ALCchar*) "alcMacOSXMixerOutputRate"); | |
234 } | |
235 | |
236 if(NULL != alcMacOSXMixerOutputRateProcPtr) | |
237 { | |
238 alcMacOSXMixerOutputRateProcPtr(sample_rate); | |
239 } | |
240 | |
241 return; | |
242 } | |
243 | |
244 ALdouble Internal_alcMacOSXGetMixerOutputRate() | |
245 { | |
246 static ALdouble (*alcMacOSXGetMixerOutputRateProcPtr)(void) = NULL; | |
247 | |
248 if(NULL == alcMacOSXGetMixerOutputRateProcPtr) | |
249 { | |
250 alcMacOSXGetMixerOutputRateProcPtr = alGetProcAddress((const ALCchar*) "alcMacOSXGetMixerOutputRate"); | |
251 } | |
252 | |
253 if(NULL != alcMacOSXGetMixerOutputRateProcPtr) | |
254 { | |
255 return alcMacOSXGetMixerOutputRateProcPtr(); | |
256 } | |
257 | |
258 return 0.0; | |
259 } | |
260 #endif | |
261 | |
262 #ifdef ALMIXER_COMPILE_WITHOUT_SDL | |
263 | |
264 #if defined(__APPLE__) | |
265 #include <QuartzCore/QuartzCore.h> | |
266 #include <unistd.h> | |
267 static CFTimeInterval s_ticksBaseTime = 0.0; | |
268 | |
269 #elif defined(_WIN32) | |
270 #define WIN32_LEAN_AND_MEAN | |
271 #include <windows.h> | |
272 #include <winbase.h> | |
273 LARGE_INTEGER s_hiResTicksPerSecond; | |
274 double s_hiResSecondsPerTick; | |
275 LARGE_INTEGER s_ticksBaseTime; | |
276 #else | |
277 #include <unistd.h> | |
278 #include <time.h> | |
279 static struct timespec s_ticksBaseTime; | |
280 #endif | |
281 static void ALmixer_InitTime() | |
282 { | |
283 #if defined(__APPLE__) | |
284 s_ticksBaseTime = CACurrentMediaTime(); | |
285 | |
286 #elif defined(_WIN32) | |
287 LARGE_INTEGER hi_res_ticks_per_second; | |
288 if(TRUE == QueryPerformanceFrequency(&hi_res_ticks_per_second)) | |
289 { | |
290 QueryPerformanceCounter(&s_ticksBaseTime); | |
291 s_hiResSecondsPerTick = 1.0 / hi_res_ticks_per_second; | |
292 } | |
293 else | |
294 { | |
295 ALMixer_SetError("Windows error: High resolution clock failed."); | |
296 fprintf(stderr, "Windows error: High resolution clock failed. Audio will not work correctly.\n"); | |
297 } | |
298 #else | |
299 /* clock_gettime is POSIX.1-2001 */ | |
300 clock_gettime(CLOCK_MONOTONIC, &s_ticksBaseTime); | |
301 #endif | |
302 | |
303 } | |
304 static ALuint ALmixer_GetTicks() | |
305 { | |
306 #if defined(__APPLE__) | |
307 return (ALuint)((CACurrentMediaTime()-s_ticksBaseTime)*1000.0); | |
308 #elif defined(_WIN32) | |
309 LARGE_INTEGER current_time; | |
310 QueryPerformanceCounter(¤t_time); | |
311 return (ALuint)((current_time.QuadPart - s_ticksBaseTime.QuadPart) * 1000 * s_hiResSecondsPerTick); | |
312 | |
313 #else /* assuming POSIX */ | |
314 /* clock_gettime is POSIX.1-2001 */ | |
315 struct timespec current_time; | |
316 clock_gettime(CLOCK_MONOTONIC, ¤t_time); | |
317 return (ALuint)((current_time.tv_sec - s_ticksBaseTime.tv_sec)*1000.0 + (current_time.tv_nec - s_ticksBaseTime.tv_nsec) / 1000000); | |
318 #endif | |
319 } | |
320 static void ALmixer_Delay(ALuint milliseconds_delay) | |
321 { | |
322 #if defined(_WIN32) | |
323 Sleep(milliseconds_delay); | |
324 #else | |
325 usleep(milliseconds_delay); | |
326 #endif | |
327 } | |
328 #else | |
329 #include "SDL.h" /* For SDL_GetTicks(), SDL_Delay */ | |
330 #define ALmixer_GetTicks SDL_GetTicks | |
331 #define ALmixer_Delay SDL_Delay | |
332 #endif | |
333 | |
191 | 334 |
192 | 335 |
193 /* If ENABLE_PARANOID_SIGNEDNESS_CHECK is used, | 336 /* If ENABLE_PARANOID_SIGNEDNESS_CHECK is used, |
194 * these values will be reset on Init() | 337 * these values will be reset on Init() |
195 * Consider these values Read-Only. | 338 * Consider these values Read-Only. |
197 | 340 |
198 #define ALMIXER_SIGNED_VALUE 127 | 341 #define ALMIXER_SIGNED_VALUE 127 |
199 #define ALMIXER_UNSIGNED_VALUE 255 | 342 #define ALMIXER_UNSIGNED_VALUE 255 |
200 | 343 |
201 #ifdef ENABLE_PARANOID_SIGNEDNESS_CHECK | 344 #ifdef ENABLE_PARANOID_SIGNEDNESS_CHECK |
202 static Uint16 SIGN_TYPE_16_BIT_FORMAT = AUDIO_S16SYS; | 345 static ALushort SIGN_TYPE_16_BIT_FORMAT = AUDIO_S16SYS; |
203 static Uint16 SIGN_TYPE_8_BIT_FORMAT = AUDIO_S8; | 346 static ALushort SIGN_TYPE_8_BIT_FORMAT = AUDIO_S8; |
204 #else | 347 #else |
205 static const Uint16 SIGN_TYPE_16_BIT_FORMAT = AUDIO_S16SYS; | 348 static const ALushort SIGN_TYPE_16_BIT_FORMAT = AUDIO_S16SYS; |
206 static const Uint16 SIGN_TYPE_8_BIT_FORMAT = AUDIO_S8; | 349 static const ALushort SIGN_TYPE_8_BIT_FORMAT = AUDIO_S8; |
207 #endif | 350 #endif |
208 | 351 |
209 | 352 |
210 /* This can be private instead of being in the header now that I moved | 353 /* This can be private instead of being in the header now that I moved |
211 * ALmixer_Data inside here. | 354 * ALmixer_Data inside here. |
213 typedef struct ALmixer_Buffer_Map ALmixer_Buffer_Map; | 356 typedef struct ALmixer_Buffer_Map ALmixer_Buffer_Map; |
214 | 357 |
215 | 358 |
216 struct ALmixer_Data | 359 struct ALmixer_Data |
217 { | 360 { |
218 SDL_bool decoded_all; /* dictates different behaviors */ | 361 ALboolean decoded_all; /* dictates different behaviors */ |
219 Sint32 total_time; /* total playing time of sample (msec) */ | 362 ALint total_time; /* total playing time of sample (msec) */ |
220 | 363 |
221 Uint32 in_use; /* needed to prevent sharing for streams */ | 364 ALuint in_use; /* needed to prevent sharing for streams */ |
222 SDL_bool eof; /* flag for eof, only used for streams */ | 365 ALboolean eof; /* flag for eof, only used for streams */ |
223 | 366 |
224 Uint32 total_bytes; /* For predecoded */ | 367 ALuint total_bytes; /* For predecoded */ |
225 Uint32 loaded_bytes; /* For predecoded (for seek) */ | 368 ALuint loaded_bytes; /* For predecoded (for seek) */ |
226 | 369 |
227 Sound_Sample* sample; /* SDL_Sound provides the data */ | 370 Sound_Sample* sample; /* SDL_Sound provides the data */ |
228 ALuint* buffer; /* array of OpenAL buffers (at least 1 for predecoded) */ | 371 ALuint* buffer; /* array of OpenAL buffers (at least 1 for predecoded) */ |
229 | 372 |
230 /* Needed for streamed buffers */ | 373 /* Needed for streamed buffers */ |
231 Uint32 max_queue_buffers; /* Max number of queue buffers */ | 374 ALuint max_queue_buffers; /* Max number of queue buffers */ |
232 Uint32 num_startup_buffers; /* Number of ramp-up buffers */ | 375 ALuint num_startup_buffers; /* Number of ramp-up buffers */ |
233 Uint32 num_buffers_in_use; /* number of buffers in use */ | 376 ALuint num_buffers_in_use; /* number of buffers in use */ |
234 | 377 |
235 /* This stuff is for streamed buffers that require data access */ | 378 /* This stuff is for streamed buffers that require data access */ |
236 ALmixer_Buffer_Map* buffer_map_list; /* translate ALbuffer to index | 379 ALmixer_Buffer_Map* buffer_map_list; /* translate ALbuffer to index |
237 and holds pointer to copy of data for | 380 and holds pointer to copy of data for |
238 data access */ | 381 data access */ |
251 | 394 |
252 }; | 395 }; |
253 | 396 |
254 static struct ALmixer_Channel | 397 static struct ALmixer_Channel |
255 { | 398 { |
256 SDL_bool channel_in_use; | 399 ALboolean channel_in_use; |
257 SDL_bool callback_update; /* For streaming determination */ | 400 ALboolean callback_update; /* For streaming determination */ |
258 SDL_bool needs_stream; /* For streaming determination */ | 401 ALboolean needs_stream; /* For streaming determination */ |
259 SDL_bool halted; | 402 ALboolean halted; |
260 SDL_bool paused; | 403 ALboolean paused; |
261 ALuint alsource; | 404 ALuint alsource; |
262 ALmixer_Data* almixer_data; | 405 ALmixer_Data* almixer_data; |
263 Sint32 loops; | 406 ALint loops; |
264 Sint32 expire_ticks; | 407 ALint expire_ticks; |
265 Uint32 start_time; | 408 ALuint start_time; |
266 | 409 |
267 SDL_bool fade_enabled; | 410 ALboolean fade_enabled; |
268 Uint32 fade_expire_ticks; | 411 ALuint fade_expire_ticks; |
269 Uint32 fade_start_time; | 412 ALuint fade_start_time; |
270 ALfloat fade_inv_time; | 413 ALfloat fade_inv_time; |
271 ALfloat fade_start_volume; | 414 ALfloat fade_start_volume; |
272 ALfloat fade_end_volume; | 415 ALfloat fade_end_volume; |
273 ALfloat max_volume; | 416 ALfloat max_volume; |
274 ALfloat min_volume; | 417 ALfloat min_volume; |
275 | 418 |
276 /* Do we need other flags? | 419 /* Do we need other flags? |
277 Uint8 *samples; | 420 ALbyte *samples; |
278 int volume; | 421 int volume; |
279 int looping; | 422 int looping; |
280 int tag; | 423 int tag; |
281 Uint32 expire; | 424 ALuint expire; |
282 Uint32 start_time; | 425 ALuint start_time; |
283 Mix_Fading fading; | 426 Mix_Fading fading; |
284 int fade_volume; | 427 int fade_volume; |
285 Uint32 fade_length; | 428 ALuint fade_length; |
286 Uint32 ticks_fade; | 429 ALuint ticks_fade; |
287 effect_info *effects; | 430 effect_info *effects; |
288 */ | 431 */ |
289 } *ALmixer_Channel_List = NULL; | 432 } *ALmixer_Channel_List = NULL; |
290 | 433 |
291 struct ALmixer_Buffer_Map | 434 struct ALmixer_Buffer_Map |
292 { | 435 { |
293 ALuint albuffer; | 436 ALuint albuffer; |
294 Sint32 index; /* might not need */ | 437 ALint index; /* might not need */ |
295 Uint8* data; | 438 ALbyte* data; |
296 Uint32 num_bytes; | 439 ALuint num_bytes; |
297 }; | 440 }; |
298 | 441 |
299 /* This will be used to find a channel if the user supplies a source */ | 442 /* This will be used to find a channel if the user supplies a source */ |
300 typedef struct Source_Map | 443 typedef struct Source_Map |
301 { | 444 { |
302 ALuint source; | 445 ALuint source; |
303 Sint32 channel; | 446 ALint channel; |
304 } Source_Map; | 447 } Source_Map; |
305 /* Keep an array of all sources with their associated channel */ | 448 /* Keep an array of all sources with their associated channel */ |
306 static Source_Map* Source_Map_List; | 449 static Source_Map* Source_Map_List; |
307 | 450 |
308 static int Compare_Source_Map(const void* a, const void* b) | 451 static int Compare_Source_Map(const void* a, const void* b) |
323 } | 466 } |
324 | 467 |
325 /* This is for the user defined callback via | 468 /* This is for the user defined callback via |
326 * ALmixer_ChannelFinished() | 469 * ALmixer_ChannelFinished() |
327 */ | 470 */ |
328 static void (*Channel_Done_Callback)(Sint32 channel, void* userdata) = NULL; | 471 static void (*Channel_Done_Callback)(ALint which_channel, ALuint al_source, ALmixer_Data* almixer_data, ALboolean finished_naturally, void* user_data) = NULL; |
329 static void* Channel_Done_Callback_Userdata = NULL; | 472 static void* Channel_Done_Callback_Userdata = NULL; |
330 static void (*Channel_Data_Callback)(Sint32 which_channel, Uint8* data, Uint32 num_bytes, Uint32 frequency, Uint8 channels, Uint8 bit_depth, SDL_bool is_unsigned, SDL_bool decode_mode_is_predecoded, Uint32 length_in_msec, void* user_data) = NULL; | 473 static void (*Channel_Data_Callback)(ALint which_channel, ALuint al_source, ALbyte* data, ALuint num_bytes, ALuint frequency, ALubyte channels, ALubyte bit_depth, ALboolean is_unsigned, ALboolean decode_mode_is_predecoded, ALuint length_in_msec, void* user_data) = NULL; |
331 static void* Channel_Data_Callback_Userdata = NULL; | 474 static void* Channel_Data_Callback_Userdata = NULL; |
332 | |
333 /* I thought OpenAL seemed to lack an error number to string converter... | |
334 * but I was wrong. Apparently they call it alGetString() which | |
335 * breaks from the OpenGL gluGetErrorString() convention. | |
336 * (And since the documentation for OpenAL is so bad, I didn't see | |
337 * it until I had already written my own aluGetErrorString().) | |
338 * So for convenience, I will just call alGetString from here. | |
339 */ | |
340 static const ALubyte* aluGetErrorString(ALenum error) | |
341 { | |
342 return alGetString(error); | |
343 | |
344 #if 0 | |
345 switch(error) | |
346 { | |
347 case AL_NO_ERROR: | |
348 return NULL; | |
349 break; | |
350 case AL_INVALID_NAME: | |
351 return "Invalid name (ID)"; | |
352 break; | |
353 case AL_INVALID_VALUE: | |
354 return "Invalid value"; | |
355 break; | |
356 case AL_OUT_OF_MEMORY: | |
357 return "Out of memory"; | |
358 break; | |
359 /* Damn, even the error values are skewed between distributions */ | |
360 /* For the Creative Labs distributions (don't know about Nvidia) */ | |
361 /* For the Loki based distributions */ | |
362 #ifdef USING_LOKI_AL_DIST | |
363 case AL_ILLEGAL_ENUM: | |
364 return "Invalid enum value"; | |
365 break; | |
366 case AL_ILLEGAL_COMMAND: | |
367 return "Requested operation is not valid"; | |
368 break; | |
369 /* | |
370 #elif USING_CREATIVE_AL_DIST | |
371 */ | |
372 #else | |
373 case AL_INVALID_ENUM: | |
374 return "Invalid enum value"; | |
375 break; | |
376 case AL_INVALID_OPERATION: | |
377 return "Requested operation is not valid"; | |
378 break; | |
379 /* | |
380 #elif USING_NVIDIA_AL_DIST | |
381 */ | |
382 /* | |
383 case alGetEnumValue((ALubyte*)"??????"); | |
384 */ | |
385 #endif | |
386 default: | |
387 return "Unknown error value passed to aluGetErrorString()"; | |
388 break; | |
389 } | |
390 | |
391 /* Make compiler happy */ | |
392 return NULL; | |
393 #endif | |
394 } | |
395 | 475 |
396 | 476 |
397 static void PrintQueueStatus(ALuint source) | 477 static void PrintQueueStatus(ALuint source) |
398 { | 478 { |
399 ALint buffers_queued = 0; | 479 ALint buffers_queued = 0; |
408 ); | 488 ); |
409 | 489 |
410 if((error = alGetError()) != AL_NO_ERROR) | 490 if((error = alGetError()) != AL_NO_ERROR) |
411 { | 491 { |
412 fprintf(stderr, "Error in PrintQueueStatus, Can't get buffers_queued: %s\n", | 492 fprintf(stderr, "Error in PrintQueueStatus, Can't get buffers_queued: %s\n", |
413 aluGetErrorString(error)); | 493 alGetString(error)); |
414 } | 494 } |
415 /* Get the number of buffers processed | 495 /* Get the number of buffers processed |
416 * so we know if we need to refill | 496 * so we know if we need to refill |
417 */ | 497 */ |
418 alGetSourcei( | 498 alGetSourcei( |
421 &buffers_processed | 501 &buffers_processed |
422 ); | 502 ); |
423 if((error = alGetError()) != AL_NO_ERROR) | 503 if((error = alGetError()) != AL_NO_ERROR) |
424 { | 504 { |
425 fprintf(stderr, "Error in PrintQueueStatus, Can't get buffers_processed: %s\n", | 505 fprintf(stderr, "Error in PrintQueueStatus, Can't get buffers_processed: %s\n", |
426 aluGetErrorString(error)); | 506 alGetString(error)); |
427 } | 507 } |
428 | 508 |
429 fprintf(stderr, "For source: %d, buffers_queued=%d, buffers_processed=%d\n", | 509 fprintf(stderr, "For source: %d, buffers_queued=%d, buffers_processed=%d\n", |
430 source, | 510 source, |
431 buffers_queued, | 511 buffers_queued, |
433 | 513 |
434 } | 514 } |
435 | 515 |
436 | 516 |
437 | 517 |
438 static void Init_Channel(Sint32 channel) | 518 static void Init_Channel(ALint channel) |
439 { | 519 { |
440 | 520 |
441 fprintf(stderr, "Init channel %d\n", channel); | 521 fprintf(stderr, "Init channel %d\n", channel); |
442 ALmixer_Channel_List[channel].channel_in_use = 0; | 522 ALmixer_Channel_List[channel].channel_in_use = 0; |
443 ALmixer_Channel_List[channel].callback_update = 0; | 523 ALmixer_Channel_List[channel].callback_update = 0; |
460 | 540 |
461 ALmixer_Channel_List[channel].almixer_data = NULL; | 541 ALmixer_Channel_List[channel].almixer_data = NULL; |
462 } | 542 } |
463 /* Quick helper function to clean up a channel | 543 /* Quick helper function to clean up a channel |
464 * after it's done playing */ | 544 * after it's done playing */ |
465 static void Clean_Channel(Sint32 channel) | 545 static void Clean_Channel(ALint channel) |
466 { | 546 { |
467 ALenum error; | 547 ALenum error; |
468 ALmixer_Channel_List[channel].channel_in_use = 0; | 548 ALmixer_Channel_List[channel].channel_in_use = 0; |
469 ALmixer_Channel_List[channel].callback_update = 0; | 549 ALmixer_Channel_List[channel].callback_update = 0; |
470 ALmixer_Channel_List[channel].needs_stream = 0; | 550 ALmixer_Channel_List[channel].needs_stream = 0; |
487 ALmixer_Channel_List[channel].max_volume); | 567 ALmixer_Channel_List[channel].max_volume); |
488 | 568 |
489 if((error = alGetError()) != AL_NO_ERROR) | 569 if((error = alGetError()) != AL_NO_ERROR) |
490 { | 570 { |
491 fprintf(stderr, "10Testing errpr before unqueue because getting stuff, for OS X this is expected: %s\n", | 571 fprintf(stderr, "10Testing errpr before unqueue because getting stuff, for OS X this is expected: %s\n", |
492 aluGetErrorString(error)); | 572 alGetString(error)); |
493 } | 573 } |
494 | 574 |
495 alSourcef(ALmixer_Channel_List[channel].alsource, AL_MIN_GAIN, | 575 alSourcef(ALmixer_Channel_List[channel].alsource, AL_MIN_GAIN, |
496 ALmixer_Channel_List[channel].min_volume); | 576 ALmixer_Channel_List[channel].min_volume); |
497 if((error = alGetError()) != AL_NO_ERROR) | 577 if((error = alGetError()) != AL_NO_ERROR) |
498 { | 578 { |
499 fprintf(stderr, "11Testing errpr before unqueue because getting stuff, for OS X this is expected: %s\n", | 579 fprintf(stderr, "11Testing errpr before unqueue because getting stuff, for OS X this is expected: %s\n", |
500 aluGetErrorString(error)); | 580 alGetString(error)); |
501 } | 581 } |
502 | 582 |
503 if(ALmixer_Channel_List[channel].almixer_data != NULL) | 583 if(ALmixer_Channel_List[channel].almixer_data != NULL) |
504 { | 584 { |
505 if(ALmixer_Channel_List[channel].almixer_data->in_use > 0) | 585 if(ALmixer_Channel_List[channel].almixer_data->in_use > 0) |
553 | 633 |
554 | 634 |
555 /* What shoud this return? | 635 /* What shoud this return? |
556 * 127 for signed, 255 for unsigned | 636 * 127 for signed, 255 for unsigned |
557 */ | 637 */ |
558 static Uint8 GetSignednessValue(Uint16 format) | 638 static ALubyte GetSignednessValue(ALushort format) |
559 { | 639 { |
560 switch(format) | 640 switch(format) |
561 { | 641 { |
562 case AUDIO_U8: | 642 case AUDIO_U8: |
563 case AUDIO_U16LSB: | 643 case AUDIO_U16LSB: |
574 } | 654 } |
575 return 0; | 655 return 0; |
576 } | 656 } |
577 | 657 |
578 | 658 |
579 static Uint8 GetBitDepth(Uint16 format) | 659 static ALubyte GetBitDepth(ALushort format) |
580 { | 660 { |
581 Uint8 bit_depth = 16; | 661 ALubyte bit_depth = 16; |
582 | 662 |
583 switch(format) | 663 switch(format) |
584 { | 664 { |
585 case AUDIO_U8: | 665 case AUDIO_U8: |
586 case AUDIO_S8: | 666 case AUDIO_S8: |
611 | 691 |
612 /* Need to translate between SDL/SDL_Sound audiospec | 692 /* Need to translate between SDL/SDL_Sound audiospec |
613 * and OpenAL conventions */ | 693 * and OpenAL conventions */ |
614 static ALenum TranslateFormat(Sound_AudioInfo* info) | 694 static ALenum TranslateFormat(Sound_AudioInfo* info) |
615 { | 695 { |
616 Uint8 bit_depth; | 696 ALubyte bit_depth; |
617 | 697 |
618 bit_depth = GetBitDepth(info->format); | 698 bit_depth = GetBitDepth(info->format); |
619 if(0 == bit_depth) | 699 if(0 == bit_depth) |
620 { | 700 { |
621 fprintf(stderr, "Warning: Unknown bit depth. Setting to 16\n"); | 701 fprintf(stderr, "Warning: Unknown bit depth. Setting to 16\n"); |
651 | 731 |
652 /* This will compute the total playing time | 732 /* This will compute the total playing time |
653 * based upon the number of bytes and audio info. | 733 * based upon the number of bytes and audio info. |
654 * (In prinicple, it should compute the time for any given length) | 734 * (In prinicple, it should compute the time for any given length) |
655 */ | 735 */ |
656 static Uint32 Compute_Total_Time_Decomposed(Uint32 bytes_per_sample, Uint32 frequency, Uint8 channels, Uint32 total_bytes) | 736 static ALuint Compute_Total_Time_Decomposed(ALuint bytes_per_sample, ALuint frequency, ALubyte channels, size_t total_bytes) |
657 { | 737 { |
658 double total_sec; | 738 double total_sec; |
659 Uint32 total_msec; | 739 ALuint total_msec; |
660 Uint32 bytes_per_sec; | 740 ALuint bytes_per_sec; |
661 | 741 |
662 if(0 == total_bytes) | 742 if(0 == total_bytes) |
663 { | 743 { |
664 return 0; | 744 return 0; |
665 } | 745 } |
674 total_sec = total_bytes / (double)bytes_per_sec; | 754 total_sec = total_bytes / (double)bytes_per_sec; |
675 | 755 |
676 /* Now convert seconds to milliseconds | 756 /* Now convert seconds to milliseconds |
677 * Add .5 to the float to do rounding before the final cast | 757 * Add .5 to the float to do rounding before the final cast |
678 */ | 758 */ |
679 total_msec = (Uint32) ( (total_sec * 1000) + 0.5 ); | 759 total_msec = (ALuint) ( (total_sec * 1000) + 0.5 ); |
680 /* | 760 /* |
681 fprintf(stderr, "freq=%d, bytes_per_sample=%d, channels=%d, total_msec=%d\n", frequency, bytes_per_sample, channels, total_msec); | 761 fprintf(stderr, "freq=%d, bytes_per_sample=%d, channels=%d, total_msec=%d\n", frequency, bytes_per_sample, channels, total_msec); |
682 */ | 762 */ |
683 return total_msec; | 763 return total_msec; |
684 } | 764 } |
685 | 765 |
686 static Uint32 Compute_Total_Time(Sound_AudioInfo *info, Uint32 total_bytes) | 766 static ALuint Compute_Total_Time(Sound_AudioInfo *info, size_t total_bytes) |
687 { | 767 { |
688 Uint32 bytes_per_sample; | 768 ALuint bytes_per_sample; |
689 | 769 |
690 if(0 == total_bytes) | 770 if(0 == total_bytes) |
691 { | 771 { |
692 return 0; | 772 return 0; |
693 } | 773 } |
694 /* SDL has a mask trick I was not aware of. Mask the upper bits | 774 /* SDL has a mask trick I was not aware of. Mask the upper bits |
695 * of the format, and you get 8 or 16 which is the bits per sample. | 775 * of the format, and you get 8 or 16 which is the bits per sample. |
696 * Divide by 8bits_per_bytes and you get bytes_per_sample | 776 * Divide by 8bits_per_bytes and you get bytes_per_sample |
697 */ | 777 * I tested this under 32-bit and 64-bit and big and little endian |
698 bytes_per_sample = (Uint32) ((info->format & 0xFF) / 8); | 778 * to make sure this still works since I have since moved from |
779 * Uint32 to unspecified size types like ALuint. | |
780 */ | |
781 bytes_per_sample = (ALuint) ((info->format & 0xFF) / 8); | |
699 | 782 |
700 return Compute_Total_Time_Decomposed(bytes_per_sample, info->rate, info->channels, total_bytes); | 783 return Compute_Total_Time_Decomposed(bytes_per_sample, info->rate, info->channels, total_bytes); |
701 } /* End Compute_Total_Time */ | 784 } /* End Compute_Total_Time */ |
702 | 785 |
786 | |
787 static size_t Compute_Total_Bytes_Decomposed(ALuint bytes_per_sample, ALuint frequency, ALubyte channels, ALuint total_msec) | |
788 { | |
789 double total_sec; | |
790 ALuint bytes_per_sec; | |
791 size_t total_bytes; | |
792 | |
793 if(0 >= total_msec) | |
794 { | |
795 return 0; | |
796 } | |
797 /* To compute Bytes per second, do | |
798 * samples_per_sec * bytes_per_sample * number_of_channels | |
799 */ | |
800 bytes_per_sec = frequency * bytes_per_sample * channels; | |
801 | |
802 /* convert milliseconds to seconds */ | |
803 total_sec = total_msec / 1000.0; | |
804 | |
805 /* Now to get total bytes */ | |
806 total_bytes = (size_t)(((double)bytes_per_sec * total_sec) + 0.5); | |
807 | |
808 /* fprintf(stderr, "freq=%d, bytes_per_sample=%d, channels=%d, total_msec=%d, total_bytes=%d\n", frequency, bytes_per_sample, channels, total_msec, total_bytes); | |
809 */ | |
810 | |
811 return total_bytes; | |
812 } | |
813 | |
814 static size_t Compute_Total_Bytes(Sound_AudioInfo *info, ALuint total_msec) | |
815 { | |
816 ALuint bytes_per_sample; | |
817 | |
818 if(0 >= total_msec) | |
819 { | |
820 return 0; | |
821 } | |
822 /* SDL has a mask trick I was not aware of. Mask the upper bits | |
823 * of the format, and you get 8 or 16 which is the bits per sample. | |
824 * Divide by 8bits_per_bytes and you get bytes_per_sample | |
825 * I tested this under 32-bit and 64-bit and big and little endian | |
826 * to make sure this still works since I have since moved from | |
827 * Uint32 to unspecified size types like ALuint. | |
828 */ | |
829 bytes_per_sample = (ALuint) ((info->format & 0xFF) / 8); | |
830 | |
831 return Compute_Total_Bytes_Decomposed(bytes_per_sample, info->rate, info->channels, total_msec); | |
832 } | |
833 | |
834 /* The back-end decoders seem to need to decode in quantized frame sizes. | |
835 * So if I can pad the bytes to the next quanta, things might go more smoothly. | |
836 */ | |
837 static size_t Compute_Total_Bytes_With_Frame_Padding(Sound_AudioInfo *info, ALuint total_msec) | |
838 { | |
839 ALuint bytes_per_sample; | |
840 ALuint bytes_per_frame; | |
841 size_t evenly_divisible_frames; | |
842 size_t remainder_frames; | |
843 size_t return_bytes; | |
844 | |
845 size_t total_bytes = Compute_Total_Bytes(info, total_msec); | |
846 | |
847 bytes_per_sample = (ALuint) ((info->format & 0xFF) / 8); | |
848 | |
849 bytes_per_frame = bytes_per_sample * info->channels; | |
850 | |
851 evenly_divisible_frames = total_bytes / bytes_per_frame; | |
852 remainder_frames = total_bytes % bytes_per_frame; | |
853 | |
854 return_bytes = (evenly_divisible_frames * bytes_per_frame) + (remainder_frames * bytes_per_frame); | |
855 | |
856 /* Experimentally, some times I see to come up short in | |
857 * actual bytes decoded and I see a second pass is needed. | |
858 * I'm worried this may have additional performance implications. | |
859 * Sometimes in the second pass (depending on file), | |
860 * I have seen between 0 and 18 bytes. | |
861 * I'm tempted to pad the bytes by some arbitrary amount. | |
862 * However, I think currently the way SDL_sound is implemented, | |
863 * there is a big waste of memory up front instead of per-pass, | |
864 * so maybe I shouldn't worry about this. | |
865 */ | |
866 /* | |
867 return_bytes += 64; | |
868 */ | |
869 /* | |
870 fprintf(stderr, "remainder_frames=%d, padded_total_bytes=%d\n", remainder_frames, return_bytes); | |
871 */ | |
872 return return_bytes; | |
873 | |
874 } | |
875 | |
876 | |
703 | 877 |
704 | 878 |
705 /**************** REMOVED ****************************/ | 879 /**************** REMOVED ****************************/ |
706 /* This was removed because I originally thought | 880 /* This was removed because I originally thought |
707 * OpenAL could return a pointer to the buffer data, | 881 * OpenAL could return a pointer to the buffer data, |
716 */ | 890 */ |
717 #ifndef DISABLE_SEEK_MEMORY_OPTIMIZATION | 891 #ifndef DISABLE_SEEK_MEMORY_OPTIMIZATION |
718 | 892 |
719 static void Set_AudioInfo(Sound_AudioInfo* info, ALint frequency, ALint bits, ALint channels) | 893 static void Set_AudioInfo(Sound_AudioInfo* info, ALint frequency, ALint bits, ALint channels) |
720 { | 894 { |
721 info->rate = (Uint32)frequency; | 895 info->rate = (ALuint)frequency; |
722 info->channels = (Uint8)channels; | 896 info->channels = (ALubyte)channels; |
723 | 897 |
724 /* Not sure if it should be signed or unsigned. Hopefully | 898 /* Not sure if it should be signed or unsigned. Hopefully |
725 * that detail won't be needed. | 899 * that detail won't be needed. |
726 */ | 900 */ |
727 if(8 == bits) | 901 if(8 == bits) |
736 info->rate, info->channels, info->format); | 910 info->rate, info->channels, info->format); |
737 | 911 |
738 } | 912 } |
739 | 913 |
740 | 914 |
741 static Sint32 Reconstruct_Sound_Sample(ALmixer_Data* data) | 915 static ALint Reconstruct_Sound_Sample(ALmixer_Data* data) |
742 { | 916 { |
743 ALenum error; | 917 ALenum error; |
744 ALint* data_from_albuffer; | 918 ALint* data_from_albuffer; |
745 ALint freq; | 919 ALint freq; |
746 ALint bits; | 920 ALint bits; |
759 alGetError(); | 933 alGetError(); |
760 | 934 |
761 alGetBufferi(data->buffer[0], AL_FREQUENCY, &freq); | 935 alGetBufferi(data->buffer[0], AL_FREQUENCY, &freq); |
762 if((error = alGetError()) != AL_NO_ERROR) | 936 if((error = alGetError()) != AL_NO_ERROR) |
763 { | 937 { |
764 ALmixer_SetError("alGetBufferi(AL_FREQUENCT): %s", aluGetErrorString(error) ); | 938 ALmixer_SetError("alGetBufferi(AL_FREQUENCY): %s", alGetString(error) ); |
765 free(data->sample); | 939 free(data->sample); |
766 data->sample = NULL; | 940 data->sample = NULL; |
767 return -1; | 941 return -1; |
768 } | 942 } |
769 | 943 |
770 alGetBufferi(data->buffer[0], AL_BITS, &bits); | 944 alGetBufferi(data->buffer[0], AL_BITS, &bits); |
771 if((error = alGetError()) != AL_NO_ERROR) | 945 if((error = alGetError()) != AL_NO_ERROR) |
772 { | 946 { |
773 ALmixer_SetError("alGetBufferi(AL_BITS): %s", aluGetErrorString(error) ); | 947 ALmixer_SetError("alGetBufferi(AL_BITS): %s", alGetString(error) ); |
774 free(data->sample); | 948 free(data->sample); |
775 data->sample = NULL; | 949 data->sample = NULL; |
776 return -1; | 950 return -1; |
777 } | 951 } |
778 | 952 |
779 alGetBufferi(data->buffer[0], AL_CHANNELS, &channels); | 953 alGetBufferi(data->buffer[0], AL_CHANNELS, &channels); |
780 if((error = alGetError()) != AL_NO_ERROR) | 954 if((error = alGetError()) != AL_NO_ERROR) |
781 { | 955 { |
782 ALmixer_SetError("alGetBufferi(AL_CHANNELS): %s", aluGetErrorString(error) ); | 956 ALmixer_SetError("alGetBufferi(AL_CHANNELS): %s", alGetString(error) ); |
783 free(data->sample); | 957 free(data->sample); |
784 data->sample = NULL; | 958 data->sample = NULL; |
785 return -1; | 959 return -1; |
786 } | 960 } |
787 | 961 |
788 alGetBufferi(data->buffer[0], AL_SIZE, &size); | 962 alGetBufferi(data->buffer[0], AL_SIZE, &size); |
789 if((error = alGetError()) != AL_NO_ERROR) | 963 if((error = alGetError()) != AL_NO_ERROR) |
790 { | 964 { |
791 ALmixer_SetError("alGetBufferi(AL_SIZE): %s", aluGetErrorString(error) ); | 965 ALmixer_SetError("alGetBufferi(AL_SIZE): %s", alGetString(error) ); |
792 free(data->sample); | 966 free(data->sample); |
793 data->sample = NULL; | 967 data->sample = NULL; |
794 return -1; | 968 return -1; |
795 } | 969 } |
796 | 970 |
797 alGetBufferi(data->buffer[0], AL_DATA, data_from_albuffer); | 971 alGetBufferi(data->buffer[0], AL_DATA, data_from_albuffer); |
798 if((error = alGetError()) != AL_NO_ERROR) | 972 if((error = alGetError()) != AL_NO_ERROR) |
799 { | 973 { |
800 ALmixer_SetError("alGetBufferi(AL_DATA): %s", aluGetErrorString(error) ); | 974 ALmixer_SetError("alGetBufferi(AL_DATA): %s", alGetString(error) ); |
801 free(data->sample); | 975 free(data->sample); |
802 data->sample = NULL; | 976 data->sample = NULL; |
803 return -1; | 977 return -1; |
804 } | 978 } |
805 | 979 |
813 | 987 |
814 /* Now that we have all the attributes, we need to | 988 /* Now that we have all the attributes, we need to |
815 * allocate memory for the buffer and reconstruct | 989 * allocate memory for the buffer and reconstruct |
816 * the AudioInfo attributes. | 990 * the AudioInfo attributes. |
817 */ | 991 */ |
818 data->sample->buffer = malloc(size*sizeof(Uint8)); | 992 data->sample->buffer = malloc(size*sizeof(ALbyte)); |
819 if(NULL == data->sample->buffer) | 993 if(NULL == data->sample->buffer) |
820 { | 994 { |
821 ALmixer_SetError("Out of memory for sample->buffer"); | 995 ALmixer_SetError("Out of memory for sample->buffer"); |
822 free(data->sample); | 996 free(data->sample); |
823 data->sample = NULL; | 997 data->sample = NULL; |
836 | 1010 |
837 #endif /* End DISABLE_SEEK_MEMORY_OPTIMIZATION */ | 1011 #endif /* End DISABLE_SEEK_MEMORY_OPTIMIZATION */ |
838 #endif | 1012 #endif |
839 /*************** END REMOVED *************************/ | 1013 /*************** END REMOVED *************************/ |
840 | 1014 |
841 static void Invoke_Channel_Done_Callback(Sint32 channel) | 1015 static void Invoke_Channel_Done_Callback(ALint which_channel, ALboolean did_finish_naturally) |
842 { | 1016 { |
843 if(NULL == Channel_Done_Callback) | 1017 if(NULL == Channel_Done_Callback) |
844 { | 1018 { |
845 return; | 1019 return; |
846 } | 1020 } |
847 Channel_Done_Callback(channel, Channel_Done_Callback_Userdata); | 1021 Channel_Done_Callback(which_channel, ALmixer_Channel_List[which_channel].alsource, ALmixer_Channel_List[which_channel].almixer_data, did_finish_naturally, Channel_Done_Callback_Userdata); |
848 } | 1022 } |
849 | 1023 |
850 static Sint32 LookUpBuffer(ALuint buffer, ALmixer_Buffer_Map* buffer_map_list, Uint32 num_items_in_list) | 1024 static ALint LookUpBuffer(ALuint buffer, ALmixer_Buffer_Map* buffer_map_list, ALuint num_items_in_list) |
851 { | 1025 { |
852 /* Only the first value is used for the key */ | 1026 /* Only the first value is used for the key */ |
853 ALmixer_Buffer_Map key = { 0, 0, NULL, 0 }; | 1027 ALmixer_Buffer_Map key = { 0, 0, NULL, 0 }; |
854 ALmixer_Buffer_Map* found_item = NULL; | 1028 ALmixer_Buffer_Map* found_item = NULL; |
855 key.albuffer = buffer; | 1029 key.albuffer = buffer; |
871 */ | 1045 */ |
872 /* | 1046 /* |
873 * channels: 1 for mono, 2 for stereo | 1047 * channels: 1 for mono, 2 for stereo |
874 * | 1048 * |
875 */ | 1049 */ |
876 static void Invoke_Channel_Data_Callback(Sint32 which_channel, Uint8* data, Uint32 num_bytes, Uint32 frequency, Uint8 channels, Uint16 format, SDL_bool decode_mode_is_predecoded) | 1050 static void Invoke_Channel_Data_Callback(ALint which_channel, ALbyte* data, ALuint num_bytes, ALuint frequency, ALubyte channels, ALushort format, ALboolean decode_mode_is_predecoded) |
877 { | 1051 { |
878 SDL_bool is_unsigned; | 1052 ALboolean is_unsigned; |
879 Uint8 bits_per_sample = GetBitDepth(format); | 1053 ALubyte bits_per_sample = GetBitDepth(format); |
880 Uint32 bytes_per_sample; | 1054 ALuint bytes_per_sample; |
881 Uint32 length_in_msec; | 1055 ALuint length_in_msec; |
882 | 1056 |
883 if(GetSignednessValue(format) == ALMIXER_UNSIGNED_VALUE) | 1057 if(GetSignednessValue(format) == ALMIXER_UNSIGNED_VALUE) |
884 { | 1058 { |
885 is_unsigned = 1; | 1059 is_unsigned = 1; |
886 } | 1060 } |
887 else | 1061 else |
888 { | 1062 { |
889 is_unsigned = 0; | 1063 is_unsigned = 0; |
890 } | 1064 } |
891 | 1065 |
892 bytes_per_sample = (Uint32) (bits_per_sample / 8); | 1066 bytes_per_sample = (ALuint) (bits_per_sample / 8); |
893 | 1067 |
894 length_in_msec = Compute_Total_Time_Decomposed(bytes_per_sample, frequency, channels, num_bytes); | 1068 length_in_msec = Compute_Total_Time_Decomposed(bytes_per_sample, frequency, channels, num_bytes); |
895 | 1069 |
896 /* | 1070 /* |
897 fprintf(stderr, "%x %x %x %x, bytes=%d, whichchan=%d, freq=%d, channels=%d\n", data[0], data[1], data[2], data[3], num_bytes, channels, frequency, channels); | 1071 fprintf(stderr, "%x %x %x %x, bytes=%d, whichchan=%d, freq=%d, channels=%d\n", data[0], data[1], data[2], data[3], num_bytes, channels, frequency, channels); |
901 return; | 1075 return; |
902 } | 1076 } |
903 /* | 1077 /* |
904 * Channel_Data_Callback(which_channel, data, num_bytes, frequency, channels, GetBitDepth(format), format, decode_mode_is_predecoded); | 1078 * Channel_Data_Callback(which_channel, data, num_bytes, frequency, channels, GetBitDepth(format), format, decode_mode_is_predecoded); |
905 */ | 1079 */ |
906 Channel_Data_Callback(which_channel, data, num_bytes, frequency, channels, bits_per_sample, is_unsigned, decode_mode_is_predecoded, length_in_msec, Channel_Data_Callback_Userdata); | 1080 Channel_Data_Callback(which_channel, ALmixer_Channel_List[which_channel].alsource, data, num_bytes, frequency, channels, bits_per_sample, is_unsigned, decode_mode_is_predecoded, length_in_msec, Channel_Data_Callback_Userdata); |
907 } | 1081 } |
908 | 1082 |
909 static void Invoke_Predecoded_Channel_Data_Callback(Sint32 channel, ALmixer_Data* data) | 1083 static void Invoke_Predecoded_Channel_Data_Callback(ALint channel, ALmixer_Data* data) |
910 { | 1084 { |
911 if(NULL == data->sample) | 1085 if(NULL == data->sample) |
912 { | 1086 { |
913 return; | 1087 return; |
914 } | 1088 } |
915 /* The buffer position is complicated because if the current data was seeked, | 1089 /* The buffer position is complicated because if the current data was seeked, |
916 * we must adjust the buffer to the seek position | 1090 * we must adjust the buffer to the seek position |
917 */ | 1091 */ |
918 Invoke_Channel_Data_Callback(channel, | 1092 Invoke_Channel_Data_Callback(channel, |
919 (((Uint8*) data->sample->buffer) + (data->total_bytes - data->loaded_bytes) ), | 1093 (((ALbyte*) data->sample->buffer) + (data->total_bytes - data->loaded_bytes) ), |
920 data->loaded_bytes, | 1094 data->loaded_bytes, |
921 data->sample->desired.rate, | 1095 data->sample->desired.rate, |
922 data->sample->desired.channels, | 1096 data->sample->desired.channels, |
923 data->sample->desired.format, | 1097 data->sample->desired.format, |
924 SDL_TRUE | 1098 AL_TRUE |
925 ); | 1099 ); |
926 } | 1100 } |
927 | 1101 |
928 static void Invoke_Streamed_Channel_Data_Callback(Sint32 channel, ALmixer_Data* data, ALuint buffer) | 1102 static void Invoke_Streamed_Channel_Data_Callback(ALint channel, ALmixer_Data* data, ALuint buffer) |
929 { | 1103 { |
930 Sint32 index; | 1104 ALint index; |
931 if(NULL == data->buffer_map_list) | 1105 if(NULL == data->buffer_map_list) |
932 { | 1106 { |
933 return; | 1107 return; |
934 } | 1108 } |
935 index = LookUpBuffer(buffer, data->buffer_map_list, data->max_queue_buffers); | 1109 index = LookUpBuffer(buffer, data->buffer_map_list, data->max_queue_buffers); |
944 data->buffer_map_list[index].data, | 1118 data->buffer_map_list[index].data, |
945 data->buffer_map_list[index].num_bytes, | 1119 data->buffer_map_list[index].num_bytes, |
946 data->sample->desired.rate, | 1120 data->sample->desired.rate, |
947 data->sample->desired.channels, | 1121 data->sample->desired.channels, |
948 data->sample->desired.format, | 1122 data->sample->desired.format, |
949 SDL_FALSE | 1123 AL_FALSE |
950 ); | 1124 ); |
951 } | 1125 } |
952 | 1126 |
953 /* From SDL_Sound's playsound. Converts milliseconds to byte positions. | 1127 /* From SDL_Sound's playsound. Converts milliseconds to byte positions. |
954 * This is needed for seeking on predecoded samples | 1128 * This is needed for seeking on predecoded samples |
955 */ | 1129 */ |
956 static Uint32 Convert_Msec_To_Byte_Pos(Sound_AudioInfo *info, Uint32 ms) | 1130 static ALuint Convert_Msec_To_Byte_Pos(Sound_AudioInfo *info, ALuint ms) |
957 { | 1131 { |
958 float frames_per_ms; | 1132 float frames_per_ms; |
959 Uint32 frame_offset; | 1133 ALuint frame_offset; |
960 Uint32 frame_size; | 1134 ALuint frame_size; |
961 fprintf(stderr, "In convert\n" ); | 1135 fprintf(stderr, "In convert\n" ); |
962 if(info == NULL) | 1136 if(info == NULL) |
963 { | 1137 { |
964 fprintf(stderr, "Error, info is NULL\n"); | 1138 fprintf(stderr, "Error, info is NULL\n"); |
965 } | 1139 } |
970 fprintf(stderr, "The rate=%d\n", info->rate); | 1144 fprintf(stderr, "The rate=%d\n", info->rate); |
971 | 1145 |
972 /* "frames" == "sample frames" */ | 1146 /* "frames" == "sample frames" */ |
973 frames_per_ms = ((float) info->rate) / 1000.0f; | 1147 frames_per_ms = ((float) info->rate) / 1000.0f; |
974 fprintf(stderr, "%f\n", frames_per_ms); | 1148 fprintf(stderr, "%f\n", frames_per_ms); |
975 frame_offset = (Uint32) (frames_per_ms * ((float) ms)); | 1149 frame_offset = (ALuint) (frames_per_ms * ((float) ms)); |
976 fprintf(stderr, "%d\n", frame_offset); | 1150 fprintf(stderr, "%d\n", frame_offset); |
977 frame_size = (Uint32) ((info->format & 0xFF) / 8) * info->channels; | 1151 frame_size = (ALuint) ((info->format & 0xFF) / 8) * info->channels; |
978 fprintf(stderr, "%d\n", frame_size); | 1152 fprintf(stderr, "%d\n", frame_size); |
979 return(frame_offset * frame_size); | 1153 return(frame_offset * frame_size); |
980 } /* cvtMsToBytePos */ | 1154 } /* cvtMsToBytePos */ |
981 | 1155 |
982 static Sint32 Set_Predecoded_Seek_Position(ALmixer_Data* data, Uint32 byte_position) | 1156 static ALint Set_Predecoded_Seek_Position(ALmixer_Data* data, ALuint byte_position) |
983 { | 1157 { |
984 ALenum error; | 1158 ALenum error; |
985 /* clear error */ | 1159 /* clear error */ |
986 alGetError(); | 1160 alGetError(); |
987 | 1161 |
994 /* In case the below thing doesn't work, | 1168 /* In case the below thing doesn't work, |
995 * just rewind the whole thing. | 1169 * just rewind the whole thing. |
996 * | 1170 * |
997 alBufferData(data->buffer[0], | 1171 alBufferData(data->buffer[0], |
998 TranslateFormat(&data->sample->desired), | 1172 TranslateFormat(&data->sample->desired), |
999 (Uint8*) data->sample->buffer, | 1173 (ALbyte*) data->sample->buffer, |
1000 data->total_bytes, | 1174 data->total_bytes, |
1001 data->sample->desired.rate | 1175 data->sample->desired.rate |
1002 ); | 1176 ); |
1003 */ | 1177 */ |
1004 | 1178 |
1008 * and it still hung. 4 didn't hang, but I got a clip | 1182 * and it still hung. 4 didn't hang, but I got a clip |
1009 * artifact. 8 seemed to work okay. | 1183 * artifact. 8 seemed to work okay. |
1010 */ | 1184 */ |
1011 alBufferData(data->buffer[0], | 1185 alBufferData(data->buffer[0], |
1012 TranslateFormat(&data->sample->desired), | 1186 TranslateFormat(&data->sample->desired), |
1013 (((Uint8*) data->sample->buffer) + (data->total_bytes - 8) ), | 1187 (((ALbyte*) data->sample->buffer) + (data->total_bytes - 8) ), |
1014 8, | 1188 8, |
1015 data->sample->desired.rate | 1189 data->sample->desired.rate |
1016 ); | 1190 ); |
1017 if( (error = alGetError()) != AL_NO_ERROR) | 1191 if( (error = alGetError()) != AL_NO_ERROR) |
1018 { | 1192 { |
1019 ALmixer_SetError("Can't seek past end and alBufferData failed: %s\n", aluGetErrorString(error)); | 1193 ALmixer_SetError("Can't seek past end and alBufferData failed: %s\n", alGetString(error)); |
1020 return -1; | 1194 return -1; |
1021 } | 1195 } |
1022 /* Need to set the loaded_bytes field because I don't trust the OpenAL | 1196 /* Need to set the loaded_bytes field because I don't trust the OpenAL |
1023 * query command to work because I don't know if it will mutilate the | 1197 * query command to work because I don't know if it will mutilate the |
1024 * size for its own purposes or return the original size | 1198 * size for its own purposes or return the original size |
1033 return 0; | 1207 return 0; |
1034 } | 1208 } |
1035 | 1209 |
1036 alBufferData(data->buffer[0], | 1210 alBufferData(data->buffer[0], |
1037 TranslateFormat(&data->sample->desired), | 1211 TranslateFormat(&data->sample->desired), |
1038 &(((Uint8*)data->sample->buffer)[byte_position]), | 1212 &(((ALbyte*)data->sample->buffer)[byte_position]), |
1039 data->total_bytes - byte_position, | 1213 data->total_bytes - byte_position, |
1040 data->sample->desired.rate | 1214 data->sample->desired.rate |
1041 ); | 1215 ); |
1042 if( (error = alGetError()) != AL_NO_ERROR) | 1216 if( (error = alGetError()) != AL_NO_ERROR) |
1043 { | 1217 { |
1044 ALmixer_SetError("alBufferData failed: %s\n", aluGetErrorString(error)); | 1218 ALmixer_SetError("alBufferData failed: %s\n", alGetString(error)); |
1045 return -1; | 1219 return -1; |
1046 } | 1220 } |
1047 /* Need to set the loaded_bytes field because I don't trust the OpenAL | 1221 /* Need to set the loaded_bytes field because I don't trust the OpenAL |
1048 * query command to work because I don't know if it will mutilate the | 1222 * query command to work because I don't know if it will mutilate the |
1049 * size for its own purposes or return the original size | 1223 * size for its own purposes or return the original size |
1054 } | 1228 } |
1055 | 1229 |
1056 /* Because we have multiple queue buffers and OpenAL won't let | 1230 /* Because we have multiple queue buffers and OpenAL won't let |
1057 * us access them, we need to keep copies of each buffer around | 1231 * us access them, we need to keep copies of each buffer around |
1058 */ | 1232 */ |
1059 static Sint32 CopyDataToAccessBuffer(ALmixer_Data* data, Uint32 num_bytes, ALuint buffer) | 1233 static ALint CopyDataToAccessBuffer(ALmixer_Data* data, ALuint num_bytes, ALuint buffer) |
1060 { | 1234 { |
1061 Sint32 index; | 1235 ALint index; |
1062 /* We only want to copy if access_data is true. | 1236 /* We only want to copy if access_data is true. |
1063 * This is determined by whether memory has been | 1237 * This is determined by whether memory has been |
1064 * allocated in the buffer_map_list or not | 1238 * allocated in the buffer_map_list or not |
1065 */ | 1239 */ |
1066 if(NULL == data->buffer_map_list) | 1240 if(NULL == data->buffer_map_list) |
1082 | 1256 |
1083 | 1257 |
1084 /* For streamed data, gets more data | 1258 /* For streamed data, gets more data |
1085 * and prepares it in the active Mix_chunk | 1259 * and prepares it in the active Mix_chunk |
1086 */ | 1260 */ |
1087 static Uint32 GetMoreData(ALmixer_Data* data, ALuint buffer) | 1261 static ALuint GetMoreData(ALmixer_Data* data, ALuint buffer) |
1088 { | 1262 { |
1089 Uint32 bytes_decoded; | 1263 ALuint bytes_decoded; |
1090 ALenum error; | 1264 ALenum error; |
1091 if(NULL == data) | 1265 if(NULL == data) |
1092 { | 1266 { |
1093 ALmixer_SetError("Cannot GetMoreData() because ALmixer_Data* is NULL\n"); | 1267 ALmixer_SetError("Cannot GetMoreData() because ALmixer_Data* is NULL\n"); |
1094 return 0; | 1268 return 0; |
1103 Sound_FreeSample(data->sample); | 1277 Sound_FreeSample(data->sample); |
1104 */ | 1278 */ |
1105 return 0; | 1279 return 0; |
1106 } | 1280 } |
1107 | 1281 |
1108 | 1282 /* fprintf(stderr, "GetMoreData bytes_decoded=%d\n", bytes_decoded); */ |
1283 | |
1109 /* Don't forget to add check for EOF */ | 1284 /* Don't forget to add check for EOF */ |
1110 /* Will return 0 bytes and pass the buck to check sample->flags */ | 1285 /* Will return 0 bytes and pass the buck to check sample->flags */ |
1111 if(0 == bytes_decoded) | 1286 if(0 == bytes_decoded) |
1112 { | 1287 { |
1113 #if 1 | 1288 data->eof = 1; |
1289 | |
1290 #if 0 | |
1114 fprintf(stderr, "Hit eof while trying to buffer\n"); | 1291 fprintf(stderr, "Hit eof while trying to buffer\n"); |
1115 data->eof = 1; | |
1116 if(data->sample->flags & SOUND_SAMPLEFLAG_EOF) | 1292 if(data->sample->flags & SOUND_SAMPLEFLAG_EOF) |
1117 { | 1293 { |
1118 fprintf(stderr, "\tEOF flag\n"); | 1294 fprintf(stderr, "\tEOF flag\n"); |
1119 } | 1295 } |
1120 if(data->sample->flags & SOUND_SAMPLEFLAG_CANSEEK) | 1296 if(data->sample->flags & SOUND_SAMPLEFLAG_CANSEEK) |
1167 * (like Ogg), then you will get breakup in between | 1343 * (like Ogg), then you will get breakup in between |
1168 * packets. | 1344 * packets. |
1169 */ | 1345 */ |
1170 if( (bytes_decoded) < data->sample->buffer_size) | 1346 if( (bytes_decoded) < data->sample->buffer_size) |
1171 { | 1347 { |
1172 Uint8 bit_depth; | 1348 ALubyte bit_depth; |
1173 Uint8 signedness_value; | 1349 ALubyte signedness_value; |
1174 int silence_value; | 1350 int silence_value; |
1175 /* Crap, memset value needs to be the "silent" value, | 1351 /* Crap, memset value needs to be the "silent" value, |
1176 * but it will differ for signed/unsigned and bit depth | 1352 * but it will differ for signed/unsigned and bit depth |
1177 */ | 1353 */ |
1178 bit_depth = GetBitDepth(data->sample->desired.format); | 1354 bit_depth = GetBitDepth(data->sample->desired.format); |
1200 * silence_value. | 1376 * silence_value. |
1201 * I don't think I have to worry about endian issues for | 1377 * I don't think I have to worry about endian issues for |
1202 * this part since the data is for internal use only | 1378 * this part since the data is for internal use only |
1203 * at this point. | 1379 * at this point. |
1204 */ | 1380 */ |
1205 memset( &( ((Uint8*)(data->sample->buffer))[bytes_decoded] ), silence_value, data->sample->buffer_size - bytes_decoded); | 1381 memset( &( ((ALbyte*)(data->sample->buffer))[bytes_decoded] ), silence_value, data->sample->buffer_size - bytes_decoded); |
1206 /* Now reset the bytes_decoded to reflect the entire | 1382 /* Now reset the bytes_decoded to reflect the entire |
1207 * buffer to tell alBufferData what our full size is. | 1383 * buffer to tell alBufferData what our full size is. |
1208 */ | 1384 */ |
1209 fprintf(stderr, "ALTERED bytes decoded for silence: Original end was %d\n", bytes_decoded); | 1385 fprintf(stderr, "ALTERED bytes decoded for silence: Original end was %d\n", bytes_decoded); |
1210 bytes_decoded = data->sample->buffer_size; | 1386 bytes_decoded = data->sample->buffer_size; |
1222 bytes_decoded, | 1398 bytes_decoded, |
1223 data->sample->desired.rate | 1399 data->sample->desired.rate |
1224 ); | 1400 ); |
1225 if( (error = alGetError()) != AL_NO_ERROR) | 1401 if( (error = alGetError()) != AL_NO_ERROR) |
1226 { | 1402 { |
1227 ALmixer_SetError("alBufferData failed: %s\n", aluGetErrorString(error)); | 1403 ALmixer_SetError("alBufferData failed: %s\n", alGetString(error)); |
1228 return 0; | 1404 return 0; |
1229 } | 1405 } |
1230 | 1406 |
1231 /* If we need to, copy the data also to the access area | 1407 /* If we need to, copy the data also to the access area |
1232 * (the function will do the check for us) | 1408 * (the function will do the check for us) |
1241 /******************** EXPERIEMENT **************************** | 1417 /******************** EXPERIEMENT **************************** |
1242 * Test function to force maximum buffer filling during loops | 1418 * Test function to force maximum buffer filling during loops |
1243 * REMOVE LATER | 1419 * REMOVE LATER |
1244 *********************************************/ | 1420 *********************************************/ |
1245 #if 0 | 1421 #if 0 |
1246 static Sint32 GetMoreData2(ALmixer_Data* data, ALuint buffer) | 1422 static ALint GetMoreData2(ALmixer_Data* data, ALuint buffer) |
1247 { | 1423 { |
1248 Sint32 bytes_decoded; | 1424 ALint bytes_decoded; |
1249 ALenum error; | 1425 ALenum error; |
1250 if(NULL == data) | 1426 if(NULL == data) |
1251 { | 1427 { |
1252 ALmixer_SetError("Cannot GetMoreData() because ALmixer_Data* is NULL\n"); | 1428 ALmixer_SetError("Cannot GetMoreData() because ALmixer_Data* is NULL\n"); |
1253 return -1; | 1429 return -1; |
1321 int retval; | 1497 int retval; |
1322 memcpy(tempbuffer1, data->sample->buffer, bytes_decoded); | 1498 memcpy(tempbuffer1, data->sample->buffer, bytes_decoded); |
1323 retval = Sound_SetBufferSize(data->sample, 16384-bytes_decoded); | 1499 retval = Sound_SetBufferSize(data->sample, 16384-bytes_decoded); |
1324 if(retval == 1) | 1500 if(retval == 1) |
1325 { | 1501 { |
1326 Uint32 new_bytes; | 1502 ALuint new_bytes; |
1327 Sound_Rewind(data->sample); | 1503 Sound_Rewind(data->sample); |
1328 new_bytes = Sound_Decode(data->sample); | 1504 new_bytes = Sound_Decode(data->sample); |
1329 fprintf(stderr, "Orig bytes: %d, Make up bytes_decoded=%d, total=%d\n", bytes_decoded, new_bytes, new_bytes+bytes_decoded); | 1505 fprintf(stderr, "Orig bytes: %d, Make up bytes_decoded=%d, total=%d\n", bytes_decoded, new_bytes, new_bytes+bytes_decoded); |
1330 | 1506 |
1331 memcpy(tempbuffer2, data->sample->buffer, new_bytes); | 1507 memcpy(tempbuffer2, data->sample->buffer, new_bytes); |
1359 bytes_decoded, | 1535 bytes_decoded, |
1360 data->sample->desired.rate | 1536 data->sample->desired.rate |
1361 ); | 1537 ); |
1362 if( (error = alGetError()) != AL_NO_ERROR) | 1538 if( (error = alGetError()) != AL_NO_ERROR) |
1363 { | 1539 { |
1364 ALmixer_SetError("alBufferData failed: %s\n", aluGetErrorString(error)); | 1540 ALmixer_SetError("alBufferData failed: %s\n", alGetString(error)); |
1365 return -1; | 1541 return -1; |
1366 } | 1542 } |
1367 | 1543 |
1368 fprintf(stderr, "GetMoreData2222 returning %d bytes decoded\n", bytes_decoded); | 1544 fprintf(stderr, "GetMoreData2222 returning %d bytes decoded\n", bytes_decoded); |
1369 return bytes_decoded; | 1545 return bytes_decoded; |
1380 | 1556 |
1381 | 1557 |
1382 | 1558 |
1383 /* This function will look up the source for the corresponding channel */ | 1559 /* This function will look up the source for the corresponding channel */ |
1384 /* Must return 0 on error instead of -1 because of unsigned int */ | 1560 /* Must return 0 on error instead of -1 because of unsigned int */ |
1385 static ALuint Internal_GetSource(Sint32 channel) | 1561 static ALuint Internal_GetSource(ALint channel) |
1386 { | 1562 { |
1387 Sint32 i; | 1563 ALint i; |
1388 /* Make sure channel is in bounds */ | 1564 /* Make sure channel is in bounds */ |
1389 if(channel >= Number_of_Channels_global) | 1565 if(channel >= Number_of_Channels_global) |
1390 { | 1566 { |
1391 ALmixer_SetError("Requested channel (%d) exceeds maximum channel (%d) because only %d channels are allocated", channel, Number_of_Channels_global-1, Number_of_Channels_global); | 1567 ALmixer_SetError("Requested channel (%d) exceeds maximum channel (%d) because only %d channels are allocated", channel, Number_of_Channels_global-1, Number_of_Channels_global); |
1392 return 0; | 1568 return 0; |
1410 /* Last case: Return the source for the channel */ | 1586 /* Last case: Return the source for the channel */ |
1411 return ALmixer_Channel_List[channel].alsource; | 1587 return ALmixer_Channel_List[channel].alsource; |
1412 } | 1588 } |
1413 | 1589 |
1414 /* This function will look up the channel for the corresponding source */ | 1590 /* This function will look up the channel for the corresponding source */ |
1415 static Sint32 Internal_GetChannel(ALuint source) | 1591 static ALint Internal_GetChannel(ALuint source) |
1416 { | 1592 { |
1417 Sint32 i; | 1593 ALint i; |
1418 /* Only the first value is used for the key */ | 1594 /* Only the first value is used for the key */ |
1419 Source_Map key = { 0, 0 }; | 1595 Source_Map key = { 0, 0 }; |
1420 Source_Map* found_item = NULL; | 1596 Source_Map* found_item = NULL; |
1421 key.source = source; | 1597 key.source = source; |
1422 | 1598 |
1459 | 1635 |
1460 /* This function will find the first available channel (not in use) | 1636 /* This function will find the first available channel (not in use) |
1461 * from the specified start channel. Reserved channels to not qualify | 1637 * from the specified start channel. Reserved channels to not qualify |
1462 * as available. | 1638 * as available. |
1463 */ | 1639 */ |
1464 static Sint32 Internal_FindFreeChannel(Sint32 start_channel) | 1640 static ALint Internal_FindFreeChannel(ALint start_channel) |
1465 { | 1641 { |
1466 /* Start at the number of reserved so we skip over | 1642 /* Start at the number of reserved so we skip over |
1467 * all the reserved channels. | 1643 * all the reserved channels. |
1468 */ | 1644 */ |
1469 Sint32 i = Number_of_Reserve_Channels_global; | 1645 ALint i = Number_of_Reserve_Channels_global; |
1470 /* Quick check to see if we're out of bounds */ | 1646 /* Quick check to see if we're out of bounds */ |
1471 if(start_channel >= Number_of_Channels_global) | 1647 if(start_channel >= Number_of_Channels_global) |
1472 { | 1648 { |
1473 return -1; | 1649 return -1; |
1474 } | 1650 } |
1491 } | 1667 } |
1492 /* If we get here, all sources are in use */ | 1668 /* If we get here, all sources are in use */ |
1493 return -1; | 1669 return -1; |
1494 } | 1670 } |
1495 | 1671 |
1672 | |
1673 | |
1674 /* Will return the number of channels halted | |
1675 * or 0 for error | |
1676 */ | |
1677 static ALint Internal_HaltChannel(ALint channel, ALboolean did_finish_naturally) | |
1678 { | |
1679 ALint retval = 0; | |
1680 ALint counter = 0; | |
1681 ALenum error; | |
1682 ALint buffers_still_queued; | |
1683 ALint buffers_processed; | |
1684 | |
1685 if(channel >= Number_of_Channels_global) | |
1686 { | |
1687 ALmixer_SetError("Cannot halt channel %d because it exceeds maximum number of channels (%d)\n", channel, Number_of_Channels_global); | |
1688 return -1; | |
1689 } | |
1690 /* If the user specified a specific channel */ | |
1691 if(channel >= 0) | |
1692 { | |
1693 fprintf(stderr, "Halt on channel %d\n", channel); | |
1694 /* only need to process channel if in use */ | |
1695 if(ALmixer_Channel_List[channel].channel_in_use) | |
1696 { | |
1697 alSourceStop(ALmixer_Channel_List[channel].alsource); | |
1698 if((error = alGetError()) != AL_NO_ERROR) | |
1699 { | |
1700 fprintf(stderr, "14Testing error: %s\n", | |
1701 alGetString(error)); | |
1702 } | |
1703 /* Here's the situation. My old method of using | |
1704 * alSourceUnqueueBuffers() seemed to be invalid in light | |
1705 * of all the problems I suffered through with getting | |
1706 * the CoreData backend to work with this code. | |
1707 * As such, I'm changing all the code to set the buffer to | |
1708 * AL_NONE. Furthermore, the queued vs. non-queued issue | |
1709 * doesn't need to apply here. For non-queued, Loki, | |
1710 * Creative Windows, and CoreAudio seem to leave the | |
1711 * buffer queued (Old Mac didn't.) For queued, we need to | |
1712 * remove the processed buffers and force remove the | |
1713 * still-queued buffers. | |
1714 */ | |
1715 fprintf(stderr, "Halt on channel %d, channel in use\n", channel); | |
1716 alGetSourcei( | |
1717 ALmixer_Channel_List[channel].alsource, | |
1718 AL_BUFFERS_QUEUED, &buffers_still_queued | |
1719 ); | |
1720 if((error = alGetError()) != AL_NO_ERROR) | |
1721 { | |
1722 fprintf(stderr, "17Testing Error with buffers_still_queued: %s", | |
1723 alGetString(error)); | |
1724 ALmixer_SetError("Failed detecting still queued buffers: %s", | |
1725 alGetString(error) ); | |
1726 retval = -1; | |
1727 } | |
1728 alGetSourcei( | |
1729 ALmixer_Channel_List[channel].alsource, | |
1730 AL_BUFFERS_PROCESSED, &buffers_processed | |
1731 ); | |
1732 if((error = alGetError()) != AL_NO_ERROR) | |
1733 { | |
1734 fprintf(stderr, "17Testing Error with buffers_processed: %s", | |
1735 alGetString(error)); | |
1736 ALmixer_SetError("Failed detecting still processed buffers: %s", | |
1737 alGetString(error) ); | |
1738 retval = -1; | |
1739 } | |
1740 /* If either of these is greater than 0, it means we need | |
1741 * to clear the source | |
1742 */ | |
1743 if((buffers_still_queued > 0) || (buffers_processed > 0)) | |
1744 { | |
1745 alSourcei(ALmixer_Channel_List[channel].alsource, | |
1746 AL_BUFFER, | |
1747 AL_NONE); | |
1748 if((error = alGetError()) != AL_NO_ERROR) | |
1749 { | |
1750 fprintf(stderr, "17Testing Error with clearing buffer from source: %s", | |
1751 alGetString(error)); | |
1752 ALmixer_SetError("Failed to clear buffer from source: %s", | |
1753 alGetString(error) ); | |
1754 retval = -1; | |
1755 } | |
1756 } | |
1757 | |
1758 ALmixer_Channel_List[channel].almixer_data->num_buffers_in_use = 0; | |
1759 | |
1760 Clean_Channel(channel); | |
1761 Is_Playing_global--; | |
1762 /* Launch callback for consistency? */ | |
1763 Invoke_Channel_Done_Callback(channel, did_finish_naturally); | |
1764 counter++; | |
1765 } | |
1766 } | |
1767 /* The user wants to halt all channels */ | |
1768 else | |
1769 { | |
1770 ALint i; | |
1771 for(i=0; i<Number_of_Channels_global; i++) | |
1772 { | |
1773 fprintf(stderr, "Halting channel %d\n", i); | |
1774 fprintf(stderr, "in use %d\n", ALmixer_Channel_List[i].channel_in_use ); | |
1775 /* only need to process channel if in use */ | |
1776 if(ALmixer_Channel_List[i].channel_in_use) | |
1777 { | |
1778 fprintf(stderr, "SourceStop %d\n", i); | |
1779 alSourceStop(ALmixer_Channel_List[i].alsource); | |
1780 if((error = alGetError()) != AL_NO_ERROR) | |
1781 { | |
1782 fprintf(stderr, "19Testing error: %s\n", | |
1783 alGetString(error)); | |
1784 } | |
1785 | |
1786 /* Here's the situation. My old method of using | |
1787 * alSourceUnqueueBuffers() seemed to be invalid in light | |
1788 * of all the problems I suffered through with getting | |
1789 * the CoreData backend to work with this code. | |
1790 * As such, I'm changing all the code to set the buffer to | |
1791 * AL_NONE. Furthermore, the queued vs. non-queued issue | |
1792 * doesn't need to apply here. For non-queued, Loki, | |
1793 * Creative Windows, and CoreAudio seem to leave the | |
1794 * buffer queued (Old Mac didn't.) For queued, we need to | |
1795 * remove the processed buffers and force remove the | |
1796 * still-queued buffers. | |
1797 */ | |
1798 fprintf(stderr, "Halt on channel %d, channel in use\n", channel); | |
1799 alGetSourcei( | |
1800 ALmixer_Channel_List[i].alsource, | |
1801 AL_BUFFERS_QUEUED, &buffers_still_queued | |
1802 ); | |
1803 if((error = alGetError()) != AL_NO_ERROR) | |
1804 { | |
1805 fprintf(stderr, "17Testing Error with buffers_still_queued: %s", | |
1806 alGetString(error)); | |
1807 ALmixer_SetError("Failed detecting still queued buffers: %s", | |
1808 alGetString(error) ); | |
1809 retval = -1; | |
1810 } | |
1811 alGetSourcei( | |
1812 ALmixer_Channel_List[i].alsource, | |
1813 AL_BUFFERS_PROCESSED, &buffers_processed | |
1814 ); | |
1815 if((error = alGetError()) != AL_NO_ERROR) | |
1816 { | |
1817 fprintf(stderr, "17Testing Error with buffers_processed: %s", | |
1818 alGetString(error)); | |
1819 ALmixer_SetError("Failed detecting still processed buffers: %s", | |
1820 alGetString(error) ); | |
1821 retval = -1; | |
1822 } | |
1823 /* If either of these is greater than 0, it means we need | |
1824 * to clear the source | |
1825 */ | |
1826 if((buffers_still_queued > 0) || (buffers_processed > 0)) | |
1827 { | |
1828 alSourcei(ALmixer_Channel_List[i].alsource, | |
1829 AL_BUFFER, | |
1830 AL_NONE); | |
1831 if((error = alGetError()) != AL_NO_ERROR) | |
1832 { | |
1833 fprintf(stderr, "17Testing Error with clearing buffer from source: %s", | |
1834 alGetString(error)); | |
1835 ALmixer_SetError("Failed to clear buffer from source: %s", | |
1836 alGetString(error) ); | |
1837 retval = -1; | |
1838 } | |
1839 } | |
1840 | |
1841 ALmixer_Channel_List[i].almixer_data->num_buffers_in_use = 0; | |
1842 | |
1843 fprintf(stderr, "Clean channel %d\n", i); | |
1844 Clean_Channel(i); | |
1845 Is_Playing_global--; | |
1846 /* Launch callback for consistency? */ | |
1847 fprintf(stderr, "Callback%d\n", i); | |
1848 Invoke_Channel_Done_Callback(i, did_finish_naturally); | |
1849 | |
1850 /* Increment the counter */ | |
1851 counter++; | |
1852 } | |
1853 /* Let's halt everything just in case there | |
1854 * are bugs. | |
1855 */ | |
1856 /* | |
1857 else | |
1858 { | |
1859 alSourceStop(ALmixer_Channel_List[channel].alsource); | |
1860 / * Can't clean because the in_use counter for | |
1861 * data will get messed up * / | |
1862 Clean_Channel(channel); | |
1863 } | |
1864 */ | |
1865 /* Just in case */ | |
1866 Is_Playing_global = 0; | |
1867 } | |
1868 } | |
1869 if(-1 == retval) | |
1870 { | |
1871 return -1; | |
1872 } | |
1873 return counter; | |
1874 } | |
1875 | |
1876 | |
1877 /* Will return the source halted or the total number of channels | |
1878 * if all were halted or 0 for error | |
1879 */ | |
1880 static ALint Internal_HaltSource(ALuint source, ALboolean did_finish_naturally) | |
1881 { | |
1882 ALint channel; | |
1883 if(0 == source) | |
1884 { | |
1885 /* Will return the number of sources halted */ | |
1886 return Internal_HaltChannel(-1, did_finish_naturally); | |
1887 } | |
1888 | |
1889 channel = Internal_GetChannel(source); | |
1890 if(-1 == channel) | |
1891 { | |
1892 ALmixer_SetError("Cannot halt source: %s", ALmixer_GetError()); | |
1893 return -1; | |
1894 } | |
1895 return Internal_HaltChannel(channel, did_finish_naturally); | |
1896 } | |
1496 | 1897 |
1497 | 1898 |
1498 | 1899 |
1499 /* Note: Behaves, almost like SDL_mixer, but keep in mind | 1900 /* Note: Behaves, almost like SDL_mixer, but keep in mind |
1500 * that there is no "music" channel anymore, so 0 | 1901 * that there is no "music" channel anymore, so 0 |
1503 * Also, callbacks for deleted channels will not be called. | 1904 * Also, callbacks for deleted channels will not be called. |
1504 * I really need to do error checking, for realloc and | 1905 * I really need to do error checking, for realloc and |
1505 * GenSources, but reversing the damage is too painful | 1906 * GenSources, but reversing the damage is too painful |
1506 * for me to think about at the moment, so it's not in here. | 1907 * for me to think about at the moment, so it's not in here. |
1507 */ | 1908 */ |
1508 static Sint32 Internal_AllocateChannels(Sint32 numchans) | 1909 static ALint Internal_AllocateChannels(ALint numchans) |
1509 { | 1910 { |
1510 ALenum error; | 1911 ALenum error; |
1511 int i; | 1912 int i; |
1512 /* Return info */ | 1913 /* Return info */ |
1513 if(numchans < 0) | 1914 if(numchans < 0) |
1539 /* Generate a new source and associate it with the channel */ | 1940 /* Generate a new source and associate it with the channel */ |
1540 alGenSources(1, &ALmixer_Channel_List[i].alsource); | 1941 alGenSources(1, &ALmixer_Channel_List[i].alsource); |
1541 if((error = alGetError()) != AL_NO_ERROR) | 1942 if((error = alGetError()) != AL_NO_ERROR) |
1542 { | 1943 { |
1543 fprintf(stderr, "12Testing errpr before unqueue because getting stuff, for OS X this is expected: %s\n", | 1944 fprintf(stderr, "12Testing errpr before unqueue because getting stuff, for OS X this is expected: %s\n", |
1544 aluGetErrorString(error)); | 1945 alGetString(error)); |
1545 } | 1946 } |
1546 /* Copy the source so the SourceMap has it too */ | 1947 /* Copy the source so the SourceMap has it too */ |
1547 Source_Map_List[i].source = ALmixer_Channel_List[i].alsource; | 1948 Source_Map_List[i].source = ALmixer_Channel_List[i].alsource; |
1548 Source_Map_List[i].channel = i; | 1949 Source_Map_List[i].channel = i; |
1549 /* Clean the channel because there are some things that need to | 1950 /* Clean the channel because there are some things that need to |
1563 if(numchans < Number_of_Channels_global) | 1964 if(numchans < Number_of_Channels_global) |
1564 { | 1965 { |
1565 for(i=numchans; i<Number_of_Channels_global; i++) | 1966 for(i=numchans; i<Number_of_Channels_global; i++) |
1566 { | 1967 { |
1567 /* Halt the channel */ | 1968 /* Halt the channel */ |
1568 ALmixer_HaltChannel(i); | 1969 Internal_HaltChannel(i, AL_FALSE); |
1569 | 1970 |
1570 /* Delete source associated with the channel */ | 1971 /* Delete source associated with the channel */ |
1571 alDeleteSources(1, &ALmixer_Channel_List[i].alsource); | 1972 alDeleteSources(1, &ALmixer_Channel_List[i].alsource); |
1572 if((error = alGetError()) != AL_NO_ERROR) | 1973 if((error = alGetError()) != AL_NO_ERROR) |
1573 { | 1974 { |
1574 fprintf(stderr, "13Testing error: %s\n", | 1975 fprintf(stderr, "13Testing error: %s\n", |
1575 aluGetErrorString(error)); | 1976 alGetString(error)); |
1576 } | 1977 } |
1577 } | 1978 } |
1578 | 1979 |
1579 | 1980 |
1580 /* Not sure how safe this is, but SDL_mixer does it | 1981 /* Not sure how safe this is, but SDL_mixer does it |
1601 /* Shouldn't ever reach here */ | 2002 /* Shouldn't ever reach here */ |
1602 return -1; | 2003 return -1; |
1603 | 2004 |
1604 } | 2005 } |
1605 | 2006 |
1606 static Sint32 Internal_ReserveChannels(Sint32 num) | 2007 static ALint Internal_ReserveChannels(ALint num) |
1607 { | 2008 { |
1608 /* Can't reserve more than the max num of channels */ | 2009 /* Can't reserve more than the max num of channels */ |
1609 /* Actually, I'll allow it for people who just want to | 2010 /* Actually, I'll allow it for people who just want to |
1610 * set the value really high to effectively disable | 2011 * set the value really high to effectively disable |
1611 * auto-assignment | 2012 * auto-assignment |
1619 Number_of_Reserve_Channels_global = num; | 2020 Number_of_Reserve_Channels_global = num; |
1620 return Number_of_Reserve_Channels_global; | 2021 return Number_of_Reserve_Channels_global; |
1621 } | 2022 } |
1622 | 2023 |
1623 | 2024 |
1624 | 2025 /* This will rewind the SDL_Sound sample for streamed |
1625 | 2026 * samples and start buffering up the data for the next |
1626 | 2027 * playback. This may require samples to be halted |
1627 static Sint32 Internal_PlayChannelTimed(Sint32 channel, ALmixer_Data* data, Sint32 loops, Sint32 ticks) | 2028 */ |
2029 static ALint Internal_RewindData(ALmixer_Data* data) | |
2030 { | |
2031 ALint retval = 0; | |
2032 /* | |
2033 ALint bytes_returned; | |
2034 ALint i; | |
2035 */ | |
2036 if(NULL == data) | |
2037 { | |
2038 ALmixer_SetError("Cannot rewind because data is NULL\n"); | |
2039 return -1; | |
2040 } | |
2041 | |
2042 | |
2043 /* Might have to require Halt */ | |
2044 /* Okay, we assume Halt or natural stop has already | |
2045 * cleared the data buffers | |
2046 */ | |
2047 if(data->in_use) | |
2048 { | |
2049 fprintf(stderr, "Warning sample is in use. May not be able to rewind\n"); | |
2050 /* | |
2051 ALmixer_SetError("Data is in use. Cannot rewind unless all sources using the data are halted\n"); | |
2052 return -1; | |
2053 */ | |
2054 } | |
2055 | |
2056 | |
2057 /* Because Seek can alter things even in predecoded data, | |
2058 * decoded data must also be rewound | |
2059 */ | |
2060 if(data->decoded_all) | |
2061 { | |
2062 data->eof = 0; | |
2063 | |
2064 #if 0 | |
2065 #if defined(DISABLE_PREDECODED_SEEK) | |
2066 /* Since we can't seek predecoded stuff, it should be rewound */ | |
2067 return 0; | |
2068 #elif !defined(DISABLE_SEEK_MEMORY_OPTIMIZATION) | |
2069 /* This case is if the Sound_Sample has been deleted. | |
2070 * It assumes the data is already at the beginning. | |
2071 */ | |
2072 if(NULL == data->sample) | |
2073 { | |
2074 return 0; | |
2075 } | |
2076 /* Else, the sample has already been reallocated, | |
2077 * and we can fall to normal behavior | |
2078 */ | |
2079 #endif | |
2080 #endif | |
2081 /* If access_data, was enabled, the sound sample | |
2082 * still exists and we can do stuff. | |
2083 * If it's NULL, we can't do anything, but | |
2084 * it should already be "rewound". | |
2085 */ | |
2086 if(NULL == data->sample) | |
2087 { | |
2088 return 0; | |
2089 } | |
2090 /* Else, the sample has already been reallocated, | |
2091 * and we can fall to normal behavior | |
2092 */ | |
2093 | |
2094 Set_Predecoded_Seek_Position(data, 0); | |
2095 /* | |
2096 return data->total_bytes; | |
2097 */ | |
2098 return 0; | |
2099 } | |
2100 | |
2101 /* Remaining stuff for streamed data */ | |
2102 | |
2103 fprintf(stderr, "Rewinding for stream\n"); | |
2104 data->eof = 0; | |
2105 retval = Sound_Rewind(data->sample); | |
2106 if(0 == retval) | |
2107 { | |
2108 ALmixer_SetError( Sound_GetError() ); | |
2109 return -1; | |
2110 } | |
2111 fprintf(stderr, "Rewinding succeeded\n"); | |
2112 fprintf(stderr, "calling GetMoreData for Rewinding for stream\n"); | |
2113 #if 0 | |
2114 /* Clear error */ | |
2115 alGetError(); | |
2116 for(i=0; i<data->num_buffers; i++) | |
2117 { | |
2118 bytes_returned = GetMoreData(data, data->buffer[i]); | |
2119 if(-1 == bytes_returned) | |
2120 { | |
2121 return -1; | |
2122 } | |
2123 else if(0 == bytes_returned) | |
2124 { | |
2125 return -1; | |
2126 } | |
2127 retval += bytes_returned; | |
2128 | |
2129 } | |
2130 #endif | |
2131 | |
2132 | |
2133 fprintf(stderr, "end Rewinding for stream\n"); | |
2134 | |
2135 return retval; | |
2136 } | |
2137 | |
2138 | |
2139 | |
2140 | |
2141 static ALint Internal_RewindChannel(ALint channel) | |
2142 { | |
2143 ALint retval = 0; | |
2144 ALenum error; | |
2145 ALint state; | |
2146 | |
2147 if(channel >= Number_of_Channels_global) | |
2148 { | |
2149 ALmixer_SetError("Cannot rewind channel %d because it exceeds maximum number of channels (%d)\n", channel, Number_of_Channels_global); | |
2150 return -1; | |
2151 } | |
2152 | |
2153 if((error = alGetError()) != AL_NO_ERROR) | |
2154 { | |
2155 fprintf(stderr, "24Testing error: %s\n", | |
2156 alGetString(error)); | |
2157 } | |
2158 /* Clear error */ | |
2159 alGetError(); | |
2160 | |
2161 /* If the user specified a specific channel */ | |
2162 if(channel >= 0) | |
2163 { | |
2164 /* only need to process channel if in use */ | |
2165 if(ALmixer_Channel_List[channel].channel_in_use) | |
2166 { | |
2167 | |
2168 /* What should I do? Do I just rewind the channel | |
2169 * or also rewind the data? Since the data is | |
2170 * shared, let's make it the user's responsibility | |
2171 * to rewind the data. | |
2172 */ | |
2173 if(ALmixer_Channel_List[channel].almixer_data->decoded_all) | |
2174 { | |
2175 alGetSourcei( | |
2176 ALmixer_Channel_List[channel].alsource, | |
2177 AL_SOURCE_STATE, &state | |
2178 ); | |
2179 if((error = alGetError()) != AL_NO_ERROR) | |
2180 { | |
2181 fprintf(stderr, "25Testing error: %s\n", | |
2182 alGetString(error)); | |
2183 } | |
2184 alSourceRewind(ALmixer_Channel_List[channel].alsource); | |
2185 if((error = alGetError()) != AL_NO_ERROR) | |
2186 { | |
2187 ALmixer_SetError("%s", | |
2188 alGetString(error) ); | |
2189 retval = -1; | |
2190 } | |
2191 /* Need to resume playback if it was originally playing */ | |
2192 if(AL_PLAYING == state) | |
2193 { | |
2194 alSourcePlay(ALmixer_Channel_List[channel].alsource); | |
2195 if((error = alGetError()) != AL_NO_ERROR) | |
2196 { | |
2197 ALmixer_SetError("%s", | |
2198 alGetString(error) ); | |
2199 retval = -1; | |
2200 } | |
2201 } | |
2202 else if(AL_PAUSED == state) | |
2203 { | |
2204 /* HACK: The problem is that when paused, after | |
2205 * the Rewind, I can't get it off the INITIAL | |
2206 * state without restarting | |
2207 */ | |
2208 alSourcePlay(ALmixer_Channel_List[channel].alsource); | |
2209 if((error = alGetError()) != AL_NO_ERROR) | |
2210 { | |
2211 fprintf(stderr, "25Testing error: %s\n", | |
2212 alGetString(error)); | |
2213 } | |
2214 alSourcePause(ALmixer_Channel_List[channel].alsource); | |
2215 if((error = alGetError()) != AL_NO_ERROR) | |
2216 { | |
2217 ALmixer_SetError("%s", | |
2218 alGetString(error) ); | |
2219 retval = -1; | |
2220 } | |
2221 } | |
2222 } | |
2223 else | |
2224 { | |
2225 /* Streamed data is different. Rewinding the channel | |
2226 * does no good. Rewinding the data will have an | |
2227 * effect, but it will be lagged based on how | |
2228 * much data is queued. Recommend users call Halt | |
2229 * before rewind if they want immediate results. | |
2230 */ | |
2231 retval = Internal_RewindData(ALmixer_Channel_List[channel].almixer_data); | |
2232 } | |
2233 } | |
2234 } | |
2235 /* The user wants to rewind all channels */ | |
2236 else | |
2237 { | |
2238 ALint i; | |
2239 for(i=0; i<Number_of_Channels_global; i++) | |
2240 { | |
2241 fprintf(stderr, "in use %d\n", ALmixer_Channel_List[i].channel_in_use ); | |
2242 /* only need to process channel if in use */ | |
2243 if(ALmixer_Channel_List[i].channel_in_use) | |
2244 { | |
2245 /* What should I do? Do I just rewind the channel | |
2246 * or also rewind the data? Since the data is | |
2247 * shared, let's make it the user's responsibility | |
2248 * to rewind the data. | |
2249 */ | |
2250 if(ALmixer_Channel_List[i].almixer_data->decoded_all) | |
2251 { | |
2252 alGetSourcei( | |
2253 ALmixer_Channel_List[i].alsource, | |
2254 AL_SOURCE_STATE, &state | |
2255 ); | |
2256 if((error = alGetError()) != AL_NO_ERROR) | |
2257 { | |
2258 fprintf(stderr, "26Testing error: %s\n", | |
2259 alGetString(error)); | |
2260 } | |
2261 alSourceRewind(ALmixer_Channel_List[i].alsource); | |
2262 if((error = alGetError()) != AL_NO_ERROR) | |
2263 { | |
2264 ALmixer_SetError("%s", | |
2265 alGetString(error) ); | |
2266 retval = -1; | |
2267 } | |
2268 /* Need to resume playback if it was originally playing */ | |
2269 if(AL_PLAYING == state) | |
2270 { | |
2271 alSourcePlay(ALmixer_Channel_List[i].alsource); | |
2272 if((error = alGetError()) != AL_NO_ERROR) | |
2273 { | |
2274 ALmixer_SetError("%s", | |
2275 alGetString(error) ); | |
2276 retval = -1; | |
2277 } | |
2278 } | |
2279 else if(AL_PAUSED == state) | |
2280 { | |
2281 /* HACK: The problem is that when paused, after | |
2282 * the Rewind, I can't get it off the INITIAL | |
2283 * state without restarting | |
2284 */ | |
2285 alSourcePlay(ALmixer_Channel_List[i].alsource); | |
2286 if((error = alGetError()) != AL_NO_ERROR) | |
2287 { | |
2288 fprintf(stderr, "27Testing error: %s\n", | |
2289 alGetString(error)); | |
2290 } | |
2291 alSourcePause(ALmixer_Channel_List[i].alsource); | |
2292 if((error = alGetError()) != AL_NO_ERROR) | |
2293 { | |
2294 ALmixer_SetError("%s", | |
2295 alGetString(error) ); | |
2296 retval = -1; | |
2297 } | |
2298 } | |
2299 } | |
2300 else | |
2301 { | |
2302 /* Streamed data is different. Rewinding the channel | |
2303 * does no good. Rewinding the data will have an | |
2304 * effect, but it will be lagged based on how | |
2305 * much data is queued. Recommend users call Halt | |
2306 * before rewind if they want immediate results. | |
2307 */ | |
2308 retval = Internal_RewindData(ALmixer_Channel_List[i].almixer_data); | |
2309 } | |
2310 } | |
2311 } | |
2312 } | |
2313 return retval; | |
2314 } | |
2315 | |
2316 | |
2317 static ALint Internal_RewindSource(ALuint source) | |
2318 { | |
2319 ALint channel; | |
2320 if(0 == source) | |
2321 { | |
2322 return Internal_RewindChannel(-1) + 1; | |
2323 } | |
2324 | |
2325 channel = Internal_GetChannel(source); | |
2326 if(-1 == channel) | |
2327 { | |
2328 ALmixer_SetError("Cannot rewind source: %s", ALmixer_GetError()); | |
2329 return 0; | |
2330 } | |
2331 return Internal_RewindChannel(channel) + 1; | |
2332 } | |
2333 | |
2334 | |
2335 | |
2336 | |
2337 | |
2338 static ALint Internal_PlayChannelTimed(ALint channel, ALmixer_Data* data, ALint loops, ALint ticks) | |
1628 { | 2339 { |
1629 ALenum error; | 2340 ALenum error; |
1630 int ret_flag = 0; | 2341 int ret_flag = 0; |
1631 if(NULL == data) | 2342 if(NULL == data) |
1632 { | 2343 { |
1653 * This mainly affects streamed files, | 2364 * This mainly affects streamed files, |
1654 * so the check is placed here | 2365 * so the check is placed here |
1655 */ | 2366 */ |
1656 if(data->eof) | 2367 if(data->eof) |
1657 { | 2368 { |
1658 if( -1 == ALmixer_RewindData(data) ) | 2369 if( -1 == Internal_RewindData(data) ) |
1659 { | 2370 { |
1660 ALmixer_SetError("Can't play sample because it is at EOF and cannot rewind"); | 2371 ALmixer_SetError("Can't play sample because it is at EOF and cannot rewind"); |
1661 return -1; | 2372 return -1; |
1662 } | 2373 } |
1663 } | 2374 } |
1664 } | 2375 } |
1665 /* We need to provide the user with the first available channel */ | 2376 /* We need to provide the user with the first available channel */ |
1666 if(-1 == channel) | 2377 if(-1 == channel) |
1667 { | 2378 { |
1668 Sint32 i; | 2379 ALint i; |
1669 for(i=Number_of_Reserve_Channels_global; i<Number_of_Channels_global; i++) | 2380 for(i=Number_of_Reserve_Channels_global; i<Number_of_Channels_global; i++) |
1670 { | 2381 { |
1671 if(0 == ALmixer_Channel_List[i].channel_in_use) | 2382 if(0 == ALmixer_Channel_List[i].channel_in_use) |
1672 { | 2383 { |
1673 channel = i; | 2384 channel = i; |
1711 /* Shouldn't need updating until a callback is fired | 2422 /* Shouldn't need updating until a callback is fired |
1712 * (assuming that we call Play in this function | 2423 * (assuming that we call Play in this function |
1713 */ | 2424 */ |
1714 ALmixer_Channel_List[channel].needs_stream = 0; | 2425 ALmixer_Channel_List[channel].needs_stream = 0; |
1715 ALmixer_Channel_List[channel].almixer_data = data; | 2426 ALmixer_Channel_List[channel].almixer_data = data; |
1716 ALmixer_Channel_List[channel].start_time = SDL_GetTicks(); | 2427 ALmixer_Channel_List[channel].start_time = ALmixer_GetTicks(); |
1717 | 2428 |
1718 /* If user entered -1 (or less), set to -1 */ | 2429 /* If user entered -1 (or less), set to -1 */ |
1719 if(ticks < 0) | 2430 if(ticks < 0) |
1720 { | 2431 { |
1721 ALmixer_Channel_List[channel].expire_ticks = -1; | 2432 ALmixer_Channel_List[channel].expire_ticks = -1; |
1740 alSourcei(ALmixer_Channel_List[channel].alsource, AL_LOOPING, AL_FALSE); | 2451 alSourcei(ALmixer_Channel_List[channel].alsource, AL_LOOPING, AL_FALSE); |
1741 } | 2452 } |
1742 if((error = alGetError()) != AL_NO_ERROR) | 2453 if((error = alGetError()) != AL_NO_ERROR) |
1743 { | 2454 { |
1744 fprintf(stderr, "13Testing error: %s\n", | 2455 fprintf(stderr, "13Testing error: %s\n", |
1745 aluGetErrorString(error)); | 2456 alGetString(error)); |
1746 } | 2457 } |
1747 | 2458 |
1748 #if 0 | 2459 #if 0 |
1749 /* Because of the corner case, predecoded | 2460 /* Because of the corner case, predecoded |
1750 * files must add +1 to the loops. | 2461 * files must add +1 to the loops. |
1803 AL_BUFFER, | 2514 AL_BUFFER, |
1804 data->buffer[0]); | 2515 data->buffer[0]); |
1805 if((error = alGetError()) != AL_NO_ERROR) | 2516 if((error = alGetError()) != AL_NO_ERROR) |
1806 { | 2517 { |
1807 ALmixer_SetError("Could not bind data to source: %s", | 2518 ALmixer_SetError("Could not bind data to source: %s", |
1808 aluGetErrorString(error) ); | 2519 alGetString(error) ); |
1809 Clean_Channel(channel); | 2520 Clean_Channel(channel); |
1810 return -1; | 2521 return -1; |
1811 } | 2522 } |
1812 | 2523 |
1813 /* Make data available if access_data is enabled */ | 2524 /* Make data available if access_data is enabled */ |
1815 } | 2526 } |
1816 else | 2527 else |
1817 { | 2528 { |
1818 /* Need to use the streaming buffer for binding */ | 2529 /* Need to use the streaming buffer for binding */ |
1819 | 2530 |
1820 Uint32 bytes_returned; | 2531 ALuint bytes_returned; |
1821 Uint32 j; | 2532 ALuint j; |
1822 data->num_buffers_in_use=0; | 2533 data->num_buffers_in_use=0; |
1823 /****** MODIFICATION must go here *********/ | 2534 /****** MODIFICATION must go here *********/ |
1824 /* Since buffer queuing is pushed off until here to | 2535 /* Since buffer queuing is pushed off until here to |
1825 * avoid buffer conflicts, we must start reading | 2536 * avoid buffer conflicts, we must start reading |
1826 * data here. First we make sure we have at least one | 2537 * data here. First we make sure we have at least one |
1857 bytes_returned = GetMoreData( | 2568 bytes_returned = GetMoreData( |
1858 data, | 2569 data, |
1859 data->buffer[j]); | 2570 data->buffer[j]); |
1860 /* | 2571 /* |
1861 * This might be a problem. I made a mistake with the types. I accidentally | 2572 * This might be a problem. I made a mistake with the types. I accidentally |
1862 * made the bytes returned an Sint32 and returned -1 on error. | 2573 * made the bytes returned an ALint and returned -1 on error. |
1863 * Bytes returned should be a Uint32, so now I no longer have a -1 case | 2574 * Bytes returned should be a ALuint, so now I no longer have a -1 case |
1864 * to check. I hope I didn't break anything here | 2575 * to check. I hope I didn't break anything here |
1865 */ | 2576 */ |
1866 #if 0 | 2577 #if 0 |
1867 if(bytes_returned < 0) | 2578 if(bytes_returned < 0) |
1868 { | 2579 { |
1932 data->num_buffers_in_use, | 2643 data->num_buffers_in_use, |
1933 data->buffer); | 2644 data->buffer); |
1934 if((error = alGetError()) != AL_NO_ERROR) | 2645 if((error = alGetError()) != AL_NO_ERROR) |
1935 { | 2646 { |
1936 ALmixer_SetError("Could not bind data to source: %s", | 2647 ALmixer_SetError("Could not bind data to source: %s", |
1937 aluGetErrorString(error) ); | 2648 alGetString(error) ); |
1938 Clean_Channel(channel); | 2649 Clean_Channel(channel); |
1939 return -1; | 2650 return -1; |
1940 } | 2651 } |
1941 /* This is part of the hideous Nvidia workaround. In order to figure out | 2652 /* This is part of the hideous Nvidia workaround. In order to figure out |
1942 * which buffer to show during callbacks (for things like | 2653 * which buffer to show during callbacks (for things like |
1944 * data structure. This code will be called only if | 2655 * data structure. This code will be called only if |
1945 * "access_data" was set, indicated by whether the queue is NULL. | 2656 * "access_data" was set, indicated by whether the queue is NULL. |
1946 */ | 2657 */ |
1947 if(data->circular_buffer_queue != NULL) | 2658 if(data->circular_buffer_queue != NULL) |
1948 { | 2659 { |
1949 Uint32 k; | 2660 ALuint k; |
1950 Uint32 queue_ret_flag; | 2661 ALuint queue_ret_flag; |
1951 for(k=0; k<data->num_buffers_in_use; k++) | 2662 for(k=0; k<data->num_buffers_in_use; k++) |
1952 { | 2663 { |
2664 // fprintf(stderr, "56c: CircularQueue_PushBack.\n"); | |
1953 queue_ret_flag = CircularQueueUnsignedInt_PushBack(data->circular_buffer_queue, data->buffer[k]); | 2665 queue_ret_flag = CircularQueueUnsignedInt_PushBack(data->circular_buffer_queue, data->buffer[k]); |
1954 if(0 == queue_ret_flag) | 2666 if(0 == queue_ret_flag) |
1955 { | 2667 { |
1956 fprintf(stderr, "Serious internal error: CircularQueue could not push into queue.\n"); | 2668 fprintf(stderr, "Serious internal error: CircularQueue could not push into queue.\n"); |
1957 ALmixer_SetError("Serious internal error: CircularQueue failed to push into queue"); | 2669 ALmixer_SetError("Serious internal error: CircularQueue failed to push into queue"); |
1974 */ | 2686 */ |
1975 alSourcePlay(ALmixer_Channel_List[channel].alsource); | 2687 alSourcePlay(ALmixer_Channel_List[channel].alsource); |
1976 if((error = alGetError()) != AL_NO_ERROR) | 2688 if((error = alGetError()) != AL_NO_ERROR) |
1977 { | 2689 { |
1978 ALmixer_SetError("Play failed: %s", | 2690 ALmixer_SetError("Play failed: %s", |
1979 aluGetErrorString(error) ); | 2691 alGetString(error) ); |
1980 Clean_Channel(channel); | 2692 Clean_Channel(channel); |
1981 return -1; | 2693 return -1; |
1982 } | 2694 } |
1983 | 2695 |
1984 /* Add to the counter that something is playing */ | 2696 /* Add to the counter that something is playing */ |
2002 * first available channels because source and channels have | 2714 * first available channels because source and channels have |
2003 * a one-to-one mapping in this API. It is quite easy for | 2715 * a one-to-one mapping in this API. It is quite easy for |
2004 * a channel/source to already be in use because of this. | 2716 * a channel/source to already be in use because of this. |
2005 * In this event, an error message will be returned to you. | 2717 * In this event, an error message will be returned to you. |
2006 */ | 2718 */ |
2007 static ALuint Internal_PlaySourceTimed(ALuint source, ALmixer_Data* data, Sint32 loops, Sint32 ticks) | 2719 static ALuint Internal_PlaySourceTimed(ALuint source, ALmixer_Data* data, ALint loops, ALint ticks) |
2008 { | 2720 { |
2009 Sint32 channel; | 2721 ALint channel; |
2010 Sint32 retval; | 2722 ALint retval; |
2011 if(0 == source) | 2723 if(0 == source) |
2012 { | 2724 { |
2013 retval = Internal_PlayChannelTimed(-1, data, loops, ticks); | 2725 retval = Internal_PlayChannelTimed(-1, data, loops, ticks); |
2014 if(-1 == retval) | 2726 if(-1 == retval) |
2015 { | 2727 { |
2040 return 0; | 2752 return 0; |
2041 } | 2753 } |
2042 | 2754 |
2043 | 2755 |
2044 | 2756 |
2045 /* Will return the number of channels halted | 2757 |
2046 * or 0 for error | 2758 /* Returns the channel or number of channels actually paused */ |
2047 */ | 2759 |
2048 static Sint32 Internal_HaltChannel(Sint32 channel) | 2760 static ALint Internal_PauseChannel(ALint channel) |
2049 { | 2761 { |
2050 Sint32 retval = 0; | |
2051 Sint32 counter = 0; | |
2052 ALenum error; | |
2053 ALint buffers_still_queued; | |
2054 ALint buffers_processed; | |
2055 | |
2056 if(channel >= Number_of_Channels_global) | |
2057 { | |
2058 ALmixer_SetError("Cannot halt channel %d because it exceeds maximum number of channels (%d)\n", channel, Number_of_Channels_global); | |
2059 return -1; | |
2060 } | |
2061 /* If the user specified a specific channel */ | |
2062 if(channel >= 0) | |
2063 { | |
2064 fprintf(stderr, "Halt on channel %d\n", channel); | |
2065 /* only need to process channel if in use */ | |
2066 if(ALmixer_Channel_List[channel].channel_in_use) | |
2067 { | |
2068 alSourceStop(ALmixer_Channel_List[channel].alsource); | |
2069 if((error = alGetError()) != AL_NO_ERROR) | |
2070 { | |
2071 fprintf(stderr, "14Testing error: %s\n", | |
2072 aluGetErrorString(error)); | |
2073 } | |
2074 /* Here's the situation. My old method of using | |
2075 * alSourceUnqueueBuffers() seemed to be invalid in light | |
2076 * of all the problems I suffered through with getting | |
2077 * the CoreData backend to work with this code. | |
2078 * As such, I'm changing all the code to set the buffer to | |
2079 * AL_NONE. Furthermore, the queued vs. non-queued issue | |
2080 * doesn't need to apply here. For non-queued, Loki, | |
2081 * Creative Windows, and CoreAudio seem to leave the | |
2082 * buffer queued (Old Mac didn't.) For queued, we need to | |
2083 * remove the processed buffers and force remove the | |
2084 * still-queued buffers. | |
2085 */ | |
2086 fprintf(stderr, "Halt on channel %d, channel in use\n", channel); | |
2087 alGetSourcei( | |
2088 ALmixer_Channel_List[channel].alsource, | |
2089 AL_BUFFERS_QUEUED, &buffers_still_queued | |
2090 ); | |
2091 if((error = alGetError()) != AL_NO_ERROR) | |
2092 { | |
2093 fprintf(stderr, "17Testing Error with buffers_still_queued: %s", | |
2094 aluGetErrorString(error)); | |
2095 ALmixer_SetError("Failed detecting still queued buffers: %s", | |
2096 aluGetErrorString(error) ); | |
2097 retval = -1; | |
2098 } | |
2099 alGetSourcei( | |
2100 ALmixer_Channel_List[channel].alsource, | |
2101 AL_BUFFERS_PROCESSED, &buffers_processed | |
2102 ); | |
2103 if((error = alGetError()) != AL_NO_ERROR) | |
2104 { | |
2105 fprintf(stderr, "17Testing Error with buffers_processed: %s", | |
2106 aluGetErrorString(error)); | |
2107 ALmixer_SetError("Failed detecting still processed buffers: %s", | |
2108 aluGetErrorString(error) ); | |
2109 retval = -1; | |
2110 } | |
2111 /* If either of these is greater than 0, it means we need | |
2112 * to clear the source | |
2113 */ | |
2114 if((buffers_still_queued > 0) || (buffers_processed > 0)) | |
2115 { | |
2116 alSourcei(ALmixer_Channel_List[channel].alsource, | |
2117 AL_BUFFER, | |
2118 AL_NONE); | |
2119 if((error = alGetError()) != AL_NO_ERROR) | |
2120 { | |
2121 fprintf(stderr, "17Testing Error with clearing buffer from source: %s", | |
2122 aluGetErrorString(error)); | |
2123 ALmixer_SetError("Failed to clear buffer from source: %s", | |
2124 aluGetErrorString(error) ); | |
2125 retval = -1; | |
2126 } | |
2127 } | |
2128 | |
2129 ALmixer_Channel_List[channel].almixer_data->num_buffers_in_use = 0; | |
2130 | |
2131 Clean_Channel(channel); | |
2132 Is_Playing_global--; | |
2133 /* Launch callback for consistency? */ | |
2134 Invoke_Channel_Done_Callback(channel); | |
2135 counter++; | |
2136 } | |
2137 } | |
2138 /* The user wants to halt all channels */ | |
2139 else | |
2140 { | |
2141 Sint32 i; | |
2142 for(i=0; i<Number_of_Channels_global; i++) | |
2143 { | |
2144 fprintf(stderr, "Halting channel %d\n", i); | |
2145 fprintf(stderr, "in use %d\n", ALmixer_Channel_List[i].channel_in_use ); | |
2146 /* only need to process channel if in use */ | |
2147 if(ALmixer_Channel_List[i].channel_in_use) | |
2148 { | |
2149 fprintf(stderr, "SourceStop %d\n", i); | |
2150 alSourceStop(ALmixer_Channel_List[i].alsource); | |
2151 if((error = alGetError()) != AL_NO_ERROR) | |
2152 { | |
2153 fprintf(stderr, "19Testing error: %s\n", | |
2154 aluGetErrorString(error)); | |
2155 } | |
2156 | |
2157 /* Here's the situation. My old method of using | |
2158 * alSourceUnqueueBuffers() seemed to be invalid in light | |
2159 * of all the problems I suffered through with getting | |
2160 * the CoreData backend to work with this code. | |
2161 * As such, I'm changing all the code to set the buffer to | |
2162 * AL_NONE. Furthermore, the queued vs. non-queued issue | |
2163 * doesn't need to apply here. For non-queued, Loki, | |
2164 * Creative Windows, and CoreAudio seem to leave the | |
2165 * buffer queued (Old Mac didn't.) For queued, we need to | |
2166 * remove the processed buffers and force remove the | |
2167 * still-queued buffers. | |
2168 */ | |
2169 fprintf(stderr, "Halt on channel %d, channel in use\n", channel); | |
2170 alGetSourcei( | |
2171 ALmixer_Channel_List[i].alsource, | |
2172 AL_BUFFERS_QUEUED, &buffers_still_queued | |
2173 ); | |
2174 if((error = alGetError()) != AL_NO_ERROR) | |
2175 { | |
2176 fprintf(stderr, "17Testing Error with buffers_still_queued: %s", | |
2177 aluGetErrorString(error)); | |
2178 ALmixer_SetError("Failed detecting still queued buffers: %s", | |
2179 aluGetErrorString(error) ); | |
2180 retval = -1; | |
2181 } | |
2182 alGetSourcei( | |
2183 ALmixer_Channel_List[i].alsource, | |
2184 AL_BUFFERS_PROCESSED, &buffers_processed | |
2185 ); | |
2186 if((error = alGetError()) != AL_NO_ERROR) | |
2187 { | |
2188 fprintf(stderr, "17Testing Error with buffers_processed: %s", | |
2189 aluGetErrorString(error)); | |
2190 ALmixer_SetError("Failed detecting still processed buffers: %s", | |
2191 aluGetErrorString(error) ); | |
2192 retval = -1; | |
2193 } | |
2194 /* If either of these is greater than 0, it means we need | |
2195 * to clear the source | |
2196 */ | |
2197 if((buffers_still_queued > 0) || (buffers_processed > 0)) | |
2198 { | |
2199 alSourcei(ALmixer_Channel_List[i].alsource, | |
2200 AL_BUFFER, | |
2201 AL_NONE); | |
2202 if((error = alGetError()) != AL_NO_ERROR) | |
2203 { | |
2204 fprintf(stderr, "17Testing Error with clearing buffer from source: %s", | |
2205 aluGetErrorString(error)); | |
2206 ALmixer_SetError("Failed to clear buffer from source: %s", | |
2207 aluGetErrorString(error) ); | |
2208 retval = -1; | |
2209 } | |
2210 } | |
2211 | |
2212 ALmixer_Channel_List[i].almixer_data->num_buffers_in_use = 0; | |
2213 | |
2214 fprintf(stderr, "Clean channel %d\n", i); | |
2215 Clean_Channel(i); | |
2216 Is_Playing_global--; | |
2217 /* Launch callback for consistency? */ | |
2218 fprintf(stderr, "Callback%d\n", i); | |
2219 Invoke_Channel_Done_Callback(i); | |
2220 | |
2221 /* Increment the counter */ | |
2222 counter++; | |
2223 } | |
2224 /* Let's halt everything just in case there | |
2225 * are bugs. | |
2226 */ | |
2227 /* | |
2228 else | |
2229 { | |
2230 alSourceStop(ALmixer_Channel_List[channel].alsource); | |
2231 / * Can't clean because the in_use counter for | |
2232 * data will get messed up * / | |
2233 Clean_Channel(channel); | |
2234 } | |
2235 */ | |
2236 /* Just in case */ | |
2237 Is_Playing_global = 0; | |
2238 } | |
2239 } | |
2240 if(-1 == retval) | |
2241 { | |
2242 return -1; | |
2243 } | |
2244 return counter; | |
2245 } | |
2246 | |
2247 | |
2248 /* Will return the source halted or the total number of channels | |
2249 * if all were halted or 0 for error | |
2250 */ | |
2251 static Sint32 Internal_HaltSource(ALuint source) | |
2252 { | |
2253 Sint32 channel; | |
2254 if(0 == source) | |
2255 { | |
2256 /* Will return the number of sources halted */ | |
2257 return Internal_HaltChannel(-1); | |
2258 } | |
2259 | |
2260 channel = Internal_GetChannel(source); | |
2261 if(-1 == channel) | |
2262 { | |
2263 ALmixer_SetError("Cannot halt source: %s", ALmixer_GetError()); | |
2264 return 0; | |
2265 } | |
2266 return Internal_HaltChannel(channel); | |
2267 } | |
2268 | |
2269 | |
2270 /* This will rewind the SDL_Sound sample for streamed | |
2271 * samples and start buffering up the data for the next | |
2272 * playback. This may require samples to be halted | |
2273 */ | |
2274 static Sint32 Internal_RewindData(ALmixer_Data* data) | |
2275 { | |
2276 Sint32 retval = 0; | |
2277 /* | |
2278 Sint32 bytes_returned; | |
2279 Sint32 i; | |
2280 */ | |
2281 if(NULL == data) | |
2282 { | |
2283 ALmixer_SetError("Cannot rewind because data is NULL\n"); | |
2284 return -1; | |
2285 } | |
2286 | |
2287 | |
2288 /* Might have to require Halt */ | |
2289 /* Okay, we assume Halt or natural stop has already | |
2290 * cleared the data buffers | |
2291 */ | |
2292 if(data->in_use) | |
2293 { | |
2294 fprintf(stderr, "Warning sample is in use. May not be able to rewind\n"); | |
2295 /* | |
2296 ALmixer_SetError("Data is in use. Cannot rewind unless all sources using the data are halted\n"); | |
2297 return -1; | |
2298 */ | |
2299 } | |
2300 | |
2301 | |
2302 /* Because Seek can alter things even in predecoded data, | |
2303 * decoded data must also be rewound | |
2304 */ | |
2305 if(data->decoded_all) | |
2306 { | |
2307 data->eof = 0; | |
2308 | |
2309 #if 0 | |
2310 #if defined(DISABLE_PREDECODED_SEEK) | |
2311 /* Since we can't seek predecoded stuff, it should be rewound */ | |
2312 return 0; | |
2313 #elif !defined(DISABLE_SEEK_MEMORY_OPTIMIZATION) | |
2314 /* This case is if the Sound_Sample has been deleted. | |
2315 * It assumes the data is already at the beginning. | |
2316 */ | |
2317 if(NULL == data->sample) | |
2318 { | |
2319 return 0; | |
2320 } | |
2321 /* Else, the sample has already been reallocated, | |
2322 * and we can fall to normal behavior | |
2323 */ | |
2324 #endif | |
2325 #endif | |
2326 /* If access_data, was enabled, the sound sample | |
2327 * still exists and we can do stuff. | |
2328 * If it's NULL, we can't do anything, but | |
2329 * it should already be "rewound". | |
2330 */ | |
2331 if(NULL == data->sample) | |
2332 { | |
2333 return 0; | |
2334 } | |
2335 /* Else, the sample has already been reallocated, | |
2336 * and we can fall to normal behavior | |
2337 */ | |
2338 | |
2339 Set_Predecoded_Seek_Position(data, 0); | |
2340 /* | |
2341 return data->total_bytes; | |
2342 */ | |
2343 return 0; | |
2344 } | |
2345 | |
2346 /* Remaining stuff for streamed data */ | |
2347 | |
2348 fprintf(stderr, "Rewinding for stream\n"); | |
2349 data->eof = 0; | |
2350 retval = Sound_Rewind(data->sample); | |
2351 if(0 == retval) | |
2352 { | |
2353 ALmixer_SetError( Sound_GetError() ); | |
2354 return -1; | |
2355 } | |
2356 fprintf(stderr, "Rewinding succeeded\n"); | |
2357 fprintf(stderr, "calling GetMoreData for Rewinding for stream\n"); | |
2358 #if 0 | |
2359 /* Clear error */ | |
2360 alGetError(); | |
2361 for(i=0; i<data->num_buffers; i++) | |
2362 { | |
2363 bytes_returned = GetMoreData(data, data->buffer[i]); | |
2364 if(-1 == bytes_returned) | |
2365 { | |
2366 return -1; | |
2367 } | |
2368 else if(0 == bytes_returned) | |
2369 { | |
2370 return -1; | |
2371 } | |
2372 retval += bytes_returned; | |
2373 | |
2374 } | |
2375 #endif | |
2376 | |
2377 | |
2378 fprintf(stderr, "end Rewinding for stream\n"); | |
2379 | |
2380 return retval; | |
2381 } | |
2382 | |
2383 | |
2384 | |
2385 | |
2386 static Sint32 Internal_RewindChannel(Sint32 channel) | |
2387 { | |
2388 Sint32 retval = 0; | |
2389 ALenum error; | 2762 ALenum error; |
2390 ALint state; | 2763 ALint state; |
2391 | 2764 ALint retval = 0; |
2392 if(channel >= Number_of_Channels_global) | 2765 ALint counter = 0; |
2393 { | |
2394 ALmixer_SetError("Cannot rewind channel %d because it exceeds maximum number of channels (%d)\n", channel, Number_of_Channels_global); | |
2395 return -1; | |
2396 } | |
2397 | |
2398 if((error = alGetError()) != AL_NO_ERROR) | |
2399 { | |
2400 fprintf(stderr, "24Testing error: %s\n", | |
2401 aluGetErrorString(error)); | |
2402 } | |
2403 /* Clear error */ | |
2404 alGetError(); | |
2405 | |
2406 /* If the user specified a specific channel */ | |
2407 if(channel >= 0) | |
2408 { | |
2409 /* only need to process channel if in use */ | |
2410 if(ALmixer_Channel_List[channel].channel_in_use) | |
2411 { | |
2412 | |
2413 /* What should I do? Do I just rewind the channel | |
2414 * or also rewind the data? Since the data is | |
2415 * shared, let's make it the user's responsibility | |
2416 * to rewind the data. | |
2417 */ | |
2418 if(ALmixer_Channel_List[channel].almixer_data->decoded_all) | |
2419 { | |
2420 alGetSourcei( | |
2421 ALmixer_Channel_List[channel].alsource, | |
2422 AL_SOURCE_STATE, &state | |
2423 ); | |
2424 if((error = alGetError()) != AL_NO_ERROR) | |
2425 { | |
2426 fprintf(stderr, "25Testing error: %s\n", | |
2427 aluGetErrorString(error)); | |
2428 } | |
2429 alSourceRewind(ALmixer_Channel_List[channel].alsource); | |
2430 if((error = alGetError()) != AL_NO_ERROR) | |
2431 { | |
2432 ALmixer_SetError("%s", | |
2433 aluGetErrorString(error) ); | |
2434 retval = -1; | |
2435 } | |
2436 /* Need to resume playback if it was originally playing */ | |
2437 if(AL_PLAYING == state) | |
2438 { | |
2439 alSourcePlay(ALmixer_Channel_List[channel].alsource); | |
2440 if((error = alGetError()) != AL_NO_ERROR) | |
2441 { | |
2442 ALmixer_SetError("%s", | |
2443 aluGetErrorString(error) ); | |
2444 retval = -1; | |
2445 } | |
2446 } | |
2447 else if(AL_PAUSED == state) | |
2448 { | |
2449 /* HACK: The problem is that when paused, after | |
2450 * the Rewind, I can't get it off the INITIAL | |
2451 * state without restarting | |
2452 */ | |
2453 alSourcePlay(ALmixer_Channel_List[channel].alsource); | |
2454 if((error = alGetError()) != AL_NO_ERROR) | |
2455 { | |
2456 fprintf(stderr, "25Testing error: %s\n", | |
2457 aluGetErrorString(error)); | |
2458 } | |
2459 alSourcePause(ALmixer_Channel_List[channel].alsource); | |
2460 if((error = alGetError()) != AL_NO_ERROR) | |
2461 { | |
2462 ALmixer_SetError("%s", | |
2463 aluGetErrorString(error) ); | |
2464 retval = -1; | |
2465 } | |
2466 } | |
2467 } | |
2468 else | |
2469 { | |
2470 /* Streamed data is different. Rewinding the channel | |
2471 * does no good. Rewinding the data will have an | |
2472 * effect, but it will be lagged based on how | |
2473 * much data is queued. Recommend users call Halt | |
2474 * before rewind if they want immediate results. | |
2475 */ | |
2476 retval = Internal_RewindData(ALmixer_Channel_List[channel].almixer_data); | |
2477 } | |
2478 } | |
2479 } | |
2480 /* The user wants to halt all channels */ | |
2481 else | |
2482 { | |
2483 Sint32 i; | |
2484 for(i=0; i<Number_of_Channels_global; i++) | |
2485 { | |
2486 fprintf(stderr, "in use %d\n", ALmixer_Channel_List[i].channel_in_use ); | |
2487 /* only need to process channel if in use */ | |
2488 if(ALmixer_Channel_List[i].channel_in_use) | |
2489 { | |
2490 /* What should I do? Do I just rewind the channel | |
2491 * or also rewind the data? Since the data is | |
2492 * shared, let's make it the user's responsibility | |
2493 * to rewind the data. | |
2494 */ | |
2495 if(ALmixer_Channel_List[i].almixer_data->decoded_all) | |
2496 { | |
2497 alGetSourcei( | |
2498 ALmixer_Channel_List[i].alsource, | |
2499 AL_SOURCE_STATE, &state | |
2500 ); | |
2501 if((error = alGetError()) != AL_NO_ERROR) | |
2502 { | |
2503 fprintf(stderr, "26Testing error: %s\n", | |
2504 aluGetErrorString(error)); | |
2505 } | |
2506 alSourceRewind(ALmixer_Channel_List[i].alsource); | |
2507 if((error = alGetError()) != AL_NO_ERROR) | |
2508 { | |
2509 ALmixer_SetError("%s", | |
2510 aluGetErrorString(error) ); | |
2511 retval = -1; | |
2512 } | |
2513 /* Need to resume playback if it was originally playing */ | |
2514 if(AL_PLAYING == state) | |
2515 { | |
2516 alSourcePlay(ALmixer_Channel_List[i].alsource); | |
2517 if((error = alGetError()) != AL_NO_ERROR) | |
2518 { | |
2519 ALmixer_SetError("%s", | |
2520 aluGetErrorString(error) ); | |
2521 retval = -1; | |
2522 } | |
2523 } | |
2524 else if(AL_PAUSED == state) | |
2525 { | |
2526 /* HACK: The problem is that when paused, after | |
2527 * the Rewind, I can't get it off the INITIAL | |
2528 * state without restarting | |
2529 */ | |
2530 alSourcePlay(ALmixer_Channel_List[i].alsource); | |
2531 if((error = alGetError()) != AL_NO_ERROR) | |
2532 { | |
2533 fprintf(stderr, "27Testing error: %s\n", | |
2534 aluGetErrorString(error)); | |
2535 } | |
2536 alSourcePause(ALmixer_Channel_List[i].alsource); | |
2537 if((error = alGetError()) != AL_NO_ERROR) | |
2538 { | |
2539 ALmixer_SetError("%s", | |
2540 aluGetErrorString(error) ); | |
2541 retval = -1; | |
2542 } | |
2543 } | |
2544 } | |
2545 else | |
2546 { | |
2547 /* Streamed data is different. Rewinding the channel | |
2548 * does no good. Rewinding the data will have an | |
2549 * effect, but it will be lagged based on how | |
2550 * much data is queued. Recommend users call Halt | |
2551 * before rewind if they want immediate results. | |
2552 */ | |
2553 retval = Internal_RewindData(ALmixer_Channel_List[i].almixer_data); | |
2554 } | |
2555 } | |
2556 } | |
2557 } | |
2558 return retval; | |
2559 } | |
2560 | |
2561 | |
2562 static Sint32 Internal_RewindSource(ALuint source) | |
2563 { | |
2564 Sint32 channel; | |
2565 if(0 == source) | |
2566 { | |
2567 return Internal_RewindChannel(-1); | |
2568 } | |
2569 | |
2570 channel = Internal_GetChannel(source); | |
2571 if(-1 == channel) | |
2572 { | |
2573 ALmixer_SetError("Cannot rewind source: %s", ALmixer_GetError()); | |
2574 return 0; | |
2575 } | |
2576 return Internal_RewindChannel(channel); | |
2577 } | |
2578 | |
2579 | |
2580 | |
2581 /* Returns the channel or number of channels actually paused */ | |
2582 | |
2583 static Sint32 Internal_PauseChannel(Sint32 channel) | |
2584 { | |
2585 ALenum error; | |
2586 ALint state; | |
2587 Sint32 retval = 0; | |
2588 Sint32 counter = 0; | |
2589 | 2766 |
2590 if(channel >= Number_of_Channels_global) | 2767 if(channel >= Number_of_Channels_global) |
2591 { | 2768 { |
2592 ALmixer_SetError("Cannot pause channel %d because it exceeds maximum number of channels (%d)\n", channel, Number_of_Channels_global); | 2769 ALmixer_SetError("Cannot pause channel %d because it exceeds maximum number of channels (%d)\n", channel, Number_of_Channels_global); |
2593 return -1; | 2770 return -1; |
2594 } | 2771 } |
2595 | 2772 |
2596 if((error = alGetError()) != AL_NO_ERROR) | 2773 if((error = alGetError()) != AL_NO_ERROR) |
2597 { | 2774 { |
2598 fprintf(stderr, "28Testing error: %s\n", | 2775 fprintf(stderr, "28Testing error: %s\n", |
2599 aluGetErrorString(error)); | 2776 alGetString(error)); |
2600 } | 2777 } |
2601 /* Clear error */ | 2778 /* Clear error */ |
2602 alGetError(); | 2779 alGetError(); |
2603 | 2780 |
2604 /* If the user specified a specific channel */ | 2781 /* If the user specified a specific channel */ |
2617 AL_SOURCE_STATE, &state | 2794 AL_SOURCE_STATE, &state |
2618 ); | 2795 ); |
2619 if((error = alGetError()) != AL_NO_ERROR) | 2796 if((error = alGetError()) != AL_NO_ERROR) |
2620 { | 2797 { |
2621 fprintf(stderr, "29Testing error: %s\n", | 2798 fprintf(stderr, "29Testing error: %s\n", |
2622 aluGetErrorString(error)); | 2799 alGetString(error)); |
2623 } | 2800 } |
2624 if(AL_PLAYING == state) | 2801 if(AL_PLAYING == state) |
2625 { | 2802 { |
2626 /* Count the actual number of channels being paused */ | 2803 /* Count the actual number of channels being paused */ |
2627 counter++; | 2804 counter++; |
2628 | 2805 |
2629 alSourcePause(ALmixer_Channel_List[channel].alsource); | 2806 alSourcePause(ALmixer_Channel_List[channel].alsource); |
2630 if((error = alGetError()) != AL_NO_ERROR) | 2807 if((error = alGetError()) != AL_NO_ERROR) |
2631 { | 2808 { |
2632 ALmixer_SetError("%s", | 2809 ALmixer_SetError("%s", |
2633 aluGetErrorString(error) ); | 2810 alGetString(error) ); |
2634 retval = -1; | 2811 retval = -1; |
2635 } | 2812 } |
2636 /* We need to pause the expire time count down */ | 2813 /* We need to pause the expire time count down */ |
2637 if(ALmixer_Channel_List[channel].expire_ticks != -1) | 2814 if(ALmixer_Channel_List[channel].expire_ticks != -1) |
2638 { | 2815 { |
2639 Uint32 current_time = SDL_GetTicks(); | 2816 ALuint current_time = ALmixer_GetTicks(); |
2640 Uint32 diff_time; | 2817 ALuint diff_time; |
2641 diff_time = current_time - | 2818 diff_time = current_time - |
2642 ALmixer_Channel_List[channel].start_time; | 2819 ALmixer_Channel_List[channel].start_time; |
2643 /* When we unpause, we will want to reset | 2820 /* When we unpause, we will want to reset |
2644 * the start time so we can continue | 2821 * the start time so we can continue |
2645 * to base calculations off GetTicks(). | 2822 * to base calculations off GetTicks(). |
2658 } | 2835 } |
2659 } | 2836 } |
2660 /* Do the same as expire time for fading */ | 2837 /* Do the same as expire time for fading */ |
2661 if(ALmixer_Channel_List[channel].fade_enabled) | 2838 if(ALmixer_Channel_List[channel].fade_enabled) |
2662 { | 2839 { |
2663 Uint32 current_time = SDL_GetTicks(); | 2840 ALuint current_time = ALmixer_GetTicks(); |
2664 Uint32 diff_time; | 2841 ALuint diff_time; |
2665 diff_time = current_time - | 2842 diff_time = current_time - |
2666 ALmixer_Channel_List[channel].fade_start_time; | 2843 ALmixer_Channel_List[channel].fade_start_time; |
2667 /* When we unpause, we will want to reset | 2844 /* When we unpause, we will want to reset |
2668 * the start time so we can continue | 2845 * the start time so we can continue |
2669 * to base calculations off GetTicks(). | 2846 * to base calculations off GetTicks(). |
2683 } /* End If in use */ | 2860 } /* End If in use */ |
2684 } /* End specific channel */ | 2861 } /* End specific channel */ |
2685 /* The user wants to halt all channels */ | 2862 /* The user wants to halt all channels */ |
2686 else | 2863 else |
2687 { | 2864 { |
2688 Sint32 i; | 2865 ALint i; |
2689 for(i=0; i<Number_of_Channels_global; i++) | 2866 for(i=0; i<Number_of_Channels_global; i++) |
2690 { | 2867 { |
2691 fprintf(stderr, "Pausing channel %d\n", i); | 2868 fprintf(stderr, "Pausing channel %d\n", i); |
2692 fprintf(stderr, "in use %d\n", ALmixer_Channel_List[i].channel_in_use ); | 2869 fprintf(stderr, "in use %d\n", ALmixer_Channel_List[i].channel_in_use ); |
2693 /* only need to process channel if in use */ | 2870 /* only need to process channel if in use */ |
2702 AL_SOURCE_STATE, &state | 2879 AL_SOURCE_STATE, &state |
2703 ); | 2880 ); |
2704 if((error = alGetError()) != AL_NO_ERROR) | 2881 if((error = alGetError()) != AL_NO_ERROR) |
2705 { | 2882 { |
2706 fprintf(stderr, "30Testing error: %s\n", | 2883 fprintf(stderr, "30Testing error: %s\n", |
2707 aluGetErrorString(error)); | 2884 alGetString(error)); |
2708 } | 2885 } |
2709 if(AL_PLAYING == state) | 2886 if(AL_PLAYING == state) |
2710 { | 2887 { |
2711 /* Count the actual number of channels being paused */ | 2888 /* Count the actual number of channels being paused */ |
2712 counter++; | 2889 counter++; |
2714 fprintf(stderr, "SourcePause %d\n", i); | 2891 fprintf(stderr, "SourcePause %d\n", i); |
2715 alSourcePause(ALmixer_Channel_List[i].alsource); | 2892 alSourcePause(ALmixer_Channel_List[i].alsource); |
2716 if((error = alGetError()) != AL_NO_ERROR) | 2893 if((error = alGetError()) != AL_NO_ERROR) |
2717 { | 2894 { |
2718 ALmixer_SetError("%s", | 2895 ALmixer_SetError("%s", |
2719 aluGetErrorString(error) ); | 2896 alGetString(error) ); |
2720 retval = -1; | 2897 retval = -1; |
2721 } | 2898 } |
2722 /* We need to pause the expire time count down */ | 2899 /* We need to pause the expire time count down */ |
2723 if(ALmixer_Channel_List[i].expire_ticks != -1) | 2900 if(ALmixer_Channel_List[i].expire_ticks != -1) |
2724 { | 2901 { |
2725 Uint32 current_time = SDL_GetTicks(); | 2902 ALuint current_time = ALmixer_GetTicks(); |
2726 Uint32 diff_time; | 2903 ALuint diff_time; |
2727 diff_time = current_time - | 2904 diff_time = current_time - |
2728 ALmixer_Channel_List[i].start_time; | 2905 ALmixer_Channel_List[i].start_time; |
2729 /* When we unpause, we will want to reset | 2906 /* When we unpause, we will want to reset |
2730 * the start time so we can continue | 2907 * the start time so we can continue |
2731 * to base calculations off GetTicks(). | 2908 * to base calculations off GetTicks(). |
2744 } | 2921 } |
2745 } | 2922 } |
2746 /* Do the same as expire time for fading */ | 2923 /* Do the same as expire time for fading */ |
2747 if(ALmixer_Channel_List[i].fade_enabled) | 2924 if(ALmixer_Channel_List[i].fade_enabled) |
2748 { | 2925 { |
2749 Uint32 current_time = SDL_GetTicks(); | 2926 ALuint current_time = ALmixer_GetTicks(); |
2750 Uint32 diff_time; | 2927 ALuint diff_time; |
2751 diff_time = current_time - | 2928 diff_time = current_time - |
2752 ALmixer_Channel_List[i].fade_start_time; | 2929 ALmixer_Channel_List[i].fade_start_time; |
2753 /* When we unpause, we will want to reset | 2930 /* When we unpause, we will want to reset |
2754 * the start time so we can continue | 2931 * the start time so we can continue |
2755 * to base calculations off GetTicks(). | 2932 * to base calculations off GetTicks(). |
2775 } | 2952 } |
2776 return counter; | 2953 return counter; |
2777 } | 2954 } |
2778 | 2955 |
2779 /* Returns the channel or number of channels actually paused */ | 2956 /* Returns the channel or number of channels actually paused */ |
2780 static Sint32 Internal_PauseSource(ALuint source) | 2957 static ALint Internal_PauseSource(ALuint source) |
2781 { | 2958 { |
2782 Sint32 channel; | 2959 ALint channel; |
2783 if(0 == source) | 2960 if(0 == source) |
2784 { | 2961 { |
2785 return Internal_PauseChannel(-1); | 2962 return Internal_PauseChannel(-1); |
2786 } | 2963 } |
2787 | 2964 |
2794 return Internal_PauseChannel(channel); | 2971 return Internal_PauseChannel(channel); |
2795 } | 2972 } |
2796 | 2973 |
2797 | 2974 |
2798 | 2975 |
2799 static Sint32 Internal_ResumeChannel(Sint32 channel) | 2976 static ALint Internal_ResumeChannel(ALint channel) |
2800 { | 2977 { |
2801 ALint state; | 2978 ALint state; |
2802 ALenum error; | 2979 ALenum error; |
2803 Sint32 retval = 0; | 2980 ALint retval = 0; |
2804 Sint32 counter = 0; | 2981 ALint counter = 0; |
2805 | 2982 |
2806 if(channel >= Number_of_Channels_global) | 2983 if(channel >= Number_of_Channels_global) |
2807 { | 2984 { |
2808 ALmixer_SetError("Cannot pause channel %d because it exceeds maximum number of channels (%d)\n", channel, Number_of_Channels_global); | 2985 ALmixer_SetError("Cannot pause channel %d because it exceeds maximum number of channels (%d)\n", channel, Number_of_Channels_global); |
2809 return -1; | 2986 return -1; |
2810 } | 2987 } |
2811 | 2988 |
2812 if((error = alGetError()) != AL_NO_ERROR) | 2989 if((error = alGetError()) != AL_NO_ERROR) |
2813 { | 2990 { |
2814 fprintf(stderr, "31Testing error: %s\n", | 2991 fprintf(stderr, "31Testing error: %s\n", |
2815 aluGetErrorString(error)); | 2992 alGetString(error)); |
2816 } | 2993 } |
2817 /* Clear error */ | 2994 /* Clear error */ |
2818 alGetError(); | 2995 alGetError(); |
2819 | 2996 |
2820 /* If the user specified a specific channel */ | 2997 /* If the user specified a specific channel */ |
2829 AL_SOURCE_STATE, &state | 3006 AL_SOURCE_STATE, &state |
2830 ); | 3007 ); |
2831 if((error = alGetError()) != AL_NO_ERROR) | 3008 if((error = alGetError()) != AL_NO_ERROR) |
2832 { | 3009 { |
2833 fprintf(stderr, "32Testing error: %s\n", | 3010 fprintf(stderr, "32Testing error: %s\n", |
2834 aluGetErrorString(error)); | 3011 alGetString(error)); |
2835 } | 3012 } |
2836 if(AL_PAUSED == state) | 3013 if(AL_PAUSED == state) |
2837 { | 3014 { |
2838 /* Count the actual number of channels resumed */ | 3015 /* Count the actual number of channels resumed */ |
2839 counter++; | 3016 counter++; |
2840 | 3017 |
2841 /* We need to resume the expire time count down */ | 3018 /* We need to resume the expire time count down */ |
2842 if(ALmixer_Channel_List[channel].expire_ticks != -1) | 3019 if(ALmixer_Channel_List[channel].expire_ticks != -1) |
2843 { | 3020 { |
2844 ALmixer_Channel_List[channel].start_time = SDL_GetTicks(); | 3021 ALmixer_Channel_List[channel].start_time = ALmixer_GetTicks(); |
2845 } | 3022 } |
2846 /* Do the same as expire time for fading */ | 3023 /* Do the same as expire time for fading */ |
2847 if(ALmixer_Channel_List[channel].fade_enabled) | 3024 if(ALmixer_Channel_List[channel].fade_enabled) |
2848 { | 3025 { |
2849 ALmixer_Channel_List[channel].fade_start_time = SDL_GetTicks(); | 3026 ALmixer_Channel_List[channel].fade_start_time = ALmixer_GetTicks(); |
2850 } | 3027 } |
2851 | 3028 |
2852 alSourcePlay(ALmixer_Channel_List[channel].alsource); | 3029 alSourcePlay(ALmixer_Channel_List[channel].alsource); |
2853 if((error = alGetError()) != AL_NO_ERROR) | 3030 if((error = alGetError()) != AL_NO_ERROR) |
2854 { | 3031 { |
2855 ALmixer_SetError("%s", | 3032 ALmixer_SetError("%s", |
2856 aluGetErrorString(error) ); | 3033 alGetString(error) ); |
2857 retval = -1; | 3034 retval = -1; |
2858 } | 3035 } |
2859 } | 3036 } |
2860 fprintf(stderr, "Pause on channel %d, channel in use\n", channel); | 3037 fprintf(stderr, "Pause on channel %d, channel in use\n", channel); |
2861 } | 3038 } |
2862 } | 3039 } |
2863 /* The user wants to halt all channels */ | 3040 /* The user wants to halt all channels */ |
2864 else | 3041 else |
2865 { | 3042 { |
2866 Sint32 i; | 3043 ALint i; |
2867 for(i=0; i<Number_of_Channels_global; i++) | 3044 for(i=0; i<Number_of_Channels_global; i++) |
2868 { | 3045 { |
2869 fprintf(stderr, "Pausing channel %d\n", i); | 3046 fprintf(stderr, "Pausing channel %d\n", i); |
2870 fprintf(stderr, "in use %d\n", ALmixer_Channel_List[i].channel_in_use ); | 3047 fprintf(stderr, "in use %d\n", ALmixer_Channel_List[i].channel_in_use ); |
2871 /* only need to process channel if in use */ | 3048 /* only need to process channel if in use */ |
2877 AL_SOURCE_STATE, &state | 3054 AL_SOURCE_STATE, &state |
2878 ); | 3055 ); |
2879 if((error = alGetError()) != AL_NO_ERROR) | 3056 if((error = alGetError()) != AL_NO_ERROR) |
2880 { | 3057 { |
2881 fprintf(stderr, "33Testing error: %s\n", | 3058 fprintf(stderr, "33Testing error: %s\n", |
2882 aluGetErrorString(error)); | 3059 alGetString(error)); |
2883 } | 3060 } |
2884 if(AL_PAUSED == state) | 3061 if(AL_PAUSED == state) |
2885 { | 3062 { |
2886 /* Count the actual number of channels resumed */ | 3063 /* Count the actual number of channels resumed */ |
2887 counter++; | 3064 counter++; |
2888 | 3065 |
2889 /* We need to resume the expire time count down */ | 3066 /* We need to resume the expire time count down */ |
2890 if(ALmixer_Channel_List[i].expire_ticks != -1) | 3067 if(ALmixer_Channel_List[i].expire_ticks != -1) |
2891 { | 3068 { |
2892 ALmixer_Channel_List[i].start_time = SDL_GetTicks(); | 3069 ALmixer_Channel_List[i].start_time = ALmixer_GetTicks(); |
2893 } | 3070 } |
2894 /* Do the same as expire time for fading */ | 3071 /* Do the same as expire time for fading */ |
2895 if(ALmixer_Channel_List[i].fade_enabled) | 3072 if(ALmixer_Channel_List[i].fade_enabled) |
2896 { | 3073 { |
2897 ALmixer_Channel_List[i].fade_start_time = SDL_GetTicks(); | 3074 ALmixer_Channel_List[i].fade_start_time = ALmixer_GetTicks(); |
2898 } | 3075 } |
2899 | 3076 |
2900 alSourcePlay(ALmixer_Channel_List[i].alsource); | 3077 alSourcePlay(ALmixer_Channel_List[i].alsource); |
2901 if((error = alGetError()) != AL_NO_ERROR) | 3078 if((error = alGetError()) != AL_NO_ERROR) |
2902 { | 3079 { |
2903 ALmixer_SetError("%s", | 3080 ALmixer_SetError("%s", |
2904 aluGetErrorString(error) ); | 3081 alGetString(error) ); |
2905 retval = -1; | 3082 retval = -1; |
2906 } | 3083 } |
2907 } | 3084 } |
2908 } | 3085 } |
2909 } | 3086 } |
2914 } | 3091 } |
2915 return counter; | 3092 return counter; |
2916 } | 3093 } |
2917 | 3094 |
2918 | 3095 |
2919 static Sint32 Internal_ResumeSource(ALuint source) | 3096 static ALint Internal_ResumeSource(ALuint source) |
2920 { | 3097 { |
2921 Sint32 channel; | 3098 ALint channel; |
2922 if(0 == source) | 3099 if(0 == source) |
2923 { | 3100 { |
2924 return Internal_ResumeChannel(-1); | 3101 return Internal_ResumeChannel(-1); |
2925 } | 3102 } |
2926 | 3103 |
2935 | 3112 |
2936 | 3113 |
2937 /* Might consider setting eof to 0 as a "feature" | 3114 /* Might consider setting eof to 0 as a "feature" |
2938 * This will allow seek to end to stay there because | 3115 * This will allow seek to end to stay there because |
2939 * Play automatically rewinds if at the end */ | 3116 * Play automatically rewinds if at the end */ |
2940 static Sint32 Internal_Seek(ALmixer_Data* data, Uint32 msec) | 3117 static ALint Internal_SeekData(ALmixer_Data* data, ALuint msec) |
2941 { | 3118 { |
2942 Sint32 retval; | 3119 ALint retval; |
2943 | 3120 |
2944 if(NULL == data) | 3121 if(NULL == data) |
2945 { | 3122 { |
2946 ALmixer_SetError("Cannot Seek because data is NULL"); | 3123 ALmixer_SetError("Cannot Seek because data is NULL"); |
2947 return -1; | 3124 return -1; |
2948 } | 3125 } |
2949 | 3126 |
2950 /* Seek for predecoded files involves moving the chunk pointer around */ | 3127 /* Seek for predecoded files involves moving the chunk pointer around */ |
2951 if(data->decoded_all) | 3128 if(data->decoded_all) |
2952 { | 3129 { |
2953 Uint32 byte_position; | 3130 ALuint byte_position; |
2954 | 3131 |
2955 /* OpenAL doesn't seem to like it if I change the buffer | 3132 /* OpenAL doesn't seem to like it if I change the buffer |
2956 * while playing (crashes), so I must require that Seek only | 3133 * while playing (crashes), so I must require that Seek only |
2957 * be done when the data is not in use. | 3134 * be done when the data is not in use. |
2958 * Since data may be shared among multiple sources, | 3135 * Since data may be shared among multiple sources, |
3027 return 0; | 3204 return 0; |
3028 } | 3205 } |
3029 | 3206 |
3030 | 3207 |
3031 | 3208 |
3032 static Sint32 Internal_FadeInChannelTimed(Sint32 channel, ALmixer_Data* data, Sint32 loops, Uint32 fade_ticks, Sint32 expire_ticks) | 3209 static ALint Internal_FadeInChannelTimed(ALint channel, ALmixer_Data* data, ALint loops, ALuint fade_ticks, ALint expire_ticks) |
3033 { | 3210 { |
3034 ALfloat value; | 3211 ALfloat value; |
3035 ALenum error; | 3212 ALenum error; |
3036 ALfloat original_value; | 3213 ALfloat original_value; |
3037 Uint32 current_time = SDL_GetTicks(); | 3214 ALuint current_time = ALmixer_GetTicks(); |
3038 Sint32 retval; | 3215 ALint retval; |
3039 | 3216 |
3040 | 3217 |
3041 | 3218 |
3042 if(channel >= Number_of_Channels_global) | 3219 if(channel >= Number_of_Channels_global) |
3043 { | 3220 { |
3071 } | 3248 } |
3072 | 3249 |
3073 | 3250 |
3074 /* Get the original volume in case of a problem */ | 3251 /* Get the original volume in case of a problem */ |
3075 alGetSourcef(ALmixer_Channel_List[channel].alsource, | 3252 alGetSourcef(ALmixer_Channel_List[channel].alsource, |
3076 AL_MAX_GAIN, &original_value); | 3253 AL_GAIN, &original_value); |
3077 | 3254 |
3078 if((error = alGetError()) != AL_NO_ERROR) | 3255 if((error = alGetError()) != AL_NO_ERROR) |
3079 { | 3256 { |
3080 fprintf(stderr, "35Testing error: %s\n", | 3257 fprintf(stderr, "35Testing error: %s\n", |
3081 aluGetErrorString(error)); | 3258 alGetString(error)); |
3082 } | 3259 } |
3083 /* Get the Max volume */ | 3260 ALmixer_Channel_List[channel].fade_end_volume = original_value; |
3084 /* | |
3085 alGetSourcef(ALmixer_Channel_List[channel].alsource, | |
3086 AL_MAX_GAIN, &value); | |
3087 ALmixer_Channel_List[channel].fade_end_volume = value; | |
3088 fprintf(stderr, "MAX gain: %f\n", value); | |
3089 */ | |
3090 ALmixer_Channel_List[channel].fade_end_volume = | |
3091 ALmixer_Channel_List[channel].max_volume; | |
3092 | 3261 |
3093 /* Get the Min volume */ | 3262 /* Get the Min volume */ |
3094 alGetSourcef(ALmixer_Channel_List[channel].alsource, | 3263 alGetSourcef(ALmixer_Channel_List[channel].alsource, |
3095 AL_MIN_GAIN, &value); | 3264 AL_MIN_GAIN, &value); |
3096 if((error = alGetError()) != AL_NO_ERROR) | 3265 if((error = alGetError()) != AL_NO_ERROR) |
3097 { | 3266 { |
3098 fprintf(stderr, "36Testing error: %s\n", | 3267 fprintf(stderr, "36Testing error: %s\n", |
3099 aluGetErrorString(error)); | 3268 alGetString(error)); |
3100 } | 3269 } |
3101 ALmixer_Channel_List[channel].fade_start_volume = value; | 3270 ALmixer_Channel_List[channel].fade_start_volume = value; |
3102 fprintf(stderr, "MIN gain: %f\n", value); | 3271 fprintf(stderr, "MIN gain: %f\n", value); |
3103 | 3272 |
3104 /* Set the actual volume */ | 3273 /* Set the actual volume */ |
3105 alSourcef(ALmixer_Channel_List[channel].alsource, | 3274 alSourcef(ALmixer_Channel_List[channel].alsource, |
3106 AL_MAX_GAIN, value); | 3275 AL_GAIN, value); |
3107 if((error = alGetError()) != AL_NO_ERROR) | 3276 if((error = alGetError()) != AL_NO_ERROR) |
3108 { | 3277 { |
3109 fprintf(stderr, "37Testing error: %s\n", | 3278 fprintf(stderr, "37Testing error: %s\n", |
3110 aluGetErrorString(error)); | 3279 alGetString(error)); |
3111 } | 3280 } |
3112 | 3281 |
3113 | 3282 |
3114 /* Now call PlayChannelTimed */ | 3283 /* Now call PlayChannelTimed */ |
3115 retval = Internal_PlayChannelTimed(channel, data, loops, expire_ticks); | 3284 retval = Internal_PlayChannelTimed(channel, data, loops, expire_ticks); |
3121 */ | 3290 */ |
3122 /* Restore the original value to avoid accidental | 3291 /* Restore the original value to avoid accidental |
3123 * distruption of playback | 3292 * distruption of playback |
3124 */ | 3293 */ |
3125 alSourcef(ALmixer_Channel_List[channel].alsource, | 3294 alSourcef(ALmixer_Channel_List[channel].alsource, |
3126 AL_MAX_GAIN, original_value); | 3295 AL_GAIN, original_value); |
3127 if((error = alGetError()) != AL_NO_ERROR) | 3296 if((error = alGetError()) != AL_NO_ERROR) |
3128 { | 3297 { |
3129 fprintf(stderr, "38Testing error: %s\n", | 3298 fprintf(stderr, "38Testing error: %s\n", |
3130 aluGetErrorString(error)); | 3299 alGetString(error)); |
3131 } | 3300 } |
3132 return retval; | 3301 return retval; |
3133 } | 3302 } |
3134 | 3303 |
3135 /* We can't accept 0 as a value because of div-by-zero. | 3304 /* We can't accept 0 as a value because of div-by-zero. |
3136 * If zero, just call PlayChannelTimed at normal | 3305 * If zero, just call PlayChannelTimed at normal |
3137 * volume | 3306 * volume |
3138 */ | 3307 */ |
3139 if(0 == fade_ticks) | 3308 if(0 == fade_ticks) |
3140 { | 3309 { |
3141 alSourcef(ALmixer_Channel_List[channel].alsource, | 3310 alSourcef(ALmixer_Channel_List[channel].alsource, |
3142 AL_MAX_GAIN, | 3311 AL_GAIN, |
3143 ALmixer_Channel_List[channel].fade_end_volume | 3312 ALmixer_Channel_List[channel].fade_end_volume |
3144 ); | 3313 ); |
3145 if((error = alGetError()) != AL_NO_ERROR) | 3314 if((error = alGetError()) != AL_NO_ERROR) |
3146 { | 3315 { |
3147 fprintf(stderr, "39Testing error: %s\n", | 3316 fprintf(stderr, "39Testing error: %s\n", |
3148 aluGetErrorString(error)); | 3317 alGetString(error)); |
3149 } | 3318 } |
3150 | 3319 |
3151 return retval; | 3320 return retval; |
3152 } | 3321 } |
3153 | 3322 |
3154 /* Enable fading effects via the flag */ | 3323 /* Enable fading effects via the flag */ |
3166 return retval; | 3335 return retval; |
3167 | 3336 |
3168 } | 3337 } |
3169 | 3338 |
3170 | 3339 |
3171 static ALuint Internal_FadeInSourceTimed(ALuint source, ALmixer_Data* data, Sint32 loops, Uint32 fade_ticks, Sint32 expire_ticks) | 3340 static ALuint Internal_FadeInSourceTimed(ALuint source, ALmixer_Data* data, ALint loops, ALuint fade_ticks, ALint expire_ticks) |
3172 { | 3341 { |
3173 Sint32 channel; | 3342 ALint channel; |
3174 Sint32 retval; | 3343 ALint retval; |
3175 if(0 == source) | 3344 if(0 == source) |
3176 { | 3345 { |
3177 retval = Internal_FadeInChannelTimed(-1, data, loops, fade_ticks, expire_ticks); | 3346 retval = Internal_FadeInChannelTimed(-1, data, loops, fade_ticks, expire_ticks); |
3178 if(-1 == retval) | 3347 if(-1 == retval) |
3179 { | 3348 { |
3207 | 3376 |
3208 | 3377 |
3209 | 3378 |
3210 /* Will fade out currently playing channels. | 3379 /* Will fade out currently playing channels. |
3211 * It starts at the current volume level and goes down */ | 3380 * It starts at the current volume level and goes down */ |
3212 static Sint32 Internal_FadeOutChannel(Sint32 channel, Uint32 ticks) | 3381 static ALint Internal_FadeOutChannel(ALint channel, ALuint ticks) |
3213 { | 3382 { |
3214 ALfloat value; | 3383 ALfloat value; |
3215 ALenum error; | 3384 ALenum error; |
3216 Uint32 current_time = SDL_GetTicks(); | 3385 ALuint current_time = ALmixer_GetTicks(); |
3217 Uint32 counter = 0; | 3386 ALuint counter = 0; |
3218 | 3387 |
3219 /* We can't accept 0 as a value because of div-by-zero. | 3388 /* We can't accept 0 as a value because of div-by-zero. |
3220 * If zero, just call Halt at normal | 3389 * If zero, just call Halt at normal |
3221 * volume | 3390 * volume |
3222 */ | 3391 */ |
3223 if(0 == ticks) | 3392 if(0 == ticks) |
3224 { | 3393 { |
3225 return Internal_HaltChannel(channel); | 3394 return Internal_HaltChannel(channel, AL_TRUE); |
3226 } | 3395 } |
3227 | 3396 |
3228 | 3397 |
3229 if(channel >= Number_of_Channels_global) | 3398 if(channel >= Number_of_Channels_global) |
3230 { | 3399 { |
3236 { | 3405 { |
3237 if(ALmixer_Channel_List[channel].channel_in_use) | 3406 if(ALmixer_Channel_List[channel].channel_in_use) |
3238 { | 3407 { |
3239 /* Get the current volume */ | 3408 /* Get the current volume */ |
3240 alGetSourcef(ALmixer_Channel_List[channel].alsource, | 3409 alGetSourcef(ALmixer_Channel_List[channel].alsource, |
3241 AL_MAX_GAIN, &value); | 3410 AL_GAIN, &value); |
3242 ALmixer_Channel_List[channel].fade_start_volume = value; | 3411 ALmixer_Channel_List[channel].fade_start_volume = value; |
3243 if((error = alGetError()) != AL_NO_ERROR) | 3412 if((error = alGetError()) != AL_NO_ERROR) |
3244 { | 3413 { |
3245 fprintf(stderr, "40Testing error: %s\n", | 3414 fprintf(stderr, "40Testing error: %s\n", |
3246 aluGetErrorString(error)); | 3415 alGetString(error)); |
3247 } | 3416 } |
3248 | 3417 |
3249 /* Get the Min volume */ | 3418 /* Get the Min volume */ |
3250 alGetSourcef(ALmixer_Channel_List[channel].alsource, | 3419 alGetSourcef(ALmixer_Channel_List[channel].alsource, |
3251 AL_MIN_GAIN, &value); | 3420 AL_MIN_GAIN, &value); |
3252 if((error = alGetError()) != AL_NO_ERROR) | 3421 if((error = alGetError()) != AL_NO_ERROR) |
3253 { | 3422 { |
3254 fprintf(stderr, "41Testing error: %s\n", | 3423 fprintf(stderr, "41Testing error: %s\n", |
3255 aluGetErrorString(error)); | 3424 alGetString(error)); |
3256 } | 3425 } |
3257 ALmixer_Channel_List[channel].fade_end_volume = value; | 3426 ALmixer_Channel_List[channel].fade_end_volume = value; |
3258 fprintf(stderr, "MIN gain: %f\n", value); | 3427 fprintf(stderr, "MIN gain: %f\n", value); |
3259 | 3428 |
3260 /* Set expire start time */ | 3429 /* Set expire start time */ |
3275 } | 3444 } |
3276 } | 3445 } |
3277 /* Else need to fade out all channels */ | 3446 /* Else need to fade out all channels */ |
3278 else | 3447 else |
3279 { | 3448 { |
3280 Sint32 i; | 3449 ALint i; |
3281 for(i=0; i<Number_of_Channels_global; i++) | 3450 for(i=0; i<Number_of_Channels_global; i++) |
3282 { | 3451 { |
3283 if(ALmixer_Channel_List[i].channel_in_use) | 3452 if(ALmixer_Channel_List[i].channel_in_use) |
3284 { | 3453 { |
3285 /* Get the current volume */ | 3454 /* Get the current volume */ |
3286 alGetSourcef(ALmixer_Channel_List[i].alsource, | 3455 alGetSourcef(ALmixer_Channel_List[i].alsource, |
3287 AL_MAX_GAIN, &value); | 3456 AL_GAIN, &value); |
3288 ALmixer_Channel_List[i].fade_start_volume = value; | 3457 ALmixer_Channel_List[i].fade_start_volume = value; |
3289 if((error = alGetError()) != AL_NO_ERROR) | 3458 if((error = alGetError()) != AL_NO_ERROR) |
3290 { | 3459 { |
3291 fprintf(stderr, "42Testing error: %s\n", | 3460 fprintf(stderr, "42Testing error: %s\n", |
3292 aluGetErrorString(error)); | 3461 alGetString(error)); |
3293 } | 3462 } |
3294 | 3463 |
3295 /* Get the Min volume */ | 3464 /* Get the Min volume */ |
3296 alGetSourcef(ALmixer_Channel_List[i].alsource, | 3465 alGetSourcef(ALmixer_Channel_List[i].alsource, |
3297 AL_MIN_GAIN, &value); | 3466 AL_MIN_GAIN, &value); |
3298 if((error = alGetError()) != AL_NO_ERROR) | 3467 if((error = alGetError()) != AL_NO_ERROR) |
3299 { | 3468 { |
3300 fprintf(stderr, "43Testing error: %s\n", | 3469 fprintf(stderr, "43Testing error: %s\n", |
3301 aluGetErrorString(error)); | 3470 alGetString(error)); |
3302 } | 3471 } |
3303 ALmixer_Channel_List[i].fade_end_volume = value; | 3472 ALmixer_Channel_List[i].fade_end_volume = value; |
3304 fprintf(stderr, "MIN gain: %f\n", value); | 3473 fprintf(stderr, "MIN gain: %f\n", value); |
3305 | 3474 |
3306 /* Set expire start time */ | 3475 /* Set expire start time */ |
3323 } | 3492 } |
3324 return counter; | 3493 return counter; |
3325 } | 3494 } |
3326 | 3495 |
3327 | 3496 |
3328 static Sint32 Internal_FadeOutSource(ALuint source, Uint32 ticks) | 3497 static ALint Internal_FadeOutSource(ALuint source, ALuint ticks) |
3329 { | 3498 { |
3330 Sint32 channel; | 3499 ALint channel; |
3331 if(0 == source) | 3500 if(0 == source) |
3332 { | 3501 { |
3333 return Internal_FadeOutChannel(-1, ticks); | 3502 return Internal_FadeOutChannel(-1, ticks); |
3334 } | 3503 } |
3335 | 3504 |
3345 | 3514 |
3346 /* Will fade currently playing channels. | 3515 /* Will fade currently playing channels. |
3347 * It starts at the current volume level and go to target | 3516 * It starts at the current volume level and go to target |
3348 * Only affects channels that are playing | 3517 * Only affects channels that are playing |
3349 */ | 3518 */ |
3350 static Sint32 Internal_FadeChannel(Sint32 channel, Uint32 ticks, ALfloat volume) | 3519 static ALint Internal_FadeChannel(ALint channel, ALuint ticks, ALfloat volume) |
3351 { | 3520 { |
3352 ALfloat value; | 3521 ALfloat value; |
3353 ALenum error; | 3522 ALenum error; |
3354 Uint32 current_time = SDL_GetTicks(); | 3523 ALuint current_time = ALmixer_GetTicks(); |
3355 Uint32 counter = 0; | 3524 ALuint counter = 0; |
3356 | 3525 |
3357 if(channel >= Number_of_Channels_global) | 3526 if(channel >= Number_of_Channels_global) |
3358 { | 3527 { |
3359 ALmixer_SetError("Requested channel (%d) exceeds maximum channel (%d) because only %d channels are allocated", channel, Number_of_Channels_global-1, Number_of_Channels_global); | 3528 ALmixer_SetError("Requested channel (%d) exceeds maximum channel (%d) because only %d channels are allocated", channel, Number_of_Channels_global-1, Number_of_Channels_global); |
3360 return -1; | 3529 return -1; |
3375 { | 3544 { |
3376 if(ticks > 0) | 3545 if(ticks > 0) |
3377 { | 3546 { |
3378 /* Get the current volume */ | 3547 /* Get the current volume */ |
3379 alGetSourcef(ALmixer_Channel_List[channel].alsource, | 3548 alGetSourcef(ALmixer_Channel_List[channel].alsource, |
3380 AL_MAX_GAIN, &value); | 3549 AL_GAIN, &value); |
3381 if((error = alGetError()) != AL_NO_ERROR) | 3550 if((error = alGetError()) != AL_NO_ERROR) |
3382 { | 3551 { |
3383 fprintf(stderr, "44Testing error: %s\n", | 3552 fprintf(stderr, "44Testing error: %s\n", |
3384 aluGetErrorString(error)); | 3553 alGetString(error)); |
3385 } | 3554 } |
3386 ALmixer_Channel_List[channel].fade_start_volume = value; | 3555 ALmixer_Channel_List[channel].fade_start_volume = value; |
3387 | 3556 |
3388 /* Set the target volume */ | 3557 /* Set the target volume */ |
3389 ALmixer_Channel_List[channel].fade_end_volume = volume; | 3558 ALmixer_Channel_List[channel].fade_end_volume = volume; |
3399 ALmixer_Channel_List[channel].fade_inv_time = 1.0f / ticks; | 3568 ALmixer_Channel_List[channel].fade_inv_time = 1.0f / ticks; |
3400 } | 3569 } |
3401 else | 3570 else |
3402 { | 3571 { |
3403 alSourcef(ALmixer_Channel_List[channel].alsource, | 3572 alSourcef(ALmixer_Channel_List[channel].alsource, |
3404 AL_MAX_GAIN, volume); | 3573 AL_GAIN, volume); |
3405 if((error = alGetError()) != AL_NO_ERROR) | 3574 if((error = alGetError()) != AL_NO_ERROR) |
3406 { | 3575 { |
3407 fprintf(stderr, "45Testing error: %s\n", | 3576 fprintf(stderr, "45Testing error: %s\n", |
3408 aluGetErrorString(error)); | 3577 alGetString(error)); |
3409 } | 3578 } |
3410 } | 3579 } |
3411 counter++; | 3580 counter++; |
3412 } | 3581 } |
3413 } | 3582 } |
3414 /* Else need to fade out all channels */ | 3583 /* Else need to fade out all channels */ |
3415 else | 3584 else |
3416 { | 3585 { |
3417 Sint32 i; | 3586 ALint i; |
3418 for(i=0; i<Number_of_Channels_global; i++) | 3587 for(i=0; i<Number_of_Channels_global; i++) |
3419 { | 3588 { |
3420 if(volume < ALmixer_Channel_List[i].min_volume) | 3589 if(volume < ALmixer_Channel_List[i].min_volume) |
3421 { | 3590 { |
3422 volume = ALmixer_Channel_List[i].min_volume; | 3591 volume = ALmixer_Channel_List[i].min_volume; |
3430 { | 3599 { |
3431 if(ticks > 0) | 3600 if(ticks > 0) |
3432 { | 3601 { |
3433 /* Get the current volume */ | 3602 /* Get the current volume */ |
3434 alGetSourcef(ALmixer_Channel_List[i].alsource, | 3603 alGetSourcef(ALmixer_Channel_List[i].alsource, |
3435 AL_MAX_GAIN, &value); | 3604 AL_GAIN, &value); |
3436 if((error = alGetError()) != AL_NO_ERROR) | 3605 if((error = alGetError()) != AL_NO_ERROR) |
3437 { | 3606 { |
3438 fprintf(stderr, "46Testing error: %s\n", | 3607 fprintf(stderr, "46Testing error: %s\n", |
3439 aluGetErrorString(error)); | 3608 alGetString(error)); |
3440 } | 3609 } |
3441 ALmixer_Channel_List[i].fade_start_volume = value; | 3610 ALmixer_Channel_List[i].fade_start_volume = value; |
3442 | 3611 |
3443 /* Set target volume */ | 3612 /* Set target volume */ |
3444 ALmixer_Channel_List[i].fade_end_volume = volume; | 3613 ALmixer_Channel_List[i].fade_end_volume = volume; |
3454 ALmixer_Channel_List[i].fade_inv_time = 1.0f / ticks; | 3623 ALmixer_Channel_List[i].fade_inv_time = 1.0f / ticks; |
3455 } | 3624 } |
3456 else | 3625 else |
3457 { | 3626 { |
3458 alSourcef(ALmixer_Channel_List[i].alsource, | 3627 alSourcef(ALmixer_Channel_List[i].alsource, |
3459 AL_MAX_GAIN, volume); | 3628 AL_GAIN, volume); |
3460 if((error = alGetError()) != AL_NO_ERROR) | 3629 if((error = alGetError()) != AL_NO_ERROR) |
3461 { | 3630 { |
3462 fprintf(stderr, "47Testing error: %s\n", | 3631 fprintf(stderr, "47Testing error: %s\n", |
3463 aluGetErrorString(error)); | 3632 alGetString(error)); |
3464 } | 3633 } |
3465 } | 3634 } |
3466 counter++; | 3635 counter++; |
3467 } | 3636 } |
3468 } /* End for loop */ | 3637 } /* End for loop */ |
3469 } | 3638 } |
3470 return counter; | 3639 return counter; |
3471 } | 3640 } |
3472 | 3641 |
3473 static Sint32 Internal_FadeSource(ALuint source, Uint32 ticks, ALfloat volume) | 3642 static ALint Internal_FadeSource(ALuint source, ALuint ticks, ALfloat volume) |
3474 { | 3643 { |
3475 Sint32 channel; | 3644 ALint channel; |
3476 if(0 == source) | 3645 if(0 == source) |
3477 { | 3646 { |
3478 return Internal_FadeChannel(-1, ticks, volume); | 3647 return Internal_FadeChannel(-1, ticks, volume); |
3479 } | 3648 } |
3480 | 3649 |
3490 | 3659 |
3491 | 3660 |
3492 | 3661 |
3493 /* Set a volume regardless if it's in use or not. | 3662 /* Set a volume regardless if it's in use or not. |
3494 */ | 3663 */ |
3495 static Sint32 Internal_SetMaxVolumeChannel(Sint32 channel, ALfloat volume) | 3664 static ALboolean Internal_SetVolumeChannel(ALint channel, ALfloat volume) |
3496 { | 3665 { |
3497 ALenum error; | 3666 ALenum error; |
3498 Sint32 retval = 0; | 3667 ALboolean retval = AL_TRUE; |
3499 | 3668 |
3500 if(channel >= Number_of_Channels_global) | 3669 if(channel >= Number_of_Channels_global) |
3501 { | 3670 { |
3671 ALmixer_SetError("Requested channel (%d) exceeds maximum channel (%d) because only %d channels are allocated", channel, Number_of_Channels_global-1, Number_of_Channels_global); | |
3672 return AL_FALSE; | |
3673 } | |
3674 | |
3675 if(channel >= 0) | |
3676 { | |
3677 if(volume < 0.0f) | |
3678 { | |
3679 volume = 0.0f; | |
3680 } | |
3681 else if(volume > 1.0f) | |
3682 { | |
3683 volume = 1.0f; | |
3684 } | |
3685 alSourcef(ALmixer_Channel_List[channel].alsource, | |
3686 AL_GAIN, volume); | |
3687 if((error = alGetError()) != AL_NO_ERROR) | |
3688 { | |
3689 ALmixer_SetError("%s", | |
3690 alGetString(error) ); | |
3691 retval = AL_FALSE; | |
3692 } | |
3693 } | |
3694 else | |
3695 { | |
3696 ALint i; | |
3697 for(i=0; i<Number_of_Channels_global; i++) | |
3698 { | |
3699 if(volume < 0.0f) | |
3700 { | |
3701 volume = 0.0f; | |
3702 } | |
3703 else if(volume > 1.0f) | |
3704 { | |
3705 volume = 1.0f; | |
3706 } | |
3707 alSourcef(ALmixer_Channel_List[i].alsource, | |
3708 AL_GAIN, volume); | |
3709 if((error = alGetError()) != AL_NO_ERROR) | |
3710 { | |
3711 ALmixer_SetError("%s", | |
3712 alGetString(error) ); | |
3713 retval = AL_FALSE; | |
3714 } | |
3715 } | |
3716 } | |
3717 return retval; | |
3718 } | |
3719 | |
3720 static ALboolean Internal_SetVolumeSource(ALuint source, ALfloat volume) | |
3721 { | |
3722 ALint channel; | |
3723 if(0 == source) | |
3724 { | |
3725 return Internal_SetVolumeChannel(-1, volume); | |
3726 } | |
3727 | |
3728 channel = Internal_GetChannel(source); | |
3729 if(-1 == channel) | |
3730 { | |
3731 ALmixer_SetError("Cannot SetMaxVolume: %s", ALmixer_GetError()); | |
3732 return AL_FALSE; | |
3733 } | |
3734 return Internal_SetVolumeChannel(channel, volume); | |
3735 } | |
3736 | |
3737 | |
3738 static ALfloat Internal_GetVolumeChannel(ALint channel) | |
3739 { | |
3740 ALfloat value; | |
3741 ALenum error; | |
3742 ALfloat running_total = 0.0f; | |
3743 ALfloat retval = 0.0f; | |
3744 | |
3745 if(channel >= Number_of_Channels_global) | |
3746 { | |
3747 ALmixer_SetError("Requested channel (%d) exceeds maximum channel (%d) because only %d channels are allocated", channel, Number_of_Channels_global-1, Number_of_Channels_global); | |
3748 return -1.0f; | |
3749 } | |
3750 | |
3751 if(channel >= 0) | |
3752 { | |
3753 alGetSourcef(ALmixer_Channel_List[channel].alsource, | |
3754 AL_GAIN, &value); | |
3755 if((error = alGetError()) != AL_NO_ERROR) | |
3756 { | |
3757 ALmixer_SetError("%s", alGetString(error) ); | |
3758 retval = -1.0f; | |
3759 } | |
3760 else | |
3761 { | |
3762 retval = value; | |
3763 } | |
3764 } | |
3765 else | |
3766 { | |
3767 ALint i; | |
3768 for(i=0; i<Number_of_Channels_global; i++) | |
3769 { | |
3770 alGetSourcef(ALmixer_Channel_List[i].alsource, | |
3771 AL_GAIN, &value); | |
3772 if((error = alGetError()) != AL_NO_ERROR) | |
3773 { | |
3774 ALmixer_SetError("%s", alGetString(error) ); | |
3775 retval = -1; | |
3776 } | |
3777 else | |
3778 { | |
3779 running_total += value; | |
3780 } | |
3781 } | |
3782 if(0 == Number_of_Channels_global) | |
3783 { | |
3784 ALmixer_SetError("No channels are allocated"); | |
3785 retval = -1.0f; | |
3786 } | |
3787 else | |
3788 { | |
3789 retval = running_total / Number_of_Channels_global; | |
3790 } | |
3791 } | |
3792 return retval; | |
3793 } | |
3794 | |
3795 static ALfloat Internal_GetVolumeSource(ALuint source) | |
3796 { | |
3797 ALint channel; | |
3798 if(0 == source) | |
3799 { | |
3800 return Internal_GetVolumeChannel(-1); | |
3801 } | |
3802 | |
3803 channel = Internal_GetChannel(source); | |
3804 if(-1 == channel) | |
3805 { | |
3806 ALmixer_SetError("Cannot GetVolume: %s", ALmixer_GetError()); | |
3807 return -1.0f; | |
3808 } | |
3809 | |
3810 return Internal_GetVolumeChannel(channel); | |
3811 } | |
3812 | |
3813 | |
3814 | |
3815 /* Set a volume regardless if it's in use or not. | |
3816 */ | |
3817 static ALboolean Internal_SetMaxVolumeChannel(ALint channel, ALfloat volume) | |
3818 { | |
3819 ALenum error; | |
3820 ALboolean retval = AL_TRUE; | |
3821 | |
3822 if(channel >= Number_of_Channels_global) | |
3823 { | |
3502 ALmixer_SetError("Requested channel (%d) exceeds maximum channel (%d) because only %d channels are allocated", channel, Number_of_Channels_global-1, Number_of_Channels_global); | 3824 ALmixer_SetError("Requested channel (%d) exceeds maximum channel (%d) because only %d channels are allocated", channel, Number_of_Channels_global-1, Number_of_Channels_global); |
3503 return -1; | 3825 return AL_FALSE; |
3504 } | 3826 } |
3505 | 3827 |
3506 if(channel >= 0) | 3828 if(channel >= 0) |
3507 { | 3829 { |
3508 if(volume < 0.0f) | 3830 if(volume < 0.0f) |
3517 alSourcef(ALmixer_Channel_List[channel].alsource, | 3839 alSourcef(ALmixer_Channel_List[channel].alsource, |
3518 AL_MAX_GAIN, volume); | 3840 AL_MAX_GAIN, volume); |
3519 if((error = alGetError()) != AL_NO_ERROR) | 3841 if((error = alGetError()) != AL_NO_ERROR) |
3520 { | 3842 { |
3521 ALmixer_SetError("%s", | 3843 ALmixer_SetError("%s", |
3522 aluGetErrorString(error) ); | 3844 alGetString(error) ); |
3523 retval = -1; | 3845 retval = AL_FALSE; |
3524 } | 3846 } |
3525 if(ALmixer_Channel_List[channel].max_volume < ALmixer_Channel_List[channel].min_volume) | 3847 if(ALmixer_Channel_List[channel].max_volume < ALmixer_Channel_List[channel].min_volume) |
3526 { | 3848 { |
3527 ALmixer_Channel_List[channel].min_volume = volume; | 3849 ALmixer_Channel_List[channel].min_volume = volume; |
3528 alSourcef(ALmixer_Channel_List[channel].alsource, | 3850 alSourcef(ALmixer_Channel_List[channel].alsource, |
3529 AL_MIN_GAIN, volume); | 3851 AL_MIN_GAIN, volume); |
3530 if((error = alGetError()) != AL_NO_ERROR) | 3852 if((error = alGetError()) != AL_NO_ERROR) |
3531 { | 3853 { |
3532 ALmixer_SetError("%s", | 3854 ALmixer_SetError("%s", |
3533 aluGetErrorString(error) ); | 3855 alGetString(error) ); |
3534 retval = -1; | 3856 retval = AL_FALSE; |
3535 } | 3857 } |
3536 } | 3858 } |
3537 } | 3859 } |
3538 else | 3860 else |
3539 { | 3861 { |
3540 Sint32 i; | 3862 ALint i; |
3541 for(i=0; i<Number_of_Channels_global; i++) | 3863 for(i=0; i<Number_of_Channels_global; i++) |
3542 { | 3864 { |
3543 if(volume < 0.0f) | 3865 if(volume < 0.0f) |
3544 { | 3866 { |
3545 volume = 0.0f; | 3867 volume = 0.0f; |
3552 alSourcef(ALmixer_Channel_List[i].alsource, | 3874 alSourcef(ALmixer_Channel_List[i].alsource, |
3553 AL_MAX_GAIN, volume); | 3875 AL_MAX_GAIN, volume); |
3554 if((error = alGetError()) != AL_NO_ERROR) | 3876 if((error = alGetError()) != AL_NO_ERROR) |
3555 { | 3877 { |
3556 ALmixer_SetError("%s", | 3878 ALmixer_SetError("%s", |
3557 aluGetErrorString(error) ); | 3879 alGetString(error) ); |
3558 retval = -1; | 3880 retval = AL_FALSE; |
3559 } | 3881 } |
3560 if(ALmixer_Channel_List[i].max_volume < ALmixer_Channel_List[i].min_volume) | 3882 if(ALmixer_Channel_List[i].max_volume < ALmixer_Channel_List[i].min_volume) |
3561 { | 3883 { |
3562 ALmixer_Channel_List[i].min_volume = volume; | 3884 ALmixer_Channel_List[i].min_volume = volume; |
3563 alSourcef(ALmixer_Channel_List[i].alsource, | 3885 alSourcef(ALmixer_Channel_List[i].alsource, |
3564 AL_MIN_GAIN, volume); | 3886 AL_MIN_GAIN, volume); |
3565 if((error = alGetError()) != AL_NO_ERROR) | 3887 if((error = alGetError()) != AL_NO_ERROR) |
3566 { | 3888 { |
3567 ALmixer_SetError("%s", | 3889 ALmixer_SetError("%s", |
3568 aluGetErrorString(error) ); | 3890 alGetString(error) ); |
3569 retval = -1; | 3891 retval = AL_FALSE; |
3570 } | 3892 } |
3571 } | 3893 } |
3572 } | 3894 } |
3573 } | 3895 } |
3574 return retval; | 3896 return retval; |
3575 } | 3897 } |
3576 | 3898 |
3577 static Sint32 Internal_SetMaxVolumeSource(ALuint source, ALfloat volume) | 3899 static ALint Internal_SetMaxVolumeSource(ALuint source, ALfloat volume) |
3578 { | 3900 { |
3579 Sint32 channel; | 3901 ALint channel; |
3580 if(0 == source) | 3902 if(0 == source) |
3581 { | 3903 { |
3582 return Internal_SetMaxVolumeChannel(-1, volume); | 3904 return Internal_SetMaxVolumeChannel(-1, volume); |
3583 } | 3905 } |
3584 | 3906 |
3585 channel = Internal_GetChannel(source); | 3907 channel = Internal_GetChannel(source); |
3586 if(-1 == channel) | 3908 if(-1 == channel) |
3587 { | 3909 { |
3588 ALmixer_SetError("Cannot SetMaxVolume: %s", ALmixer_GetError()); | 3910 ALmixer_SetError("Cannot SetMaxVolume: %s", ALmixer_GetError()); |
3589 return -1; | 3911 return AL_FALSE; |
3590 } | 3912 } |
3591 return Internal_SetMaxVolumeChannel(channel, volume); | 3913 return Internal_SetMaxVolumeChannel(channel, volume); |
3592 } | 3914 } |
3593 | 3915 |
3594 static ALfloat Internal_GetMaxVolumeChannel(Sint32 channel) | 3916 static ALfloat Internal_GetMaxVolumeChannel(ALint channel) |
3595 { | 3917 { |
3596 /* | 3918 /* |
3597 ALfloat value; | 3919 ALfloat value; |
3598 ALenum error; | 3920 ALenum error; |
3599 */ | 3921 */ |
3612 alGetSourcef(ALmixer_Channel_List[channel].alsource, | 3934 alGetSourcef(ALmixer_Channel_List[channel].alsource, |
3613 AL_GAIN, &value); | 3935 AL_GAIN, &value); |
3614 if((error = alGetError()) != AL_NO_ERROR) | 3936 if((error = alGetError()) != AL_NO_ERROR) |
3615 { | 3937 { |
3616 ALmixer_SetError("%s", | 3938 ALmixer_SetError("%s", |
3617 aluGetErrorString(error) ); | 3939 alGetString(error) ); |
3618 retval = -1.0f; | 3940 retval = -1.0f; |
3619 } | 3941 } |
3620 else | 3942 else |
3621 { | 3943 { |
3622 retval = value; | 3944 retval = value; |
3625 retval = ALmixer_Channel_List[channel].max_volume; | 3947 retval = ALmixer_Channel_List[channel].max_volume; |
3626 | 3948 |
3627 } | 3949 } |
3628 else | 3950 else |
3629 { | 3951 { |
3630 Sint32 i; | 3952 ALint i; |
3631 for(i=0; i<Number_of_Channels_global; i++) | 3953 for(i=0; i<Number_of_Channels_global; i++) |
3632 { | 3954 { |
3633 /* | 3955 /* |
3634 alGetSourcef(ALmixer_Channel_List[i].alsource, | 3956 alGetSourcef(ALmixer_Channel_List[i].alsource, |
3635 AL_GAIN, &value); | 3957 AL_GAIN, &value); |
3636 if((error = alGetError()) != AL_NO_ERROR) | 3958 if((error = alGetError()) != AL_NO_ERROR) |
3637 { | 3959 { |
3638 ALmixer_SetError("%s", | 3960 ALmixer_SetError("%s", |
3639 aluGetErrorString(error) ); | 3961 alGetString(error) ); |
3640 retval = -1; | 3962 retval = -1; |
3641 } | 3963 } |
3642 else | 3964 else |
3643 { | 3965 { |
3644 running_total += value; | 3966 running_total += value; |
3659 return retval; | 3981 return retval; |
3660 } | 3982 } |
3661 | 3983 |
3662 static ALfloat Internal_GetMaxVolumeSource(ALuint source) | 3984 static ALfloat Internal_GetMaxVolumeSource(ALuint source) |
3663 { | 3985 { |
3664 Sint32 channel; | 3986 ALint channel; |
3665 if(0 == source) | 3987 if(0 == source) |
3666 { | 3988 { |
3667 return Internal_GetMaxVolumeChannel(-1); | 3989 return Internal_GetMaxVolumeChannel(-1); |
3668 } | 3990 } |
3669 | 3991 |
3678 } | 4000 } |
3679 | 4001 |
3680 | 4002 |
3681 /* Set a volume regardless if it's in use or not. | 4003 /* Set a volume regardless if it's in use or not. |
3682 */ | 4004 */ |
3683 static Sint32 Internal_SetMinVolumeChannel(Sint32 channel, ALfloat volume) | 4005 static ALboolean Internal_SetMinVolumeChannel(ALint channel, ALfloat volume) |
3684 { | 4006 { |
3685 ALenum error; | 4007 ALenum error; |
3686 Sint32 retval = 0; | 4008 ALboolean retval = AL_TRUE; |
3687 | 4009 |
3688 if(channel >= Number_of_Channels_global) | 4010 if(channel >= Number_of_Channels_global) |
3689 { | 4011 { |
3690 ALmixer_SetError("Requested channel (%d) exceeds maximum channel (%d) because only %d channels are allocated", channel, Number_of_Channels_global-1, Number_of_Channels_global); | 4012 ALmixer_SetError("Requested channel (%d) exceeds maximum channel (%d) because only %d channels are allocated", channel, Number_of_Channels_global-1, Number_of_Channels_global); |
3691 return -1; | 4013 return AL_FALSE; |
3692 } | 4014 } |
3693 | 4015 |
3694 if(channel >= 0) | 4016 if(channel >= 0) |
3695 { | 4017 { |
3696 if(volume < 0.0f) | 4018 if(volume < 0.0f) |
3705 alSourcef(ALmixer_Channel_List[channel].alsource, | 4027 alSourcef(ALmixer_Channel_List[channel].alsource, |
3706 AL_MIN_GAIN, volume); | 4028 AL_MIN_GAIN, volume); |
3707 if((error = alGetError()) != AL_NO_ERROR) | 4029 if((error = alGetError()) != AL_NO_ERROR) |
3708 { | 4030 { |
3709 ALmixer_SetError("%s", | 4031 ALmixer_SetError("%s", |
3710 aluGetErrorString(error) ); | 4032 alGetString(error) ); |
3711 retval = -1; | 4033 retval = AL_FALSE; |
3712 } | 4034 } |
3713 if(ALmixer_Channel_List[channel].max_volume < ALmixer_Channel_List[channel].min_volume) | 4035 if(ALmixer_Channel_List[channel].max_volume < ALmixer_Channel_List[channel].min_volume) |
3714 { | 4036 { |
3715 ALmixer_Channel_List[channel].max_volume = volume; | 4037 ALmixer_Channel_List[channel].max_volume = volume; |
3716 alSourcef(ALmixer_Channel_List[channel].alsource, | 4038 alSourcef(ALmixer_Channel_List[channel].alsource, |
3717 AL_MAX_GAIN, volume); | 4039 AL_MAX_GAIN, volume); |
3718 if((error = alGetError()) != AL_NO_ERROR) | 4040 if((error = alGetError()) != AL_NO_ERROR) |
3719 { | 4041 { |
3720 ALmixer_SetError("%s", | 4042 ALmixer_SetError("%s", |
3721 aluGetErrorString(error) ); | 4043 alGetString(error) ); |
3722 retval = -1; | 4044 retval = AL_FALSE; |
3723 } | 4045 } |
3724 } | 4046 } |
3725 } | 4047 } |
3726 else | 4048 else |
3727 { | 4049 { |
3728 Sint32 i; | 4050 ALint i; |
3729 for(i=0; i<Number_of_Channels_global; i++) | 4051 for(i=0; i<Number_of_Channels_global; i++) |
3730 { | 4052 { |
3731 if(volume < 0.0f) | 4053 if(volume < 0.0f) |
3732 { | 4054 { |
3733 volume = 0.0f; | 4055 volume = 0.0f; |
3740 alSourcef(ALmixer_Channel_List[i].alsource, | 4062 alSourcef(ALmixer_Channel_List[i].alsource, |
3741 AL_MIN_GAIN, volume); | 4063 AL_MIN_GAIN, volume); |
3742 if((error = alGetError()) != AL_NO_ERROR) | 4064 if((error = alGetError()) != AL_NO_ERROR) |
3743 { | 4065 { |
3744 ALmixer_SetError("%s", | 4066 ALmixer_SetError("%s", |
3745 aluGetErrorString(error) ); | 4067 alGetString(error) ); |
3746 retval = -1; | 4068 retval = AL_FALSE; |
3747 } | 4069 } |
3748 if(ALmixer_Channel_List[i].max_volume < ALmixer_Channel_List[i].min_volume) | 4070 if(ALmixer_Channel_List[i].max_volume < ALmixer_Channel_List[i].min_volume) |
3749 { | 4071 { |
3750 ALmixer_Channel_List[i].max_volume = volume; | 4072 ALmixer_Channel_List[i].max_volume = volume; |
3751 alSourcef(ALmixer_Channel_List[i].alsource, | 4073 alSourcef(ALmixer_Channel_List[i].alsource, |
3752 AL_MAX_GAIN, volume); | 4074 AL_MAX_GAIN, volume); |
3753 if((error = alGetError()) != AL_NO_ERROR) | 4075 if((error = alGetError()) != AL_NO_ERROR) |
3754 { | 4076 { |
3755 ALmixer_SetError("%s", | 4077 ALmixer_SetError("%s", |
3756 aluGetErrorString(error) ); | 4078 alGetString(error) ); |
3757 retval = -1; | 4079 retval = AL_FALSE; |
3758 } | 4080 } |
3759 } | 4081 } |
3760 } | 4082 } |
3761 } | 4083 } |
3762 return retval; | 4084 return retval; |
3763 } | 4085 } |
3764 | 4086 |
3765 static Sint32 Internal_SetMinVolumeSource(ALuint source, ALfloat volume) | 4087 static ALboolean Internal_SetMinVolumeSource(ALuint source, ALfloat volume) |
3766 { | 4088 { |
3767 Sint32 channel; | 4089 ALint channel; |
3768 if(0 == source) | 4090 if(0 == source) |
3769 { | 4091 { |
3770 return Internal_SetMinVolumeChannel(-1, volume); | 4092 return Internal_SetMinVolumeChannel(-1, volume); |
3771 } | 4093 } |
3772 | 4094 |
3773 channel = Internal_GetChannel(source); | 4095 channel = Internal_GetChannel(source); |
3774 if(-1 == channel) | 4096 if(-1 == channel) |
3775 { | 4097 { |
3776 ALmixer_SetError("Cannot SetMaxVolume: %s", ALmixer_GetError()); | 4098 ALmixer_SetError("Cannot SetMaxVolume: %s", ALmixer_GetError()); |
3777 return -1; | 4099 return AL_FALSE; |
3778 } | 4100 } |
3779 return Internal_SetMinVolumeChannel(channel, volume); | 4101 return Internal_SetMinVolumeChannel(channel, volume); |
3780 } | 4102 } |
3781 | 4103 |
3782 static ALfloat Internal_GetMinVolumeChannel(Sint32 channel) | 4104 static ALfloat Internal_GetMinVolumeChannel(ALint channel) |
3783 { | 4105 { |
3784 /* | 4106 /* |
3785 ALfloat value; | 4107 ALfloat value; |
3786 ALenum error; | 4108 ALenum error; |
3787 */ | 4109 */ |
3800 alGetSourcef(ALmixer_Channel_List[channel].alsource, | 4122 alGetSourcef(ALmixer_Channel_List[channel].alsource, |
3801 AL_GAIN, &value); | 4123 AL_GAIN, &value); |
3802 if((error = alGetError()) != AL_NO_ERROR) | 4124 if((error = alGetError()) != AL_NO_ERROR) |
3803 { | 4125 { |
3804 ALmixer_SetError("%s", | 4126 ALmixer_SetError("%s", |
3805 aluGetErrorString(error) ); | 4127 alGetString(error) ); |
3806 retval = -1.0f; | 4128 retval = -1.0f; |
3807 } | 4129 } |
3808 else | 4130 else |
3809 { | 4131 { |
3810 retval = value; | 4132 retval = value; |
3813 retval = ALmixer_Channel_List[channel].min_volume; | 4135 retval = ALmixer_Channel_List[channel].min_volume; |
3814 | 4136 |
3815 } | 4137 } |
3816 else | 4138 else |
3817 { | 4139 { |
3818 Sint32 i; | 4140 ALint i; |
3819 for(i=0; i<Number_of_Channels_global; i++) | 4141 for(i=0; i<Number_of_Channels_global; i++) |
3820 { | 4142 { |
3821 /* | 4143 /* |
3822 alGetSourcef(ALmixer_Channel_List[i].alsource, | 4144 alGetSourcef(ALmixer_Channel_List[i].alsource, |
3823 AL_GAIN, &value); | 4145 AL_GAIN, &value); |
3824 if((error = alGetError()) != AL_NO_ERROR) | 4146 if((error = alGetError()) != AL_NO_ERROR) |
3825 { | 4147 { |
3826 ALmixer_SetError("%s", | 4148 ALmixer_SetError("%s", |
3827 aluGetErrorString(error) ); | 4149 alGetString(error) ); |
3828 retval = -1; | 4150 retval = -1; |
3829 } | 4151 } |
3830 else | 4152 else |
3831 { | 4153 { |
3832 running_total += value; | 4154 running_total += value; |
3847 return retval; | 4169 return retval; |
3848 } | 4170 } |
3849 | 4171 |
3850 static ALfloat Internal_GetMinVolumeSource(ALuint source) | 4172 static ALfloat Internal_GetMinVolumeSource(ALuint source) |
3851 { | 4173 { |
3852 Sint32 channel; | 4174 ALint channel; |
3853 if(0 == source) | 4175 if(0 == source) |
3854 { | 4176 { |
3855 return Internal_GetMinVolumeChannel(-1); | 4177 return Internal_GetMinVolumeChannel(-1); |
3856 } | 4178 } |
3857 | 4179 |
3865 return Internal_GetMinVolumeChannel(channel); | 4187 return Internal_GetMinVolumeChannel(channel); |
3866 } | 4188 } |
3867 | 4189 |
3868 | 4190 |
3869 /* Changes the listener volume */ | 4191 /* Changes the listener volume */ |
3870 static Sint32 Internal_SetMasterVolume(ALfloat volume) | 4192 static ALboolean Internal_SetMasterVolume(ALfloat volume) |
3871 { | 4193 { |
3872 ALenum error; | 4194 ALenum error; |
3873 alListenerf(AL_GAIN, volume); | 4195 alListenerf(AL_GAIN, volume); |
3874 if((error = alGetError()) != AL_NO_ERROR) | 4196 if((error = alGetError()) != AL_NO_ERROR) |
3875 { | 4197 { |
3876 ALmixer_SetError("%s", | 4198 ALmixer_SetError("%s", |
3877 aluGetErrorString(error) ); | 4199 alGetString(error) ); |
3878 return -1; | 4200 return AL_FALSE; |
3879 } | 4201 } |
3880 return 0; | 4202 return AL_TRUE; |
3881 } | 4203 } |
3882 | 4204 |
3883 static ALfloat Internal_GetMasterVolume() | 4205 static ALfloat Internal_GetMasterVolume() |
3884 { | 4206 { |
3885 ALenum error; | 4207 ALenum error; |
3886 ALfloat volume; | 4208 ALfloat volume; |
3887 alGetListenerf(AL_GAIN, &volume); | 4209 alGetListenerf(AL_GAIN, &volume); |
3888 if((error = alGetError()) != AL_NO_ERROR) | 4210 if((error = alGetError()) != AL_NO_ERROR) |
3889 { | 4211 { |
3890 ALmixer_SetError("%s", | 4212 ALmixer_SetError("%s", |
3891 aluGetErrorString(error) ); | 4213 alGetString(error) ); |
3892 return -1.0f; | 4214 return -1.0f; |
3893 } | 4215 } |
3894 return volume; | 4216 return volume; |
3895 } | 4217 } |
3896 | 4218 |
3897 | 4219 |
3898 | 4220 |
3899 | 4221 |
3900 /* Will fade out currently playing channels. | 4222 /* Will fade out currently playing channels. |
3901 * It starts at the current volume level and goes down */ | 4223 * It starts at the current volume level and goes down */ |
3902 static Sint32 Internal_ExpireChannel(Sint32 channel, Sint32 ticks) | 4224 static ALint Internal_ExpireChannel(ALint channel, ALint ticks) |
3903 { | 4225 { |
3904 Uint32 current_time = SDL_GetTicks(); | 4226 ALuint current_time = ALmixer_GetTicks(); |
3905 Uint32 counter = 0; | 4227 ALuint counter = 0; |
3906 | 4228 |
3907 /* We can't accept 0 as a value because of div-by-zero. | 4229 /* We can't accept 0 as a value because of div-by-zero. |
3908 * If zero, just call Halt at normal | 4230 * If zero, just call Halt at normal |
3909 * volume | 4231 * volume |
3910 */ | 4232 */ |
3911 if(0 == ticks) | 4233 if(0 == ticks) |
3912 { | 4234 { |
3913 return Internal_HaltChannel(channel); | 4235 return Internal_HaltChannel(channel, AL_TRUE); |
3914 } | 4236 } |
3915 if(ticks < -1) | 4237 if(ticks < -1) |
3916 { | 4238 { |
3917 ticks = -1; | 4239 ticks = -1; |
3918 } | 4240 } |
3937 } | 4259 } |
3938 } | 4260 } |
3939 /* Else need to fade out all channels */ | 4261 /* Else need to fade out all channels */ |
3940 else | 4262 else |
3941 { | 4263 { |
3942 Sint32 i; | 4264 ALint i; |
3943 for(i=0; i<Number_of_Channels_global; i++) | 4265 for(i=0; i<Number_of_Channels_global; i++) |
3944 { | 4266 { |
3945 if(ALmixer_Channel_List[i].channel_in_use) | 4267 if(ALmixer_Channel_List[i].channel_in_use) |
3946 { | 4268 { |
3947 /* Set expire start time */ | 4269 /* Set expire start time */ |
3955 } | 4277 } |
3956 return counter; | 4278 return counter; |
3957 } | 4279 } |
3958 | 4280 |
3959 | 4281 |
3960 static Sint32 Internal_ExpireSource(ALuint source, Sint32 ticks) | 4282 static ALint Internal_ExpireSource(ALuint source, ALint ticks) |
3961 { | 4283 { |
3962 Sint32 channel; | 4284 ALint channel; |
3963 if(0 == source) | 4285 if(0 == source) |
3964 { | 4286 { |
3965 return Internal_ExpireChannel(-1, ticks); | 4287 return Internal_ExpireChannel(-1, ticks); |
3966 } | 4288 } |
3967 | 4289 |
3973 } | 4295 } |
3974 return Internal_ExpireChannel(channel, ticks); | 4296 return Internal_ExpireChannel(channel, ticks); |
3975 } | 4297 } |
3976 | 4298 |
3977 | 4299 |
3978 static Sint32 Internal_QueryChannel(Sint32 channel) | 4300 static ALint Internal_QueryChannel(ALint channel) |
3979 { | 4301 { |
3980 Sint32 i; | 4302 ALint i; |
3981 Sint32 counter = 0; | 4303 ALint counter = 0; |
3982 if(channel >= Number_of_Channels_global) | 4304 if(channel >= Number_of_Channels_global) |
3983 { | 4305 { |
3984 ALmixer_SetError("Invalid channel: %d", channel); | 4306 ALmixer_SetError("Invalid channel: %d", channel); |
3985 return -1; | 4307 return -1; |
3986 } | 4308 } |
4000 } | 4322 } |
4001 return counter; | 4323 return counter; |
4002 } | 4324 } |
4003 | 4325 |
4004 | 4326 |
4005 static Sint32 Internal_QuerySource(ALuint source) | 4327 static ALint Internal_QuerySource(ALuint source) |
4006 { | 4328 { |
4007 Sint32 channel; | 4329 ALint channel; |
4008 if(0 == source) | 4330 if(0 == source) |
4009 { | 4331 { |
4010 return Internal_QueryChannel(-1); | 4332 return Internal_QueryChannel(-1); |
4011 } | 4333 } |
4012 | 4334 |
4019 | 4341 |
4020 return Internal_QueryChannel(channel); | 4342 return Internal_QueryChannel(channel); |
4021 } | 4343 } |
4022 | 4344 |
4023 | 4345 |
4024 static Sint32 Internal_CountUnreservedUsedChannels() | 4346 static ALuint Internal_CountUnreservedUsedChannels() |
4025 { | 4347 { |
4026 Sint32 i; | 4348 ALint i; |
4027 Sint32 counter = 0; | 4349 ALuint counter = 0; |
4028 | 4350 |
4029 | 4351 |
4030 /* Else, return the number of channels in use */ | 4352 /* Else, return the number of channels in use */ |
4031 for(i=Number_of_Reserve_Channels_global; i<Number_of_Channels_global; i++) | 4353 for(i=Number_of_Reserve_Channels_global; i<Number_of_Channels_global; i++) |
4032 { | 4354 { |
4036 } | 4358 } |
4037 } | 4359 } |
4038 return counter; | 4360 return counter; |
4039 } | 4361 } |
4040 | 4362 |
4041 static Sint32 Internal_CountUnreservedFreeChannels() | 4363 static ALuint Internal_CountUnreservedFreeChannels() |
4042 { | 4364 { |
4043 Sint32 i; | 4365 ALint i; |
4044 Sint32 counter = 0; | 4366 ALuint counter = 0; |
4045 | 4367 |
4046 | 4368 |
4047 /* Else, return the number of channels in use */ | 4369 /* Else, return the number of channels in use */ |
4048 for(i=Number_of_Reserve_Channels_global; i<Number_of_Channels_global; i++) | 4370 for(i=Number_of_Reserve_Channels_global; i<Number_of_Channels_global; i++) |
4049 { | 4371 { |
4053 } | 4375 } |
4054 } | 4376 } |
4055 return counter; | 4377 return counter; |
4056 } | 4378 } |
4057 | 4379 |
4058 static Sint32 Internal_CountAllUsedChannels() | 4380 static ALuint Internal_CountAllUsedChannels() |
4059 { | 4381 { |
4060 Sint32 i; | 4382 ALint i; |
4061 Sint32 counter = 0; | 4383 ALuint counter = 0; |
4062 | 4384 |
4063 | 4385 |
4064 /* Else, return the number of channels in use */ | 4386 /* Else, return the number of channels in use */ |
4065 for(i=0; i<Number_of_Channels_global; i++) | 4387 for(i=0; i<Number_of_Channels_global; i++) |
4066 { | 4388 { |
4070 } | 4392 } |
4071 } | 4393 } |
4072 return counter; | 4394 return counter; |
4073 } | 4395 } |
4074 | 4396 |
4075 static Sint32 Internal_CountAllFreeChannels() | 4397 static ALuint Internal_CountAllFreeChannels() |
4076 { | 4398 { |
4077 Sint32 i; | 4399 ALint i; |
4078 Sint32 counter = 0; | 4400 ALuint counter = 0; |
4079 | 4401 |
4080 | 4402 |
4081 /* Else, return the number of channels in use */ | 4403 /* Else, return the number of channels in use */ |
4082 for(i=0; i<Number_of_Channels_global; i++) | 4404 for(i=0; i<Number_of_Channels_global; i++) |
4083 { | 4405 { |
4088 } | 4410 } |
4089 return counter; | 4411 return counter; |
4090 } | 4412 } |
4091 | 4413 |
4092 | 4414 |
4093 static Sint32 Internal_PlayingChannel(Sint32 channel) | 4415 static ALint Internal_PlayingChannel(ALint channel) |
4094 { | 4416 { |
4095 Sint32 i; | 4417 ALint i; |
4096 Sint32 counter = 0; | 4418 ALint counter = 0; |
4097 ALint state; | 4419 ALint state; |
4098 | 4420 |
4099 if(channel >= Number_of_Channels_global) | 4421 if(channel >= Number_of_Channels_global) |
4100 { | 4422 { |
4101 ALmixer_SetError("Invalid channel: %d", channel); | 4423 ALmixer_SetError("Invalid channel: %d", channel); |
4135 } | 4457 } |
4136 return counter; | 4458 return counter; |
4137 } | 4459 } |
4138 | 4460 |
4139 | 4461 |
4140 static Sint32 Internal_PlayingSource(ALuint source) | 4462 static ALint Internal_PlayingSource(ALuint source) |
4141 { | 4463 { |
4142 Sint32 channel; | 4464 ALint channel; |
4143 if(0 == source) | 4465 if(0 == source) |
4144 { | 4466 { |
4145 return Internal_PlayingChannel(-1); | 4467 return Internal_PlayingChannel(-1); |
4146 } | 4468 } |
4147 | 4469 |
4154 | 4476 |
4155 return Internal_PlayingChannel(channel); | 4477 return Internal_PlayingChannel(channel); |
4156 } | 4478 } |
4157 | 4479 |
4158 | 4480 |
4159 static Sint32 Internal_PausedChannel(Sint32 channel) | 4481 static ALint Internal_PausedChannel(ALint channel) |
4160 { | 4482 { |
4161 Sint32 i; | 4483 ALint i; |
4162 Sint32 counter = 0; | 4484 ALint counter = 0; |
4163 ALint state; | 4485 ALint state; |
4164 | 4486 |
4165 if(channel >= Number_of_Channels_global) | 4487 if(channel >= Number_of_Channels_global) |
4166 { | 4488 { |
4167 ALmixer_SetError("Invalid channel: %d", channel); | 4489 ALmixer_SetError("Invalid channel: %d", channel); |
4201 } | 4523 } |
4202 return counter; | 4524 return counter; |
4203 } | 4525 } |
4204 | 4526 |
4205 | 4527 |
4206 static Sint32 Internal_PausedSource(ALuint source) | 4528 static ALint Internal_PausedSource(ALuint source) |
4207 { | 4529 { |
4208 Sint32 channel; | 4530 ALint channel; |
4209 if(0 == source) | 4531 if(0 == source) |
4210 { | 4532 { |
4211 return Internal_PausedChannel(-1); | 4533 return Internal_PausedChannel(-1); |
4212 } | 4534 } |
4213 | 4535 |
4234 * call the next update loop in case you are worried | 4556 * call the next update loop in case you are worried |
4235 * about preserving CPU cycles. The idea is that | 4557 * about preserving CPU cycles. The idea is that |
4236 * when a buffer is queued, there was probably some | 4558 * when a buffer is queued, there was probably some |
4237 * CPU intensive looping which took awhile. | 4559 * CPU intensive looping which took awhile. |
4238 * It's mainly provided as a convenience. | 4560 * It's mainly provided as a convenience. |
4239 * Timing the call with SDL_GetTicks() would produce | 4561 * Timing the call with ALmixer_GetTicks() would produce |
4240 * more accurate information. | 4562 * more accurate information. |
4241 * Returns a negative value if there was an error, | 4563 * Returns a negative value if there was an error, |
4242 * the value being the number of errors. | 4564 * the value being the number of errors. |
4243 */ | 4565 */ |
4244 static Sint32 Update_ALmixer(void* data) | 4566 static ALint Update_ALmixer(void* data) |
4245 { | 4567 { |
4246 Sint32 retval = 0; | 4568 ALint retval = 0; |
4247 Sint32 error_flag = 0; | 4569 ALint error_flag = 0; |
4248 ALenum error; | 4570 ALenum error; |
4249 ALint state; | 4571 ALint state; |
4250 Sint32 i=0; | 4572 ALint i=0; |
4251 | 4573 |
4252 SDL_LockMutex(simple_lock); | 4574 #ifdef ENABLE_ALMIXER_THREADS |
4575 SDL_LockMutex(s_simpleLock); | |
4576 #endif | |
4253 if(0 == ALmixer_Initialized) | 4577 if(0 == ALmixer_Initialized) |
4254 { | 4578 { |
4255 SDL_UnlockMutex(simple_lock); | 4579 #ifdef ENABLE_ALMIXER_THREADS |
4580 SDL_UnlockMutex(s_simpleLock); | |
4581 #endif | |
4256 return 0; | 4582 return 0; |
4257 } | 4583 } |
4258 | 4584 |
4259 /* Check the quick flag to see if anything needs updating */ | 4585 /* Check the quick flag to see if anything needs updating */ |
4260 /* If anything is playing, then we have to do work */ | 4586 /* If anything is playing, then we have to do work */ |
4261 if( 0 == Is_Playing_global) | 4587 if( 0 == Is_Playing_global) |
4262 { | 4588 { |
4263 SDL_UnlockMutex(simple_lock); | 4589 #ifdef ENABLE_ALMIXER_THREADS |
4590 SDL_UnlockMutex(s_simpleLock); | |
4591 #endif | |
4264 return 0; | 4592 return 0; |
4265 } | 4593 } |
4266 /* Clear error */ | 4594 /* Clear error */ |
4267 if((error = alGetError()) != AL_NO_ERROR) | 4595 if((error = alGetError()) != AL_NO_ERROR) |
4268 { | 4596 { |
4269 fprintf(stderr, "08Testing errpr before unqueue because getting stuff, for OS X this is expected: %s\n", | 4597 fprintf(stderr, "08Testing errpr before unqueue because getting stuff, for OS X this is expected: %s\n", |
4270 aluGetErrorString(error)); | 4598 alGetString(error)); |
4271 } | 4599 } |
4272 alGetError(); | 4600 alGetError(); |
4273 | 4601 |
4274 for(i=0; i<Number_of_Channels_global; i++) | 4602 for(i=0; i<Number_of_Channels_global; i++) |
4275 { | 4603 { |
4278 | 4606 |
4279 /* For simplicity, before we do anything else, | 4607 /* For simplicity, before we do anything else, |
4280 * we can check the timeout and fading values | 4608 * we can check the timeout and fading values |
4281 * and do the appropriate things | 4609 * and do the appropriate things |
4282 */ | 4610 */ |
4283 Uint32 current_time = SDL_GetTicks(); | 4611 ALuint current_time = ALmixer_GetTicks(); |
4284 | 4612 |
4285 /* Check to see if we need to halt due to Timed play */ | 4613 /* Check to see if we need to halt due to Timed play */ |
4286 if(ALmixer_Channel_List[i].expire_ticks != -1) | 4614 if(ALmixer_Channel_List[i].expire_ticks != -1) |
4287 { | 4615 { |
4288 Uint32 target_time = (Uint32)ALmixer_Channel_List[i].expire_ticks | 4616 ALuint target_time = (ALuint)ALmixer_Channel_List[i].expire_ticks |
4289 + ALmixer_Channel_List[i].start_time; | 4617 + ALmixer_Channel_List[i].start_time; |
4290 alGetSourcei(ALmixer_Channel_List[i].alsource, | 4618 alGetSourcei(ALmixer_Channel_List[i].alsource, |
4291 AL_SOURCE_STATE, &state); | 4619 AL_SOURCE_STATE, &state); |
4292 if((error = alGetError()) != AL_NO_ERROR) | 4620 if((error = alGetError()) != AL_NO_ERROR) |
4293 { | 4621 { |
4294 fprintf(stderr, "06Testing errpr before unqueue because getting stuff, for OS X this is expected: %s\n", | 4622 fprintf(stderr, "06Testing errpr before unqueue because getting stuff, for OS X this is expected: %s\n", |
4295 aluGetErrorString(error)); | 4623 alGetString(error)); |
4296 } | 4624 } |
4297 | 4625 |
4298 /* Check the time, and also make sure that it is not | 4626 /* Check the time, and also make sure that it is not |
4299 * paused (if paused, we don't want to make the | 4627 * paused (if paused, we don't want to make the |
4300 * evaluation because when resumed, we will adjust | 4628 * evaluation because when resumed, we will adjust |
4302 */ | 4630 */ |
4303 if( (current_time >= target_time) | 4631 if( (current_time >= target_time) |
4304 && (state != AL_PAUSED) ) | 4632 && (state != AL_PAUSED) ) |
4305 { | 4633 { |
4306 /* Stop the playback */ | 4634 /* Stop the playback */ |
4307 ALmixer_HaltChannel(i); | 4635 Internal_HaltChannel(i, AL_TRUE); |
4308 if((error = alGetError()) != AL_NO_ERROR) | 4636 if((error = alGetError()) != AL_NO_ERROR) |
4309 { | 4637 { |
4310 fprintf(stderr, "07Testing errpr before unqueue because getting stuff, for OS X this is expected: %s\n", | 4638 fprintf(stderr, "07Testing errpr before unqueue because getting stuff, for OS X this is expected: %s\n", |
4311 aluGetErrorString(error)); | 4639 alGetString(error)); |
4312 } | 4640 } |
4313 | 4641 |
4314 /* Everything should be done so go on to the next loop */ | 4642 /* Everything should be done so go on to the next loop */ |
4315 continue; | 4643 continue; |
4316 } | 4644 } |
4317 } /* End if time expired check */ | 4645 } /* End if time expired check */ |
4318 | 4646 |
4319 /* Check to see if we need to adjust the volume for fading */ | 4647 /* Check to see if we need to adjust the volume for fading */ |
4320 if( ALmixer_Channel_List[i].fade_enabled ) | 4648 if( ALmixer_Channel_List[i].fade_enabled ) |
4321 { | 4649 { |
4322 Uint32 target_time = ALmixer_Channel_List[i].fade_expire_ticks | 4650 ALuint target_time = ALmixer_Channel_List[i].fade_expire_ticks |
4323 + ALmixer_Channel_List[i].fade_start_time; | 4651 + ALmixer_Channel_List[i].fade_start_time; |
4324 alGetSourcei(ALmixer_Channel_List[i].alsource, | 4652 alGetSourcei(ALmixer_Channel_List[i].alsource, |
4325 AL_SOURCE_STATE, &state); | 4653 AL_SOURCE_STATE, &state); |
4326 if((error = alGetError()) != AL_NO_ERROR) | 4654 if((error = alGetError()) != AL_NO_ERROR) |
4327 { | 4655 { |
4328 fprintf(stderr, "05Testing errpr before unqueue because getting stuff, for OS X this is expected: %s\n", | 4656 fprintf(stderr, "05Testing errpr before unqueue because getting stuff, for OS X this is expected: %s\n", |
4329 aluGetErrorString(error)); | 4657 alGetString(error)); |
4330 } | 4658 } |
4331 | 4659 |
4332 /* Check the time, and also make sure that it is not | 4660 /* Check the time, and also make sure that it is not |
4333 * paused (if paused, we don't want to make the | 4661 * paused (if paused, we don't want to make the |
4334 * evaluation because when resumed, we will adjust | 4662 * evaluation because when resumed, we will adjust |
4335 * the times to compensate for the pause). | 4663 * the times to compensate for the pause). |
4336 */ | 4664 */ |
4337 if(state != AL_PAUSED) | 4665 if(state != AL_PAUSED) |
4338 { | 4666 { |
4339 ALfloat t; | 4667 ALfloat t; |
4340 Uint32 delta_time; | 4668 ALuint delta_time; |
4341 ALfloat current_volume; | 4669 ALfloat current_volume; |
4342 if(current_time >= target_time) | 4670 if(current_time >= target_time) |
4343 { | 4671 { |
4344 /* Need to constrain value to the end time | 4672 /* Need to constrain value to the end time |
4345 * (can't go pass the value for calculations) | 4673 * (can't go pass the value for calculations) |
4368 alSourcef(ALmixer_Channel_List[i].alsource, | 4696 alSourcef(ALmixer_Channel_List[i].alsource, |
4369 AL_MAX_GAIN, current_volume); | 4697 AL_MAX_GAIN, current_volume); |
4370 if((error = alGetError()) != AL_NO_ERROR) | 4698 if((error = alGetError()) != AL_NO_ERROR) |
4371 { | 4699 { |
4372 fprintf(stderr, "04Testing errpr before unqueue because getting stuff, for OS X this is expected: %s\n", | 4700 fprintf(stderr, "04Testing errpr before unqueue because getting stuff, for OS X this is expected: %s\n", |
4373 aluGetErrorString(error)); | 4701 alGetString(error)); |
4374 } | 4702 } |
4375 | 4703 |
4376 /* | 4704 /* |
4377 fprintf(stderr, "Current time =%d\n", current_time); | 4705 fprintf(stderr, "Current time =%d\n", current_time); |
4378 fprintf(stderr, "Current vol=%f on channel %d\n", current_volume, i); | 4706 fprintf(stderr, "Current vol=%f on channel %d\n", current_volume, i); |
4440 */ | 4768 */ |
4441 | 4769 |
4442 if((error = alGetError()) != AL_NO_ERROR) | 4770 if((error = alGetError()) != AL_NO_ERROR) |
4443 { | 4771 { |
4444 fprintf(stderr, "03Testing errpr before unqueue because getting stuff, for OS X this is expected: %s\n", | 4772 fprintf(stderr, "03Testing errpr before unqueue because getting stuff, for OS X this is expected: %s\n", |
4445 aluGetErrorString(error)); | 4773 alGetString(error)); |
4446 } | 4774 } |
4447 | 4775 |
4448 | 4776 |
4449 alGetSourcei( | 4777 alGetSourcei( |
4450 ALmixer_Channel_List[i].alsource, | 4778 ALmixer_Channel_List[i].alsource, |
4451 AL_SOURCE_STATE, &state | 4779 AL_SOURCE_STATE, &state |
4452 ); | 4780 ); |
4453 if((error = alGetError()) != AL_NO_ERROR) | 4781 if((error = alGetError()) != AL_NO_ERROR) |
4454 { | 4782 { |
4455 fprintf(stderr, "02Testing errpr before unqueue because getting stuff, for OS X this is expected: %s\n", | 4783 fprintf(stderr, "02Testing errpr before unqueue because getting stuff, for OS X this is expected: %s\n", |
4456 aluGetErrorString(error)); | 4784 alGetString(error)); |
4457 } | 4785 } |
4458 | 4786 |
4459 | 4787 |
4460 if(AL_STOPPED == state) | 4788 if(AL_STOPPED == state) |
4461 { | 4789 { |
4480 } | 4808 } |
4481 alSourcePlay(ALmixer_Channel_List[i].alsource); | 4809 alSourcePlay(ALmixer_Channel_List[i].alsource); |
4482 if((error = alGetError()) != AL_NO_ERROR) | 4810 if((error = alGetError()) != AL_NO_ERROR) |
4483 { | 4811 { |
4484 fprintf(stderr, "50Testing error: %s\n", | 4812 fprintf(stderr, "50Testing error: %s\n", |
4485 aluGetErrorString(error)); | 4813 alGetString(error)); |
4486 } | 4814 } |
4487 continue; | 4815 continue; |
4488 } | 4816 } |
4489 /* No loops. End play. */ | 4817 /* No loops. End play. */ |
4490 else | 4818 else |
4522 */ | 4850 */ |
4523 ALint buffers_still_queued; | 4851 ALint buffers_still_queued; |
4524 if((error = alGetError()) != AL_NO_ERROR) | 4852 if((error = alGetError()) != AL_NO_ERROR) |
4525 { | 4853 { |
4526 fprintf(stderr, "01Testing errpr before unqueue because getting stuff, for OS X this is expected: %s\n", | 4854 fprintf(stderr, "01Testing errpr before unqueue because getting stuff, for OS X this is expected: %s\n", |
4527 aluGetErrorString(error)); | 4855 alGetString(error)); |
4528 } | 4856 } |
4529 | 4857 |
4530 alGetSourcei( | 4858 alGetSourcei( |
4531 ALmixer_Channel_List[i].alsource, | 4859 ALmixer_Channel_List[i].alsource, |
4532 AL_BUFFERS_QUEUED, &buffers_still_queued | 4860 AL_BUFFERS_QUEUED, &buffers_still_queued |
4533 ); | 4861 ); |
4534 if((error = alGetError()) != AL_NO_ERROR) | 4862 if((error = alGetError()) != AL_NO_ERROR) |
4535 { | 4863 { |
4536 fprintf(stderr, "Error with unqueue, for OS X this is expected: %s\n", | 4864 fprintf(stderr, "Error with unqueue, for OS X this is expected: %s\n", |
4537 aluGetErrorString(error)); | 4865 alGetString(error)); |
4538 ALmixer_SetError("Failed detecting unqueued predecoded buffer (expected with OS X): %s", | 4866 ALmixer_SetError("Failed detecting unqueued predecoded buffer (expected with OS X): %s", |
4539 aluGetErrorString(error) ); | 4867 alGetString(error) ); |
4540 error_flag--; | 4868 error_flag--; |
4541 } | 4869 } |
4542 if(buffers_still_queued > 0) | 4870 if(buffers_still_queued > 0) |
4543 { | 4871 { |
4544 | 4872 |
4563 */ | 4891 */ |
4564 #endif | 4892 #endif |
4565 if((error = alGetError()) != AL_NO_ERROR) | 4893 if((error = alGetError()) != AL_NO_ERROR) |
4566 { | 4894 { |
4567 fprintf(stderr, "Error with unqueue, after alSourceUnqueueBuffers, buffers_still_queued=%d, error is: %s", buffers_still_queued, | 4895 fprintf(stderr, "Error with unqueue, after alSourceUnqueueBuffers, buffers_still_queued=%d, error is: %s", buffers_still_queued, |
4568 aluGetErrorString(error)); | 4896 alGetString(error)); |
4569 ALmixer_SetError("Predecoded Unqueue buffer failed: %s", | 4897 ALmixer_SetError("Predecoded Unqueue buffer failed: %s", |
4570 aluGetErrorString(error) ); | 4898 alGetString(error) ); |
4571 error_flag--; | 4899 error_flag--; |
4572 } | 4900 } |
4573 | 4901 |
4574 } | 4902 } |
4575 | 4903 |
4576 Clean_Channel(i); | 4904 Clean_Channel(i); |
4577 /* Subtract counter */ | 4905 /* Subtract counter */ |
4578 Is_Playing_global--; | 4906 Is_Playing_global--; |
4579 | 4907 |
4580 /* Launch callback */ | 4908 /* Launch callback */ |
4581 Invoke_Channel_Done_Callback(i); | 4909 Invoke_Channel_Done_Callback(i, AL_TRUE); |
4582 | 4910 |
4583 /* We're done for this loop. | 4911 /* We're done for this loop. |
4584 * Go to next channel | 4912 * Go to next channel |
4585 */ | 4913 */ |
4586 continue; | 4914 continue; |
4629 AL_BUFFERS_QUEUED, &buffers_still_queued | 4957 AL_BUFFERS_QUEUED, &buffers_still_queued |
4630 ); | 4958 ); |
4631 if((error = alGetError()) != AL_NO_ERROR) | 4959 if((error = alGetError()) != AL_NO_ERROR) |
4632 { | 4960 { |
4633 fprintf(stderr, "51Testing error: %s\n", | 4961 fprintf(stderr, "51Testing error: %s\n", |
4634 aluGetErrorString(error)); | 4962 alGetString(error)); |
4635 } | 4963 } |
4636 /* Get the number of buffers processed | 4964 /* Get the number of buffers processed |
4637 * so we know if we need to refill | 4965 * so we know if we need to refill |
4638 */ | 4966 */ |
4967 /* WARNING: It looks like Snow Leopard some times crashes on this call under x86_64 | |
4968 * typically when I suffer a lot of buffer underruns. | |
4969 */ | |
4970 // fprintf(stderr, "calling AL_BUFFERS_PROCESSED on source:%d", ALmixer_Channel_List[i].alsource); | |
4639 alGetSourcei( | 4971 alGetSourcei( |
4640 ALmixer_Channel_List[i].alsource, | 4972 ALmixer_Channel_List[i].alsource, |
4641 AL_BUFFERS_PROCESSED, &buffers_processed | 4973 AL_BUFFERS_PROCESSED, &buffers_processed |
4642 ); | 4974 ); |
4643 if((error = alGetError()) != AL_NO_ERROR) | 4975 if((error = alGetError()) != AL_NO_ERROR) |
4644 { | 4976 { |
4645 fprintf(stderr, "52Testing error: %s\n", | 4977 fprintf(stderr, "52Testing error: %s\n", |
4646 aluGetErrorString(error)); | 4978 alGetString(error)); |
4647 } | 4979 } |
4980 // fprintf(stderr, "finished AL_BUFFERS_PROCESSED, buffers_processed=%d", buffers_processed); | |
4648 | 4981 |
4649 /* WTF!!! The Nvidia distribution is failing on the alGetSourcei(source, AL_BUFFER, buf_id) call. | 4982 /* WTF!!! The Nvidia distribution is failing on the alGetSourcei(source, AL_BUFFER, buf_id) call. |
4650 * I need this call to figure out which buffer OpenAL is currently playing. | 4983 * I need this call to figure out which buffer OpenAL is currently playing. |
4651 * It keeps returning an "Invalid Enum" error. | 4984 * It keeps returning an "Invalid Enum" error. |
4652 * This is totally inane! It's a basic query. | 4985 * This is totally inane! It's a basic query. |
4670 AL_BUFFER, ¤t_buffer_id | 5003 AL_BUFFER, ¤t_buffer_id |
4671 ); | 5004 ); |
4672 if((error = alGetError()) != AL_NO_ERROR) | 5005 if((error = alGetError()) != AL_NO_ERROR) |
4673 { | 5006 { |
4674 fprintf(stderr, "53Testing error: %s\n", | 5007 fprintf(stderr, "53Testing error: %s\n", |
4675 aluGetErrorString(error)); | 5008 alGetString(error)); |
4676 } | 5009 } |
4677 | 5010 |
4678 /* Before the hard stuff, check to see if the | 5011 /* Before the hard stuff, check to see if the |
4679 * current queued AL buffer has changed. | 5012 * current queued AL buffer has changed. |
4680 * If it has, we should launch a data callback if | 5013 * If it has, we should launch a data callback if |
4699 && ( | 5032 && ( |
4700 (buffers_processed > 0) || (0 == ALmixer_Channel_List[i].almixer_data->current_buffer) | 5033 (buffers_processed > 0) || (0 == ALmixer_Channel_List[i].almixer_data->current_buffer) |
4701 ) | 5034 ) |
4702 ) | 5035 ) |
4703 { | 5036 { |
4704 Uint32 k; | 5037 ALint k; |
4705 Uint32 queue_ret_flag; | 5038 ALuint queue_ret_flag; |
4706 Uint8 is_out_of_sync = 0; | 5039 ALubyte is_out_of_sync = 0; |
4707 Uint32 my_queue_size = CircularQueueUnsignedInt_Size(ALmixer_Channel_List[i].almixer_data->circular_buffer_queue); | 5040 ALuint my_queue_size = CircularQueueUnsignedInt_Size(ALmixer_Channel_List[i].almixer_data->circular_buffer_queue); |
4708 /* Ugh, I have to deal with signed/unsigned mismatch here. */ | 5041 /* Ugh, I have to deal with signed/unsigned mismatch here. */ |
4709 ALint buffers_unplayed_int = buffers_still_queued - buffers_processed; | 5042 ALint buffers_unplayed_int = buffers_still_queued - buffers_processed; |
4710 Uint32 unplayed_buffers; | 5043 ALuint unplayed_buffers; |
4711 if(buffers_unplayed_int < 0) | 5044 if(buffers_unplayed_int < 0) |
4712 { | 5045 { |
4713 unplayed_buffers = 0; | 5046 unplayed_buffers = 0; |
4714 } | 5047 } |
4715 else | 5048 else |
4716 { | 5049 { |
4717 unplayed_buffers = (Uint32)buffers_unplayed_int; | 5050 unplayed_buffers = (ALuint)buffers_unplayed_int; |
4718 } | 5051 } |
4719 /* | 5052 /* |
4720 fprintf(stderr, "Queue in processed check, before pop, buffers_processed=%d\n", buffers_processed); | 5053 fprintf(stderr, "Queue in processed check, before pop, buffers_processed=%d\n", buffers_processed); |
4721 CircularQueueUnsignedInt_Print(ALmixer_Channel_List[i].almixer_data->circular_buffer_queue); | 5054 CircularQueueUnsignedInt_Print(ALmixer_Channel_List[i].almixer_data->circular_buffer_queue); |
4722 */ | 5055 */ |
4742 /* First, let's syncronize our queue with the OpenAL queue */ | 5075 /* First, let's syncronize our queue with the OpenAL queue */ |
4743 #if 0 | 5076 #if 0 |
4744 fprintf(stderr, "inside, Buffers processed=%d, Buffers queued=%d, my queue=%d\n", | 5077 fprintf(stderr, "inside, Buffers processed=%d, Buffers queued=%d, my queue=%d\n", |
4745 buffers_processed, buffers_still_queued, my_queue_size); | 5078 buffers_processed, buffers_still_queued, my_queue_size); |
4746 #endif | 5079 #endif |
4747 if(my_queue_size > unplayed_buffers) | 5080 is_out_of_sync = 1; |
5081 for(k=0; k<buffers_processed; k++) | |
4748 { | 5082 { |
4749 is_out_of_sync = 1; | 5083 queue_ret_flag = CircularQueueUnsignedInt_PopFront( |
4750 for(k=0; k<(my_queue_size - unplayed_buffers); k++) | 5084 ALmixer_Channel_List[i].almixer_data->circular_buffer_queue); |
5085 if(0 == queue_ret_flag) | |
4751 { | 5086 { |
4752 queue_ret_flag = CircularQueueUnsignedInt_PopFront( | 5087 fprintf(stderr, "53 Error popping queue\n"); |
4753 ALmixer_Channel_List[i].almixer_data->circular_buffer_queue); | 5088 } |
4754 if(0 == queue_ret_flag) | 5089 } |
4755 { | |
4756 fprintf(stderr, "53 Error popping queue\n"); | |
4757 } | |
4758 } | |
4759 } | |
4760 my_queue_size = CircularQueueUnsignedInt_Size(ALmixer_Channel_List[i].almixer_data->circular_buffer_queue); | 5090 my_queue_size = CircularQueueUnsignedInt_Size(ALmixer_Channel_List[i].almixer_data->circular_buffer_queue); |
4761 /* We have several possibilities we need to handle: | 5091 /* We have several possibilities we need to handle: |
4762 * 1) We are in an initial state or underrun and need to do a data callback on the head. | 5092 * 1) We are in an initial state or underrun and need to do a data callback on the head. |
4763 * 2) We were out of sync and need to do a new data callback on the new head. | 5093 * 2) We were out of sync and need to do a new data callback on the new head. |
4764 * 3) We were not out of sync but just had left over processed buffers which caused us to | 5094 * 3) We were not out of sync but just had left over processed buffers which caused us to |
4844 * We also might find no buffers we need to fill, | 5174 * We also might find no buffers we need to fill, |
4845 * in which case we just keep going | 5175 * in which case we just keep going |
4846 */ | 5176 */ |
4847 if( ! ALmixer_Channel_List[i].almixer_data->eof) | 5177 if( ! ALmixer_Channel_List[i].almixer_data->eof) |
4848 { | 5178 { |
4849 Uint32 bytes_returned; | 5179 ALuint bytes_returned; |
4850 /* We have a priority. We first must assign | 5180 /* We have a priority. We first must assign |
4851 * unused buffers in reserve. If there is nothing | 5181 * unused buffers in reserve. If there is nothing |
4852 * left, then we may unqueue buffers. We can't | 5182 * left, then we may unqueue buffers. We can't |
4853 * do it the other way around because we will | 5183 * do it the other way around because we will |
4854 * lose the pointer to the unqueued buffer | 5184 * lose the pointer to the unqueued buffer |
4887 1, &unqueued_buffer_id | 5217 1, &unqueued_buffer_id |
4888 ); | 5218 ); |
4889 if((error = alGetError()) != AL_NO_ERROR) | 5219 if((error = alGetError()) != AL_NO_ERROR) |
4890 { | 5220 { |
4891 fprintf(stderr, "Error with unqueue: %s", | 5221 fprintf(stderr, "Error with unqueue: %s", |
4892 aluGetErrorString(error)); | 5222 alGetString(error)); |
4893 ALmixer_SetError("Unqueue buffer failed: %s", | 5223 ALmixer_SetError("Unqueue buffer failed: %s", |
4894 aluGetErrorString(error) ); | 5224 alGetString(error) ); |
4895 error_flag--; | 5225 error_flag--; |
4896 } | 5226 } |
4897 /* | 5227 /* |
4898 fprintf(stderr, "Right after unqueue..."); | 5228 fprintf(stderr, "Right after unqueue..."); |
4899 PrintQueueStatus(ALmixer_Channel_List[i].alsource); | 5229 PrintQueueStatus(ALmixer_Channel_List[i].alsource); |
4908 * don't need to fill any buffers */ | 5238 * don't need to fill any buffers */ |
4909 else | 5239 else |
4910 { | 5240 { |
4911 /* Might want to check state */ | 5241 /* Might want to check state */ |
4912 /* In case the playback stopped, | 5242 /* In case the playback stopped, |
4913 * we need to resume */ | 5243 * we need to resume |
5244 * a.k.a. buffer underrun | |
5245 */ | |
4914 #if 1 | 5246 #if 1 |
4915 /* Try not refetching the state here because I'm getting a duplicate | 5247 /* Try not refetching the state here because I'm getting a duplicate |
4916 buffer playback (hiccup) */ | 5248 buffer playback (hiccup) */ |
4917 alGetSourcei( | 5249 alGetSourcei( |
4918 ALmixer_Channel_List[i].alsource, | 5250 ALmixer_Channel_List[i].alsource, |
4919 AL_SOURCE_STATE, &state | 5251 AL_SOURCE_STATE, &state |
4920 ); | 5252 ); |
4921 if((error = alGetError()) != AL_NO_ERROR) | 5253 if((error = alGetError()) != AL_NO_ERROR) |
4922 { | 5254 { |
4923 fprintf(stderr, "54bTesting error: %s\n", | 5255 fprintf(stderr, "54bTesting error: %s\n", |
4924 aluGetErrorString(error)); | 5256 alGetString(error)); |
4925 } | 5257 } |
4926 /* Get the number of buffers processed | 5258 /* Get the number of buffers processed |
4927 */ | 5259 */ |
4928 alGetSourcei( | 5260 alGetSourcei( |
4929 ALmixer_Channel_List[i].alsource, | 5261 ALmixer_Channel_List[i].alsource, |
4931 &buffers_processed | 5263 &buffers_processed |
4932 ); | 5264 ); |
4933 if((error = alGetError()) != AL_NO_ERROR) | 5265 if((error = alGetError()) != AL_NO_ERROR) |
4934 { | 5266 { |
4935 fprintf(stderr, "54cError, Can't get buffers_processed: %s\n", | 5267 fprintf(stderr, "54cError, Can't get buffers_processed: %s\n", |
4936 aluGetErrorString(error)); | 5268 alGetString(error)); |
4937 } | 5269 } |
4938 #endif | 5270 #endif |
4939 if(AL_STOPPED == state) | 5271 if(AL_STOPPED == state) |
4940 { | 5272 { |
4941 /* Resuming in not eof, but nothing to buffer */ | 5273 /* Resuming in not eof, but nothing to buffer */ |
4956 * There is currently an assumption that a buffer | 5288 * There is currently an assumption that a buffer |
4957 * was queued above so I actually have something | 5289 * was queued above so I actually have something |
4958 * to play. | 5290 * to play. |
4959 */ | 5291 */ |
4960 ALint temp_count; | 5292 ALint temp_count; |
4961 /* | 5293 #if 0 |
4962 fprintf(stderr, "STOPPED1, need to clear processed, status is:\n"); | 5294 fprintf(stderr, "STOPPED1, need to clear processed=%d, status is:\n", buffers_processed); |
4963 PrintQueueStatus(ALmixer_Channel_List[i].alsource); | 5295 PrintQueueStatus(ALmixer_Channel_List[i].alsource); |
4964 */ | 5296 #endif |
4965 for(temp_count=0; temp_count<buffers_processed; temp_count++) | 5297 for(temp_count=0; temp_count<buffers_processed; temp_count++) |
4966 { | 5298 { |
4967 alSourceUnqueueBuffers( | 5299 alSourceUnqueueBuffers( |
4968 ALmixer_Channel_List[i].alsource, | 5300 ALmixer_Channel_List[i].alsource, |
4969 1, &unqueued_buffer_id | 5301 1, &unqueued_buffer_id |
4970 ); | 5302 ); |
4971 if((error = alGetError()) != AL_NO_ERROR) | 5303 if((error = alGetError()) != AL_NO_ERROR) |
4972 { | 5304 { |
4973 fprintf(stderr, "55aTesting error: %s\n", | 5305 fprintf(stderr, "55aTesting error: %s\n", |
4974 aluGetErrorString(error)); | 5306 alGetString(error)); |
4975 error_flag--; | 5307 error_flag--; |
4976 } | 5308 } |
4977 } | 5309 } |
4978 /* | 5310 #if 0 |
4979 fprintf(stderr, "After unqueue clear...:\n"); | 5311 fprintf(stderr, "After unqueue clear...:\n"); |
4980 PrintQueueStatus(ALmixer_Channel_List[i].alsource); | 5312 PrintQueueStatus(ALmixer_Channel_List[i].alsource); |
4981 */ | 5313 #endif |
4982 alSourcePlay(ALmixer_Channel_List[i].alsource); | 5314 /* My assertion: We are STOPPED but not EOF. |
5315 * This means we have a buffer underrun. | |
5316 * We just cleared out the unqueued buffers. | |
5317 * So we need to reset the mixer_data to reflect we have | |
5318 * no buffers in queue. | |
5319 * We need to GetMoreData and then queue up the data. | |
5320 * Then we need to resume playing. | |
5321 */ | |
5322 #if 0 | |
5323 int buffers_queued; | |
5324 alGetSourcei( | |
5325 ALmixer_Channel_List[i].alsource, | |
5326 AL_BUFFERS_QUEUED, | |
5327 &buffers_queued | |
5328 ); | |
5329 | |
4983 if((error = alGetError()) != AL_NO_ERROR) | 5330 if((error = alGetError()) != AL_NO_ERROR) |
4984 { | 5331 { |
4985 fprintf(stderr, "55Tbesting error: %s\n", | 5332 fprintf(stderr, "Error in PrintQueueStatus, Can't get buffers_queued: %s\n", |
4986 aluGetErrorString(error)); | 5333 alGetString(error)); |
5334 } | |
5335 assert(buffers_queued == 0); | |
5336 fprintf(stderr, "buffer underrun: buffers_queued:%d\n", buffers_queued); | |
5337 #endif | |
5338 | |
5339 /* Reset the number of buffers in use to 0 */ | |
5340 ALmixer_Channel_List[i].almixer_data->num_buffers_in_use = 0; | |
5341 | |
5342 /* Get more data and put it in the first buffer */ | |
5343 bytes_returned = GetMoreData( | |
5344 ALmixer_Channel_List[i].almixer_data, | |
5345 ALmixer_Channel_List[i].almixer_data->buffer[0] | |
5346 ); | |
5347 /* NOTE: We might want to look for EOF and handle it here. | |
5348 * Currently, I just let the next loop handle it which seems to be working. | |
5349 */ | |
5350 if(bytes_returned > 0) | |
5351 { | |
5352 /* Queue up the new data */ | |
5353 alSourceQueueBuffers( | |
5354 ALmixer_Channel_List[i].alsource, | |
5355 1, | |
5356 &ALmixer_Channel_List[i].almixer_data->buffer[0] | |
5357 ); | |
5358 if((error = alGetError()) != AL_NO_ERROR) | |
5359 { | |
5360 fprintf(stderr, "56e alSourceQueueBuffers error: %s\n", | |
5361 alGetString(error)); | |
5362 } | |
5363 /* Increment the number of buffers in use */ | |
5364 ALmixer_Channel_List[i].almixer_data->num_buffers_in_use++; | |
5365 | |
5366 | |
5367 /* We need to empty and update the circular buffer queue if it is in use */ | |
5368 if(ALmixer_Channel_List[i].almixer_data->circular_buffer_queue != NULL) | |
5369 { | |
5370 ALuint queue_ret_flag; | |
5371 CircularQueueUnsignedInt_Clear(ALmixer_Channel_List[i].almixer_data->circular_buffer_queue); | |
5372 queue_ret_flag = CircularQueueUnsignedInt_PushBack( | |
5373 ALmixer_Channel_List[i].almixer_data->circular_buffer_queue, | |
5374 ALmixer_Channel_List[i].almixer_data->buffer[0] | |
5375 ); | |
5376 if(0 == queue_ret_flag) | |
5377 { | |
5378 fprintf(stderr, "56fSerious internal error: CircularQueue could not push into queue.\n"); | |
5379 ALmixer_SetError("Serious internal error: CircularQueue failed to push into queue"); | |
5380 } | |
5381 } | |
5382 | |
5383 | |
5384 | |
5385 | |
5386 /* Resume playback from underrun */ | |
5387 alSourcePlay(ALmixer_Channel_List[i].alsource); | |
5388 if((error = alGetError()) != AL_NO_ERROR) | |
5389 { | |
5390 fprintf(stderr, "55Tbesting error: %s\n", | |
5391 alGetString(error)); | |
5392 } | |
4987 } | 5393 } |
5394 | |
4988 } | 5395 } |
4989 /* Let's escape to the next loop. | 5396 /* Let's escape to the next loop. |
4990 * All code below this point is for queuing up | 5397 * All code below this point is for queuing up |
4991 */ | 5398 */ |
4992 /* | 5399 /* |
5000 | 5407 |
5001 /* In the previous branch, we just grabbed more data. | 5408 /* In the previous branch, we just grabbed more data. |
5002 * Let's check it to make sure it's okay, | 5409 * Let's check it to make sure it's okay, |
5003 * and then queue it up | 5410 * and then queue it up |
5004 */ | 5411 */ |
5005 /* This check doesn't work anymore because it is now Uint32 */ | 5412 /* This check doesn't work anymore because it is now ALuint */ |
5006 #if 0 | 5413 #if 0 |
5007 if(-1 == bytes_returned) | 5414 if(-1 == bytes_returned) |
5008 { | 5415 { |
5009 /* Problem occurred...not sure what to do */ | 5416 /* Problem occurred...not sure what to do */ |
5010 /* Go to next loop? */ | 5417 /* Go to next loop? */ |
5149 ALmixer_Channel_List[i].almixer_data->num_buffers_in_use] | 5556 ALmixer_Channel_List[i].almixer_data->num_buffers_in_use] |
5150 ); | 5557 ); |
5151 if((error = alGetError()) != AL_NO_ERROR) | 5558 if((error = alGetError()) != AL_NO_ERROR) |
5152 { | 5559 { |
5153 fprintf(stderr, "56Testing error: %s\n", | 5560 fprintf(stderr, "56Testing error: %s\n", |
5154 aluGetErrorString(error)); | 5561 alGetString(error)); |
5155 } | 5562 } |
5156 /* This is part of the hideous Nvidia workaround. In order to figure out | 5563 /* This is part of the hideous Nvidia workaround. In order to figure out |
5157 * which buffer to show during callbacks (for things like | 5564 * which buffer to show during callbacks (for things like |
5158 * o-scopes), I must keep a copy of the buffers that are queued in my own | 5565 * o-scopes), I must keep a copy of the buffers that are queued in my own |
5159 * data structure. This code will be called only if | 5566 * data structure. This code will be called only if |
5160 * "access_data" was set, indicated by whether the queue is NULL. | 5567 * "access_data" was set, indicated by whether the queue is NULL. |
5161 */ | 5568 */ |
5162 if(ALmixer_Channel_List[i].almixer_data->circular_buffer_queue != NULL) | 5569 if(ALmixer_Channel_List[i].almixer_data->circular_buffer_queue != NULL) |
5163 { | 5570 { |
5164 Uint32 queue_ret_flag; | 5571 ALuint queue_ret_flag; |
5572 // fprintf(stderr, "56d: CircularQueue_PushBack.\n"); | |
5165 queue_ret_flag = CircularQueueUnsignedInt_PushBack( | 5573 queue_ret_flag = CircularQueueUnsignedInt_PushBack( |
5166 ALmixer_Channel_List[i].almixer_data->circular_buffer_queue, | 5574 ALmixer_Channel_List[i].almixer_data->circular_buffer_queue, |
5167 ALmixer_Channel_List[i].almixer_data->buffer[ALmixer_Channel_List[i].almixer_data->num_buffers_in_use] | 5575 ALmixer_Channel_List[i].almixer_data->buffer[ALmixer_Channel_List[i].almixer_data->num_buffers_in_use] |
5168 ); | 5576 ); |
5169 if(0 == queue_ret_flag) | 5577 if(0 == queue_ret_flag) |
5194 ALmixer_Channel_List[i].alsource, | 5602 ALmixer_Channel_List[i].alsource, |
5195 1, &unqueued_buffer_id); | 5603 1, &unqueued_buffer_id); |
5196 if((error = alGetError()) != AL_NO_ERROR) | 5604 if((error = alGetError()) != AL_NO_ERROR) |
5197 { | 5605 { |
5198 ALmixer_SetError("Could not QueueBuffer: %s", | 5606 ALmixer_SetError("Could not QueueBuffer: %s", |
5199 aluGetErrorString(error) ); | 5607 alGetString(error) ); |
5200 error_flag--; | 5608 error_flag--; |
5201 continue; | 5609 continue; |
5202 } | 5610 } |
5203 /* This is part of the hideous Nvidia workaround. In order to figure out | 5611 /* This is part of the hideous Nvidia workaround. In order to figure out |
5204 * which buffer to show during callbacks (for things like | 5612 * which buffer to show during callbacks (for things like |
5206 * data structure. This code will be called only if | 5614 * data structure. This code will be called only if |
5207 * "access_data" was set, indicated by whether the queue is NULL. | 5615 * "access_data" was set, indicated by whether the queue is NULL. |
5208 */ | 5616 */ |
5209 if(ALmixer_Channel_List[i].almixer_data->circular_buffer_queue != NULL) | 5617 if(ALmixer_Channel_List[i].almixer_data->circular_buffer_queue != NULL) |
5210 { | 5618 { |
5211 Uint32 queue_ret_flag; | 5619 ALuint queue_ret_flag; |
5620 // fprintf(stderr, "56e: CircularQueue_PushBack.\n"); | |
5212 queue_ret_flag = CircularQueueUnsignedInt_PushBack( | 5621 queue_ret_flag = CircularQueueUnsignedInt_PushBack( |
5213 ALmixer_Channel_List[i].almixer_data->circular_buffer_queue, | 5622 ALmixer_Channel_List[i].almixer_data->circular_buffer_queue, |
5214 unqueued_buffer_id | 5623 unqueued_buffer_id |
5215 ); | 5624 ); |
5216 if(0 == queue_ret_flag) | 5625 if(0 == queue_ret_flag) |
5217 { | 5626 { |
5218 fprintf(stderr, "56bSerious internal error: CircularQueue could not push into queue.\n"); | 5627 fprintf(stderr, "56bSerious internal error: CircularQueue could not push into queue.\n"); |
5219 ALmixer_SetError("Serious internal error: CircularQueue failed to push into queue"); | 5628 ALmixer_SetError("Serious internal error: CircularQueue failed to push into queue"); |
5220 } | 5629 } |
5221 /* | 5630 #if 0 |
5222 else | 5631 else |
5223 { | 5632 { |
5224 CircularQueueUnsignedInt_Print(ALmixer_Channel_List[i].almixer_data->circular_buffer_queue); | 5633 CircularQueueUnsignedInt_Print(ALmixer_Channel_List[i].almixer_data->circular_buffer_queue); |
5225 } | 5634 } |
5226 */ | 5635 #endif |
5227 } | 5636 } |
5228 } | 5637 } |
5229 /* If we used an available buffer queue, | 5638 /* If we used an available buffer queue, |
5230 * then we need to update the number of them in use | 5639 * then we need to update the number of them in use |
5231 */ | 5640 */ |
5246 AL_SOURCE_STATE, &state | 5655 AL_SOURCE_STATE, &state |
5247 ); | 5656 ); |
5248 if((error = alGetError()) != AL_NO_ERROR) | 5657 if((error = alGetError()) != AL_NO_ERROR) |
5249 { | 5658 { |
5250 fprintf(stderr, "57bTesting error: %s\n", | 5659 fprintf(stderr, "57bTesting error: %s\n", |
5251 aluGetErrorString(error)); | 5660 alGetString(error)); |
5252 } | 5661 } |
5253 /* Get the number of buffers processed | 5662 /* Get the number of buffers processed |
5254 */ | 5663 */ |
5255 alGetSourcei( | 5664 alGetSourcei( |
5256 ALmixer_Channel_List[i].alsource, | 5665 ALmixer_Channel_List[i].alsource, |
5258 &buffers_processed | 5667 &buffers_processed |
5259 ); | 5668 ); |
5260 if((error = alGetError()) != AL_NO_ERROR) | 5669 if((error = alGetError()) != AL_NO_ERROR) |
5261 { | 5670 { |
5262 fprintf(stderr, "57cError, Can't get buffers_processed: %s\n", | 5671 fprintf(stderr, "57cError, Can't get buffers_processed: %s\n", |
5263 aluGetErrorString(error)); | 5672 alGetString(error)); |
5264 } | 5673 } |
5265 #endif | 5674 #endif |
5266 if(AL_STOPPED == state) | 5675 if(AL_STOPPED == state) |
5267 { | 5676 { |
5268 /* | 5677 /* |
5298 1, &unqueued_buffer_id | 5707 1, &unqueued_buffer_id |
5299 ); | 5708 ); |
5300 if((error = alGetError()) != AL_NO_ERROR) | 5709 if((error = alGetError()) != AL_NO_ERROR) |
5301 { | 5710 { |
5302 fprintf(stderr, "58aTesting error: %s\n", | 5711 fprintf(stderr, "58aTesting error: %s\n", |
5303 aluGetErrorString(error)); | 5712 alGetString(error)); |
5304 error_flag--; | 5713 error_flag--; |
5305 } | 5714 } |
5306 } | 5715 } |
5307 /* | 5716 /* |
5308 fprintf(stderr, "After unqueue clear...:\n"); | 5717 fprintf(stderr, "After unqueue clear...:\n"); |
5311 | 5720 |
5312 alSourcePlay(ALmixer_Channel_List[i].alsource); | 5721 alSourcePlay(ALmixer_Channel_List[i].alsource); |
5313 if((error = alGetError()) != AL_NO_ERROR) | 5722 if((error = alGetError()) != AL_NO_ERROR) |
5314 { | 5723 { |
5315 fprintf(stderr, "55Tbesting 8rror: %s\n", | 5724 fprintf(stderr, "55Tbesting 8rror: %s\n", |
5316 aluGetErrorString(error)); | 5725 alGetString(error)); |
5317 } | 5726 } |
5318 } | 5727 } |
5319 continue; | 5728 continue; |
5320 } /* END if( ! eof) */ | 5729 } /* END if( ! eof) */ |
5321 /* We have hit EOF in the SDL_Sound sample and there | 5730 /* We have hit EOF in the SDL_Sound sample and there |
5329 { | 5738 { |
5330 /* Let's continue to remove the used up | 5739 /* Let's continue to remove the used up |
5331 * buffers as they come in. */ | 5740 * buffers as they come in. */ |
5332 if(buffers_processed > 0) | 5741 if(buffers_processed > 0) |
5333 { | 5742 { |
5334 Sint32 temp_count; | 5743 ALint temp_count; |
5335 /* Do as a for-loop because I don't want | 5744 /* Do as a for-loop because I don't want |
5336 * to have to create an array for the | 5745 * to have to create an array for the |
5337 * unqueued_buffer_id's | 5746 * unqueued_buffer_id's |
5338 */ | 5747 */ |
5339 for(temp_count=0; temp_count<buffers_processed; temp_count++) | 5748 for(temp_count=0; temp_count<buffers_processed; temp_count++) |
5344 1, &unqueued_buffer_id | 5753 1, &unqueued_buffer_id |
5345 ); | 5754 ); |
5346 if((error = alGetError()) != AL_NO_ERROR) | 5755 if((error = alGetError()) != AL_NO_ERROR) |
5347 { | 5756 { |
5348 fprintf(stderr, "59Testing error: %s\n", | 5757 fprintf(stderr, "59Testing error: %s\n", |
5349 aluGetErrorString(error)); | 5758 alGetString(error)); |
5350 } | 5759 } |
5351 } | 5760 } |
5352 fprintf(stderr, "done unqueuing remainder for this loop, %d\n", temp_count); | 5761 fprintf(stderr, "done unqueuing remainder for this loop, %d\n", temp_count); |
5353 | 5762 |
5354 /* Need to update counts since we removed everything. | 5763 /* Need to update counts since we removed everything. |
5360 AL_BUFFERS_QUEUED, &buffers_still_queued | 5769 AL_BUFFERS_QUEUED, &buffers_still_queued |
5361 ); | 5770 ); |
5362 if((error = alGetError()) != AL_NO_ERROR) | 5771 if((error = alGetError()) != AL_NO_ERROR) |
5363 { | 5772 { |
5364 fprintf(stderr, "5100Testing error: %s\n", | 5773 fprintf(stderr, "5100Testing error: %s\n", |
5365 aluGetErrorString(error)); | 5774 alGetString(error)); |
5366 } | 5775 } |
5367 /* Get the number of buffers processed | 5776 /* Get the number of buffers processed |
5368 * so we know if we need to refill | 5777 * so we know if we need to refill |
5369 */ | 5778 */ |
5370 alGetSourcei( | 5779 alGetSourcei( |
5372 AL_BUFFERS_PROCESSED, &buffers_processed | 5781 AL_BUFFERS_PROCESSED, &buffers_processed |
5373 ); | 5782 ); |
5374 if((error = alGetError()) != AL_NO_ERROR) | 5783 if((error = alGetError()) != AL_NO_ERROR) |
5375 { | 5784 { |
5376 fprintf(stderr, "5200Testing error: %s\n", | 5785 fprintf(stderr, "5200Testing error: %s\n", |
5377 aluGetErrorString(error)); | 5786 alGetString(error)); |
5378 } | 5787 } |
5379 } | 5788 } |
5380 | 5789 |
5381 | 5790 |
5382 /* Else if buffers_processed == 0 | 5791 /* Else if buffers_processed == 0 |
5397 AL_SOURCE_STATE, &state | 5806 AL_SOURCE_STATE, &state |
5398 ); | 5807 ); |
5399 if((error = alGetError()) != AL_NO_ERROR) | 5808 if((error = alGetError()) != AL_NO_ERROR) |
5400 { | 5809 { |
5401 fprintf(stderr, "60Testing error: %s\n", | 5810 fprintf(stderr, "60Testing error: %s\n", |
5402 aluGetErrorString(error)); | 5811 alGetString(error)); |
5403 } | 5812 } |
5404 if(AL_STOPPED == state) | 5813 if(AL_STOPPED == state) |
5405 { | 5814 { |
5406 ALmixer_Channel_List[i].almixer_data->num_buffers_in_use = 0; | 5815 ALmixer_Channel_List[i].almixer_data->num_buffers_in_use = 0; |
5407 /* Playback has ended. | 5816 /* Playback has ended. |
5412 Clean_Channel(i); | 5821 Clean_Channel(i); |
5413 /* Subtract counter */ | 5822 /* Subtract counter */ |
5414 Is_Playing_global--; | 5823 Is_Playing_global--; |
5415 | 5824 |
5416 /* Launch callback */ | 5825 /* Launch callback */ |
5417 Invoke_Channel_Done_Callback(i); | 5826 Invoke_Channel_Done_Callback(i, AL_TRUE); |
5418 | 5827 |
5419 /* We're done for this loop. | 5828 /* We're done for this loop. |
5420 * Go to next channel | 5829 * Go to next channel |
5421 */ | 5830 */ |
5422 continue; | 5831 continue; |
5434 AL_SOURCE_STATE, &state | 5843 AL_SOURCE_STATE, &state |
5435 ); | 5844 ); |
5436 if((error = alGetError()) != AL_NO_ERROR) | 5845 if((error = alGetError()) != AL_NO_ERROR) |
5437 { | 5846 { |
5438 fprintf(stderr, "61Testing error: %s\n", | 5847 fprintf(stderr, "61Testing error: %s\n", |
5439 aluGetErrorString(error)); | 5848 alGetString(error)); |
5440 } | 5849 } |
5441 if(AL_STOPPED == state) | 5850 if(AL_STOPPED == state) |
5442 { | 5851 { |
5443 fprintf(stderr, "Shouldn't be here. %d Buffers still in queue, but play stopped. This might be correct though because race conditions could have caused the STOP to happen right after our other tests...Checking queue status...\n", buffers_still_queued); | 5852 fprintf(stderr, "Shouldn't be here. %d Buffers still in queue, but play stopped. This might be correct though because race conditions could have caused the STOP to happen right after our other tests...Checking queue status...\n", buffers_still_queued); |
5444 /* | 5853 /* |
5471 #ifdef ENABLE_ALMIXER_ALC_SYNC | 5880 #ifdef ENABLE_ALMIXER_ALC_SYNC |
5472 alcProcessContext(alcGetCurrentContext()); | 5881 alcProcessContext(alcGetCurrentContext()); |
5473 if((error = alGetError()) != AL_NO_ERROR) | 5882 if((error = alGetError()) != AL_NO_ERROR) |
5474 { | 5883 { |
5475 fprintf(stderr, "62Testing error: %s\n", | 5884 fprintf(stderr, "62Testing error: %s\n", |
5476 aluGetErrorString(error)); | 5885 alGetString(error)); |
5477 } | 5886 } |
5478 #endif | 5887 #endif |
5479 | 5888 |
5480 SDL_UnlockMutex(simple_lock); | 5889 #ifdef ENABLE_ALMIXER_THREADS |
5890 SDL_UnlockMutex(s_simpleLock); | |
5891 #endif | |
5481 /* Return the number of errors */ | 5892 /* Return the number of errors */ |
5482 if(error_flag < 0) | 5893 if(error_flag < 0) |
5483 { | 5894 { |
5484 return error_flag; | 5895 return error_flag; |
5485 } | 5896 } |
5487 return retval; | 5898 return retval; |
5488 } | 5899 } |
5489 | 5900 |
5490 #ifdef ENABLE_PARANOID_SIGNEDNESS_CHECK | 5901 #ifdef ENABLE_PARANOID_SIGNEDNESS_CHECK |
5491 /* This is only here so we can call SDL_OpenAudio() */ | 5902 /* This is only here so we can call SDL_OpenAudio() */ |
5492 static void my_dummy_audio_callback(void* userdata, Uint8* stream, int len) | 5903 static void my_dummy_audio_callback(void* userdata, ALbyte* stream, int len) |
5493 { | 5904 { |
5494 } | 5905 } |
5495 #endif | 5906 #endif |
5496 | 5907 |
5497 | 5908 |
5507 * finish the threads. | 5918 * finish the threads. |
5508 */ | 5919 */ |
5509 | 5920 |
5510 static int Stream_Data_Thread_Callback(void* data) | 5921 static int Stream_Data_Thread_Callback(void* data) |
5511 { | 5922 { |
5512 Sint32 retval; | 5923 ALint retval; |
5513 | 5924 |
5514 while(ALmixer_Initialized) | 5925 while(ALmixer_Initialized) |
5515 { | 5926 { |
5516 retval = Update_ALmixer(data); | 5927 retval = Update_ALmixer(data); |
5517 /* 0 means that nothing needed updating and | 5928 /* 0 means that nothing needed updating and |
5523 * little work was done in update | 5934 * little work was done in update |
5524 */ | 5935 */ |
5525 /* Make sure times are multiples of 10 | 5936 /* Make sure times are multiples of 10 |
5526 * for optimal performance and accuracy in Linux | 5937 * for optimal performance and accuracy in Linux |
5527 */ | 5938 */ |
5528 SDL_Delay(10); | 5939 ALmixer_Delay(10); |
5529 } | 5940 } |
5530 else | 5941 else |
5531 { | 5942 { |
5532 /* should I also be sleeping/yielding here? */ | 5943 /* should I also be sleeping/yielding here? */ |
5533 SDL_Delay(0); | 5944 ALmixer_Delay(0); |
5534 } | 5945 } |
5535 } | 5946 } |
5536 fprintf(stderr, "Thread is closing\n"); | 5947 fprintf(stderr, "Thread is closing\n"); |
5537 return 0; | 5948 return 0; |
5538 } | 5949 } |
5539 #endif /* End of ENABLE_ALMIXER_THREADS */ | 5950 #endif /* End of ENABLE_ALMIXER_THREADS */ |
5540 | 5951 |
5541 | 5952 |
5542 /* Using -1 on error and 0 on success to follow SDL/SDL_mixer conventions, | 5953 /* SDL/SDL_mixer returns -1 on error and 0 on success. |
5543 * though I actually prefer 0/1 conventions (SDL_Sound/OpenAL/GL). | 5954 * I actually prefer false/true conventions (SDL_Sound/OpenAL/GL) |
5955 * so SDL_mixer porting people beware. | |
5544 * Warning: SDL_QuitSubSystem(SDL_INIT_AUDIO) is called which | 5956 * Warning: SDL_QuitSubSystem(SDL_INIT_AUDIO) is called which |
5545 * means the SDL audio system will be disabled. It will not | 5957 * means the SDL audio system will be disabled. It will not |
5546 * be restored (in case SDL is not actually being used) so | 5958 * be restored (in case SDL is not actually being used) so |
5547 * the user will need to restart it if they need it after | 5959 * the user will need to restart it if they need it after |
5548 * OpenAL shuts down. | 5960 * OpenAL shuts down. |
5549 */ | 5961 */ |
5550 Sint32 ALmixer_Init(Uint32 frequency, Sint32 num_sources, Uint32 refresh) | 5962 ALboolean ALmixer_Init(ALuint frequency, ALint num_sources, ALuint refresh) |
5551 { | 5963 { |
5552 ALCdevice* dev; | 5964 ALCdevice* dev; |
5553 ALCcontext* context; | 5965 ALCcontext* context; |
5554 Sint32 i; | 5966 ALint i; |
5555 ALenum error; | 5967 ALenum error; |
5556 ALuint* source; | 5968 ALuint* source; |
5557 | 5969 |
5558 #ifdef USING_LOKI_AL_DIST | 5970 #ifdef USING_LOKI_AL_DIST |
5559 /* The Loki dist requires that I set both the | 5971 /* The Loki dist requires that I set both the |
5622 /* Redo: I'm going to allow ALC_REFRESH to be set. | 6034 /* Redo: I'm going to allow ALC_REFRESH to be set. |
5623 * However, if no value is specified, I don't | 6035 * However, if no value is specified, I don't |
5624 * want it in the list so I can get the OpenAL defaults | 6036 * want it in the list so I can get the OpenAL defaults |
5625 */ | 6037 */ |
5626 ALint attrlist[7]; | 6038 ALint attrlist[7]; |
6039 ALsizei current_attrlist_index = 0; | |
5627 | 6040 |
5628 #ifdef ENABLE_PARANOID_SIGNEDNESS_CHECK | 6041 #ifdef ENABLE_PARANOID_SIGNEDNESS_CHECK |
5629 /* More problems: I'm getting bit by endian/signedness issues on | 6042 /* More problems: I'm getting bit by endian/signedness issues on |
5630 * different platforms. I can find the endianess easily enough, | 6043 * different platforms. I can find the endianess easily enough, |
5631 * but I don't know how to determine what the correct signedness | 6044 * but I don't know how to determine what the correct signedness |
5652 SDL_AudioSpec desired; | 6065 SDL_AudioSpec desired; |
5653 SDL_AudioSpec obtained; | 6066 SDL_AudioSpec obtained; |
5654 #endif | 6067 #endif |
5655 | 6068 |
5656 | 6069 |
5657 | |
5658 | |
5659 /* Make sure ALmixer isn't already initialized */ | 6070 /* Make sure ALmixer isn't already initialized */ |
5660 if(ALmixer_Initialized) | 6071 if(ALmixer_Initialized) |
5661 { | 6072 { |
5662 return -1; | 6073 return AL_FALSE; |
5663 } | 6074 } |
5664 #ifdef USING_LOKI_AL_DIST | 6075 #ifdef USING_LOKI_AL_DIST |
5665 fprintf(stderr, "Found Loki dist\n"); | 6076 fprintf(stderr, "Found Loki dist\n"); |
5666 #elif defined(USING_CREATIVE_AL_DIST) | 6077 #elif defined(USING_CREATIVE_AL_DIST) |
5667 fprintf(stderr, "Found Creative dist\n"); | 6078 fprintf(stderr, "Found Creative dist\n"); |
5668 | 6079 |
5669 #elif defined(USING_NVIDIA_AL_DIST) | 6080 #elif defined(USING_NVIDIA_AL_DIST) |
5670 fprintf(stderr, "Found Nvidia dist\n"); | 6081 fprintf(stderr, "Found Nvidia dist\n"); |
5671 #endif | 6082 #endif |
5672 | 6083 |
6084 #ifdef ALMIXER_COMPILE_WITHOUT_SDL | |
6085 ALmixer_InitTime(); | |
6086 | |
6087 /* Note: The pool may have been created on previous Init's */ | |
6088 /* I leave the pool allocated allocated in case the user wants | |
6089 * to read the pool in case of a failure (such as in this function). | |
6090 * This is not actually a leak. | |
6091 */ | |
6092 if(NULL == s_ALmixerErrorPool) | |
6093 { | |
6094 s_ALmixerErrorPool = TError_CreateErrorPool(); | |
6095 } | |
6096 if(NULL == s_ALmixerErrorPool) | |
6097 { | |
6098 return AL_FALSE; | |
6099 } | |
6100 fprintf(stderr, "tError Test0\n"); | |
6101 ALmixer_SetError("Initing (and testing SetError)"); | |
6102 fprintf(stderr, "tError Test1: %s\n", ALmixer_GetError()); | |
6103 fprintf(stderr, "tError Test2: %s\n", ALmixer_GetError()); | |
6104 #endif | |
6105 | |
6106 | |
5673 /* Set the defaults */ | 6107 /* Set the defaults */ |
6108 /* | |
5674 attrlist[0] = ALC_FREQUENCY; | 6109 attrlist[0] = ALC_FREQUENCY; |
5675 attrlist[1] = ALMIXER_DEFAULT_FREQUENCY; | 6110 attrlist[1] = ALMIXER_DEFAULT_FREQUENCY; |
5676 attrlist[2] = ALC_SYNC; | 6111 attrlist[2] = ALC_SYNC; |
5677 #ifdef ENABLE_ALMIXER_ALC_SYNC | 6112 #ifdef ENABLE_ALMIXER_ALC_SYNC |
5678 attrlist[3] = ALC_TRUE; | 6113 attrlist[3] = ALC_TRUE; |
5679 #else | 6114 #else |
5680 attrlist[3] = ALC_FALSE; | 6115 attrlist[3] = ALC_FALSE; |
5681 #endif | 6116 #endif |
5682 | 6117 */ |
5683 /* Set frequency value if it is not 0 */ | 6118 /* Set frequency value if it is not 0 */ |
5684 if(0 != frequency) | 6119 if(0 != frequency) |
5685 { | 6120 { |
5686 attrlist[1] = (ALint)frequency; | 6121 attrlist[current_attrlist_index] = ALC_FREQUENCY; |
5687 } | 6122 current_attrlist_index++; |
6123 attrlist[current_attrlist_index] = (ALint)frequency; | |
6124 current_attrlist_index++; | |
6125 } | |
6126 | |
6127 #ifdef ENABLE_ALMIXER_ALC_SYNC | |
6128 attrlist[current_attrlist_index] = ALC_SYNC; | |
6129 current_attrlist_index++; | |
6130 attrlist[current_attrlist_index] = ALC_TRUE; | |
6131 current_attrlist_index++; | |
6132 #endif | |
5688 | 6133 |
5689 /* If the user specifies a refresh value, | 6134 /* If the user specifies a refresh value, |
5690 * make room for it | 6135 * make room for it |
5691 */ | 6136 */ |
5692 if(0 != refresh) | 6137 if(0 != refresh) |
5693 { | 6138 { |
5694 attrlist[4] = (ALint)ALC_REFRESH; | 6139 attrlist[current_attrlist_index] = (ALint)ALC_REFRESH; |
5695 attrlist[5] = refresh; | 6140 current_attrlist_index++; |
5696 attrlist[6] = '\0'; | 6141 attrlist[current_attrlist_index] = refresh; |
5697 } | 6142 current_attrlist_index++; |
5698 /* Terminate the list without any refresh values */ | |
5699 else | |
5700 { | |
5701 attrlist[4] = '\0'; | |
5702 } | 6143 } |
5703 | 6144 |
5704 /* It looks like OpenAL won't let us ask it what | 6145 /* End attribute list */ |
5705 * the set frequency is, so we need to save our | 6146 attrlist[current_attrlist_index] = '\0'; |
5706 * own copy. Yuck. | 6147 |
5707 * Update: J. Valenzuela just updated the Loki | 6148 |
5708 * dist (2003/01/02) to handle this. | |
5709 * The demo is in testattrib.c. However, this | |
5710 * looks kind of cumbersome to parse, and I've | |
5711 * already put this in my code, so I guess I'll | |
5712 * leave it for now. | |
5713 */ | |
5714 ALmixer_Frequency_global = attrlist[1]; | |
5715 | |
5716 /* Initialize SDL_Sound */ | 6149 /* Initialize SDL_Sound */ |
5717 if(! Sound_Init() ) | 6150 if(! Sound_Init() ) |
5718 { | 6151 { |
5719 ALmixer_SetError(Sound_GetError()); | 6152 ALmixer_SetError(Sound_GetError()); |
5720 return -1; | 6153 return AL_FALSE; |
5721 } | 6154 } |
5722 #ifdef ENABLE_PARANOID_SIGNEDNESS_CHECK | 6155 #ifdef ENABLE_PARANOID_SIGNEDNESS_CHECK |
5723 /* Here is the paranoid check that opens | 6156 /* Here is the paranoid check that opens |
5724 * SDL audio in an attempt to find the correct | 6157 * SDL audio in an attempt to find the correct |
5725 * system values. | 6158 * system values. |
5758 */ | 6191 */ |
5759 SIGN_TYPE_16_BIT_FORMAT = AUDIO_S16SYS; | 6192 SIGN_TYPE_16_BIT_FORMAT = AUDIO_S16SYS; |
5760 SIGN_TYPE_8_BIT_FORMAT = AUDIO_S8; | 6193 SIGN_TYPE_8_BIT_FORMAT = AUDIO_S8; |
5761 } | 6194 } |
5762 #endif | 6195 #endif |
6196 | |
6197 #ifndef ALMIXER_COMPILE_WITHOUT_SDL | |
5763 /* Weirdness: It seems that SDL_Init(SDL_INIT_AUDIO) | 6198 /* Weirdness: It seems that SDL_Init(SDL_INIT_AUDIO) |
5764 * causes OpenAL and SMPEG to conflict. For some reason | 6199 * causes OpenAL and SMPEG to conflict. For some reason |
5765 * if SDL_Init on audio is active, then all the SMPEG | 6200 * if SDL_Init on audio is active, then all the SMPEG |
5766 * decoded sound comes out silent. Unfortunately, | 6201 * decoded sound comes out silent. Unfortunately, |
5767 * Sound_Init() invokes SDL_Init on audio. I'm | 6202 * Sound_Init() invokes SDL_Init on audio. I'm |
5768 * not sure why it actually needs it... | 6203 * not sure why it actually needs it... |
5769 * But we'll attempt to disable it here after the | 6204 * But we'll attempt to disable it here after the |
5770 * SDL_Sound::Init call and hope it doesn't break SDL_Sound. | 6205 * SDL_Sound::Init call and hope it doesn't break SDL_Sound. |
5771 */ | 6206 */ |
5772 SDL_QuitSubSystem(SDL_INIT_AUDIO); | 6207 SDL_QuitSubSystem(SDL_INIT_AUDIO); |
5773 | 6208 #endif |
6209 | |
5774 /* I'm told NULL will call the default string | 6210 /* I'm told NULL will call the default string |
5775 * and hopefully do the right thing for each platform | 6211 * and hopefully do the right thing for each platform |
5776 */ | 6212 */ |
5777 /* | 6213 /* |
5778 dev = alcOpenDevice( NULL ); | 6214 dev = alcOpenDevice( NULL ); |
5794 #endif | 6230 #endif |
5795 fprintf(stderr,"sampling-rate is %d\n", attrlist[1]); | 6231 fprintf(stderr,"sampling-rate is %d\n", attrlist[1]); |
5796 if(NULL == dev) | 6232 if(NULL == dev) |
5797 { | 6233 { |
5798 ALmixer_SetError("Cannot open sound device for OpenAL"); | 6234 ALmixer_SetError("Cannot open sound device for OpenAL"); |
5799 return -1; | 6235 return AL_FALSE; |
5800 } | 6236 } |
6237 | |
6238 #ifdef __APPLE__ | |
6239 /* The ALC_FREQUENCY attribute is ignored with Apple's implementation. */ | |
6240 /* This extension must be called before the context is created. */ | |
6241 if(0 != frequency) | |
6242 { | |
6243 Internal_alcMacOSXMixerOutputRate((ALdouble)frequency); | |
6244 } | |
6245 ALmixer_Frequency_global = (ALuint)Internal_alcMacOSXGetMixerOutputRate(); | |
6246 fprintf(stderr, "Internal_alcMacOSXMixerOutputRate is: %lf", Internal_alcMacOSXGetMixerOutputRate()); | |
6247 #endif | |
5801 | 6248 |
5802 context = alcCreateContext(dev, attrlist); | 6249 context = alcCreateContext(dev, attrlist); |
5803 if(NULL == context) | 6250 if(NULL == context) |
5804 { | 6251 { |
5805 ALmixer_SetError("Cannot create a context OpenAL"); | 6252 ALmixer_SetError("Cannot create a context OpenAL"); |
5806 alcCloseDevice(dev); | 6253 alcCloseDevice(dev); |
5807 return -1; | 6254 return AL_FALSE; |
5808 } | 6255 } |
5809 fprintf(stderr, "Context checking...\n"); | 6256 fprintf(stderr, "Context checking...\n"); |
5810 | 6257 |
5811 | 6258 |
5812 /* Hmmm, OSX is returning 1 on alcMakeContextCurrent, | 6259 /* Hmmm, OSX is returning 1 on alcMakeContextCurrent, |
5824 if( (ALC_NO_ERROR != error) ) | 6271 if( (ALC_NO_ERROR != error) ) |
5825 { | 6272 { |
5826 ALmixer_SetError("Could not MakeContextCurrent"); | 6273 ALmixer_SetError("Could not MakeContextCurrent"); |
5827 alcDestroyContext(context); | 6274 alcDestroyContext(context); |
5828 alcCloseDevice(dev); | 6275 alcCloseDevice(dev); |
5829 return -1; | 6276 return AL_FALSE; |
5830 } | 6277 } |
5831 | 6278 |
5832 | 6279 /* It looks like OpenAL won't let us ask it what |
6280 * the set frequency is, so we need to save our | |
6281 * own copy. Yuck. | |
6282 * Update: J. Valenzuela just updated the Loki | |
6283 * dist (2003/01/02) to handle this. | |
6284 * The demo is in testattrib.c. | |
6285 */ | |
6286 /* | |
6287 ALmixer_Frequency_global = frequency; | |
6288 */ | |
6289 #ifndef __APPLE__ | |
6290 alcGetIntegerv(dev, ALC_FREQUENCY, 1, &ALmixer_Frequency_global); | |
6291 fprintf(stderr, "alcGetIntegerv ALC_FREQUENCY is: %d", ALmixer_Frequency_global); | |
6292 #endif | |
6293 | |
6294 | |
5833 #if 0 | 6295 #if 0 |
5834 /* OSX is failing on alcMakeContextCurrent(). Try checking it first? */ | 6296 /* OSX is failing on alcMakeContextCurrent(). Try checking it first? */ |
5835 if(alcGetCurrentContext() != context) | 6297 if(alcGetCurrentContext() != context) |
5836 { | 6298 { |
5837 /* Hmmm, OSX is returning 1 on alcMakeContextCurrent, | 6299 /* Hmmm, OSX is returning 1 on alcMakeContextCurrent, |
5848 #endif | 6310 #endif |
5849 { | 6311 { |
5850 ALmixer_SetError("Could not MakeContextCurrent"); | 6312 ALmixer_SetError("Could not MakeContextCurrent"); |
5851 alcDestroyContext(context); | 6313 alcDestroyContext(context); |
5852 alcCloseDevice(dev); | 6314 alcCloseDevice(dev); |
5853 return -1; | 6315 return AL_FALSE; |
5854 } | 6316 } |
5855 } | 6317 } |
5856 #endif | 6318 #endif |
5857 | 6319 |
5858 | 6320 |
5871 * This feature is toggled on/off by using the alDisable() & alEnable() APIs. This | 6333 * This feature is toggled on/off by using the alDisable() & alEnable() APIs. This |
5872 * setting will be applied to all subsequent | 6334 * setting will be applied to all subsequent |
5873 * calls to alBufferData(). | 6335 * calls to alBufferData(). |
5874 */ | 6336 */ |
5875 #ifdef __APPLE__ | 6337 #ifdef __APPLE__ |
5876 alEnable(ALC_MAC_OSX_CONVERT_DATA_UPON_LOADING); | 6338 /* |
6339 #if (TARGET_OS_IPHONE == 1) || (TARGET_IPHONE_SIMULATOR == 1) | |
6340 | |
6341 #else | |
6342 #endif | |
6343 */ | |
6344 ALenum convert_data_enum = alcGetEnumValue(dev, "ALC_MAC_OSX_CONVERT_DATA_UPON_LOADING"); | |
6345 fprintf(stderr, "ALC_MAC_OSX_CONVERT_DATA_UPON_LOADING=0x%x", convert_data_enum); | |
6346 if(0 != convert_data_enum) | |
6347 { | |
6348 alEnable(convert_data_enum); | |
6349 } | |
6350 if( (AL_NO_ERROR != alGetError()) ) | |
6351 { | |
6352 ALmixer_SetError("ALC_MAC_OSX_CONVERT_DATA_UPON_LOADING attempted but failed"); | |
6353 } | |
6354 | |
5877 #endif | 6355 #endif |
5878 | 6356 |
5879 | 6357 |
5880 | 6358 |
5881 | 6359 |
5904 ALmixer_SetError("Out of Memory for Channel List"); | 6382 ALmixer_SetError("Out of Memory for Channel List"); |
5905 alcDestroyContext(context); | 6383 alcDestroyContext(context); |
5906 alcCloseDevice(dev); | 6384 alcCloseDevice(dev); |
5907 ALmixer_Initialized = 0; | 6385 ALmixer_Initialized = 0; |
5908 Number_of_Channels_global = 0; | 6386 Number_of_Channels_global = 0; |
5909 return -1; | 6387 return AL_FALSE; |
5910 } | 6388 } |
5911 | 6389 |
5912 /* Allocate memory for the list of sources that map to the channels */ | 6390 /* Allocate memory for the list of sources that map to the channels */ |
5913 Source_Map_List = (Source_Map*) malloc(Number_of_Channels_global * sizeof(Source_Map)); | 6391 Source_Map_List = (Source_Map*) malloc(Number_of_Channels_global * sizeof(Source_Map)); |
5914 if(NULL == Source_Map_List) | 6392 if(NULL == Source_Map_List) |
5917 free(ALmixer_Channel_List); | 6395 free(ALmixer_Channel_List); |
5918 alcDestroyContext(context); | 6396 alcDestroyContext(context); |
5919 alcCloseDevice(dev); | 6397 alcCloseDevice(dev); |
5920 ALmixer_Initialized = 0; | 6398 ALmixer_Initialized = 0; |
5921 Number_of_Channels_global = 0; | 6399 Number_of_Channels_global = 0; |
5922 return -1; | 6400 return AL_FALSE; |
5923 } | 6401 } |
5924 | 6402 |
5925 /* Create array that will hold the sources */ | 6403 /* Create array that will hold the sources */ |
5926 source = (ALuint*)malloc(Number_of_Channels_global * sizeof(ALuint)); | 6404 source = (ALuint*)malloc(Number_of_Channels_global * sizeof(ALuint)); |
5927 if(NULL == source) | 6405 if(NULL == source) |
5931 free(ALmixer_Channel_List); | 6409 free(ALmixer_Channel_List); |
5932 alcDestroyContext(context); | 6410 alcDestroyContext(context); |
5933 alcCloseDevice(dev); | 6411 alcCloseDevice(dev); |
5934 ALmixer_Initialized = 0; | 6412 ALmixer_Initialized = 0; |
5935 Number_of_Channels_global = 0; | 6413 Number_of_Channels_global = 0; |
5936 return -1; | 6414 return AL_FALSE; |
5937 } | 6415 } |
5938 | 6416 |
5939 /* Clear the error state */ | 6417 /* Clear the error state */ |
5940 alGetError(); | 6418 alGetError(); |
5941 /* Generate the OpenAL sources */ | 6419 /* Generate the OpenAL sources */ |
5942 alGenSources(Number_of_Channels_global, source); | 6420 alGenSources(Number_of_Channels_global, source); |
5943 if( (error=alGetError()) != AL_NO_ERROR) | 6421 if( (error=alGetError()) != AL_NO_ERROR) |
5944 { | 6422 { |
5945 ALmixer_SetError("Couldn't generate sources: %s\n", aluGetErrorString(error)); | 6423 ALmixer_SetError("Couldn't generate sources: %s\n", alGetString(error)); |
5946 free(ALmixer_Channel_List); | 6424 free(ALmixer_Channel_List); |
5947 free(Source_Map_List); | 6425 free(Source_Map_List); |
5948 alcDestroyContext(context); | 6426 alcDestroyContext(context); |
5949 alcCloseDevice(dev); | 6427 alcCloseDevice(dev); |
5950 ALmixer_Initialized = 0; | 6428 ALmixer_Initialized = 0; |
5951 Number_of_Channels_global = 0; | 6429 Number_of_Channels_global = 0; |
5952 return -1; | 6430 return AL_FALSE; |
5953 } | 6431 } |
5954 | 6432 |
5955 /* Initialize each channel and associate one source to one channel */ | 6433 /* Initialize each channel and associate one source to one channel */ |
5956 for(i=0; i<Number_of_Channels_global; i++) | 6434 for(i=0; i<Number_of_Channels_global; i++) |
5957 { | 6435 { |
5986 for(i=0; i<Number_of_Channels_global; i++) | 6464 for(i=0; i<Number_of_Channels_global; i++) |
5987 { | 6465 { |
5988 fprintf(stderr, "Source: %d, Channel: %d\n", Source_Map_List[i].source, Source_Map_List[i].channel); | 6466 fprintf(stderr, "Source: %d, Channel: %d\n", Source_Map_List[i].source, Source_Map_List[i].channel); |
5989 } | 6467 } |
5990 fprintf(stderr, "\n"); | 6468 fprintf(stderr, "\n"); |
5991 | 6469 ALmixer_OutputDecoders(); |
5992 simple_lock = SDL_CreateMutex(); | 6470 |
5993 if(NULL == simple_lock) | 6471 #ifdef ENABLE_ALMIXER_THREADS |
6472 s_simpleLock = SDL_CreateMutex(); | |
6473 if(NULL == s_simpleLock) | |
5994 { | 6474 { |
5995 /* SDL sets the error message already? */ | 6475 /* SDL sets the error message already? */ |
5996 free(source); | 6476 free(source); |
5997 free(ALmixer_Channel_List); | 6477 free(ALmixer_Channel_List); |
5998 free(Source_Map_List); | 6478 free(Source_Map_List); |
5999 alcDestroyContext(context); | 6479 alcDestroyContext(context); |
6000 alcCloseDevice(dev); | 6480 alcCloseDevice(dev); |
6001 ALmixer_Initialized = 0; | 6481 ALmixer_Initialized = 0; |
6002 Number_of_Channels_global = 0; | 6482 Number_of_Channels_global = 0; |
6003 return -1; | 6483 return AL_FALSE; |
6004 } | 6484 } |
6005 | 6485 |
6006 | 6486 |
6007 #ifdef ENABLE_ALMIXER_THREADS | |
6008 Stream_Thread_global = SDL_CreateThread(Stream_Data_Thread_Callback, NULL); | 6487 Stream_Thread_global = SDL_CreateThread(Stream_Data_Thread_Callback, NULL); |
6009 if(NULL == Stream_Thread_global) | 6488 if(NULL == Stream_Thread_global) |
6010 { | 6489 { |
6011 /* SDL sets the error message already? */ | 6490 /* SDL sets the error message already? */ |
6012 SDL_DestroyMutex(simple_lock); | 6491 SDL_DestroyMutex(s_simpleLock); |
6013 free(source); | 6492 free(source); |
6014 free(ALmixer_Channel_List); | 6493 free(ALmixer_Channel_List); |
6015 free(Source_Map_List); | 6494 free(Source_Map_List); |
6016 alcDestroyContext(context); | 6495 alcDestroyContext(context); |
6017 alcCloseDevice(dev); | 6496 alcCloseDevice(dev); |
6018 ALmixer_Initialized = 0; | 6497 ALmixer_Initialized = 0; |
6019 Number_of_Channels_global = 0; | 6498 Number_of_Channels_global = 0; |
6020 return -1; | 6499 return AL_FALSE; |
6021 } | 6500 } |
6022 | 6501 |
6023 fprintf(stderr, "Using threads\n"); | 6502 fprintf(stderr, "Using threads\n"); |
6024 #endif /* End of ENABLE_ALMIXER_THREADS */ | 6503 #endif /* End of ENABLE_ALMIXER_THREADS */ |
6025 | 6504 |
6026 /* We don't need this array any more because all the sources | 6505 /* We don't need this array any more because all the sources |
6027 * are connected to channels | 6506 * are connected to channels |
6028 */ | 6507 */ |
6029 free(source); | 6508 free(source); |
6030 return 0; | 6509 return AL_TRUE; |
6031 } | 6510 } |
6032 | 6511 |
6033 | 6512 |
6034 Sint32 ALmixer_Init_Context(Uint32 frequency, Uint32 refresh) | 6513 ALboolean ALmixer_InitContext(ALuint frequency, ALuint refresh) |
6035 { | 6514 { |
6036 ALCdevice* dev; | 6515 ALCdevice* dev; |
6037 ALCcontext* context; | 6516 ALCcontext* context; |
6038 ALCenum error; | 6517 ALCenum error; |
6039 | 6518 |
6104 /* Redo: I'm going to allow ALC_REFRESH to be set. | 6583 /* Redo: I'm going to allow ALC_REFRESH to be set. |
6105 * However, if no value is specified, I don't | 6584 * However, if no value is specified, I don't |
6106 * want it in the list so I can get the OpenAL defaults | 6585 * want it in the list so I can get the OpenAL defaults |
6107 */ | 6586 */ |
6108 ALint attrlist[7]; | 6587 ALint attrlist[7]; |
6588 ALsizei current_attrlist_index = 0; | |
6109 | 6589 |
6110 #ifdef ENABLE_PARANOID_SIGNEDNESS_CHECK | 6590 #ifdef ENABLE_PARANOID_SIGNEDNESS_CHECK |
6111 /* More problems: I'm getting bit by endian/signedness issues on | 6591 /* More problems: I'm getting bit by endian/signedness issues on |
6112 * different platforms. I can find the endianess easily enough, | 6592 * different platforms. I can find the endianess easily enough, |
6113 * but I don't know how to determine what the correct signedness | 6593 * but I don't know how to determine what the correct signedness |
6139 | 6619 |
6140 | 6620 |
6141 /* Make sure ALmixer isn't already initialized */ | 6621 /* Make sure ALmixer isn't already initialized */ |
6142 if(ALmixer_Initialized) | 6622 if(ALmixer_Initialized) |
6143 { | 6623 { |
6144 return -1; | 6624 return AL_FALSE; |
6145 } | 6625 } |
6146 #ifdef USING_LOKI_AL_DIST | 6626 #ifdef USING_LOKI_AL_DIST |
6147 fprintf(stderr, "Found Loki dist\n"); | 6627 fprintf(stderr, "Found Loki dist\n"); |
6148 #elif defined(USING_CREATIVE_AL_DIST) | 6628 #elif defined(USING_CREATIVE_AL_DIST) |
6149 fprintf(stderr, "Found Creative dist\n"); | 6629 fprintf(stderr, "Found Creative dist\n"); |
6159 #ifdef ENABLE_ALMIXER_ALC_SYNC | 6639 #ifdef ENABLE_ALMIXER_ALC_SYNC |
6160 attrlist[3] = ALC_TRUE; | 6640 attrlist[3] = ALC_TRUE; |
6161 #else | 6641 #else |
6162 attrlist[3] = ALC_FALSE; | 6642 attrlist[3] = ALC_FALSE; |
6163 #endif | 6643 #endif |
6164 | |
6165 /* Set frequency value if it is not 0 */ | 6644 /* Set frequency value if it is not 0 */ |
6166 if(0 != frequency) | 6645 if(0 != frequency) |
6167 { | 6646 { |
6168 attrlist[1] = (ALint)frequency; | 6647 attrlist[current_attrlist_index] = ALC_FREQUENCY; |
6169 } | 6648 current_attrlist_index++; |
6649 attrlist[current_attrlist_index] = (ALint)frequency; | |
6650 current_attrlist_index++; | |
6651 } | |
6652 | |
6653 #ifdef ENABLE_ALMIXER_ALC_SYNC | |
6654 attrlist[current_attrlist_index] = ALC_SYNC; | |
6655 current_attrlist_index++; | |
6656 attrlist[current_attrlist_index] = ALC_TRUE; | |
6657 current_attrlist_index++; | |
6658 #endif | |
6170 | 6659 |
6171 /* If the user specifies a refresh value, | 6660 /* If the user specifies a refresh value, |
6172 * make room for it | 6661 * make room for it |
6173 */ | 6662 */ |
6174 if(0 != refresh) | 6663 if(0 != refresh) |
6175 { | 6664 { |
6176 attrlist[4] = (ALint)ALC_REFRESH; | 6665 attrlist[current_attrlist_index] = (ALint)ALC_REFRESH; |
6177 attrlist[5] = refresh; | 6666 current_attrlist_index++; |
6178 attrlist[6] = '\0'; | 6667 attrlist[current_attrlist_index] = refresh; |
6179 } | 6668 current_attrlist_index++; |
6180 /* Terminate the list without any refresh values */ | |
6181 else | |
6182 { | |
6183 attrlist[4] = '\0'; | |
6184 } | 6669 } |
6185 | 6670 |
6186 /* It looks like OpenAL won't let us ask it what | 6671 /* End attribute list */ |
6187 * the set frequency is, so we need to save our | 6672 attrlist[current_attrlist_index] = '\0'; |
6188 * own copy. Yuck. | 6673 |
6189 * Update: J. Valenzuela just updated the Loki | 6674 |
6190 * dist (2003/01/02) to handle this. | 6675 |
6191 * The demo is in testattrib.c. However, this | |
6192 * looks kind of cumbersome to parse, and I've | |
6193 * already put this in my code, so I guess I'll | |
6194 * leave it for now. | |
6195 */ | |
6196 ALmixer_Frequency_global = attrlist[1]; | |
6197 | |
6198 /* Initialize SDL_Sound */ | 6676 /* Initialize SDL_Sound */ |
6199 if(! Sound_Init() ) | 6677 if(! Sound_Init() ) |
6200 { | 6678 { |
6201 ALmixer_SetError(Sound_GetError()); | 6679 ALmixer_SetError(Sound_GetError()); |
6202 return -1; | 6680 return AL_FALSE; |
6203 } | 6681 } |
6204 #ifdef ENABLE_PARANOID_SIGNEDNESS_CHECK | 6682 #ifdef ENABLE_PARANOID_SIGNEDNESS_CHECK |
6205 /* Here is the paranoid check that opens | 6683 /* Here is the paranoid check that opens |
6206 * SDL audio in an attempt to find the correct | 6684 * SDL audio in an attempt to find the correct |
6207 * system values. | 6685 * system values. |
6240 */ | 6718 */ |
6241 SIGN_TYPE_16_BIT_FORMAT = AUDIO_S16SYS; | 6719 SIGN_TYPE_16_BIT_FORMAT = AUDIO_S16SYS; |
6242 SIGN_TYPE_8_BIT_FORMAT = AUDIO_S8; | 6720 SIGN_TYPE_8_BIT_FORMAT = AUDIO_S8; |
6243 } | 6721 } |
6244 #endif | 6722 #endif |
6723 | |
6724 #ifndef ALMIXER_COMPILE_WITHOUT_SDL | |
6245 /* Weirdness: It seems that SDL_Init(SDL_INIT_AUDIO) | 6725 /* Weirdness: It seems that SDL_Init(SDL_INIT_AUDIO) |
6246 * causes OpenAL and SMPEG to conflict. For some reason | 6726 * causes OpenAL and SMPEG to conflict. For some reason |
6247 * if SDL_Init on audio is active, then all the SMPEG | 6727 * if SDL_Init on audio is active, then all the SMPEG |
6248 * decoded sound comes out silent. Unfortunately, | 6728 * decoded sound comes out silent. Unfortunately, |
6249 * Sound_Init() invokes SDL_Init on audio. I'm | 6729 * Sound_Init() invokes SDL_Init on audio. I'm |
6250 * not sure why it actually needs it... | 6730 * not sure why it actually needs it... |
6251 * But we'll attempt to disable it here after the | 6731 * But we'll attempt to disable it here after the |
6252 * SDL_Sound::Init call and hope it doesn't break SDL_Sound. | 6732 * SDL_Sound::Init call and hope it doesn't break SDL_Sound. |
6253 */ | 6733 */ |
6254 SDL_QuitSubSystem(SDL_INIT_AUDIO); | 6734 SDL_QuitSubSystem(SDL_INIT_AUDIO); |
6255 | 6735 #endif |
6736 | |
6256 /* I'm told NULL will call the default string | 6737 /* I'm told NULL will call the default string |
6257 * and hopefully do the right thing for each platform | 6738 * and hopefully do the right thing for each platform |
6258 */ | 6739 */ |
6259 /* | 6740 /* |
6260 dev = alcOpenDevice( NULL ); | 6741 dev = alcOpenDevice( NULL ); |
6276 #endif | 6757 #endif |
6277 fprintf(stderr,"sampling-rate is %d\n", attrlist[1]); | 6758 fprintf(stderr,"sampling-rate is %d\n", attrlist[1]); |
6278 if(NULL == dev) | 6759 if(NULL == dev) |
6279 { | 6760 { |
6280 ALmixer_SetError("Cannot open sound device for OpenAL"); | 6761 ALmixer_SetError("Cannot open sound device for OpenAL"); |
6281 return -1; | 6762 return AL_FALSE; |
6282 } | 6763 } |
6764 | |
6765 #ifdef __APPLE__ | |
6766 /* The ALC_FREQUENCY attribute is ignored with Apple's implementation. */ | |
6767 /* This extension must be called before the context is created. */ | |
6768 if(0 != frequency) | |
6769 { | |
6770 Internal_alcMacOSXMixerOutputRate((ALdouble)frequency); | |
6771 } | |
6772 ALmixer_Frequency_global = (ALuint)Internal_alcMacOSXGetMixerOutputRate(); | |
6773 fprintf(stderr, "Internal_alcMacOSXMixerOutputRate is: %lf", Internal_alcMacOSXGetMixerOutputRate()); | |
6774 #endif | |
6775 | |
6283 | 6776 |
6284 context = alcCreateContext(dev, attrlist); | 6777 context = alcCreateContext(dev, attrlist); |
6285 if(NULL == context) | 6778 if(NULL == context) |
6286 { | 6779 { |
6287 ALmixer_SetError("Cannot create a context OpenAL"); | 6780 ALmixer_SetError("Cannot create a context OpenAL"); |
6288 alcCloseDevice(dev); | 6781 alcCloseDevice(dev); |
6289 return -1; | 6782 return AL_FALSE; |
6290 } | 6783 } |
6291 | 6784 |
6292 | 6785 |
6293 /* Hmmm, OSX is returning 1 on alcMakeContextCurrent, | 6786 /* Hmmm, OSX is returning 1 on alcMakeContextCurrent, |
6294 * but ALC_NO_ERROR is defined to ALC_FALSE. | 6787 * but ALC_NO_ERROR is defined to ALC_FALSE. |
6305 if( (ALC_NO_ERROR != error) ) | 6798 if( (ALC_NO_ERROR != error) ) |
6306 { | 6799 { |
6307 ALmixer_SetError("Could not MakeContextCurrent"); | 6800 ALmixer_SetError("Could not MakeContextCurrent"); |
6308 alcDestroyContext(context); | 6801 alcDestroyContext(context); |
6309 alcCloseDevice(dev); | 6802 alcCloseDevice(dev); |
6310 return -1; | 6803 return AL_FALSE; |
6311 } | 6804 } |
6312 | 6805 |
6313 | 6806 |
6314 #if 0 | 6807 #if 0 |
6315 /* OSX is failing on alcMakeContextCurrent(). Try checking it first? */ | 6808 /* OSX is failing on alcMakeContextCurrent(). Try checking it first? */ |
6329 #endif | 6822 #endif |
6330 { | 6823 { |
6331 ALmixer_SetError("Could not MakeContextCurrent"); | 6824 ALmixer_SetError("Could not MakeContextCurrent"); |
6332 alcDestroyContext(context); | 6825 alcDestroyContext(context); |
6333 alcCloseDevice(dev); | 6826 alcCloseDevice(dev); |
6334 return -1; | 6827 return AL_FALSE; |
6335 } | 6828 } |
6336 | 6829 |
6337 } | 6830 } |
6338 #endif | 6831 #endif |
6832 | |
6833 /* It looks like OpenAL won't let us ask it what | |
6834 * the set frequency is, so we need to save our | |
6835 * own copy. Yuck. | |
6836 * Update: J. Valenzuela just updated the Loki | |
6837 * dist (2003/01/02) to handle this. | |
6838 * The demo is in testattrib.c. | |
6839 */ | |
6840 #ifndef __APPLE__ | |
6841 alcGetIntegerv(dev, ALC_FREQUENCY, 1, &ALmixer_Frequency_global); | |
6842 fprintf(stderr, "alcGetIntegerv ALC_FREQUENCY is: %d", ALmixer_Frequency_global); | |
6843 #endif | |
6844 | |
6339 | 6845 |
6340 fprintf(stderr, "done Context\n"); | 6846 fprintf(stderr, "done Context\n"); |
6341 | 6847 |
6342 /* Saw this in the README with the OS X OpenAL distribution. | 6848 /* Saw this in the README with the OS X OpenAL distribution. |
6343 * It looked interesting and simple, so I thought I might | 6849 * It looked interesting and simple, so I thought I might |
6352 * This feature is toggled on/off by using the alDisable() & alEnable() APIs. This | 6858 * This feature is toggled on/off by using the alDisable() & alEnable() APIs. This |
6353 * setting will be applied to all subsequent | 6859 * setting will be applied to all subsequent |
6354 * calls to alBufferData(). | 6860 * calls to alBufferData(). |
6355 */ | 6861 */ |
6356 #ifdef __APPLE__ | 6862 #ifdef __APPLE__ |
6357 alEnable(ALC_MAC_OSX_CONVERT_DATA_UPON_LOADING); | 6863 /* |
6358 #endif | 6864 #if (TARGET_OS_IPHONE == 1) || (TARGET_IPHONE_SIMULATOR == 1) |
6359 | 6865 |
6360 return 0; | 6866 #else |
6361 } | 6867 #endif |
6362 | 6868 */ |
6363 | 6869 ALenum convert_data_enum = alcGetEnumValue(dev, "ALC_MAC_OSX_CONVERT_DATA_UPON_LOADING"); |
6364 Sint32 ALmixer_Init_Mixer(Sint32 num_sources) | 6870 fprintf(stderr, "ALC_MAC_OSX_CONVERT_DATA_UPON_LOADING=0x%x", convert_data_enum); |
6871 if(0 != convert_data_enum) | |
6872 { | |
6873 alEnable(convert_data_enum); | |
6874 } | |
6875 if( (AL_NO_ERROR != alGetError()) ) | |
6876 { | |
6877 ALmixer_SetError("ALC_MAC_OSX_CONVERT_DATA_UPON_LOADING attempted but failed"); | |
6878 } | |
6879 #endif | |
6880 | |
6881 return AL_TRUE; | |
6882 } | |
6883 | |
6884 | |
6885 ALboolean ALmixer_InitMixer(ALint num_sources) | |
6365 { | 6886 { |
6366 Sint32 i; | 6887 ALint i; |
6367 ALenum error; | 6888 ALenum error; |
6368 ALuint* source; | 6889 ALuint* source; |
6369 | 6890 |
6370 | 6891 |
6371 ALmixer_Initialized = 1; | 6892 ALmixer_Initialized = 1; |
6893 | |
6894 | |
6895 #ifdef ALMIXER_COMPILE_WITHOUT_SDL | |
6896 ALmixer_InitTime(); | |
6897 | |
6898 /* Note: The pool may have been created on previous Init's */ | |
6899 /* I leave the pool allocated allocated in case the user wants | |
6900 * to read the pool in case of a failure (such as in this function). | |
6901 * This is not actually a leak. | |
6902 */ | |
6903 if(NULL == s_ALmixerErrorPool) | |
6904 { | |
6905 s_ALmixerErrorPool = TError_CreateErrorPool(); | |
6906 } | |
6907 if(NULL == s_ALmixerErrorPool) | |
6908 { | |
6909 return AL_FALSE; | |
6910 } | |
6911 /* | |
6912 fprintf(stderr, "tError Test0\n"); | |
6913 ALmixer_SetError("Initing (and testing SetError)"); | |
6914 fprintf(stderr, "tError Test1: %s\n", ALmixer_GetError()); | |
6915 fprintf(stderr, "tError Test2: %s\n", ALmixer_GetError()); | |
6916 */ | |
6917 #endif | |
6372 | 6918 |
6373 if(num_sources <= 0) | 6919 if(num_sources <= 0) |
6374 { | 6920 { |
6375 Number_of_Channels_global = ALMIXER_DEFAULT_NUM_CHANNELS; | 6921 Number_of_Channels_global = ALMIXER_DEFAULT_NUM_CHANNELS; |
6376 } | 6922 } |
6391 if(NULL == ALmixer_Channel_List) | 6937 if(NULL == ALmixer_Channel_List) |
6392 { | 6938 { |
6393 ALmixer_SetError("Out of Memory for Channel List"); | 6939 ALmixer_SetError("Out of Memory for Channel List"); |
6394 ALmixer_Initialized = 0; | 6940 ALmixer_Initialized = 0; |
6395 Number_of_Channels_global = 0; | 6941 Number_of_Channels_global = 0; |
6396 return -1; | 6942 return AL_FALSE; |
6397 } | 6943 } |
6398 | 6944 |
6399 /* Allocate memory for the list of sources that map to the channels */ | 6945 /* Allocate memory for the list of sources that map to the channels */ |
6400 Source_Map_List = (Source_Map*) malloc(Number_of_Channels_global * sizeof(Source_Map)); | 6946 Source_Map_List = (Source_Map*) malloc(Number_of_Channels_global * sizeof(Source_Map)); |
6401 if(NULL == Source_Map_List) | 6947 if(NULL == Source_Map_List) |
6402 { | 6948 { |
6403 ALmixer_SetError("Out of Memory for Source Map List"); | 6949 ALmixer_SetError("Out of Memory for Source Map List"); |
6404 free(ALmixer_Channel_List); | 6950 free(ALmixer_Channel_List); |
6405 ALmixer_Initialized = 0; | 6951 ALmixer_Initialized = 0; |
6406 Number_of_Channels_global = 0; | 6952 Number_of_Channels_global = 0; |
6407 return -1; | 6953 return AL_FALSE; |
6408 } | 6954 } |
6409 | 6955 |
6410 /* Create array that will hold the sources */ | 6956 /* Create array that will hold the sources */ |
6411 source = (ALuint*)malloc(Number_of_Channels_global * sizeof(ALuint)); | 6957 source = (ALuint*)malloc(Number_of_Channels_global * sizeof(ALuint)); |
6412 if(NULL == source) | 6958 if(NULL == source) |
6414 ALmixer_SetError("Out of Memory for sources"); | 6960 ALmixer_SetError("Out of Memory for sources"); |
6415 free(Source_Map_List); | 6961 free(Source_Map_List); |
6416 free(ALmixer_Channel_List); | 6962 free(ALmixer_Channel_List); |
6417 ALmixer_Initialized = 0; | 6963 ALmixer_Initialized = 0; |
6418 Number_of_Channels_global = 0; | 6964 Number_of_Channels_global = 0; |
6419 return -1; | 6965 return AL_FALSE; |
6420 } | 6966 } |
6421 | 6967 |
6422 /* Clear the error state */ | 6968 /* Clear the error state */ |
6423 alGetError(); | 6969 alGetError(); |
6424 /* Generate the OpenAL sources */ | 6970 /* Generate the OpenAL sources */ |
6425 alGenSources(Number_of_Channels_global, source); | 6971 alGenSources(Number_of_Channels_global, source); |
6426 if( (error=alGetError()) != AL_NO_ERROR) | 6972 if( (error=alGetError()) != AL_NO_ERROR) |
6427 { | 6973 { |
6428 ALmixer_SetError("Couldn't generate sources: %s\n", aluGetErrorString(error)); | 6974 ALmixer_SetError("Couldn't generate sources: %s\n", alGetString(error)); |
6429 free(ALmixer_Channel_List); | 6975 free(ALmixer_Channel_List); |
6430 free(Source_Map_List); | 6976 free(Source_Map_List); |
6431 ALmixer_Initialized = 0; | 6977 ALmixer_Initialized = 0; |
6432 Number_of_Channels_global = 0; | 6978 Number_of_Channels_global = 0; |
6433 return -1; | 6979 return AL_FALSE; |
6434 } | 6980 } |
6435 | 6981 |
6436 /* Initialize each channel and associate one source to one channel */ | 6982 /* Initialize each channel and associate one source to one channel */ |
6437 for(i=0; i<Number_of_Channels_global; i++) | 6983 for(i=0; i<Number_of_Channels_global; i++) |
6438 { | 6984 { |
6463 { | 7009 { |
6464 fprintf(stderr, "Source: %d, Channel: %d\n", Source_Map_List[i].source, Source_Map_List[i].channel); | 7010 fprintf(stderr, "Source: %d, Channel: %d\n", Source_Map_List[i].source, Source_Map_List[i].channel); |
6465 } | 7011 } |
6466 fprintf(stderr, "\n"); | 7012 fprintf(stderr, "\n"); |
6467 | 7013 |
6468 simple_lock = SDL_CreateMutex(); | 7014 |
6469 if(NULL == simple_lock) | 7015 |
7016 #ifdef ENABLE_ALMIXER_THREADS | |
7017 s_simpleLock = SDL_CreateMutex(); | |
7018 if(NULL == s_simpleLock) | |
6470 { | 7019 { |
6471 /* SDL sets the error message already? */ | 7020 /* SDL sets the error message already? */ |
6472 free(source); | 7021 free(source); |
6473 free(ALmixer_Channel_List); | 7022 free(ALmixer_Channel_List); |
6474 free(Source_Map_List); | 7023 free(Source_Map_List); |
6475 ALmixer_Initialized = 0; | 7024 ALmixer_Initialized = 0; |
6476 Number_of_Channels_global = 0; | 7025 Number_of_Channels_global = 0; |
6477 return -1; | 7026 return AL_FALSE; |
6478 } | 7027 } |
6479 | 7028 |
6480 | 7029 |
6481 #ifdef ENABLE_ALMIXER_THREADS | |
6482 Stream_Thread_global = SDL_CreateThread(Stream_Data_Thread_Callback, NULL); | 7030 Stream_Thread_global = SDL_CreateThread(Stream_Data_Thread_Callback, NULL); |
6483 if(NULL == Stream_Thread_global) | 7031 if(NULL == Stream_Thread_global) |
6484 { | 7032 { |
6485 /* SDL sets the error message already? */ | 7033 /* SDL sets the error message already? */ |
6486 SDL_DestroyMutex(simple_lock); | 7034 SDL_DestroyMutex(s_simpleLock); |
6487 free(source); | 7035 free(source); |
6488 free(ALmixer_Channel_List); | 7036 free(ALmixer_Channel_List); |
6489 free(Source_Map_List); | 7037 free(Source_Map_List); |
6490 ALmixer_Initialized = 0; | 7038 ALmixer_Initialized = 0; |
6491 Number_of_Channels_global = 0; | 7039 Number_of_Channels_global = 0; |
6492 return -1; | 7040 return AL_FALSE; |
6493 } | 7041 } |
6494 | 7042 |
6495 fprintf(stderr, "Using threads\n"); | 7043 fprintf(stderr, "Using threads\n"); |
6496 #endif /* End of ENABLE_ALMIXER_THREADS */ | 7044 #endif /* End of ENABLE_ALMIXER_THREADS */ |
6497 | 7045 |
6498 /* We don't need this array any more because all the sources | 7046 /* We don't need this array any more because all the sources |
6499 * are connected to channels | 7047 * are connected to channels |
6500 */ | 7048 */ |
6501 free(source); | 7049 free(source); |
6502 return 0; | 7050 return AL_TRUE; |
6503 } | 7051 } |
6504 | 7052 |
6505 | 7053 |
6506 | 7054 |
6507 /* Keep the return value void to allow easy use with | 7055 /* Keep the return value void to allow easy use with |
6509 */ | 7057 */ |
6510 void ALmixer_Quit() | 7058 void ALmixer_Quit() |
6511 { | 7059 { |
6512 ALCcontext* context; | 7060 ALCcontext* context; |
6513 ALCdevice* dev; | 7061 ALCdevice* dev; |
6514 Sint32 i; | 7062 ALint i; |
6515 | 7063 |
6516 if( ! ALmixer_Initialized) | 7064 if( ! ALmixer_Initialized) |
6517 { | 7065 { |
6518 return; | 7066 return; |
6519 } | 7067 } |
6520 | 7068 #ifdef ENABLE_ALMIXER_THREADS |
6521 SDL_LockMutex(simple_lock); | 7069 SDL_LockMutex(s_simpleLock); |
6522 | 7070 #endif |
6523 /* Shutdown everything before closing context */ | 7071 /* Shutdown everything before closing context */ |
6524 fprintf(stderr, "Halting channels\n"); | 7072 fprintf(stderr, "Halting channels\n"); |
6525 Internal_HaltChannel(-1); | 7073 Internal_HaltChannel(-1, AL_FALSE); |
6526 | 7074 |
6527 /* This flag will cause the thread to terminate */ | 7075 /* This flag will cause the thread to terminate */ |
6528 ALmixer_Initialized = 0; | 7076 ALmixer_Initialized = 0; |
6529 SDL_UnlockMutex(simple_lock); | 7077 #ifdef ENABLE_ALMIXER_THREADS |
6530 #ifdef ENABLE_ALMIXER_THREADS | 7078 SDL_UnlockMutex(s_simpleLock); |
6531 fprintf(stderr, "Closing thread\n"); | 7079 fprintf(stderr, "Closing thread\n"); |
6532 SDL_WaitThread(Stream_Thread_global, NULL); | 7080 SDL_WaitThread(Stream_Thread_global, NULL); |
6533 #endif | |
6534 | 7081 |
6535 fprintf(stderr, "Destroying mutex\n"); | 7082 fprintf(stderr, "Destroying mutex\n"); |
6536 SDL_DestroyMutex(simple_lock); | 7083 SDL_DestroyMutex(s_simpleLock); |
7084 #endif | |
6537 | 7085 |
6538 fprintf(stderr, "Deleting OpenAL sources\n"); | 7086 fprintf(stderr, "Deleting OpenAL sources\n"); |
6539 /* Delete all the OpenAL sources */ | 7087 /* Delete all the OpenAL sources */ |
6540 for(i=0; i<Number_of_Channels_global; i++) | 7088 for(i=0; i<Number_of_Channels_global; i++) |
6541 { | 7089 { |
6568 } | 7116 } |
6569 alcCloseDevice(dev); | 7117 alcCloseDevice(dev); |
6570 | 7118 |
6571 Sound_Quit(); | 7119 Sound_Quit(); |
6572 | 7120 |
7121 #ifdef ALMIXER_COMPILE_WITHOUT_SDL | |
7122 /* Remember: ALmixer_SetError/GetError calls will not work while this is gone. */ | |
7123 TError_FreeErrorPool(s_ALmixerErrorPool); | |
7124 s_ALmixerErrorPool = NULL; | |
7125 #endif | |
6573 return; | 7126 return; |
6574 } | 7127 } |
6575 | 7128 |
6576 SDL_bool ALmixer_IsInitialized() | 7129 ALboolean ALmixer_IsInitialized() |
6577 { | 7130 { |
6578 return ALmixer_Initialized; | 7131 return ALmixer_Initialized; |
6579 } | 7132 } |
6580 | 7133 |
6581 Uint32 ALmixer_GetFrequency() | 7134 ALuint ALmixer_GetFrequency() |
6582 { | 7135 { |
6583 return ALmixer_Frequency_global; | 7136 return ALmixer_Frequency_global; |
6584 } | 7137 } |
6585 | 7138 |
6586 const SDL_version* ALmixer_Linked_Version() | 7139 const ALmixer_version* ALmixer_GetLinkedVersion() |
6587 { | 7140 { |
6588 static SDL_version linked_mixver; | 7141 static ALmixer_version linked_mixver; |
6589 ALMIXER_VERSION(&linked_mixver); | 7142 ALMIXER_GET_COMPILED_VERSION(&linked_mixver); |
6590 return(&linked_mixver); | 7143 return(&linked_mixver); |
6591 } | 7144 } |
6592 | 7145 |
7146 #ifdef ALMIXER_COMPILE_WITHOUT_SDL | |
7147 | |
7148 const char* ALmixer_GetError() | |
7149 { | |
7150 const char* error_string = NULL; | |
7151 if(NULL == s_ALmixerErrorPool) | |
7152 { | |
7153 return "Error: You should not call ALmixer_GetError while ALmixer is not initialized"; | |
7154 } | |
7155 error_string = TError_GetLastErrorStr(s_ALmixerErrorPool); | |
7156 /* SDL returns empty strings instead of NULL */ | |
7157 if(NULL == error_string) | |
7158 { | |
7159 return ""; | |
7160 } | |
7161 else | |
7162 { | |
7163 return error_string; | |
7164 } | |
7165 } | |
7166 | |
7167 void ALmixer_SetError(const char* err_str, ...) | |
7168 { | |
7169 if(NULL == s_ALmixerErrorPool) | |
7170 { | |
7171 fprintf(stderr, "Error: You should not call ALmixer_SetError while ALmixer is not initialized\n"); | |
7172 return; | |
7173 } | |
7174 va_list argp; | |
7175 va_start(argp, err_str); | |
7176 // SDL_SetError which I'm emulating has no number parameter. | |
7177 TError_SetErrorv(s_ALmixerErrorPool, 1, err_str, argp); | |
7178 va_end(argp); | |
7179 } | |
7180 | |
7181 #endif | |
6593 | 7182 |
6594 | 7183 |
6595 | 7184 |
6596 | 7185 |
6597 #if 0 | 7186 #if 0 |
6598 void ALmixer_Output_Attributes() | 7187 void ALmixer_OutputAttributes() |
6599 { | 7188 { |
6600 ALint num_flags = 0; | 7189 ALint num_flags = 0; |
6601 ALint* flags = 0; | 7190 ALint* flags = 0; |
6602 int i; | 7191 int i; |
6603 ALCdevice* dev = alcGetContextsDevice( alcGetCurrentContext() ); | 7192 ALCdevice* dev = alcGetContextsDevice( alcGetCurrentContext() ); |
6626 free(flags); | 7215 free(flags); |
6627 } | 7216 } |
6628 #endif | 7217 #endif |
6629 | 7218 |
6630 | 7219 |
6631 void ALmixer_Output_Decoders() | 7220 void ALmixer_OutputDecoders() |
6632 { | 7221 { |
6633 Sound_Version sound_compile_version; | 7222 Sound_Version sound_compile_version; |
6634 Sound_Version sound_link_version; | 7223 Sound_Version sound_link_version; |
6635 | 7224 |
6636 const Sound_DecoderInfo **rc = Sound_AvailableDecoders(); | 7225 const Sound_DecoderInfo **rc = Sound_AvailableDecoders(); |
6671 } /* else */ | 7260 } /* else */ |
6672 | 7261 |
6673 fprintf(stream, "\n"); | 7262 fprintf(stream, "\n"); |
6674 } | 7263 } |
6675 | 7264 |
6676 void ALmixer_Output_OpenAL_Info() | 7265 void ALmixer_OutputOpenALInfo() |
6677 { | 7266 { |
6678 SDL_version mixer_compile_version; | 7267 ALmixer_version mixer_compile_version; |
6679 const SDL_version * mixer_link_version=ALmixer_Linked_Version(); | 7268 const ALmixer_version * mixer_link_version=ALmixer_GetLinkedVersion(); |
6680 FILE* stream = stdout; | 7269 FILE* stream = stdout; |
6681 | 7270 |
6682 fprintf(stream, "OpenAL Information:\n"); | 7271 fprintf(stream, "OpenAL Information:\n"); |
6683 fprintf(stream, "\tAL_VENDOR: %s\n", alGetString( AL_VENDOR ) ); | 7272 fprintf(stream, "\tAL_VENDOR: %s\n", alGetString( AL_VENDOR ) ); |
6684 fprintf(stream, "\tAL_VERSION: %s\n", alGetString( AL_VERSION ) ); | 7273 fprintf(stream, "\tAL_VERSION: %s\n", alGetString( AL_VERSION ) ); |
6685 fprintf(stream, "\tAL_RENDERER: %s\n", alGetString( AL_RENDERER ) ); | 7274 fprintf(stream, "\tAL_RENDERER: %s\n", alGetString( AL_RENDERER ) ); |
6686 fprintf(stream, "\tAL_EXTENSIONS: %s\n", alGetString( AL_EXTENSIONS ) ); | 7275 fprintf(stream, "\tAL_EXTENSIONS: %s\n", alGetString( AL_EXTENSIONS ) ); |
6687 | 7276 |
6688 ALMIXER_VERSION(&mixer_compile_version); | 7277 ALMIXER_GET_COMPILED_VERSION(&mixer_compile_version); |
6689 fprintf(stream, "\nSDL_ALmixer Information:\n"); | 7278 fprintf(stream, "\nSDL_ALmixer Information:\n"); |
6690 fprintf(stream, "\tCompiled with SDL_ALmixer version: %d.%d.%d\n", | 7279 fprintf(stream, "\tCompiled with SDL_ALmixer version: %d.%d.%d\n", |
6691 mixer_compile_version.major, | 7280 mixer_compile_version.major, |
6692 mixer_compile_version.minor, | 7281 mixer_compile_version.minor, |
6693 mixer_compile_version.patch); | 7282 mixer_compile_version.patch); |
6709 #endif | 7298 #endif |
6710 fprintf(stream, "\n"); | 7299 fprintf(stream, "\n"); |
6711 } | 7300 } |
6712 | 7301 |
6713 | 7302 |
6714 Sint32 ALmixer_AllocateChannels(Sint32 numchans) | 7303 ALint ALmixer_AllocateChannels(ALint numchans) |
6715 { | 7304 { |
6716 Sint32 retval; | 7305 ALint retval; |
6717 SDL_LockMutex(simple_lock); | 7306 #ifdef ENABLE_ALMIXER_THREADS |
7307 SDL_LockMutex(s_simpleLock); | |
7308 #endif | |
6718 retval = Internal_AllocateChannels(numchans); | 7309 retval = Internal_AllocateChannels(numchans); |
6719 SDL_UnlockMutex(simple_lock); | 7310 #ifdef ENABLE_ALMIXER_THREADS |
7311 SDL_UnlockMutex(s_simpleLock); | |
7312 #endif | |
6720 return retval; | 7313 return retval; |
6721 } | 7314 } |
6722 | 7315 |
6723 | 7316 |
6724 Sint32 ALmixer_ReserveChannels(Sint32 num) | 7317 ALint ALmixer_ReserveChannels(ALint num) |
6725 { | 7318 { |
6726 Sint32 retval; | 7319 ALint retval; |
6727 SDL_LockMutex(simple_lock); | 7320 #ifdef ENABLE_ALMIXER_THREADS |
7321 SDL_LockMutex(s_simpleLock); | |
7322 #endif | |
6728 retval = Internal_ReserveChannels(num); | 7323 retval = Internal_ReserveChannels(num); |
6729 SDL_UnlockMutex(simple_lock); | 7324 #ifdef ENABLE_ALMIXER_THREADS |
7325 SDL_UnlockMutex(s_simpleLock); | |
7326 #endif | |
6730 return retval; | 7327 return retval; |
6731 } | 7328 } |
6732 | 7329 |
6733 | 7330 |
6734 | 7331 |
6735 | 7332 |
6736 static ALmixer_Data* DoLoad(Sound_Sample* sample, Uint32 buffersize, SDL_bool decode_mode_is_predecoded, Uint32 max_queue_buffers, Uint32 num_startup_buffers, SDL_bool access_data) | 7333 static ALmixer_Data* DoLoad(Sound_Sample* sample, ALuint buffersize, ALboolean decode_mode_is_predecoded, ALuint max_queue_buffers, ALuint num_startup_buffers, ALboolean access_data) |
6737 { | 7334 { |
6738 Uint32 bytes_decoded; | 7335 ALuint bytes_decoded; |
6739 ALmixer_Data* ret_data; | 7336 ALmixer_Data* ret_data; |
6740 ALenum error; | 7337 ALenum error; |
6741 | 7338 |
6742 /* Allocate memory */ | 7339 /* Allocate memory */ |
6743 ret_data = (ALmixer_Data *)malloc(sizeof(ALmixer_Data)); | 7340 ret_data = (ALmixer_Data *)malloc(sizeof(ALmixer_Data)); |
6793 | 7390 |
6794 /* Now decode and load the data into a data chunk */ | 7391 /* Now decode and load the data into a data chunk */ |
6795 /* Different cases for Streamed and Predecoded | 7392 /* Different cases for Streamed and Predecoded |
6796 * Streamed might turn into a predecoded if buffersize | 7393 * Streamed might turn into a predecoded if buffersize |
6797 * is large enough */ | 7394 * is large enough */ |
6798 if(SDL_FALSE == decode_mode_is_predecoded) | 7395 if(AL_FALSE == decode_mode_is_predecoded) |
6799 { | 7396 { |
6800 bytes_decoded = Sound_Decode(sample); | 7397 bytes_decoded = Sound_Decode(sample); |
6801 if(sample->flags & SOUND_SAMPLEFLAG_ERROR) | 7398 if(sample->flags & SOUND_SAMPLEFLAG_ERROR) |
6802 { | 7399 { |
6803 ALmixer_SetError(Sound_GetError()); | 7400 ALmixer_SetError(Sound_GetError()); |
6879 alGetError(); | 7476 alGetError(); |
6880 /* Now generate an OpenAL buffer using that first element */ | 7477 /* Now generate an OpenAL buffer using that first element */ |
6881 alGenBuffers(1, ret_data->buffer); | 7478 alGenBuffers(1, ret_data->buffer); |
6882 if( (error = alGetError()) != AL_NO_ERROR) | 7479 if( (error = alGetError()) != AL_NO_ERROR) |
6883 { | 7480 { |
6884 ALmixer_SetError("alGenBuffers failed: %s\n", aluGetErrorString(error)); | 7481 ALmixer_SetError("alGenBuffers failed: %s\n", alGetString(error)); |
6885 Sound_FreeSample(sample); | 7482 Sound_FreeSample(sample); |
6886 free(ret_data->buffer); | 7483 free(ret_data->buffer); |
6887 free(ret_data); | 7484 free(ret_data); |
6888 return NULL; | 7485 return NULL; |
6889 } | 7486 } |
6898 bytes_decoded, | 7495 bytes_decoded, |
6899 sample->desired.rate | 7496 sample->desired.rate |
6900 ); | 7497 ); |
6901 if( (error = alGetError()) != AL_NO_ERROR) | 7498 if( (error = alGetError()) != AL_NO_ERROR) |
6902 { | 7499 { |
6903 ALmixer_SetError("alBufferData failed: %s\n", aluGetErrorString(error)); | 7500 ALmixer_SetError("alBufferData failed: %s\n", alGetString(error)); |
6904 Sound_FreeSample(sample); | 7501 Sound_FreeSample(sample); |
6905 alDeleteBuffers(1, ret_data->buffer); | 7502 alDeleteBuffers(1, ret_data->buffer); |
6906 free(ret_data->buffer); | 7503 free(ret_data->buffer); |
6907 free(ret_data); | 7504 free(ret_data); |
6908 return NULL; | 7505 return NULL; |
6980 alGetError(); | 7577 alGetError(); |
6981 /* Now generate an OpenAL buffer using that first element */ | 7578 /* Now generate an OpenAL buffer using that first element */ |
6982 alGenBuffers(max_queue_buffers, ret_data->buffer); | 7579 alGenBuffers(max_queue_buffers, ret_data->buffer); |
6983 if( (error = alGetError()) != AL_NO_ERROR) | 7580 if( (error = alGetError()) != AL_NO_ERROR) |
6984 { | 7581 { |
6985 ALmixer_SetError("alGenBuffers failed: %s\n", aluGetErrorString(error)); | 7582 ALmixer_SetError("alGenBuffers failed: %s\n", alGetString(error)); |
6986 Sound_FreeSample(sample); | 7583 Sound_FreeSample(sample); |
6987 free(ret_data->buffer); | 7584 free(ret_data->buffer); |
6988 free(ret_data); | 7585 free(ret_data); |
6989 return NULL; | 7586 return NULL; |
6990 } | 7587 } |
7030 * Allocate the memory for the buffers here | 7627 * Allocate the memory for the buffers here |
7031 * and initialize the albuffer-index map | 7628 * and initialize the albuffer-index map |
7032 */ | 7629 */ |
7033 if(access_data) | 7630 if(access_data) |
7034 { | 7631 { |
7035 Uint32 j; | 7632 ALuint j; |
7036 /* Create buffers for data access | 7633 /* Create buffers for data access |
7037 * Should be the same number as the number of queue buffers | 7634 * Should be the same number as the number of queue buffers |
7038 */ | 7635 */ |
7039 ret_data->buffer_map_list = (ALmixer_Buffer_Map*)malloc( sizeof(ALmixer_Buffer_Map) * max_queue_buffers); | 7636 ret_data->buffer_map_list = (ALmixer_Buffer_Map*)malloc( sizeof(ALmixer_Buffer_Map) * max_queue_buffers); |
7040 if(NULL == ret_data->buffer_map_list) | 7637 if(NULL == ret_data->buffer_map_list) |
7061 for(j=0; j<max_queue_buffers; j++) | 7658 for(j=0; j<max_queue_buffers; j++) |
7062 { | 7659 { |
7063 ret_data->buffer_map_list[j].albuffer = ret_data->buffer[j]; | 7660 ret_data->buffer_map_list[j].albuffer = ret_data->buffer[j]; |
7064 ret_data->buffer_map_list[j].index = j; | 7661 ret_data->buffer_map_list[j].index = j; |
7065 ret_data->buffer_map_list[j].num_bytes = 0; | 7662 ret_data->buffer_map_list[j].num_bytes = 0; |
7066 ret_data->buffer_map_list[j].data = (Uint8*)malloc( sizeof(Uint8) * buffersize); | 7663 ret_data->buffer_map_list[j].data = (ALbyte*)malloc( sizeof(ALbyte) * buffersize); |
7067 if(NULL == ret_data->buffer_map_list[j].data) | 7664 if(NULL == ret_data->buffer_map_list[j].data) |
7068 { | 7665 { |
7069 ALmixer_SetError("Out of Memory"); | 7666 ALmixer_SetError("Out of Memory"); |
7070 break; | 7667 break; |
7071 } | 7668 } |
7093 | 7690 |
7094 | 7691 |
7095 } /* End of do stream */ | 7692 } /* End of do stream */ |
7096 } /* end of DECODE_STREAM */ | 7693 } /* end of DECODE_STREAM */ |
7097 /* User requested decode all (easy, nothing to figure out) */ | 7694 /* User requested decode all (easy, nothing to figure out) */ |
7098 else if(SDL_TRUE == decode_mode_is_predecoded) | 7695 else if(AL_TRUE == decode_mode_is_predecoded) |
7099 { | 7696 { |
7697 #ifndef ALMIXER_DISABLE_PREDECODED_PRECOMPUTE_BUFFER_SIZE_OPTIMIZATION | |
7698 /* SDL_sound (behind the scenes) seems to loop on buffer_size chunks | |
7699 * until the buffer is filled. It seems like we can | |
7700 * do much better and precompute the size of the buffer | |
7701 * so looping isn't needed. | |
7702 * WARNING: Due to the way SDL_sound is currently implemented, | |
7703 * this may waste a lot of memory up front. | |
7704 * SDL_sound seems to pre-create a buffer of the requested size, | |
7705 * but on DecodeAll, an entirely new buffer is created and | |
7706 * everything is memcpy'd into the new buffer in read chunks | |
7707 * of the buffer_size. This means we need roughly twice the memory | |
7708 * to load a file. | |
7709 */ | |
7710 ALint sound_duration = Sound_GetDuration(sample); | |
7711 if(sound_duration > 0) | |
7712 { | |
7713 size_t total_bytes = Compute_Total_Bytes_With_Frame_Padding(&sample->desired, (ALuint)sound_duration); | |
7714 int buffer_resize_succeeded = Sound_SetBufferSize(sample, total_bytes); | |
7715 if(0 == buffer_resize_succeeded) | |
7716 { | |
7717 ALmixer_SetError(Sound_GetError()); | |
7718 Sound_FreeSample(sample); | |
7719 free(ret_data); | |
7720 return NULL; | |
7721 } | |
7722 } | |
7723 #endif /* ALMIXER_DISABLE_PREDECODED_PRECOMPUTE_BUFFER_SIZE_OPTIMIZATION */ | |
7100 bytes_decoded = Sound_DecodeAll(sample); | 7724 bytes_decoded = Sound_DecodeAll(sample); |
7101 if(sample->flags & SOUND_SAMPLEFLAG_ERROR) | 7725 if(sample->flags & SOUND_SAMPLEFLAG_ERROR) |
7102 { | 7726 { |
7103 ALmixer_SetError(Sound_GetError()); | 7727 ALmixer_SetError(Sound_GetError()); |
7104 Sound_FreeSample(sample); | 7728 Sound_FreeSample(sample); |
7145 alGetError(); | 7769 alGetError(); |
7146 /* Now generate an OpenAL buffer using that first element */ | 7770 /* Now generate an OpenAL buffer using that first element */ |
7147 alGenBuffers(1, ret_data->buffer); | 7771 alGenBuffers(1, ret_data->buffer); |
7148 if( (error = alGetError()) != AL_NO_ERROR) | 7772 if( (error = alGetError()) != AL_NO_ERROR) |
7149 { | 7773 { |
7150 ALmixer_SetError("alGenBuffers failed: %s\n", aluGetErrorString(error)); | 7774 ALmixer_SetError("alGenBuffers failed: %s\n", alGetString(error)); |
7151 Sound_FreeSample(sample); | 7775 Sound_FreeSample(sample); |
7152 free(ret_data->buffer); | 7776 free(ret_data->buffer); |
7153 free(ret_data); | 7777 free(ret_data); |
7154 return NULL; | 7778 return NULL; |
7155 } | 7779 } |
7164 bytes_decoded, | 7788 bytes_decoded, |
7165 sample->desired.rate | 7789 sample->desired.rate |
7166 ); | 7790 ); |
7167 if( (error = alGetError()) != AL_NO_ERROR) | 7791 if( (error = alGetError()) != AL_NO_ERROR) |
7168 { | 7792 { |
7169 ALmixer_SetError("alBufferData failed: %s\n", aluGetErrorString(error)); | 7793 ALmixer_SetError("alBufferData failed: %s\n", alGetString(error)); |
7170 Sound_FreeSample(sample); | 7794 Sound_FreeSample(sample); |
7171 alDeleteBuffers(1, ret_data->buffer); | 7795 alDeleteBuffers(1, ret_data->buffer); |
7172 free(ret_data->buffer); | 7796 free(ret_data->buffer); |
7173 free(ret_data); | 7797 free(ret_data); |
7174 return NULL; | 7798 return NULL; |
7236 * I don't like the AudioInfo parameter. I removed it once, | 7860 * I don't like the AudioInfo parameter. I removed it once, |
7237 * but the system will fail on RAW samples because the user | 7861 * but the system will fail on RAW samples because the user |
7238 * must specify it, so I had to bring it back. | 7862 * must specify it, so I had to bring it back. |
7239 * Remember I must close the rwops if there is an error before NewSample() | 7863 * Remember I must close the rwops if there is an error before NewSample() |
7240 */ | 7864 */ |
7241 ALmixer_Data* ALmixer_LoadSample_RW(SDL_RWops* rwops, const char* fileext, Uint32 buffersize, SDL_bool decode_mode_is_predecoded, Uint32 max_queue_buffers, Uint32 num_startup_buffers, SDL_bool access_data) | 7865 ALmixer_Data* ALmixer_LoadSample_RW(ALmixer_RWops* rwops, const char* fileext, ALuint buffersize, ALboolean decode_mode_is_predecoded, ALuint max_queue_buffers, ALuint num_startup_buffers, ALboolean access_data) |
7242 { | 7866 { |
7243 Sound_Sample* sample = NULL; | 7867 Sound_Sample* sample = NULL; |
7244 Sound_AudioInfo target; | 7868 Sound_AudioInfo target; |
7245 | 7869 |
7246 /* Initialize target values to defaults | 7870 /* Initialize target values to defaults |
7282 /* This will load a sample for us from | 7906 /* This will load a sample for us from |
7283 * a file (instead of RWops). Most of the uglyness is | 7907 * a file (instead of RWops). Most of the uglyness is |
7284 * error checking and the fact that streamed/predecoded files | 7908 * error checking and the fact that streamed/predecoded files |
7285 * must be treated differently. | 7909 * must be treated differently. |
7286 */ | 7910 */ |
7287 ALmixer_Data* ALmixer_LoadSample(const char* filename, Uint32 buffersize, SDL_bool decode_mode_is_predecoded, Uint32 max_queue_buffers, Uint32 num_startup_buffers, SDL_bool access_data) | 7911 ALmixer_Data* ALmixer_LoadSample(const char* filename, ALuint buffersize, ALboolean decode_mode_is_predecoded, ALuint max_queue_buffers, ALuint num_startup_buffers, ALboolean access_data) |
7288 { | 7912 { |
7289 Sound_Sample* sample = NULL; | 7913 Sound_Sample* sample = NULL; |
7290 Sound_AudioInfo target; | 7914 Sound_AudioInfo target; |
7291 | 7915 |
7292 /* Initialize target values to defaults | 7916 /* Initialize target values to defaults |
7383 | 8007 |
7384 | 8008 |
7385 /* This is a back door for RAW samples or if you need the | 8009 /* This is a back door for RAW samples or if you need the |
7386 * AudioInfo field. Use at your own risk. | 8010 * AudioInfo field. Use at your own risk. |
7387 */ | 8011 */ |
7388 ALmixer_Data* ALmixer_LoadSample_RAW_RW(SDL_RWops* rwops, const char* fileext, ALmixer_AudioInfo* desired, Uint32 buffersize, SDL_bool decode_mode_is_predecoded, Uint32 max_queue_buffers, Uint32 num_startup_buffers, SDL_bool access_data) | 8012 ALmixer_Data* ALmixer_LoadSample_RAW_RW(ALmixer_RWops* rwops, const char* fileext, ALmixer_AudioInfo* desired, ALuint buffersize, ALboolean decode_mode_is_predecoded, ALuint max_queue_buffers, ALuint num_startup_buffers, ALboolean access_data) |
7389 { | 8013 { |
7390 Sound_Sample* sample = NULL; | 8014 Sound_Sample* sample = NULL; |
7391 Sound_AudioInfo sound_desired; | 8015 Sound_AudioInfo sound_desired; |
7392 /* Rather than copying the data from struct to struct, I could just | 8016 /* Rather than copying the data from struct to struct, I could just |
7393 * cast the thing since the structs are meant to be identical. | 8017 * cast the thing since the structs are meant to be identical. |
7419 | 8043 |
7420 | 8044 |
7421 /* This is a back door for RAW samples or if you need the | 8045 /* This is a back door for RAW samples or if you need the |
7422 * AudioInfo field. Use at your own risk. | 8046 * AudioInfo field. Use at your own risk. |
7423 */ | 8047 */ |
7424 ALmixer_Data* ALmixer_LoadSample_RAW(const char* filename, ALmixer_AudioInfo* desired, Uint32 buffersize, SDL_bool decode_mode_is_predecoded, Uint32 max_queue_buffers, Uint32 num_startup_buffers, SDL_bool access_data) | 8048 ALmixer_Data* ALmixer_LoadSample_RAW(const char* filename, ALmixer_AudioInfo* desired, ALuint buffersize, ALboolean decode_mode_is_predecoded, ALuint max_queue_buffers, ALuint num_startup_buffers, ALboolean access_data) |
7425 { | 8049 { |
7426 Sound_Sample* sample = NULL; | 8050 Sound_Sample* sample = NULL; |
7427 Sound_AudioInfo sound_desired; | 8051 Sound_AudioInfo sound_desired; |
7428 /* Rather than copying the data from struct to struct, I could just | 8052 /* Rather than copying the data from struct to struct, I could just |
7429 * cast the thing since the structs are meant to be identical. | 8053 * cast the thing since the structs are meant to be identical. |
7474 } | 8098 } |
7475 alDeleteBuffers(1, data->buffer); | 8099 alDeleteBuffers(1, data->buffer); |
7476 if((error = alGetError()) != AL_NO_ERROR) | 8100 if((error = alGetError()) != AL_NO_ERROR) |
7477 { | 8101 { |
7478 fprintf(stderr, "70Testing error: %s\n", | 8102 fprintf(stderr, "70Testing error: %s\n", |
7479 aluGetErrorString(error)); | 8103 alGetString(error)); |
7480 } | 8104 } |
7481 | 8105 |
7482 } | 8106 } |
7483 else | 8107 else |
7484 { | 8108 { |
7485 Uint32 i; | 8109 ALuint i; |
7486 | 8110 |
7487 /* Delete buffer copies if access_data was enabled */ | 8111 /* Delete buffer copies if access_data was enabled */ |
7488 if(data->buffer_map_list != NULL) | 8112 if(data->buffer_map_list != NULL) |
7489 { | 8113 { |
7490 for(i=0; i<data->max_queue_buffers; i++) | 8114 for(i=0; i<data->max_queue_buffers; i++) |
7501 Sound_FreeSample(data->sample); | 8125 Sound_FreeSample(data->sample); |
7502 alDeleteBuffers(data->max_queue_buffers, data->buffer); | 8126 alDeleteBuffers(data->max_queue_buffers, data->buffer); |
7503 if((error = alGetError()) != AL_NO_ERROR) | 8127 if((error = alGetError()) != AL_NO_ERROR) |
7504 { | 8128 { |
7505 fprintf(stderr, "71Testing error: %s\n", | 8129 fprintf(stderr, "71Testing error: %s\n", |
7506 aluGetErrorString(error)); | 8130 alGetString(error)); |
7507 } | 8131 } |
7508 } | 8132 } |
7509 free(data->buffer); | 8133 free(data->buffer); |
7510 free(data); | 8134 free(data); |
7511 } | 8135 } |
7512 | 8136 |
7513 Sint32 ALmixer_GetTotalTime(ALmixer_Data* data) | 8137 ALint ALmixer_GetTotalTime(ALmixer_Data* data) |
7514 { | 8138 { |
8139 if(NULL == data) | |
8140 { | |
8141 return -1; | |
8142 } | |
7515 return data->total_time; | 8143 return data->total_time; |
7516 } | 8144 } |
7517 | 8145 |
7518 /* This function will look up the source for the corresponding channel */ | 8146 /* This function will look up the source for the corresponding channel */ |
7519 /* Must return 0 on error instead of -1 because of unsigned int */ | 8147 /* Must return 0 on error instead of -1 because of unsigned int */ |
7520 ALuint ALmixer_GetSource(Sint32 channel) | 8148 ALuint ALmixer_GetSource(ALint channel) |
7521 { | 8149 { |
7522 ALuint retval; | 8150 ALuint retval; |
7523 SDL_LockMutex(simple_lock); | 8151 #ifdef ENABLE_ALMIXER_THREADS |
8152 SDL_LockMutex(s_simpleLock); | |
8153 #endif | |
7524 retval = Internal_GetSource(channel); | 8154 retval = Internal_GetSource(channel); |
7525 SDL_UnlockMutex(simple_lock); | 8155 #ifdef ENABLE_ALMIXER_THREADS |
8156 SDL_UnlockMutex(s_simpleLock); | |
8157 #endif | |
7526 return retval; | 8158 return retval; |
7527 } | 8159 } |
7528 | 8160 |
7529 /* This function will look up the channel for the corresponding source */ | 8161 /* This function will look up the channel for the corresponding source */ |
7530 Sint32 ALmixer_GetChannel(ALuint source) | 8162 ALint ALmixer_GetChannel(ALuint source) |
7531 { | 8163 { |
7532 Sint32 retval; | 8164 ALint retval; |
7533 SDL_LockMutex(simple_lock); | 8165 #ifdef ENABLE_ALMIXER_THREADS |
8166 SDL_LockMutex(s_simpleLock); | |
8167 #endif | |
7534 retval = Internal_GetChannel(source); | 8168 retval = Internal_GetChannel(source); |
7535 SDL_UnlockMutex(simple_lock); | 8169 #ifdef ENABLE_ALMIXER_THREADS |
8170 SDL_UnlockMutex(s_simpleLock); | |
8171 #endif | |
7536 return retval; | 8172 return retval; |
7537 } | 8173 } |
7538 | 8174 |
7539 Sint32 ALmixer_FindFreeChannel(Sint32 start_channel) | 8175 ALint ALmixer_FindFreeChannel(ALint start_channel) |
7540 { | 8176 { |
7541 Sint32 retval; | 8177 ALint retval; |
7542 SDL_LockMutex(simple_lock); | 8178 #ifdef ENABLE_ALMIXER_THREADS |
8179 SDL_LockMutex(s_simpleLock); | |
8180 #endif | |
7543 retval = Internal_FindFreeChannel(start_channel); | 8181 retval = Internal_FindFreeChannel(start_channel); |
7544 SDL_UnlockMutex(simple_lock); | 8182 #ifdef ENABLE_ALMIXER_THREADS |
8183 SDL_UnlockMutex(s_simpleLock); | |
8184 #endif | |
7545 return retval; | 8185 return retval; |
7546 } | 8186 } |
7547 | 8187 |
7548 | 8188 |
7549 | 8189 |
7554 * call the next update loop in case you are worried | 8194 * call the next update loop in case you are worried |
7555 * about preserving CPU cycles. The idea is that | 8195 * about preserving CPU cycles. The idea is that |
7556 * when a buffer is queued, there was probably some | 8196 * when a buffer is queued, there was probably some |
7557 * CPU intensive looping which took awhile. | 8197 * CPU intensive looping which took awhile. |
7558 * It's mainly provided as a convenience. | 8198 * It's mainly provided as a convenience. |
7559 * Timing the call with SDL_GetTicks() would produce | 8199 * Timing the call with ALmixer_GetTicks() would produce |
7560 * more accurate information. | 8200 * more accurate information. |
7561 * Returns a negative value if there was an error, | 8201 * Returns a negative value if there was an error, |
7562 * the value being the number of errors. | 8202 * the value being the number of errors. |
7563 */ | 8203 */ |
7564 Sint32 ALmixer_Update() | 8204 ALint ALmixer_Update() |
7565 { | 8205 { |
7566 #ifdef ENABLE_ALMIXER_THREADS | 8206 #ifdef ENABLE_ALMIXER_THREADS |
7567 /* The thread will handle all updates by itself. | 8207 /* The thread will handle all updates by itself. |
7568 * Don't allow the user to explicitly call update. | 8208 * Don't allow the user to explicitly call update. |
7569 */ | 8209 */ |
7573 #endif | 8213 #endif |
7574 } | 8214 } |
7575 | 8215 |
7576 | 8216 |
7577 | 8217 |
7578 void ALmixer_ChannelFinished(void (*channel_finished)(Sint32 channel, void* userdata), void* userdata) | 8218 void ALmixer_SetPlaybackFinishedCallback(void (*playback_finished_callback)(ALint which_channel, ALuint al_source, ALmixer_Data* almixer_data, ALboolean finished_naturally, void* user_data), void* user_data) |
7579 { | 8219 { |
7580 SDL_LockMutex(simple_lock); | 8220 #ifdef ENABLE_ALMIXER_THREADS |
7581 Channel_Done_Callback = channel_finished; | 8221 SDL_LockMutex(s_simpleLock); |
7582 Channel_Done_Callback_Userdata = userdata; | 8222 #endif |
7583 SDL_UnlockMutex(simple_lock); | 8223 Channel_Done_Callback = playback_finished_callback; |
7584 } | 8224 Channel_Done_Callback_Userdata = user_data; |
7585 | 8225 #ifdef ENABLE_ALMIXER_THREADS |
7586 | 8226 SDL_UnlockMutex(s_simpleLock); |
7587 void ALmixer_ChannelData(void (*channel_data)(Sint32 which_chan, Uint8* data, Uint32 num_bytes, Uint32 frequency, Uint8 channels, Uint8 bit_depth, SDL_bool is_unsigned, SDL_bool decode_mode_is_predecoded, Uint32 length_in_msec, void* user_data), void* user_data) | 8227 #endif |
7588 { | 8228 } |
7589 SDL_LockMutex(simple_lock); | 8229 |
7590 Channel_Data_Callback = channel_data; | 8230 |
8231 void ALmixer_SetPlaybackDataCallback(void (*playback_data_callback)(ALint which_chan, ALuint al_source, ALbyte* data, ALuint num_bytes, ALuint frequency, ALubyte channels, ALubyte bit_depth, ALboolean is_unsigned, ALboolean decode_mode_is_predecoded, ALuint length_in_msec, void* user_data), void* user_data) | |
8232 { | |
8233 #ifdef ENABLE_ALMIXER_THREADS | |
8234 SDL_LockMutex(s_simpleLock); | |
8235 #endif | |
8236 Channel_Data_Callback = playback_data_callback; | |
7591 Channel_Data_Callback_Userdata = user_data; | 8237 Channel_Data_Callback_Userdata = user_data; |
7592 SDL_UnlockMutex(simple_lock); | 8238 #ifdef ENABLE_ALMIXER_THREADS |
7593 } | 8239 SDL_UnlockMutex(s_simpleLock); |
7594 | 8240 #endif |
7595 | 8241 } |
7596 | 8242 |
7597 | 8243 |
7598 | 8244 |
7599 Sint32 ALmixer_PlayChannelTimed(Sint32 channel, ALmixer_Data* data, Sint32 loops, Sint32 ticks) | 8245 |
7600 { | 8246 |
7601 Sint32 retval; | 8247 ALint ALmixer_PlayChannelTimed(ALint channel, ALmixer_Data* data, ALint loops, ALint ticks) |
7602 SDL_LockMutex(simple_lock); | 8248 { |
8249 ALint retval; | |
8250 #ifdef ENABLE_ALMIXER_THREADS | |
8251 SDL_LockMutex(s_simpleLock); | |
8252 #endif | |
7603 retval = Internal_PlayChannelTimed(channel, data, loops, ticks); | 8253 retval = Internal_PlayChannelTimed(channel, data, loops, ticks); |
7604 SDL_UnlockMutex(simple_lock); | 8254 #ifdef ENABLE_ALMIXER_THREADS |
8255 SDL_UnlockMutex(s_simpleLock); | |
8256 #endif | |
7605 return retval; | 8257 return retval; |
7606 } | 8258 } |
7607 | 8259 |
7608 | 8260 |
7609 /* In case the user wants to specify a source instead of a channel, | 8261 /* In case the user wants to specify a source instead of a channel, |
7616 * first available channels because source and channels have | 8268 * first available channels because source and channels have |
7617 * a one-to-one mapping in this API. It is quite easy for | 8269 * a one-to-one mapping in this API. It is quite easy for |
7618 * a channel/source to already be in use because of this. | 8270 * a channel/source to already be in use because of this. |
7619 * In this event, an error message will be returned to you. | 8271 * In this event, an error message will be returned to you. |
7620 */ | 8272 */ |
7621 ALuint ALmixer_PlaySourceTimed(ALuint source, ALmixer_Data* data, Sint32 loops, Sint32 ticks) | 8273 ALuint ALmixer_PlaySourceTimed(ALuint source, ALmixer_Data* data, ALint loops, ALint ticks) |
7622 { | 8274 { |
7623 ALuint retval; | 8275 ALuint retval; |
7624 SDL_LockMutex(simple_lock); | 8276 #ifdef ENABLE_ALMIXER_THREADS |
8277 SDL_LockMutex(s_simpleLock); | |
8278 #endif | |
7625 retval = Internal_PlaySourceTimed(source, data, loops, ticks); | 8279 retval = Internal_PlaySourceTimed(source, data, loops, ticks); |
7626 SDL_UnlockMutex(simple_lock); | 8280 #ifdef ENABLE_ALMIXER_THREADS |
8281 SDL_UnlockMutex(s_simpleLock); | |
8282 #endif | |
7627 return retval; | 8283 return retval; |
7628 } | 8284 } |
7629 | 8285 |
7630 | 8286 |
7631 /* Will return the number of channels halted | 8287 /* Will return the number of channels halted |
7632 * or 0 for error | 8288 * or 0 for error |
7633 */ | 8289 */ |
7634 Sint32 ALmixer_HaltChannel(Sint32 channel) | 8290 ALint ALmixer_HaltChannel(ALint channel) |
7635 { | 8291 { |
7636 Sint32 retval; | 8292 ALint retval; |
7637 SDL_LockMutex(simple_lock); | 8293 #ifdef ENABLE_ALMIXER_THREADS |
7638 retval = Internal_HaltChannel(channel); | 8294 SDL_LockMutex(s_simpleLock); |
7639 SDL_UnlockMutex(simple_lock); | 8295 #endif |
8296 retval = Internal_HaltChannel(channel, AL_FALSE); | |
8297 #ifdef ENABLE_ALMIXER_THREADS | |
8298 SDL_UnlockMutex(s_simpleLock); | |
8299 #endif | |
7640 return retval; | 8300 return retval; |
7641 } | 8301 } |
7642 | 8302 |
7643 /* Will return the number of channels halted | 8303 /* Will return the number of channels halted |
7644 * or 0 for error | 8304 * or 0 for error |
7645 */ | 8305 */ |
7646 Sint32 ALmixer_HaltSource(ALuint source) | 8306 ALint ALmixer_HaltSource(ALuint source) |
7647 { | 8307 { |
7648 Sint32 retval; | 8308 ALint retval; |
7649 SDL_LockMutex(simple_lock); | 8309 #ifdef ENABLE_ALMIXER_THREADS |
7650 retval = Internal_HaltSource(source); | 8310 SDL_LockMutex(s_simpleLock); |
7651 SDL_UnlockMutex(simple_lock); | 8311 #endif |
8312 retval = Internal_HaltSource(source, AL_FALSE); | |
8313 #ifdef ENABLE_ALMIXER_THREADS | |
8314 SDL_UnlockMutex(s_simpleLock); | |
8315 #endif | |
7652 return retval; | 8316 return retval; |
7653 } | 8317 } |
7654 | 8318 |
7655 | 8319 |
7656 /* This will rewind the SDL_Sound sample for streamed | 8320 /* This will rewind the SDL_Sound sample for streamed |
7657 * samples and start buffering up the data for the next | 8321 * samples and start buffering up the data for the next |
7658 * playback. This may require samples to be halted | 8322 * playback. This may require samples to be halted |
7659 */ | 8323 */ |
7660 Sint32 ALmixer_RewindData(ALmixer_Data* data) | 8324 ALint ALmixer_RewindData(ALmixer_Data* data) |
7661 { | 8325 { |
7662 Sint32 retval; | 8326 ALint retval; |
7663 SDL_LockMutex(simple_lock); | 8327 #ifdef ENABLE_ALMIXER_THREADS |
8328 SDL_LockMutex(s_simpleLock); | |
8329 #endif | |
7664 retval = Internal_RewindData(data); | 8330 retval = Internal_RewindData(data); |
7665 SDL_UnlockMutex(simple_lock); | 8331 #ifdef ENABLE_ALMIXER_THREADS |
8332 SDL_UnlockMutex(s_simpleLock); | |
8333 #endif | |
7666 return retval; | 8334 return retval; |
7667 } | 8335 } |
7668 | 8336 |
7669 Sint32 ALmixer_RewindChannel(Sint32 channel) | 8337 ALint ALmixer_RewindChannel(ALint channel) |
7670 { | 8338 { |
7671 Sint32 retval; | 8339 ALint retval; |
7672 SDL_LockMutex(simple_lock); | 8340 #ifdef ENABLE_ALMIXER_THREADS |
8341 SDL_LockMutex(s_simpleLock); | |
8342 #endif | |
7673 retval = Internal_RewindChannel(channel); | 8343 retval = Internal_RewindChannel(channel); |
7674 SDL_UnlockMutex(simple_lock); | 8344 #ifdef ENABLE_ALMIXER_THREADS |
8345 SDL_UnlockMutex(s_simpleLock); | |
8346 #endif | |
7675 return retval; | 8347 return retval; |
7676 } | 8348 } |
7677 | 8349 |
7678 Sint32 ALmixer_RewindSource(ALuint source) | 8350 ALint ALmixer_RewindSource(ALuint source) |
7679 { | 8351 { |
7680 Sint32 retval; | 8352 ALint retval; |
7681 SDL_LockMutex(simple_lock); | 8353 #ifdef ENABLE_ALMIXER_THREADS |
8354 SDL_LockMutex(s_simpleLock); | |
8355 #endif | |
7682 retval = Internal_RewindSource(source); | 8356 retval = Internal_RewindSource(source); |
7683 SDL_UnlockMutex(simple_lock); | 8357 #ifdef ENABLE_ALMIXER_THREADS |
8358 SDL_UnlockMutex(s_simpleLock); | |
8359 #endif | |
7684 return retval; | 8360 return retval; |
7685 } | 8361 } |
7686 | 8362 |
7687 Sint32 ALmixer_PauseChannel(Sint32 channel) | 8363 ALint ALmixer_PauseChannel(ALint channel) |
7688 { | 8364 { |
7689 Sint32 retval; | 8365 ALint retval; |
7690 SDL_LockMutex(simple_lock); | 8366 #ifdef ENABLE_ALMIXER_THREADS |
8367 SDL_LockMutex(s_simpleLock); | |
8368 #endif | |
7691 retval = Internal_PauseChannel(channel); | 8369 retval = Internal_PauseChannel(channel); |
7692 SDL_UnlockMutex(simple_lock); | 8370 #ifdef ENABLE_ALMIXER_THREADS |
8371 SDL_UnlockMutex(s_simpleLock); | |
8372 #endif | |
7693 return retval; | 8373 return retval; |
7694 } | 8374 } |
7695 | 8375 |
7696 Sint32 ALmixer_PauseSource(ALuint source) | 8376 ALint ALmixer_PauseSource(ALuint source) |
7697 { | 8377 { |
7698 Sint32 retval; | 8378 ALint retval; |
7699 SDL_LockMutex(simple_lock); | 8379 #ifdef ENABLE_ALMIXER_THREADS |
8380 SDL_LockMutex(s_simpleLock); | |
8381 #endif | |
7700 retval = Internal_PauseSource(source); | 8382 retval = Internal_PauseSource(source); |
7701 SDL_UnlockMutex(simple_lock); | 8383 #ifdef ENABLE_ALMIXER_THREADS |
8384 SDL_UnlockMutex(s_simpleLock); | |
8385 #endif | |
7702 return retval; | 8386 return retval; |
7703 } | 8387 } |
7704 | 8388 |
7705 Sint32 ALmixer_ResumeChannel(Sint32 channel) | 8389 ALint ALmixer_ResumeChannel(ALint channel) |
7706 { | 8390 { |
7707 Sint32 retval; | 8391 ALint retval; |
7708 SDL_LockMutex(simple_lock); | 8392 #ifdef ENABLE_ALMIXER_THREADS |
8393 SDL_LockMutex(s_simpleLock); | |
8394 #endif | |
7709 retval = Internal_ResumeChannel(channel); | 8395 retval = Internal_ResumeChannel(channel); |
7710 SDL_UnlockMutex(simple_lock); | 8396 #ifdef ENABLE_ALMIXER_THREADS |
8397 SDL_UnlockMutex(s_simpleLock); | |
8398 #endif | |
7711 return retval; | 8399 return retval; |
7712 } | 8400 } |
7713 | 8401 |
7714 Sint32 ALmixer_ResumeSource(ALuint source) | 8402 ALint ALmixer_ResumeSource(ALuint source) |
7715 { | 8403 { |
7716 Sint32 retval; | 8404 ALint retval; |
7717 SDL_LockMutex(simple_lock); | 8405 #ifdef ENABLE_ALMIXER_THREADS |
8406 SDL_LockMutex(s_simpleLock); | |
8407 #endif | |
7718 retval = Internal_ResumeSource(source); | 8408 retval = Internal_ResumeSource(source); |
7719 SDL_UnlockMutex(simple_lock); | 8409 #ifdef ENABLE_ALMIXER_THREADS |
8410 SDL_UnlockMutex(s_simpleLock); | |
8411 #endif | |
7720 return retval; | 8412 return retval; |
7721 } | 8413 } |
7722 | 8414 |
7723 /* Might consider setting eof to 0 as a "feature" | 8415 /* Might consider setting eof to 0 as a "feature" |
7724 * This will allow seek to end to stay there because | 8416 * This will allow seek to end to stay there because |
7725 * Play automatically rewinds if at the end */ | 8417 * Play automatically rewinds if at the end */ |
7726 Sint32 ALmixer_Seek(ALmixer_Data* data, Uint32 msec) | 8418 ALint ALmixer_SeekData(ALmixer_Data* data, ALuint msec) |
7727 { | 8419 { |
7728 Sint32 retval; | 8420 ALint retval; |
7729 SDL_LockMutex(simple_lock); | 8421 #ifdef ENABLE_ALMIXER_THREADS |
7730 retval = Internal_Seek(data, msec); | 8422 SDL_LockMutex(s_simpleLock); |
7731 SDL_UnlockMutex(simple_lock); | 8423 #endif |
8424 retval = Internal_SeekData(data, msec); | |
8425 #ifdef ENABLE_ALMIXER_THREADS | |
8426 SDL_UnlockMutex(s_simpleLock); | |
8427 #endif | |
7732 return retval; | 8428 return retval; |
7733 } | 8429 } |
7734 | 8430 |
7735 Sint32 ALmixer_FadeInChannelTimed(Sint32 channel, ALmixer_Data* data, Sint32 loops, Uint32 fade_ticks, Sint32 expire_ticks) | 8431 ALint ALmixer_FadeInChannelTimed(ALint channel, ALmixer_Data* data, ALint loops, ALuint fade_ticks, ALint expire_ticks) |
7736 { | 8432 { |
7737 Sint32 retval; | 8433 ALint retval; |
7738 SDL_LockMutex(simple_lock); | 8434 #ifdef ENABLE_ALMIXER_THREADS |
8435 SDL_LockMutex(s_simpleLock); | |
8436 #endif | |
7739 retval = Internal_FadeInChannelTimed(channel, data, loops, fade_ticks, expire_ticks); | 8437 retval = Internal_FadeInChannelTimed(channel, data, loops, fade_ticks, expire_ticks); |
7740 SDL_UnlockMutex(simple_lock); | 8438 #ifdef ENABLE_ALMIXER_THREADS |
8439 SDL_UnlockMutex(s_simpleLock); | |
8440 #endif | |
7741 return retval; | 8441 return retval; |
7742 } | 8442 } |
7743 | 8443 |
7744 ALuint ALmixer_FadeInSourceTimed(ALuint source, ALmixer_Data* data, Sint32 loops, Uint32 fade_ticks, Sint32 expire_ticks) | 8444 ALuint ALmixer_FadeInSourceTimed(ALuint source, ALmixer_Data* data, ALint loops, ALuint fade_ticks, ALint expire_ticks) |
7745 { | 8445 { |
7746 ALuint retval; | 8446 ALuint retval; |
7747 SDL_LockMutex(simple_lock); | 8447 #ifdef ENABLE_ALMIXER_THREADS |
8448 SDL_LockMutex(s_simpleLock); | |
8449 #endif | |
7748 retval = Internal_FadeInSourceTimed(source, data, loops, fade_ticks, expire_ticks); | 8450 retval = Internal_FadeInSourceTimed(source, data, loops, fade_ticks, expire_ticks); |
7749 SDL_UnlockMutex(simple_lock); | 8451 #ifdef ENABLE_ALMIXER_THREADS |
8452 SDL_UnlockMutex(s_simpleLock); | |
8453 #endif | |
7750 return retval; | 8454 return retval; |
7751 } | 8455 } |
7752 | 8456 |
7753 Sint32 ALmixer_FadeOutChannel(Sint32 channel, Uint32 ticks) | 8457 ALint ALmixer_FadeOutChannel(ALint channel, ALuint ticks) |
7754 { | 8458 { |
7755 Sint32 retval; | 8459 ALint retval; |
7756 SDL_LockMutex(simple_lock); | 8460 #ifdef ENABLE_ALMIXER_THREADS |
8461 SDL_LockMutex(s_simpleLock); | |
8462 #endif | |
7757 retval = Internal_FadeOutChannel(channel, ticks); | 8463 retval = Internal_FadeOutChannel(channel, ticks); |
7758 SDL_UnlockMutex(simple_lock); | 8464 #ifdef ENABLE_ALMIXER_THREADS |
8465 SDL_UnlockMutex(s_simpleLock); | |
8466 #endif | |
7759 return retval; | 8467 return retval; |
7760 } | 8468 } |
7761 | 8469 |
7762 Sint32 ALmixer_FadeOutSource(ALuint source, Uint32 ticks) | 8470 ALint ALmixer_FadeOutSource(ALuint source, ALuint ticks) |
7763 { | 8471 { |
7764 Sint32 retval; | 8472 ALint retval; |
7765 SDL_LockMutex(simple_lock); | 8473 #ifdef ENABLE_ALMIXER_THREADS |
8474 SDL_LockMutex(s_simpleLock); | |
8475 #endif | |
7766 retval = Internal_FadeOutSource(source, ticks); | 8476 retval = Internal_FadeOutSource(source, ticks); |
7767 SDL_UnlockMutex(simple_lock); | 8477 #ifdef ENABLE_ALMIXER_THREADS |
8478 SDL_UnlockMutex(s_simpleLock); | |
8479 #endif | |
7768 return retval; | 8480 return retval; |
7769 } | 8481 } |
7770 | 8482 |
7771 Sint32 ALmixer_FadeChannel(Sint32 channel, Uint32 ticks, ALfloat volume) | 8483 ALint ALmixer_FadeChannel(ALint channel, ALuint ticks, ALfloat volume) |
7772 { | 8484 { |
7773 Sint32 retval; | 8485 ALint retval; |
7774 SDL_LockMutex(simple_lock); | 8486 #ifdef ENABLE_ALMIXER_THREADS |
8487 SDL_LockMutex(s_simpleLock); | |
8488 #endif | |
7775 retval = Internal_FadeChannel(channel, ticks, volume); | 8489 retval = Internal_FadeChannel(channel, ticks, volume); |
7776 SDL_UnlockMutex(simple_lock); | 8490 #ifdef ENABLE_ALMIXER_THREADS |
8491 SDL_UnlockMutex(s_simpleLock); | |
8492 #endif | |
7777 return retval; | 8493 return retval; |
7778 } | 8494 } |
7779 | 8495 |
7780 Sint32 ALmixer_FadeSource(ALuint source, Uint32 ticks, ALfloat volume) | 8496 ALint ALmixer_FadeSource(ALuint source, ALuint ticks, ALfloat volume) |
7781 { | 8497 { |
7782 Sint32 retval; | 8498 ALint retval; |
7783 SDL_LockMutex(simple_lock); | 8499 #ifdef ENABLE_ALMIXER_THREADS |
8500 SDL_LockMutex(s_simpleLock); | |
8501 #endif | |
7784 retval = Internal_FadeSource(source, ticks, volume); | 8502 retval = Internal_FadeSource(source, ticks, volume); |
7785 SDL_UnlockMutex(simple_lock); | 8503 #ifdef ENABLE_ALMIXER_THREADS |
8504 SDL_UnlockMutex(s_simpleLock); | |
8505 #endif | |
7786 return retval; | 8506 return retval; |
7787 } | 8507 } |
7788 | 8508 |
7789 Sint32 ALmixer_SetMaxVolumeChannel(Sint32 channel, ALfloat volume) | 8509 |
7790 { | 8510 ALboolean ALmixer_SetVolumeChannel(ALint channel, ALfloat volume) |
7791 Sint32 retval; | 8511 { |
7792 SDL_LockMutex(simple_lock); | 8512 ALboolean retval; |
8513 #ifdef ENABLE_ALMIXER_THREADS | |
8514 SDL_LockMutex(s_simpleLock); | |
8515 #endif | |
8516 retval = Internal_SetVolumeChannel(channel, volume); | |
8517 #ifdef ENABLE_ALMIXER_THREADS | |
8518 SDL_UnlockMutex(s_simpleLock); | |
8519 #endif | |
8520 return retval; | |
8521 } | |
8522 | |
8523 ALboolean ALmixer_SetVolumeSource(ALuint source, ALfloat volume) | |
8524 { | |
8525 ALboolean retval; | |
8526 #ifdef ENABLE_ALMIXER_THREADS | |
8527 SDL_LockMutex(s_simpleLock); | |
8528 #endif | |
8529 retval = Internal_SetVolumeSource(source, volume); | |
8530 #ifdef ENABLE_ALMIXER_THREADS | |
8531 SDL_UnlockMutex(s_simpleLock); | |
8532 #endif | |
8533 return retval; | |
8534 } | |
8535 | |
8536 ALfloat ALmixer_GetVolumeChannel(ALint channel) | |
8537 { | |
8538 ALfloat retval; | |
8539 #ifdef ENABLE_ALMIXER_THREADS | |
8540 SDL_LockMutex(s_simpleLock); | |
8541 #endif | |
8542 retval = Internal_GetVolumeChannel(channel); | |
8543 #ifdef ENABLE_ALMIXER_THREADS | |
8544 SDL_UnlockMutex(s_simpleLock); | |
8545 #endif | |
8546 return retval; | |
8547 } | |
8548 | |
8549 ALfloat ALmixer_GetVolumeSource(ALuint source) | |
8550 { | |
8551 ALfloat retval; | |
8552 #ifdef ENABLE_ALMIXER_THREADS | |
8553 SDL_LockMutex(s_simpleLock); | |
8554 #endif | |
8555 retval = Internal_GetVolumeSource(source); | |
8556 #ifdef ENABLE_ALMIXER_THREADS | |
8557 SDL_UnlockMutex(s_simpleLock); | |
8558 #endif | |
8559 return retval; | |
8560 } | |
8561 | |
8562 ALboolean ALmixer_SetMaxVolumeChannel(ALint channel, ALfloat volume) | |
8563 { | |
8564 ALboolean retval; | |
8565 #ifdef ENABLE_ALMIXER_THREADS | |
8566 SDL_LockMutex(s_simpleLock); | |
8567 #endif | |
7793 retval = Internal_SetMaxVolumeChannel(channel, volume); | 8568 retval = Internal_SetMaxVolumeChannel(channel, volume); |
7794 SDL_UnlockMutex(simple_lock); | 8569 #ifdef ENABLE_ALMIXER_THREADS |
8570 SDL_UnlockMutex(s_simpleLock); | |
8571 #endif | |
7795 return retval; | 8572 return retval; |
7796 } | 8573 } |
7797 | 8574 |
7798 Sint32 ALmixer_SetMaxVolumeSource(ALuint source, ALfloat volume) | 8575 ALboolean ALmixer_SetMaxVolumeSource(ALuint source, ALfloat volume) |
7799 { | 8576 { |
7800 Sint32 retval; | 8577 ALboolean retval; |
7801 SDL_LockMutex(simple_lock); | 8578 #ifdef ENABLE_ALMIXER_THREADS |
8579 SDL_LockMutex(s_simpleLock); | |
8580 #endif | |
7802 retval = Internal_SetMaxVolumeSource(source, volume); | 8581 retval = Internal_SetMaxVolumeSource(source, volume); |
7803 SDL_UnlockMutex(simple_lock); | 8582 #ifdef ENABLE_ALMIXER_THREADS |
8583 SDL_UnlockMutex(s_simpleLock); | |
8584 #endif | |
7804 return retval; | 8585 return retval; |
7805 } | 8586 } |
7806 | 8587 |
7807 ALfloat ALmixer_GetMaxVolumeChannel(Sint32 channel) | 8588 ALfloat ALmixer_GetMaxVolumeChannel(ALint channel) |
7808 { | 8589 { |
7809 ALfloat retval; | 8590 ALfloat retval; |
7810 SDL_LockMutex(simple_lock); | 8591 #ifdef ENABLE_ALMIXER_THREADS |
8592 SDL_LockMutex(s_simpleLock); | |
8593 #endif | |
7811 retval = Internal_GetMaxVolumeChannel(channel); | 8594 retval = Internal_GetMaxVolumeChannel(channel); |
7812 SDL_UnlockMutex(simple_lock); | 8595 #ifdef ENABLE_ALMIXER_THREADS |
8596 SDL_UnlockMutex(s_simpleLock); | |
8597 #endif | |
7813 return retval; | 8598 return retval; |
7814 } | 8599 } |
7815 | 8600 |
7816 ALfloat ALmixer_GetMaxVolumeSource(ALuint source) | 8601 ALfloat ALmixer_GetMaxVolumeSource(ALuint source) |
7817 { | 8602 { |
7818 ALfloat retval; | 8603 ALfloat retval; |
7819 SDL_LockMutex(simple_lock); | 8604 #ifdef ENABLE_ALMIXER_THREADS |
8605 SDL_LockMutex(s_simpleLock); | |
8606 #endif | |
7820 retval = Internal_GetMaxVolumeSource(source); | 8607 retval = Internal_GetMaxVolumeSource(source); |
7821 SDL_UnlockMutex(simple_lock); | 8608 #ifdef ENABLE_ALMIXER_THREADS |
8609 SDL_UnlockMutex(s_simpleLock); | |
8610 #endif | |
7822 return retval; | 8611 return retval; |
7823 } | 8612 } |
7824 | 8613 |
7825 | 8614 |
7826 Sint32 ALmixer_SetMinVolumeChannel(Sint32 channel, ALfloat volume) | 8615 ALboolean ALmixer_SetMinVolumeChannel(ALint channel, ALfloat volume) |
7827 { | 8616 { |
7828 Sint32 retval; | 8617 ALboolean retval; |
7829 SDL_LockMutex(simple_lock); | 8618 #ifdef ENABLE_ALMIXER_THREADS |
8619 SDL_LockMutex(s_simpleLock); | |
8620 #endif | |
7830 retval = Internal_SetMinVolumeChannel(channel, volume); | 8621 retval = Internal_SetMinVolumeChannel(channel, volume); |
7831 SDL_UnlockMutex(simple_lock); | 8622 #ifdef ENABLE_ALMIXER_THREADS |
8623 SDL_UnlockMutex(s_simpleLock); | |
8624 #endif | |
7832 return retval; | 8625 return retval; |
7833 } | 8626 } |
7834 | 8627 |
7835 Sint32 ALmixer_SetMinVolumeSource(ALuint source, ALfloat volume) | 8628 ALboolean ALmixer_SetMinVolumeSource(ALuint source, ALfloat volume) |
7836 { | 8629 { |
7837 Sint32 retval; | 8630 ALboolean retval; |
7838 SDL_LockMutex(simple_lock); | 8631 #ifdef ENABLE_ALMIXER_THREADS |
8632 SDL_LockMutex(s_simpleLock); | |
8633 #endif | |
7839 retval = Internal_SetMinVolumeSource(source, volume); | 8634 retval = Internal_SetMinVolumeSource(source, volume); |
7840 SDL_UnlockMutex(simple_lock); | 8635 #ifdef ENABLE_ALMIXER_THREADS |
8636 SDL_UnlockMutex(s_simpleLock); | |
8637 #endif | |
7841 return retval; | 8638 return retval; |
7842 } | 8639 } |
7843 | 8640 |
7844 ALfloat ALmixer_GetMinVolumeChannel(Sint32 channel) | 8641 ALfloat ALmixer_GetMinVolumeChannel(ALint channel) |
7845 { | 8642 { |
7846 ALfloat retval; | 8643 ALfloat retval; |
7847 SDL_LockMutex(simple_lock); | 8644 #ifdef ENABLE_ALMIXER_THREADS |
8645 SDL_LockMutex(s_simpleLock); | |
8646 #endif | |
7848 retval = Internal_GetMinVolumeChannel(channel); | 8647 retval = Internal_GetMinVolumeChannel(channel); |
7849 SDL_UnlockMutex(simple_lock); | 8648 #ifdef ENABLE_ALMIXER_THREADS |
8649 SDL_UnlockMutex(s_simpleLock); | |
8650 #endif | |
7850 return retval; | 8651 return retval; |
7851 } | 8652 } |
7852 | 8653 |
7853 ALfloat ALmixer_GetMinVolumeSource(ALuint source) | 8654 ALfloat ALmixer_GetMinVolumeSource(ALuint source) |
7854 { | 8655 { |
7855 ALfloat retval; | 8656 ALfloat retval; |
7856 SDL_LockMutex(simple_lock); | 8657 #ifdef ENABLE_ALMIXER_THREADS |
8658 SDL_LockMutex(s_simpleLock); | |
8659 #endif | |
7857 retval = Internal_GetMinVolumeSource(source); | 8660 retval = Internal_GetMinVolumeSource(source); |
7858 SDL_UnlockMutex(simple_lock); | 8661 #ifdef ENABLE_ALMIXER_THREADS |
8662 SDL_UnlockMutex(s_simpleLock); | |
8663 #endif | |
7859 return retval; | 8664 return retval; |
7860 } | 8665 } |
7861 | 8666 |
7862 | 8667 |
7863 | 8668 |
7864 Sint32 ALmixer_SetMasterVolume(ALfloat volume) | 8669 ALboolean ALmixer_SetMasterVolume(ALfloat volume) |
7865 { | 8670 { |
7866 Sint32 retval; | 8671 ALboolean retval; |
7867 SDL_LockMutex(simple_lock); | 8672 #ifdef ENABLE_ALMIXER_THREADS |
8673 SDL_LockMutex(s_simpleLock); | |
8674 #endif | |
7868 retval = Internal_SetMasterVolume(volume); | 8675 retval = Internal_SetMasterVolume(volume); |
7869 SDL_UnlockMutex(simple_lock); | 8676 #ifdef ENABLE_ALMIXER_THREADS |
8677 SDL_UnlockMutex(s_simpleLock); | |
8678 #endif | |
7870 return retval; | 8679 return retval; |
7871 } | 8680 } |
7872 | 8681 |
7873 ALfloat ALmixer_GetMasterVolume() | 8682 ALfloat ALmixer_GetMasterVolume() |
7874 { | 8683 { |
7875 ALfloat retval; | 8684 ALfloat retval; |
7876 SDL_LockMutex(simple_lock); | 8685 #ifdef ENABLE_ALMIXER_THREADS |
8686 SDL_LockMutex(s_simpleLock); | |
8687 #endif | |
7877 retval = Internal_GetMasterVolume(); | 8688 retval = Internal_GetMasterVolume(); |
7878 SDL_UnlockMutex(simple_lock); | 8689 #ifdef ENABLE_ALMIXER_THREADS |
8690 SDL_UnlockMutex(s_simpleLock); | |
8691 #endif | |
7879 return retval; | 8692 return retval; |
7880 } | 8693 } |
7881 | 8694 |
7882 Sint32 ALmixer_ExpireChannel(Sint32 channel, Sint32 ticks) | 8695 ALint ALmixer_ExpireChannel(ALint channel, ALint ticks) |
7883 { | 8696 { |
7884 Sint32 retval; | 8697 ALint retval; |
7885 SDL_LockMutex(simple_lock); | 8698 #ifdef ENABLE_ALMIXER_THREADS |
8699 SDL_LockMutex(s_simpleLock); | |
8700 #endif | |
7886 retval = Internal_ExpireChannel(channel, ticks); | 8701 retval = Internal_ExpireChannel(channel, ticks); |
7887 SDL_UnlockMutex(simple_lock); | 8702 #ifdef ENABLE_ALMIXER_THREADS |
8703 SDL_UnlockMutex(s_simpleLock); | |
8704 #endif | |
7888 return retval; | 8705 return retval; |
7889 } | 8706 } |
7890 | 8707 |
7891 Sint32 ALmixer_ExpireSource(ALuint source, Sint32 ticks) | 8708 ALint ALmixer_ExpireSource(ALuint source, ALint ticks) |
7892 { | 8709 { |
7893 Sint32 retval; | 8710 ALint retval; |
7894 SDL_LockMutex(simple_lock); | 8711 #ifdef ENABLE_ALMIXER_THREADS |
8712 SDL_LockMutex(s_simpleLock); | |
8713 #endif | |
7895 retval = Internal_ExpireSource(source, ticks); | 8714 retval = Internal_ExpireSource(source, ticks); |
7896 SDL_UnlockMutex(simple_lock); | 8715 #ifdef ENABLE_ALMIXER_THREADS |
8716 SDL_UnlockMutex(s_simpleLock); | |
8717 #endif | |
7897 return retval; | 8718 return retval; |
7898 } | 8719 } |
7899 | 8720 |
7900 Sint32 ALmixer_QueryChannel(Sint32 channel) | 8721 ALint ALmixer_IsActiveChannel(ALint channel) |
7901 { | 8722 { |
7902 Sint32 retval; | 8723 ALint retval; |
7903 SDL_LockMutex(simple_lock); | 8724 #ifdef ENABLE_ALMIXER_THREADS |
8725 SDL_LockMutex(s_simpleLock); | |
8726 #endif | |
7904 retval = Internal_QueryChannel(channel); | 8727 retval = Internal_QueryChannel(channel); |
7905 SDL_UnlockMutex(simple_lock); | 8728 #ifdef ENABLE_ALMIXER_THREADS |
8729 SDL_UnlockMutex(s_simpleLock); | |
8730 #endif | |
7906 return retval; | 8731 return retval; |
7907 } | 8732 } |
7908 | 8733 |
7909 Sint32 ALmixer_QuerySource(ALuint source) | 8734 ALint ALmixer_IsActiveSource(ALuint source) |
7910 { | 8735 { |
7911 Sint32 retval; | 8736 ALint retval; |
7912 SDL_LockMutex(simple_lock); | 8737 #ifdef ENABLE_ALMIXER_THREADS |
8738 SDL_LockMutex(s_simpleLock); | |
8739 #endif | |
7913 retval = Internal_QuerySource(source); | 8740 retval = Internal_QuerySource(source); |
7914 SDL_UnlockMutex(simple_lock); | 8741 #ifdef ENABLE_ALMIXER_THREADS |
8742 SDL_UnlockMutex(s_simpleLock); | |
8743 #endif | |
7915 return retval; | 8744 return retval; |
7916 } | 8745 } |
7917 | 8746 |
7918 | 8747 |
7919 Sint32 ALmixer_PlayingChannel(Sint32 channel) | 8748 ALint ALmixer_IsPlayingChannel(ALint channel) |
7920 { | 8749 { |
7921 Sint32 retval; | 8750 ALint retval; |
7922 SDL_LockMutex(simple_lock); | 8751 #ifdef ENABLE_ALMIXER_THREADS |
8752 SDL_LockMutex(s_simpleLock); | |
8753 #endif | |
7923 retval = Internal_PlayingChannel(channel); | 8754 retval = Internal_PlayingChannel(channel); |
7924 SDL_UnlockMutex(simple_lock); | 8755 #ifdef ENABLE_ALMIXER_THREADS |
8756 SDL_UnlockMutex(s_simpleLock); | |
8757 #endif | |
7925 return retval; | 8758 return retval; |
7926 } | 8759 } |
7927 | 8760 |
7928 Sint32 ALmixer_PlayingSource(ALuint source) | 8761 ALint ALmixer_IsPlayingSource(ALuint source) |
7929 { | 8762 { |
7930 Sint32 retval; | 8763 ALint retval; |
7931 SDL_LockMutex(simple_lock); | 8764 #ifdef ENABLE_ALMIXER_THREADS |
8765 SDL_LockMutex(s_simpleLock); | |
8766 #endif | |
7932 retval = Internal_PlayingSource(source); | 8767 retval = Internal_PlayingSource(source); |
7933 SDL_UnlockMutex(simple_lock); | 8768 #ifdef ENABLE_ALMIXER_THREADS |
8769 SDL_UnlockMutex(s_simpleLock); | |
8770 #endif | |
7934 return retval; | 8771 return retval; |
7935 } | 8772 } |
7936 | 8773 |
7937 | 8774 |
7938 Sint32 ALmixer_PausedChannel(Sint32 channel) | 8775 ALint ALmixer_IsPausedChannel(ALint channel) |
7939 { | 8776 { |
7940 Sint32 retval; | 8777 ALint retval; |
7941 SDL_LockMutex(simple_lock); | 8778 #ifdef ENABLE_ALMIXER_THREADS |
8779 SDL_LockMutex(s_simpleLock); | |
8780 #endif | |
7942 retval = Internal_PausedChannel(channel); | 8781 retval = Internal_PausedChannel(channel); |
7943 SDL_UnlockMutex(simple_lock); | 8782 #ifdef ENABLE_ALMIXER_THREADS |
8783 SDL_UnlockMutex(s_simpleLock); | |
8784 #endif | |
7944 return retval; | 8785 return retval; |
7945 } | 8786 } |
7946 | 8787 |
7947 Sint32 ALmixer_PausedSource(ALuint source) | 8788 ALint ALmixer_IsPausedSource(ALuint source) |
7948 { | 8789 { |
7949 Sint32 retval; | 8790 ALint retval; |
7950 SDL_LockMutex(simple_lock); | 8791 #ifdef ENABLE_ALMIXER_THREADS |
8792 SDL_LockMutex(s_simpleLock); | |
8793 #endif | |
7951 retval = Internal_PausedSource(source); | 8794 retval = Internal_PausedSource(source); |
7952 SDL_UnlockMutex(simple_lock); | 8795 #ifdef ENABLE_ALMIXER_THREADS |
8796 SDL_UnlockMutex(s_simpleLock); | |
8797 #endif | |
7953 return retval; | 8798 return retval; |
7954 } | 8799 } |
7955 | 8800 |
7956 | 8801 |
7957 Sint32 ALmixer_CountAllFreeChannels() | 8802 ALuint ALmixer_CountAllFreeChannels() |
7958 { | 8803 { |
7959 Sint32 retval; | 8804 ALuint retval; |
7960 SDL_LockMutex(simple_lock); | 8805 #ifdef ENABLE_ALMIXER_THREADS |
8806 SDL_LockMutex(s_simpleLock); | |
8807 #endif | |
7961 retval = Internal_CountAllFreeChannels(); | 8808 retval = Internal_CountAllFreeChannels(); |
7962 SDL_UnlockMutex(simple_lock); | 8809 #ifdef ENABLE_ALMIXER_THREADS |
8810 SDL_UnlockMutex(s_simpleLock); | |
8811 #endif | |
7963 return retval; | 8812 return retval; |
7964 } | 8813 } |
7965 | 8814 |
7966 Sint32 ALmixer_CountUnreservedFreeChannels() | 8815 ALuint ALmixer_CountUnreservedFreeChannels() |
7967 { | 8816 { |
7968 Sint32 retval; | 8817 ALuint retval; |
7969 SDL_LockMutex(simple_lock); | 8818 #ifdef ENABLE_ALMIXER_THREADS |
8819 SDL_LockMutex(s_simpleLock); | |
8820 #endif | |
7970 retval = Internal_CountUnreservedFreeChannels(); | 8821 retval = Internal_CountUnreservedFreeChannels(); |
7971 SDL_UnlockMutex(simple_lock); | 8822 #ifdef ENABLE_ALMIXER_THREADS |
8823 SDL_UnlockMutex(s_simpleLock); | |
8824 #endif | |
7972 return retval; | 8825 return retval; |
7973 } | 8826 } |
7974 | 8827 |
7975 Sint32 ALmixer_CountAllUsedChannels() | 8828 ALuint ALmixer_CountAllUsedChannels() |
7976 { | 8829 { |
7977 Sint32 retval; | 8830 ALuint retval; |
7978 SDL_LockMutex(simple_lock); | 8831 #ifdef ENABLE_ALMIXER_THREADS |
8832 SDL_LockMutex(s_simpleLock); | |
8833 #endif | |
7979 retval = Internal_CountAllUsedChannels(); | 8834 retval = Internal_CountAllUsedChannels(); |
7980 SDL_UnlockMutex(simple_lock); | 8835 #ifdef ENABLE_ALMIXER_THREADS |
8836 SDL_UnlockMutex(s_simpleLock); | |
8837 #endif | |
7981 return retval; | 8838 return retval; |
7982 } | 8839 } |
7983 | 8840 |
7984 Sint32 ALmixer_CountUnreservedUsedChannels() | 8841 ALuint ALmixer_CountUnreservedUsedChannels() |
7985 { | 8842 { |
7986 Sint32 retval; | 8843 ALuint retval; |
7987 SDL_LockMutex(simple_lock); | 8844 #ifdef ENABLE_ALMIXER_THREADS |
8845 SDL_LockMutex(s_simpleLock); | |
8846 #endif | |
7988 retval = Internal_CountUnreservedUsedChannels(); | 8847 retval = Internal_CountUnreservedUsedChannels(); |
7989 SDL_UnlockMutex(simple_lock); | 8848 #ifdef ENABLE_ALMIXER_THREADS |
8849 SDL_UnlockMutex(s_simpleLock); | |
8850 #endif | |
7990 return retval; | 8851 return retval; |
7991 } | 8852 } |
7992 | 8853 |
7993 SDL_bool ALmixer_IsPredecoded(ALmixer_Data* data) | 8854 ALboolean ALmixer_IsPredecoded(ALmixer_Data* data) |
7994 { | 8855 { |
7995 if(NULL == data) | 8856 if(NULL == data) |
7996 { | 8857 { |
7997 return SDL_FALSE; | 8858 return AL_FALSE; |
7998 } | 8859 } |
7999 return data->decoded_all; | 8860 return data->decoded_all; |
8000 } | 8861 } |
8001 | 8862 |
8002 | 8863 ALboolean ALmixer_CompiledWithThreadBackend() |
8003 | 8864 { |
8004 | 8865 #ifdef ENABLE_ALMIXER_THREADS |
8005 | 8866 return AL_TRUE; |
8867 #else | |
8868 return AL_FALSE; | |
8869 #endif | |
8870 } | |
8871 | |
8872 | |
8873 | |
8874 |