diff 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
line wrap: on
line diff
--- a/SDL_ALmixer.c	Wed Oct 27 16:51:16 2010 -0700
+++ b/SDL_ALmixer.c	Wed Oct 27 16:52:44 2010 -0700
@@ -7,8 +7,13 @@
 
 #include "SDL_ALmixer.h"
 
-#include "SDL.h" /* For SDL_GetTicks(), SDL_Delay */
-#include "SDL_sound.h"
+#ifdef ALMIXER_COMPILE_WITHOUT_SDL
+	#include "ALmixer_rwops.h"
+	#include "SoundDecoder.h"
+#else
+	#include "SDL_sound.h"
+#endif
+
 #include "al.h" /* OpenAL */
 #include "alc.h" /* For creating OpenAL contexts */
 
@@ -19,7 +24,15 @@
 	 * define was moved to a new header file and renamed to
 	 * ALC_MAC_OSX_CONVERT_DATA_UPON_LOADING.
 	 */
-	#include <OpenAL/MacOSX_OALExtensions.h>
+/*
+	#include <TargetConditionals.h>
+	#if (TARGET_OS_IPHONE == 1) || (TARGET_IPHONE_SIMULATOR == 1)
+
+	#else
+		#include <OpenAL/MacOSX_OALExtensions.h>
+	#endif
+*/
+
 #endif
 
 /* For malloc, bsearch, qsort */
@@ -44,8 +57,24 @@
  */
 #include "CircularQueue.h"
 
+#ifdef ENABLE_ALMIXER_THREADS
 /* Needed for the Mutex locks (and threads if enabled) */
-#include "SDL_thread.h"
+	#ifdef ALMIXER_COMPILE_WITHOUT_SDL
+		#include "SimpleMutex.h"
+		#include "SimpleThread.h"
+		typedef struct SimpleMutex SDL_mutex;
+		typedef struct SimpleThread SDL_Thread;
+		#define SDL_CreateMutex SimpleMutex_CreateMutex
+		#define SDL_DestroyMutex SimpleMutex_DestroyMutex
+		#define SDL_LockMutex SimpleMutex_LockMutex
+		#define SDL_UnlockMutex SimpleMutex_UnlockMutex
+		#define SDL_CreateThread SimpleThread_CreateThread
+		#define SDL_WaitThread SimpleThread_WaitThread
+	
+	#else
+		#include "SDL_thread.h"
+	#endif
+#endif
 
 /* Because of the API differences between the Loki
  * and Creative distributions, we need to know which
@@ -59,7 +88,7 @@
  * from the Creative distribution. So for
  * now, the Nvidia distribution gets lumped with the 
  * Creative dist and I hope nothing will break.
- * My aluGetErrorString may be the most vulnerable.
+ * My alGetString may be the most vulnerable.
  */
 #ifdef AL_BYTE_LOKI
 	#define USING_LOKI_AL_DIST
@@ -171,25 +200,139 @@
 #endif
 /************ END REMOVE  ME (Don't need anymore) ********/
 
-static SDL_bool ALmixer_Initialized = 0;
+#ifdef ALMIXER_COMPILE_WITHOUT_SDL
+	#include "tErrorLib.h"
+	static TErrorPool* s_ALmixerErrorPool = NULL;
+#endif
+
+static ALboolean ALmixer_Initialized = 0;
 /* This should be set correctly by Init */
-static Uint32 ALmixer_Frequency_global = ALMIXER_DEFAULT_FREQUENCY;
+static ALuint ALmixer_Frequency_global = ALMIXER_DEFAULT_FREQUENCY;
 
 /* Will be initialized in Init */
-static Sint32 Number_of_Channels_global = 0;
-static Sint32 Number_of_Reserve_Channels_global = 0;
-static Uint32 Is_Playing_global = 0;
-
+static ALint Number_of_Channels_global = 0;
+static ALint Number_of_Reserve_Channels_global = 0;
+static ALuint Is_Playing_global = 0;
+
+#ifdef ENABLE_ALMIXER_THREADS
 /* This is for a simple lock system. It is not meant to be good,
  * but just sufficient to minimize/avoid threading issues
  */
-static SDL_mutex* simple_lock;
-
-#ifdef ENABLE_ALMIXER_THREADS
+static SDL_mutex* s_simpleLock;
 static SDL_Thread* Stream_Thread_global = NULL;
 #endif
 
 
+#ifdef __APPLE__
+static ALvoid Internal_alcMacOSXMixerOutputRate(const ALdouble sample_rate)
+{
+    static void (*alcMacOSXMixerOutputRateProcPtr)(const ALdouble) = NULL;
+    
+    if(NULL == alcMacOSXMixerOutputRateProcPtr)
+	{
+		alcMacOSXMixerOutputRateProcPtr = alGetProcAddress((const ALCchar*) "alcMacOSXMixerOutputRate");
+    }
+	
+    if(NULL != alcMacOSXMixerOutputRateProcPtr)
+	{
+        alcMacOSXMixerOutputRateProcPtr(sample_rate);		
+	}
+	
+    return;
+}
+
+ALdouble Internal_alcMacOSXGetMixerOutputRate()
+{
+    static ALdouble (*alcMacOSXGetMixerOutputRateProcPtr)(void) = NULL;
+    
+    if(NULL == alcMacOSXGetMixerOutputRateProcPtr)
+	{
+		alcMacOSXGetMixerOutputRateProcPtr = alGetProcAddress((const ALCchar*) "alcMacOSXGetMixerOutputRate");
+    }
+	
+    if(NULL != alcMacOSXGetMixerOutputRateProcPtr)
+	{
+        return alcMacOSXGetMixerOutputRateProcPtr();		
+	}
+	
+    return 0.0;
+}
+#endif
+
+#ifdef ALMIXER_COMPILE_WITHOUT_SDL
+
+	#if defined(__APPLE__)
+		#include <QuartzCore/QuartzCore.h>
+   	  	#include <unistd.h>
+		static CFTimeInterval s_ticksBaseTime = 0.0;
+		
+	#elif defined(_WIN32)
+		#define WIN32_LEAN_AND_MEAN
+		#include <windows.h>
+		#include <winbase.h>
+			LARGE_INTEGER s_hiResTicksPerSecond;
+			double s_hiResSecondsPerTick;
+			LARGE_INTEGER s_ticksBaseTime;
+	#else
+   	  	#include <unistd.h>
+		#include <time.h>
+		static struct timespec s_ticksBaseTime;
+	#endif
+	static void ALmixer_InitTime()
+	{
+		#if defined(__APPLE__)
+			s_ticksBaseTime = CACurrentMediaTime();
+		
+		#elif defined(_WIN32)
+			LARGE_INTEGER hi_res_ticks_per_second;
+			if(TRUE == QueryPerformanceFrequency(&hi_res_ticks_per_second))
+			{
+				QueryPerformanceCounter(&s_ticksBaseTime);
+				s_hiResSecondsPerTick = 1.0 / hi_res_ticks_per_second;
+			}
+			else
+			{
+				ALMixer_SetError("Windows error: High resolution clock failed.");
+				fprintf(stderr, "Windows error: High resolution clock failed. Audio will not work correctly.\n");
+			}
+		#else
+			/* clock_gettime is POSIX.1-2001 */
+			clock_gettime(CLOCK_MONOTONIC, &s_ticksBaseTime);
+		#endif
+
+	}
+	static ALuint ALmixer_GetTicks()
+	{
+		#if defined(__APPLE__)
+			return (ALuint)((CACurrentMediaTime()-s_ticksBaseTime)*1000.0);
+		#elif defined(_WIN32)
+			LARGE_INTEGER current_time;
+			QueryPerformanceCounter(&current_time);
+			return (ALuint)((current_time.QuadPart - s_ticksBaseTime.QuadPart) * 1000 * s_hiResSecondsPerTick);
+
+		#else /* assuming POSIX */
+			/* clock_gettime is POSIX.1-2001 */
+			struct timespec current_time;
+			clock_gettime(CLOCK_MONOTONIC, &current_time);
+			return (ALuint)((current_time.tv_sec - s_ticksBaseTime.tv_sec)*1000.0 + (current_time.tv_nec - s_ticksBaseTime.tv_nsec) / 1000000);
+		#endif
+	}
+	static void ALmixer_Delay(ALuint milliseconds_delay)
+	{
+		#if defined(_WIN32)
+		Sleep(milliseconds_delay);
+		#else
+		usleep(milliseconds_delay);
+		#endif
+	}
+#else
+	#include "SDL.h" /* For SDL_GetTicks(), SDL_Delay */
+	#define ALmixer_GetTicks SDL_GetTicks
+	#define ALmixer_Delay SDL_Delay
+#endif
+
+
+
 /* If ENABLE_PARANOID_SIGNEDNESS_CHECK is used,
  * these values will be reset on Init()
  * Consider these values Read-Only.
@@ -199,11 +342,11 @@
 #define ALMIXER_UNSIGNED_VALUE 255
 
 #ifdef ENABLE_PARANOID_SIGNEDNESS_CHECK
-static Uint16 SIGN_TYPE_16_BIT_FORMAT = AUDIO_S16SYS;
-static Uint16 SIGN_TYPE_8_BIT_FORMAT = AUDIO_S8;
+static ALushort SIGN_TYPE_16_BIT_FORMAT = AUDIO_S16SYS;
+static ALushort SIGN_TYPE_8_BIT_FORMAT = AUDIO_S8;
 #else
-static const Uint16 SIGN_TYPE_16_BIT_FORMAT = AUDIO_S16SYS;
-static const Uint16 SIGN_TYPE_8_BIT_FORMAT = AUDIO_S8;
+static const ALushort SIGN_TYPE_16_BIT_FORMAT = AUDIO_S16SYS;
+static const ALushort SIGN_TYPE_8_BIT_FORMAT = AUDIO_S8;
 #endif
 
 
@@ -215,22 +358,22 @@
 
 struct ALmixer_Data
 {
-	SDL_bool decoded_all; /* dictates different behaviors */
-	Sint32 total_time; /* total playing time of sample (msec) */
-	
-	Uint32 in_use; /* needed to prevent sharing for streams */
-	SDL_bool eof; /* flag for eof, only used for streams  */
-	
-	Uint32 total_bytes; /* For predecoded */
-	Uint32 loaded_bytes; /* For predecoded (for seek) */
+	ALboolean decoded_all; /* dictates different behaviors */
+	ALint total_time; /* total playing time of sample (msec) */
+	
+	ALuint in_use; /* needed to prevent sharing for streams */
+	ALboolean eof; /* flag for eof, only used for streams  */
+	
+	ALuint total_bytes; /* For predecoded */
+	ALuint loaded_bytes; /* For predecoded (for seek) */
 
 	Sound_Sample* sample; /* SDL_Sound provides the data */
 	ALuint* buffer; /* array of OpenAL buffers (at least 1 for predecoded) */
 
 	/* Needed for streamed buffers */
-	Uint32 max_queue_buffers; /* Max number of queue buffers */
-	Uint32 num_startup_buffers; /* Number of ramp-up buffers */
-	Uint32 num_buffers_in_use; /* number of buffers in use */
+	ALuint max_queue_buffers; /* Max number of queue buffers */
+	ALuint num_startup_buffers; /* Number of ramp-up buffers */
+	ALuint num_buffers_in_use; /* number of buffers in use */
 	
 	/* This stuff is for streamed buffers that require data access */
 	ALmixer_Buffer_Map* buffer_map_list; /* translate ALbuffer to index 
@@ -253,20 +396,20 @@
 
 static struct ALmixer_Channel
 {
-	SDL_bool channel_in_use;
-	SDL_bool callback_update; /* For streaming determination */
-	SDL_bool needs_stream; /* For streaming determination */
-	SDL_bool halted;
-	SDL_bool paused;
+	ALboolean channel_in_use;
+	ALboolean callback_update; /* For streaming determination */
+	ALboolean needs_stream; /* For streaming determination */
+	ALboolean halted;
+	ALboolean paused;
 	ALuint alsource;
 	ALmixer_Data* almixer_data;
-	Sint32 loops;
-	Sint32 expire_ticks;
-	Uint32 start_time;
-
-	SDL_bool fade_enabled;
-	Uint32 fade_expire_ticks;
-	Uint32 fade_start_time;
+	ALint loops;
+	ALint expire_ticks;
+	ALuint start_time;
+
+	ALboolean fade_enabled;
+	ALuint fade_expire_ticks;
+	ALuint fade_start_time;
 	ALfloat fade_inv_time;
 	ALfloat fade_start_volume;
 	ALfloat fade_end_volume;
@@ -274,16 +417,16 @@
 	ALfloat min_volume;
 
 	/* Do we need other flags?
-	Uint8 *samples;
+	ALbyte *samples;
 	int volume;
 	int looping;
 	int tag;
-	Uint32 expire;
-	Uint32 start_time;
+	ALuint expire;
+	ALuint start_time;
 	Mix_Fading fading;
 	int fade_volume;
-	Uint32 fade_length;
-	Uint32 ticks_fade;
+	ALuint fade_length;
+	ALuint ticks_fade;
 	effect_info *effects;
 	*/
 } *ALmixer_Channel_List = NULL;
@@ -291,16 +434,16 @@
 struct ALmixer_Buffer_Map
 {
 	ALuint albuffer;
-	Sint32 index; /* might not need */
-	Uint8* data;
-	Uint32 num_bytes;
+	ALint index; /* might not need */
+	ALbyte* data;
+	ALuint num_bytes;
 };
 
 /* This will be used to find a channel if the user supplies a source */
 typedef struct Source_Map
 {
     ALuint source;
-    Sint32 channel;
+    ALint channel;
 } Source_Map;
 /* Keep an array of all sources with their associated channel */
 static Source_Map* Source_Map_List;
@@ -325,74 +468,11 @@
 /* This is for the user defined callback via 
  * ALmixer_ChannelFinished()
  */
-static void (*Channel_Done_Callback)(Sint32 channel, void* userdata) = NULL;
+static void (*Channel_Done_Callback)(ALint which_channel, ALuint al_source, ALmixer_Data* almixer_data, ALboolean finished_naturally, void* user_data) = NULL;
 static void* Channel_Done_Callback_Userdata = NULL;
-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;
+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;
 static void* Channel_Data_Callback_Userdata = NULL;
 
-/* I thought OpenAL seemed to lack an error number to string converter...
-* but I was wrong. Apparently they call it alGetString() which
-* breaks from the OpenGL gluGetErrorString() convention.
-* (And since the documentation for OpenAL is so bad, I didn't see
-   * it until I had already written my own aluGetErrorString().)
-* So for convenience, I will just call alGetString from here.
-*/
-static const ALubyte* aluGetErrorString(ALenum error)
-{
-	return alGetString(error);
-	
-#if 0
-	switch(error)
-	{
-		case AL_NO_ERROR:
-			return NULL;
-			break;
-		case AL_INVALID_NAME:
-			return "Invalid name (ID)";
-			break;
-		case AL_INVALID_VALUE:
-			return "Invalid value";
-			break;
-		case AL_OUT_OF_MEMORY:
-			return "Out of memory";
-			break;
-			/* Damn, even the error values are skewed between distributions */
-			/* For the Creative Labs distributions (don't know about Nvidia) */
-			/* For the Loki based distributions */
-#ifdef USING_LOKI_AL_DIST
-		case AL_ILLEGAL_ENUM:
-			return "Invalid enum value";
-			break;
-		case AL_ILLEGAL_COMMAND:
-			return "Requested operation is not valid";
-			break;
-			/*
-#elif USING_CREATIVE_AL_DIST
-			 */
-#else
-		case AL_INVALID_ENUM:
-			return "Invalid enum value";
-			break;
-		case AL_INVALID_OPERATION:
-			return "Requested operation is not valid";
-			break;
-			/*
-#elif USING_NVIDIA_AL_DIST
-			 */
-			/*
-			 case alGetEnumValue((ALubyte*)"??????");
-			 */
-#endif
-		default:
-			return "Unknown error value passed to aluGetErrorString()";
-			break;
-	}
-	
-	/* Make compiler happy */
-	return NULL;
-#endif
-}
-
 
 static void PrintQueueStatus(ALuint source)
 {
@@ -410,7 +490,7 @@
 	if((error = alGetError()) != AL_NO_ERROR)
 	{
 		fprintf(stderr, "Error in PrintQueueStatus, Can't get buffers_queued: %s\n",
-			aluGetErrorString(error));				
+			alGetString(error));				
 	}
 	/* Get the number of buffers processed
 	 * so we know if we need to refill 
@@ -423,7 +503,7 @@
 	if((error = alGetError()) != AL_NO_ERROR)
 	{
 		fprintf(stderr, "Error in PrintQueueStatus, Can't get buffers_processed: %s\n",
-			aluGetErrorString(error));				
+			alGetString(error));				
 	}
 	
 	fprintf(stderr, "For source: %d, buffers_queued=%d, buffers_processed=%d\n",
@@ -435,7 +515,7 @@
 
 
 
-static void Init_Channel(Sint32 channel)
+static void Init_Channel(ALint channel)
 {
 
 fprintf(stderr, "Init channel %d\n", channel);
@@ -462,7 +542,7 @@
 }
 /* Quick helper function to clean up a channel 
  * after it's done playing */
-static void Clean_Channel(Sint32 channel)
+static void Clean_Channel(ALint channel)
 {
 	ALenum error;
 	ALmixer_Channel_List[channel].channel_in_use = 0;
@@ -489,7 +569,7 @@
 	if((error = alGetError()) != AL_NO_ERROR)
 	{
 		fprintf(stderr, "10Testing errpr before unqueue because getting stuff, for OS X this is expected: %s\n",
-			aluGetErrorString(error));				
+			alGetString(error));				
 	}
 	
 	alSourcef(ALmixer_Channel_List[channel].alsource, AL_MIN_GAIN, 
@@ -497,7 +577,7 @@
 	if((error = alGetError()) != AL_NO_ERROR)
 	{
 		fprintf(stderr, "11Testing errpr before unqueue because getting stuff, for OS X this is expected: %s\n",
-			aluGetErrorString(error));				
+			alGetString(error));				
 	}
 	
 	if(ALmixer_Channel_List[channel].almixer_data != NULL)
@@ -555,7 +635,7 @@
 /* What shoud this return?
  * 127 for signed, 255 for unsigned
  */
