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/nto/SDL_nto_audio.c | |
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/nto/SDL_nto_audio.c')
-rw-r--r-- | apps/plugins/sdl/src/audio/nto/SDL_nto_audio.c | 507 |
1 files changed, 0 insertions, 507 deletions
diff --git a/apps/plugins/sdl/src/audio/nto/SDL_nto_audio.c b/apps/plugins/sdl/src/audio/nto/SDL_nto_audio.c deleted file mode 100644 index f951825460..0000000000 --- a/apps/plugins/sdl/src/audio/nto/SDL_nto_audio.c +++ /dev/null | |||
@@ -1,507 +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 | #include <errno.h> | ||
25 | #include <unistd.h> | ||
26 | #include <fcntl.h> | ||
27 | #include <signal.h> | ||
28 | #include <sys/types.h> | ||
29 | #include <sys/time.h> | ||
30 | #include <sched.h> | ||
31 | #include <sys/select.h> | ||
32 | #include <sys/neutrino.h> | ||
33 | #include <sys/asoundlib.h> | ||
34 | |||
35 | #include "SDL_timer.h" | ||
36 | #include "SDL_audio.h" | ||
37 | #include "../SDL_audiomem.h" | ||
38 | #include "../SDL_audio_c.h" | ||
39 | #include "SDL_nto_audio.h" | ||
40 | |||
41 | /* The tag name used by NTO audio */ | ||
42 | #define DRIVER_NAME "qsa-nto" | ||
43 | |||
44 | /* default channel communication parameters */ | ||
45 | #define DEFAULT_CPARAMS_RATE 22050 | ||
46 | #define DEFAULT_CPARAMS_VOICES 1 | ||
47 | /* FIXME: need to add in the near future flexible logic with frag_size and frags count */ | ||
48 | #define DEFAULT_CPARAMS_FRAG_SIZE 4096 | ||
49 | #define DEFAULT_CPARAMS_FRAGS_MIN 1 | ||
50 | #define DEFAULT_CPARAMS_FRAGS_MAX 1 | ||
51 | |||
52 | /* Open the audio device for playback, and don't block if busy */ | ||
53 | #define OPEN_FLAGS SND_PCM_OPEN_PLAYBACK | ||
54 | |||
55 | #define QSA_NO_WORKAROUNDS 0x00000000 | ||
56 | #define QSA_MMAP_WORKAROUND 0x00000001 | ||
57 | |||
58 | struct BuggyCards | ||
59 | { | ||
60 | char* cardname; | ||
61 | unsigned long bugtype; | ||
62 | }; | ||
63 | |||
64 | #define QSA_WA_CARDS 3 | ||
65 | |||
66 | struct BuggyCards buggycards[QSA_WA_CARDS]= | ||
67 | { | ||
68 | {"Sound Blaster Live!", QSA_MMAP_WORKAROUND}, | ||
69 | {"Vortex 8820", QSA_MMAP_WORKAROUND}, | ||
70 | {"Vortex 8830", QSA_MMAP_WORKAROUND}, | ||
71 | }; | ||
72 | |||
73 | /* Audio driver functions */ | ||
74 | static void NTO_ThreadInit(_THIS); | ||
75 | static int NTO_OpenAudio(_THIS, SDL_AudioSpec* spec); | ||
76 | static void NTO_WaitAudio(_THIS); | ||
77 | static void NTO_PlayAudio(_THIS); | ||
78 | static Uint8* NTO_GetAudioBuf(_THIS); | ||
79 | static void NTO_CloseAudio(_THIS); | ||
80 | |||
81 | /* card names check to apply the workarounds */ | ||
82 | static int NTO_CheckBuggyCards(_THIS, unsigned long checkfor) | ||
83 | { | ||
84 | char scardname[33]; | ||
85 | int it; | ||
86 | |||
87 | if (snd_card_get_name(cardno, scardname, 32)<0) | ||
88 | { | ||
89 | return 0; | ||
90 | } | ||
91 | |||
92 | for (it=0; it<QSA_WA_CARDS; it++) | ||
93 | { | ||
94 | if (SDL_strcmp(buggycards[it].cardname, scardname)==0) | ||
95 | { | ||
96 | if (buggycards[it].bugtype==checkfor) | ||
97 | { | ||
98 | return 1; | ||
99 | } | ||
100 | } | ||
101 | } | ||
102 | |||
103 | return 0; | ||
104 | } | ||
105 | |||
106 | static void NTO_ThreadInit(_THIS) | ||
107 | { | ||
108 | int status; | ||
109 | struct sched_param param; | ||
110 | |||
111 | /* increasing default 10 priority to 25 to avoid jerky sound */ | ||
112 | status=SchedGet(0, 0, ¶m); | ||
113 | param.sched_priority=param.sched_curpriority+15; | ||
114 | status=SchedSet(0, 0, SCHED_NOCHANGE, ¶m); | ||
115 | } | ||
116 | |||
117 | /* PCM transfer channel parameters initialize function */ | ||
118 | static void NTO_InitAudioParams(snd_pcm_channel_params_t* cpars) | ||
119 | { | ||
120 | SDL_memset(cpars, 0, sizeof(snd_pcm_channel_params_t)); | ||
121 | |||
122 | cpars->channel = SND_PCM_CHANNEL_PLAYBACK; | ||
123 | cpars->mode = SND_PCM_MODE_BLOCK; | ||
124 | cpars->start_mode = SND_PCM_START_DATA; | ||
125 | cpars->stop_mode = SND_PCM_STOP_STOP; | ||
126 | cpars->format.format = SND_PCM_SFMT_S16_LE; | ||
127 | cpars->format.interleave = 1; | ||
128 | cpars->format.rate = DEFAULT_CPARAMS_RATE; | ||
129 | cpars->format.voices = DEFAULT_CPARAMS_VOICES; | ||
130 | cpars->buf.block.frag_size = DEFAULT_CPARAMS_FRAG_SIZE; | ||
131 | cpars->buf.block.frags_min = DEFAULT_CPARAMS_FRAGS_MIN; | ||
132 | cpars->buf.block.frags_max = DEFAULT_CPARAMS_FRAGS_MAX; | ||
133 | } | ||
134 | |||
135 | static int NTO_AudioAvailable(void) | ||
136 | { | ||
137 | /* See if we can open a nonblocking channel. | ||
138 | Return value '1' means we can. | ||
139 | Return value '0' means we cannot. */ | ||
140 | |||
141 | int available; | ||
142 | int rval; | ||
143 | snd_pcm_t* handle; | ||
144 | |||
145 | available = 0; | ||
146 | handle = NULL; | ||
147 | |||
148 | rval = snd_pcm_open_preferred(&handle, NULL, NULL, OPEN_FLAGS); | ||
149 | |||
150 | if (rval >= 0) | ||
151 | { | ||
152 | available = 1; | ||
153 | |||
154 | if ((rval = snd_pcm_close(handle)) < 0) | ||
155 | { | ||
156 | SDL_SetError("NTO_AudioAvailable(): snd_pcm_close failed: %s\n", snd_strerror(rval)); | ||
157 | available = 0; | ||
158 | } | ||
159 | } | ||
160 | else | ||
161 | { | ||
162 | SDL_SetError("NTO_AudioAvailable(): there are no available audio devices.\n"); | ||
163 | } | ||
164 | |||
165 | return (available); | ||
166 | } | ||
167 | |||
168 | static void NTO_DeleteAudioDevice(SDL_AudioDevice *device) | ||
169 | { | ||
170 | if ((device)&&(device->hidden)) | ||
171 | { | ||
172 | SDL_free(device->hidden); | ||
173 | } | ||
174 | if (device) | ||
175 | { | ||
176 | SDL_free(device); | ||
177 | } | ||
178 | } | ||
179 | |||
180 | static SDL_AudioDevice* NTO_CreateAudioDevice(int devindex) | ||
181 | { | ||
182 | SDL_AudioDevice *this; | ||
183 | |||
184 | /* Initialize all variables that we clean on shutdown */ | ||
185 | this = (SDL_AudioDevice *)SDL_malloc(sizeof(SDL_AudioDevice)); | ||
186 | if (this) | ||
187 | { | ||
188 | SDL_memset(this, 0, sizeof(SDL_AudioDevice)); | ||
189 | this->hidden = (struct SDL_PrivateAudioData *)SDL_malloc(sizeof(struct SDL_PrivateAudioData)); | ||
190 | } | ||
191 | if ((this == NULL) || (this->hidden == NULL)) | ||
192 | { | ||
193 | SDL_OutOfMemory(); | ||
194 | if (this) | ||
195 | { | ||
196 | SDL_free(this); | ||
197 | } | ||
198 | return (0); | ||
199 | } | ||
200 | SDL_memset(this->hidden, 0, sizeof(struct SDL_PrivateAudioData)); | ||
201 | audio_handle = NULL; | ||
202 | |||
203 | /* Set the function pointers */ | ||
204 | this->ThreadInit = NTO_ThreadInit; | ||
205 | this->OpenAudio = NTO_OpenAudio; | ||
206 | this->WaitAudio = NTO_WaitAudio; | ||
207 | this->PlayAudio = NTO_PlayAudio; | ||
208 | this->GetAudioBuf = NTO_GetAudioBuf; | ||
209 | this->CloseAudio = NTO_CloseAudio; | ||
210 | |||
211 | this->free = NTO_DeleteAudioDevice; | ||
212 | |||
213 | return this; | ||
214 | } | ||
215 | |||
216 | AudioBootStrap QNXNTOAUDIO_bootstrap = | ||
217 | { | ||
218 | DRIVER_NAME, "QNX6 QSA-NTO Audio", | ||
219 | NTO_AudioAvailable, | ||
220 | NTO_CreateAudioDevice | ||
221 | }; | ||
222 | |||
223 | /* This function waits until it is possible to write a full sound buffer */ | ||
224 | static void NTO_WaitAudio(_THIS) | ||
225 | { | ||
226 | fd_set wfds; | ||
227 | int selectret; | ||
228 | |||
229 | FD_ZERO(&wfds); | ||
230 | FD_SET(audio_fd, &wfds); | ||
231 | |||
232 | do { | ||
233 | selectret=select(audio_fd + 1, NULL, &wfds, NULL, NULL); | ||
234 | switch (selectret) | ||
235 | { | ||
236 | case -1: | ||
237 | case 0: SDL_SetError("NTO_WaitAudio(): select() failed: %s\n", strerror(errno)); | ||
238 | return; | ||
239 | default: if (FD_ISSET(audio_fd, &wfds)) | ||
240 | { | ||
241 | return; | ||
242 | } | ||
243 | break; | ||
244 | } | ||
245 | } while(1); | ||
246 | } | ||
247 | |||
248 | static void NTO_PlayAudio(_THIS) | ||
249 | { | ||
250 | int written, rval; | ||
251 | int towrite; | ||
252 | void* pcmbuffer; | ||
253 | |||
254 | if (!this->enabled) | ||
255 | { | ||
256 | return; | ||
257 | } | ||
258 | |||
259 | towrite = this->spec.size; | ||
260 | pcmbuffer = pcm_buf; | ||
261 | |||
262 | /* Write the audio data, checking for EAGAIN (buffer full) and underrun */ | ||
263 | do { | ||
264 | written = snd_pcm_plugin_write(audio_handle, pcm_buf, towrite); | ||
265 | if (written != towrite) | ||
266 | { | ||
267 | if ((errno == EAGAIN) || (errno == EWOULDBLOCK)) | ||
268 | { | ||
269 | /* Let a little CPU time go by and try to write again */ | ||
270 | SDL_Delay(1); | ||
271 | /* if we wrote some data */ | ||
272 | towrite -= written; | ||
273 | pcmbuffer += written * this->spec.channels; | ||
274 | continue; | ||
275 | } | ||
276 | else | ||
277 | { | ||
278 | if ((errno == EINVAL) || (errno == EIO)) | ||
279 | { | ||
280 | SDL_memset(&cstatus, 0, sizeof(cstatus)); | ||
281 | cstatus.channel = SND_PCM_CHANNEL_PLAYBACK; | ||
282 | if ((rval = snd_pcm_plugin_status(audio_handle, &cstatus)) < 0) | ||
283 | { | ||
284 | SDL_SetError("NTO_PlayAudio(): snd_pcm_plugin_status failed: %s\n", snd_strerror(rval)); | ||
285 | return; | ||
286 | } | ||
287 | if ((cstatus.status == SND_PCM_STATUS_UNDERRUN) || (cstatus.status == SND_PCM_STATUS_READY)) | ||
288 | { | ||
289 | if ((rval = snd_pcm_plugin_prepare(audio_handle, SND_PCM_CHANNEL_PLAYBACK)) < 0) | ||
290 | { | ||
291 | SDL_SetError("NTO_PlayAudio(): snd_pcm_plugin_prepare failed: %s\n", snd_strerror(rval)); | ||
292 | return; | ||
293 | } | ||
294 | } | ||
295 | continue; | ||
296 | } | ||
297 | else | ||
298 | { | ||
299 | return; | ||
300 | } | ||
301 | } | ||
302 | } | ||
303 | else | ||
304 | { | ||
305 | /* we wrote all remaining data */ | ||
306 | towrite -= written; | ||
307 | pcmbuffer += written * this->spec.channels; | ||
308 | } | ||
309 | } while ((towrite > 0) && (this->enabled)); | ||
310 | |||
311 | /* If we couldn't write, assume fatal error for now */ | ||
312 | if (towrite != 0) | ||
313 | { | ||
314 | this->enabled = 0; | ||
315 | } | ||
316 | |||
317 | return; | ||
318 | } | ||
319 | |||
320 | static Uint8* NTO_GetAudioBuf(_THIS) | ||
321 | { | ||
322 | return pcm_buf; | ||
323 | } | ||
324 | |||
325 | static void NTO_CloseAudio(_THIS) | ||
326 | { | ||
327 | int rval; | ||
328 | |||
329 | this->enabled = 0; | ||
330 | |||
331 | if (audio_handle != NULL) | ||
332 | { | ||
333 | if ((rval = snd_pcm_plugin_flush(audio_handle, SND_PCM_CHANNEL_PLAYBACK)) < 0) | ||
334 | { | ||
335 | SDL_SetError("NTO_CloseAudio(): snd_pcm_plugin_flush failed: %s\n", snd_strerror(rval)); | ||
336 | return; | ||
337 | } | ||
338 | if ((rval = snd_pcm_close(audio_handle)) < 0) | ||
339 | { | ||
340 | SDL_SetError("NTO_CloseAudio(): snd_pcm_close failed: %s\n",snd_strerror(rval)); | ||
341 | return; | ||
342 | } | ||
343 | audio_handle = NULL; | ||
344 | } | ||
345 | } | ||
346 | |||
347 | static int NTO_OpenAudio(_THIS, SDL_AudioSpec* spec) | ||
348 | { | ||
349 | int rval; | ||
350 | int format; | ||
351 | Uint16 test_format; | ||
352 | int found; | ||
353 | |||
354 | audio_handle = NULL; | ||
355 | this->enabled = 0; | ||
356 | |||
357 | if (pcm_buf != NULL) | ||
358 | { | ||
359 | SDL_FreeAudioMem(pcm_buf); | ||
360 | pcm_buf = NULL; | ||
361 | } | ||
362 | |||
363 | /* initialize channel transfer parameters to default */ | ||
364 | NTO_InitAudioParams(&cparams); | ||
365 | |||
366 | /* Open the audio device */ | ||
367 | rval = snd_pcm_open_preferred(&audio_handle, &cardno, &deviceno, OPEN_FLAGS); | ||
368 | if (rval < 0) | ||
369 | { | ||
370 | SDL_SetError("NTO_OpenAudio(): snd_pcm_open failed: %s\n", snd_strerror(rval)); | ||
371 | return (-1); | ||
372 | } | ||
373 | |||
374 | if (!NTO_CheckBuggyCards(this, QSA_MMAP_WORKAROUND)) | ||
375 | { | ||
376 | /* enable count status parameter */ | ||
377 | if ((rval = snd_pcm_plugin_set_disable(audio_handle, PLUGIN_DISABLE_MMAP)) < 0) | ||
378 | { | ||
379 | SDL_SetError("snd_pcm_plugin_set_disable failed: %s\n", snd_strerror(rval)); | ||
380 | return (-1); | ||
381 | } | ||
382 | } | ||
383 | |||
384 | /* Try for a closest match on audio format */ | ||
385 | format = 0; | ||
386 | /* can't use format as SND_PCM_SFMT_U8 = 0 in nto */ | ||
387 | found = 0; | ||
388 | |||
389 | for (test_format=SDL_FirstAudioFormat(spec->format); !found ;) | ||
390 | { | ||
391 | /* if match found set format to equivalent ALSA format */ | ||
392 | switch (test_format) | ||
393 | { | ||
394 | case AUDIO_U8: | ||
395 | format = SND_PCM_SFMT_U8; | ||
396 | found = 1; | ||
397 | break; | ||
398 | case AUDIO_S8: | ||
399 | format = SND_PCM_SFMT_S8; | ||
400 | found = 1; | ||
401 | break; | ||
402 | case AUDIO_S16LSB: | ||
403 | format = SND_PCM_SFMT_S16_LE; | ||
404 | found = 1; | ||
405 | break; | ||
406 | case AUDIO_S16MSB: | ||
407 | format = SND_PCM_SFMT_S16_BE; | ||
408 | found = 1; | ||
409 | break; | ||
410 | case AUDIO_U16LSB: | ||
411 | format = SND_PCM_SFMT_U16_LE; | ||
412 | found = 1; | ||
413 | break; | ||
414 | case AUDIO_U16MSB: | ||
415 | format = SND_PCM_SFMT_U16_BE; | ||
416 | found = 1; | ||
417 | break; | ||
418 | default: | ||
419 | break; | ||
420 | } | ||
421 | |||
422 | if (!found) | ||
423 | { | ||
424 | test_format = SDL_NextAudioFormat(); | ||
425 | } | ||
426 | } | ||
427 | |||
428 | /* assumes test_format not 0 on success */ | ||
429 | if (test_format == 0) | ||
430 | { | ||
431 | SDL_SetError("NTO_OpenAudio(): Couldn't find any hardware audio formats"); | ||
432 | return (-1); | ||
433 | } | ||
434 | |||
435 | spec->format = test_format; | ||
436 | |||
437 | /* Set the audio format */ | ||
438 | cparams.format.format = format; | ||
439 | |||
440 | /* Set mono or stereo audio (currently only two channels supported) */ | ||
441 | cparams.format.voices = spec->channels; | ||
442 | |||
443 | /* Set rate */ | ||
444 | cparams.format.rate = spec->freq; | ||
445 | |||
446 | /* Setup the transfer parameters according to cparams */ | ||
447 | rval = snd_pcm_plugin_params(audio_handle, &cparams); | ||
448 | if (rval < 0) | ||
449 | { | ||
450 | SDL_SetError("NTO_OpenAudio(): snd_pcm_channel_params failed: %s\n", snd_strerror(rval)); | ||
451 | return (-1); | ||
452 | } | ||
453 | |||
454 | /* Make sure channel is setup right one last time */ | ||
455 | SDL_memset(&csetup, 0x00, sizeof(csetup)); | ||
456 | csetup.channel = SND_PCM_CHANNEL_PLAYBACK; | ||
457 | if (snd_pcm_plugin_setup(audio_handle, &csetup) < 0) | ||
458 | { | ||
459 | SDL_SetError("NTO_OpenAudio(): Unable to setup playback channel\n"); | ||
460 | return -1; | ||
461 | } | ||
462 | |||
463 | |||
464 | /* Calculate the final parameters for this audio specification */ | ||
465 | SDL_CalculateAudioSpec(spec); | ||
466 | |||
467 | pcm_len = spec->size; | ||
468 | |||
469 | if (pcm_len==0) | ||
470 | { | ||
471 | pcm_len = csetup.buf.block.frag_size * spec->channels * (snd_pcm_format_width(format)/8); | ||
472 | } | ||
473 | |||
474 | /* Allocate memory to the audio buffer and initialize with silence (Note that | ||
475 | buffer size must be a multiple of fragment size, so find closest multiple) | ||
476 | */ | ||
477 | pcm_buf = (Uint8*)SDL_AllocAudioMem(pcm_len); | ||
478 | if (pcm_buf == NULL) | ||
479 | { | ||
480 | SDL_SetError("NTO_OpenAudio(): pcm buffer allocation failed\n"); | ||
481 | return (-1); | ||
482 | } | ||
483 | SDL_memset(pcm_buf, spec->silence, pcm_len); | ||
484 | |||
485 | /* get the file descriptor */ | ||
486 | if ((audio_fd = snd_pcm_file_descriptor(audio_handle, SND_PCM_CHANNEL_PLAYBACK)) < 0) | ||
487 | { | ||
488 | SDL_SetError("NTO_OpenAudio(): snd_pcm_file_descriptor failed with error code: %s\n", snd_strerror(rval)); | ||
489 | return (-1); | ||
490 | } | ||
491 | |||
492 | /* Trigger audio playback */ | ||
493 | rval = snd_pcm_plugin_prepare(audio_handle, SND_PCM_CHANNEL_PLAYBACK); | ||
494 | if (rval < 0) | ||
495 | { | ||
496 | SDL_SetError("snd_pcm_plugin_prepare failed: %s\n", snd_strerror(rval)); | ||
497 | return (-1); | ||
498 | } | ||
499 | |||
500 | this->enabled = 1; | ||
501 | |||
502 | /* Get the parent process id (we're the parent of the audio thread) */ | ||
503 | parent = getpid(); | ||
504 | |||
505 | /* We're really ready to rock and roll. :-) */ | ||
506 | return (0); | ||
507 | } | ||