comparison 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
comparison
equal deleted inserted replaced
293:585a7e1285ae 294:d2d48e10f370
41 #include "SDL_audio_c.h" 41 #include "SDL_audio_c.h"
42 #include "SDL_timer.h" 42 #include "SDL_timer.h"
43 #include "SDL_audiodev_c.h" 43 #include "SDL_audiodev_c.h"
44 #include "SDL_artsaudio.h" 44 #include "SDL_artsaudio.h"
45 45
46 #ifdef ARTSC_DYNAMIC
47 #include "SDL_name.h"
48 #include "SDL_loadso.h"
49 #else
50 #define SDL_NAME(X) X
51 #endif
52
46 /* The tag name used by artsc audio */ 53 /* The tag name used by artsc audio */
47 #define ARTSC_DRIVER_NAME "artsc" 54 #define ARTSC_DRIVER_NAME "artsc"
48 55
49 /* Audio driver functions */ 56 /* Audio driver functions */
50 static int ARTSC_OpenAudio(_THIS, SDL_AudioSpec *spec); 57 static int ARTSC_OpenAudio(_THIS, SDL_AudioSpec *spec);
51 static void ARTSC_WaitAudio(_THIS); 58 static void ARTSC_WaitAudio(_THIS);
52 static void ARTSC_PlayAudio(_THIS); 59 static void ARTSC_PlayAudio(_THIS);
53 static Uint8 *ARTSC_GetAudioBuf(_THIS); 60 static Uint8 *ARTSC_GetAudioBuf(_THIS);
54 static void ARTSC_CloseAudio(_THIS); 61 static void ARTSC_CloseAudio(_THIS);
55 62
63 #ifdef ARTSC_DYNAMIC
64
65 static const char *arts_library = ARTSC_DYNAMIC;
66 static void *arts_handle = NULL;
67 static int arts_loaded = 0;
68
69 static int (*SDL_NAME(arts_init))();
70 static int (*SDL_NAME(arts_free))();
71 static int (*SDL_NAME(arts_play_stream))();
72 static int (*SDL_NAME(arts_stream_set))();
73 static int (*SDL_NAME(arts_stream_get))();
74 static int (*SDL_NAME(arts_write))();
75 static int (*SDL_NAME(arts_close_stream))();
76 static struct {
77 const char *name;
78 void **func;
79 } arts_functions[] = {
80 { "arts_init", (void **)&SDL_NAME(arts_init) },
81 { "arts_free", (void **)&SDL_NAME(arts_free) },
82 { "arts_play_stream", (void **)&SDL_NAME(arts_play_stream) },
83 { "arts_stream_set", (void **)&SDL_NAME(arts_stream_set) },
84 { "arts_stream_get", (void **)&SDL_NAME(arts_stream_get) },
85 { "arts_write", (void **)&SDL_NAME(arts_write) },
86 { "arts_close_stream", (void **)&SDL_NAME(arts_close_stream) },
87 };
88
89 static void UnloadARTSLibrary()
90 {
91 if ( arts_loaded ) {
92 SDL_UnloadObject(arts_handle);
93 arts_handle = NULL;
94 arts_loaded = 0;
95 }
96 }
97
98 static int LoadARTSLibrary(void)
99 {
100 int i, retval = -1;
101
102 arts_handle = SDL_LoadObject(arts_library);
103 if ( arts_handle ) {
104 arts_loaded = 1;
105 retval = 0;
106 for ( i=0; i<SDL_TABLESIZE(arts_functions); ++i ) {
107 *arts_functions[i].func = SDL_LoadFunction(arts_handle, arts_functions[i].name);
108 if ( ! arts_functions[i].func ) {
109 retval = -1;
110 UnloadARTSLibrary();
111 break;
112 }
113 }
114 }
115 return retval;
116 }
117
118 #else
119
120 static void UnloadARTSLibrary()
121 {
122 return;
123 }
124
125 static int LoadARTSLibrary(void)
126 {
127 return 0;
128 }
129
130 #endif /* ARTSC_DYNAMIC */
131
56 /* Audio driver bootstrap functions */ 132 /* Audio driver bootstrap functions */
57 133
58 static int Audio_Available(void) 134 static int Audio_Available(void)
59 { 135 {
60 if(arts_init()) 136 int available = 0;
61 return 0; 137
62 else 138 if ( LoadARTSLibrary() < 0 ) {
63 return 1; 139 return available;
140 }
141 if ( SDL_NAME(arts_init)() == 0 ) {
142 available = 1;
143 SDL_NAME(arts_free)();
144 }
145 UnloadARTSLibrary();
64 } 146 }
65 147
66 static void Audio_DeleteDevice(SDL_AudioDevice *device) 148 static void Audio_DeleteDevice(SDL_AudioDevice *device)
67 { 149 {
68 free(device->hidden); 150 free(device->hidden);
69 free(device); 151 free(device);
152 UnloadARTSLibrary();
70 } 153 }
71 154
72 static SDL_AudioDevice *Audio_CreateDevice(int devindex) 155 static SDL_AudioDevice *Audio_CreateDevice(int devindex)
73 { 156 {
74 SDL_AudioDevice *this; 157 SDL_AudioDevice *this;
75 158
76 /* Initialize all variables that we clean on shutdown */ 159 /* Initialize all variables that we clean on shutdown */
160 LoadARTSLibrary();
77 this = (SDL_AudioDevice *)malloc(sizeof(SDL_AudioDevice)); 161 this = (SDL_AudioDevice *)malloc(sizeof(SDL_AudioDevice));
78 if ( this ) { 162 if ( this ) {
79 memset(this, 0, (sizeof *this)); 163 memset(this, 0, (sizeof *this));
80 this->hidden = (struct SDL_PrivateAudioData *) 164 this->hidden = (struct SDL_PrivateAudioData *)
81 malloc((sizeof *this->hidden)); 165 malloc((sizeof *this->hidden));
134 static void ARTSC_PlayAudio(_THIS) 218 static void ARTSC_PlayAudio(_THIS)
135 { 219 {
136 int written; 220 int written;
137 221
138 /* Write the audio data */ 222 /* Write the audio data */
139 written = arts_write(stream, mixbuf, mixlen); 223 written = SDL_NAME(arts_write)(stream, mixbuf, mixlen);
140 224
141 /* If timer synchronization is enabled, set the next write frame */ 225 /* If timer synchronization is enabled, set the next write frame */
142 if ( frame_ticks ) { 226 if ( frame_ticks ) {
143 next_frame += frame_ticks; 227 next_frame += frame_ticks;
144 } 228 }
162 if ( mixbuf != NULL ) { 246 if ( mixbuf != NULL ) {
163 SDL_FreeAudioMem(mixbuf); 247 SDL_FreeAudioMem(mixbuf);
164 mixbuf = NULL; 248 mixbuf = NULL;
165 } 249 }
166 if ( stream ) { 250 if ( stream ) {
167 arts_close_stream(stream); 251 SDL_NAME(arts_close_stream)(stream);
168 stream = 0; 252 stream = 0;
169 } 253 }
254 SDL_NAME(arts_free)();
170 } 255 }
171 256
172 static int ARTSC_OpenAudio(_THIS, SDL_AudioSpec *spec) 257 static int ARTSC_OpenAudio(_THIS, SDL_AudioSpec *spec)
173 { 258 {
174 int bits, frag_spec; 259 int bits, frag_spec;
208 SDL_SetError("Couldn't find any hardware audio formats"); 293 SDL_SetError("Couldn't find any hardware audio formats");
209 return(-1); 294 return(-1);
210 } 295 }
211 spec->format = test_format; 296 spec->format = test_format;
212 297
213 stream = arts_play_stream(spec->freq, bits, spec->channels, "SDL"); 298 if ( SDL_NAME(arts_init)() != 0 ) {
299 SDL_SetError("Unable to initialize ARTS");
300 return(-1);
301 }
302 stream = SDL_NAME(arts_play_stream)(spec->freq, bits, spec->channels, "SDL");
214 303
215 /* Calculate the final parameters for this audio specification */ 304 /* Calculate the final parameters for this audio specification */
216 SDL_CalculateAudioSpec(spec); 305 SDL_CalculateAudioSpec(spec);
217 306
218 /* Determine the power of two of the fragment size */ 307 /* Determine the power of two of the fragment size */
222 return(-1); 311 return(-1);
223 } 312 }
224 frag_spec |= 0x00020000; /* two fragments, for low latency */ 313 frag_spec |= 0x00020000; /* two fragments, for low latency */
225 314
226 #ifdef ARTS_P_PACKET_SETTINGS 315 #ifdef ARTS_P_PACKET_SETTINGS
227 arts_stream_set(stream, ARTS_P_PACKET_SETTINGS, frag_spec); 316 SDL_NAME(arts_stream_set)(stream, ARTS_P_PACKET_SETTINGS, frag_spec);
228 #else 317 #else
229 arts_stream_set(stream, ARTS_P_PACKET_SIZE, frag_spec&0xffff); 318 SDL_NAME(arts_stream_set)(stream, ARTS_P_PACKET_SIZE, frag_spec&0xffff);
230 arts_stream_set(stream, ARTS_P_PACKET_COUNT, frag_spec>>16); 319 SDL_NAME(arts_stream_set)(stream, ARTS_P_PACKET_COUNT, frag_spec>>16);
231 #endif 320 #endif
232 spec->size = arts_stream_get(stream, ARTS_P_PACKET_SIZE); 321 spec->size = SDL_NAME(arts_stream_get)(stream, ARTS_P_PACKET_SIZE);
233 322
234 /* Allocate mixing buffer */ 323 /* Allocate mixing buffer */
235 mixlen = spec->size; 324 mixlen = spec->size;
236 mixbuf = (Uint8 *)SDL_AllocAudioMem(mixlen); 325 mixbuf = (Uint8 *)SDL_AllocAudioMem(mixlen);
237 if ( mixbuf == NULL ) { 326 if ( mixbuf == NULL ) {