-static Uint8 GetSignednessValue(Uint16 format)
+static ALubyte GetSignednessValue(ALushort format)
 {
 	switch(format)
 	{
@@ -576,9 +656,9 @@
 }
 
 
-static Uint8 GetBitDepth(Uint16 format)
-{
-	Uint8 bit_depth = 16;
+static ALubyte GetBitDepth(ALushort format)
+{
+	ALubyte bit_depth = 16;
 	
 	switch(format)
 	{
@@ -613,7 +693,7 @@
  * and OpenAL conventions */
 static ALenum TranslateFormat(Sound_AudioInfo* info)
 {
-	Uint8 bit_depth;
+	ALubyte bit_depth;
 	
 	bit_depth = GetBitDepth(info->format);
 	if(0 == bit_depth)
@@ -653,11 +733,11 @@
 * based upon the number of bytes and audio info.
 * (In prinicple, it should compute the time for any given length) 
 */
-static Uint32 Compute_Total_Time_Decomposed(Uint32 bytes_per_sample, Uint32 frequency, Uint8 channels, Uint32 total_bytes)
+static ALuint Compute_Total_Time_Decomposed(ALuint bytes_per_sample, ALuint frequency, ALubyte channels, size_t total_bytes)
 {
 	double total_sec;
-	Uint32 total_msec;
-	Uint32 bytes_per_sec;
+	ALuint total_msec;
+	ALuint bytes_per_sec;
 	
 	if(0 == total_bytes)
 	{
@@ -676,31 +756,125 @@
 	/* Now convert seconds to milliseconds
 		* Add .5 to the float to do rounding before the final cast
 		*/
-	total_msec = (Uint32) ( (total_sec * 1000) + 0.5 );
+	total_msec = (ALuint) ( (total_sec * 1000) + 0.5 );
 	/*
 	 fprintf(stderr, "freq=%d, bytes_per_sample=%d, channels=%d, total_msec=%d\n", frequency, bytes_per_sample, channels, total_msec);
 	*/
 	return total_msec;
 }
 
-static Uint32 Compute_Total_Time(Sound_AudioInfo *info, Uint32 total_bytes)
-{
-	Uint32 bytes_per_sample;
+static ALuint Compute_Total_Time(Sound_AudioInfo *info, size_t total_bytes)
+{
+	ALuint bytes_per_sample;
 	
 	if(0 == total_bytes)
 	{
 		return 0;
 	}
 	/* SDL has a mask trick I was not aware of. Mask the upper bits
-		* of the format, and you get 8 or 16 which is the bits per sample.
-		* Divide by 8bits_per_bytes and you get bytes_per_sample
-		*/
-	bytes_per_sample = (Uint32) ((info->format & 0xFF) / 8);
+	 * of the format, and you get 8 or 16 which is the bits per sample.
+ 	 * Divide by 8bits_per_bytes and you get bytes_per_sample
+	 * I tested this under 32-bit and 64-bit and big and little endian
+	 * to make sure this still works since I have since moved from 
+	 * Uint32 to unspecified size types like ALuint.
+	 */
+	bytes_per_sample = (ALuint) ((info->format & 0xFF) / 8);
 	
 	return Compute_Total_Time_Decomposed(bytes_per_sample, info->rate, info->channels, total_bytes);
 } /* End Compute_Total_Time */
 	
 
+static size_t Compute_Total_Bytes_Decomposed(ALuint bytes_per_sample, ALuint frequency, ALubyte channels, ALuint total_msec)
+{
+	double total_sec;
+	ALuint bytes_per_sec;
+	size_t total_bytes;
+
+	if(0 >= total_msec)
+	{
+		return 0;
+	}
+	/* To compute Bytes per second, do
+		* samples_per_sec * bytes_per_sample * number_of_channels
+		*/
+	bytes_per_sec = frequency * bytes_per_sample * channels;
+	
+	/* convert milliseconds to seconds */
+	total_sec = total_msec / 1000.0;
+
+	/* Now to get total bytes */
+	total_bytes = (size_t)(((double)bytes_per_sec * total_sec) + 0.5);
+	
+/*	 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);
+*/
+
+	return total_bytes;
+}
+
+static size_t Compute_Total_Bytes(Sound_AudioInfo *info, ALuint total_msec)
+{
+	ALuint bytes_per_sample;
+	
+	if(0 >= total_msec)
+	{
+		return 0;
+	}
+	/* SDL has a mask trick I was not aware of. Mask the upper bits
+	 * of the format, and you get 8 or 16 which is the bits per sample.
+ 	 * Divide by 8bits_per_bytes and you get bytes_per_sample
+	 * I tested this under 32-bit and 64-bit and big and little endian
+	 * to make sure this still works since I have since moved from 
+	 * Uint32 to unspecified size types like ALuint.
+	 */
+	bytes_per_sample = (ALuint) ((info->format & 0xFF) / 8);
+	
+	return Compute_Total_Bytes_Decomposed(bytes_per_sample, info->rate, info->channels, total_msec);
+}
+
+/* The back-end decoders seem to need to decode in quantized frame sizes.
+ * So if I can pad the bytes to the next quanta, things might go more smoothly.
+ */
+static size_t Compute_Total_Bytes_With_Frame_Padding(Sound_AudioInfo *info, ALuint total_msec)
+{
+	ALuint bytes_per_sample;
+	ALuint bytes_per_frame;
+	size_t evenly_divisible_frames;
+	size_t remainder_frames;
+	size_t return_bytes;
+
+	size_t total_bytes = Compute_Total_Bytes(info, total_msec);
+
+	bytes_per_sample = (ALuint) ((info->format & 0xFF) / 8);
+	
+	bytes_per_frame = bytes_per_sample * info->channels;
+
+	evenly_divisible_frames = total_bytes / bytes_per_frame;
+	remainder_frames = total_bytes % bytes_per_frame;
+
+	return_bytes = (evenly_divisible_frames * bytes_per_frame)  + (remainder_frames * bytes_per_frame);
+
+	/* Experimentally, some times I see to come up short in 
+	 * actual bytes decoded and I see a second pass is needed.
+	 * I'm worried this may have additional performance implications.
+	 * Sometimes in the second pass (depending on file), 
+	 * I have seen between 0 and 18 bytes.
+	 * I'm tempted to pad the bytes by some arbitrary amount.
+	 * However, I think currently the way SDL_sound is implemented,
+	 * there is a big waste of memory up front instead of per-pass,
+	 * so maybe I shouldn't worry about this.
+	 */
+	/*
+	return_bytes += 64;
+	*/
+	/*
+	 fprintf(stderr, "remainder_frames=%d, padded_total_bytes=%d\n", remainder_frames, return_bytes);
+	 */
+	 return return_bytes;
+
+}
+
+
+
 
 /**************** REMOVED ****************************/
 /* This was removed because I originally thought
@@ -718,8 +892,8 @@
 
 static void Set_AudioInfo(Sound_AudioInfo* info, ALint frequency, ALint bits, ALint channels)
 {
-	info->rate = (Uint32)frequency;
-	info->channels = (Uint8)channels;
+	info->rate = (ALuint)frequency;
+	info->channels = (ALubyte)channels;
 	
 	/* Not sure if it should be signed or unsigned. Hopefully
 	 * that detail won't be needed.
@@ -738,7 +912,7 @@
 }
 
 
-static Sint32 Reconstruct_Sound_Sample(ALmixer_Data* data)
+static ALint Reconstruct_Sound_Sample(ALmixer_Data* data)
 {
 	ALenum error;	
 	ALint* data_from_albuffer;
@@ -761,7 +935,7 @@
 	alGetBufferi(data->buffer[0], AL_FREQUENCY, &freq);
 	if((error = alGetError()) != AL_NO_ERROR)
 	{
-		ALmixer_SetError("alGetBufferi(AL_FREQUENCT): %s", aluGetErrorString(error) );
+		ALmixer_SetError("alGetBufferi(AL_FREQUENCY): %s", alGetString(error) );
 		free(data->sample);
 		data->sample = NULL;
 		return -1;
@@ -770,7 +944,7 @@
 	alGetBufferi(data->buffer[0], AL_BITS, &bits);
 	if((error = alGetError()) != AL_NO_ERROR)
 	{
-		ALmixer_SetError("alGetBufferi(AL_BITS): %s", aluGetErrorString(error) );
+		ALmixer_SetError("alGetBufferi(AL_BITS): %s", alGetString(error) );
 		free(data->sample);
 		data->sample = NULL;
 		return -1;
@@ -779,7 +953,7 @@
 	alGetBufferi(data->buffer[0], AL_CHANNELS, &channels);
 	if((error = alGetError()) != AL_NO_ERROR)
 	{
-		ALmixer_SetError("alGetBufferi(AL_CHANNELS): %s", aluGetErrorString(error) );
+		ALmixer_SetError("alGetBufferi(AL_CHANNELS): %s", alGetString(error) );
 		free(data->sample);
 		data->sample = NULL;
 		return -1;
@@ -788,7 +962,7 @@
 	alGetBufferi(data->buffer[0], AL_SIZE, &size);
 	if((error = alGetError()) != AL_NO_ERROR)
 	{
-		ALmixer_SetError("alGetBufferi(AL_SIZE): %s", aluGetErrorString(error) );
+		ALmixer_SetError("alGetBufferi(AL_SIZE): %s", alGetString(error) );
 		free(data->sample);
 		data->sample = NULL;
 		return -1;
@@ -797,7 +971,7 @@
 	alGetBufferi(data->buffer[0], AL_DATA, data_from_albuffer);
 	if((error = alGetError()) != AL_NO_ERROR)
 	{
-		ALmixer_SetError("alGetBufferi(AL_DATA): %s", aluGetErrorString(error) );
+		ALmixer_SetError("alGetBufferi(AL_DATA): %s", alGetString(error) );
 		free(data->sample);
 		data->sample = NULL;
 		return -1;
@@ -815,7 +989,7 @@
 	 * allocate memory for the buffer and reconstruct
 	 * the AudioInfo attributes.
 	 */
-	data->sample->buffer = malloc(size*sizeof(Uint8));
+	data->sample->buffer = malloc(size*sizeof(ALbyte));
 	if(NULL == data->sample->buffer)
 	{
 		ALmixer_SetError("Out of memory for sample->buffer");
@@ -838,16 +1012,16 @@
 #endif
 /*************** END REMOVED *************************/	
 
-static void Invoke_Channel_Done_Callback(Sint32 channel)
+static void Invoke_Channel_Done_Callback(ALint which_channel, ALboolean did_finish_naturally)
 {
 	if(NULL == Channel_Done_Callback)
 	{
 		return;
 	}
-	Channel_Done_Callback(channel, Channel_Done_Callback_Userdata);
-}
-
-static Sint32 LookUpBuffer(ALuint buffer, ALmixer_Buffer_Map* buffer_map_list, Uint32 num_items_in_list)
+	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);
+}
+
+static ALint LookUpBuffer(ALuint buffer, ALmixer_Buffer_Map* buffer_map_list, ALuint num_items_in_list)
 {
 	/* Only the first value is used for the key */
 	ALmixer_Buffer_Map key = { 0, 0, NULL, 0 };
@@ -873,12 +1047,12 @@
  * channels: 1 for mono, 2 for stereo
  *
  */
-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)
-{
-	SDL_bool is_unsigned;
-	Uint8 bits_per_sample = GetBitDepth(format);
-	Uint32 bytes_per_sample;
-	Uint32 length_in_msec;
+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)
+{
+	ALboolean is_unsigned;
+	ALubyte bits_per_sample = GetBitDepth(format);
+	ALuint bytes_per_sample;
+	ALuint length_in_msec;
 
 	if(GetSignednessValue(format) == ALMIXER_UNSIGNED_VALUE)
 	{
@@ -889,7 +1063,7 @@
 		is_unsigned = 0;
 	}
 
-	bytes_per_sample = (Uint32) (bits_per_sample / 8);
+	bytes_per_sample = (ALuint) (bits_per_sample / 8);
 
 	length_in_msec = Compute_Total_Time_Decomposed(bytes_per_sample, frequency, channels, num_bytes);
 
@@ -903,10 +1077,10 @@
 	/*
 	 * Channel_Data_Callback(which_channel, data, num_bytes, frequency, channels, GetBitDepth(format), format, decode_mode_is_predecoded);
 	*/
-	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);
-}
-
-static void Invoke_Predecoded_Channel_Data_Callback(Sint32 channel, ALmixer_Data* data)
+	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);
+}
+
+static void Invoke_Predecoded_Channel_Data_Callback(ALint channel, ALmixer_Data* data)
 {
 	if(NULL == data->sample)
 	{
@@ -916,18 +1090,18 @@
 	 * we must adjust the buffer to the seek position
 	 */
 	Invoke_Channel_Data_Callback(channel, 
-		(((Uint8*) data->sample->buffer) + (data->total_bytes - data->loaded_bytes) ),
+		(((ALbyte*) data->sample->buffer) + (data->total_bytes - data->loaded_bytes) ),
 		data->loaded_bytes,
 		data->sample->desired.rate,
 		data->sample->desired.channels,
 		data->sample->desired.format,
-		SDL_TRUE
+		AL_TRUE
 	);
 }
 
-static void Invoke_Streamed_Channel_Data_Callback(Sint32 channel, ALmixer_Data* data, ALuint buffer)
-{
-	Sint32 index;
+static void Invoke_Streamed_Channel_Data_Callback(ALint channel, ALmixer_Data* data, ALuint buffer)
+{
+	ALint index;
 	if(NULL == data->buffer_map_list)
 	{
 		return;
@@ -946,18 +1120,18 @@
 		data->sample->desired.rate,
 		data->sample->desired.channels,
 		data->sample->desired.format,
-		SDL_FALSE
+		AL_FALSE
 	);
 }
 
 /* From SDL_Sound's playsound. Converts milliseconds to byte positions.
  * This is needed for seeking on predecoded samples 
  */
-static Uint32 Convert_Msec_To_Byte_Pos(Sound_AudioInfo *info, Uint32 ms)
+static ALuint Convert_Msec_To_Byte_Pos(Sound_AudioInfo *info, ALuint ms)
 {
 	float frames_per_ms;
-	Uint32 frame_offset;
-	Uint32 frame_size;
+	ALuint frame_offset;
+	ALuint frame_size;
 	fprintf(stderr, "In convert\n" );
 	if(info == NULL)
 	{
@@ -972,14 +1146,14 @@
 	/* "frames" == "sample frames" */
 	frames_per_ms = ((float) info->rate) / 1000.0f;
 	fprintf(stderr, "%f\n", frames_per_ms);
-	frame_offset = (Uint32) (frames_per_ms * ((float) ms));
+	frame_offset = (ALuint) (frames_per_ms * ((float) ms));
 	fprintf(stderr, "%d\n", frame_offset);
-	frame_size = (Uint32) ((info->format & 0xFF) / 8) * info->channels;
+	frame_size = (ALuint) ((info->format & 0xFF) / 8) * info->channels;
 	fprintf(stderr, "%d\n", frame_size);
 	return(frame_offset * frame_size);
 } /* cvtMsToBytePos */
 
-static Sint32 Set_Predecoded_Seek_Position(ALmixer_Data* data, Uint32 byte_position)
+static ALint Set_Predecoded_Seek_Position(ALmixer_Data* data, ALuint byte_position)
 {
 	ALenum error;
 	/* clear error */
@@ -996,7 +1170,7 @@
 	 *
 		alBufferData(data->buffer[0],
 			TranslateFormat(&data->sample->desired), 
-			 (Uint8*) data->sample->buffer,
+			 (ALbyte*) data->sample->buffer,
 			 data->total_bytes,
 			data->sample->desired.rate
 		);
@@ -1010,13 +1184,13 @@
 		 */
 		alBufferData(data->buffer[0],
 			TranslateFormat(&data->sample->desired), 
-			 (((Uint8*) data->sample->buffer) + (data->total_bytes - 8) ),
+			 (((ALbyte*) data->sample->buffer) + (data->total_bytes - 8) ),
 			 8,
 			data->sample->desired.rate
 		);
 		if( (error = alGetError()) != AL_NO_ERROR)
 		{
-			ALmixer_SetError("Can't seek past end and alBufferData failed: %s\n", aluGetErrorString(error));
+			ALmixer_SetError("Can't seek past end and alBufferData failed: %s\n", alGetString(error));
 			return -1;
 		}
 		/* Need to set the loaded_bytes field because I don't trust the OpenAL
@@ -1035,13 +1209,13 @@
 	
 	alBufferData(data->buffer[0],
 		TranslateFormat(&data->sample->desired), 
-		&(((Uint8*)data->sample->buffer)[byte_position]),
+		&(((ALbyte*)data->sample->buffer)[byte_position]),
 		data->total_bytes - byte_position,
 		data->sample->desired.rate
 	);
 	if( (error = alGetError()) != AL_NO_ERROR)
 	{
-		ALmixer_SetError("alBufferData failed: %s\n", aluGetErrorString(error));
+		ALmixer_SetError("alBufferData failed: %s\n", alGetString(error));
 		return -1;
 	}
 	/* Need to set the loaded_bytes field because I don't trust the OpenAL
@@ -1056,9 +1230,9 @@
 /* Because we have multiple queue buffers and OpenAL won't let
  * us access them, we need to keep copies of each buffer around
  */
-static Sint32 CopyDataToAccessBuffer(ALmixer_Data* data, Uint32 num_bytes, ALuint buffer)
-{
-	Sint32 index;
+static ALint CopyDataToAccessBuffer(ALmixer_Data* data, ALuint num_bytes, ALuint buffer)
+{
+	ALint index;
 	/* We only want to copy if access_data is true.
 	 * This is determined by whether memory has been
 	 * allocated in the buffer_map_list or not
@@ -1084,9 +1258,9 @@
 /* For streamed data, gets more data
  * and prepares it in the active Mix_chunk
  */
-static Uint32 GetMoreData(ALmixer_Data* data, ALuint buffer)
-{
-	Uint32 bytes_decoded;
+static ALuint GetMoreData(ALmixer_Data* data, ALuint buffer)
+{
+	ALuint bytes_decoded;
 	ALenum error;
 	if(NULL == data)
 	{
@@ -1105,14 +1279,16 @@
 		return 0;
 	}
 	
-	
+/*	fprintf(stderr, "GetMoreData bytes_decoded=%d\n", bytes_decoded); */
+
 	/* Don't forget to add check for EOF */
 	/* Will return 0 bytes and pass the buck to check sample->flags */
 	if(0 == bytes_decoded)
 	{
-#if 1 
+		data->eof = 1;
+
+#if 0 
 fprintf(stderr, "Hit eof while trying to buffer\n");
-		data->eof = 1;
 		if(data->sample->flags & SOUND_SAMPLEFLAG_EOF)
 		{
 			fprintf(stderr, "\tEOF flag\n");
@@ -1169,8 +1345,8 @@
 	 */
 	if( (bytes_decoded) < data->sample->buffer_size)
 	{
-		Uint8 bit_depth;
-		Uint8 signedness_value;
+		ALubyte bit_depth;
+		ALubyte signedness_value;
 		int silence_value;
 		/* Crap, memset value needs to be the "silent" value, 
 		 * but it will differ for signed/unsigned and bit depth
@@ -1202,7 +1378,7 @@
 		 * this part since the data is for internal use only
 		 * at this point.
 		 */
-		memset( &( ((Uint8*)(data->sample->buffer))[bytes_decoded] ), silence_value, data->sample->buffer_size - bytes_decoded);
+		memset( &( ((ALbyte*)(data->sample->buffer))[bytes_decoded] ), silence_value, data->sample->buffer_size - bytes_decoded);
 		/* Now reset the bytes_decoded to reflect the entire 
 		 * buffer to tell alBufferData what our full size is.
 		 */
@@ -1224,7 +1400,7 @@
 	);
 	if( (error = alGetError()) != AL_NO_ERROR)
 	{
-		ALmixer_SetError("alBufferData failed: %s\n", aluGetErrorString(error));
+		ALmixer_SetError("alBufferData failed: %s\n", alGetString(error));
 		return 0;
 	}
 
@@ -1243,9 +1419,9 @@
  * REMOVE LATER
  *********************************************/
 #if 0
-static Sint32 GetMoreData2(ALmixer_Data* data, ALuint buffer)
-{
-	Sint32 bytes_decoded;
+static ALint GetMoreData2(ALmixer_Data* data, ALuint buffer)
+{
+	ALint bytes_decoded;
 	ALenum error;
 	if(NULL == data)
 	{
@@ -1323,7 +1499,7 @@
 		retval = Sound_SetBufferSize(data->sample, 16384-bytes_decoded);
 		if(retval == 1)
 		{
-			Uint32 new_bytes;
+			ALuint new_bytes;
 			Sound_Rewind(data->sample);
 			new_bytes = Sound_Decode(data->sample);
 			fprintf(stderr, "Orig bytes: %d, Make up bytes_decoded=%d, total=%d\n", bytes_decoded, new_bytes, new_bytes+bytes_decoded);
@@ -1361,7 +1537,7 @@
 	);
 	if( (error = alGetError()) != AL_NO_ERROR)
 	{
-		ALmixer_SetError("alBufferData failed: %s\n", aluGetErrorString(error));
+		ALmixer_SetError("alBufferData failed: %s\n", alGetString(error));
 		return -1;
 	}
 	
@@ -1382,9 +1558,9 @@
 
 /* This function will look up the source for the corresponding channel */
 /* Must return 0 on error instead of -1 because of unsigned int */
-static ALuint Internal_GetSource(Sint32 channel)
-{
-	Sint32 i;
+static ALuint Internal_GetSource(ALint channel)
+{
+	ALint i;
 	/* Make sure channel is in bounds */
 	if(channel >= Number_of_Channels_global)
 	{
@@ -1412,9 +1588,9 @@
 }
 
 /* This function will look up the channel for the corresponding source */
-static Sint32 Internal_GetChannel(ALuint source)
-{
-	Sint32 i;
+static ALint Internal_GetChannel(ALuint source)
+{
+	ALint i;
 	/* Only the first value is used for the key */
 	Source_Map key = { 0, 0 };
 	Source_Map* found_item = NULL;
@@ -1461,12 +1637,12 @@
  * from the specified start channel. Reserved channels to not qualify
  * as available.
  */
-static Sint32 Internal_FindFreeChannel(Sint32 start_channel)
+static ALint Internal_FindFreeChannel(ALint start_channel)
 {
 	/* Start at the number of reserved so we skip over
 	 * all the reserved channels.
 	 */
-	Sint32 i = Number_of_Reserve_Channels_global;
+	ALint i = Number_of_Reserve_Channels_global;
 	/* Quick check to see if we're out of bounds */
 	if(start_channel >= Number_of_Channels_global)
 	{
@@ -1495,6 +1671,231 @@
 
 
 
+/* Will return the number of channels halted
+ * or 0 for error
+ */
+static ALint Internal_HaltChannel(ALint channel, ALboolean did_finish_naturally)
+{
+	ALint retval = 0;
+	ALint counter = 0;
+	ALenum error;
+	ALint buffers_still_queued;
+	ALint buffers_processed;
+
+	if(channel >= Number_of_Channels_global)
+	{
+		ALmixer_SetError("Cannot halt channel %d because it exceeds maximum number of channels (%d)\n", channel, Number_of_Channels_global);
+		return -1;
+	}
+	/* If the user specified a specific channel */
+	if(channel >= 0)
+	{
+		fprintf(stderr, "Halt on channel %d\n", channel);
+		/* only need to process channel if in use */
+		if(ALmixer_Channel_List[channel].channel_in_use)
+		{
+			alSourceStop(ALmixer_Channel_List[channel].alsource);
+			if((error = alGetError()) != AL_NO_ERROR)
+			{
+				fprintf(stderr, "14Testing error: %s\n",
+					alGetString(error));				
+			}
+			/* Here's the situation. My old method of using
+			 * alSourceUnqueueBuffers() seemed to be invalid in light
+			 * of all the problems I suffered through with getting 
+			 * the CoreData backend to work with this code.
+			 * As such, I'm changing all the code to set the buffer to
+			 * AL_NONE. Furthermore, the queued vs. non-queued issue
+			 * doesn't need to apply here. For non-queued, Loki,
+			 * Creative Windows, and CoreAudio seem to leave the 
+			 * buffer queued (Old Mac didn't.) For queued, we need to 
+			 * remove the processed buffers and force remove the
+			 * still-queued buffers.
+			 */
+			fprintf(stderr, "Halt on channel %d, channel in use\n", channel);
+			alGetSourcei(
+				ALmixer_Channel_List[channel].alsource,
+				AL_BUFFERS_QUEUED, &buffers_still_queued
+			);
+			if((error = alGetError()) != AL_NO_ERROR)
+			{
+				fprintf(stderr, "17Testing Error with buffers_still_queued: %s",
+					alGetString(error));
+				ALmixer_SetError("Failed detecting still queued buffers: %s",
+					alGetString(error) );
+				retval = -1;
+			}
+			alGetSourcei(
+				ALmixer_Channel_List[channel].alsource,
+				AL_BUFFERS_PROCESSED, &buffers_processed
+			);
+			if((error = alGetError()) != AL_NO_ERROR)
+			{
+				fprintf(stderr, "17Testing Error with buffers_processed: %s",
+					alGetString(error));
+				ALmixer_SetError("Failed detecting still processed buffers: %s",
+					alGetString(error) );
+				retval = -1;
+			}
+			/* If either of these is greater than 0, it means we need
+			 * to clear the source
+			 */
+			if((buffers_still_queued > 0) || (buffers_processed > 0))
+			{
+				alSourcei(ALmixer_Channel_List[channel].alsource,
+					AL_BUFFER,
+					AL_NONE);
+				if((error = alGetError()) != AL_NO_ERROR)
+				{
+					fprintf(stderr, "17Testing Error with clearing buffer from source: %s",
+						alGetString(error));
+					ALmixer_SetError("Failed to clear buffer from source: %s",
+						alGetString(error) );
+					retval = -1;
+				}
+			}
+
+			ALmixer_Channel_List[channel].almixer_data->num_buffers_in_use  = 0;
+
+			Clean_Channel(channel);
+			Is_Playing_global--;
+			/* Launch callback for consistency? */
+			Invoke_Channel_Done_Callback(channel, did_finish_naturally);
+			counter++;
+		}
+	}
+	/* The user wants to halt all channels */
+	else
+	{
+		ALint i;
+		for(i=0; i<Number_of_Channels_global; i++)
+		{
+			fprintf(stderr, "Halting channel %d\n", i);
+			fprintf(stderr, "in use %d\n", ALmixer_Channel_List[i].channel_in_use );
+			/* only need to process channel if in use */
+			if(ALmixer_Channel_List[i].channel_in_use)
+			{
+				fprintf(stderr, "SourceStop %d\n", i);
+				alSourceStop(ALmixer_Channel_List[i].alsource);
+				if((error = alGetError()) != AL_NO_ERROR)
+				{
+					fprintf(stderr, "19Testing error: %s\n",
+						alGetString(error));				
+				}
+
+				/* Here's the situation. My old method of using
+				 * alSourceUnqueueBuffers() seemed to be invalid in light
+				 * of all the problems I suffered through with getting 
+				 * the CoreData backend to work with this code.
+				 * As such, I'm changing all the code to set the buffer to
+				 * AL_NONE. Furthermore, the queued vs. non-queued issue
+				 * doesn't need to apply here. For non-queued, Loki,
+				 * Creative Windows, and CoreAudio seem to leave the 
+				 * buffer queued (Old Mac didn't.) For queued, we need to 
+				 * remove the processed buffers and force remove the
+				 * still-queued buffers.
+				 */
+				fprintf(stderr, "Halt on channel %d, channel in use\n", channel);
+				alGetSourcei(
+					ALmixer_Channel_List[i].alsource,
+					AL_BUFFERS_QUEUED, &buffers_still_queued
+				);
+				if((error = alGetError()) != AL_NO_ERROR)
+				{
+					fprintf(stderr, "17Testing Error with buffers_still_queued: %s",
+						alGetString(error));
+					ALmixer_SetError("Failed detecting still queued buffers: %s",
+						alGetString(error) );
+					retval = -1;
+				}
+				alGetSourcei(
+					ALmixer_Channel_List[i].alsource,
+					AL_BUFFERS_PROCESSED, &buffers_processed
+				);
+				if((error = alGetError()) != AL_NO_ERROR)
+				{
+					fprintf(stderr, "17Testing Error with buffers_processed: %s",
+						alGetString(error));
+					ALmixer_SetError("Failed detecting still processed buffers: %s",
+						alGetString(error) );
+					retval = -1;
+				}
+				/* If either of these is greater than 0, it means we need
+				 * to clear the source
+				 */
+				if((buffers_still_queued > 0) || (buffers_processed > 0))
+				{
+					alSourcei(ALmixer_Channel_List[i].alsource,
+						AL_BUFFER,
+						AL_NONE);
+					if((error = alGetError()) != AL_NO_ERROR)
+					{
+						fprintf(stderr, "17Testing Error with clearing buffer from source: %s",
+							alGetString(error));
+						ALmixer_SetError("Failed to clear buffer from source: %s",
+							alGetString(error) );
+						retval = -1;
+					}
+				}
+				
+				ALmixer_Channel_List[i].almixer_data->num_buffers_in_use  = 0;
+
+	fprintf(stderr, "Clean channel %d\n", i);
+				Clean_Channel(i);
+				Is_Playing_global--;
+				/* Launch callback for consistency? */
+	fprintf(stderr, "Callback%d\n", i);
+				Invoke_Channel_Done_Callback(i, did_finish_naturally);
+
+				/* Increment the counter */
+				counter++;
+			}
+			/* Let's halt everything just in case there 
+			 * are bugs.
+			 */
+			/*
+			else
+			{
+				alSourceStop(ALmixer_Channel_List[channel].alsource);
+				/ * Can't clean because the in_use counter for
+				 * data will get messed up * /
+				Clean_Channel(channel);
+			}
+			*/
+			/* Just in case */
+			Is_Playing_global = 0;
+		}
+	}
+	if(-1 == retval)
+	{		
+		return -1;	
+	}
+	return counter;
+}
+
+
+/* Will return the source halted or the total number of channels
+ * if all were halted or 0 for error
+ */
+static ALint Internal_HaltSource(ALuint source, ALboolean did_finish_naturally)
+{
+	ALint channel;
+	if(0 == source)
+	{
+		/* Will return the number of sources halted */
+		return Internal_HaltChannel(-1, did_finish_naturally);
+	}
+	
+	channel = Internal_GetChannel(source);
+	if(-1 == channel)
+	{
+		ALmixer_SetError("Cannot halt source: %s", ALmixer_GetError());
+		return -1;
+	}
+	return Internal_HaltChannel(channel, did_finish_naturally);
+}
+
+
 
 /* Note: Behaves, almost like SDL_mixer, but keep in mind
  * that there is no "music" channel anymore, so 0
@@ -1505,7 +1906,7 @@
  * GenSources, but reversing the damage is too painful
  * for me to think about at the moment, so it's not in here.
  */
-static Sint32 Internal_AllocateChannels(Sint32 numchans)
+static ALint Internal_AllocateChannels(ALint numchans)
 {
 	ALenum error;
 	int i;
@@ -1541,7 +1942,7 @@
 	if((error = alGetError()) != AL_NO_ERROR)
 	{
 		fprintf(stderr, "12Testing errpr before unqueue because getting stuff, for OS X this is expected: %s\n",
-			aluGetErrorString(error));				
+			alGetString(error));				
 	}
 			/* Copy the source so the SourceMap has it too */
 			Source_Map_List[i].source = ALmixer_Channel_List[i].alsource;
@@ -1565,14 +1966,14 @@
 		for(i=numchans; i<Number_of_Channels_global; i++)
 		{
 			/* Halt the channel */
-			ALmixer_HaltChannel(i);
+			Internal_HaltChannel(i, AL_FALSE);
 
 			/* Delete source associated with the channel */
 			alDeleteSources(1, &ALmixer_Channel_List[i].alsource);
 	if((error = alGetError()) != AL_NO_ERROR)
 	{
 		fprintf(stderr, "13Testing error: %s\n",
-			aluGetErrorString(error));				
+			alGetString(error));				
 	}
 		}
 
@@ -1603,7 +2004,7 @@
 	
 }
 	
-static Sint32 Internal_ReserveChannels(Sint32 num)
+static ALint Internal_ReserveChannels(ALint num)
 {
 	/* Can't reserve more than the max num of channels */
 	/* Actually, I'll allow it for people who just want to
@@ -1621,662 +2022,16 @@
 }
 	
 
-
-
-
-static Sint32 Internal_PlayChannelTimed(Sint32 channel, ALmixer_Data* data, Sint32 loops, Sint32 ticks)
-{
-	ALenum error;
-	int ret_flag = 0;
-	if(NULL == data)
-	{
-		ALmixer_SetError("Can't play because data is NULL\n");
-		return -1;
-	}
-
-	/* There isn't a good way to share streamed files because
-	 * the decoded data doesn't stick around. 
-	 * You must "Load" a brand new instance of
-	 * the data. If you try using the same data,
-	 * bad things may happen. This check will attempt
-	 * to prevent sharing
-	 */
-	if(0 == data->decoded_all)
-	{
-		if(data->in_use)
-		{
-			ALmixer_SetError("Can't play shared streamed sample because it is already in use");
-			return -1;
-		}
-
-		/* Make sure SDL_sound sample is not at EOF.
-		 * This mainly affects streamed files,
-	 	 * so the check is placed here
-		 */
-		if(data->eof)
-		{
-			if( -1 == ALmixer_RewindData(data) )
-			{
-				ALmixer_SetError("Can't play sample because it is at EOF and cannot rewind");
-				return -1;
-			}
-		}
-	}
-	/* We need to provide the user with the first available channel */
-	if(-1 == channel)
-	{
-		Sint32 i;
-		for(i=Number_of_Reserve_Channels_global; i<Number_of_Channels_global; i++)
-		{
-			if(0 == ALmixer_Channel_List[i].channel_in_use)
-			{
-				channel = i;
-				break;
-			}
-		}
-		/* if we couldn't find a channel, return an error */
-		if(i == Number_of_Channels_global)
-		{
-			ALmixer_SetError("No channels available for playing");
-			return -1;
-		}
-	}
-	/* If we didn't assign the channel number, make sure it's not
-	 * out of bounds or in use */
-	else
-	{
-		if(channel >= Number_of_Channels_global)
-		{
-			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);
-			return -1;
-		}
-		else if(ALmixer_Channel_List[channel].channel_in_use)
-		{
-			ALmixer_SetError("Requested channel (%d) is in use", channel, Number_of_Channels_global-1, Number_of_Channels_global);
-			return -1;
-		}	
-	}
-	/* Make sure the user doesn't enter some meaningless value */
-	if(loops < -1)
-	{
-		loops = -1;
-	}
-							
-	/* loops will probably have to change to be controlled by SDL_Sound */
-
-	/* Set up the initial values for playing */
-	ALmixer_Channel_List[channel].channel_in_use = 1;
-	data->in_use++;
-		
-	/* Shouldn't need updating until a callback is fired
-	 * (assuming that we call Play in this function 
-	 */
-	ALmixer_Channel_List[channel].needs_stream = 0;
-	ALmixer_Channel_List[channel].almixer_data = data;
-	ALmixer_Channel_List[channel].start_time = SDL_GetTicks();
-
-	/* If user entered -1 (or less), set to -1 */
-	if(ticks < 0)
-	{
-		ALmixer_Channel_List[channel].expire_ticks = -1;
-	}
-	else
-	{
-		ALmixer_Channel_List[channel].expire_ticks = ticks;
-	}
-
-	
-	ALmixer_Channel_List[channel].halted = 0;
-	ALmixer_Channel_List[channel].paused = 0;
-
-	/* Ran just use OpenAL to control loops if predecoded and infinite */
-	ALmixer_Channel_List[channel].loops = loops; 
-	if( (-1 == loops) && (data->decoded_all) )
-	{
-		alSourcei(ALmixer_Channel_List[channel].alsource, AL_LOOPING, AL_TRUE);
-	}
-	else
-	{
-		alSourcei(ALmixer_Channel_List[channel].alsource, AL_LOOPING, AL_FALSE);
-	}
-	if((error = alGetError()) != AL_NO_ERROR)
-	{
-		fprintf(stderr, "13Testing error: %s\n",
-			aluGetErrorString(error));				
-	}
-
-#if 0
-	/* Because of the corner case, predecoded
-	 * files must add +1 to the loops.
-	 * Streams do not have this problem
-	 * because they can use the eof flag to 
-	 * avoid the conflict.
-	 * Sharing data chunks prevents the use of the eof flag.
-	 * Since streams, cannot share, only predecoded
-	 * files are affected 
-	 */
-	if(data->decoded_all)
-	{
-		/* Corner Case: Now that play calls are pushed
-		 * off to update(), the start call must
-		 * also come through here. So, start loops
-		 * must be +1 
-		 */
-		if(-1 == loops)
-		{
-			/* -1 is a special case, and you don't want
-			 * to add +1 to it */
-			ALmixer_Channel_List[channel].loops = -1;
-			alSourcei(ALmixer_Channel_List[channel].alsource, AL_LOOPING, AL_TRUE);
-		}
-		else
-		{
-			ALmixer_Channel_List[channel].loops = loops+1;
-			alSourcei(ALmixer_Channel_List[channel].alsource, AL_LOOPING, AL_FALSE);
-		}
-	}
-	else
-	{
-		ALmixer_Channel_List[channel].loops = loops;
-		/* Can we really loop on streamed data? */
-		alSourcei(ALmixer_Channel_List[channel].alsource, AL_LOOPING, AL_TRUE);
-	}
-#endif
-
-	/* Should I start playing here or pass the buck to update? */
-	/* Unlike SDL_SoundMixer, I think I'll do it here because
-	 * this library isn't a *total* hack and OpenAL has more 
-	 * built in functionality I need, so less needs to be 
-	 * controlled and directed through the update function.
-	 * The downside is less functionality is centralized.
-	 * The upside is that the update function should be
-	 * easier to maintain.
-	 */
-
-	/* Clear the error flag */
-	alGetError();
-	if(data->decoded_all)
-	{
-		/* Bind the data to the source */
-		alSourcei(
-			ALmixer_Channel_List[channel].alsource, 
-			AL_BUFFER, 
-			data->buffer[0]);
-		if((error = alGetError()) != AL_NO_ERROR)
-		{
-			ALmixer_SetError("Could not bind data to source: %s",
-				aluGetErrorString(error) );
-			Clean_Channel(channel);
-			return -1;
-		}
-
-		/* Make data available if access_data is enabled */
-		Invoke_Predecoded_Channel_Data_Callback(channel, data);
-	}
-	else
-	{
-		/* Need to use the streaming buffer for binding */
-
-		Uint32 bytes_returned;
-		Uint32 j;
-		data->num_buffers_in_use=0;
-/****** MODIFICATION must go here *********/
-		/* Since buffer queuing is pushed off until here to 
-		 * avoid buffer conflicts, we must start reading 
-		 * data here. First we make sure we have at least one
-		 * packet. Then we queue up until we hit our limit.
-		 */
-		bytes_returned = GetMoreData(
-			data,
-			data->buffer[0]);
-		if(0 == bytes_returned)
-		{
-			/* No data or error */
-			ALmixer_SetError("Could not get data for streamed PlayChannel: %s", ALmixer_GetError());
-			Clean_Channel(channel);
-			return -1;
-		}
-		/* Increment the number of buffers in use */
-		data->num_buffers_in_use++;
-		
-
-		/* Now we need to fill up the rest of the buffers.
-		 * There is a corner case where we run out of data
-		 * before the last buffer is filled.
-		 * Stop conditions are we run out of 
-		 * data or we max out our preload buffers.
-		 */
-			
-	fprintf(stderr, "Filling buffer #%d (AL id is %d)\n", 0, data->buffer[0]);
-		for(j=1; j<data->num_startup_buffers; j++)
-		{
-	fprintf(stderr, "Filling buffer #%d (AL id is %d)\n", j, data->buffer[j]);
-	/*
-	fprintf(stderr, ">>>>>>>>>>>>>>>>>>HACK for GetMoreData2\n");
-	*/
-		bytes_returned = GetMoreData(
-				data,
-				data->buffer[j]);
-		/* 
-		 * This might be a problem. I made a mistake with the types. I accidentally
-		 * made the bytes returned an Sint32 and returned -1 on error.
-		 * Bytes returned should be a Uint32, so now I no longer have a -1 case
-		 * to check. I hope I didn't break anything here
-		 */
-		#if 0
-			if(bytes_returned < 0)
-			{
-				/* Error found */
-				ALmixer_SetError("Could not get data for additional startup buffers for PlayChannel: %s", ALmixer_GetError());
-				/* We'll continue on because we do have some valid data */
-				ret_flag = -1;
-				break;
-			}
-			else if(0 == bytes_returned)
-		#endif
-			if(0 == bytes_returned)
-			{
-				/* No more data to buffer */
-				/* Check for loops */
-				if( ALmixer_Channel_List[channel].loops != 0 )
-				{
-fprintf(stderr, "Need to rewind. In RAMPUP, handling loop\n");
-					if(0 == Sound_Rewind(data->sample))
-					{
-fprintf(stderr, "error in rewind\n"); 
-						ALmixer_SetError( Sound_GetError() );
-						ALmixer_Channel_List[channel].loops = 0;
-						ret_flag = -1;
-						/* We'll continue on because we do have some valid data */
-						break;
-					}
-					/* Remember to reset the data->eof flag */
-					data->eof = 0;
-					if(ALmixer_Channel_List[channel].loops > 0)
-					{
-						ALmixer_Channel_List[channel].loops--;
-fprintf(stderr, "Inside 000 >>>>>>>>>>Loops=%d\n", ALmixer_Channel_List[channel].loops); 
-					}
-					/* Would like to redo the loop, but due to 
-					 * Sound_Rewind() bugs, we would risk falling 
-					 * into an infinite loop
-					 */
-					bytes_returned = GetMoreData(
-						data,
-						data->buffer[j]);
-					if(bytes_returned <= 0)
-					{
-						ALmixer_SetError("Could not get data: %s", ALmixer_GetError());
-						/* We'll continue on because we do have some valid data */
-						ret_flag = -1;
-						break;
-					}
-				}
-				else
-				{
-					/* No loops to do so quit here */
-					break;
-				}
-			}
-			/* Increment the number of buffers in use */
-			data->num_buffers_in_use++;
-		}
-		/*
-	fprintf(stderr, "In PlayChannel, about to queue: source=%d, num_buffers_in_use=%d\n",
-			ALmixer_Channel_List[channel].alsource, 
-			data->num_buffers_in_use);
-*/
-		
-		alSourceQueueBuffers(
-			ALmixer_Channel_List[channel].alsource, 
-			data->num_buffers_in_use, 
-			data->buffer);
-		if((error = alGetError()) != AL_NO_ERROR)
-		{
-			ALmixer_SetError("Could not bind data to source: %s",
-				aluGetErrorString(error) );
-			Clean_Channel(channel);
-			return -1;
-		}
-		/* This is part of the hideous Nvidia workaround. In order to figure out
-		 * which buffer to show during callbacks (for things like
-		 * o-scopes), I must keep a copy of the buffers that are queued in my own
-		 * data structure. This code will be called only if
-		 * "access_data" was set, indicated by whether the queue is NULL.
-		 */
-		if(data->circular_buffer_queue != NULL)
-		{
-			Uint32 k;
-			Uint32 queue_ret_flag;
-			for(k=0; k<data->num_buffers_in_use; k++)
-			{
-				queue_ret_flag = CircularQueueUnsignedInt_PushBack(data->circular_buffer_queue, data->buffer[k]);
-				if(0 == queue_ret_flag)
-				{
-					fprintf(stderr, "Serious internal error: CircularQueue could not push into queue.\n");
-					ALmixer_SetError("Serious internal error: CircularQueue failed to push into queue");
-				}
-				/*
-				else
-				{
-					fprintf(stderr, "Queue in PlayTimed\n");
-					CircularQueueUnsignedInt_Print(data->circular_buffer_queue);
-				}
-				 */
-			}
-		}
-				
-		
-/****** END **********/
-	}
-	/* We have finished loading the data (predecoded or queued)
-	 * so now we can play 
-	 */
-	alSourcePlay(ALmixer_Channel_List[channel].alsource);
-	if((error = alGetError()) != AL_NO_ERROR)
-	{
-		ALmixer_SetError("Play failed: %s",
-			aluGetErrorString(error) );
-		Clean_Channel(channel);
-		return -1;
-	}
-
-	/* Add to the counter that something is playing */
-	Is_Playing_global++;
-	if(-1 == ret_flag)
-	{
-			fprintf(stderr, "BACKDOOR ERROR >>>>>>>>>>>>>>>>>>\n");
-		return -1;
-	}
-	return channel;
-}
-
-
-/* In case the user wants to specify a source instead of a channel,
- * they may use this function. This function will look up the 
- * source-to-channel map, and convert the call into a
- * PlayChannelTimed() function call.
- * Returns the channel it's being played on.
- * Note: If you are prefer this method, then you need to be careful
- * about using PlayChannel, particularly if you request the
- * first available channels because source and channels have 
- * a one-to-one mapping in this API. It is quite easy for 
- * a channel/source to already be in use because of this.
- * In this event, an error message will be returned to you.
- */
-static ALuint Internal_PlaySourceTimed(ALuint source, ALmixer_Data* data, Sint32 loops, Sint32 ticks)
-{
-	Sint32 channel;
-	Sint32 retval;
-	if(0 == source)
-	{
-		retval = Internal_PlayChannelTimed(-1, data, loops, ticks);
-		if(-1 == retval)
-		{
-			return 0;
-		}
-		else
-		{
-			return Internal_GetSource(retval);
-		}
-	}
-	
-	channel = Internal_GetChannel(source);
-	if(-1 == channel)
-	{
-		ALmixer_SetError("Cannot Play source: %s", ALmixer_GetError());
-		return 0;
-	}
-	retval = Internal_PlayChannelTimed(channel, data, loops, ticks);
-	if(-1 == retval)
-	{
-		return 0;
-	}
-	else
-	{
-		return source;
-	}
-	/* make compiler happy */
-	return 0;
-}
-
-
-
-/* Will return the number of channels halted
- * or 0 for error
- */
-static Sint32 Internal_HaltChannel(Sint32 channel)
-{
-	Sint32 retval = 0;
-	Sint32 counter = 0;
-	ALenum error;
-	ALint buffers_still_queued;
-	ALint buffers_processed;
-
-	if(channel >= Number_of_Channels_global)
-	{
-		ALmixer_SetError("Cannot halt channel %d because it exceeds maximum number of channels (%d)\n", channel, Number_of_Channels_global);
-		return -1;
-	}
-	/* If the user specified a specific channel */
-	if(channel >= 0)
-	{
-		fprintf(stderr, "Halt on channel %d\n", channel);
-		/* only need to process channel if in use */
-		if(ALmixer_Channel_List[channel].channel_in_use)
-		{
-			alSourceStop(ALmixer_Channel_List[channel].alsource);
-			if((error = alGetError()) != AL_NO_ERROR)
-			{
-				fprintf(stderr, "14Testing error: %s\n",
-					aluGetErrorString(error));				
-			}
-			/* Here's the situation. My old method of using
-			 * alSourceUnqueueBuffers() seemed to be invalid in light
-			 * of all the problems I suffered through with getting 
-			 * the CoreData backend to work with this code.
-			 * As such, I'm changing all the code to set the buffer to
-			 * AL_NONE. Furthermore, the queued vs. non-queued issue
-			 * doesn't need to apply here. For non-queued, Loki,
-			 * Creative Windows, and CoreAudio seem to leave the 
-			 * buffer queued (Old Mac didn't.) For queued, we need to 
-			 * remove the processed buffers and force remove the
-			 * still-queued buffers.
-			 */
-			fprintf(stderr, "Halt on channel %d, channel in use\n", channel);
-			alGetSourcei(
-				ALmixer_Channel_List[channel].alsource,
-				AL_BUFFERS_QUEUED, &buffers_still_queued
-			);
-			if((error = alGetError()) != AL_NO_ERROR)
-			{
-				fprintf(stderr, "17Testing Error with buffers_still_queued: %s",
-					aluGetErrorString(error));
-				ALmixer_SetError("Failed detecting still queued buffers: %s",
-					aluGetErrorString(error) );
-				retval = -1;
-			}
-			alGetSourcei(
-				ALmixer_Channel_List[channel].alsource,
-				AL_BUFFERS_PROCESSED, &buffers_processed
-			);
-			if((error = alGetError()) != AL_NO_ERROR)
-			{
-				fprintf(stderr, "17Testing Error with buffers_processed: %s",
-					aluGetErrorString(error));
-				ALmixer_SetError("Failed detecting still processed buffers: %s",
-					aluGetErrorString(error) );
-				retval = -1;
-			}
-			/* If either of these is greater than 0, it means we need
-			 * to clear the source
-			 */
-			if((buffers_still_queued > 0) || (buffers_processed > 0))
-			{
-				alSourcei(ALmixer_Channel_List[channel].alsource,
-					AL_BUFFER,
-					AL_NONE);
-				if((error = alGetError()) != AL_NO_ERROR)
-				{
-					fprintf(stderr, "17Testing Error with clearing buffer from source: %s",
-						aluGetErrorString(error));
-					ALmixer_SetError("Failed to clear buffer from source: %s",
-						aluGetErrorString(error) );
-					retval = -1;
-				}
-			}
-
-			ALmixer_Channel_List[channel].almixer_data->num_buffers_in_use  = 0;
-
-			Clean_Channel(channel);
-			Is_Playing_global--;
-			/* Launch callback for consistency? */
-			Invoke_Channel_Done_Callback(channel);
-			counter++;
-		}
-	}
-	/* The user wants to halt all channels */
-	else
-	{
-		Sint32 i;
-		for(i=0; i<Number_of_Channels_global; i++)
-		{
-			fprintf(stderr, "Halting channel %d\n", i);
-			fprintf(stderr, "in use %d\n", ALmixer_Channel_List[i].channel_in_use );
-			/* only need to process channel if in use */
-			if(ALmixer_Channel_List[i].channel_in_use)
-			{
-				fprintf(stderr, "SourceStop %d\n", i);
-				alSourceStop(ALmixer_Channel_List[i].alsource);
-				if((error = alGetError()) != AL_NO_ERROR)
-				{
-					fprintf(stderr, "19Testing error: %s\n",
-						aluGetErrorString(error));				
-				}
-
-				/* Here's the situation. My old method of using
-				 * alSourceUnqueueBuffers() seemed to be invalid in light
-				 * of all the problems I suffered through with getting 
-				 * the CoreData backend to work with this code.
-				 * As such, I'm changing all the code to set the buffer to
-				 * AL_NONE. Furthermore, the queued vs. non-queued issue
-				 * doesn't need to apply here. For non-queued, Loki,
-				 * Creative Windows, and CoreAudio seem to leave the 
-				 * buffer queued (Old Mac didn't.) For queued, we need to 
-				 * remove the processed buffers and force remove the
-				 * still-queued buffers.
-				 */
-				fprintf(stderr, "Halt on channel %d, channel in use\n", channel);
-				alGetSourcei(
-					ALmixer_Channel_List[i].alsource,
-					AL_BUFFERS_QUEUED, &buffers_still_queued
-				);
-				if((error = alGetError()) != AL_NO_ERROR)
-				{
-					fprintf(stderr, "17Testing Error with buffers_still_queued: %s",
-						aluGetErrorString(error));
-					ALmixer_SetError("Failed detecting still queued buffers: %s",
-						aluGetErrorString(error) );
-					retval = -1;
-				}
-				alGetSourcei(
-					ALmixer_Channel_List[i].alsource,
-					AL_BUFFERS_PROCESSED, &buffers_processed
-				);
-				if((error = alGetError()) != AL_NO_ERROR)
-				{
-					fprintf(stderr, "17Testing Error with buffers_processed: %s",
-						aluGetErrorString(error));
-					ALmixer_SetError("Failed detecting still processed buffers: %s",
-						aluGetErrorString(error) );
-					retval = -1;
-				}
-				/* If either of these is greater than 0, it means we need
-				 * to clear the source
-				 */
-				if((buffers_still_queued > 0) || (buffers_processed > 0))
-				{
-					alSourcei(ALmixer_Channel_List[i].alsource,
-						AL_BUFFER,
-						AL_NONE);
-					if((error = alGetError()) != AL_NO_ERROR)
-					{
-						fprintf(stderr, "17Testing Error with clearing buffer from source: %s",
-							aluGetErrorString(error));
-						ALmixer_SetError("Failed to clear buffer from source: %s",
-							aluGetErrorString(error) );
-						retval = -1;
-					}
-				}
-				
-				ALmixer_Channel_List[i].almixer_data->num_buffers_in_use  = 0;
-
-	fprintf(stderr, "Clean channel %d\n", i);
-				Clean_Channel(i);
-				Is_Playing_global--;
-				/* Launch callback for consistency? */
-	fprintf(stderr, "Callback%d\n", i);
-				Invoke_Channel_Done_Callback(i);
-
-				/* Increment the counter */
-				counter++;
-			}
-			/* Let's halt everything just in case there 
-			 * are bugs.
-			 */
-			/*
-			else
-			{
-				alSourceStop(ALmixer_Channel_List[channel].alsource);
-				/ * Can't clean because the in_use counter for
-				 * data will get messed up * /
-				Clean_Channel(channel);
-			}
-			*/
-			/* Just in case */
-			Is_Playing_global = 0;
-		}
-	}
-	if(-1 == retval)
-	{		
-		return -1;	
-	}
-	return counter;
-}
-
-
-/* Will return the source halted or the total number of channels
- * if all were halted or 0 for error
- */
-static Sint32 Internal_HaltSource(ALuint source)
-{
-	Sint32 channel;
-	if(0 == source)
-	{
-		/* Will return the number of sources halted */
-		return Internal_HaltChannel(-1);
-	}
-	
-	channel = Internal_GetChannel(source);
-	if(-1 == channel)
-	{
-		ALmixer_SetError("Cannot halt source: %s", ALmixer_GetError());
-		return 0;
-	}
-	return Internal_HaltChannel(channel);
-}
-
-
 /* This will rewind the SDL_Sound sample for streamed
  * samples and start buffering up the data for the next
  * playback. This may require samples to be halted
  */
-static Sint32 Internal_RewindData(ALmixer_Data* data)
-{
-	Sint32 retval = 0;
+static ALint Internal_RewindData(ALmixer_Data* data)
+{
+	ALint retval = 0;
 	/*
-	Sint32 bytes_returned;
-	Sint32 i;
+	ALint bytes_returned;
+	ALint i;
 	*/
 	if(NULL == data)
 	{
@@ -2383,9 +2138,9 @@
 
 
 
-static Sint32 Internal_RewindChannel(Sint32 channel)
-{
-	Sint32 retval = 0;
+static ALint Internal_RewindChannel(ALint channel)
+{
+	ALint retval = 0;
 	ALenum error;
 	ALint state;
 
@@ -2398,7 +2153,7 @@
 	if((error = alGetError()) != AL_NO_ERROR)
 	{
 		fprintf(stderr, "24Testing error: %s\n",
-			aluGetErrorString(error));				
+			alGetString(error));				
 	}
 	/* Clear error */
 	alGetError();
@@ -2424,13 +2179,13 @@
 	if((error = alGetError()) != AL_NO_ERROR)
 	{
 		fprintf(stderr, "25Testing error: %s\n",
-			aluGetErrorString(error));				
+			alGetString(error));				
 	}
 				alSourceRewind(ALmixer_Channel_List[channel].alsource);
 				if((error = alGetError()) != AL_NO_ERROR)
 				{
 					ALmixer_SetError("%s",
-						aluGetErrorString(error) );
+						alGetString(error) );
 					retval = -1;
 				}
 				/* Need to resume playback if it was originally playing */
@@ -2440,7 +2195,7 @@
 					if((error = alGetError()) != AL_NO_ERROR)
 					{
 						ALmixer_SetError("%s",
-							aluGetErrorString(error) );
+							alGetString(error) );
 						retval = -1;
 					}
 				}
@@ -2454,13 +2209,13 @@
 	if((error = alGetError()) != AL_NO_ERROR)
 	{
 		fprintf(stderr, "25Testing error: %s\n",
-			aluGetErrorString(error));				
+			alGetString(error));				
 	}
 					alSourcePause(ALmixer_Channel_List[channel].alsource);
 					if((error = alGetError()) != AL_NO_ERROR)
 					{
 						ALmixer_SetError("%s",
-							aluGetErrorString(error) );
+							alGetString(error) );
 						retval = -1;
 					}
 				}
@@ -2477,10 +2232,10 @@
 			}
 		}
 	}
-	/* The user wants to halt all channels */
+	/* The user wants to rewind all channels */
 	else
 	{
-		Sint32 i;
+		ALint i;
 		for(i=0; i<Number_of_Channels_global; i++)
 		{
 	fprintf(stderr, "in use %d\n", ALmixer_Channel_List[i].channel_in_use );
@@ -2501,13 +2256,13 @@
 	if((error = alGetError()) != AL_NO_ERROR)
 	{
 		fprintf(stderr, "26Testing error: %s\n",
-			aluGetErrorString(error));				
+			alGetString(error));				
 	}
 					alSourceRewind(ALmixer_Channel_List[i].alsource);
 					if((error = alGetError()) != AL_NO_ERROR)
 					{
 						ALmixer_SetError("%s",
-							aluGetErrorString(error) );
+							alGetString(error) );
 						retval = -1;
 					}
 					/* Need to resume playback if it was originally playing */
@@ -2517,7 +2272,7 @@
 						if((error = alGetError()) != AL_NO_ERROR)
 						{
 							ALmixer_SetError("%s",
-								aluGetErrorString(error) );
+								alGetString(error) );
 							retval = -1;
 						}
 					}
@@ -2531,13 +2286,13 @@
 	if((error = alGetError()) != AL_NO_ERROR)
 	{
 		fprintf(stderr, "27Testing error: %s\n",
-			aluGetErrorString(error));				
+			alGetString(error));				
 	}
 						alSourcePause(ALmixer_Channel_List[i].alsource);
 						if((error = alGetError()) != AL_NO_ERROR)
 						{
 							ALmixer_SetError("%s",
-								aluGetErrorString(error) );
+								alGetString(error) );
 							retval = -1;
 						}
 					}
@@ -2559,12 +2314,12 @@
 }
 
 
-static Sint32 Internal_RewindSource(ALuint source)
-{
-	Sint32 channel;
+static ALint Internal_RewindSource(ALuint source)
+{
+	ALint channel;
 	if(0 == source)
 	{
-		return Internal_RewindChannel(-1);
+		return Internal_RewindChannel(-1) + 1;
 	}
 	
 	channel = Internal_GetChannel(source);
@@ -2573,19 +2328,441 @@
 		ALmixer_SetError("Cannot rewind source: %s", ALmixer_GetError());
 		return 0;
 	}
-	return Internal_RewindChannel(channel);
-}
+	return Internal_RewindChannel(channel) + 1;
+}
+
+
+
+
+
+static ALint Internal_PlayChannelTimed(ALint channel, ALmixer_Data* data, ALint loops, ALint ticks)
+{
+	ALenum error;
+	int ret_flag = 0;
+	if(NULL == data)
+	{
+		ALmixer_SetError("Can't play because data is NULL\n");
+		return -1;
+	}
+
+	/* There isn't a good way to share streamed files because
+	 * the decoded data doesn't stick around. 
+	 * You must "Load" a brand new instance of
+	 * the data. If you try using the same data,
+	 * bad things may happen. This check will attempt
+	 * to prevent sharing
+	 */
+	if(0 == data->decoded_all)
+	{
+		if(data->in_use)
+		{
+			ALmixer_SetError("Can't play shared streamed sample because it is already in use");
+			return -1;
+		}
+
+		/* Make sure SDL_sound sample is not at EOF.
+		 * This mainly affects streamed files,
+	 	 * so the check is placed here
+		 */
+		if(data->eof)
+		{
+			if( -1 == Internal_RewindData(data) )
+			{
+				ALmixer_SetError("Can't play sample because it is at EOF and cannot rewind");
+				return -1;
+			}
+		}
+	}
+	/* We need to provide the user with the first available channel */
+	if(-1 == channel)
+	{
+		ALint i;
+		for(i=Number_of_Reserve_Channels_global; i<Number_of_Channels_global; i++)
+		{
+			if(0 == ALmixer_Channel_List[i].channel_in_use)
+			{
+				channel = i;
+				break;
+			}
+		}
+		/* if we couldn't find a channel, return an error */
+		if(i == Number_of_Channels_global)
+		{
+			ALmixer_SetError("No channels available for playing");
+			return -1;
+		}
+	}
+	/* If we didn't assign the channel number, make sure it's not
+	 * out of bounds or in use */
+	else
+	{
+		if(channel >= Number_of_Channels_global)
+		{
+			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);
+			return -1;
+		}
+		else if(ALmixer_Channel_List[channel].channel_in_use)
+		{
+			ALmixer_SetError("Requested channel (%d) is in use", channel, Number_of_Channels_global-1, Number_of_Channels_global);
+			return -1;
+		}	
+	}
+	/* Make sure the user doesn't enter some meaningless value */
+	if(loops < -1)
+	{
+		loops = -1;
+	}
+							
+	/* loops will probably have to change to be controlled by SDL_Sound */
+
+	/* Set up the initial values for playing */
+	ALmixer_Channel_List[channel].channel_in_use = 1;
+	data->in_use++;
+		
+	/* Shouldn't need updating until a callback is fired
+	 * (assuming that we call Play in this function 
+	 */
+	ALmixer_Channel_List[channel].needs_stream = 0;
+	ALmixer_Channel_List[channel].almixer_data = data;
+	ALmixer_Channel_List[channel].start_time = ALmixer_GetTicks();
+
+	/* If user entered -1 (or less), set to -1 */
+	if(ticks < 0)
+	{
+		ALmixer_Channel_List[channel].expire_ticks = -1;
+	}
+	else
+	{
+		ALmixer_Channel_List[channel].expire_ticks = ticks;
+	}
+
+	
+	ALmixer_Channel_List[channel].halted = 0;
+	ALmixer_Channel_List[channel].paused = 0;
+
+	/* Ran just use OpenAL to control loops if predecoded and infinite */
+	ALmixer_Channel_List[channel].loops = loops; 
+	if( (-1 == loops) && (data->decoded_all) )
+	{
+		alSourcei(ALmixer_Channel_List[channel].alsource, AL_LOOPING, AL_TRUE);
+	}
+	else
+	{
+		alSourcei(ALmixer_Channel_List[channel].alsource, AL_LOOPING, AL_FALSE);
+	}
+	if((error = alGetError()) != AL_NO_ERROR)
+	{
+		fprintf(stderr, "13Testing error: %s\n",
+			alGetString(error));				
+	}
+
+#if 0
+	/* Because of the corner case, predecoded
+	 * files must add +1 to the loops.
+	 * Streams do not have this problem
+	 * because they can use the eof flag to 
+	 * avoid the conflict.
+	 * Sharing data chunks prevents the use of the eof flag.
+	 * Since streams, cannot share, only predecoded
+	 * files are affected 
+	 */
+	if(data->decoded_all)
+	{
+		/* Corner Case: Now that play calls are pushed
+		 * off to update(), the start call must
+		 * also come through here. So, start loops
+		 * must be +1 
+		 */
+		if(-1 == loops)
+		{
+			/* -1 is a special case, and you don't want
+			 * to add +1 to it */
+			ALmixer_Channel_List[channel].loops = -1;
+			alSourcei(ALmixer_Channel_List[channel].alsource, AL_LOOPING, AL_TRUE);
+		}
+		else
+		{
+			ALmixer_Channel_List[channel].loops = loops+1;
+			alSourcei(ALmixer_Channel_List[channel].alsource, AL_LOOPING, AL_FALSE);
+		}
+	}
+	else
+	{
+		ALmixer_Channel_List[channel].loops = loops;
+		/* Can we really loop on streamed data? */
+		alSourcei(ALmixer_Channel_List[channel].alsource, AL_LOOPING, AL_TRUE);
+	}
+#endif
+
+	/* Should I start playing here or pass the buck to update? */
+	/* Unlike SDL_SoundMixer, I think I'll do it here because
+	 * this library isn't a *total* hack and OpenAL has more 
+	 * built in functionality I need, so less needs to be 
+	 * controlled and directed through the update function.
+	 * The downside is less functionality is centralized.
+	 * The upside is that the update function should be
+	 * easier to maintain.
+	 */
+
+	/* Clear the error flag */
+	alGetError();
+	if(data->decoded_all)
+	{
+		/* Bind the data to the source */
+		alSourcei(
+			ALmixer_Channel_List[channel].alsource, 
+			AL_BUFFER, 
+			data->buffer[0]);
+		if((error = alGetError()) != AL_NO_ERROR)
+		{
+			ALmixer_SetError("Could not bind data to source: %s",
+				alGetString(error) );
+			Clean_Channel(channel);
+			return -1;
+		}
+
+		/* Make data available if access_data is enabled */
+		Invoke_Predecoded_Channel_Data_Callback(channel, data);
+	}
+	else
+	{
+		/* Need to use the streaming buffer for binding */
+
+		ALuint bytes_returned;
+		ALuint j;
+		data->num_buffers_in_use=0;
+/****** MODIFICATION must go here *********/
+		/* Since buffer queuing is pushed off until here to 
+		 * avoid buffer conflicts, we must start reading 
+		 * data here. First we make sure we have at least one
+		 * packet. Then we queue up until we hit our limit.
+		 */
+		bytes_returned = GetMoreData(
+			data,
+			data->buffer[0]);
+		if(0 == bytes_returned)
+		{
+			/* No data or error */
+			ALmixer_SetError("Could not get data for streamed PlayChannel: %s", ALmixer_GetError());
+			Clean_Channel(channel);
+			return -1;
+		}
+		/* Increment the number of buffers in use */
+		data->num_buffers_in_use++;
+		
+
+		/* Now we need to fill up the rest of the buffers.
+		 * There is a corner case where we run out of data
+		 * before the last buffer is filled.
+		 * Stop conditions are we run out of 
+		 * data or we max out our preload buffers.
+		 */
+			
+	fprintf(stderr, "Filling buffer #%d (AL id is %d)\n", 0, data->buffer[0]);
+		for(j=1; j<data->num_startup_buffers; j++)
+		{
+	fprintf(stderr, "Filling buffer #%d (AL id is %d)\n", j, data->buffer[j]);
+	/*
+	fprintf(stderr, ">>>>>>>>>>>>>>>>>>HACK for GetMoreData2\n");
+	*/
+		bytes_returned = GetMoreData(
+				data,
+				data->buffer[j]);
+		/* 
+		 * This might be a problem. I made a mistake with the types. I accidentally
+		 * made the bytes returned an ALint and returned -1 on error.
+		 * Bytes returned should be a ALuint, so now I no longer have a -1 case
+		 * to check. I hope I didn't break anything here
+		 */
+		#if 0
+			if(bytes_returned < 0)
+			{
+				/* Error found */
+				ALmixer_SetError("Could not get data for additional startup buffers for PlayChannel: %s", ALmixer_GetError());
+				/* We'll continue on because we do have some valid data */
+				ret_flag = -1;
+				break;
+			}
+			else if(0 == bytes_returned)
+		#endif
+			if(0 == bytes_returned)
+			{
+				/* No more data to buffer */
+				/* Check for loops */
+				if( ALmixer_Channel_List[channel].loops != 0 )
+				{
+fprintf(stderr, "Need to rewind. In RAMPUP, handling loop\n");
+					if(0 == Sound_Rewind(data->sample))
+					{
+fprintf(stderr, "error in rewind\n"); 
+						ALmixer_SetError( Sound_GetError() );
+						ALmixer_Channel_List[channel].loops = 0;
+						ret_flag = -1;
+						/* We'll continue on because we do have some valid data */
+						break;
+					}
+					/* Remember to reset the data->eof flag */
+					data->eof = 0;
+					if(ALmixer_Channel_List[channel].loops > 0)
+					{
+						ALmixer_Channel_List[channel].loops--;
+fprintf(stderr, "Inside 000 >>>>>>>>>>Loops=%d\n", ALmixer_Channel_List[channel].loops); 
+					}
+					/* Would like to redo the loop, but due to 
+					 * Sound_Rewind() bugs, we would risk falling 
+					 * into an infinite loop
+					 */
+					bytes_returned = GetMoreData(
+						data,
+						data->buffer[j]);
+					if(bytes_returned <= 0)
+					{
+						ALmixer_SetError("Could not get data: %s", ALmixer_GetError());
+						/* We'll continue on because we do have some valid data */
+						ret_flag = -1;
+						break;
+					}
+				}
+				else
+				{
+					/* No loops to do so quit here */
+					break;
+				}
+			}
+			/* Increment the number of buffers in use */
+			data->num_buffers_in_use++;
+		}
+		/*
+	fprintf(stderr, "In PlayChannel, about to queue: source=%d, num_buffers_in_use=%d\n",
+			ALmixer_Channel_List[channel].alsource, 
+			data->num_buffers_in_use);
+*/
+		
+		alSourceQueueBuffers(
+			ALmixer_Channel_List[channel].alsource, 
+			data->num_buffers_in_use, 
+			data->buffer);
+		if((error = alGetError()) != AL_NO_ERROR)
+		{
+			ALmixer_SetError("Could not bind data to source: %s",
+				alGetString(error) );
+			Clean_Channel(channel);
+			return -1;
+		}
+		/* This is part of the hideous Nvidia workaround. In order to figure out
+		 * which buffer to show during callbacks (for things like
+		 * o-scopes), I must keep a copy of the buffers that are queued in my own
+		 * data structure. This code will be called only if
+		 * "access_data" was set, indicated by whether the queue is NULL.
+		 */
+		if(data->circular_buffer_queue != NULL)
+		{
+			ALuint k;
+			ALuint queue_ret_flag;
+			for(k=0; k<data->num_buffers_in_use; k++)
+			{
+//				fprintf(stderr, "56c: CircularQueue_PushBack.\n");
+				queue_ret_flag = CircularQueueUnsignedInt_PushBack(data->circular_buffer_queue, data->buffer[k]);
+				if(0 == queue_ret_flag)
+				{
+					fprintf(stderr, "Serious internal error: CircularQueue could not push into queue.\n");
+					ALmixer_SetError("Serious internal error: CircularQueue failed to push into queue");
+				}
+				/*
+				else
+				{
+					fprintf(stderr, "Queue in PlayTimed\n");
+					CircularQueueUnsignedInt_Print(data->circular_buffer_queue);
+				}
+				 */
+			}
+		}
+				
+		
+/****** END **********/
+	}
+	/* We have finished loading the data (predecoded or queued)
+	 * so now we can play 
+	 */
+	alSourcePlay(ALmixer_Channel_List[channel].alsource);
+	if((error = alGetError()) != AL_NO_ERROR)
+	{
+		ALmixer_SetError("Play failed: %s",
+			alGetString(error) );
+		Clean_Channel(channel);
+		return -1;
+	}
+
+	/* Add to the counter that something is playing */
+	Is_Playing_global++;
+	if(-1 == ret_flag)
+	{
+			fprintf(stderr, "BACKDOOR ERROR >>>>>>>>>>>>>>>>>>\n");
+		return -1;
+	}
+	return channel;
+}
+
+
+/* In case the user wants to specify a source instead of a channel,
+ * they may use this function. This function will look up the 
+ * source-to-channel map, and convert the call into a
+ * PlayChannelTimed() function call.
+ * Returns the channel it's being played on.
+ * Note: If you are prefer this method, then you need to be careful
+ * about using PlayChannel, particularly if you request the
+ * first available channels because source and channels have 
+ * a one-to-one mapping in this API. It is quite easy for 
+ * a channel/source to already be in use because of this.
+ * In this event, an error message will be returned to you.
+ */
+static ALuint Internal_PlaySourceTimed(ALuint source, ALmixer_Data* data, ALint loops, ALint ticks)
+{
+	ALint channel;
+	ALint retval;
+	if(0 == source)
+	{
+		retval = Internal_PlayChannelTimed(-1, data, loops, ticks);
+		if(-1 == retval)
+		{
+			return 0;
+		}
+		else
+		{
+			return Internal_GetSource(retval);
+		}
+	}
+	
+	channel = Internal_GetChannel(source);
+	if(-1 == channel)
+	{
+		ALmixer_SetError("Cannot Play source: %s", ALmixer_GetError());
+		return 0;
+	}
+	retval = Internal_PlayChannelTimed(channel, data, loops, ticks);
+	if(-1 == retval)
+	{
+		return 0;
+	}
+	else
+	{
+		return source;
+	}
+	/* make compiler happy */
+	return 0;
+}
+
 
 
 
 /* Returns the channel or number of channels actually paused */
 
-static Sint32 Internal_PauseChannel(Sint32 channel)
+static ALint Internal_PauseChannel(ALint channel)
 {
 	ALenum error;
 	ALint state;
-	Sint32 retval = 0;
-	Sint32 counter = 0;
+	ALint retval = 0;
+	ALint counter = 0;
 	
 	if(channel >= Number_of_Channels_global)
 	{
@@ -2596,7 +2773,7 @@
 	if((error = alGetError()) != AL_NO_ERROR)
 	{
 		fprintf(stderr, "28Testing error: %s\n",
-			aluGetErrorString(error));				
+			alGetString(error));				
 	}
 	/* Clear error */
 	alGetError();
@@ -2619,7 +2796,7 @@
 	if((error = alGetError()) != AL_NO_ERROR)
 	{
 		fprintf(stderr, "29Testing error: %s\n",
-			aluGetErrorString(error));				
+			alGetString(error));				
 	}
 			if(AL_PLAYING == state)
 			{
@@ -2630,14 +2807,14 @@
 				if((error = alGetError()) != AL_NO_ERROR)
 				{
 					ALmixer_SetError("%s",
-						aluGetErrorString(error) );
+						alGetString(error) );
 					retval = -1;
 				}
 				/* We need to pause the expire time count down */
 				if(ALmixer_Channel_List[channel].expire_ticks != -1)
 				{
-					Uint32 current_time = SDL_GetTicks();
-					Uint32 diff_time;
+					ALuint current_time = ALmixer_GetTicks();
+					ALuint diff_time;
 					diff_time = current_time - 
 						ALmixer_Channel_List[channel].start_time;
 					/* When we unpause, we will want to reset
@@ -2660,8 +2837,8 @@
 				/* Do the same as expire time for fading */
 				if(ALmixer_Channel_List[channel].fade_enabled)
 				{
-					Uint32 current_time = SDL_GetTicks();
-					Uint32 diff_time;
+					ALuint current_time = ALmixer_GetTicks();
+					ALuint diff_time;
 					diff_time = current_time - 
 						ALmixer_Channel_List[channel].fade_start_time;
 					/* When we unpause, we will want to reset
@@ -2685,7 +2862,7 @@
 	/* The user wants to halt all channels */
 	else
 	{
-		Sint32 i;
+		ALint i;
 		for(i=0; i<Number_of_Channels_global; i++)
 		{
 	fprintf(stderr, "Pausing channel %d\n", i);
@@ -2704,7 +2881,7 @@
 	if((error = alGetError()) != AL_NO_ERROR)
 	{
 		fprintf(stderr, "30Testing error: %s\n",
-			aluGetErrorString(error));				
+			alGetString(error));				
 	}
 				if(AL_PLAYING == state)
 				{
@@ -2716,14 +2893,14 @@
 					if((error = alGetError()) != AL_NO_ERROR)
 					{
 						ALmixer_SetError("%s",
-							aluGetErrorString(error) );
+							alGetString(error) );
 						retval = -1;
 					}
 					/* We need to pause the expire time count down */
 					if(ALmixer_Channel_List[i].expire_ticks != -1)
 					{
-						Uint32 current_time = SDL_GetTicks();
-						Uint32 diff_time;
+						ALuint current_time = ALmixer_GetTicks();
+						ALuint diff_time;
 						diff_time = current_time - 
 							ALmixer_Channel_List[i].start_time;
 						/* When we unpause, we will want to reset
@@ -2746,8 +2923,8 @@
 					/* Do the same as expire time for fading */
 					if(ALmixer_Channel_List[i].fade_enabled)
 					{
-						Uint32 current_time = SDL_GetTicks();
-						Uint32 diff_time;
+						ALuint current_time = ALmixer_GetTicks();
+						ALuint diff_time;
 						diff_time = current_time - 
 							ALmixer_Channel_List[i].fade_start_time;
 						/* When we unpause, we will want to reset
@@ -2777,9 +2954,9 @@
 }
 
 /* Returns the channel or number of channels actually paused */
-static Sint32 Internal_PauseSource(ALuint source)
-{
-	Sint32 channel;
+static ALint Internal_PauseSource(ALuint source)
+{
+	ALint channel;
 	if(0 == source)
 	{
 		return Internal_PauseChannel(-1);
@@ -2796,12 +2973,12 @@
 
 
 
-static Sint32 Internal_ResumeChannel(Sint32 channel)
+static ALint Internal_ResumeChannel(ALint channel)
 {
 	ALint state;
 	ALenum error;
-	Sint32 retval = 0;
-	Sint32 counter = 0;
+	ALint retval = 0;
+	ALint counter = 0;
 	
 	if(channel >= Number_of_Channels_global)
 	{
@@ -2812,7 +2989,7 @@
 	if((error = alGetError()) != AL_NO_ERROR)
 	{
 		fprintf(stderr, "31Testing error: %s\n",
-			aluGetErrorString(error));				
+			alGetString(error));				
 	}
 	/* Clear error */
 	alGetError();
@@ -2831,7 +3008,7 @@
 	if((error = alGetError()) != AL_NO_ERROR)
 	{
 		fprintf(stderr, "32Testing error: %s\n",
-			aluGetErrorString(error));				
+			alGetString(error));				
 	}
 			if(AL_PAUSED == state)
 			{
@@ -2841,19 +3018,19 @@
 				/* We need to resume the expire time count down */
 				if(ALmixer_Channel_List[channel].expire_ticks != -1)
 				{
-					ALmixer_Channel_List[channel].start_time = SDL_GetTicks();
+					ALmixer_Channel_List[channel].start_time = ALmixer_GetTicks();
 				}
 				/* Do the same as expire time for fading */
 				if(ALmixer_Channel_List[channel].fade_enabled)
 				{
-					ALmixer_Channel_List[channel].fade_start_time = SDL_GetTicks();
+					ALmixer_Channel_List[channel].fade_start_time = ALmixer_GetTicks();
 				}	
 
 				alSourcePlay(ALmixer_Channel_List[channel].alsource);
 				if((error = alGetError()) != AL_NO_ERROR)
 				{
 					ALmixer_SetError("%s",
-						aluGetErrorString(error) );
+						alGetString(error) );
 					retval = -1;
 				}
 			}
@@ -2863,7 +3040,7 @@
 	/* The user wants to halt all channels */
 	else
 	{
-		Sint32 i;
+		ALint i;
 		for(i=0; i<Number_of_Channels_global; i++)
 		{
 	fprintf(stderr, "Pausing channel %d\n", i);
@@ -2879,7 +3056,7 @@
 	if((error = alGetError()) != AL_NO_ERROR)
 	{
 		fprintf(stderr, "33Testing error: %s\n",
-			aluGetErrorString(error));				
+			alGetString(error));				
 	}
 				if(AL_PAUSED == state)
 				{
@@ -2889,19 +3066,19 @@
 					/* We need to resume the expire time count down */
 					if(ALmixer_Channel_List[i].expire_ticks != -1)
 					{
-						ALmixer_Channel_List[i].start_time = SDL_GetTicks();
+						ALmixer_Channel_List[i].start_time = ALmixer_GetTicks();
 					}
 					/* Do the same as expire time for fading */
 					if(ALmixer_Channel_List[i].fade_enabled)
 					{
-						ALmixer_Channel_List[i].fade_start_time = SDL_GetTicks();
+						ALmixer_Channel_List[i].fade_start_time = ALmixer_GetTicks();
 					}	
 						
 					alSourcePlay(ALmixer_Channel_List[i].alsource);
 					if((error = alGetError()) != AL_NO_ERROR)
 					{
 						ALmixer_SetError("%s",
-							aluGetErrorString(error) );
+							alGetString(error) );
 						retval = -1;
 					}
 				}
@@ -2916,9 +3093,9 @@
 }
 
 
-static Sint32 Internal_ResumeSource(ALuint source)
-{
-	Sint32 channel;
+static ALint Internal_ResumeSource(ALuint source)
+{
+	ALint channel;
 	if(0 == source)
 	{
 		return Internal_ResumeChannel(-1);
@@ -2937,9 +3114,9 @@
 /* Might consider setting eof to 0 as a "feature"
  * This will allow seek to end to stay there because
  * Play automatically rewinds if at the end */
-static Sint32 Internal_Seek(ALmixer_Data* data, Uint32 msec)
-{
-	Sint32 retval;
+static ALint Internal_SeekData(ALmixer_Data* data, ALuint msec)
+{
+	ALint retval;
 	
 	if(NULL == data)
 	{
@@ -2950,7 +3127,7 @@
 	/* Seek for predecoded files involves moving the chunk pointer around */
 	if(data->decoded_all)
 	{
-		Uint32 byte_position;
+		ALuint byte_position;
 
 		/* OpenAL doesn't seem to like it if I change the buffer
 		 * while playing (crashes), so I must require that Seek only
@@ -3029,13 +3206,13 @@
 		
 
 
-static Sint32 Internal_FadeInChannelTimed(Sint32 channel, ALmixer_Data* data, Sint32 loops, Uint32 fade_ticks, Sint32 expire_ticks)
+static ALint Internal_FadeInChannelTimed(ALint channel, ALmixer_Data* data, ALint loops, ALuint fade_ticks, ALint expire_ticks)
 {
 	ALfloat value;
 	ALenum error;
 	ALfloat original_value;
-	Uint32 current_time = SDL_GetTicks();
-	Sint32 retval;
+	ALuint current_time = ALmixer_GetTicks();
+	ALint retval;
 
 	
 	
@@ -3073,22 +3250,14 @@
 	
 	/* Get the original volume in case of a problem */
 	alGetSourcef(ALmixer_Channel_List[channel].alsource,
-		AL_MAX_GAIN, &original_value);
+		AL_GAIN, &original_value);
 	
 	if((error = alGetError()) != AL_NO_ERROR)
 	{
 		fprintf(stderr, "35Testing error: %s\n",
-			aluGetErrorString(error));				
-	}
-	/* Get the Max volume */
-	/*
-	alGetSourcef(ALmixer_Channel_List[channel].alsource,
-		AL_MAX_GAIN, &value);
-	ALmixer_Channel_List[channel].fade_end_volume = value;
-	fprintf(stderr, "MAX gain: %f\n", value);
-	*/
-	ALmixer_Channel_List[channel].fade_end_volume = 
-		ALmixer_Channel_List[channel].max_volume;
+			alGetString(error));				
+	}
+	ALmixer_Channel_List[channel].fade_end_volume = original_value;
 
 	/* Get the Min volume */
 	alGetSourcef(ALmixer_Channel_List[channel].alsource,
@@ -3096,18 +3265,18 @@
 	if((error = alGetError()) != AL_NO_ERROR)
 	{
 		fprintf(stderr, "36Testing error: %s\n",
-			aluGetErrorString(error));				
+			alGetString(error));				
 	}
 	ALmixer_Channel_List[channel].fade_start_volume = value;
 	fprintf(stderr, "MIN gain: %f\n", value);
 	
 	/* Set the actual volume */
 	alSourcef(ALmixer_Channel_List[channel].alsource,
-		AL_MAX_GAIN, value);
+		AL_GAIN, value);
 	if((error = alGetError()) != AL_NO_ERROR)
 	{
 		fprintf(stderr, "37Testing error: %s\n",
-			aluGetErrorString(error));				
+			alGetString(error));				
 	}
 	
 	
@@ -3123,12 +3292,12 @@
 		 * distruption of playback
 		 */
 		alSourcef(ALmixer_Channel_List[channel].alsource,
-			AL_MAX_GAIN, original_value);
-	if((error = alGetError()) != AL_NO_ERROR)
-	{
-		fprintf(stderr, "38Testing error: %s\n",
-			aluGetErrorString(error));				
-	}
+			AL_GAIN, original_value);
+		if((error = alGetError()) != AL_NO_ERROR)
+		{
+			fprintf(stderr, "38Testing error: %s\n",
+				alGetString(error));				
+		}
 		return retval;
 	}
 
@@ -3139,14 +3308,14 @@
 	if(0 == fade_ticks)
 	{
 		alSourcef(ALmixer_Channel_List[channel].alsource,
-			AL_MAX_GAIN, 
+			AL_GAIN, 
 			ALmixer_Channel_List[channel].fade_end_volume
 		);
-	if((error = alGetError()) != AL_NO_ERROR)
-	{
-		fprintf(stderr, "39Testing error: %s\n",
-			aluGetErrorString(error));				
-	}
+		if((error = alGetError()) != AL_NO_ERROR)
+		{
+			fprintf(stderr, "39Testing error: %s\n",
+				alGetString(error));				
+		}
 
 		return retval;
 	}
@@ -3168,10 +3337,10 @@
 }
 
 		
-static ALuint Internal_FadeInSourceTimed(ALuint source, ALmixer_Data* data, Sint32 loops, Uint32 fade_ticks, Sint32 expire_ticks)
-{
-	Sint32 channel;
-	Sint32 retval;
+static ALuint Internal_FadeInSourceTimed(ALuint source, ALmixer_Data* data, ALint loops, ALuint fade_ticks, ALint expire_ticks)
+{
+	ALint channel;
+	ALint retval;
 	if(0 == source)
 	{
 		retval = Internal_FadeInChannelTimed(-1, data, loops, fade_ticks, expire_ticks);
@@ -3209,12 +3378,12 @@
 
 /* Will fade out currently playing channels.
  * It starts at the current volume level and goes down */
-static Sint32 Internal_FadeOutChannel(Sint32 channel, Uint32 ticks)
+static ALint Internal_FadeOutChannel(ALint channel, ALuint ticks)
 {
 	ALfloat value;
 	ALenum error;
-	Uint32 current_time = SDL_GetTicks();
-	Uint32 counter = 0;
+	ALuint current_time = ALmixer_GetTicks();
+	ALuint counter = 0;
 	
 	/* We can't accept 0 as a value because of div-by-zero.
 	 * If zero, just call Halt at normal
@@ -3222,7 +3391,7 @@
 	 */
 	if(0 == ticks)
 	{
-		return Internal_HaltChannel(channel);
+		return Internal_HaltChannel(channel, AL_TRUE);
 	}
 	
 	
@@ -3238,12 +3407,12 @@
 		{
 			/* Get the current volume */
 			alGetSourcef(ALmixer_Channel_List[channel].alsource,
-				AL_MAX_GAIN, &value);
+				AL_GAIN, &value);
 			ALmixer_Channel_List[channel].fade_start_volume = value;
 	if((error = alGetError()) != AL_NO_ERROR)
 	{
 		fprintf(stderr, "40Testing error: %s\n",
-			aluGetErrorString(error));				
+			alGetString(error));				
 	}
 		
 			/* Get the Min volume */
@@ -3252,7 +3421,7 @@
 	if((error = alGetError()) != AL_NO_ERROR)
 	{
 		fprintf(stderr, "41Testing error: %s\n",
-			aluGetErrorString(error));				
+			alGetString(error));				
 	}
 			ALmixer_Channel_List[channel].fade_end_volume = value;
 			fprintf(stderr, "MIN gain: %f\n", value);
@@ -3277,19 +3446,19 @@
 	/* Else need to fade out all channels */
 	else
 	{
-		Sint32 i;
+		ALint i;
 		for(i=0; i<Number_of_Channels_global; i++)
 		{
 			if(ALmixer_Channel_List[i].channel_in_use)
 			{
 				/* Get the current volume */
 				alGetSourcef(ALmixer_Channel_List[i].alsource,
-					AL_MAX_GAIN, &value);
+					AL_GAIN, &value);
 				ALmixer_Channel_List[i].fade_start_volume = value;
 	if((error = alGetError()) != AL_NO_ERROR)
 	{
 		fprintf(stderr, "42Testing error: %s\n",
-			aluGetErrorString(error));				
+			alGetString(error));				
 	}
 			
 				/* Get the Min volume */
@@ -3298,7 +3467,7 @@
 	if((error = alGetError()) != AL_NO_ERROR)
 	{
 		fprintf(stderr, "43Testing error: %s\n",
-			aluGetErrorString(error));				
+			alGetString(error));				
 	}
 				ALmixer_Channel_List[i].fade_end_volume = value;
 				fprintf(stderr, "MIN gain: %f\n", value);
@@ -3325,9 +3494,9 @@
 }
 
 
-static Sint32 Internal_FadeOutSource(ALuint source, Uint32 ticks)
-{
-	Sint32 channel;
+static ALint Internal_FadeOutSource(ALuint source, ALuint ticks)
+{
+	ALint channel;
 	if(0 == source)
 	{
 		return Internal_FadeOutChannel(-1, ticks);
@@ -3347,12 +3516,12 @@
  * It starts at the current volume level and go to target 
  * Only affects channels that are playing
  */
-static Sint32 Internal_FadeChannel(Sint32 channel, Uint32 ticks, ALfloat volume)
+static ALint Internal_FadeChannel(ALint channel, ALuint ticks, ALfloat volume)
 {
 	ALfloat value;
 	ALenum error;
-	Uint32 current_time = SDL_GetTicks();
-	Uint32 counter = 0;
+	ALuint current_time = ALmixer_GetTicks();
+	ALuint counter = 0;
 	
 	if(channel >= Number_of_Channels_global)
 	{
@@ -3377,11 +3546,11 @@
 			{
 				/* Get the current volume */
 				alGetSourcef(ALmixer_Channel_List[channel].alsource,
-					AL_MAX_GAIN, &value);
+					AL_GAIN, &value);
 	if((error = alGetError()) != AL_NO_ERROR)
 	{
 		fprintf(stderr, "44Testing error: %s\n",
-			aluGetErrorString(error));				
+			alGetString(error));				
 	}
 				ALmixer_Channel_List[channel].fade_start_volume = value;
 			
@@ -3401,11 +3570,11 @@
 			else
 			{
 				alSourcef(ALmixer_Channel_List[channel].alsource,
-					AL_MAX_GAIN, volume);
+					AL_GAIN, volume);
 	if((error = alGetError()) != AL_NO_ERROR)
 	{
 		fprintf(stderr, "45Testing error: %s\n",
-			aluGetErrorString(error));				
+			alGetString(error));				
 	}
 			}
 			counter++;
@@ -3414,7 +3583,7 @@
 	/* Else need to fade out all channels */
 	else
 	{
-		Sint32 i;
+		ALint i;
 		for(i=0; i<Number_of_Channels_global; i++)
 		{
 			if(volume < ALmixer_Channel_List[i].min_volume)
@@ -3432,11 +3601,11 @@
 				{
 					/* Get the current volume */
 					alGetSourcef(ALmixer_Channel_List[i].alsource,
-						AL_MAX_GAIN, &value);
+						AL_GAIN, &value);
 	if((error = alGetError()) != AL_NO_ERROR)
 	{
 		fprintf(stderr, "46Testing error: %s\n",
-			aluGetErrorString(error));				
+			alGetString(error));				
 	}
 					ALmixer_Channel_List[i].fade_start_volume = value;
 				
@@ -3456,11 +3625,11 @@
 				else
 				{
 					alSourcef(ALmixer_Channel_List[i].alsource,
-						AL_MAX_GAIN, volume);
+						AL_GAIN, volume);
 	if((error = alGetError()) != AL_NO_ERROR)
 	{
 		fprintf(stderr, "47Testing error: %s\n",
-			aluGetErrorString(error));				
+			alGetString(error));				
 	}
 				}
 				counter++;
@@ -3470,9 +3639,9 @@
 	return counter;
 }
 
-static Sint32 Internal_FadeSource(ALuint source, Uint32 ticks, ALfloat volume)
-{
-	Sint32 channel;
+static ALint Internal_FadeSource(ALuint source, ALuint ticks, ALfloat volume)
+{
+	ALint channel;
 	if(0 == source)
 	{
 		return Internal_FadeChannel(-1, ticks, volume);
@@ -3492,15 +3661,168 @@
 
 /* Set a volume regardless if it's in use or not.
  */
-static Sint32 Internal_SetMaxVolumeChannel(Sint32 channel, ALfloat volume)
+static ALboolean Internal_SetVolumeChannel(ALint channel, ALfloat volume)
 {
 	ALenum error;
-	Sint32 retval = 0;
+	ALboolean retval = AL_TRUE;
+	
+	if(channel >= Number_of_Channels_global)
+	{
+		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);
+		return AL_FALSE;
+	}
+	
+	if(channel >= 0)
+	{
+		if(volume < 0.0f)
+		{
+			volume = 0.0f;
+		}
+		else if(volume > 1.0f)
+		{
+			volume = 1.0f;
+		}
+		alSourcef(ALmixer_Channel_List[channel].alsource,
+				  AL_GAIN, volume);
+		if((error = alGetError()) != AL_NO_ERROR)
+		{
+			ALmixer_SetError("%s",
+							 alGetString(error) );
+			retval = AL_FALSE;
+		}
+	}
+	else
+	{
+		ALint i;
+		for(i=0; i<Number_of_Channels_global; i++)
+		{
+			if(volume < 0.0f)
+			{
+				volume = 0.0f;
+			}
+			else if(volume > 1.0f)
+			{
+				volume = 1.0f;
+			}
+			alSourcef(ALmixer_Channel_List[i].alsource,
+					  AL_GAIN, volume);
+			if((error = alGetError()) != AL_NO_ERROR)
+			{
+				ALmixer_SetError("%s",
+								 alGetString(error) );
+				retval = AL_FALSE;
+			}
+		}
+	}
+	return retval;
+}
+
+static ALboolean Internal_SetVolumeSource(ALuint source, ALfloat volume)
+{
+	ALint channel;
+	if(0 == source)
+	{
+		return Internal_SetVolumeChannel(-1, volume);
+	}
+	
+	channel = Internal_GetChannel(source);
+	if(-1 == channel)
+	{
+		ALmixer_SetError("Cannot SetMaxVolume: %s", ALmixer_GetError());
+		return AL_FALSE;
+	}
+	return Internal_SetVolumeChannel(channel, volume);
+}
+
+
+static ALfloat Internal_GetVolumeChannel(ALint channel)
+{
+	 ALfloat value;
+	 ALenum error;
+	ALfloat running_total = 0.0f;
+	ALfloat retval = 0.0f;
+	
+	if(channel >= Number_of_Channels_global)
+	{
+		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);
+		return -1.0f;
+	}
+	
+	if(channel >= 0)
+	{
+		 alGetSourcef(ALmixer_Channel_List[channel].alsource,
+		 AL_GAIN, &value);
+		 if((error = alGetError()) != AL_NO_ERROR)
+		 {
+			 ALmixer_SetError("%s", alGetString(error) );
+			 retval = -1.0f;
+		 }
+		 else
+		 {
+			 retval = value;
+		 }
+	}
+	else
+	{
+		ALint i;
+		for(i=0; i<Number_of_Channels_global; i++)
+		{
+			 alGetSourcef(ALmixer_Channel_List[i].alsource,
+			 AL_GAIN, &value);
+			 if((error = alGetError()) != AL_NO_ERROR)
+			 {
+				 ALmixer_SetError("%s", alGetString(error) );
+				 retval = -1;
+			 }
+			 else
+			 {
+				 running_total += value;
+			 }
+		}
+		if(0 == Number_of_Channels_global)
+		{
+			ALmixer_SetError("No channels are allocated");
+			retval = -1.0f;
+		}
+		else
+		{
+			retval = running_total / Number_of_Channels_global;
+		}
+	}
+	return retval;
+}
+
+static ALfloat Internal_GetVolumeSource(ALuint source)
+{
+	ALint channel;
+	if(0 == source)
+	{
+		return Internal_GetVolumeChannel(-1);
+	}
+	
+	channel = Internal_GetChannel(source);
+	if(-1 == channel)
+	{
+		ALmixer_SetError("Cannot GetVolume: %s", ALmixer_GetError());
+		return -1.0f;
+	}
+	
+	return Internal_GetVolumeChannel(channel);
+}
+
+
+
+/* Set a volume regardless if it's in use or not.
+ */
+static ALboolean Internal_SetMaxVolumeChannel(ALint channel, ALfloat volume)
+{
+	ALenum error;
+	ALboolean retval = AL_TRUE;
 	
 	if(channel >= Number_of_Channels_global)
 	{
 			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);
-		return -1;
+		return AL_FALSE;
 	}
 
 	if(channel >= 0)
@@ -3519,8 +3841,8 @@
 		if((error = alGetError()) != AL_NO_ERROR)
 		{
 			ALmixer_SetError("%s",
-				aluGetErrorString(error) );
-			retval = -1;
+				alGetString(error) );
+			retval = AL_FALSE;
 		}
 		if(ALmixer_Channel_List[channel].max_volume < ALmixer_Channel_List[channel].min_volume)
 		{
@@ -3530,14 +3852,14 @@
 			if((error = alGetError()) != AL_NO_ERROR)
 			{
 				ALmixer_SetError("%s",
-					aluGetErrorString(error) );
-				retval = -1;
+					alGetString(error) );
+				retval = AL_FALSE;
 			}
 		}
 	}
 	else
 	{
-		Sint32 i;
+		ALint i;
 		for(i=0; i<Number_of_Channels_global; i++)
 		{
 			if(volume < 0.0f)
@@ -3554,8 +3876,8 @@
 			if((error = alGetError()) != AL_NO_ERROR)
 			{
 				ALmixer_SetError("%s",
-					aluGetErrorString(error) );
-				retval = -1;
+					alGetString(error) );
+				retval = AL_FALSE;
 			}
 			if(ALmixer_Channel_List[i].max_volume < ALmixer_Channel_List[i].min_volume)
 			{
@@ -3565,8 +3887,8 @@
 				if((error = alGetError()) != AL_NO_ERROR)
 				{
 					ALmixer_SetError("%s",
-						aluGetErrorString(error) );
-					retval = -1;
+						alGetString(error) );
+					retval = AL_FALSE;
 				}
 			}
 		}
@@ -3574,9 +3896,9 @@
 	return retval;
 }
 
-static Sint32 Internal_SetMaxVolumeSource(ALuint source, ALfloat volume)
-{
-	Sint32 channel;
+static ALint Internal_SetMaxVolumeSource(ALuint source, ALfloat volume)
+{
+	ALint channel;
 	if(0 == source)
 	{
 		return Internal_SetMaxVolumeChannel(-1, volume);
@@ -3586,12 +3908,12 @@
 	if(-1 == channel)
 	{
 		ALmixer_SetError("Cannot SetMaxVolume: %s", ALmixer_GetError());
-		return -1;
+		return AL_FALSE;
 	}
 	return Internal_SetMaxVolumeChannel(channel, volume);
 }
 
-static ALfloat Internal_GetMaxVolumeChannel(Sint32 channel)
+static ALfloat Internal_GetMaxVolumeChannel(ALint channel)
 {
 	/*
 	ALfloat value;
@@ -3614,7 +3936,7 @@
 		if((error = alGetError()) != AL_NO_ERROR)
 		{
 			ALmixer_SetError("%s",
-				aluGetErrorString(error) );
+				alGetString(error) );
 			retval = -1.0f;
 		}
 		else
@@ -3627,7 +3949,7 @@
 	}
 	else
 	{
-		Sint32 i;
+		ALint i;
 		for(i=0; i<Number_of_Channels_global; i++)
 		{
 			/*
@@ -3636,7 +3958,7 @@
 			if((error = alGetError()) != AL_NO_ERROR)
 			{
 				ALmixer_SetError("%s",
-					aluGetErrorString(error) );
+					alGetString(error) );
 				retval = -1;
 			}
 			else
@@ -3661,7 +3983,7 @@
 
 static ALfloat Internal_GetMaxVolumeSource(ALuint source)
 {
-	Sint32 channel;
+	ALint channel;
 	if(0 == source)
 	{
 		return Internal_GetMaxVolumeChannel(-1);
@@ -3680,15 +4002,15 @@
 
 /* Set a volume regardless if it's in use or not.
  */
-static Sint32 Internal_SetMinVolumeChannel(Sint32 channel, ALfloat volume)
+static ALboolean Internal_SetMinVolumeChannel(ALint channel, ALfloat volume)
 {
 	ALenum error;
-	Sint32 retval = 0;
+	ALboolean retval = AL_TRUE;
 	
 	if(channel >= Number_of_Channels_global)
 	{
 			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);
-		return -1;
+		return AL_FALSE;
 	}
 
 	if(channel >= 0)
@@ -3707,8 +4029,8 @@
 		if((error = alGetError()) != AL_NO_ERROR)
 		{
 			ALmixer_SetError("%s",
-				aluGetErrorString(error) );
-			retval = -1;
+				alGetString(error) );
+			retval = AL_FALSE;
 		}
 		if(ALmixer_Channel_List[channel].max_volume < ALmixer_Channel_List[channel].min_volume)
 		{
@@ -3718,14 +4040,14 @@
 			if((error = alGetError()) != AL_NO_ERROR)
 			{
 				ALmixer_SetError("%s",
-					aluGetErrorString(error) );
-				retval = -1;
+					alGetString(error) );
+				retval = AL_FALSE;
 			}
 		}
 	}
 	else
 	{
-		Sint32 i;
+		ALint i;
 		for(i=0; i<Number_of_Channels_global; i++)
 		{
 			if(volume < 0.0f)
@@ -3742,8 +4064,8 @@
 			if((error = alGetError()) != AL_NO_ERROR)
 			{
 				ALmixer_SetError("%s",
-					aluGetErrorString(error) );
-				retval = -1;
+					alGetString(error) );
+				retval = AL_FALSE;
 			}
 			if(ALmixer_Channel_List[i].max_volume < ALmixer_Channel_List[i].min_volume)
 			{
@@ -3753,8 +4075,8 @@
 				if((error = alGetError()) != AL_NO_ERROR)
 				{
 					ALmixer_SetError("%s",
-						aluGetErrorString(error) );
-					retval = -1;
+						alGetString(error) );
+					retval = AL_FALSE;
 				}
 			}
 		}
@@ -3762,9 +4084,9 @@
 	return retval;
 }
 
-static Sint32 Internal_SetMinVolumeSource(ALuint source, ALfloat volume)
-{
-	Sint32 channel;
+static ALboolean Internal_SetMinVolumeSource(ALuint source, ALfloat volume)
+{
+	ALint channel;
 	if(0 == source)
 	{
 		return Internal_SetMinVolumeChannel(-1, volume);
@@ -3774,12 +4096,12 @@
 	if(-1 == channel)
 	{
 		ALmixer_SetError("Cannot SetMaxVolume: %s", ALmixer_GetError());
-		return -1;
+		return AL_FALSE;
 	}
 	return Internal_SetMinVolumeChannel(channel, volume);
 }
 
-static ALfloat Internal_GetMinVolumeChannel(Sint32 channel)
+static ALfloat Internal_GetMinVolumeChannel(ALint channel)
 {
 	/*
 	ALfloat value;
@@ -3802,7 +4124,7 @@
 		if((error = alGetError()) != AL_NO_ERROR)
 		{
 			ALmixer_SetError("%s",
-				aluGetErrorString(error) );
+				alGetString(error) );
 			retval = -1.0f;
 		}
 		else
@@ -3815,7 +4137,7 @@
 	}
 	else
 	{
-		Sint32 i;
+		ALint i;
 		for(i=0; i<Number_of_Channels_global; i++)
 		{
 			/*
@@ -3824,7 +4146,7 @@
 			if((error = alGetError()) != AL_NO_ERROR)
 			{
 				ALmixer_SetError("%s",
-					aluGetErrorString(error) );
+					alGetString(error) );
 				retval = -1;
 			}
 			else
@@ -3849,7 +4171,7 @@
 
 static ALfloat Internal_GetMinVolumeSource(ALuint source)
 {
-	Sint32 channel;
+	ALint channel;
 	if(0 == source)
 	{
 		return Internal_GetMinVolumeChannel(-1);
@@ -3867,17 +4189,17 @@
 
 
 /* Changes the listener volume */
-static Sint32 Internal_SetMasterVolume(ALfloat volume)
+static ALboolean Internal_SetMasterVolume(ALfloat volume)
 {
 	ALenum error;
 	alListenerf(AL_GAIN, volume);
 	if((error = alGetError()) != AL_NO_ERROR)
 	{
 		ALmixer_SetError("%s",
-			aluGetErrorString(error) );
-		return -1;
-	}
-	return 0;	
+			alGetString(error) );
+		return AL_FALSE;
+	}
+	return AL_TRUE;
 }
 
 static ALfloat Internal_GetMasterVolume()
@@ -3888,7 +4210,7 @@
 	if((error = alGetError()) != AL_NO_ERROR)
 	{
 		ALmixer_SetError("%s",
-			aluGetErrorString(error) );
+			alGetString(error) );
 		return -1.0f;
 	}
 	return volume;	
@@ -3899,10 +4221,10 @@
 
 /* Will fade out currently playing channels.
  * It starts at the current volume level and goes down */
-static Sint32 Internal_ExpireChannel(Sint32 channel, Sint32 ticks)
-{
-	Uint32 current_time = SDL_GetTicks();
-	Uint32 counter = 0;
+static ALint Internal_ExpireChannel(ALint channel, ALint ticks)
+{
+	ALuint current_time = ALmixer_GetTicks();
+	ALuint counter = 0;
 	
 	/* We can't accept 0 as a value because of div-by-zero.
 	 * If zero, just call Halt at normal
@@ -3910,7 +4232,7 @@
 	 */
 	if(0 == ticks)
 	{
-		return Internal_HaltChannel(channel);
+		return Internal_HaltChannel(channel, AL_TRUE);
 	}
 	if(ticks < -1)
 	{
@@ -3939,7 +4261,7 @@
 	/* Else need to fade out all channels */
 	else
 	{
-		Sint32 i;
+		ALint i;
 		for(i=0; i<Number_of_Channels_global; i++)
 		{
 			if(ALmixer_Channel_List[i].channel_in_use)
@@ -3957,9 +4279,9 @@
 }
 
 
-static Sint32 Internal_ExpireSource(ALuint source, Sint32 ticks)
-{
-	Sint32 channel;
+static ALint Internal_ExpireSource(ALuint source, ALint ticks)
+{
+	ALint channel;
 	if(0 == source)
 	{
 		return Internal_ExpireChannel(-1, ticks);
@@ -3975,10 +4297,10 @@
 }
 
 
-static Sint32 Internal_QueryChannel(Sint32 channel)
-{
-	Sint32 i;
-	Sint32 counter = 0;
+static ALint Internal_QueryChannel(ALint channel)
+{
+	ALint i;
+	ALint counter = 0;
 	if(channel >= Number_of_Channels_global)
 	{
 		ALmixer_SetError("Invalid channel: %d", channel);
@@ -4002,9 +4324,9 @@
 }
 
 
-static Sint32 Internal_QuerySource(ALuint source)
-{
-	Sint32 channel;
+static ALint Internal_QuerySource(ALuint source)
+{
+	ALint channel;
 	if(0 == source)
 	{
 		return Internal_QueryChannel(-1);
@@ -4021,10 +4343,10 @@
 }
 
 
-static Sint32 Internal_CountUnreservedUsedChannels()
-{
-	Sint32 i;
-	Sint32 counter = 0;
+static ALuint Internal_CountUnreservedUsedChannels()
+{
+	ALint i;
+	ALuint counter = 0;
 
 
 	/* Else, return the number of channels in use */
@@ -4038,10 +4360,10 @@
 	return counter;
 }
 
-static Sint32 Internal_CountUnreservedFreeChannels()
-{
-	Sint32 i;
-	Sint32 counter = 0;
+static ALuint Internal_CountUnreservedFreeChannels()
+{
+	ALint i;
+	ALuint counter = 0;
 
 
 	/* Else, return the number of channels in use */
@@ -4055,10 +4377,10 @@
 	return counter;
 }
 
-static Sint32 Internal_CountAllUsedChannels()
-{
-	Sint32 i;
-	Sint32 counter = 0;
+static ALuint Internal_CountAllUsedChannels()
+{
+	ALint i;
+	ALuint counter = 0;
 
 
 	/* Else, return the number of channels in use */
@@ -4072,10 +4394,10 @@
 	return counter;
 }
 
-static Sint32 Internal_CountAllFreeChannels()
-{
-	Sint32 i;
-	Sint32 counter = 0;
+static ALuint Internal_CountAllFreeChannels()
+{
+	ALint i;
+	ALuint counter = 0;
 
 
 	/* Else, return the number of channels in use */
@@ -4090,10 +4412,10 @@
 }
 
 
-static Sint32 Internal_PlayingChannel(Sint32 channel)
-{
-	Sint32 i;
-	Sint32 counter = 0;
+static ALint Internal_PlayingChannel(ALint channel)
+{
+	ALint i;
+	ALint counter = 0;
 	ALint state;
 	
 	if(channel >= Number_of_Channels_global)
@@ -4137,9 +4459,9 @@
 }
 
 
-static Sint32 Internal_PlayingSource(ALuint source)
-{
-	Sint32 channel;
+static ALint Internal_PlayingSource(ALuint source)
+{
+	ALint channel;
 	if(0 == source)
 	{
 		return Internal_PlayingChannel(-1);
@@ -4156,10 +4478,10 @@
 }
 
 
-static Sint32 Internal_PausedChannel(Sint32 channel)
-{
-	Sint32 i;
-	Sint32 counter = 0;
+static ALint Internal_PausedChannel(ALint channel)
+{
+	ALint i;
+	ALint counter = 0;
 	ALint state;
 	
 	if(channel >= Number_of_Channels_global)
@@ -4203,9 +4525,9 @@
 }
 
 
-static Sint32 Internal_PausedSource(ALuint source)
-{
-	Sint32 channel;
+static ALint Internal_PausedSource(ALuint source)
+{
+	ALint channel;
 	if(0 == source)
 	{
 		return Internal_PausedChannel(-1);
@@ -4236,23 +4558,27 @@
  * when a buffer is queued, there was probably some
  * CPU intensive looping which took awhile.
  * It's mainly provided as a convenience.
- * Timing the call with SDL_GetTicks() would produce
+ * Timing the call with ALmixer_GetTicks() would produce
  * more accurate information.
  * Returns a negative value if there was an error,
  * the value being the number of errors.
  */
-static Sint32 Update_ALmixer(void* data)
-{
-	Sint32 retval = 0;
-	Sint32 error_flag = 0;
+static ALint Update_ALmixer(void* data)
+{
+	ALint retval = 0;
+	ALint error_flag = 0;
 	ALenum error;
 	ALint state;
-	Sint32 i=0;
-
-	SDL_LockMutex(simple_lock);
+	ALint i=0;
+
+#ifdef ENABLE_ALMIXER_THREADS
+	SDL_LockMutex(s_simpleLock);
+#endif
 	if(0 == ALmixer_Initialized)
 	{
-		SDL_UnlockMutex(simple_lock);
+#ifdef ENABLE_ALMIXER_THREADS
+		SDL_UnlockMutex(s_simpleLock);
+#endif
 		return 0;
 	}
 	
@@ -4260,14 +4586,16 @@
 	/* If anything is playing, then we have to do work */
 	if( 0 == Is_Playing_global)
 	{
-		SDL_UnlockMutex(simple_lock);
+#ifdef ENABLE_ALMIXER_THREADS
+		SDL_UnlockMutex(s_simpleLock);
+#endif
 		return 0;
 	}
 	/* Clear error */
 	if((error = alGetError()) != AL_NO_ERROR)
 				{
 		fprintf(stderr, "08Testing errpr before unqueue because getting stuff, for OS X this is expected: %s\n",
-				aluGetErrorString(error));				
+				alGetString(error));				
 				}
 	alGetError();
 
@@ -4280,19 +4608,19 @@
 			 * we can check the timeout and fading values
 			 * and do the appropriate things
 			 */
-			Uint32 current_time = SDL_GetTicks();
+			ALuint current_time = ALmixer_GetTicks();
 
 			/* Check to see if we need to halt due to Timed play */
 			if(ALmixer_Channel_List[i].expire_ticks != -1) 
 			{
-				Uint32 target_time = (Uint32)ALmixer_Channel_List[i].expire_ticks 
+				ALuint target_time = (ALuint)ALmixer_Channel_List[i].expire_ticks 
 					 + ALmixer_Channel_List[i].start_time;
 				alGetSourcei(ALmixer_Channel_List[i].alsource,
 					AL_SOURCE_STATE, &state);
 				if((error = alGetError()) != AL_NO_ERROR)
 				{
 					fprintf(stderr, "06Testing errpr before unqueue because getting stuff, for OS X this is expected: %s\n",
-							aluGetErrorString(error));				
+							alGetString(error));				
 				}
 				
 				/* Check the time, and also make sure that it is not
@@ -4304,11 +4632,11 @@
 					&& (state != AL_PAUSED) )
 				{
 					/* Stop the playback */
-					ALmixer_HaltChannel(i);
+					Internal_HaltChannel(i, AL_TRUE);
 					if((error = alGetError()) != AL_NO_ERROR)
 					{
 						fprintf(stderr, "07Testing errpr before unqueue because getting stuff, for OS X this is expected: %s\n",
-								aluGetErrorString(error));				
+								alGetString(error));				
 					}
 					
 					/* Everything should be done so go on to the next loop */
@@ -4319,14 +4647,14 @@
 			/* Check to see if we need to adjust the volume for fading */
 			if( ALmixer_Channel_List[i].fade_enabled )
 			{
-				Uint32 target_time = ALmixer_Channel_List[i].fade_expire_ticks 
+				ALuint target_time = ALmixer_Channel_List[i].fade_expire_ticks 
 					 + ALmixer_Channel_List[i].fade_start_time;
 				alGetSourcei(ALmixer_Channel_List[i].alsource,
 					AL_SOURCE_STATE, &state);
 				if((error = alGetError()) != AL_NO_ERROR)
 				{
 					fprintf(stderr, "05Testing errpr before unqueue because getting stuff, for OS X this is expected: %s\n",
-							aluGetErrorString(error));				
+							alGetString(error));				
 				}
 				
 				/* Check the time, and also make sure that it is not
@@ -4337,7 +4665,7 @@
 				if(state != AL_PAUSED)
 				{
 					ALfloat t;
-					Uint32 delta_time;
+					ALuint delta_time;
 					ALfloat current_volume;
 					if(current_time >= target_time)
 					{
@@ -4370,7 +4698,7 @@
 					if((error = alGetError()) != AL_NO_ERROR)
 					{
 						fprintf(stderr, "04Testing errpr before unqueue because getting stuff, for OS X this is expected: %s\n",
-								aluGetErrorString(error));				
+								alGetString(error));				
 					}
 					
 	/*
@@ -4442,7 +4770,7 @@
 				if((error = alGetError()) != AL_NO_ERROR)
 				{
 					fprintf(stderr, "03Testing errpr before unqueue because getting stuff, for OS X this is expected: %s\n",
-							aluGetErrorString(error));				
+							alGetString(error));				
 				}
 				
 					
@@ -4453,7 +4781,7 @@
 				if((error = alGetError()) != AL_NO_ERROR)
 				{
 					fprintf(stderr, "02Testing errpr before unqueue because getting stuff, for OS X this is expected: %s\n",
-							aluGetErrorString(error));				
+							alGetString(error));				
 				}
 				
 				
@@ -4482,7 +4810,7 @@
 	if((error = alGetError()) != AL_NO_ERROR)
 	{
 		fprintf(stderr, "50Testing error: %s\n",
-			aluGetErrorString(error));				
+			alGetString(error));				
 	}
 						continue;
 					}
@@ -4524,7 +4852,7 @@
 						if((error = alGetError()) != AL_NO_ERROR)
 						{
 							fprintf(stderr, "01Testing errpr before unqueue because getting stuff, for OS X this is expected: %s\n",
-									aluGetErrorString(error));				
+									alGetString(error));				
 						}
 						
 						alGetSourcei(
@@ -4534,9 +4862,9 @@
 						if((error = alGetError()) != AL_NO_ERROR)
 						{
 		fprintf(stderr, "Error with unqueue, for OS X this is expected: %s\n",
-							aluGetErrorString(error));
+							alGetString(error));
 							ALmixer_SetError("Failed detecting unqueued predecoded buffer (expected with OS X): %s",
-								aluGetErrorString(error) );
+								alGetString(error) );
 							error_flag--;
 						}
 						if(buffers_still_queued > 0)
@@ -4565,9 +4893,9 @@
 							if((error = alGetError()) != AL_NO_ERROR)
 							{
 		fprintf(stderr, "Error with unqueue, after alSourceUnqueueBuffers, buffers_still_queued=%d, error is: %s", buffers_still_queued,
-								aluGetErrorString(error));
+								alGetString(error));
 								ALmixer_SetError("Predecoded Unqueue buffer failed: %s",
-									aluGetErrorString(error) );
+									alGetString(error) );
 								error_flag--;
 							}
 
@@ -4578,7 +4906,7 @@
 						Is_Playing_global--;
 
 						/* Launch callback */
-						Invoke_Channel_Done_Callback(i);
+						Invoke_Channel_Done_Callback(i, AL_TRUE);
 
 						/* We're done for this loop.
 						 * Go to next channel 
@@ -4631,11 +4959,15 @@
 				if((error = alGetError()) != AL_NO_ERROR)
 				{
 					fprintf(stderr, "51Testing error: %s\n",
-						aluGetErrorString(error));				
+						alGetString(error));				
 				}
 				/* Get the number of buffers processed
 				 * so we know if we need to refill 
 				 */
+				 /* WARNING: It looks like Snow Leopard some times crashes on this call under x86_64
+				  * typically when I suffer a lot of buffer underruns.
+				  */
+//				 fprintf(stderr, "calling AL_BUFFERS_PROCESSED on source:%d", ALmixer_Channel_List[i].alsource);
 				alGetSourcei(
 					ALmixer_Channel_List[i].alsource,
 					AL_BUFFERS_PROCESSED, &buffers_processed
@@ -4643,8 +4975,9 @@
 				if((error = alGetError()) != AL_NO_ERROR)
 				{
 					fprintf(stderr, "52Testing error: %s\n",
-						aluGetErrorString(error));				
+						alGetString(error));				
 				}
+//				fprintf(stderr, "finished AL_BUFFERS_PROCESSED, buffers_processed=%d", buffers_processed);
 
  /* WTF!!! The Nvidia distribution is failing on the alGetSourcei(source, AL_BUFFER, buf_id) call.
  * I need this call to figure out which buffer OpenAL is currently playing. 
@@ -4672,7 +5005,7 @@
 				if((error = alGetError()) != AL_NO_ERROR)
 				{
 					fprintf(stderr, "53Testing error: %s\n",
-						aluGetErrorString(error));				
+						alGetString(error));				
 				}
 
 				/* Before the hard stuff, check to see if the 
@@ -4701,20 +5034,20 @@
 					)
 				   )
 				{
-					Uint32 k;
-					Uint32 queue_ret_flag;
-					Uint8 is_out_of_sync = 0;
-					Uint32 my_queue_size = CircularQueueUnsignedInt_Size(ALmixer_Channel_List[i].almixer_data->circular_buffer_queue);
+					ALint k;
+					ALuint queue_ret_flag;
+					ALubyte is_out_of_sync = 0;
+					ALuint my_queue_size = CircularQueueUnsignedInt_Size(ALmixer_Channel_List[i].almixer_data->circular_buffer_queue);
 					/* Ugh, I have to deal with signed/unsigned mismatch here. */
 					ALint buffers_unplayed_int = buffers_still_queued - buffers_processed;
-					Uint32 unplayed_buffers;
+					ALuint unplayed_buffers;
 					if(buffers_unplayed_int < 0)
 					{
 						unplayed_buffers = 0;
 					}
 					else
 					{
-						unplayed_buffers = (Uint32)buffers_unplayed_int;
+						unplayed_buffers = (ALuint)buffers_unplayed_int;
 					}
 /*
 					fprintf(stderr, "Queue in processed check, before pop, buffers_processed=%d\n", buffers_processed);
@@ -4744,19 +5077,16 @@
 					fprintf(stderr, "inside, Buffers processed=%d, Buffers queued=%d, my queue=%d\n",
 							buffers_processed, buffers_still_queued, my_queue_size);
 					#endif	
-					if(my_queue_size > unplayed_buffers)
+					is_out_of_sync = 1;
+					for(k=0; k<buffers_processed; k++)
 					{
-						is_out_of_sync = 1;
-						for(k=0; k<(my_queue_size - unplayed_buffers); k++)
+						queue_ret_flag = CircularQueueUnsignedInt_PopFront(
+							ALmixer_Channel_List[i].almixer_data->circular_buffer_queue);
+						if(0 == queue_ret_flag)
 						{
-							queue_ret_flag = CircularQueueUnsignedInt_PopFront(
-								ALmixer_Channel_List[i].almixer_data->circular_buffer_queue);
-							if(0 == queue_ret_flag)
-							{
-								fprintf(stderr, "53 Error popping queue\n");
-							}
-						}						
-					}
+							fprintf(stderr, "53 Error popping queue\n");
+						}
+					}		
 					my_queue_size = CircularQueueUnsignedInt_Size(ALmixer_Channel_List[i].almixer_data->circular_buffer_queue);
 					/* We have several possibilities we need to handle:
 					 * 1) We are in an initial state or underrun and need to do a data callback on the head.
@@ -4846,7 +5176,7 @@
 				 */
 				if( ! ALmixer_Channel_List[i].almixer_data->eof)
 				{
-					Uint32 bytes_returned;
+					ALuint bytes_returned;
 					/* We have a priority. We first must assign
 					 * unused buffers in reserve. If there is nothing
 					 * left, then we may unqueue buffers. We can't
@@ -4889,9 +5219,9 @@
 						if((error = alGetError()) != AL_NO_ERROR)
 						{
 				fprintf(stderr, "Error with unqueue: %s",
-							aluGetErrorString(error));
+							alGetString(error));
 							ALmixer_SetError("Unqueue buffer failed: %s",
-								aluGetErrorString(error) );
+								alGetString(error) );
 							error_flag--;
 						}
 /*
@@ -4910,7 +5240,9 @@
 					{
 						/* Might want to check state */
 						/* In case the playback stopped,
-						 * we need to resume */
+						 * we need to resume 
+						 * a.k.a. buffer underrun
+						 */
 						#if 1 
 						/* Try not refetching the state here because I'm getting a duplicate
 						 buffer playback (hiccup) */
@@ -4921,7 +5253,7 @@
 						if((error = alGetError()) != AL_NO_ERROR)
 						{
 							fprintf(stderr, "54bTesting error: %s\n",
-								aluGetErrorString(error));				
+								alGetString(error));				
 						}
 						/* Get the number of buffers processed
 						 */
@@ -4933,7 +5265,7 @@
 						if((error = alGetError()) != AL_NO_ERROR)
 						{
 							fprintf(stderr, "54cError, Can't get buffers_processed: %s\n",
-								aluGetErrorString(error));				
+								alGetString(error));				
 						}
 #endif
 						if(AL_STOPPED == state)
@@ -4958,10 +5290,10 @@
 							 * to play.
 							 */
 							ALint temp_count;
-/*							
-							fprintf(stderr, "STOPPED1, need to clear processed, status is:\n");
+#if 0
+							fprintf(stderr, "STOPPED1, need to clear processed=%d, status is:\n", buffers_processed);
 							PrintQueueStatus(ALmixer_Channel_List[i].alsource);
-*/
+#endif
 							for(temp_count=0; temp_count<buffers_processed; temp_count++)
 							{
 								alSourceUnqueueBuffers(
@@ -4971,20 +5303,95 @@
 								if((error = alGetError()) != AL_NO_ERROR)
 								{
 									fprintf(stderr, "55aTesting error: %s\n",
-										aluGetErrorString(error));				
+										alGetString(error));				
 									error_flag--;
 								}
 							}
-/*
+#if 0
 							fprintf(stderr, "After unqueue clear...:\n");
 							PrintQueueStatus(ALmixer_Channel_List[i].alsource);
-*/
-							alSourcePlay(ALmixer_Channel_List[i].alsource);
+#endif						
+							/* My assertion: We are STOPPED but not EOF.
+							 * This means we have a buffer underrun.
+							 * We just cleared out the unqueued buffers.
+							 * So we need to reset the mixer_data to reflect we have
+							 * no buffers in queue.
+							 * We need to GetMoreData and then queue up the data.
+							 * Then we need to resume playing.
+							 */
+#if 0
+							int buffers_queued;
+							alGetSourcei(
+										 ALmixer_Channel_List[i].alsource,
+										 AL_BUFFERS_QUEUED, 
+										 &buffers_queued
+										 );
+							
 							if((error = alGetError()) != AL_NO_ERROR)
 							{
-								fprintf(stderr, "55Tbesting error: %s\n",
-									aluGetErrorString(error));				
+								fprintf(stderr, "Error in PrintQueueStatus, Can't get buffers_queued: %s\n",
+										alGetString(error));				
+							} 
+							assert(buffers_queued == 0);
+							fprintf(stderr, "buffer underrun: buffers_queued:%d\n", buffers_queued);
+#endif
+
+							/* Reset the number of buffers in use to 0 */
+							ALmixer_Channel_List[i].almixer_data->num_buffers_in_use = 0;
+
+							/* Get more data and put it in the first buffer */
+							bytes_returned = GetMoreData(
+								ALmixer_Channel_List[i].almixer_data,
+								ALmixer_Channel_List[i].almixer_data->buffer[0]
+							);
+							/* NOTE: We might want to look for EOF and handle it here.
+							 * Currently, I just let the next loop handle it which seems to be working.
+							 */
+							if(bytes_returned > 0)
+							{
+								/* Queue up the new data */
+								alSourceQueueBuffers(
+													 ALmixer_Channel_List[i].alsource,
+													 1, 
+													 &ALmixer_Channel_List[i].almixer_data->buffer[0]
+								);
+								if((error = alGetError()) != AL_NO_ERROR)
+								{
+									fprintf(stderr, "56e alSourceQueueBuffers error: %s\n",
+											alGetString(error));				
+								}
+								/* Increment the number of buffers in use */
+								ALmixer_Channel_List[i].almixer_data->num_buffers_in_use++;
+								
+
+								/* We need to empty and update the circular buffer queue if it is in use */
+								if(ALmixer_Channel_List[i].almixer_data->circular_buffer_queue != NULL)
+								{
+									ALuint queue_ret_flag;
+									CircularQueueUnsignedInt_Clear(ALmixer_Channel_List[i].almixer_data->circular_buffer_queue);
+									queue_ret_flag = CircularQueueUnsignedInt_PushBack(
+																					   ALmixer_Channel_List[i].almixer_data->circular_buffer_queue, 
+																					   ALmixer_Channel_List[i].almixer_data->buffer[0]
+																					   );	
+									if(0 == queue_ret_flag)
+									{
+										fprintf(stderr, "56fSerious internal error: CircularQueue could not push into queue.\n");
+										ALmixer_SetError("Serious internal error: CircularQueue failed to push into queue");
+									}
+								}
+								
+								
+
+
+								/* Resume playback from underrun */
+								alSourcePlay(ALmixer_Channel_List[i].alsource);
+								if((error = alGetError()) != AL_NO_ERROR)
+								{
+									fprintf(stderr, "55Tbesting error: %s\n",
+										alGetString(error));				
+								}
 							}
+
 						}
 						/* Let's escape to the next loop.
 						 * All code below this point is for queuing up 
@@ -5002,7 +5409,7 @@
 					 * Let's check it to make sure it's okay,
 					 * and then queue it up
 					 */
-					/* This check doesn't work anymore because it is now Uint32 */
+					/* This check doesn't work anymore because it is now ALuint */
 				#if 0
 					if(-1 == bytes_returned)
 					{
@@ -5151,7 +5558,7 @@
 						if((error = alGetError()) != AL_NO_ERROR)
 						{
 							fprintf(stderr, "56Testing error: %s\n",
-								aluGetErrorString(error));				
+								alGetString(error));				
 						}
 						/* This is part of the hideous Nvidia workaround. In order to figure out
 						 * which buffer to show during callbacks (for things like
@@ -5161,7 +5568,8 @@
 						 */
 						if(ALmixer_Channel_List[i].almixer_data->circular_buffer_queue != NULL)
 						{
-							Uint32 queue_ret_flag;
+							ALuint queue_ret_flag;
+//				fprintf(stderr, "56d: CircularQueue_PushBack.\n");
 							queue_ret_flag = CircularQueueUnsignedInt_PushBack(
 								ALmixer_Channel_List[i].almixer_data->circular_buffer_queue, 
 								ALmixer_Channel_List[i].almixer_data->buffer[ALmixer_Channel_List[i].almixer_data->num_buffers_in_use]
@@ -5196,7 +5604,7 @@
 						if((error = alGetError()) != AL_NO_ERROR)
 						{
 							ALmixer_SetError("Could not QueueBuffer: %s",
-								aluGetErrorString(error) );
+								alGetString(error) );
 							error_flag--;
 							continue;
 						}
@@ -5208,7 +5616,8 @@
 						 */
 						if(ALmixer_Channel_List[i].almixer_data->circular_buffer_queue != NULL)
 						{
-							Uint32 queue_ret_flag;
+							ALuint queue_ret_flag;
+//				fprintf(stderr, "56e: CircularQueue_PushBack.\n");
 							queue_ret_flag = CircularQueueUnsignedInt_PushBack(
 								ALmixer_Channel_List[i].almixer_data->circular_buffer_queue, 
 								unqueued_buffer_id
@@ -5218,12 +5627,12 @@
 								fprintf(stderr, "56bSerious internal error: CircularQueue could not push into queue.\n");
 								ALmixer_SetError("Serious internal error: CircularQueue failed to push into queue");
 							}
-							/*
+#if 0
 							else
 							{
 								CircularQueueUnsignedInt_Print(ALmixer_Channel_List[i].almixer_data->circular_buffer_queue);
 							}
-							 */
+#endif
 						}
 					}
 					/* If we used an available buffer queue,
@@ -5248,7 +5657,7 @@
 					if((error = alGetError()) != AL_NO_ERROR)
 					{
 						fprintf(stderr, "57bTesting error: %s\n",
-							aluGetErrorString(error));				
+							alGetString(error));				
 					}
 					/* Get the number of buffers processed
 					 */
@@ -5260,7 +5669,7 @@
 					if((error = alGetError()) != AL_NO_ERROR)
 					{
 						fprintf(stderr, "57cError, Can't get buffers_processed: %s\n",
-							aluGetErrorString(error));				
+							alGetString(error));				
 					}
 					#endif
 					if(AL_STOPPED == state)
@@ -5300,7 +5709,7 @@
 								if((error = alGetError()) != AL_NO_ERROR)
 								{
 									fprintf(stderr, "58aTesting error: %s\n",
-										aluGetErrorString(error));				
+										alGetString(error));				
 									error_flag--;
 								}
 							}
@@ -5313,7 +5722,7 @@
 							if((error = alGetError()) != AL_NO_ERROR)
 							{
 								fprintf(stderr, "55Tbesting 8rror: %s\n",
-									aluGetErrorString(error));				
+									alGetString(error));				
 							}
 					}
 					continue;
@@ -5331,7 +5740,7 @@
 					 * buffers as they come in. */
 					if(buffers_processed > 0)
 					{
-						Sint32 temp_count;
+						ALint temp_count;
 						/* Do as a for-loop because I don't want
 						 * to have to create an array for the 
 						 * unqueued_buffer_id's
@@ -5346,7 +5755,7 @@
 							if((error = alGetError()) != AL_NO_ERROR)
 							{
 								fprintf(stderr, "59Testing error: %s\n",
-										aluGetErrorString(error));				
+										alGetString(error));				
 							}
 						}
 						fprintf(stderr, "done unqueuing remainder for this loop, %d\n", temp_count);
@@ -5362,7 +5771,7 @@
 						if((error = alGetError()) != AL_NO_ERROR)
 						{
 							fprintf(stderr, "5100Testing error: %s\n",
-									aluGetErrorString(error));				
+									alGetString(error));				
 						}
 						/* Get the number of buffers processed
 							* so we know if we need to refill 
@@ -5374,7 +5783,7 @@
 						if((error = alGetError()) != AL_NO_ERROR)
 						{
 							fprintf(stderr, "5200Testing error: %s\n",
-									aluGetErrorString(error));				
+									alGetString(error));				
 						}
 					}
 
@@ -5399,7 +5808,7 @@
 	if((error = alGetError()) != AL_NO_ERROR)
 	{
 		fprintf(stderr, "60Testing error: %s\n",
-			aluGetErrorString(error));				
+			alGetString(error));				
 	}
 						if(AL_STOPPED == state)
 						{
@@ -5414,7 +5823,7 @@
 							Is_Playing_global--;
 	
 							/* Launch callback */
-							Invoke_Channel_Done_Callback(i);
+							Invoke_Channel_Done_Callback(i, AL_TRUE);
 	
 							/* We're done for this loop.
 							 * Go to next channel 
@@ -5436,7 +5845,7 @@
 	if((error = alGetError()) != AL_NO_ERROR)
 	{
 		fprintf(stderr, "61Testing error: %s\n",
-			aluGetErrorString(error));				
+			alGetString(error));				
 	}
 						if(AL_STOPPED == state)
 						{
@@ -5473,11 +5882,13 @@
 	if((error = alGetError()) != AL_NO_ERROR)
 	{
 		fprintf(stderr, "62Testing error: %s\n",
-			aluGetErrorString(error));				
-	}
-#endif
-
-	SDL_UnlockMutex(simple_lock);
+			alGetString(error));				
+	}
+#endif
+
+#ifdef ENABLE_ALMIXER_THREADS
+	SDL_UnlockMutex(s_simpleLock);
+#endif
 	/* Return the number of errors */
 	if(error_flag < 0) 
 	{
@@ -5489,7 +5900,7 @@
 
 #ifdef ENABLE_PARANOID_SIGNEDNESS_CHECK
 /* This is only here so we can call SDL_OpenAudio() */
-static void my_dummy_audio_callback(void* userdata, Uint8* stream, int len)
+static void my_dummy_audio_callback(void* userdata, ALbyte* stream, int len)
 {
 }
 #endif
@@ -5509,7 +5920,7 @@
 
 static int Stream_Data_Thread_Callback(void* data)
 {
-	Sint32 retval;
+	ALint retval;
 	
 	while(ALmixer_Initialized)
 	{
@@ -5525,12 +5936,12 @@
 			/* Make sure times are multiples of 10
 			 * for optimal performance and accuracy in Linux
 			 */
-			SDL_Delay(10);
+			ALmixer_Delay(10);
 		}
 		else
 		{
 			/* should I also be sleeping/yielding here? */
-			SDL_Delay(0);
+			ALmixer_Delay(0);
 		}
 	}
 fprintf(stderr, "Thread is closing\n");
@@ -5539,19 +5950,20 @@
 #endif /* End of ENABLE_ALMIXER_THREADS */
 
 
-/* Using -1 on error and 0 on success to follow SDL/SDL_mixer conventions,
- * though I actually prefer 0/1 conventions (SDL_Sound/OpenAL/GL).
+/* SDL/SDL_mixer returns -1 on error and 0 on success.
+ * I actually prefer false/true conventions (SDL_Sound/OpenAL/GL)
+ * so SDL_mixer porting people beware.
  * Warning: SDL_QuitSubSystem(SDL_INIT_AUDIO) is called which
  * means the SDL audio system will be disabled. It will not
  * be restored (in case SDL is not actually being used) so
  * the user will need to restart it if they need it after
  * OpenAL shuts down.
  */
-Sint32 ALmixer_Init(Uint32 frequency, Sint32 num_sources, Uint32 refresh)
+ALboolean ALmixer_Init(ALuint frequency, ALint num_sources, ALuint refresh)
 {
 	ALCdevice* dev;
 	ALCcontext* context;
-	Sint32 i;
+	ALint i;
 	ALenum error;
 	ALuint* source;
 
@@ -5624,6 +6036,7 @@
 	 * want it in the list so I can get the OpenAL defaults
 	 */
 	ALint attrlist[7];
+	ALsizei current_attrlist_index = 0;
 
 #ifdef ENABLE_PARANOID_SIGNEDNESS_CHECK
 	/* More problems: I'm getting bit by endian/signedness issues on
@@ -5654,12 +6067,10 @@
 #endif
 
 
-
-
 	/* Make sure ALmixer isn't already initialized */
 	if(ALmixer_Initialized)
 	{
-		return -1;
+		return AL_FALSE;
 	}
 #ifdef USING_LOKI_AL_DIST
 fprintf(stderr, "Found Loki dist\n");
@@ -5670,7 +6081,31 @@
 fprintf(stderr, "Found Nvidia dist\n");
 #endif
 
+#ifdef ALMIXER_COMPILE_WITHOUT_SDL
+	ALmixer_InitTime();
+
+	/* Note: The pool may have been created on previous Init's */
+	/* I leave the pool allocated allocated in case the user wants
+	 * to read the pool in case of a failure (such as in this function).
+	 * This is not actually a leak.
+	 */
+	if(NULL == s_ALmixerErrorPool)
+	{
+		s_ALmixerErrorPool = TError_CreateErrorPool();
+	}
+	if(NULL == s_ALmixerErrorPool)
+	{
+		return AL_FALSE;
+	}
+		fprintf(stderr, "tError Test0\n");
+		ALmixer_SetError("Initing (and testing SetError)");
+		fprintf(stderr, "tError Test1: %s\n", ALmixer_GetError());
+		fprintf(stderr, "tError Test2: %s\n", ALmixer_GetError());
+#endif
+
+
 	/* Set the defaults */
+/*
 	attrlist[0] = ALC_FREQUENCY;
 	attrlist[1] = ALMIXER_DEFAULT_FREQUENCY;
 	attrlist[2] = ALC_SYNC;
@@ -5679,45 +6114,43 @@
 #else
 	attrlist[3] = ALC_FALSE;
 #endif
-	
+*/	
 	/* Set frequency value if it is not 0 */
 	if(0 != frequency)
 	{
-		attrlist[1] = (ALint)frequency;
-	}
+		attrlist[current_attrlist_index] = ALC_FREQUENCY;
+		current_attrlist_index++;
+		attrlist[current_attrlist_index] = (ALint)frequency;
+		current_attrlist_index++;
+	}
+
+#ifdef ENABLE_ALMIXER_ALC_SYNC	
+		attrlist[current_attrlist_index] = ALC_SYNC;
+		current_attrlist_index++;
+		attrlist[current_attrlist_index] = ALC_TRUE;
+		current_attrlist_index++;
+#endif
 
 	/* If the user specifies a refresh value,
 	 * make room for it 
 	 */
 	if(0 != refresh)
 	{
-		attrlist[4] = (ALint)ALC_REFRESH;
-		attrlist[5] = refresh;
-		attrlist[6] = '\0';
-	}
-	/* Terminate the list without any refresh values */
-	else
-	{
-		attrlist[4] = '\0';
+		attrlist[current_attrlist_index] = (ALint)ALC_REFRESH;
+		current_attrlist_index++;
+		attrlist[current_attrlist_index] = refresh;
+		current_attrlist_index++;		
 	}
 			
-	/* It looks like OpenAL won't let us ask it what 
-	 * the set frequency is, so we need to save our
-	 * own copy. Yuck.
-	 * Update: J. Valenzuela just updated the Loki 
-	 * dist (2003/01/02) to handle this.
-	 * The demo is in testattrib.c. However, this
-	 * looks kind of cumbersome to parse, and I've
-	 * already put this in my code, so I guess I'll 
-	 * leave it for now.
-	 */
-	ALmixer_Frequency_global = attrlist[1];
-	
+	/* End attribute list */
+	attrlist[current_attrlist_index] = '\0';
+
+
 	/* Initialize SDL_Sound */
 	if(! Sound_Init() )
 	{
 		ALmixer_SetError(Sound_GetError());
-		return -1;
+		return AL_FALSE;
 	}
 #ifdef ENABLE_PARANOID_SIGNEDNESS_CHECK
 	/* Here is the paranoid check that opens
@@ -5760,6 +6193,8 @@
 		SIGN_TYPE_8_BIT_FORMAT = AUDIO_S8;
 	}
 #endif
+
+#ifndef ALMIXER_COMPILE_WITHOUT_SDL
 	/* Weirdness: It seems that SDL_Init(SDL_INIT_AUDIO)
 	 * causes OpenAL and SMPEG to conflict. For some reason
 	 * if SDL_Init on audio is active, then all the SMPEG
@@ -5770,7 +6205,8 @@
 	 * SDL_Sound::Init call and hope it doesn't break SDL_Sound.
 	 */
 	SDL_QuitSubSystem(SDL_INIT_AUDIO);
-	
+#endif
+
 	/* I'm told NULL will call the default string
 	 * and hopefully do the right thing for each platform 
 	 */
@@ -5796,15 +6232,26 @@
 	if(NULL == dev)
 	{
 		ALmixer_SetError("Cannot open sound device for OpenAL");
-		return -1;
-	}
+		return AL_FALSE;
+	}
+
+#ifdef __APPLE__
+	/* The ALC_FREQUENCY attribute is ignored with Apple's implementation. */
+	/* This extension must be called before the context is created. */
+	if(0 != frequency)
+	{
+		Internal_alcMacOSXMixerOutputRate((ALdouble)frequency);
+	}
+	ALmixer_Frequency_global = (ALuint)Internal_alcMacOSXGetMixerOutputRate();
+		fprintf(stderr, "Internal_alcMacOSXMixerOutputRate is: %lf", Internal_alcMacOSXGetMixerOutputRate());
+#endif
 	
 	context = alcCreateContext(dev, attrlist);
 	if(NULL == context)
 	{
 		ALmixer_SetError("Cannot create a context OpenAL");
 		alcCloseDevice(dev);
-		return -1;
+		return AL_FALSE;
 	}
 	fprintf(stderr, "Context checking...\n");
 
@@ -5826,10 +6273,25 @@
 		ALmixer_SetError("Could not MakeContextCurrent");
 		alcDestroyContext(context);
 		alcCloseDevice(dev);
-		return -1;
-	}
-	
-	
+		return AL_FALSE;
+	}
+	
+	/* It looks like OpenAL won't let us ask it what 
+	 * the set frequency is, so we need to save our
+	 * own copy. Yuck.
+	 * Update: J. Valenzuela just updated the Loki 
+	 * dist (2003/01/02) to handle this.
+	 * The demo is in testattrib.c. 
+	 */
+/*
+	ALmixer_Frequency_global = frequency;
+*/
+#ifndef __APPLE__
+	alcGetIntegerv(dev, ALC_FREQUENCY, 1, &ALmixer_Frequency_global);
+	fprintf(stderr, "alcGetIntegerv ALC_FREQUENCY is: %d", ALmixer_Frequency_global);
+#endif
+	
+
 #if 0
 	/* OSX is failing on alcMakeContextCurrent(). Try checking it first? */
 	if(alcGetCurrentContext() != context)
@@ -5850,7 +6312,7 @@
 			ALmixer_SetError("Could not MakeContextCurrent");
 			alcDestroyContext(context);
 			alcCloseDevice(dev);
-			return -1;
+			return AL_FALSE;
 		}
 	}
 #endif
@@ -5873,7 +6335,23 @@
 	 *	calls to alBufferData().
 	 */	
 #ifdef __APPLE__
-	alEnable(ALC_MAC_OSX_CONVERT_DATA_UPON_LOADING);
+/*
+	#if (TARGET_OS_IPHONE == 1) || (TARGET_IPHONE_SIMULATOR == 1)
+
+	#else
+	#endif
+*/
+	ALenum convert_data_enum = alcGetEnumValue(dev, "ALC_MAC_OSX_CONVERT_DATA_UPON_LOADING");
+	fprintf(stderr, "ALC_MAC_OSX_CONVERT_DATA_UPON_LOADING=0x%x", convert_data_enum);
+	if(0 != convert_data_enum)
+	{
+		alEnable(convert_data_enum);		
+	}
+	if( (AL_NO_ERROR != alGetError()) )
+	{
+		ALmixer_SetError("ALC_MAC_OSX_CONVERT_DATA_UPON_LOADING attempted but failed");
+	}
+	
 #endif
 	
 
@@ -5906,7 +6384,7 @@
 		alcCloseDevice(dev);
 		ALmixer_Initialized = 0;
 		Number_of_Channels_global = 0;
-		return -1;
+		return AL_FALSE;
 	}
 
 	/* Allocate memory for the list of sources that map to the channels */
@@ -5919,7 +6397,7 @@
 		alcCloseDevice(dev);
 		ALmixer_Initialized = 0;
 		Number_of_Channels_global = 0;
-		return -1;
+		return AL_FALSE;
 	}
 
 	/* Create array that will hold the sources */
@@ -5933,7 +6411,7 @@
 		alcCloseDevice(dev);
 		ALmixer_Initialized = 0;
 		Number_of_Channels_global = 0;
-		return -1;
+		return AL_FALSE;
 	}	
 
 	/* Clear the error state */
@@ -5942,14 +6420,14 @@
 	alGenSources(Number_of_Channels_global, source);
 	if( (error=alGetError()) != AL_NO_ERROR)
 	{
-		ALmixer_SetError("Couldn't generate sources: %s\n", aluGetErrorString(error));
+		ALmixer_SetError("Couldn't generate sources: %s\n", alGetString(error));
 		free(ALmixer_Channel_List);
 		free(Source_Map_List);
 		alcDestroyContext(context);
 		alcCloseDevice(dev);
 		ALmixer_Initialized = 0;
 		Number_of_Channels_global = 0;
-		return -1;
+		return AL_FALSE;
 	}
 	
 	/* Initialize each channel and associate one source to one channel */
@@ -5988,9 +6466,11 @@
 		fprintf(stderr, "Source: %d, Channel: %d\n", Source_Map_List[i].source, Source_Map_List[i].channel);
 	}
 	fprintf(stderr, "\n");
-	
-	simple_lock = SDL_CreateMutex();
-	if(NULL == simple_lock)
+	ALmixer_OutputDecoders();
+
+#ifdef ENABLE_ALMIXER_THREADS
+	s_simpleLock = SDL_CreateMutex();
+	if(NULL == s_simpleLock)
 	{
 		/* SDL sets the error message already? */
 		free(source);
@@ -6000,16 +6480,15 @@
 		alcCloseDevice(dev);
 		ALmixer_Initialized = 0;
 		Number_of_Channels_global = 0;
-		return -1;
+		return AL_FALSE;
 	}
 		
 
-#ifdef ENABLE_ALMIXER_THREADS
 	Stream_Thread_global = SDL_CreateThread(Stream_Data_Thread_Callback, NULL);
 	if(NULL == Stream_Thread_global)
 	{
 		/* SDL sets the error message already? */
-		SDL_DestroyMutex(simple_lock);
+		SDL_DestroyMutex(s_simpleLock);
 		free(source);
 		free(ALmixer_Channel_List);
 		free(Source_Map_List);
@@ -6017,7 +6496,7 @@
 		alcCloseDevice(dev);
 		ALmixer_Initialized = 0;
 		Number_of_Channels_global = 0;
-		return -1;
+		return AL_FALSE;
 	}
 		
 	fprintf(stderr, "Using threads\n");
@@ -6027,11 +6506,11 @@
 	 * are connected to channels
 	 */
 	free(source);
-	return 0;
-}
-
-	
-Sint32 ALmixer_Init_Context(Uint32 frequency, Uint32 refresh)
+	return AL_TRUE;
+}
+
+	
+ALboolean ALmixer_InitContext(ALuint frequency, ALuint refresh)
 {
 	ALCdevice* dev;
 	ALCcontext* context;
@@ -6106,6 +6585,7 @@
 	 * want it in the list so I can get the OpenAL defaults
 	 */
 	ALint attrlist[7];
+	ALsizei current_attrlist_index = 0;
 
 #ifdef ENABLE_PARANOID_SIGNEDNESS_CHECK
 	/* More problems: I'm getting bit by endian/signedness issues on
@@ -6141,7 +6621,7 @@
 	/* Make sure ALmixer isn't already initialized */
 	if(ALmixer_Initialized)
 	{
-		return -1;
+		return AL_FALSE;
 	}
 #ifdef USING_LOKI_AL_DIST
 fprintf(stderr, "Found Loki dist\n");
@@ -6161,45 +6641,43 @@
 #else
 	attrlist[3] = ALC_FALSE;
 #endif
-	
 	/* Set frequency value if it is not 0 */
 	if(0 != frequency)
 	{
-		attrlist[1] = (ALint)frequency;
-	}
+		attrlist[current_attrlist_index] = ALC_FREQUENCY;
+		current_attrlist_index++;
+		attrlist[current_attrlist_index] = (ALint)frequency;
+		current_attrlist_index++;
+	}
+
+#ifdef ENABLE_ALMIXER_ALC_SYNC	
+		attrlist[current_attrlist_index] = ALC_SYNC;
+		current_attrlist_index++;
+		attrlist[current_attrlist_index] = ALC_TRUE;
+		current_attrlist_index++;
+#endif
 
 	/* If the user specifies a refresh value,
 	 * make room for it 
 	 */
 	if(0 != refresh)
 	{
-		attrlist[4] = (ALint)ALC_REFRESH;
-		attrlist[5] = refresh;
-		attrlist[6] = '\0';
-	}
-	/* Terminate the list without any refresh values */
-	else
-	{
-		attrlist[4] = '\0';
+		attrlist[current_attrlist_index] = (ALint)ALC_REFRESH;
+		current_attrlist_index++;
+		attrlist[current_attrlist_index] = refresh;
+		current_attrlist_index++;		
 	}
 			
-	/* It looks like OpenAL won't let us ask it what 
-	 * the set frequency is, so we need to save our
-	 * own copy. Yuck.
-	 * Update: J. Valenzuela just updated the Loki 
-	 * dist (2003/01/02) to handle this.
-	 * The demo is in testattrib.c. However, this
-	 * looks kind of cumbersome to parse, and I've
-	 * already put this in my code, so I guess I'll 
-	 * leave it for now.
-	 */
-	ALmixer_Frequency_global = attrlist[1];
-	
+	/* End attribute list */
+	attrlist[current_attrlist_index] = '\0';
+
+
+
 	/* Initialize SDL_Sound */
 	if(! Sound_Init() )
 	{
 		ALmixer_SetError(Sound_GetError());
-		return -1;
+		return AL_FALSE;
 	}
 #ifdef ENABLE_PARANOID_SIGNEDNESS_CHECK
 	/* Here is the paranoid check that opens
@@ -6242,6 +6720,8 @@
 		SIGN_TYPE_8_BIT_FORMAT = AUDIO_S8;
 	}
 #endif
+
+#ifndef ALMIXER_COMPILE_WITHOUT_SDL
 	/* Weirdness: It seems that SDL_Init(SDL_INIT_AUDIO)
 	 * causes OpenAL and SMPEG to conflict. For some reason
 	 * if SDL_Init on audio is active, then all the SMPEG
@@ -6252,7 +6732,8 @@
 	 * SDL_Sound::Init call and hope it doesn't break SDL_Sound.
 	 */
 	SDL_QuitSubSystem(SDL_INIT_AUDIO);
-	
+#endif
+
 	/* I'm told NULL will call the default string
 	 * and hopefully do the right thing for each platform 
 	 */
@@ -6278,15 +6759,27 @@
 	if(NULL == dev)
 	{
 		ALmixer_SetError("Cannot open sound device for OpenAL");
-		return -1;
-	}
+		return AL_FALSE;
+	}
+
+#ifdef __APPLE__
+	/* The ALC_FREQUENCY attribute is ignored with Apple's implementation. */
+	/* This extension must be called before the context is created. */
+	if(0 != frequency)
+	{
+		Internal_alcMacOSXMixerOutputRate((ALdouble)frequency);
+	}
+	ALmixer_Frequency_global = (ALuint)Internal_alcMacOSXGetMixerOutputRate();
+		fprintf(stderr, "Internal_alcMacOSXMixerOutputRate is: %lf", Internal_alcMacOSXGetMixerOutputRate());
+#endif
+	
 	
 	context = alcCreateContext(dev, attrlist);
 	if(NULL == context)
 	{
 		ALmixer_SetError("Cannot create a context OpenAL");
 		alcCloseDevice(dev);
-		return -1;
+		return AL_FALSE;
 	}
 
 
@@ -6307,7 +6800,7 @@
 		ALmixer_SetError("Could not MakeContextCurrent");
 		alcDestroyContext(context);
 		alcCloseDevice(dev);
-		return -1;
+		return AL_FALSE;
 	}
 
 
@@ -6331,11 +6824,24 @@
 			ALmixer_SetError("Could not MakeContextCurrent");
 			alcDestroyContext(context);
 			alcCloseDevice(dev);
-			return -1;
-		}
-
-	}
-#endif
+			return AL_FALSE;
+		}
+
+	}
+#endif
+		
+	/* It looks like OpenAL won't let us ask it what 
+	 * the set frequency is, so we need to save our
+	 * own copy. Yuck.
+	 * Update: J. Valenzuela just updated the Loki 
+	 * dist (2003/01/02) to handle this.
+	 * The demo is in testattrib.c. 
+	 */
+#ifndef __APPLE__
+	alcGetIntegerv(dev, ALC_FREQUENCY, 1, &ALmixer_Frequency_global);
+	fprintf(stderr, "alcGetIntegerv ALC_FREQUENCY is: %d", ALmixer_Frequency_global);
+#endif
+	
 
 	fprintf(stderr, "done Context\n");
 
@@ -6354,22 +6860,62 @@
 	 *	calls to alBufferData().
 	 */	
 #ifdef __APPLE__
-	alEnable(ALC_MAC_OSX_CONVERT_DATA_UPON_LOADING);
-#endif
-	
-	return 0;
-}
-
-	
-Sint32 ALmixer_Init_Mixer(Sint32 num_sources)
+	/*
+	 #if (TARGET_OS_IPHONE == 1) || (TARGET_IPHONE_SIMULATOR == 1)
+	 
+	 #else
+	 #endif
+	 */
+	ALenum convert_data_enum = alcGetEnumValue(dev, "ALC_MAC_OSX_CONVERT_DATA_UPON_LOADING");
+	fprintf(stderr, "ALC_MAC_OSX_CONVERT_DATA_UPON_LOADING=0x%x", convert_data_enum);
+	if(0 != convert_data_enum)
+	{
+		alEnable(convert_data_enum);		
+	}
+	if( (AL_NO_ERROR != alGetError()) )
+	{
+		ALmixer_SetError("ALC_MAC_OSX_CONVERT_DATA_UPON_LOADING attempted but failed");
+	}
+#endif
+	
+	return AL_TRUE;
+}
+
+	
+ALboolean ALmixer_InitMixer(ALint num_sources)
 {	
-	Sint32 i;
+	ALint i;
 	ALenum error;
 	ALuint* source;
 
 
 	ALmixer_Initialized = 1;
 
+
+#ifdef ALMIXER_COMPILE_WITHOUT_SDL
+	ALmixer_InitTime();
+
+	/* Note: The pool may have been created on previous Init's */
+	/* I leave the pool allocated allocated in case the user wants
+	 * to read the pool in case of a failure (such as in this function).
+	 * This is not actually a leak.
+	 */
+	if(NULL == s_ALmixerErrorPool)
+	{
+		s_ALmixerErrorPool = TError_CreateErrorPool();
+	}
+	if(NULL == s_ALmixerErrorPool)
+	{
+		return AL_FALSE;
+	}
+	/*
+		fprintf(stderr, "tError Test0\n");
+		ALmixer_SetError("Initing (and testing SetError)");
+		fprintf(stderr, "tError Test1: %s\n", ALmixer_GetError());
+		fprintf(stderr, "tError Test2: %s\n", ALmixer_GetError());
+	 */
+#endif
+
 	if(num_sources <= 0)
 	{
 		Number_of_Channels_global = ALMIXER_DEFAULT_NUM_CHANNELS;
@@ -6393,7 +6939,7 @@
 		ALmixer_SetError("Out of Memory for Channel List");
 		ALmixer_Initialized = 0;
 		Number_of_Channels_global = 0;
-		return -1;
+		return AL_FALSE;
 	}
 
 	/* Allocate memory for the list of sources that map to the channels */
@@ -6404,7 +6950,7 @@
 		free(ALmixer_Channel_List);
 		ALmixer_Initialized = 0;
 		Number_of_Channels_global = 0;
-		return -1;
+		return AL_FALSE;
 	}
 
 	/* Create array that will hold the sources */
@@ -6416,7 +6962,7 @@
 		free(ALmixer_Channel_List);
 		ALmixer_Initialized = 0;
 		Number_of_Channels_global = 0;
-		return -1;
+		return AL_FALSE;
 	}	
 
 	/* Clear the error state */
@@ -6425,12 +6971,12 @@
 	alGenSources(Number_of_Channels_global, source);
 	if( (error=alGetError()) != AL_NO_ERROR)
 	{
-		ALmixer_SetError("Couldn't generate sources: %s\n", aluGetErrorString(error));
+		ALmixer_SetError("Couldn't generate sources: %s\n", alGetString(error));
 		free(ALmixer_Channel_List);
 		free(Source_Map_List);
 		ALmixer_Initialized = 0;
 		Number_of_Channels_global = 0;
-		return -1;
+		return AL_FALSE;
 	}
 	
 	/* Initialize each channel and associate one source to one channel */
@@ -6465,8 +7011,11 @@
 	}
 	fprintf(stderr, "\n");
 	
