Mercurial > sdl-ios-xcode
comparison src/audio/alsa/SDL_alsa_audio.c @ 4292:464126f4c7db SDL-1.2
Moved to stable ALSA API.
This cleans up a few problems with our use of the ancient ALSA 0.9 API.
This means we can ditch the dlvsym() nonsense and use SDL_LoadFunction(), too.
Fixes Bugzilla #745.
author | Ryan C. Gordon <icculus@icculus.org> |
---|---|
date | Sat, 10 Oct 2009 07:33:18 +0000 |
parents | a1b03ba2fcd0 |
children | 33d306630296 |
comparison
equal
deleted
inserted
replaced
4291:6cc2b35ac610 | 4292:464126f4c7db |
---|---|
31 #include "../SDL_audiomem.h" | 31 #include "../SDL_audiomem.h" |
32 #include "../SDL_audio_c.h" | 32 #include "../SDL_audio_c.h" |
33 #include "SDL_alsa_audio.h" | 33 #include "SDL_alsa_audio.h" |
34 | 34 |
35 #ifdef SDL_AUDIO_DRIVER_ALSA_DYNAMIC | 35 #ifdef SDL_AUDIO_DRIVER_ALSA_DYNAMIC |
36 #include <dlfcn.h> | |
37 #include "SDL_name.h" | 36 #include "SDL_name.h" |
38 #include "SDL_loadso.h" | 37 #include "SDL_loadso.h" |
39 #else | 38 #else |
40 #define SDL_NAME(X) X | 39 #define SDL_NAME(X) X |
41 #endif | 40 #endif |
72 static size_t (*SDL_NAME(snd_pcm_sw_params_sizeof))(void); | 71 static size_t (*SDL_NAME(snd_pcm_sw_params_sizeof))(void); |
73 static int (*SDL_NAME(snd_pcm_hw_params_any))(snd_pcm_t *pcm, snd_pcm_hw_params_t *params); | 72 static int (*SDL_NAME(snd_pcm_hw_params_any))(snd_pcm_t *pcm, snd_pcm_hw_params_t *params); |
74 static int (*SDL_NAME(snd_pcm_hw_params_set_access))(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_access_t access); | 73 static int (*SDL_NAME(snd_pcm_hw_params_set_access))(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_access_t access); |
75 static int (*SDL_NAME(snd_pcm_hw_params_set_format))(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_format_t val); | 74 static int (*SDL_NAME(snd_pcm_hw_params_set_format))(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_format_t val); |
76 static int (*SDL_NAME(snd_pcm_hw_params_set_channels))(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val); | 75 static int (*SDL_NAME(snd_pcm_hw_params_set_channels))(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val); |
77 static int (*SDL_NAME(snd_pcm_hw_params_get_channels))(const snd_pcm_hw_params_t *params); | 76 static int (*SDL_NAME(snd_pcm_hw_params_set_rate_near))(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir); |
78 static unsigned int (*SDL_NAME(snd_pcm_hw_params_set_rate_near))(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val, int *dir); | 77 static int (*SDL_NAME(snd_pcm_hw_params_set_period_size_near))(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val, int *dir); |
79 static snd_pcm_uframes_t (*SDL_NAME(snd_pcm_hw_params_set_period_size_near))(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t val, int *dir); | 78 static int (*SDL_NAME(snd_pcm_hw_params_get_channels))(const snd_pcm_hw_params_t *params, unsigned int *val); |
80 static snd_pcm_sframes_t (*SDL_NAME(snd_pcm_hw_params_get_period_size))(const snd_pcm_hw_params_t *params); | 79 static snd_pcm_sframes_t (*SDL_NAME(snd_pcm_hw_params_get_period_size))(const snd_pcm_hw_params_t *params); |
81 static unsigned int (*SDL_NAME(snd_pcm_hw_params_set_periods_near))(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val, int *dir); | 80 static int (*SDL_NAME(snd_pcm_hw_params_set_periods_near))(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir); |
82 static int (*SDL_NAME(snd_pcm_hw_params_get_periods))(snd_pcm_hw_params_t *params); | 81 static int (*SDL_NAME(snd_pcm_hw_params_get_periods))(snd_pcm_hw_params_t *params); |
83 static int (*SDL_NAME(snd_pcm_hw_params))(snd_pcm_t *pcm, snd_pcm_hw_params_t *params); | 82 static int (*SDL_NAME(snd_pcm_hw_params))(snd_pcm_t *pcm, snd_pcm_hw_params_t *params); |
84 /* | 83 /* |
85 */ | 84 */ |
86 static int (*SDL_NAME(snd_pcm_sw_params_current))(snd_pcm_t *pcm, snd_pcm_sw_params_t *swparams); | 85 static int (*SDL_NAME(snd_pcm_sw_params_current))(snd_pcm_t *pcm, snd_pcm_sw_params_t *swparams); |
123 { "snd_pcm_nonblock", (void**)(char*)&SDL_NAME(snd_pcm_nonblock) }, | 122 { "snd_pcm_nonblock", (void**)(char*)&SDL_NAME(snd_pcm_nonblock) }, |
124 }; | 123 }; |
125 | 124 |
126 static void UnloadALSALibrary(void) { | 125 static void UnloadALSALibrary(void) { |
127 if (alsa_loaded) { | 126 if (alsa_loaded) { |
128 /* SDL_UnloadObject(alsa_handle);*/ | 127 SDL_UnloadObject(alsa_handle); |
129 dlclose(alsa_handle); | |
130 alsa_handle = NULL; | 128 alsa_handle = NULL; |
131 alsa_loaded = 0; | 129 alsa_loaded = 0; |
132 } | 130 } |
133 } | 131 } |
134 | 132 |
135 static int LoadALSALibrary(void) { | 133 static int LoadALSALibrary(void) { |
136 int i, retval = -1; | 134 int i, retval = -1; |
137 | 135 |
138 /* alsa_handle = SDL_LoadObject(alsa_library);*/ | 136 alsa_handle = SDL_LoadObject(alsa_library); |
139 alsa_handle = dlopen(alsa_library,RTLD_NOW); | |
140 if (alsa_handle) { | 137 if (alsa_handle) { |
141 alsa_loaded = 1; | 138 alsa_loaded = 1; |
142 retval = 0; | 139 retval = 0; |
143 for (i = 0; i < SDL_arraysize(alsa_functions); i++) { | 140 for (i = 0; i < SDL_arraysize(alsa_functions); i++) { |
144 /* *alsa_functions[i].func = SDL_LoadFunction(alsa_handle,alsa_functions[i].name);*/ | 141 *alsa_functions[i].func = SDL_LoadFunction(alsa_handle,alsa_functions[i].name); |
145 #if HAVE_DLVSYM | |
146 *alsa_functions[i].func = dlvsym(alsa_handle,alsa_functions[i].name,"ALSA_0.9"); | |
147 if (!*alsa_functions[i].func) | |
148 #endif | |
149 *alsa_functions[i].func = dlsym(alsa_handle,alsa_functions[i].name); | |
150 if (!*alsa_functions[i].func) { | 142 if (!*alsa_functions[i].func) { |
151 retval = -1; | 143 retval = -1; |
152 UnloadALSALibrary(); | 144 UnloadALSALibrary(); |
153 break; | 145 break; |
154 } | 146 } |
372 int status; | 364 int status; |
373 snd_pcm_hw_params_t *hwparams; | 365 snd_pcm_hw_params_t *hwparams; |
374 snd_pcm_sw_params_t *swparams; | 366 snd_pcm_sw_params_t *swparams; |
375 snd_pcm_format_t format; | 367 snd_pcm_format_t format; |
376 snd_pcm_uframes_t frames; | 368 snd_pcm_uframes_t frames; |
369 unsigned int rate; | |
370 unsigned int periods; | |
371 unsigned int channels; | |
377 Uint16 test_format; | 372 Uint16 test_format; |
378 | 373 |
379 /* Open the audio device */ | 374 /* Open the audio device */ |
380 /* Name of device should depend on # channels in spec */ | 375 /* Name of device should depend on # channels in spec */ |
381 status = SDL_NAME(snd_pcm_open)(&pcm_handle, get_audio_device(spec->channels), SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK); | 376 status = SDL_NAME(snd_pcm_open)(&pcm_handle, get_audio_device(spec->channels), SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK); |
443 } | 438 } |
444 spec->format = test_format; | 439 spec->format = test_format; |
445 | 440 |
446 /* Set the number of channels */ | 441 /* Set the number of channels */ |
447 status = SDL_NAME(snd_pcm_hw_params_set_channels)(pcm_handle, hwparams, spec->channels); | 442 status = SDL_NAME(snd_pcm_hw_params_set_channels)(pcm_handle, hwparams, spec->channels); |
448 if ( status < 0 ) { | 443 channels = spec->channels; |
449 status = SDL_NAME(snd_pcm_hw_params_get_channels)(hwparams); | 444 if ( status < 0 ) { |
450 if ( (status <= 0) || (status > 2) ) { | 445 status = SDL_NAME(snd_pcm_hw_params_get_channels)(hwparams, &channels); |
446 if ( status < 0 ) { | |
451 SDL_SetError("Couldn't set audio channels"); | 447 SDL_SetError("Couldn't set audio channels"); |
452 ALSA_CloseAudio(this); | 448 ALSA_CloseAudio(this); |
453 return(-1); | 449 return(-1); |
454 } | 450 } |
455 spec->channels = status; | 451 spec->channels = channels; |
456 } | 452 } |
457 | 453 |
458 /* Set the audio rate */ | 454 /* Set the audio rate */ |
459 status = SDL_NAME(snd_pcm_hw_params_set_rate_near)(pcm_handle, hwparams, spec->freq, NULL); | 455 rate = spec->freq; |
456 | |
457 status = SDL_NAME(snd_pcm_hw_params_set_rate_near)(pcm_handle, hwparams, &rate, NULL); | |
460 if ( status < 0 ) { | 458 if ( status < 0 ) { |
461 SDL_SetError("Couldn't set audio frequency: %s", SDL_NAME(snd_strerror)(status)); | 459 SDL_SetError("Couldn't set audio frequency: %s", SDL_NAME(snd_strerror)(status)); |
462 ALSA_CloseAudio(this); | 460 ALSA_CloseAudio(this); |
463 return(-1); | 461 return(-1); |
464 } | 462 } |
465 spec->freq = status; | 463 spec->freq = rate; |
466 | 464 |
467 /* Set the buffer size, in samples */ | 465 /* Set the buffer size, in samples */ |
468 frames = spec->samples; | 466 frames = spec->samples; |
469 frames = SDL_NAME(snd_pcm_hw_params_set_period_size_near)(pcm_handle, hwparams, frames, NULL); | 467 status = SDL_NAME(snd_pcm_hw_params_set_period_size_near)(pcm_handle, hwparams, &frames, NULL); |
468 if ( status < 0 ) { | |
469 SDL_SetError("Couldn't set audio frequency: %s", SDL_NAME(snd_strerror)(status)); | |
470 ALSA_CloseAudio(this); | |
471 return(-1); | |
472 } | |
473 | |
470 spec->samples = frames; | 474 spec->samples = frames; |
471 SDL_NAME(snd_pcm_hw_params_set_periods_near)(pcm_handle, hwparams, 2, NULL); | 475 |
476 periods = 2; | |
477 SDL_NAME(snd_pcm_hw_params_set_periods_near)(pcm_handle, hwparams, &periods, NULL); | |
472 | 478 |
473 /* "set" the hardware with the desired parameters */ | 479 /* "set" the hardware with the desired parameters */ |
474 status = SDL_NAME(snd_pcm_hw_params)(pcm_handle, hwparams); | 480 status = SDL_NAME(snd_pcm_hw_params)(pcm_handle, hwparams); |
475 if ( status < 0 ) { | 481 if ( status < 0 ) { |
476 SDL_SetError("Couldn't set hardware audio parameters: %s", SDL_NAME(snd_strerror)(status)); | 482 SDL_SetError("Couldn't set hardware audio parameters: %s", SDL_NAME(snd_strerror)(status)); |