diff options
author | Franklin Wei <git@fwei.tk> | 2018-02-07 20:04:46 -0500 |
---|---|---|
committer | Franklin Wei <git@fwei.tk> | 2018-03-12 20:52:01 -0400 |
commit | 6039eb05ba6d82ef56f2868c96654c552d117bf9 (patch) | |
tree | 9db7016bcbf66cfdf7b9bc998d84c6eaff9c8378 /apps/plugins/sdl/src/audio/alsa | |
parent | ef373c03b96b0be08babca581d9f10bccfd4931f (diff) | |
download | rockbox-6039eb05ba6d82ef56f2868c96654c552d117bf9.tar.gz rockbox-6039eb05ba6d82ef56f2868c96654c552d117bf9.zip |
sdl: remove non-rockbox drivers
We never use any of these other drivers, so having them around just takes
up space.
Change-Id: Iced812162df1fef3fd55522b7e700acb6c3bcd41
Diffstat (limited to 'apps/plugins/sdl/src/audio/alsa')
-rw-r--r-- | apps/plugins/sdl/src/audio/alsa/SDL_alsa_audio.c | 619 | ||||
-rw-r--r-- | apps/plugins/sdl/src/audio/alsa/SDL_alsa_audio.h | 48 |
2 files changed, 0 insertions, 667 deletions
diff --git a/apps/plugins/sdl/src/audio/alsa/SDL_alsa_audio.c b/apps/plugins/sdl/src/audio/alsa/SDL_alsa_audio.c deleted file mode 100644 index f10733e432..0000000000 --- a/apps/plugins/sdl/src/audio/alsa/SDL_alsa_audio.c +++ /dev/null | |||
@@ -1,619 +0,0 @@ | |||
1 | /* | ||
2 | SDL - Simple DirectMedia Layer | ||
3 | Copyright (C) 1997-2012 Sam Lantinga | ||
4 | |||
5 | This library is free software; you can redistribute it and/or | ||
6 | modify it under the terms of the GNU Library General Public | ||
7 | License as published by the Free Software Foundation; either | ||
8 | version 2 of the License, or (at your option) any later version. | ||
9 | |||
10 | This library is distributed in the hope that it will be useful, | ||
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | Library General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU Library General Public | ||
16 | License along with this library; if not, write to the Free | ||
17 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
18 | |||
19 | Sam Lantinga | ||
20 | slouken@libsdl.org | ||
21 | */ | ||
22 | #include "SDL_config.h" | ||
23 | |||
24 | /* Allow access to a raw mixing buffer */ | ||
25 | |||
26 | #include <sys/types.h> | ||
27 | #include <signal.h> /* For kill() */ | ||
28 | |||
29 | #include "SDL_timer.h" | ||
30 | #include "SDL_audio.h" | ||
31 | #include "../SDL_audiomem.h" | ||
32 | #include "../SDL_audio_c.h" | ||
33 | #include "SDL_alsa_audio.h" | ||
34 | |||
35 | #ifdef SDL_AUDIO_DRIVER_ALSA_DYNAMIC | ||
36 | #include "SDL_name.h" | ||
37 | #include "SDL_loadso.h" | ||
38 | #else | ||
39 | #define SDL_NAME(X) X | ||
40 | #endif | ||
41 | |||
42 | |||
43 | /* The tag name used by ALSA audio */ | ||
44 | #define DRIVER_NAME "alsa" | ||
45 | |||
46 | /* Audio driver functions */ | ||
47 | static int ALSA_OpenAudio(_THIS, SDL_AudioSpec *spec); | ||
48 | static void ALSA_WaitAudio(_THIS); | ||
49 | static void ALSA_PlayAudio(_THIS); | ||
50 | static Uint8 *ALSA_GetAudioBuf(_THIS); | ||
51 | static void ALSA_CloseAudio(_THIS); | ||
52 | |||
53 | #ifdef SDL_AUDIO_DRIVER_ALSA_DYNAMIC | ||
54 | |||
55 | static const char *alsa_library = SDL_AUDIO_DRIVER_ALSA_DYNAMIC; | ||
56 | static void *alsa_handle = NULL; | ||
57 | static int alsa_loaded = 0; | ||
58 | |||
59 | static int (*SDL_NAME(snd_pcm_open))(snd_pcm_t **pcm, const char *name, snd_pcm_stream_t stream, int mode); | ||
60 | static int (*SDL_NAME(snd_pcm_close))(snd_pcm_t *pcm); | ||
61 | static snd_pcm_sframes_t (*SDL_NAME(snd_pcm_writei))(snd_pcm_t *pcm, const void *buffer, snd_pcm_uframes_t size); | ||
62 | static int (*SDL_NAME(snd_pcm_recover))(snd_pcm_t *pcm, int err, int silent); | ||
63 | static int (*SDL_NAME(snd_pcm_prepare))(snd_pcm_t *pcm); | ||
64 | static int (*SDL_NAME(snd_pcm_drain))(snd_pcm_t *pcm); | ||
65 | static const char *(*SDL_NAME(snd_strerror))(int errnum); | ||
66 | static size_t (*SDL_NAME(snd_pcm_hw_params_sizeof))(void); | ||
67 | static size_t (*SDL_NAME(snd_pcm_sw_params_sizeof))(void); | ||
68 | static void (*SDL_NAME(snd_pcm_hw_params_copy))(snd_pcm_hw_params_t *dst, const snd_pcm_hw_params_t *src); | ||
69 | static int (*SDL_NAME(snd_pcm_hw_params_any))(snd_pcm_t *pcm, snd_pcm_hw_params_t *params); | ||
70 | 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); | ||
71 | 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); | ||
72 | static int (*SDL_NAME(snd_pcm_hw_params_set_channels))(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val); | ||
73 | static int (*SDL_NAME(snd_pcm_hw_params_get_channels))(const snd_pcm_hw_params_t *params, unsigned int *val); | ||
74 | 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); | ||
75 | 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); | ||
76 | static int (*SDL_NAME(snd_pcm_hw_params_get_period_size))(const snd_pcm_hw_params_t *params, snd_pcm_uframes_t *frames, int *dir); | ||
77 | 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); | ||
78 | static int (*SDL_NAME(snd_pcm_hw_params_get_periods))(const snd_pcm_hw_params_t *params, unsigned int *val, int *dir); | ||
79 | static int (*SDL_NAME(snd_pcm_hw_params_set_buffer_size_near))(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val); | ||
80 | static int (*SDL_NAME(snd_pcm_hw_params_get_buffer_size))(const snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val); | ||
81 | static int (*SDL_NAME(snd_pcm_hw_params))(snd_pcm_t *pcm, snd_pcm_hw_params_t *params); | ||
82 | /* | ||
83 | */ | ||
84 | static int (*SDL_NAME(snd_pcm_sw_params_set_avail_min))(snd_pcm_t *pcm, snd_pcm_sw_params_t *swparams, snd_pcm_uframes_t val); | ||
85 | static int (*SDL_NAME(snd_pcm_sw_params_current))(snd_pcm_t *pcm, snd_pcm_sw_params_t *swparams); | ||
86 | static int (*SDL_NAME(snd_pcm_sw_params_set_start_threshold))(snd_pcm_t *pcm, snd_pcm_sw_params_t *params, snd_pcm_uframes_t val); | ||
87 | static int (*SDL_NAME(snd_pcm_sw_params))(snd_pcm_t *pcm, snd_pcm_sw_params_t *params); | ||
88 | static int (*SDL_NAME(snd_pcm_nonblock))(snd_pcm_t *pcm, int nonblock); | ||
89 | static int (*SDL_NAME(snd_pcm_wait))(snd_pcm_t *pcm, int timeout); | ||
90 | #define snd_pcm_hw_params_sizeof SDL_NAME(snd_pcm_hw_params_sizeof) | ||
91 | #define snd_pcm_sw_params_sizeof SDL_NAME(snd_pcm_sw_params_sizeof) | ||
92 | |||
93 | /* cast funcs to char* first, to please GCC's strict aliasing rules. */ | ||
94 | static struct { | ||
95 | const char *name; | ||
96 | void **func; | ||
97 | } alsa_functions[] = { | ||
98 | { "snd_pcm_open", (void**)(char*)&SDL_NAME(snd_pcm_open) }, | ||
99 | { "snd_pcm_close", (void**)(char*)&SDL_NAME(snd_pcm_close) }, | ||
100 | { "snd_pcm_writei", (void**)(char*)&SDL_NAME(snd_pcm_writei) }, | ||
101 | { "snd_pcm_recover", (void**)(char*)&SDL_NAME(snd_pcm_recover) }, | ||
102 | { "snd_pcm_prepare", (void**)(char*)&SDL_NAME(snd_pcm_prepare) }, | ||
103 | { "snd_pcm_drain", (void**)(char*)&SDL_NAME(snd_pcm_drain) }, | ||
104 | { "snd_strerror", (void**)(char*)&SDL_NAME(snd_strerror) }, | ||
105 | { "snd_pcm_hw_params_sizeof", (void**)(char*)&SDL_NAME(snd_pcm_hw_params_sizeof) }, | ||
106 | { "snd_pcm_sw_params_sizeof", (void**)(char*)&SDL_NAME(snd_pcm_sw_params_sizeof) }, | ||
107 | { "snd_pcm_hw_params_copy", (void**)(char*)&SDL_NAME(snd_pcm_hw_params_copy) }, | ||
108 | { "snd_pcm_hw_params_any", (void**)(char*)&SDL_NAME(snd_pcm_hw_params_any) }, | ||
109 | { "snd_pcm_hw_params_set_access", (void**)(char*)&SDL_NAME(snd_pcm_hw_params_set_access) }, | ||
110 | { "snd_pcm_hw_params_set_format", (void**)(char*)&SDL_NAME(snd_pcm_hw_params_set_format) }, | ||
111 | { "snd_pcm_hw_params_set_channels", (void**)(char*)&SDL_NAME(snd_pcm_hw_params_set_channels) }, | ||
112 | { "snd_pcm_hw_params_get_channels", (void**)(char*)&SDL_NAME(snd_pcm_hw_params_get_channels) }, | ||
113 | { "snd_pcm_hw_params_set_rate_near", (void**)(char*)&SDL_NAME(snd_pcm_hw_params_set_rate_near) }, | ||
114 | { "snd_pcm_hw_params_set_period_size_near", (void**)(char*)&SDL_NAME(snd_pcm_hw_params_set_period_size_near) }, | ||
115 | { "snd_pcm_hw_params_get_period_size", (void**)(char*)&SDL_NAME(snd_pcm_hw_params_get_period_size) }, | ||
116 | { "snd_pcm_hw_params_set_periods_near", (void**)(char*)&SDL_NAME(snd_pcm_hw_params_set_periods_near) }, | ||
117 | { "snd_pcm_hw_params_get_periods", (void**)(char*)&SDL_NAME(snd_pcm_hw_params_get_periods) }, | ||
118 | { "snd_pcm_hw_params_set_buffer_size_near", (void**)(char*)&SDL_NAME(snd_pcm_hw_params_set_buffer_size_near) }, | ||
119 | { "snd_pcm_hw_params_get_buffer_size", (void**)(char*)&SDL_NAME(snd_pcm_hw_params_get_buffer_size) }, | ||
120 | { "snd_pcm_hw_params", (void**)(char*)&SDL_NAME(snd_pcm_hw_params) }, | ||
121 | { "snd_pcm_sw_params_set_avail_min", (void**)(char*)&SDL_NAME(snd_pcm_sw_params_set_avail_min) }, | ||
122 | { "snd_pcm_sw_params_current", (void**)(char*)&SDL_NAME(snd_pcm_sw_params_current) }, | ||
123 | { "snd_pcm_sw_params_set_start_threshold", (void**)(char*)&SDL_NAME(snd_pcm_sw_params_set_start_threshold) }, | ||
124 | { "snd_pcm_sw_params", (void**)(char*)&SDL_NAME(snd_pcm_sw_params) }, | ||
125 | { "snd_pcm_nonblock", (void**)(char*)&SDL_NAME(snd_pcm_nonblock) }, | ||
126 | { "snd_pcm_wait", (void**)(char*)&SDL_NAME(snd_pcm_wait) }, | ||
127 | }; | ||
128 | |||
129 | static void UnloadALSALibrary(void) { | ||
130 | if (alsa_loaded) { | ||
131 | SDL_UnloadObject(alsa_handle); | ||
132 | alsa_handle = NULL; | ||
133 | alsa_loaded = 0; | ||
134 | } | ||
135 | } | ||
136 | |||
137 | static int LoadALSALibrary(void) { | ||
138 | int i, retval = -1; | ||
139 | |||
140 | alsa_handle = SDL_LoadObject(alsa_library); | ||
141 | if (alsa_handle) { | ||
142 | alsa_loaded = 1; | ||
143 | retval = 0; | ||
144 | for (i = 0; i < SDL_arraysize(alsa_functions); i++) { | ||
145 | *alsa_functions[i].func = SDL_LoadFunction(alsa_handle,alsa_functions[i].name); | ||
146 | if (!*alsa_functions[i].func) { | ||
147 | retval = -1; | ||
148 | UnloadALSALibrary(); | ||
149 | break; | ||
150 | } | ||
151 | } | ||
152 | } | ||
153 | return retval; | ||
154 | } | ||
155 | |||
156 | #else | ||
157 | |||
158 | static void UnloadALSALibrary(void) { | ||
159 | return; | ||
160 | } | ||
161 | |||
162 | static int LoadALSALibrary(void) { | ||
163 | return 0; | ||
164 | } | ||
165 | |||
166 | #endif /* SDL_AUDIO_DRIVER_ALSA_DYNAMIC */ | ||
167 | |||
168 | static const char *get_audio_device(int channels) | ||
169 | { | ||
170 | const char *device; | ||
171 | |||
172 | device = SDL_getenv("AUDIODEV"); /* Is there a standard variable name? */ | ||
173 | if ( device == NULL ) { | ||
174 | switch (channels) { | ||
175 | case 6: | ||
176 | device = "plug:surround51"; | ||
177 | break; | ||
178 | case 4: | ||
179 | device = "plug:surround40"; | ||
180 | break; | ||
181 | default: | ||
182 | device = "default"; | ||
183 | break; | ||
184 | } | ||
185 | } | ||
186 | return device; | ||
187 | } | ||
188 | |||
189 | /* Audio driver bootstrap functions */ | ||
190 | |||
191 | static int Audio_Available(void) | ||
192 | { | ||
193 | int available; | ||
194 | int status; | ||
195 | snd_pcm_t *handle; | ||
196 | |||
197 | available = 0; | ||
198 | if (LoadALSALibrary() < 0) { | ||
199 | return available; | ||
200 | } | ||
201 | status = SDL_NAME(snd_pcm_open)(&handle, get_audio_device(2), SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK); | ||
202 | if ( status >= 0 ) { | ||
203 | available = 1; | ||
204 | SDL_NAME(snd_pcm_close)(handle); | ||
205 | } | ||
206 | UnloadALSALibrary(); | ||
207 | return(available); | ||
208 | } | ||
209 | |||
210 | static void Audio_DeleteDevice(SDL_AudioDevice *device) | ||
211 | { | ||
212 | SDL_free(device->hidden); | ||
213 | SDL_free(device); | ||
214 | UnloadALSALibrary(); | ||
215 | } | ||
216 | |||
217 | static SDL_AudioDevice *Audio_CreateDevice(int devindex) | ||
218 | { | ||
219 | SDL_AudioDevice *this; | ||
220 | |||
221 | /* Initialize all variables that we clean on shutdown */ | ||
222 | LoadALSALibrary(); | ||
223 | this = (SDL_AudioDevice *)SDL_malloc(sizeof(SDL_AudioDevice)); | ||
224 | if ( this ) { | ||
225 | SDL_memset(this, 0, (sizeof *this)); | ||
226 | this->hidden = (struct SDL_PrivateAudioData *) | ||
227 | SDL_malloc((sizeof *this->hidden)); | ||
228 | } | ||
229 | if ( (this == NULL) || (this->hidden == NULL) ) { | ||
230 | SDL_OutOfMemory(); | ||
231 | if ( this ) { | ||
232 | SDL_free(this); | ||
233 | } | ||
234 | return(0); | ||
235 | } | ||
236 | SDL_memset(this->hidden, 0, (sizeof *this->hidden)); | ||
237 | |||
238 | /* Set the function pointers */ | ||
239 | this->OpenAudio = ALSA_OpenAudio; | ||
240 | this->WaitAudio = ALSA_WaitAudio; | ||
241 | this->PlayAudio = ALSA_PlayAudio; | ||
242 | this->GetAudioBuf = ALSA_GetAudioBuf; | ||
243 | this->CloseAudio = ALSA_CloseAudio; | ||
244 | |||
245 | this->free = Audio_DeleteDevice; | ||
246 | |||
247 | return this; | ||
248 | } | ||
249 | |||
250 | AudioBootStrap ALSA_bootstrap = { | ||
251 | DRIVER_NAME, "ALSA PCM audio", | ||
252 | Audio_Available, Audio_CreateDevice | ||
253 | }; | ||
254 | |||
255 | /* This function waits until it is possible to write a full sound buffer */ | ||
256 | static void ALSA_WaitAudio(_THIS) | ||
257 | { | ||
258 | /* We're in blocking mode, so there's nothing to do here */ | ||
259 | } | ||
260 | |||
261 | |||
262 | /* | ||
263 | * http://bugzilla.libsdl.org/show_bug.cgi?id=110 | ||
264 | * "For Linux ALSA, this is FL-FR-RL-RR-C-LFE | ||
265 | * and for Windows DirectX [and CoreAudio], this is FL-FR-C-LFE-RL-RR" | ||
266 | */ | ||
267 | #define SWIZ6(T) \ | ||
268 | T *ptr = (T *) mixbuf; \ | ||
269 | Uint32 i; \ | ||
270 | for (i = 0; i < this->spec.samples; i++, ptr += 6) { \ | ||
271 | T tmp; \ | ||
272 | tmp = ptr[2]; ptr[2] = ptr[4]; ptr[4] = tmp; \ | ||
273 | tmp = ptr[3]; ptr[3] = ptr[5]; ptr[5] = tmp; \ | ||
274 | } | ||
275 | |||
276 | static __inline__ void swizzle_alsa_channels_6_64bit(_THIS) { SWIZ6(Uint64); } | ||
277 | static __inline__ void swizzle_alsa_channels_6_32bit(_THIS) { SWIZ6(Uint32); } | ||
278 | static __inline__ void swizzle_alsa_channels_6_16bit(_THIS) { SWIZ6(Uint16); } | ||
279 | static __inline__ void swizzle_alsa_channels_6_8bit(_THIS) { SWIZ6(Uint8); } | ||
280 | |||
281 | #undef SWIZ6 | ||
282 | |||
283 | |||
284 | /* | ||
285 | * Called right before feeding this->mixbuf to the hardware. Swizzle channels | ||
286 | * from Windows/Mac order to the format alsalib will want. | ||
287 | */ | ||
288 | static __inline__ void swizzle_alsa_channels(_THIS) | ||
289 | { | ||
290 | if (this->spec.channels == 6) { | ||
291 | const Uint16 fmtsize = (this->spec.format & 0xFF); /* bits/channel. */ | ||
292 | if (fmtsize == 16) | ||
293 | swizzle_alsa_channels_6_16bit(this); | ||
294 | else if (fmtsize == 8) | ||
295 | swizzle_alsa_channels_6_8bit(this); | ||
296 | else if (fmtsize == 32) | ||
297 | swizzle_alsa_channels_6_32bit(this); | ||
298 | else if (fmtsize == 64) | ||
299 | swizzle_alsa_channels_6_64bit(this); | ||
300 | } | ||
301 | |||
302 | /* !!! FIXME: update this for 7.1 if needed, later. */ | ||
303 | } | ||
304 | |||
305 | |||
306 | static void ALSA_PlayAudio(_THIS) | ||
307 | { | ||
308 | int status; | ||
309 | snd_pcm_uframes_t frames_left; | ||
310 | const Uint8 *sample_buf = (const Uint8 *) mixbuf; | ||
311 | const int frame_size = (((int) (this->spec.format & 0xFF)) / 8) * this->spec.channels; | ||
312 | |||
313 | swizzle_alsa_channels(this); | ||
314 | |||
315 | frames_left = ((snd_pcm_uframes_t) this->spec.samples); | ||
316 | |||
317 | while ( frames_left > 0 && this->enabled ) { | ||
318 | /* This works, but needs more testing before going live */ | ||
319 | /*SDL_NAME(snd_pcm_wait)(pcm_handle, -1);*/ | ||
320 | |||
321 | status = SDL_NAME(snd_pcm_writei)(pcm_handle, sample_buf, frames_left); | ||
322 | if ( status < 0 ) { | ||
323 | if ( status == -EAGAIN ) { | ||
324 | /* Apparently snd_pcm_recover() doesn't handle this case - does it assume snd_pcm_wait() above? */ | ||
325 | SDL_Delay(1); | ||
326 | continue; | ||
327 | } | ||
328 | status = SDL_NAME(snd_pcm_recover)(pcm_handle, status, 0); | ||
329 | if ( status < 0 ) { | ||
330 | /* Hmm, not much we can do - abort */ | ||
331 | fprintf(stderr, "ALSA write failed (unrecoverable): %s\n", SDL_NAME(snd_strerror)(status)); | ||
332 | this->enabled = 0; | ||
333 | return; | ||
334 | } | ||
335 | continue; | ||
336 | } | ||
337 | sample_buf += status * frame_size; | ||
338 | frames_left -= status; | ||
339 | } | ||
340 | } | ||
341 | |||
342 | static Uint8 *ALSA_GetAudioBuf(_THIS) | ||
343 | { | ||
344 | return(mixbuf); | ||
345 | } | ||
346 | |||
347 | static void ALSA_CloseAudio(_THIS) | ||
348 | { | ||
349 | if ( mixbuf != NULL ) { | ||
350 | SDL_FreeAudioMem(mixbuf); | ||
351 | mixbuf = NULL; | ||
352 | } | ||
353 | if ( pcm_handle ) { | ||
354 | SDL_NAME(snd_pcm_drain)(pcm_handle); | ||
355 | SDL_NAME(snd_pcm_close)(pcm_handle); | ||
356 | pcm_handle = NULL; | ||
357 | } | ||
358 | } | ||
359 | |||
360 | static int ALSA_finalize_hardware(_THIS, SDL_AudioSpec *spec, snd_pcm_hw_params_t *hwparams, int override) | ||
361 | { | ||
362 | int status; | ||
363 | snd_pcm_uframes_t bufsize; | ||
364 | |||
365 | /* "set" the hardware with the desired parameters */ | ||
366 | status = SDL_NAME(snd_pcm_hw_params)(pcm_handle, hwparams); | ||
367 | if ( status < 0 ) { | ||
368 | return(-1); | ||
369 | } | ||
370 | |||
371 | /* Get samples for the actual buffer size */ | ||
372 | status = SDL_NAME(snd_pcm_hw_params_get_buffer_size)(hwparams, &bufsize); | ||
373 | if ( status < 0 ) { | ||
374 | return(-1); | ||
375 | } | ||
376 | if ( !override && bufsize != spec->samples * 2 ) { | ||
377 | return(-1); | ||
378 | } | ||
379 | |||
380 | /* FIXME: Is this safe to do? */ | ||
381 | spec->samples = bufsize / 2; | ||
382 | |||
383 | /* This is useful for debugging */ | ||
384 | if ( getenv("SDL_AUDIO_ALSA_DEBUG") ) { | ||
385 | snd_pcm_uframes_t persize = 0; | ||
386 | unsigned int periods = 0; | ||
387 | |||
388 | SDL_NAME(snd_pcm_hw_params_get_period_size)(hwparams, &persize, NULL); | ||
389 | SDL_NAME(snd_pcm_hw_params_get_periods)(hwparams, &periods, NULL); | ||
390 | |||
391 | fprintf(stderr, "ALSA: period size = %ld, periods = %u, buffer size = %lu\n", persize, periods, bufsize); | ||
392 | } | ||
393 | return(0); | ||
394 | } | ||
395 | |||
396 | static int ALSA_set_period_size(_THIS, SDL_AudioSpec *spec, snd_pcm_hw_params_t *params, int override) | ||
397 | { | ||
398 | const char *env; | ||
399 | int status; | ||
400 | snd_pcm_hw_params_t *hwparams; | ||
401 | snd_pcm_uframes_t frames; | ||
402 | unsigned int periods; | ||
403 | |||
404 | /* Copy the hardware parameters for this setup */ | ||
405 | snd_pcm_hw_params_alloca(&hwparams); | ||
406 | SDL_NAME(snd_pcm_hw_params_copy)(hwparams, params); | ||
407 | |||
408 | if ( !override ) { | ||
409 | env = getenv("SDL_AUDIO_ALSA_SET_PERIOD_SIZE"); | ||
410 | if ( env ) { | ||
411 | override = SDL_atoi(env); | ||
412 | if ( override == 0 ) { | ||
413 | return(-1); | ||
414 | } | ||
415 | } | ||
416 | } | ||
417 | |||
418 | frames = spec->samples; | ||
419 | status = SDL_NAME(snd_pcm_hw_params_set_period_size_near)(pcm_handle, hwparams, &frames, NULL); | ||
420 | if ( status < 0 ) { | ||
421 | return(-1); | ||
422 | } | ||
423 | |||
424 | periods = 2; | ||
425 | status = SDL_NAME(snd_pcm_hw_params_set_periods_near)(pcm_handle, hwparams, &periods, NULL); | ||
426 | if ( status < 0 ) { | ||
427 | return(-1); | ||
428 | } | ||
429 | |||
430 | return ALSA_finalize_hardware(this, spec, hwparams, override); | ||
431 | } | ||
432 | |||
433 | static int ALSA_set_buffer_size(_THIS, SDL_AudioSpec *spec, snd_pcm_hw_params_t *params, int override) | ||
434 | { | ||
435 | const char *env; | ||
436 | int status; | ||
437 | snd_pcm_hw_params_t *hwparams; | ||
438 | snd_pcm_uframes_t frames; | ||
439 | |||
440 | /* Copy the hardware parameters for this setup */ | ||
441 | snd_pcm_hw_params_alloca(&hwparams); | ||
442 | SDL_NAME(snd_pcm_hw_params_copy)(hwparams, params); | ||
443 | |||
444 | if ( !override ) { | ||
445 | env = getenv("SDL_AUDIO_ALSA_SET_BUFFER_SIZE"); | ||
446 | if ( env ) { | ||
447 | override = SDL_atoi(env); | ||
448 | if ( override == 0 ) { | ||
449 | return(-1); | ||
450 | } | ||
451 | } | ||
452 | } | ||
453 | |||
454 | frames = spec->samples * 2; | ||
455 | status = SDL_NAME(snd_pcm_hw_params_set_buffer_size_near)(pcm_handle, hwparams, &frames); | ||
456 | if ( status < 0 ) { | ||
457 | return(-1); | ||
458 | } | ||
459 | |||
460 | return ALSA_finalize_hardware(this, spec, hwparams, override); | ||
461 | } | ||
462 | |||
463 | static int ALSA_OpenAudio(_THIS, SDL_AudioSpec *spec) | ||
464 | { | ||
465 | int status; | ||
466 | snd_pcm_hw_params_t *hwparams; | ||
467 | snd_pcm_sw_params_t *swparams; | ||
468 | snd_pcm_format_t format; | ||
469 | unsigned int rate; | ||
470 | unsigned int channels; | ||
471 | Uint16 test_format; | ||
472 | |||
473 | /* Open the audio device */ | ||
474 | /* Name of device should depend on # channels in spec */ | ||
475 | status = SDL_NAME(snd_pcm_open)(&pcm_handle, get_audio_device(spec->channels), SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK); | ||
476 | |||
477 | if ( status < 0 ) { | ||
478 | SDL_SetError("Couldn't open audio device: %s", SDL_NAME(snd_strerror)(status)); | ||
479 | return(-1); | ||
480 | } | ||
481 | |||
482 | /* Figure out what the hardware is capable of */ | ||
483 | snd_pcm_hw_params_alloca(&hwparams); | ||
484 | status = SDL_NAME(snd_pcm_hw_params_any)(pcm_handle, hwparams); | ||
485 | if ( status < 0 ) { | ||
486 | SDL_SetError("Couldn't get hardware config: %s", SDL_NAME(snd_strerror)(status)); | ||
487 | ALSA_CloseAudio(this); | ||
488 | return(-1); | ||
489 | } | ||
490 | |||
491 | /* SDL only uses interleaved sample output */ | ||
492 | status = SDL_NAME(snd_pcm_hw_params_set_access)(pcm_handle, hwparams, SND_PCM_ACCESS_RW_INTERLEAVED); | ||
493 | if ( status < 0 ) { | ||
494 | SDL_SetError("Couldn't set interleaved access: %s", SDL_NAME(snd_strerror)(status)); | ||
495 | ALSA_CloseAudio(this); | ||
496 | return(-1); | ||
497 | } | ||
498 | |||
499 | /* Try for a closest match on audio format */ | ||
500 | status = -1; | ||
501 | for ( test_format = SDL_FirstAudioFormat(spec->format); | ||
502 | test_format && (status < 0); ) { | ||
503 | switch ( test_format ) { | ||
504 | case AUDIO_U8: | ||
505 | format = SND_PCM_FORMAT_U8; | ||
506 | break; | ||
507 | case AUDIO_S8: | ||
508 | format = SND_PCM_FORMAT_S8; | ||
509 | break; | ||
510 | case AUDIO_S16LSB: | ||
511 | format = SND_PCM_FORMAT_S16_LE; | ||
512 | break; | ||
513 | case AUDIO_S16MSB: | ||
514 | format = SND_PCM_FORMAT_S16_BE; | ||
515 | break; | ||
516 | case AUDIO_U16LSB: | ||
517 | format = SND_PCM_FORMAT_U16_LE; | ||
518 | break; | ||
519 | case AUDIO_U16MSB: | ||
520 | format = SND_PCM_FORMAT_U16_BE; | ||
521 | break; | ||
522 | default: | ||
523 | format = 0; | ||
524 | break; | ||
525 | } | ||
526 | if ( format != 0 ) { | ||
527 | status = SDL_NAME(snd_pcm_hw_params_set_format)(pcm_handle, hwparams, format); | ||
528 | } | ||
529 | if ( status < 0 ) { | ||
530 | test_format = SDL_NextAudioFormat(); | ||
531 | } | ||
532 | } | ||
533 | if ( status < 0 ) { | ||
534 | SDL_SetError("Couldn't find any hardware audio formats"); | ||
535 | ALSA_CloseAudio(this); | ||
536 | return(-1); | ||
537 | } | ||
538 | spec->format = test_format; | ||
539 | |||
540 | /* Set the number of channels */ | ||
541 | status = SDL_NAME(snd_pcm_hw_params_set_channels)(pcm_handle, hwparams, spec->channels); | ||
542 | channels = spec->channels; | ||
543 | if ( status < 0 ) { | ||
544 | status = SDL_NAME(snd_pcm_hw_params_get_channels)(hwparams, &channels); | ||
545 | if ( status < 0 ) { | ||
546 | SDL_SetError("Couldn't set audio channels"); | ||
547 | ALSA_CloseAudio(this); | ||
548 | return(-1); | ||
549 | } | ||
550 | spec->channels = channels; | ||
551 | } | ||
552 | |||
553 | /* Set the audio rate */ | ||
554 | rate = spec->freq; | ||
555 | |||
556 | status = SDL_NAME(snd_pcm_hw_params_set_rate_near)(pcm_handle, hwparams, &rate, NULL); | ||
557 | if ( status < 0 ) { | ||
558 | SDL_SetError("Couldn't set audio frequency: %s", SDL_NAME(snd_strerror)(status)); | ||
559 | ALSA_CloseAudio(this); | ||
560 | return(-1); | ||
561 | } | ||
562 | spec->freq = rate; | ||
563 | |||
564 | /* Set the buffer size, in samples */ | ||
565 | if ( ALSA_set_period_size(this, spec, hwparams, 0) < 0 && | ||
566 | ALSA_set_buffer_size(this, spec, hwparams, 0) < 0 ) { | ||
567 | /* Failed to set desired buffer size, do the best you can... */ | ||
568 | if ( ALSA_set_period_size(this, spec, hwparams, 1) < 0 ) { | ||
569 | SDL_SetError("Couldn't set hardware audio parameters: %s", SDL_NAME(snd_strerror)(status)); | ||
570 | ALSA_CloseAudio(this); | ||
571 | return(-1); | ||
572 | } | ||
573 | } | ||
574 | |||
575 | /* Set the software parameters */ | ||
576 | snd_pcm_sw_params_alloca(&swparams); | ||
577 | status = SDL_NAME(snd_pcm_sw_params_current)(pcm_handle, swparams); | ||
578 | if ( status < 0 ) { | ||
579 | SDL_SetError("Couldn't get software config: %s", SDL_NAME(snd_strerror)(status)); | ||
580 | ALSA_CloseAudio(this); | ||
581 | return(-1); | ||
582 | } | ||
583 | status = SDL_NAME(snd_pcm_sw_params_set_avail_min)(pcm_handle, swparams, spec->samples); | ||
584 | if ( status < 0 ) { | ||
585 | SDL_SetError("Couldn't set minimum available samples: %s", SDL_NAME(snd_strerror)(status)); | ||
586 | ALSA_CloseAudio(this); | ||
587 | return(-1); | ||
588 | } | ||
589 | status = SDL_NAME(snd_pcm_sw_params_set_start_threshold)(pcm_handle, swparams, 1); | ||
590 | if ( status < 0 ) { | ||
591 | SDL_SetError("Couldn't set start threshold: %s", SDL_NAME(snd_strerror)(status)); | ||
592 | ALSA_CloseAudio(this); | ||
593 | return(-1); | ||
594 | } | ||
595 | status = SDL_NAME(snd_pcm_sw_params)(pcm_handle, swparams); | ||
596 | if ( status < 0 ) { | ||
597 | SDL_SetError("Couldn't set software audio parameters: %s", SDL_NAME(snd_strerror)(status)); | ||
598 | ALSA_CloseAudio(this); | ||
599 | return(-1); | ||
600 | } | ||
601 | |||
602 | /* Calculate the final parameters for this audio specification */ | ||
603 | SDL_CalculateAudioSpec(spec); | ||
604 | |||
605 | /* Allocate mixing buffer */ | ||
606 | mixlen = spec->size; | ||
607 | mixbuf = (Uint8 *)SDL_AllocAudioMem(mixlen); | ||
608 | if ( mixbuf == NULL ) { | ||
609 | ALSA_CloseAudio(this); | ||
610 | return(-1); | ||
611 | } | ||
612 | SDL_memset(mixbuf, spec->silence, spec->size); | ||
613 | |||
614 | /* Switch to blocking mode for playback */ | ||
615 | SDL_NAME(snd_pcm_nonblock)(pcm_handle, 0); | ||
616 | |||
617 | /* We're ready to rock and roll. :-) */ | ||
618 | return(0); | ||
619 | } | ||
diff --git a/apps/plugins/sdl/src/audio/alsa/SDL_alsa_audio.h b/apps/plugins/sdl/src/audio/alsa/SDL_alsa_audio.h deleted file mode 100644 index 55ae87b8ac..0000000000 --- a/apps/plugins/sdl/src/audio/alsa/SDL_alsa_audio.h +++ /dev/null | |||
@@ -1,48 +0,0 @@ | |||
1 | /* | ||
2 | SDL - Simple DirectMedia Layer | ||
3 | Copyright (C) 1997-2012 Sam Lantinga | ||
4 | |||
5 | This library is free software; you can redistribute it and/or | ||
6 | modify it under the terms of the GNU Library General Public | ||
7 | License as published by the Free Software Foundation; either | ||
8 | version 2 of the License, or (at your option) any later version. | ||
9 | |||
10 | This library is distributed in the hope that it will be useful, | ||
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | Library General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU Library General Public | ||
16 | License along with this library; if not, write to the Free | ||
17 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
18 | |||
19 | Sam Lantinga | ||
20 | slouken@libsdl.org | ||
21 | */ | ||
22 | #include "SDL_config.h" | ||
23 | |||
24 | #ifndef _ALSA_PCM_audio_h | ||
25 | #define _ALSA_PCM_audio_h | ||
26 | |||
27 | #include <alsa/asoundlib.h> | ||
28 | |||
29 | #include "../SDL_sysaudio.h" | ||
30 | |||
31 | /* Hidden "this" pointer for the video functions */ | ||
32 | #define _THIS SDL_AudioDevice *this | ||
33 | |||
34 | struct SDL_PrivateAudioData { | ||
35 | /* The audio device handle */ | ||
36 | snd_pcm_t *pcm_handle; | ||
37 | |||
38 | /* Raw mixing buffer */ | ||
39 | Uint8 *mixbuf; | ||
40 | int mixlen; | ||
41 | }; | ||
42 | |||
43 | /* Old variable names */ | ||
44 | #define pcm_handle (this->hidden->pcm_handle) | ||
45 | #define mixbuf (this->hidden->mixbuf) | ||
46 | #define mixlen (this->hidden->mixlen) | ||
47 | |||
48 | #endif /* _ALSA_PCM_audio_h */ | ||