-	simple_lock = SDL_CreateMutex();
-	if(NULL == simple_lock)
+	
+	
+#ifdef ENABLE_ALMIXER_THREADS
+	s_simpleLock = SDL_CreateMutex();
+	if(NULL == s_simpleLock)
 	{
 		/* SDL sets the error message already? */
 		free(source);
@@ -6474,22 +7023,21 @@
 		free(Source_Map_List);
 		ALmixer_Initialized = 0;
 		Number_of_Channels_global = 0;
-		return -1;
+		return AL_FALSE;
 	}
 		
 
-#ifdef ENABLE_ALMIXER_THREADS
 	Stream_Thread_global = SDL_CreateThread(Stream_Data_Thread_Callback, NULL);
 	if(NULL == Stream_Thread_global)
 	{
 		/* SDL sets the error message already? */
-		SDL_DestroyMutex(simple_lock);
+		SDL_DestroyMutex(s_simpleLock);
 		free(source);
 		free(ALmixer_Channel_List);
 		free(Source_Map_List);
 		ALmixer_Initialized = 0;
 		Number_of_Channels_global = 0;
-		return -1;
+		return AL_FALSE;
 	}
 		
 	fprintf(stderr, "Using threads\n");
@@ -6499,7 +7047,7 @@
 	 * are connected to channels
 	 */
 	free(source);
