diff src/audio/arts/SDL_artsaudio.c @ 294:d2d48e10f370

Added a new header file: SDL_loadso.h It contains the following functions: SDL_LoadObject(), SDL_LoadFunction(), SDL_UnloadObject() The UNIX esd and arts audio code use these to dynamically load their respective audio libraries.
author Sam Lantinga <slouken@libsdl.org>
date Wed, 06 Mar 2002 05:20:11 +0000
parents e8157fcb3114
children f6ffac90895c
line wrap: on
line diff
--- a/src/audio/arts/SDL_artsaudio.c	Tue Mar 05 23:19:37 2002 +0000
+++ b/src/audio/arts/SDL_artsaudio.c	Wed Mar 06 05:20:11 2002 +0000
@@ -43,6 +43,13 @@
 #include "SDL_audiodev_c.h"
 #include "SDL_artsaudio.h"
 
+#ifdef ARTSC_DYNAMIC
+#include "SDL_name.h"
+#include "SDL_loadso.h"
+#else
+#define SDL_NAME(X)	X
+#endif
+
 /* The tag name used by artsc audio */
 #define ARTSC_DRIVER_NAME         "artsc"
 
@@ -53,20 +60,96 @@
 static Uint8 *ARTSC_GetAudioBuf(_THIS);
 static void ARTSC_CloseAudio(_THIS);
 
+#ifdef ARTSC_DYNAMIC
+
+static const char *arts_library = ARTSC_DYNAMIC;
+static void *arts_handle = NULL;
+static int arts_loaded = 0;
+
+static int (*SDL_NAME(arts_init))();
+static int (*SDL_NAME(arts_free))();
+static int (*SDL_NAME(arts_play_stream))();
+static int (*SDL_NAME(arts_stream_set))();
+static int (*SDL_NAME(arts_stream_get))();
+static int (*SDL_NAME(arts_write))();
+static int (*SDL_NAME(arts_close_stream))();
+static struct {
+	const char *name;
+	void **func;
+} arts_functions[] = {
+	{ "arts_init",		(void **)&SDL_NAME(arts_init)		},
+	{ "arts_free",		(void **)&SDL_NAME(arts_free)		},
+	{ "arts_play_stream",	(void **)&SDL_NAME(arts_play_stream)	},
+	{ "arts_stream_set",	(void **)&SDL_NAME(arts_stream_set)	},
+	{ "arts_stream_get",	(void **)&SDL_NAME(arts_stream_get)	},
+	{ "arts_write",		(void **)&SDL_NAME(arts_write)		},
+	{ "arts_close_stream",	(void **)&SDL_NAME(arts_close_stream)	},
+};
+
+static void UnloadARTSLibrary()
+{
+	if ( arts_loaded ) {
+		SDL_UnloadObject(arts_handle);
+		arts_handle = NULL;
+		arts_loaded = 0;
+	}
+}
+
+static int LoadARTSLibrary(void)
+{
+	int i, retval = -1;
+
+	arts_handle = SDL_LoadObject(arts_library);
+	if ( arts_handle ) {
+		arts_loaded = 1;
+		retval = 0;
+		for ( i=0; i<SDL_TABLESIZE(arts_functions); ++i ) {
+			*arts_functions[i].func = SDL_LoadFunction(arts_handle, arts_functions[i].name);
+			if ( ! arts_functions[i].func ) {
+				retval = -1;
+				UnloadARTSLibrary();
+				break;
+			}
+		}
+	}
+	return retval;
+}
+
+#else
+
+static void UnloadARTSLibrary()
+{
+	return;
+}
+
+static int LoadARTSLibrary(void)
+{
+	return 0;
+}
+
+#endif /* ARTSC_DYNAMIC */
+
 /* Audio driver bootstrap functions */
 
 static int Audio_Available(void)
 {
-	if(arts_init())
-		return 0;
-	else
-		return 1;
+	int available = 0;
+
+	if ( LoadARTSLibrary() < 0 ) {
+		return available;
+	}
+	if ( SDL_NAME(arts_init)() == 0 ) {
+		available = 1;
+		SDL_NAME(arts_free)();
+	}
+	UnloadARTSLibrary();
 }
 
 static void Audio_DeleteDevice(SDL_AudioDevice *device)
 {
 	free(device->hidden);
 	free(device);
+	UnloadARTSLibrary();
 }
 
 static SDL_AudioDevice *Audio_CreateDevice(int devindex)
@@ -74,6 +157,7 @@
 	SDL_AudioDevice *this;
 
 	/* Initialize all variables that we clean on shutdown */
+	LoadARTSLibrary();
 	this = (SDL_AudioDevice *)malloc(sizeof(SDL_AudioDevice));
 	if ( this ) {
 		memset(this, 0, (sizeof *this));
@@ -136,7 +220,7 @@
 	int written;
 
 	/* Write the audio data */
-	written = arts_write(stream, mixbuf, mixlen);
+	written = SDL_NAME(arts_write)(stream, mixbuf, mixlen);
 	
 	/* If timer synchronization is enabled, set the next write frame */
 	if ( frame_ticks ) {
@@ -164,9 +248,10 @@
 		mixbuf = NULL;
 	}
 	if ( stream ) {
-		arts_close_stream(stream);
+		SDL_NAME(arts_close_stream)(stream);
 		stream = 0;
 	}
+	SDL_NAME(arts_free)();
 }
 
 static int ARTSC_OpenAudio(_THIS, SDL_AudioSpec *spec)
@@ -210,7 +295,11 @@
 	}
 	spec->format = test_format;
 
-	stream = arts_play_stream(spec->freq, bits, spec->channels, "SDL");
+	if ( SDL_NAME(arts_init)() != 0 ) {
+		SDL_SetError("Unable to initialize ARTS");
+		return(-1);
+	}
+	stream = SDL_NAME(arts_play_stream)(spec->freq, bits, spec->channels, "SDL");
 
 	/* Calculate the final parameters for this audio specification */
 	SDL_CalculateAudioSpec(spec);
@@ -224,12 +313,12 @@
 	frag_spec |= 0x00020000;	/* two fragments, for low latency */
 
 #ifdef ARTS_P_PACKET_SETTINGS
-	arts_stream_set(stream, ARTS_P_PACKET_SETTINGS, frag_spec);
+	SDL_NAME(arts_stream_set)(stream, ARTS_P_PACKET_SETTINGS, frag_spec);
 #else
-	arts_stream_set(stream, ARTS_P_PACKET_SIZE, frag_spec&0xffff);
-	arts_stream_set(stream, ARTS_P_PACKET_COUNT, frag_spec>>16);
+	SDL_NAME(arts_stream_set)(stream, ARTS_P_PACKET_SIZE, frag_spec&0xffff);
+	SDL_NAME(arts_stream_set)(stream, ARTS_P_PACKET_COUNT, frag_spec>>16);
 #endif
-	spec->size = arts_stream_get(stream, ARTS_P_PACKET_SIZE);
+	spec->size = SDL_NAME(arts_stream_get)(stream, ARTS_P_PACKET_SIZE);
 
 	/* Allocate mixing buffer */
 	mixlen = spec->size;