comparison src/audio/nas/SDL_nasaudio.c @ 3846:66fb40445587 SDL-ryan-multiple-audio-device

Removed distinction between "available" and "init" in audio backends, since both had to be checked for success as a pair at the higher level and several of the Available methods were just always-succeed placeholders anyhow. Now the availability check is done in the init code, and the higher level tries all possible drivers until one manages to initialize successfully.
author Ryan C. Gordon <icculus@icculus.org>
date Tue, 17 Oct 2006 09:09:21 +0000
parents 76c5a414b996
children
comparison
equal deleted inserted replaced
3845:ee5dfa7f7993 3846:66fb40445587
95 } 95 }
96 #undef SDL_NAS_SYM 96 #undef SDL_NAS_SYM
97 97
98 #ifdef SDL_AUDIO_DRIVER_NAS_DYNAMIC 98 #ifdef SDL_AUDIO_DRIVER_NAS_DYNAMIC
99 99
100 static int library_load_count = 0;
101
102 static void 100 static void
103 UnloadNASLibrary(void) 101 UnloadNASLibrary(void)
104 { 102 {
105 if ((nas_handle != NULL) && (--library_load_count == 0)) { 103 if (nas_handle != NULL) {
106 SDL_UnloadObject(nas_handle); 104 SDL_UnloadObject(nas_handle);
107 nas_handle = NULL; 105 nas_handle = NULL;
108 } 106 }
109 } 107 }
110 108
111 static int 109 static int
112 LoadNASLibrary(void) 110 LoadNASLibrary(void)
113 { 111 {
114 int retval = 0; 112 int retval = 0;
115 if (library_load_count++ == 0) { 113 if (nas_handle == NULL) {
116 nas_handle = SDL_LoadObject(nas_library); 114 nas_handle = SDL_LoadObject(nas_library);
117 if (nas_handle == NULL) { 115 if (nas_handle == NULL) {
118 /* Copy error string so we can use it in a new SDL_SetError(). */ 116 /* Copy error string so we can use it in a new SDL_SetError(). */
119 char *origerr = SDL_GetError(); 117 char *origerr = SDL_GetError();
120 size_t len = SDL_strlen(origerr) + 1; 118 size_t len = SDL_strlen(origerr) + 1;
121 char *err = (char *) alloca(len); 119 char *err = (char *) alloca(len);
122 SDL_strlcpy(err, origerr, len); 120 SDL_strlcpy(err, origerr, len);
123
124 library_load_count--;
125 retval = -1; 121 retval = -1;
126 SDL_SetError("NAS: SDL_LoadObject('%s') failed: %s\n", 122 SDL_SetError("NAS: SDL_LoadObject('%s') failed: %s\n",
127 nas_library, err); 123 nas_library, err);
128 } else { 124 } else {
129 retval = load_nas_syms(); 125 retval = load_nas_syms();
148 load_nas_syms(); 144 load_nas_syms();
149 return 0; 145 return 0;
150 } 146 }
151 147
152 #endif /* SDL_AUDIO_DRIVER_NAS_DYNAMIC */ 148 #endif /* SDL_AUDIO_DRIVER_NAS_DYNAMIC */
153
154 static int
155 NAS_Available(void)
156 {
157 int available = 0;
158 if (LoadNASLibrary() >= 0) {
159 AuServer *aud = NAS_AuOpenServer("", 0, NULL, 0, NULL, NULL);
160 if (aud != NULL) {
161 available = 1;
162 NAS_AuCloseServer(aud);
163 }
164 UnloadNASLibrary();
165 }
166 return available;
167 }
168 149
169 /* This function waits until it is possible to write a full sound buffer */ 150 /* This function waits until it is possible to write a full sound buffer */
170 static void 151 static void
171 NAS_WaitDevice(_THIS) 152 NAS_WaitDevice(_THIS)
172 { 153 {
221 NAS_AuCloseServer(this->hidden->aud); 202 NAS_AuCloseServer(this->hidden->aud);
222 this->hidden->aud = 0; 203 this->hidden->aud = 0;
223 } 204 }
224 SDL_free(this->hidden); 205 SDL_free(this->hidden);
225 this2 = this->hidden = NULL; 206 this2 = this->hidden = NULL;
226 UnloadNASLibrary();
227 } 207 }
228 } 208 }
229 209
230 static unsigned char 210 static unsigned char
231 sdlformat_to_auformat(unsigned int fmt) 211 sdlformat_to_auformat(unsigned int fmt)
314 SDL_OutOfMemory(); 294 SDL_OutOfMemory();
315 return 0; 295 return 0;
316 } 296 }
317 SDL_memset(this->hidden, 0, (sizeof *this->hidden)); 297 SDL_memset(this->hidden, 0, (sizeof *this->hidden));
318 298
319 if (LoadNASLibrary() < 0) {
320 NAS_CloseDevice(this);
321 return 0;
322 }
323
324 /* Try for a closest match on audio format */ 299 /* Try for a closest match on audio format */
325 format = 0; 300 format = 0;
326 for (test_format = SDL_FirstAudioFormat(this->spec.format); 301 for (test_format = SDL_FirstAudioFormat(this->spec.format);
327 !format && test_format;) { 302 !format && test_format;) {
328 format = sdlformat_to_auformat(test_format); 303 format = sdlformat_to_auformat(test_format);
388 363
389 /* We're ready to rock and roll. :-) */ 364 /* We're ready to rock and roll. :-) */
390 return 1; 365 return 1;
391 } 366 }
392 367
368 static void
369 NAS_Deinitialize(void)
370 {
371 UnloadNASLibrary();
372 }
373
393 static int 374 static int
394 NAS_Init(SDL_AudioDriverImpl *impl) 375 NAS_Init(SDL_AudioDriverImpl *impl)
395 { 376 {
377 if (LoadNASLibrary() < 0) {
378 return 0;
379 } else {
380 AuServer *aud = NAS_AuOpenServer("", 0, NULL, 0, NULL, NULL);
381 if (aud == NULL) {
382 SDL_SetError("NAS: AuOpenServer() failed (no audio server?)");
383 return 0;
384 }
385 NAS_AuCloseServer(aud);
386 }
387
396 /* Set the function pointers */ 388 /* Set the function pointers */
397 impl->OpenDevice = NAS_OpenDevice; 389 impl->OpenDevice = NAS_OpenDevice;
398 impl->PlayDevice = NAS_PlayDevice; 390 impl->PlayDevice = NAS_PlayDevice;
399 impl->WaitDevice = NAS_WaitDevice; 391 impl->WaitDevice = NAS_WaitDevice;
400 impl->GetDeviceBuf = NAS_GetDeviceBuf; 392 impl->GetDeviceBuf = NAS_GetDeviceBuf;
401 impl->CloseDevice = NAS_CloseDevice; 393 impl->CloseDevice = NAS_CloseDevice;
394 impl->Deinitialize = NAS_Deinitialize;
402 impl->OnlyHasDefaultOutputDevice = 1; /* !!! FIXME: is this true? */ 395 impl->OnlyHasDefaultOutputDevice = 1; /* !!! FIXME: is this true? */
403 396
404 return 1; 397 return 1;
405 } 398 }
406 399
407 AudioBootStrap NAS_bootstrap = { 400 AudioBootStrap NAS_bootstrap = {
408 NAS_DRIVER_NAME, "Network Audio System", 401 NAS_DRIVER_NAME, "Network Audio System", NAS_Init, 0
409 NAS_Available, NAS_Init, 0
410 }; 402 };
411 403
412 /* vi: set ts=4 sw=4 expandtab: */ 404 /* vi: set ts=4 sw=4 expandtab: */