-	return 0;
+	return AL_TRUE;
 }
 
 
@@ -6511,29 +7059,29 @@
 {
 	ALCcontext* context;
 	ALCdevice* dev;
-	Sint32 i;
+	ALint i;
 	
 	if( ! ALmixer_Initialized)
 	{
 		return;
 	}
-
-	SDL_LockMutex(simple_lock);
-	
+#ifdef ENABLE_ALMIXER_THREADS
+	SDL_LockMutex(s_simpleLock);
+#endif
 	/* Shutdown everything before closing context */
 	fprintf(stderr, "Halting channels\n");
-	Internal_HaltChannel(-1);
+	Internal_HaltChannel(-1, AL_FALSE);
 	
 	/* This flag will cause the thread to terminate */
 	ALmixer_Initialized = 0;
-	SDL_UnlockMutex(simple_lock);
 #ifdef ENABLE_ALMIXER_THREADS
+	SDL_UnlockMutex(s_simpleLock);
 	fprintf(stderr, "Closing thread\n");
 	SDL_WaitThread(Stream_Thread_global, NULL);
-#endif
 
 	fprintf(stderr, "Destroying mutex\n");
-	SDL_DestroyMutex(simple_lock);
+	SDL_DestroyMutex(s_simpleLock);
+#endif
 
 	fprintf(stderr, "Deleting OpenAL sources\n");
 	/* Delete all the OpenAL sources */
@@ -6570,32 +7118,73 @@
 	
 	Sound_Quit();
 
+#ifdef ALMIXER_COMPILE_WITHOUT_SDL
+	/* Remember: ALmixer_SetError/GetError calls will not work while this is gone. */
+	TError_FreeErrorPool(s_ALmixerErrorPool);
+	s_ALmixerErrorPool = NULL;
+#endif
 	return;
 }
 
