comparison SDL_ALmixer.c @ 1:a8a8fe374984

Subversion era
author Eric Wing <ewing . public |-at-| gmail . com>
date Wed, 27 Oct 2010 16:51:16 -0700
parents 01e39f9f58d5
children 279d0427ef26
comparison
equal deleted inserted replaced
0:01e39f9f58d5 1:a8a8fe374984
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 #include "SDL.h" /* For SDL_GetTicks(), SDL_Delay */
11 #include "SDL_sound.h"
11 #include "al.h" /* OpenAL */ 12 #include "al.h" /* OpenAL */
12 #include "alc.h" /* For creating OpenAL contexts */ 13 #include "alc.h" /* For creating OpenAL contexts */
14
15 #ifdef __APPLE__
16 /* For performance things like ALC_CONVERT_DATA_UPON_LOADING */
17 /* 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
19 * define was moved to a new header file and renamed to
20 * ALC_MAC_OSX_CONVERT_DATA_UPON_LOADING.
21 */
22 #include <OpenAL/MacOSX_OALExtensions.h>
23 #endif
13 24
14 /* For malloc, bsearch, qsort */ 25 /* For malloc, bsearch, qsort */
15 #include <stdlib.h> 26 #include <stdlib.h>
16 27
17 /* For memcpy */ 28 /* For memcpy */
158 */ 169 */
159 #define NUMBER_OF_START_UP_BUFFERS 2 170 #define NUMBER_OF_START_UP_BUFFERS 2
160 #endif 171 #endif
161 /************ END REMOVE ME (Don't need anymore) ********/ 172 /************ END REMOVE ME (Don't need anymore) ********/
162 173
163 static Uint8 ALmixer_Initialized = 0; 174 static SDL_bool ALmixer_Initialized = 0;
164 /* This should be set correctly by Init */ 175 /* This should be set correctly by Init */
165 static Uint32 ALmixer_Frequency_global = ALMIXER_DEFAULT_FREQUENCY; 176 static Uint32 ALmixer_Frequency_global = ALMIXER_DEFAULT_FREQUENCY;
166 177
167 /* Will be initialized in Init */ 178 /* Will be initialized in Init */
168 static Sint32 Number_of_Channels_global = 0; 179 static Sint32 Number_of_Channels_global = 0;
193 #else 204 #else
194 static const Uint16 SIGN_TYPE_16_BIT_FORMAT = AUDIO_S16SYS; 205 static const Uint16 SIGN_TYPE_16_BIT_FORMAT = AUDIO_S16SYS;
195 static const Uint16 SIGN_TYPE_8_BIT_FORMAT = AUDIO_S8; 206 static const Uint16 SIGN_TYPE_8_BIT_FORMAT = AUDIO_S8;
196 #endif 207 #endif
197 208
209
210 /* This can be private instead of being in the header now that I moved
211 * ALmixer_Data inside here.
212 */
213 typedef struct ALmixer_Buffer_Map ALmixer_Buffer_Map;
214
215
216 struct ALmixer_Data
217 {
218 SDL_bool decoded_all; /* dictates different behaviors */
219 Sint32 total_time; /* total playing time of sample (msec) */
220
221 Uint32 in_use; /* needed to prevent sharing for streams */
222 SDL_bool eof; /* flag for eof, only used for streams */
223
224 Uint32 total_bytes; /* For predecoded */
225 Uint32 loaded_bytes; /* For predecoded (for seek) */
226
227 Sound_Sample* sample; /* SDL_Sound provides the data */
228 ALuint* buffer; /* array of OpenAL buffers (at least 1 for predecoded) */
229
230 /* Needed for streamed buffers */
231 Uint32 max_queue_buffers; /* Max number of queue buffers */
232 Uint32 num_startup_buffers; /* Number of ramp-up buffers */
233 Uint32 num_buffers_in_use; /* number of buffers in use */
234
235 /* This stuff is for streamed buffers that require data access */
236 ALmixer_Buffer_Map* buffer_map_list; /* translate ALbuffer to index
237 and holds pointer to copy of data for
238 data access */
239 ALuint current_buffer; /* The current playing buffer */
240
241 /* Nvidia distribution refuses to recognize a simple buffer query command
242 * unlike all other distributions. It's forcing me to redo the code
243 * to accomodate this Nvidia flaw by making me maintain a "best guess"
244 * copy of what I think the buffer queue state looks like.
245 * A circular queue would a helpful data structure for this task,
246 * but I wanted to avoid making an additional header requirement,
247 * so I'm making it a void*
248 */
249 void* circular_buffer_queue;
250
251
252 };
253
198 static struct ALmixer_Channel 254 static struct ALmixer_Channel
199 { 255 {
200 Uint8 channel_in_use; 256 SDL_bool channel_in_use;
201 Uint8 callback_update; /* For streaming determination */ 257 SDL_bool callback_update; /* For streaming determination */
202 Uint8 needs_stream; /* For streaming determination */ 258 SDL_bool needs_stream; /* For streaming determination */
203 Uint8 halted; 259 SDL_bool halted;
204 Uint8 paused; 260 SDL_bool paused;
205 ALuint alsource; 261 ALuint alsource;
206 ALmixer_Data* almixer_data; 262 ALmixer_Data* almixer_data;
207 Sint32 loops; 263 Sint32 loops;
208 Sint32 expire_ticks; 264 Sint32 expire_ticks;
209 Uint32 start_time; 265 Uint32 start_time;
210 266
211 Uint8 fade_enabled; 267 SDL_bool fade_enabled;
212 Uint32 fade_expire_ticks; 268 Uint32 fade_expire_ticks;
213 Uint32 fade_start_time; 269 Uint32 fade_start_time;
214 ALfloat fade_inv_time; 270 ALfloat fade_inv_time;
215 ALfloat fade_start_volume; 271 ALfloat fade_start_volume;
216 ALfloat fade_end_volume; 272 ALfloat fade_end_volume;
230 Uint32 ticks_fade; 286 Uint32 ticks_fade;
231 effect_info *effects; 287 effect_info *effects;
232 */ 288 */
233 } *ALmixer_Channel_List = NULL; 289 } *ALmixer_Channel_List = NULL;
234 290
291 struct ALmixer_Buffer_Map
292 {
293 ALuint albuffer;
294 Sint32 index; /* might not need */
295 Uint8* data;
296 Uint32 num_bytes;
297 };
298
235 /* This will be used to find a channel if the user supplies a source */ 299 /* This will be used to find a channel if the user supplies a source */
236 typedef struct Source_Map 300 typedef struct Source_Map
237 { 301 {
238 ALuint source; 302 ALuint source;
239 Sint32 channel; 303 Sint32 channel;
253 } 317 }
254 318
255 /* Compare by albuffer */ 319 /* Compare by albuffer */
256 static int Compare_Buffer_Map(const void* a, const void* b) 320 static int Compare_Buffer_Map(const void* a, const void* b)
257 { 321 {
258 return ( ((Buffer_Map*)a)->albuffer - ((Buffer_Map*)b)->albuffer ); 322 return ( ((ALmixer_Buffer_Map*)a)->albuffer - ((ALmixer_Buffer_Map*)b)->albuffer );
259 } 323 }
260 324
261 /* This is for the user defined callback via 325 /* This is for the user defined callback via
262 * ALmixer_ChannelFinished() 326 * ALmixer_ChannelFinished()
263 */ 327 */
264 static void (*Channel_Done_Callback)(Sint32 channel, void* userdata) = NULL; 328 static void (*Channel_Done_Callback)(Sint32 channel, void* userdata) = NULL;
265 static void* Channel_Done_Callback_Userdata = NULL; 329 static void* Channel_Done_Callback_Userdata = NULL;
266 static void (*Channel_Data_Callback)(Sint32 which_channel, Uint8* data, Uint32 num_bytes, Uint32 frequency, Uint8 channels, Uint8 bitdepth, Uint16 format, Uint8 decode_mode) = 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;
267 331 static void* Channel_Data_Callback_Userdata = NULL;
268 332
269 /* I thought OpenAL seemed to lack an error number to string converter... 333 /* I thought OpenAL seemed to lack an error number to string converter...
270 * but I was wrong. Apparently they call it alGetString() which 334 * but I was wrong. Apparently they call it alGetString() which
271 * breaks from the OpenGL gluGetErrorString() convention. 335 * breaks from the OpenGL gluGetErrorString() convention.
272 * (And since the documentation for OpenAL is so bad, I didn't see 336 * (And since the documentation for OpenAL is so bad, I didn't see
364 428
365 fprintf(stderr, "For source: %d, buffers_queued=%d, buffers_processed=%d\n", 429 fprintf(stderr, "For source: %d, buffers_queued=%d, buffers_processed=%d\n",
366 source, 430 source,
367 buffers_queued, 431 buffers_queued,
368 buffers_processed); 432 buffers_processed);
433
369 } 434 }
370 435
371 436
372 437
373 static void Init_Channel(Sint32 channel) 438 static void Init_Channel(Sint32 channel)
581 } 646 }
582 /* Make compiler happy. Shouldn't get here */ 647 /* Make compiler happy. Shouldn't get here */
583 return AL_FORMAT_STEREO16; 648 return AL_FORMAT_STEREO16;
584 } 649 }
585 650
651
652 /* This will compute the total playing time
653 * based upon the number of bytes and audio info.
654 * (In prinicple, it should compute the time for any given length)
655 */
656 static Uint32 Compute_Total_Time_Decomposed(Uint32 bytes_per_sample, Uint32 frequency, Uint8 channels, Uint32 total_bytes)
657 {
658 double total_sec;
659 Uint32 total_msec;
660 Uint32 bytes_per_sec;
661
662 if(0 == total_bytes)
663 {
664 return 0;
665 }
666 /* To compute Bytes per second, do
667 * samples_per_sec * bytes_per_sample * number_of_channels
668 */
669 bytes_per_sec = frequency * bytes_per_sample * channels;
670
671 /* Now to get total time (sec), do
672 * total_bytes / bytes_per_sec
673 */
674 total_sec = total_bytes / (double)bytes_per_sec;
675
676 /* Now convert seconds to milliseconds
677 * Add .5 to the float to do rounding before the final cast
678 */
679 total_msec = (Uint32) ( (total_sec * 1000) + 0.5 );
680 /*
681 fprintf(stderr, "freq=%d, bytes_per_sample=%d, channels=%d, total_msec=%d\n", frequency, bytes_per_sample, channels, total_msec);
682 */
683 return total_msec;
684 }
685
686 static Uint32 Compute_Total_Time(Sound_AudioInfo *info, Uint32 total_bytes)
687 {
688 Uint32 bytes_per_sample;
689
690 if(0 == total_bytes)
691 {
692 return 0;
693 }
694 /* 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.
696 * Divide by 8bits_per_bytes and you get bytes_per_sample
697 */
698 bytes_per_sample = (Uint32) ((info->format & 0xFF) / 8);
699
700 return Compute_Total_Time_Decomposed(bytes_per_sample, info->rate, info->channels, total_bytes);
701 } /* End Compute_Total_Time */
702
703
704
586 /**************** REMOVED ****************************/ 705 /**************** REMOVED ****************************/
587 /* This was removed because I originally thought 706 /* This was removed because I originally thought
588 * OpenAL could return a pointer to the buffer data, 707 * OpenAL could return a pointer to the buffer data,
589 * but I was wrong. If something like that is ever 708 * but I was wrong. If something like that is ever
590 * implemented, then this might become useful. 709 * implemented, then this might become useful.
726 return; 845 return;
727 } 846 }
728 Channel_Done_Callback(channel, Channel_Done_Callback_Userdata); 847 Channel_Done_Callback(channel, Channel_Done_Callback_Userdata);
729 } 848 }
730 849
731 static Sint32 LookUpBuffer(ALuint buffer, Buffer_Map* buffer_map_list, Uint32 num_items_in_list) 850 static Sint32 LookUpBuffer(ALuint buffer, ALmixer_Buffer_Map* buffer_map_list, Uint32 num_items_in_list)
732 { 851 {
733 /* Only the first value is used for the key */ 852 /* Only the first value is used for the key */
734 Buffer_Map key = { 0, 0, NULL, 0 }; 853 ALmixer_Buffer_Map key = { 0, 0, NULL, 0 };
735 Buffer_Map* found_item = NULL; 854 ALmixer_Buffer_Map* found_item = NULL;
736 key.albuffer = buffer; 855 key.albuffer = buffer;
737 856
738 /* Use the ANSI C binary search feature (yea!) */ 857 /* Use the ANSI C binary search feature (yea!) */
739 found_item = (Buffer_Map*)bsearch(&key, buffer_map_list, num_items_in_list, sizeof(Buffer_Map), Compare_Buffer_Map); 858 found_item = (ALmixer_Buffer_Map*)bsearch(&key, buffer_map_list, num_items_in_list, sizeof(ALmixer_Buffer_Map), Compare_Buffer_Map);
740 if(NULL == found_item) 859 if(NULL == found_item)
741 { 860 {
742 ALmixer_SetError("Can't find buffer"); 861 ALmixer_SetError("Can't find buffer");
743 return -1; 862 return -1;
744 } 863 }
748 867
749 /* FIXME: Need to pass back additional info to be useful. 868 /* FIXME: Need to pass back additional info to be useful.
750 * Bit rate, stereo/mono (num chans), time in msec? 869 * Bit rate, stereo/mono (num chans), time in msec?
751 * Precoded/streamed flag so user can plan for future data? 870 * Precoded/streamed flag so user can plan for future data?
752 */ 871 */
753 static void Invoke_Channel_Data_Callback(Sint32 which_channel, Uint8* data, Uint32 num_bytes, Uint32 frequency, Uint8 channels, Uint16 format, Uint8 decode_mode) 872 /*
754 { 873 * channels: 1 for mono, 2 for stereo
874 *
875 */
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)
877 {
878 SDL_bool is_unsigned;
879 Uint8 bits_per_sample = GetBitDepth(format);
880 Uint32 bytes_per_sample;
881 Uint32 length_in_msec;
882
883 if(GetSignednessValue(format) == ALMIXER_UNSIGNED_VALUE)
884 {
885 is_unsigned = 1;
886 }
887 else
888 {
889 is_unsigned = 0;
890 }
891
892 bytes_per_sample = (Uint32) (bits_per_sample / 8);
893
894 length_in_msec = Compute_Total_Time_Decomposed(bytes_per_sample, frequency, channels, num_bytes);
895
755 /* 896 /*
756 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); 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);
757 */ 898 */
758 if(NULL == Channel_Data_Callback) 899 if(NULL == Channel_Data_Callback)
759 { 900 {
760 return; 901 return;
761 } 902 }
762 Channel_Data_Callback(which_channel, data, num_bytes, frequency, channels, GetBitDepth(format), format, decode_mode); 903 /*
904 * Channel_Data_Callback(which_channel, data, num_bytes, frequency, channels, GetBitDepth(format), format, decode_mode_is_predecoded);
905 */
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);
763 } 907 }
764 908
765 static void Invoke_Predecoded_Channel_Data_Callback(Sint32 channel, ALmixer_Data* data) 909 static void Invoke_Predecoded_Channel_Data_Callback(Sint32 channel, ALmixer_Data* data)
766 { 910 {
767 if(NULL == data->sample) 911 if(NULL == data->sample)
775 (((Uint8*) data->sample->buffer) + (data->total_bytes - data->loaded_bytes) ), 919 (((Uint8*) data->sample->buffer) + (data->total_bytes - data->loaded_bytes) ),
776 data->loaded_bytes, 920 data->loaded_bytes,
777 data->sample->desired.rate, 921 data->sample->desired.rate,
778 data->sample->desired.channels, 922 data->sample->desired.channels,
779 data->sample->desired.format, 923 data->sample->desired.format,
780 ALMIXER_DECODE_ALL 924 SDL_TRUE
781 ); 925 );
782 } 926 }
783 927
784 static void Invoke_Streamed_Channel_Data_Callback(Sint32 channel, ALmixer_Data* data, ALuint buffer) 928 static void Invoke_Streamed_Channel_Data_Callback(Sint32 channel, ALmixer_Data* data, ALuint buffer)
785 { 929 {
800 data->buffer_map_list[index].data, 944 data->buffer_map_list[index].data,
801 data->buffer_map_list[index].num_bytes, 945 data->buffer_map_list[index].num_bytes,
802 data->sample->desired.rate, 946 data->sample->desired.rate,
803 data->sample->desired.channels, 947 data->sample->desired.channels,
804 data->sample->desired.format, 948 data->sample->desired.format,
805 ALMIXER_DECODE_STREAM 949 SDL_FALSE
806 ); 950 );
807 } 951 }
808 952
809 /* From SDL_Sound's playsound. Converts milliseconds to byte positions. 953 /* From SDL_Sound's playsound. Converts milliseconds to byte positions.
810 * This is needed for seeking on predecoded samples 954 * This is needed for seeking on predecoded samples
906 */ 1050 */
907 data->loaded_bytes = data->total_bytes - byte_position; 1051 data->loaded_bytes = data->total_bytes - byte_position;
908 1052
909 return 0; 1053 return 0;
910 } 1054 }
911
912 /* This will compute the total playing time
913 * based upon the number of bytes and audio info.
914 * (In prinicple, it should compute the time for any given length)
915 */
916 static Uint32 Compute_Total_Time(Sound_AudioInfo *info, Uint32 total_bytes)
917 {
918 Uint32 bytes_per_sec;
919 Uint32 bytes_per_sample;
920 double total_sec;
921 Uint32 total_msec;
922
923 if(0 == total_bytes)
924 {
925 return 0;
926 }
927 /* SDL has a mask trick I was not aware of. Mask the upper bits
928 * of the format, and you get 8 or 16 which is the bits per sample.
929 * Divide by 8bits_per_bytes and you get bytes_per_sample
930 */
931 bytes_per_sample = (Uint32) ((info->format & 0xFF) / 8);
932 /* To compute Bytes per second, do
933 * samples_per_sec * bytes_per_sample * number_of_channels
934 */
935 bytes_per_sec = info->rate * bytes_per_sample * info->channels;
936
937 /* Now to get total time (sec), do
938 * total_bytes / bytes_per_sec
939 */
940 total_sec = total_bytes / (double)bytes_per_sec;
941
942 /* Now convert seconds to milliseconds
943 * Add .5 to the float to do rounding before the final cast
944 */
945 total_msec = (Uint32) ( (total_sec * 1000) + 0.5 );
946
947 fprintf(stderr, "%d\n", total_msec);
948 return total_msec;
949 } /* End Compute_Total_Time */
950
951
952
953 1055
954 /* Because we have multiple queue buffers and OpenAL won't let 1056 /* Because we have multiple queue buffers and OpenAL won't let
955 * us access them, we need to keep copies of each buffer around 1057 * us access them, we need to keep copies of each buffer around
956 */ 1058 */
957 static Sint32 CopyDataToAccessBuffer(ALmixer_Data* data, Uint32 num_bytes, ALuint buffer) 1059 static Sint32 CopyDataToAccessBuffer(ALmixer_Data* data, Uint32 num_bytes, ALuint buffer)
2981 /* Get the Max volume */ 3083 /* Get the Max volume */
2982 /* 3084 /*
2983 alGetSourcef(ALmixer_Channel_List[channel].alsource, 3085 alGetSourcef(ALmixer_Channel_List[channel].alsource,
2984 AL_MAX_GAIN, &value); 3086 AL_MAX_GAIN, &value);
2985 ALmixer_Channel_List[channel].fade_end_volume = value; 3087 ALmixer_Channel_List[channel].fade_end_volume = value;
3088 fprintf(stderr, "MAX gain: %f\n", value);
2986 */ 3089 */
2987 ALmixer_Channel_List[channel].fade_end_volume = 3090 ALmixer_Channel_List[channel].fade_end_volume =
2988 ALmixer_Channel_List[channel].max_volume; 3091 ALmixer_Channel_List[channel].max_volume;
2989 3092
2990 fprintf(stderr, "MAX gain: %f\n", value);
2991 /* Get the Min volume */ 3093 /* Get the Min volume */
2992 alGetSourcef(ALmixer_Channel_List[channel].alsource, 3094 alGetSourcef(ALmixer_Channel_List[channel].alsource,
2993 AL_MIN_GAIN, &value); 3095 AL_MIN_GAIN, &value);
2994 if((error = alGetError()) != AL_NO_ERROR) 3096 if((error = alGetError()) != AL_NO_ERROR)
2995 { 3097 {
4437 aluGetErrorString(error) ); 4539 aluGetErrorString(error) );
4438 error_flag--; 4540 error_flag--;
4439 } 4541 }
4440 if(buffers_still_queued > 0) 4542 if(buffers_still_queued > 0)
4441 { 4543 {
4442 /* 4544
4545 #if 0 /* This triggers an error in OS X Core Audio. */
4546 alSourceUnqueueBuffers(
4547 ALmixer_Channel_List[i].alsource,
4548 1,
4549 ALmixer_Channel_List[i].almixer_data->buffer
4550 );
4551 #else
4552 /* fprintf(stderr, "In the Bob Aron section...about to clear source\n");
4443 PrintQueueStatus(ALmixer_Channel_List[i].alsource); 4553 PrintQueueStatus(ALmixer_Channel_List[i].alsource);
4444 */ 4554 */
4445
4446 /* Rather than force unqueuing the buffer, let's see if 4555 /* Rather than force unqueuing the buffer, let's see if
4447 * setting the buffer to none works (the OpenAL 1.0 4556 * setting the buffer to none works (the OpenAL 1.0
4448 * Reference Annotation suggests this should work). 4557 * Reference Annotation suggests this should work).
4449 */ 4558 */
4450 alSourcei(ALmixer_Channel_List[i].alsource, 4559 alSourcei(ALmixer_Channel_List[i].alsource,
4451 AL_BUFFER, AL_NONE); 4560 AL_BUFFER, AL_NONE);
4452 /* 4561 /*
4453 PrintQueueStatus(ALmixer_Channel_List[i].alsource); 4562 PrintQueueStatus(ALmixer_Channel_List[i].alsource);
4454 */ 4563 */
4564 #endif
4455 if((error = alGetError()) != AL_NO_ERROR) 4565 if((error = alGetError()) != AL_NO_ERROR)
4456 { 4566 {
4457 fprintf(stderr, "Error with unqueue, after alSourceUnqueueBuffers, buffers_still_queued=%d, error is: %s", buffers_still_queued, 4567 fprintf(stderr, "Error with unqueue, after alSourceUnqueueBuffers, buffers_still_queued=%d, error is: %s", buffers_still_queued,
4458 aluGetErrorString(error)); 4568 aluGetErrorString(error));
4459 ALmixer_SetError("Predecoded Unqueue buffer failed: %s", 4569 ALmixer_SetError("Predecoded Unqueue buffer failed: %s",
4593 { 4703 {
4594 Uint32 k; 4704 Uint32 k;
4595 Uint32 queue_ret_flag; 4705 Uint32 queue_ret_flag;
4596 Uint8 is_out_of_sync = 0; 4706 Uint8 is_out_of_sync = 0;
4597 Uint32 my_queue_size = CircularQueueUnsignedInt_Size(ALmixer_Channel_List[i].almixer_data->circular_buffer_queue); 4707 Uint32 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. */
4709 ALint buffers_unplayed_int = buffers_still_queued - buffers_processed;
4710 Uint32 unplayed_buffers;
4711 if(buffers_unplayed_int < 0)
4712 {
4713 unplayed_buffers = 0;
4714 }
4715 else
4716 {
4717 unplayed_buffers = (Uint32)buffers_unplayed_int;
4718 }
4598 /* 4719 /*
4599 fprintf(stderr, "Queue in processed check, before pop, buffers_processed=%d\n", buffers_processed); 4720 fprintf(stderr, "Queue in processed check, before pop, buffers_processed=%d\n", buffers_processed);
4600 CircularQueueUnsignedInt_Print(ALmixer_Channel_List[i].almixer_data->circular_buffer_queue); 4721 CircularQueueUnsignedInt_Print(ALmixer_Channel_List[i].almixer_data->circular_buffer_queue);
4601 */ 4722 */
4602 /* We can't make any determinations solely based on the number of buffers_processed 4723 /* We can't make any determinations solely based on the number of buffers_processed
4620 4741
4621 /* First, let's syncronize our queue with the OpenAL queue */ 4742 /* First, let's syncronize our queue with the OpenAL queue */
4622 #if 0 4743 #if 0
4623 fprintf(stderr, "inside, Buffers processed=%d, Buffers queued=%d, my queue=%d\n", 4744 fprintf(stderr, "inside, Buffers processed=%d, Buffers queued=%d, my queue=%d\n",
4624 buffers_processed, buffers_still_queued, my_queue_size); 4745 buffers_processed, buffers_still_queued, my_queue_size);
4625 #endif 4746 #endif
4626 if(my_queue_size > (buffers_still_queued - buffers_processed)) 4747 if(my_queue_size > unplayed_buffers)
4627 { 4748 {
4628 is_out_of_sync = 1; 4749 is_out_of_sync = 1;
4629 for(k=0; k<(my_queue_size - (buffers_still_queued - buffers_processed)); k++) 4750 for(k=0; k<(my_queue_size - unplayed_buffers); k++)
4630 { 4751 {
4631 queue_ret_flag = CircularQueueUnsignedInt_PopFront( 4752 queue_ret_flag = CircularQueueUnsignedInt_PopFront(
4632 ALmixer_Channel_List[i].almixer_data->circular_buffer_queue); 4753 ALmixer_Channel_List[i].almixer_data->circular_buffer_queue);
4633 if(0 == queue_ret_flag) 4754 if(0 == queue_ret_flag)
4634 { 4755 {
4677 #endif 4798 #endif
4678 Invoke_Streamed_Channel_Data_Callback(i, ALmixer_Channel_List[i].almixer_data, current_buffer_id); 4799 Invoke_Streamed_Channel_Data_Callback(i, ALmixer_Channel_List[i].almixer_data, current_buffer_id);
4679 } 4800 }
4680 else 4801 else
4681 { 4802 {
4803 /*
4682 fprintf(stderr, "53b, Notice/Warning:, OpenAL queue has been depleted.\n"); 4804 fprintf(stderr, "53b, Notice/Warning:, OpenAL queue has been depleted.\n");
4805 PrintQueueStatus(ALmixer_Channel_List[i].alsource);
4806 */
4683 /* In this case, we might either be in an underrun or finished with playback */ 4807 /* In this case, we might either be in an underrun or finished with playback */
4684 ALmixer_Channel_List[i].almixer_data->current_buffer = 0; 4808 ALmixer_Channel_List[i].almixer_data->current_buffer = 0;
4685 } 4809 }
4686 } 4810 }
4687 } 4811 }
4730 * lose the pointer to the unqueued buffer 4854 * lose the pointer to the unqueued buffer
4731 */ 4855 */
4732 if(ALmixer_Channel_List[i].almixer_data->num_buffers_in_use 4856 if(ALmixer_Channel_List[i].almixer_data->num_buffers_in_use
4733 < ALmixer_Channel_List[i].almixer_data->max_queue_buffers) 4857 < ALmixer_Channel_List[i].almixer_data->max_queue_buffers)
4734 { 4858 {
4735 /* 4859 #if 0
4736 fprintf(stderr, "Getting more data in NOT_EOF and num_buffers_in_use (%d) < max_queue (%d)\n", 4860 fprintf(stderr, "Getting more data in NOT_EOF and num_buffers_in_use (%d) < max_queue (%d)\n",
4737 ALmixer_Channel_List[i].almixer_data->num_buffers_in_use, 4861 ALmixer_Channel_List[i].almixer_data->num_buffers_in_use,
4738 ALmixer_Channel_List[i].almixer_data->max_queue_buffers); 4862 ALmixer_Channel_List[i].almixer_data->max_queue_buffers);
4739 */ 4863 #endif
4740 /* Going to add an unused packet. 4864 /* Going to add an unused packet.
4741 * Grab next packet */ 4865 * Grab next packet */
4742 bytes_returned = GetMoreData( 4866 bytes_returned = GetMoreData(
4743 ALmixer_Channel_List[i].almixer_data, 4867 ALmixer_Channel_List[i].almixer_data,
4744 ALmixer_Channel_List[i].almixer_data->buffer[ 4868 ALmixer_Channel_List[i].almixer_data->buffer[
4785 else 4909 else
4786 { 4910 {
4787 /* Might want to check state */ 4911 /* Might want to check state */
4788 /* In case the playback stopped, 4912 /* In case the playback stopped,
4789 * we need to resume */ 4913 * we need to resume */
4914 #if 1
4915 /* Try not refetching the state here because I'm getting a duplicate
4916 buffer playback (hiccup) */
4790 alGetSourcei( 4917 alGetSourcei(
4791 ALmixer_Channel_List[i].alsource, 4918 ALmixer_Channel_List[i].alsource,
4792 AL_SOURCE_STATE, &state 4919 AL_SOURCE_STATE, &state
4793 ); 4920 );
4794 if((error = alGetError()) != AL_NO_ERROR) 4921 if((error = alGetError()) != AL_NO_ERROR)
4795 { 4922 {
4796 fprintf(stderr, "54Testing error: %s\n", 4923 fprintf(stderr, "54bTesting error: %s\n",
4797 aluGetErrorString(error)); 4924 aluGetErrorString(error));
4798 } 4925 }
4926 /* Get the number of buffers processed
4927 */
4928 alGetSourcei(
4929 ALmixer_Channel_List[i].alsource,
4930 AL_BUFFERS_PROCESSED,
4931 &buffers_processed
4932 );
4933 if((error = alGetError()) != AL_NO_ERROR)
4934 {
4935 fprintf(stderr, "54cError, Can't get buffers_processed: %s\n",
4936 aluGetErrorString(error));
4937 }
4938 #endif
4799 if(AL_STOPPED == state) 4939 if(AL_STOPPED == state)
4800 { 4940 {
4801 /* Resuming in not eof, but nothing to buffer */ 4941 /* Resuming in not eof, but nothing to buffer */
4942
4943 /* Okay, here's another lately discovered problem:
4944 * I can't find it in the spec, but for at least some of the
4945 * implementations, if I call play on a stopped source that
4946 * has processed buffers, all those buffers get marked as unprocessed
4947 * on alSourcePlay. So if I had a queue of 25 with 24 of the buffers
4948 * processed, on resume, the earlier 24 buffers will get replayed,
4949 * causing a "hiccup" like sound in the playback.
4950 * To avoid this, I must unqueue all processed buffers before
4951 * calling play. But to complicate things, I need to worry about resyncing
4952 * the circular queue with this since I designed this thing
4953 * with some correlation between the two. However, I might
4954 * have already handled this, so I will try writing this code without
4955 * syncing for now.
4956 * There is currently an assumption that a buffer
4957 * was queued above so I actually have something
4958 * to play.
4959 */
4960 ALint temp_count;
4961 /*
4962 fprintf(stderr, "STOPPED1, need to clear processed, status is:\n");
4963 PrintQueueStatus(ALmixer_Channel_List[i].alsource);
4964 */
4965 for(temp_count=0; temp_count<buffers_processed; temp_count++)
4966 {
4967 alSourceUnqueueBuffers(
4968 ALmixer_Channel_List[i].alsource,
4969 1, &unqueued_buffer_id
4970 );
4971 if((error = alGetError()) != AL_NO_ERROR)
4972 {
4973 fprintf(stderr, "55aTesting error: %s\n",
4974 aluGetErrorString(error));
4975 error_flag--;
4976 }
4977 }
4978 /*
4979 fprintf(stderr, "After unqueue clear...:\n");
4980 PrintQueueStatus(ALmixer_Channel_List[i].alsource);
4981 */
4802 alSourcePlay(ALmixer_Channel_List[i].alsource); 4982 alSourcePlay(ALmixer_Channel_List[i].alsource);
4803 if((error = alGetError()) != AL_NO_ERROR) 4983 if((error = alGetError()) != AL_NO_ERROR)
4804 { 4984 {
4805 fprintf(stderr, "55Testing error: %s\n", 4985 fprintf(stderr, "55Tbesting error: %s\n",
4806 aluGetErrorString(error)); 4986 aluGetErrorString(error));
4807 } 4987 }
4808 } 4988 }
4809 /* Let's escape to the next loop. 4989 /* Let's escape to the next loop.
4810 * All code below this point is for queuing up 4990 * All code below this point is for queuing up
4811 */ 4991 */
4812 /* 4992 /*
4813 fprintf(stderr, "Entry: Nothing to do...continue\n\n"); 4993 fprintf(stderr, "Entry: Nothing to do...continue\n\n");
4814 */ 4994 */
4815 continue; 4995 continue;
4816 } 4996 }
4817 /* We now know we have to fill an available 4997 /* We now know we have to fill an available
4818 * buffer. 4998 * buffer.
4819 */ 4999 */
4932 * EOF flag should be set. 5112 * EOF flag should be set.
4933 * Just go to next loop and 5113 * Just go to next loop and
4934 * let things be handled correctly 5114 * let things be handled correctly
4935 * in future update calls 5115 * in future update calls
4936 */ 5116 */
5117 /*
4937 fprintf(stderr, "SHOULD BE EOF\n"); 5118 fprintf(stderr, "SHOULD BE EOF\n");
4938 5119
4939 PrintQueueStatus(ALmixer_Channel_List[i].alsource); 5120 PrintQueueStatus(ALmixer_Channel_List[i].alsource);
4940 5121 */
4941 continue; 5122 continue;
4942 } 5123 }
4943 } /* END if bytes_returned == 0 */ 5124 } /* END if bytes_returned == 0 */
4944 /********* Possible trouble point. I might be queueing empty buffers on the mac. 5125 /********* Possible trouble point. I might be queueing empty buffers on the mac.
4945 * This check doesn't say if the buffer is valid. Only the EOF assumption is a clue at this point 5126 * This check doesn't say if the buffer is valid. Only the EOF assumption is a clue at this point
4954 { 5135 {
4955 /* Keep count of how many buffers we have 5136 /* Keep count of how many buffers we have
4956 * to queue so we can return the value 5137 * to queue so we can return the value
4957 */ 5138 */
4958 retval++; 5139 retval++;
5140 /*
4959 fprintf(stderr, "NOT_EOF???, about to Queue more data for num_buffers (%d) < max_queue (%d)\n", 5141 fprintf(stderr, "NOT_EOF???, about to Queue more data for num_buffers (%d) < max_queue (%d)\n",
4960 ALmixer_Channel_List[i].almixer_data->num_buffers_in_use, 5142 ALmixer_Channel_List[i].almixer_data->num_buffers_in_use,
4961 ALmixer_Channel_List[i].almixer_data->max_queue_buffers); 5143 ALmixer_Channel_List[i].almixer_data->max_queue_buffers);
4962 5144 */
4963 alSourceQueueBuffers( 5145 alSourceQueueBuffers(
4964 ALmixer_Channel_List[i].alsource, 5146 ALmixer_Channel_List[i].alsource,
4965 1, 5147 1,
4966 &ALmixer_Channel_List[i].almixer_data->buffer[ 5148 &ALmixer_Channel_List[i].almixer_data->buffer[
4967 ALmixer_Channel_List[i].almixer_data->num_buffers_in_use] 5149 ALmixer_Channel_List[i].almixer_data->num_buffers_in_use]
5054 ALmixer_Channel_List[i].almixer_data->num_buffers_in_use++; 5236 ALmixer_Channel_List[i].almixer_data->num_buffers_in_use++;
5055 } 5237 }
5056 /* Might want to check state */ 5238 /* Might want to check state */
5057 /* In case the playback stopped, 5239 /* In case the playback stopped,
5058 * we need to resume */ 5240 * we need to resume */
5241 #if 1
5242 /* Try not refetching the state here because I'm getting a duplicate
5243 buffer playback (hiccup) */
5059 alGetSourcei( 5244 alGetSourcei(
5060 ALmixer_Channel_List[i].alsource, 5245 ALmixer_Channel_List[i].alsource,
5061 AL_SOURCE_STATE, &state 5246 AL_SOURCE_STATE, &state
5062 ); 5247 );
5063 if((error = alGetError()) != AL_NO_ERROR) 5248 if((error = alGetError()) != AL_NO_ERROR)
5064 { 5249 {
5065 fprintf(stderr, "57Testing error: %s\n", 5250 fprintf(stderr, "57bTesting error: %s\n",
5066 aluGetErrorString(error)); 5251 aluGetErrorString(error));
5067 } 5252 }
5253 /* Get the number of buffers processed
5254 */
5255 alGetSourcei(
5256 ALmixer_Channel_List[i].alsource,
5257 AL_BUFFERS_PROCESSED,
5258 &buffers_processed
5259 );
5260 if((error = alGetError()) != AL_NO_ERROR)
5261 {
5262 fprintf(stderr, "57cError, Can't get buffers_processed: %s\n",
5263 aluGetErrorString(error));
5264 }
5265 #endif
5068 if(AL_STOPPED == state) 5266 if(AL_STOPPED == state)
5069 { 5267 {
5268 /*
5070 fprintf(stderr, "Resuming in not eof\n"); 5269 fprintf(stderr, "Resuming in not eof\n");
5071 alSourcePlay(ALmixer_Channel_List[i].alsource); 5270 */
5072 if((error = alGetError()) != AL_NO_ERROR) 5271 /* Okay, here's another lately discovered problem:
5073 { 5272 * I can't find it in the spec, but for at least some of the
5074 fprintf(stderr, "58Testing error: %s\n", 5273 * implementations, if I call play on a stopped source that
5075 aluGetErrorString(error)); 5274 * has processed buffers, all those buffers get marked as unprocessed
5076 } 5275 * on alSourcePlay. So if I had a queue of 25 with 24 of the buffers
5276 * processed, on resume, the earlier 24 buffers will get replayed,
5277 * causing a "hiccup" like sound in the playback.
5278 * To avoid this, I must unqueue all processed buffers before
5279 * calling play. But to complicate things, I need to worry about resyncing
5280 * the circular queue with this since I designed this thing
5281 * with some correlation between the two. However, I might
5282 * have already handled this, so I will try writing this code without
5283 * syncing for now.
5284 * There is currently an assumption that a buffer
5285 * was queued above so I actually have something
5286 * to play.
5287 */
5288 ALint temp_count;
5289 /*
5290 fprintf(stderr, "STOPPED2, need to clear processed, status is:\n");
5291 PrintQueueStatus(ALmixer_Channel_List[i].alsource);
5292 */
5293
5294 for(temp_count=0; temp_count<buffers_processed; temp_count++)
5295 {
5296 alSourceUnqueueBuffers(
5297 ALmixer_Channel_List[i].alsource,
5298 1, &unqueued_buffer_id
5299 );
5300 if((error = alGetError()) != AL_NO_ERROR)
5301 {
5302 fprintf(stderr, "58aTesting error: %s\n",
5303 aluGetErrorString(error));
5304 error_flag--;
5305 }
5306 }
5307 /*
5308 fprintf(stderr, "After unqueue clear...:\n");
5309 PrintQueueStatus(ALmixer_Channel_List[i].alsource);
5310 */
5311
5312 alSourcePlay(ALmixer_Channel_List[i].alsource);
5313 if((error = alGetError()) != AL_NO_ERROR)
5314 {
5315 fprintf(stderr, "55Tbesting 8rror: %s\n",
5316 aluGetErrorString(error));
5317 }
5077 } 5318 }
5078 continue; 5319 continue;
5079 } /* END if( ! eof) */ 5320 } /* END if( ! eof) */
5080 /* We have hit EOF in the SDL_Sound sample and there 5321 /* We have hit EOF in the SDL_Sound sample and there
5081 * are no more loops. However, there may still be 5322 * are no more loops. However, there may still be
5198 aluGetErrorString(error)); 5439 aluGetErrorString(error));
5199 } 5440 }
5200 if(AL_STOPPED == state) 5441 if(AL_STOPPED == state)
5201 { 5442 {
5202 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); 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);
5203 5444 /*
5204 PrintQueueStatus(ALmixer_Channel_List[i].alsource); 5445 PrintQueueStatus(ALmixer_Channel_List[i].alsource);
5205 5446 */
5206 /* Rather than force unqueuing the buffer, let's see if 5447 /* Rather than force unqueuing the buffer, let's see if
5207 * setting the buffer to none works (the OpenAL 1.0 5448 * setting the buffer to none works (the OpenAL 1.0
5208 * Reference Annotation suggests this should work). 5449 * Reference Annotation suggests this should work).
5209 */ 5450 */
5210 alSourcei(ALmixer_Channel_List[i].alsource, 5451 alSourcei(ALmixer_Channel_List[i].alsource,
5630 * This feature is toggled on/off by using the alDisable() & alEnable() APIs. This 5871 * This feature is toggled on/off by using the alDisable() & alEnable() APIs. This
5631 * setting will be applied to all subsequent 5872 * setting will be applied to all subsequent
5632 * calls to alBufferData(). 5873 * calls to alBufferData().
5633 */ 5874 */
5634 #ifdef __APPLE__ 5875 #ifdef __APPLE__
5635 alEnable(ALC_CONVERT_DATA_UPON_LOADING); 5876 alEnable(ALC_MAC_OSX_CONVERT_DATA_UPON_LOADING);
5636 #endif 5877 #endif
5637 5878
5638 5879
5639 5880
5640 5881
5652 Is_Playing_global = 0; 5893 Is_Playing_global = 0;
5653 /* Set to Null in case system quit and was reinitialized */ 5894 /* Set to Null in case system quit and was reinitialized */
5654 Channel_Done_Callback = NULL; 5895 Channel_Done_Callback = NULL;
5655 Channel_Done_Callback_Userdata = NULL; 5896 Channel_Done_Callback_Userdata = NULL;
5656 Channel_Data_Callback = NULL; 5897 Channel_Data_Callback = NULL;
5898 Channel_Data_Callback_Userdata = NULL;
5657 5899
5658 /* Allocate memory for the list of channels */ 5900 /* Allocate memory for the list of channels */
5659 ALmixer_Channel_List = (struct ALmixer_Channel*) malloc(Number_of_Channels_global * sizeof(struct ALmixer_Channel)); 5901 ALmixer_Channel_List = (struct ALmixer_Channel*) malloc(Number_of_Channels_global * sizeof(struct ALmixer_Channel));
5660 if(NULL == ALmixer_Channel_List) 5902 if(NULL == ALmixer_Channel_List)
5661 { 5903 {
6110 * This feature is toggled on/off by using the alDisable() & alEnable() APIs. This 6352 * This feature is toggled on/off by using the alDisable() & alEnable() APIs. This
6111 * setting will be applied to all subsequent 6353 * setting will be applied to all subsequent
6112 * calls to alBufferData(). 6354 * calls to alBufferData().
6113 */ 6355 */
6114 #ifdef __APPLE__ 6356 #ifdef __APPLE__
6115 alEnable(ALC_CONVERT_DATA_UPON_LOADING); 6357 alEnable(ALC_MAC_OSX_CONVERT_DATA_UPON_LOADING);
6116 #endif 6358 #endif
6117 6359
6118 return 0; 6360 return 0;
6119 } 6361 }
6120 6362
6140 Is_Playing_global = 0; 6382 Is_Playing_global = 0;
6141 /* Set to Null in case system quit and was reinitialized */ 6383 /* Set to Null in case system quit and was reinitialized */
6142 Channel_Done_Callback = NULL; 6384 Channel_Done_Callback = NULL;
6143 Channel_Done_Callback_Userdata = NULL; 6385 Channel_Done_Callback_Userdata = NULL;
6144 Channel_Data_Callback = NULL; 6386 Channel_Data_Callback = NULL;
6387 Channel_Data_Callback_Userdata = NULL;
6145 6388
6146 /* Allocate memory for the list of channels */ 6389 /* Allocate memory for the list of channels */
6147 ALmixer_Channel_List = (struct ALmixer_Channel*) malloc(Number_of_Channels_global * sizeof(struct ALmixer_Channel)); 6390 ALmixer_Channel_List = (struct ALmixer_Channel*) malloc(Number_of_Channels_global * sizeof(struct ALmixer_Channel));
6148 if(NULL == ALmixer_Channel_List) 6391 if(NULL == ALmixer_Channel_List)
6149 { 6392 {
6328 Sound_Quit(); 6571 Sound_Quit();
6329 6572
6330 return; 6573 return;
6331 } 6574 }
6332 6575
6333 Uint8 ALmixer_IsInitialized() 6576 SDL_bool ALmixer_IsInitialized()
6334 { 6577 {
6335 return ALmixer_Initialized; 6578 return ALmixer_Initialized;
6336 } 6579 }
6337 6580
6338 Uint32 ALmixer_GetFrequency() 6581 Uint32 ALmixer_GetFrequency()
6488 } 6731 }
6489 6732
6490 6733
6491 6734
6492 6735
6493 static ALmixer_Data* DoLoad(Sound_Sample* sample, Uint32 buffersize, Uint8 decode_mode, Uint32 max_queue_buffers, Uint32 num_startup_buffers, Uint8 access_data) 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)
6494 { 6737 {
6495 Uint32 bytes_decoded; 6738 Uint32 bytes_decoded;
6496 ALmixer_Data* ret_data; 6739 ALmixer_Data* ret_data;
6497 ALenum error; 6740 ALenum error;
6498 6741
6550 6793
6551 /* Now decode and load the data into a data chunk */ 6794 /* Now decode and load the data into a data chunk */
6552 /* Different cases for Streamed and Predecoded 6795 /* Different cases for Streamed and Predecoded
6553 * Streamed might turn into a predecoded if buffersize 6796 * Streamed might turn into a predecoded if buffersize
6554 * is large enough */ 6797 * is large enough */
6555 if(ALMIXER_DECODE_STREAM == decode_mode) 6798 if(SDL_FALSE == decode_mode_is_predecoded)
6556 { 6799 {
6557 bytes_decoded = Sound_Decode(sample); 6800 bytes_decoded = Sound_Decode(sample);
6558 if(sample->flags & SOUND_SAMPLEFLAG_ERROR) 6801 if(sample->flags & SOUND_SAMPLEFLAG_ERROR)
6559 { 6802 {
6560 ALmixer_SetError(Sound_GetError()); 6803 ALmixer_SetError(Sound_GetError());
6791 { 7034 {
6792 Uint32 j; 7035 Uint32 j;
6793 /* Create buffers for data access 7036 /* Create buffers for data access
6794 * Should be the same number as the number of queue buffers 7037 * Should be the same number as the number of queue buffers
6795 */ 7038 */
6796 ret_data->buffer_map_list = (Buffer_Map*)malloc( sizeof(Buffer_Map) * max_queue_buffers); 7039 ret_data->buffer_map_list = (ALmixer_Buffer_Map*)malloc( sizeof(ALmixer_Buffer_Map) * max_queue_buffers);
6797 if(NULL == ret_data->buffer_map_list) 7040 if(NULL == ret_data->buffer_map_list)
6798 { 7041 {
6799 ALmixer_SetError("Out of Memory"); 7042 ALmixer_SetError("Out of Memory");
6800 Sound_FreeSample(sample); 7043 Sound_FreeSample(sample);
6801 free(ret_data->buffer); 7044 free(ret_data->buffer);
6843 return NULL; 7086 return NULL;
6844 } 7087 }
6845 7088
6846 /* The Buffer_Map_List must be sorted by albuffer for binary searches 7089 /* The Buffer_Map_List must be sorted by albuffer for binary searches
6847 */ 7090 */
6848 qsort(ret_data->buffer_map_list, max_queue_buffers, sizeof(Buffer_Map), Compare_Buffer_Map); 7091 qsort(ret_data->buffer_map_list, max_queue_buffers, sizeof(ALmixer_Buffer_Map), Compare_Buffer_Map);
6849 } /* End if access_data==true */ 7092 } /* End if access_data==true */
6850 7093
6851 7094
6852 } /* End of do stream */ 7095 } /* End of do stream */
6853 } /* end of DECODE_STREAM */ 7096 } /* end of DECODE_STREAM */
6854 /* User requested decode all (easy, nothing to figure out) */ 7097 /* User requested decode all (easy, nothing to figure out) */
6855 else if(ALMIXER_DECODE_ALL == decode_mode) 7098 else if(SDL_TRUE == decode_mode_is_predecoded)
6856 { 7099 {
6857 bytes_decoded = Sound_DecodeAll(sample); 7100 bytes_decoded = Sound_DecodeAll(sample);
6858 if(sample->flags & SOUND_SAMPLEFLAG_ERROR) 7101 if(sample->flags & SOUND_SAMPLEFLAG_ERROR)
6859 { 7102 {
6860 ALmixer_SetError(Sound_GetError()); 7103 ALmixer_SetError(Sound_GetError());
6993 * I don't like the AudioInfo parameter. I removed it once, 7236 * I don't like the AudioInfo parameter. I removed it once,
6994 * but the system will fail on RAW samples because the user 7237 * but the system will fail on RAW samples because the user
6995 * must specify it, so I had to bring it back. 7238 * must specify it, so I had to bring it back.
6996 * Remember I must close the rwops if there is an error before NewSample() 7239 * Remember I must close the rwops if there is an error before NewSample()
6997 */ 7240 */
6998 ALmixer_Data* ALmixer_LoadSample_RW(SDL_RWops* rwops, const char* fileext, Uint32 buffersize, Uint8 decode_mode, Uint32 max_queue_buffers, Uint32 num_startup_buffers, Uint8 access_data) 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)
6999 { 7242 {
7000 Sound_Sample* sample = NULL; 7243 Sound_Sample* sample = NULL;
7001 Sound_AudioInfo target; 7244 Sound_AudioInfo target;
7002 7245
7003 /* Initialize target values to defaults 7246 /* Initialize target values to defaults
7029 { 7272 {
7030 ALmixer_SetError(Sound_GetError()); 7273 ALmixer_SetError(Sound_GetError());
7031 return NULL; 7274 return NULL;
7032 } 7275 }
7033 7276
7034 return( DoLoad(sample, buffersize, decode_mode, max_queue_buffers, num_startup_buffers, access_data)); 7277 return( DoLoad(sample, buffersize, decode_mode_is_predecoded, max_queue_buffers, num_startup_buffers, access_data));
7035 } 7278 }
7036 7279
7037 7280
7038 7281
7039 /* This will load a sample for us from 7282 /* This will load a sample for us from
7040 * a file (instead of RWops). Most of the uglyness is 7283 * a file (instead of RWops). Most of the uglyness is
7041 * error checking and the fact that streamed/predecoded files 7284 * error checking and the fact that streamed/predecoded files
7042 * must be treated differently. 7285 * must be treated differently.
7043 */ 7286 */
7044 ALmixer_Data* ALmixer_LoadSample(const char* filename, Uint32 buffersize, Uint8 decode_mode, Uint32 max_queue_buffers, Uint32 num_startup_buffers, Uint8 access_data) 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)
7045 { 7288 {
7046 Sound_Sample* sample = NULL; 7289 Sound_Sample* sample = NULL;
7047 Sound_AudioInfo target; 7290 Sound_AudioInfo target;
7048 7291
7049 /* Initialize target values to defaults 7292 /* Initialize target values to defaults
7133 return NULL; 7376 return NULL;
7134 } 7377 }
7135 7378
7136 fprintf(stderr, "Correction test: Actual rate=%d, desired=%d, actual format=%d, desired format=%d\n", sample->actual.rate, sample->desired.rate, sample->actual.format, sample->desired.format); 7379 fprintf(stderr, "Correction test: Actual rate=%d, desired=%d, actual format=%d, desired format=%d\n", sample->actual.rate, sample->desired.rate, sample->actual.format, sample->desired.format);
7137 7380
7138 return( DoLoad(sample, buffersize, decode_mode, max_queue_buffers, num_startup_buffers, access_data)); 7381 return( DoLoad(sample, buffersize, decode_mode_is_predecoded, max_queue_buffers, num_startup_buffers, access_data));
7139 } 7382 }
7140 7383
7141 7384
7142 /* This is a back door for RAW samples or if you need the 7385 /* This is a back door for RAW samples or if you need the
7143 * AudioInfo field. Use at your own risk. 7386 * AudioInfo field. Use at your own risk.
7144 */ 7387 */
7145 ALmixer_Data* ALmixer_LoadSample_RAW_RW(SDL_RWops* rwops, const char* fileext, Sound_AudioInfo* desired, Uint32 buffersize, Uint8 decode_mode, Uint32 max_queue_buffers, Uint32 num_startup_buffers, Uint8 access_data) 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)
7146 { 7389 {
7147 Sound_Sample* sample = NULL; 7390 Sound_Sample* sample = NULL;
7148 sample = Sound_NewSample(rwops, fileext, desired, buffersize); 7391 Sound_AudioInfo sound_desired;
7392 /* Rather than copying the data from struct to struct, I could just
7393 * cast the thing since the structs are meant to be identical.
7394 * But if SDL_sound changes it's implementation, bad things
7395 * will probably happen. (Or if I change my implementation and
7396 * forget about the cast, same bad scenario.) Since this is a load
7397 * function, performance of this is negligible.
7398 */
7399 if(NULL == desired)
7400 {
7401 sample = Sound_NewSample(rwops, fileext, NULL, buffersize);
7402 }
7403 else
7404 {
7405 sound_desired.format = desired->format;
7406 sound_desired.channels = desired->channels;
7407 sound_desired.rate = desired->rate;
7408 sample = Sound_NewSample(rwops, fileext, &sound_desired, buffersize);
7409 }
7149 if(NULL == sample) 7410 if(NULL == sample)
7150 { 7411 {
7151 ALmixer_SetError(Sound_GetError()); 7412 ALmixer_SetError(Sound_GetError());
7152 return NULL; 7413 return NULL;
7153 } 7414 }
7154 return( DoLoad(sample, buffersize, decode_mode, max_queue_buffers, num_startup_buffers, access_data)); 7415 return( DoLoad(sample, buffersize, decode_mode_is_predecoded, max_queue_buffers, num_startup_buffers, access_data));
7155 } 7416 }
7156 7417
7157 7418
7158 7419
7159 7420
7160 /* This is a back door for RAW samples or if you need the 7421 /* This is a back door for RAW samples or if you need the
7161 * AudioInfo field. Use at your own risk. 7422 * AudioInfo field. Use at your own risk.
7162 */ 7423 */
7163 ALmixer_Data* ALmixer_LoadSample_RAW(const char* filename, Sound_AudioInfo* desired, Uint32 buffersize, Uint8 decode_mode, Uint32 max_queue_buffers, Uint32 num_startup_buffers, Uint8 access_data) 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)
7164 { 7425 {
7165 Sound_Sample* sample = NULL; 7426 Sound_Sample* sample = NULL;
7166 sample = Sound_NewSampleFromFile(filename, desired, buffersize); 7427 Sound_AudioInfo sound_desired;
7428 /* Rather than copying the data from struct to struct, I could just
7429 * cast the thing since the structs are meant to be identical.
7430 * But if SDL_sound changes it's implementation, bad things
7431 * will probably happen. (Or if I change my implementation and
7432 * forget about the cast, same bad scenario.) Since this is a load
7433 * function, performance of this is negligible.
7434 */
7435 if(NULL == desired)
7436 {
7437 sample = Sound_NewSampleFromFile(filename, NULL, buffersize);
7438 }
7439 else
7440 {
7441 sound_desired.format = desired->format;
7442 sound_desired.channels = desired->channels;
7443 sound_desired.rate = desired->rate;
7444 sample = Sound_NewSampleFromFile(filename, &sound_desired, buffersize);
7445 }
7446
7167 if(NULL == sample) 7447 if(NULL == sample)
7168 { 7448 {
7169 ALmixer_SetError(Sound_GetError()); 7449 ALmixer_SetError(Sound_GetError());
7170 return NULL; 7450 return NULL;
7171 } 7451 }
7172 return( DoLoad(sample, buffersize, decode_mode, max_queue_buffers, num_startup_buffers, access_data)); 7452 return( DoLoad(sample, buffersize, decode_mode_is_predecoded, max_queue_buffers, num_startup_buffers, access_data));
7173 } 7453 }
7174 7454
7175 7455
7176 7456
7177 7457
7302 Channel_Done_Callback_Userdata = userdata; 7582 Channel_Done_Callback_Userdata = userdata;
7303 SDL_UnlockMutex(simple_lock); 7583 SDL_UnlockMutex(simple_lock);
7304 } 7584 }
7305 7585
7306 7586
7307 void ALmixer_ChannelData(void (*channel_data)(Sint32 which_chan, Uint8* data, Uint32 num_bytes, Uint32 frequency, Uint8 channels, Uint8 bitdepth, Uint16 format, Uint8 decode_mode)) 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)
7308 { 7588 {
7309 SDL_LockMutex(simple_lock); 7589 SDL_LockMutex(simple_lock);
7310 Channel_Data_Callback = channel_data; 7590 Channel_Data_Callback = channel_data;
7591 Channel_Data_Callback_Userdata = user_data;
7311 SDL_UnlockMutex(simple_lock); 7592 SDL_UnlockMutex(simple_lock);
7312 } 7593 }
7313 7594
7314 7595
7315 7596
7707 retval = Internal_CountUnreservedUsedChannels(); 7988 retval = Internal_CountUnreservedUsedChannels();
7708 SDL_UnlockMutex(simple_lock); 7989 SDL_UnlockMutex(simple_lock);
7709 return retval; 7990 return retval;
7710 } 7991 }
7711 7992
7712 7993 SDL_bool ALmixer_IsPredecoded(ALmixer_Data* data)
7713 7994 {
7714 7995 if(NULL == data)
7715 7996 {
7997 return SDL_FALSE;
7998 }
7999 return data->decoded_all;
8000 }
8001
8002
8003
8004
8005