-SDL_bool ALmixer_IsInitialized()
+ALboolean ALmixer_IsInitialized()
 {
 	return ALmixer_Initialized;
 }
 
-Uint32 ALmixer_GetFrequency()
+ALuint ALmixer_GetFrequency()
 {
 	return ALmixer_Frequency_global;
 }
 
-const SDL_version* ALmixer_Linked_Version()
-{
-	static SDL_version linked_mixver;
-	ALMIXER_VERSION(&linked_mixver);
+const ALmixer_version* ALmixer_GetLinkedVersion()
+{
+	static ALmixer_version linked_mixver;
+	ALMIXER_GET_COMPILED_VERSION(&linked_mixver);
 	return(&linked_mixver);
 }
 
+#ifdef ALMIXER_COMPILE_WITHOUT_SDL
+
+const char* ALmixer_GetError()
+{
+	const char* error_string = NULL;
+	if(NULL == s_ALmixerErrorPool)
+	{
+		return "Error: You should not call ALmixer_GetError while ALmixer is not initialized";
+	}
+	error_string = TError_GetLastErrorStr(s_ALmixerErrorPool);
+	/* SDL returns empty strings instead of NULL */
+	if(NULL == error_string)
+	{
+		return "";
+	}
+	else
+	{
+		return error_string;
+	}
+}
+
+void ALmixer_SetError(const char* err_str, ...)
+{
+	if(NULL == s_ALmixerErrorPool)
+	{
+		fprintf(stderr, "Error: You should not call ALmixer_SetError while ALmixer is not initialized\n");
+		return;
+	}
+	va_list argp;
+	va_start(argp, err_str);
+	// SDL_SetError which I'm emulating has no number parameter.
+	TError_SetErrorv(s_ALmixerErrorPool, 1, err_str, argp);
+	va_end(argp);
+}
+
+#endif
 
 
 
 
 #if 0
-void ALmixer_Output_Attributes()
+void ALmixer_OutputAttributes()
 {
 	ALint num_flags = 0;
 	ALint* flags = 0;
@@ -6628,7 +7217,7 @@
 #endif
 
 
-void ALmixer_Output_Decoders()
+void ALmixer_OutputDecoders()
 {
 	Sound_Version sound_compile_version;
 	Sound_Version sound_link_version;
@@ -6673,10 +7262,10 @@
 	fprintf(stream, "\n");
 } 
 
-void ALmixer_Output_OpenAL_Info()
-{
-	SDL_version mixer_compile_version;
-	const SDL_version * mixer_link_version=ALmixer_Linked_Version();
+void ALmixer_OutputOpenALInfo()
+{
+	ALmixer_version mixer_compile_version;
+	const ALmixer_version * mixer_link_version=ALmixer_GetLinkedVersion();
 	FILE* stream = stdout;
 
 	fprintf(stream, "OpenAL Information:\n");
@@ -6685,7 +7274,7 @@
 	fprintf(stream, "\tAL_RENDERER: %s\n", alGetString( AL_RENDERER ) );
 	fprintf(stream, "\tAL_EXTENSIONS: %s\n", alGetString( AL_EXTENSIONS ) );
 
-	ALMIXER_VERSION(&mixer_compile_version);
+	ALMIXER_GET_COMPILED_VERSION(&mixer_compile_version);
 	fprintf(stream, "\nSDL_ALmixer Information:\n");
 	fprintf(stream, "\tCompiled with SDL_ALmixer version: %d.%d.%d\n",
 		mixer_compile_version.major,
@@ -6711,31 +7300,39 @@
 }
 
 
-Sint32 ALmixer_AllocateChannels(Sint32 numchans)
-{
-	Sint32 retval;
-	SDL_LockMutex(simple_lock);
+ALint ALmixer_AllocateChannels(ALint numchans)
+{
+	ALint retval;
+#ifdef ENABLE_ALMIXER_THREADS
+	SDL_LockMutex(s_simpleLock);
+#endif
 	retval = Internal_AllocateChannels(numchans);
-	SDL_UnlockMutex(simple_lock);
+#ifdef ENABLE_ALMIXER_THREADS
+	SDL_UnlockMutex(s_simpleLock);
+#endif
 	return retval;
 }
 
 	
-Sint32 ALmixer_ReserveChannels(Sint32 num)
-{
-	Sint32 retval;
-	SDL_LockMutex(simple_lock);
+ALint ALmixer_ReserveChannels(ALint num)
+{
+	ALint retval;
+#ifdef ENABLE_ALMIXER_THREADS
+	SDL_LockMutex(s_simpleLock);
+#endif
 	retval = Internal_ReserveChannels(num);
-	SDL_UnlockMutex(simple_lock);
+#ifdef ENABLE_ALMIXER_THREADS
+	SDL_UnlockMutex(s_simpleLock);
+#endif
 	return retval;
 }
 
 	
 
 
-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)
-{
-	Uint32 bytes_decoded;
+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)
+{
+	ALuint bytes_decoded;
 	ALmixer_Data* ret_data;
 	ALenum error;
 
@@ -6795,7 +7392,7 @@
 	/* Different cases for Streamed and Predecoded 
 	 * Streamed might turn into a predecoded if buffersize
 	 * is large enough */
-	if(SDL_FALSE == decode_mode_is_predecoded)
+	if(AL_FALSE == decode_mode_is_predecoded)
 	{
 		bytes_decoded = Sound_Decode(sample);
 		if(sample->flags & SOUND_SAMPLEFLAG_ERROR)
@@ -6881,7 +7478,7 @@
 			alGenBuffers(1, ret_data->buffer);
 			if( (error = alGetError()) != AL_NO_ERROR)
 			{
-				ALmixer_SetError("alGenBuffers failed: %s\n", aluGetErrorString(error));
+				ALmixer_SetError("alGenBuffers failed: %s\n", alGetString(error));
 				Sound_FreeSample(sample);
 				free(ret_data->buffer);
 				free(ret_data);
@@ -6900,7 +7497,7 @@
 			);
 			if( (error = alGetError()) != AL_NO_ERROR)
 			{
-				ALmixer_SetError("alBufferData failed: %s\n", aluGetErrorString(error));
+				ALmixer_SetError("alBufferData failed: %s\n", alGetString(error));
 				Sound_FreeSample(sample);
 				alDeleteBuffers(1, ret_data->buffer);
 				free(ret_data->buffer);
@@ -6982,7 +7579,7 @@
 			alGenBuffers(max_queue_buffers, ret_data->buffer);
 			if( (error = alGetError()) != AL_NO_ERROR)
 			{
-				ALmixer_SetError("alGenBuffers failed: %s\n", aluGetErrorString(error));
+				ALmixer_SetError("alGenBuffers failed: %s\n", alGetString(error));
 				Sound_FreeSample(sample);
 				free(ret_data->buffer);
 				free(ret_data);
@@ -7032,7 +7629,7 @@
 			 */
 			if(access_data)
 			{
-				Uint32 j;
+				ALuint j;
 				/* Create buffers for data access
 				 * Should be the same number as the number of queue buffers
 				 */
@@ -7063,7 +7660,7 @@
 					ret_data->buffer_map_list[j].albuffer = ret_data->buffer[j];
 					ret_data->buffer_map_list[j].index = j;
 					ret_data->buffer_map_list[j].num_bytes = 0;
-					ret_data->buffer_map_list[j].data = (Uint8*)malloc( sizeof(Uint8) * buffersize);
+					ret_data->buffer_map_list[j].data = (ALbyte*)malloc( sizeof(ALbyte) * buffersize);
 					if(NULL == ret_data->buffer_map_list[j].data)
 					{
 						ALmixer_SetError("Out of Memory");
@@ -7095,8 +7692,35 @@
 		} /* End of do stream */
 	} /* end of DECODE_STREAM */
 	/* User requested decode all (easy, nothing to figure out) */
-	else if(SDL_TRUE == decode_mode_is_predecoded)
-	{
+	else if(AL_TRUE == decode_mode_is_predecoded)
+	{
+#ifndef ALMIXER_DISABLE_PREDECODED_PRECOMPUTE_BUFFER_SIZE_OPTIMIZATION
+		/* SDL_sound (behind the scenes) seems to loop on buffer_size chunks 
+		 * until the buffer is filled. It seems like we can 
+		 * do much better and precompute the size of the buffer
+		 * so looping isn't needed.
+		 * WARNING: Due to the way SDL_sound is currently implemented,
+		 * this may waste a lot of memory up front.
+		 * SDL_sound seems to pre-create a buffer of the requested size,
+		 * but on DecodeAll, an entirely new buffer is created and 
+		 * everything is memcpy'd into the new buffer in read chunks
+		 * of the buffer_size. This means we need roughly twice the memory
+		 * to load a file.
+		 */
+		ALint sound_duration = Sound_GetDuration(sample);
+		if(sound_duration > 0)
+		{
+			size_t total_bytes = Compute_Total_Bytes_With_Frame_Padding(&sample->desired, (ALuint)sound_duration);
+			int buffer_resize_succeeded = Sound_SetBufferSize(sample, total_bytes);
+			if(0 == buffer_resize_succeeded)
+			{
+				ALmixer_SetError(Sound_GetError());
+				Sound_FreeSample(sample);
+				free(ret_data);
+				return NULL;
+			}
+		}
+#endif /* ALMIXER_DISABLE_PREDECODED_PRECOMPUTE_BUFFER_SIZE_OPTIMIZATION */
 		bytes_decoded = Sound_DecodeAll(sample);
 		if(sample->flags & SOUND_SAMPLEFLAG_ERROR)
 		{
@@ -7147,7 +7771,7 @@
 		alGenBuffers(1, ret_data->buffer);
 		if( (error = alGetError()) != AL_NO_ERROR)
 		{
-			ALmixer_SetError("alGenBuffers failed: %s\n", aluGetErrorString(error));
+			ALmixer_SetError("alGenBuffers failed: %s\n", alGetString(error));
 			Sound_FreeSample(sample);
 			free(ret_data->buffer);
 			free(ret_data);
@@ -7166,7 +7790,7 @@
 		);
 		if( (error = alGetError()) != AL_NO_ERROR)
 		{
-			ALmixer_SetError("alBufferData failed: %s\n", aluGetErrorString(error));
+			ALmixer_SetError("alBufferData failed: %s\n", alGetString(error));
 			Sound_FreeSample(sample);
 			alDeleteBuffers(1, ret_data->buffer);
 			free(ret_data->buffer);
@@ -7238,7 +7862,7 @@
  * must specify it, so I had to bring it back.
  * Remember I must close the rwops if there is an error before NewSample()
  */
-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)
+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)
 {
 	Sound_Sample* sample = NULL;
 	Sound_AudioInfo target;
@@ -7284,7 +7908,7 @@
  * error checking and the fact that streamed/predecoded files
  * must be treated differently.
  */
-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)
+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)
 {
 	Sound_Sample* sample = NULL;
 	Sound_AudioInfo target;
@@ -7385,7 +8009,7 @@
 /* This is a back door for RAW samples or if you need the
  * AudioInfo field. Use at your own risk.
  */
-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)
+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)
 {
 	Sound_Sample* sample = NULL;
 	Sound_AudioInfo sound_desired;
@@ -7421,7 +8045,7 @@
 /* This is a back door for RAW samples or if you need the
  * AudioInfo field. Use at your own risk.
  */
-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)
+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)
 {
 	Sound_Sample* sample = NULL;
 	Sound_AudioInfo sound_desired;
@@ -7476,13 +8100,13 @@
 	if((error = alGetError()) != AL_NO_ERROR)
 	{
 		fprintf(stderr, "70Testing error: %s\n",
-			aluGetErrorString(error));				
+			alGetString(error));				
 	}
 
 	}
 	else
 	{
-		Uint32 i;
+		ALuint i;
 		
 		/* Delete buffer copies if access_data was enabled */
 		if(data->buffer_map_list != NULL)
@@ -7503,45 +8127,61 @@
 	if((error = alGetError()) != AL_NO_ERROR)
 	{
 		fprintf(stderr, "71Testing error: %s\n",
-			aluGetErrorString(error));				
+			alGetString(error));				
 	}
 	}
 	free(data->buffer);
 	free(data);
 }
 
-Sint32 ALmixer_GetTotalTime(ALmixer_Data* data)
-{
+ALint ALmixer_GetTotalTime(ALmixer_Data* data)
+{
+	if(NULL == data)
+	{
+		return -1;
+	}
 	return data->total_time;
 }
 
 /* This function will look up the source for the corresponding channel */
 /* Must return 0 on error instead of -1 because of unsigned int */
-ALuint ALmixer_GetSource(Sint32 channel)
+ALuint ALmixer_GetSource(ALint channel)
 {
 	ALuint retval;
-	SDL_LockMutex(simple_lock);
+#ifdef ENABLE_ALMIXER_THREADS
+	SDL_LockMutex(s_simpleLock);
+#endif
 	retval = Internal_GetSource(channel);
-	SDL_UnlockMutex(simple_lock);
+#ifdef ENABLE_ALMIXER_THREADS	
+	SDL_UnlockMutex(s_simpleLock);
+#endif
 	return retval;
 }
 
 /* This function will look up the channel for the corresponding source */
-Sint32 ALmixer_GetChannel(ALuint source)
-{
-	Sint32 retval;
-	SDL_LockMutex(simple_lock);
+ALint ALmixer_GetChannel(ALuint source)
+{
+	ALint retval;
+#ifdef ENABLE_ALMIXER_THREADS
+	SDL_LockMutex(s_simpleLock);
+#endif
 	retval = Internal_GetChannel(source);
-	SDL_UnlockMutex(simple_lock);
+#ifdef ENABLE_ALMIXER_THREADS	
+	SDL_UnlockMutex(s_simpleLock);
+#endif
 	return retval;
 }
 
-Sint32 ALmixer_FindFreeChannel(Sint32 start_channel)
-{
-	Sint32 retval;
-	SDL_LockMutex(simple_lock);
+ALint ALmixer_FindFreeChannel(ALint start_channel)
+{
+	ALint retval;
+#ifdef ENABLE_ALMIXER_THREADS
+	SDL_LockMutex(s_simpleLock);
+#endif
 	retval = Internal_FindFreeChannel(start_channel);
-	SDL_UnlockMutex(simple_lock);
+#ifdef ENABLE_ALMIXER_THREADS	
+	SDL_UnlockMutex(s_simpleLock);
+#endif
 	return retval;
 }
 
@@ -7556,12 +8196,12 @@
  * when a buffer is queued, there was probably some
  * CPU intensive looping which took awhile.
  * It's mainly provided as a convenience.
- * Timing the call with SDL_GetTicks() would produce
+ * Timing the call with ALmixer_GetTicks() would produce
  * more accurate information.
  * Returns a negative value if there was an error,
  * the value being the number of errors.
  */
-Sint32 ALmixer_Update()
+ALint ALmixer_Update()
 {
 #ifdef ENABLE_ALMIXER_THREADS
 	/* The thread will handle all updates by itself.
@@ -7575,33 +8215,45 @@
 
 
 
-void ALmixer_ChannelFinished(void (*channel_finished)(Sint32 channel, void* userdata), void* userdata)
-{
-	SDL_LockMutex(simple_lock);
-	Channel_Done_Callback = channel_finished;
-	Channel_Done_Callback_Userdata = userdata;
-	SDL_UnlockMutex(simple_lock);
-}
-
-
-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)
-{
-	SDL_LockMutex(simple_lock);
-	Channel_Data_Callback = channel_data;
+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)
+{
+#ifdef ENABLE_ALMIXER_THREADS
+	SDL_LockMutex(s_simpleLock);
+#endif
+	Channel_Done_Callback = playback_finished_callback;
+	Channel_Done_Callback_Userdata = user_data;
+#ifdef ENABLE_ALMIXER_THREADS
+	SDL_UnlockMutex(s_simpleLock);
+#endif
+}
+
+
+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)
+{
+#ifdef ENABLE_ALMIXER_THREADS
+	SDL_LockMutex(s_simpleLock);
+#endif
+	Channel_Data_Callback = playback_data_callback;
 	Channel_Data_Callback_Userdata = user_data;
-	SDL_UnlockMutex(simple_lock);
-}
-
-
-
-
-
-Sint32 ALmixer_PlayChannelTimed(Sint32 channel, ALmixer_Data* data, Sint32 loops, Sint32 ticks)
-{
-	Sint32 retval;
-	SDL_LockMutex(simple_lock);
+#ifdef ENABLE_ALMIXER_THREADS
+	SDL_UnlockMutex(s_simpleLock);
+#endif
+}
+
+
+
+
+
+ALint ALmixer_PlayChannelTimed(ALint channel, ALmixer_Data* data, ALint loops, ALint ticks)
+{
+	ALint retval;
+#ifdef ENABLE_ALMIXER_THREADS
+	SDL_LockMutex(s_simpleLock);
+#endif
 	retval = Internal_PlayChannelTimed(channel, data, loops, ticks);
-	SDL_UnlockMutex(simple_lock);
+#ifdef ENABLE_ALMIXER_THREADS
+	SDL_UnlockMutex(s_simpleLock);
+#endif
 	return retval;
 }
 
@@ -7618,12 +8270,16 @@
  * a channel/source to already be in use because of this.
  * In this event, an error message will be returned to you.
  */
-ALuint ALmixer_PlaySourceTimed(ALuint source, ALmixer_Data* data, Sint32 loops, Sint32 ticks)
+ALuint ALmixer_PlaySourceTimed(ALuint source, ALmixer_Data* data, ALint loops, ALint ticks)
 {
 	ALuint retval;
-	SDL_LockMutex(simple_lock);
+#ifdef ENABLE_ALMIXER_THREADS
+	SDL_LockMutex(s_simpleLock);
+#endif
 	retval = Internal_PlaySourceTimed(source, data, loops, ticks);
-	SDL_UnlockMutex(simple_lock);
+#ifdef ENABLE_ALMIXER_THREADS
+	SDL_UnlockMutex(s_simpleLock);
+#endif
 	return retval;
 }
 
@@ -7631,24 +8287,32 @@
 /* Will return the number of channels halted
  * or 0 for error
  */
-Sint32 ALmixer_HaltChannel(Sint32 channel)
-{
-	Sint32 retval;
-	SDL_LockMutex(simple_lock);
-	retval = Internal_HaltChannel(channel);
-	SDL_UnlockMutex(simple_lock);
+ALint ALmixer_HaltChannel(ALint channel)
+{
+	ALint retval;
+#ifdef ENABLE_ALMIXER_THREADS
+	SDL_LockMutex(s_simpleLock);
+#endif
+	retval = Internal_HaltChannel(channel, AL_FALSE);
+#ifdef ENABLE_ALMIXER_THREADS
+	SDL_UnlockMutex(s_simpleLock);
+#endif
 	return retval;
 }
 
 /* Will return the number of channels halted
  * or 0 for error
  */
-Sint32 ALmixer_HaltSource(ALuint source)
-{
-	Sint32 retval;
-	SDL_LockMutex(simple_lock);
-	retval = Internal_HaltSource(source);
-	SDL_UnlockMutex(simple_lock);
+ALint ALmixer_HaltSource(ALuint source)
+{
+	ALint retval;
+#ifdef ENABLE_ALMIXER_THREADS
+	SDL_LockMutex(s_simpleLock);
+#endif
+	retval = Internal_HaltSource(source, AL_FALSE);
+#ifdef ENABLE_ALMIXER_THREADS
+	SDL_UnlockMutex(s_simpleLock);
+#endif
 	return retval;
 }
 
@@ -7657,349 +8321,554 @@
  * samples and start buffering up the data for the next
  * playback. This may require samples to be halted
  */
-Sint32 ALmixer_RewindData(ALmixer_Data* data)
-{
-	Sint32 retval;
-	SDL_LockMutex(simple_lock);
+ALint ALmixer_RewindData(ALmixer_Data* data)
+{
+	ALint retval;
+#ifdef ENABLE_ALMIXER_THREADS
+	SDL_LockMutex(s_simpleLock);
+#endif
 	retval = Internal_RewindData(data);
-	SDL_UnlockMutex(simple_lock);
+#ifdef ENABLE_ALMIXER_THREADS
+	SDL_UnlockMutex(s_simpleLock);
+#endif
 	return retval;
 }
 
-Sint32 ALmixer_RewindChannel(Sint32 channel)
-{
-	Sint32 retval;
-	SDL_LockMutex(simple_lock);
+ALint ALmixer_RewindChannel(ALint channel)
+{
+	ALint retval;
+#ifdef ENABLE_ALMIXER_THREADS
+	SDL_LockMutex(s_simpleLock);
+#endif
 	retval = Internal_RewindChannel(channel);
-	SDL_UnlockMutex(simple_lock);
+#ifdef ENABLE_ALMIXER_THREADS
+	SDL_UnlockMutex(s_simpleLock);
+#endif
 	return retval;
 }
 
-Sint32 ALmixer_RewindSource(ALuint source)
-{
-	Sint32 retval;
-	SDL_LockMutex(simple_lock);
+ALint ALmixer_RewindSource(ALuint source)
+{
+	ALint retval;
+#ifdef ENABLE_ALMIXER_THREADS
+	SDL_LockMutex(s_simpleLock);
+#endif
 	retval = Internal_RewindSource(source);
-	SDL_UnlockMutex(simple_lock);
+#ifdef ENABLE_ALMIXER_THREADS
+	SDL_UnlockMutex(s_simpleLock);
+#endif
 	return retval;
 }
 
-Sint32 ALmixer_PauseChannel(Sint32 channel)
-{
-	Sint32 retval;
-	SDL_LockMutex(simple_lock);
+ALint ALmixer_PauseChannel(ALint channel)
+{
+	ALint retval;
+#ifdef ENABLE_ALMIXER_THREADS
+	SDL_LockMutex(s_simpleLock);
+#endif
 	retval = Internal_PauseChannel(channel);
-	SDL_UnlockMutex(simple_lock);
+#ifdef ENABLE_ALMIXER_THREADS
+	SDL_UnlockMutex(s_simpleLock);
+#endif
 	return retval;
 }
 
-Sint32 ALmixer_PauseSource(ALuint source)
-{
-	Sint32 retval;
-	SDL_LockMutex(simple_lock);
+ALint ALmixer_PauseSource(ALuint source)
+{
+	ALint retval;
+#ifdef ENABLE_ALMIXER_THREADS
+	SDL_LockMutex(s_simpleLock);
+#endif
 	retval = Internal_PauseSource(source);
-	SDL_UnlockMutex(simple_lock);
+#ifdef ENABLE_ALMIXER_THREADS
+	SDL_UnlockMutex(s_simpleLock);
+#endif
 	return retval;
 }
 
-Sint32 ALmixer_ResumeChannel(Sint32 channel)
-{
-	Sint32 retval;
-	SDL_LockMutex(simple_lock);
+ALint ALmixer_ResumeChannel(ALint channel)
+{
+	ALint retval;
+#ifdef ENABLE_ALMIXER_THREADS
+	SDL_LockMutex(s_simpleLock);
+#endif
 	retval = Internal_ResumeChannel(channel);
-	SDL_UnlockMutex(simple_lock);
+#ifdef ENABLE_ALMIXER_THREADS
+	SDL_UnlockMutex(s_simpleLock);
+#endif
 	return retval;
 }
 
-Sint32 ALmixer_ResumeSource(ALuint source)
-{
-	Sint32 retval;
-	SDL_LockMutex(simple_lock);
+ALint ALmixer_ResumeSource(ALuint source)
+{
+	ALint retval;
+#ifdef ENABLE_ALMIXER_THREADS
+	SDL_LockMutex(s_simpleLock);
+#endif
 	retval = Internal_ResumeSource(source);
-	SDL_UnlockMutex(simple_lock);
+#ifdef ENABLE_ALMIXER_THREADS
+	SDL_UnlockMutex(s_simpleLock);
+#endif
 	return retval;
 }
 
 /* Might consider setting eof to 0 as a "feature"
  * This will allow seek to end to stay there because
  * Play automatically rewinds if at the end */
-Sint32 ALmixer_Seek(ALmixer_Data* data, Uint32 msec)
-{
-	Sint32 retval;
-	SDL_LockMutex(simple_lock);
-	retval = Internal_Seek(data, msec);
-	SDL_UnlockMutex(simple_lock);
+ALint ALmixer_SeekData(ALmixer_Data* data, ALuint msec)
+{
+	ALint retval;
+#ifdef ENABLE_ALMIXER_THREADS
+	SDL_LockMutex(s_simpleLock);
+#endif
+	retval = Internal_SeekData(data, msec);
+#ifdef ENABLE_ALMIXER_THREADS
+	SDL_UnlockMutex(s_simpleLock);
+#endif
 	return retval;
 }
 
-Sint32 ALmixer_FadeInChannelTimed(Sint32 channel, ALmixer_Data* data, Sint32 loops, Uint32 fade_ticks, Sint32 expire_ticks)
-{
-	Sint32 retval;
-	SDL_LockMutex(simple_lock);
+ALint ALmixer_FadeInChannelTimed(ALint channel, ALmixer_Data* data, ALint loops, ALuint fade_ticks, ALint expire_ticks)
+{
+	ALint retval;
+#ifdef ENABLE_ALMIXER_THREADS
+	SDL_LockMutex(s_simpleLock);
+#endif
 	retval = Internal_FadeInChannelTimed(channel, data, loops, fade_ticks, expire_ticks);
-	SDL_UnlockMutex(simple_lock);
+#ifdef ENABLE_ALMIXER_THREADS
+	SDL_UnlockMutex(s_simpleLock);
+#endif
 	return retval;
 }
 
-ALuint ALmixer_FadeInSourceTimed(ALuint source, ALmixer_Data* data, Sint32 loops, Uint32 fade_ticks, Sint32 expire_ticks)
+ALuint ALmixer_FadeInSourceTimed(ALuint source, ALmixer_Data* data, ALint loops, ALuint fade_ticks, ALint expire_ticks)
 {
 	ALuint retval;
-	SDL_LockMutex(simple_lock);
+#ifdef ENABLE_ALMIXER_THREADS
+	SDL_LockMutex(s_simpleLock);
+#endif
 	retval = Internal_FadeInSourceTimed(source, data, loops, fade_ticks, expire_ticks);
-	SDL_UnlockMutex(simple_lock);
-	return retval;
-}
-
-Sint32 ALmixer_FadeOutChannel(Sint32 channel, Uint32 ticks)
-{
-	Sint32 retval;
-	SDL_LockMutex(simple_lock);
-	retval = Internal_FadeOutChannel(channel, ticks);
-	SDL_UnlockMutex(simple_lock);
+#ifdef ENABLE_ALMIXER_THREADS
+	SDL_UnlockMutex(s_simpleLock);
+#endif
 	return retval;
 }
-	
-Sint32 ALmixer_FadeOutSource(ALuint source, Uint32 ticks)
-{
-	Sint32 retval;
-	SDL_LockMutex(simple_lock);
-	retval = Internal_FadeOutSource(source, ticks);
-	SDL_UnlockMutex(simple_lock);
+
+ALint ALmixer_FadeOutChannel(ALint channel, ALuint ticks)
+{
+	ALint retval;
+#ifdef ENABLE_ALMIXER_THREADS
+	SDL_LockMutex(s_simpleLock);
+#endif
+	retval = Internal_FadeOutChannel(channel, ticks);
+#ifdef ENABLE_ALMIXER_THREADS
+	SDL_UnlockMutex(s_simpleLock);
+#endif
 	return retval;
 }
-
-Sint32 ALmixer_FadeChannel(Sint32 channel, Uint32 ticks, ALfloat volume)
-{
-	Sint32 retval;
-	SDL_LockMutex(simple_lock);
-	retval = Internal_FadeChannel(channel, ticks, volume);
-	SDL_UnlockMutex(simple_lock);
+	
+ALint ALmixer_FadeOutSource(ALuint source, ALuint ticks)
+{
+	ALint retval;
+#ifdef ENABLE_ALMIXER_THREADS
+	SDL_LockMutex(s_simpleLock);
+#endif
+	retval = Internal_FadeOutSource(source, ticks);
+#ifdef ENABLE_ALMIXER_THREADS
+	SDL_UnlockMutex(s_simpleLock);
+#endif
 	return retval;
 }
 
-Sint32 ALmixer_FadeSource(ALuint source, Uint32 ticks, ALfloat volume)
-{
-	Sint32 retval;
-	SDL_LockMutex(simple_lock);
+ALint ALmixer_FadeChannel(ALint channel, ALuint ticks, ALfloat volume)
+{
+	ALint retval;
+#ifdef ENABLE_ALMIXER_THREADS
+	SDL_LockMutex(s_simpleLock);
+#endif
+	retval = Internal_FadeChannel(channel, ticks, volume);
+#ifdef ENABLE_ALMIXER_THREADS
+	SDL_UnlockMutex(s_simpleLock);
+#endif
+	return retval;
+}
+
+ALint ALmixer_FadeSource(ALuint source, ALuint ticks, ALfloat volume)
+{
+	ALint retval;
+#ifdef ENABLE_ALMIXER_THREADS
+	SDL_LockMutex(s_simpleLock);
+#endif
 	retval = Internal_FadeSource(source, ticks, volume);
-	SDL_UnlockMutex(simple_lock);
+#ifdef ENABLE_ALMIXER_THREADS
+	SDL_UnlockMutex(s_simpleLock);
+#endif
 	return retval;
 }
 
-Sint32 ALmixer_SetMaxVolumeChannel(Sint32 channel, ALfloat volume)
-{
-	Sint32 retval;
-	SDL_LockMutex(simple_lock);
-	retval = Internal_SetMaxVolumeChannel(channel, volume);
-	SDL_UnlockMutex(simple_lock);
+
+ALboolean ALmixer_SetVolumeChannel(ALint channel, ALfloat volume)
+{
+	ALboolean retval;
+#ifdef ENABLE_ALMIXER_THREADS
+	SDL_LockMutex(s_simpleLock);
+#endif
+	retval = Internal_SetVolumeChannel(channel, volume);
+#ifdef ENABLE_ALMIXER_THREADS
+	SDL_UnlockMutex(s_simpleLock);
+#endif
 	return retval;
 }
 
-Sint32 ALmixer_SetMaxVolumeSource(ALuint source, ALfloat volume)
-{
-	Sint32 retval;
-	SDL_LockMutex(simple_lock);
-	retval = Internal_SetMaxVolumeSource(source, volume);
-	SDL_UnlockMutex(simple_lock);
+ALboolean ALmixer_SetVolumeSource(ALuint source, ALfloat volume)
+{
+	ALboolean retval;
+#ifdef ENABLE_ALMIXER_THREADS
+	SDL_LockMutex(s_simpleLock);
+#endif
+	retval = Internal_SetVolumeSource(source, volume);
+#ifdef ENABLE_ALMIXER_THREADS
+	SDL_UnlockMutex(s_simpleLock);
+#endif
 	return retval;
 }
 
-ALfloat ALmixer_GetMaxVolumeChannel(Sint32 channel)
+ALfloat ALmixer_GetVolumeChannel(ALint channel)
 {
 	ALfloat retval;
-	SDL_LockMutex(simple_lock);
+#ifdef ENABLE_ALMIXER_THREADS
+	SDL_LockMutex(s_simpleLock);
+#endif
+	retval = Internal_GetVolumeChannel(channel);
+#ifdef ENABLE_ALMIXER_THREADS
+	SDL_UnlockMutex(s_simpleLock);
+#endif
+	return retval;	
+}
+
+ALfloat ALmixer_GetVolumeSource(ALuint source)
+{
+	ALfloat retval;
+#ifdef ENABLE_ALMIXER_THREADS
+	SDL_LockMutex(s_simpleLock);
+#endif
+	retval = Internal_GetVolumeSource(source);
+#ifdef ENABLE_ALMIXER_THREADS
+	SDL_UnlockMutex(s_simpleLock);
+#endif
+	return retval;	
+}
+
+ALboolean ALmixer_SetMaxVolumeChannel(ALint channel, ALfloat volume)
+{
+	ALboolean retval;
+#ifdef ENABLE_ALMIXER_THREADS
+	SDL_LockMutex(s_simpleLock);
+#endif
+	retval = Internal_SetMaxVolumeChannel(channel, volume);
+#ifdef ENABLE_ALMIXER_THREADS
+	SDL_UnlockMutex(s_simpleLock);
+#endif
+	return retval;
+}
+
+ALboolean ALmixer_SetMaxVolumeSource(ALuint source, ALfloat volume)
+{
+	ALboolean retval;
+#ifdef ENABLE_ALMIXER_THREADS
+	SDL_LockMutex(s_simpleLock);
+#endif
+	retval = Internal_SetMaxVolumeSource(source, volume);
+#ifdef ENABLE_ALMIXER_THREADS
+	SDL_UnlockMutex(s_simpleLock);
+#endif
+	return retval;
+}
+
+ALfloat ALmixer_GetMaxVolumeChannel(ALint channel)
+{
+	ALfloat retval;
+#ifdef ENABLE_ALMIXER_THREADS
+	SDL_LockMutex(s_simpleLock);
+#endif
 	retval = Internal_GetMaxVolumeChannel(channel);
-	SDL_UnlockMutex(simple_lock);
+#ifdef ENABLE_ALMIXER_THREADS
+	SDL_UnlockMutex(s_simpleLock);
+#endif
 	return retval;	
 }
 
 ALfloat ALmixer_GetMaxVolumeSource(ALuint source)
 {
 	ALfloat retval;
-	SDL_LockMutex(simple_lock);
+#ifdef ENABLE_ALMIXER_THREADS
+	SDL_LockMutex(s_simpleLock);
+#endif
 	retval = Internal_GetMaxVolumeSource(source);
-	SDL_UnlockMutex(simple_lock);
+#ifdef ENABLE_ALMIXER_THREADS
+	SDL_UnlockMutex(s_simpleLock);
+#endif
 	return retval;	
 }
 
 
-Sint32 ALmixer_SetMinVolumeChannel(Sint32 channel, ALfloat volume)
-{
-	Sint32 retval;
-	SDL_LockMutex(simple_lock);
+ALboolean ALmixer_SetMinVolumeChannel(ALint channel, ALfloat volume)
+{
+	ALboolean retval;
+#ifdef ENABLE_ALMIXER_THREADS
+	SDL_LockMutex(s_simpleLock);
+#endif
 	retval = Internal_SetMinVolumeChannel(channel, volume);
-	SDL_UnlockMutex(simple_lock);
+#ifdef ENABLE_ALMIXER_THREADS
+	SDL_UnlockMutex(s_simpleLock);
+#endif
 	return retval;
 }
 
-Sint32 ALmixer_SetMinVolumeSource(ALuint source, ALfloat volume)
-{
-	Sint32 retval;
-	SDL_LockMutex(simple_lock);
+ALboolean ALmixer_SetMinVolumeSource(ALuint source, ALfloat volume)
+{
+	ALboolean retval;
+#ifdef ENABLE_ALMIXER_THREADS
+	SDL_LockMutex(s_simpleLock);
+#endif
 	retval = Internal_SetMinVolumeSource(source, volume);
-	SDL_UnlockMutex(simple_lock);
+#ifdef ENABLE_ALMIXER_THREADS
+	SDL_UnlockMutex(s_simpleLock);
+#endif
 	return retval;
 }
 
-ALfloat ALmixer_GetMinVolumeChannel(Sint32 channel)
+ALfloat ALmixer_GetMinVolumeChannel(ALint channel)
 {
 	ALfloat retval;
-	SDL_LockMutex(simple_lock);
+#ifdef ENABLE_ALMIXER_THREADS
+	SDL_LockMutex(s_simpleLock);
+#endif
 	retval = Internal_GetMinVolumeChannel(channel);
-	SDL_UnlockMutex(simple_lock);
+#ifdef ENABLE_ALMIXER_THREADS
+	SDL_UnlockMutex(s_simpleLock);
+#endif
 	return retval;	
 }
 
 ALfloat ALmixer_GetMinVolumeSource(ALuint source)
 {
 	ALfloat retval;
-	SDL_LockMutex(simple_lock);
+#ifdef ENABLE_ALMIXER_THREADS
+	SDL_LockMutex(s_simpleLock);
+#endif
 	retval = Internal_GetMinVolumeSource(source);
-	SDL_UnlockMutex(simple_lock);
+#ifdef ENABLE_ALMIXER_THREADS
+	SDL_UnlockMutex(s_simpleLock);
+#endif
 	return retval;	
 }
 
 
 
-Sint32 ALmixer_SetMasterVolume(ALfloat volume)
-{
-	Sint32 retval;
-	SDL_LockMutex(simple_lock);
+ALboolean ALmixer_SetMasterVolume(ALfloat volume)
+{
+	ALboolean retval;
+#ifdef ENABLE_ALMIXER_THREADS
+	SDL_LockMutex(s_simpleLock);
+#endif
 	retval = Internal_SetMasterVolume(volume);
-	SDL_UnlockMutex(simple_lock);
+#ifdef ENABLE_ALMIXER_THREADS
+	SDL_UnlockMutex(s_simpleLock);
+#endif
 	return retval;	
 }
 
 ALfloat ALmixer_GetMasterVolume()
 {
 	ALfloat retval;
-	SDL_LockMutex(simple_lock);
+#ifdef ENABLE_ALMIXER_THREADS
+	SDL_LockMutex(s_simpleLock);
+#endif
 	retval = Internal_GetMasterVolume();
-	SDL_UnlockMutex(simple_lock);
+#ifdef ENABLE_ALMIXER_THREADS
+	SDL_UnlockMutex(s_simpleLock);
+#endif
 	return retval;	
 }
 
-Sint32 ALmixer_ExpireChannel(Sint32 channel, Sint32 ticks)
-{
-	Sint32 retval;
-	SDL_LockMutex(simple_lock);
+ALint ALmixer_ExpireChannel(ALint channel, ALint ticks)
+{
+	ALint retval;
+#ifdef ENABLE_ALMIXER_THREADS
+	SDL_LockMutex(s_simpleLock);
+#endif
 	retval = Internal_ExpireChannel(channel, ticks);
-	SDL_UnlockMutex(simple_lock);
+#ifdef ENABLE_ALMIXER_THREADS
+	SDL_UnlockMutex(s_simpleLock);
+#endif
 	return retval;
 }
 
-Sint32 ALmixer_ExpireSource(ALuint source, Sint32 ticks)
-{
-	Sint32 retval;
-	SDL_LockMutex(simple_lock);
+ALint ALmixer_ExpireSource(ALuint source, ALint ticks)
+{
+	ALint retval;
+#ifdef ENABLE_ALMIXER_THREADS
+	SDL_LockMutex(s_simpleLock);
+#endif
 	retval = Internal_ExpireSource(source, ticks);
-	SDL_UnlockMutex(simple_lock);
+#ifdef ENABLE_ALMIXER_THREADS
+	SDL_UnlockMutex(s_simpleLock);
+#endif
 	return retval;
 }
 
-Sint32 ALmixer_QueryChannel(Sint32 channel)
-{
-	Sint32 retval;
-	SDL_LockMutex(simple_lock);
+ALint ALmixer_IsActiveChannel(ALint channel)
+{
+	ALint retval;
+#ifdef ENABLE_ALMIXER_THREADS
+	SDL_LockMutex(s_simpleLock);
+#endif
 	retval = Internal_QueryChannel(channel);
-	SDL_UnlockMutex(simple_lock);
-	return retval;
-}
-
-Sint32 ALmixer_QuerySource(ALuint source)
-{
-	Sint32 retval;
-	SDL_LockMutex(simple_lock);
-	retval = Internal_QuerySource(source);
-	SDL_UnlockMutex(simple_lock);
+#ifdef ENABLE_ALMIXER_THREADS
+	SDL_UnlockMutex(s_simpleLock);
+#endif
 	return retval;
 }
 
-
-Sint32 ALmixer_PlayingChannel(Sint32 channel)
-{
-	Sint32 retval;
-	SDL_LockMutex(simple_lock);
-	retval = Internal_PlayingChannel(channel);
-	SDL_UnlockMutex(simple_lock);
+ALint ALmixer_IsActiveSource(ALuint source)
+{
+	ALint retval;
+#ifdef ENABLE_ALMIXER_THREADS
+	SDL_LockMutex(s_simpleLock);
+#endif
+	retval = Internal_QuerySource(source);
+#ifdef ENABLE_ALMIXER_THREADS
+	SDL_UnlockMutex(s_simpleLock);
+#endif
 	return retval;
 }
 
-Sint32 ALmixer_PlayingSource(ALuint source)
-{
-	Sint32 retval;
-	SDL_LockMutex(simple_lock);
-	retval = Internal_PlayingSource(source);
-	SDL_UnlockMutex(simple_lock);
+
+ALint ALmixer_IsPlayingChannel(ALint channel)
+{
+	ALint retval;
+#ifdef ENABLE_ALMIXER_THREADS
+	SDL_LockMutex(s_simpleLock);
+#endif
+	retval = Internal_PlayingChannel(channel);
+#ifdef ENABLE_ALMIXER_THREADS
+	SDL_UnlockMutex(s_simpleLock);
+#endif
 	return retval;
 }
 
-
-Sint32 ALmixer_PausedChannel(Sint32 channel)
-{
-	Sint32 retval;
-	SDL_LockMutex(simple_lock);
-	retval = Internal_PausedChannel(channel);
-	SDL_UnlockMutex(simple_lock);
+ALint ALmixer_IsPlayingSource(ALuint source)
+{
+	ALint retval;
+#ifdef ENABLE_ALMIXER_THREADS
+	SDL_LockMutex(s_simpleLock);
+#endif
+	retval = Internal_PlayingSource(source);
+#ifdef ENABLE_ALMIXER_THREADS
+	SDL_UnlockMutex(s_simpleLock);
+#endif
 	return retval;
 }
 
-Sint32 ALmixer_PausedSource(ALuint source)
-{
-	Sint32 retval;
-	SDL_LockMutex(simple_lock);
-	retval = Internal_PausedSource(source);
-	SDL_UnlockMutex(simple_lock);
+
+ALint ALmixer_IsPausedChannel(ALint channel)
+{
+	ALint retval;
+#ifdef ENABLE_ALMIXER_THREADS
+	SDL_LockMutex(s_simpleLock);
+#endif
+	retval = Internal_PausedChannel(channel);
+#ifdef ENABLE_ALMIXER_THREADS
+	SDL_UnlockMutex(s_simpleLock);
+#endif
 	return retval;
 }
 
-
-Sint32 ALmixer_CountAllFreeChannels()
-{
-	Sint32 retval;
-	SDL_LockMutex(simple_lock);
-	retval = Internal_CountAllFreeChannels();
-	SDL_UnlockMutex(simple_lock);
+ALint ALmixer_IsPausedSource(ALuint source)
+{
+	ALint retval;
+#ifdef ENABLE_ALMIXER_THREADS
+	SDL_LockMutex(s_simpleLock);
+#endif
+	retval = Internal_PausedSource(source);
+#ifdef ENABLE_ALMIXER_THREADS
+	SDL_UnlockMutex(s_simpleLock);
+#endif
 	return retval;
 }
 
-Sint32 ALmixer_CountUnreservedFreeChannels()
-{
-	Sint32 retval;
-	SDL_LockMutex(simple_lock);
-	retval = Internal_CountUnreservedFreeChannels();
-	SDL_UnlockMutex(simple_lock);
+
+ALuint ALmixer_CountAllFreeChannels()
+{
+	ALuint retval;
+#ifdef ENABLE_ALMIXER_THREADS
+	SDL_LockMutex(s_simpleLock);
+#endif
+	retval = Internal_CountAllFreeChannels();
+#ifdef ENABLE_ALMIXER_THREADS
+	SDL_UnlockMutex(s_simpleLock);
+#endif
 	return retval;
 }
 
-Sint32 ALmixer_CountAllUsedChannels()
-{
-	Sint32 retval;
-	SDL_LockMutex(simple_lock);
+ALuint ALmixer_CountUnreservedFreeChannels()
+{
+	ALuint retval;
+#ifdef ENABLE_ALMIXER_THREADS
+	SDL_LockMutex(s_simpleLock);
+#endif
+	retval = Internal_CountUnreservedFreeChannels();
+#ifdef ENABLE_ALMIXER_THREADS
+	SDL_UnlockMutex(s_simpleLock);
+#endif
+	return retval;
+}
+
+ALuint ALmixer_CountAllUsedChannels()
+{
+	ALuint retval;
+#ifdef ENABLE_ALMIXER_THREADS
+	SDL_LockMutex(s_simpleLock);
+#endif
 	retval = Internal_CountAllUsedChannels();
-	SDL_UnlockMutex(simple_lock);
+#ifdef ENABLE_ALMIXER_THREADS
+	SDL_UnlockMutex(s_simpleLock);
+#endif
 	return retval;
 }
 
-Sint32 ALmixer_CountUnreservedUsedChannels()
-{
-	Sint32 retval;
-	SDL_LockMutex(simple_lock);
+ALuint ALmixer_CountUnreservedUsedChannels()
+{
+	ALuint retval;
+#ifdef ENABLE_ALMIXER_THREADS
+	SDL_LockMutex(s_simpleLock);
+#endif
 	retval = Internal_CountUnreservedUsedChannels();
-	SDL_UnlockMutex(simple_lock);
+#ifdef ENABLE_ALMIXER_THREADS
+	SDL_UnlockMutex(s_simpleLock);
+#endif
 	return retval;
 }
 
-SDL_bool ALmixer_IsPredecoded(ALmixer_Data* data)
+ALboolean ALmixer_IsPredecoded(ALmixer_Data* data)
 {
 	if(NULL == data)
 	{
-		return SDL_FALSE;
+		return AL_FALSE;
 	}
 	return data->decoded_all;
 }
 
-
-
-
-
+ALboolean ALmixer_CompiledWithThreadBackend()
+{
+#ifdef ENABLE_ALMIXER_THREADS
+	return AL_TRUE;
+#else
+	return AL_FALSE;
+#endif
+}
+
+
+
+