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 | |
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')
67 files changed, 0 insertions, 15098 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 */ | ||
diff --git a/apps/plugins/sdl/src/audio/arts/SDL_artsaudio.c b/apps/plugins/sdl/src/audio/arts/SDL_artsaudio.c deleted file mode 100644 index 373f8c1677..0000000000 --- a/apps/plugins/sdl/src/audio/arts/SDL_artsaudio.c +++ /dev/null | |||
@@ -1,362 +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 Lesser General Public | ||
7 | License as published by the Free Software Foundation; either | ||
8 | version 2.1 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 | Lesser General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU Lesser General Public | ||
16 | License along with this library; if not, write to the Free Software | ||
17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 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 | #ifdef HAVE_SIGNAL_H | ||
27 | #include <signal.h> | ||
28 | #endif | ||
29 | #include <unistd.h> | ||
30 | |||
31 | #include "SDL_timer.h" | ||
32 | #include "SDL_audio.h" | ||
33 | #include "../SDL_audiomem.h" | ||
34 | #include "../SDL_audio_c.h" | ||
35 | #include "../SDL_audiodev_c.h" | ||
36 | #include "SDL_artsaudio.h" | ||
37 | |||
38 | #ifdef SDL_AUDIO_DRIVER_ARTS_DYNAMIC | ||
39 | #include "SDL_name.h" | ||
40 | #include "SDL_loadso.h" | ||
41 | #else | ||
42 | #define SDL_NAME(X) X | ||
43 | #endif | ||
44 | |||
45 | /* The tag name used by artsc audio */ | ||
46 | #define ARTS_DRIVER_NAME "arts" | ||
47 | |||
48 | /* Audio driver functions */ | ||
49 | static int ARTS_OpenAudio(_THIS, SDL_AudioSpec *spec); | ||
50 | static void ARTS_WaitAudio(_THIS); | ||
51 | static void ARTS_PlayAudio(_THIS); | ||
52 | static Uint8 *ARTS_GetAudioBuf(_THIS); | ||
53 | static void ARTS_CloseAudio(_THIS); | ||
54 | |||
55 | #ifdef SDL_AUDIO_DRIVER_ARTS_DYNAMIC | ||
56 | |||
57 | static const char *arts_library = SDL_AUDIO_DRIVER_ARTS_DYNAMIC; | ||
58 | static void *arts_handle = NULL; | ||
59 | static int arts_loaded = 0; | ||
60 | |||
61 | static int (*SDL_NAME(arts_init))(void); | ||
62 | static void (*SDL_NAME(arts_free))(void); | ||
63 | static arts_stream_t (*SDL_NAME(arts_play_stream))(int rate, int bits, int channels, const char *name); | ||
64 | static int (*SDL_NAME(arts_stream_set))(arts_stream_t s, arts_parameter_t param, int value); | ||
65 | static int (*SDL_NAME(arts_stream_get))(arts_stream_t s, arts_parameter_t param); | ||
66 | static int (*SDL_NAME(arts_write))(arts_stream_t s, const void *buffer, int count); | ||
67 | static void (*SDL_NAME(arts_close_stream))(arts_stream_t s); | ||
68 | static int (*SDL_NAME(arts_suspend))(void); | ||
69 | static int (*SDL_NAME(arts_suspended))(void); | ||
70 | static const char *(*SDL_NAME(arts_error_text))(int errorcode); | ||
71 | |||
72 | static struct { | ||
73 | const char *name; | ||
74 | void **func; | ||
75 | } arts_functions[] = { | ||
76 | { "arts_init", (void **)&SDL_NAME(arts_init) }, | ||
77 | { "arts_free", (void **)&SDL_NAME(arts_free) }, | ||
78 | { "arts_play_stream", (void **)&SDL_NAME(arts_play_stream) }, | ||
79 | { "arts_stream_set", (void **)&SDL_NAME(arts_stream_set) }, | ||
80 | { "arts_stream_get", (void **)&SDL_NAME(arts_stream_get) }, | ||
81 | { "arts_write", (void **)&SDL_NAME(arts_write) }, | ||
82 | { "arts_close_stream", (void **)&SDL_NAME(arts_close_stream) }, | ||
83 | { "arts_suspend", (void **)&SDL_NAME(arts_suspend) }, | ||
84 | { "arts_suspended", (void **)&SDL_NAME(arts_suspended) }, | ||
85 | { "arts_error_text", (void **)&SDL_NAME(arts_error_text) }, | ||
86 | }; | ||
87 | |||
88 | static void UnloadARTSLibrary() | ||
89 | { | ||
90 | if ( arts_loaded ) { | ||
91 | SDL_UnloadObject(arts_handle); | ||
92 | arts_handle = NULL; | ||
93 | arts_loaded = 0; | ||
94 | } | ||
95 | } | ||
96 | |||
97 | static int LoadARTSLibrary(void) | ||
98 | { | ||
99 | int i, retval = -1; | ||
100 | |||
101 | arts_handle = SDL_LoadObject(arts_library); | ||
102 | if ( arts_handle ) { | ||
103 | arts_loaded = 1; | ||
104 | retval = 0; | ||
105 | for ( i=0; i<SDL_arraysize(arts_functions); ++i ) { | ||
106 | *arts_functions[i].func = SDL_LoadFunction(arts_handle, arts_functions[i].name); | ||
107 | if ( !*arts_functions[i].func ) { | ||
108 | retval = -1; | ||
109 | UnloadARTSLibrary(); | ||
110 | break; | ||
111 | } | ||
112 | } | ||
113 | } | ||
114 | return retval; | ||
115 | } | ||
116 | |||
117 | #else | ||
118 | |||
119 | static void UnloadARTSLibrary() | ||
120 | { | ||
121 | return; | ||
122 | } | ||
123 | |||
124 | static int LoadARTSLibrary(void) | ||
125 | { | ||
126 | return 0; | ||
127 | } | ||
128 | |||
129 | #endif /* SDL_AUDIO_DRIVER_ARTS_DYNAMIC */ | ||
130 | |||
131 | /* Audio driver bootstrap functions */ | ||
132 | |||
133 | static int ARTS_Suspend(void) | ||
134 | { | ||
135 | const Uint32 abortms = SDL_GetTicks() + 3000; /* give up after 3 secs */ | ||
136 | while ( (!SDL_NAME(arts_suspended)()) && (SDL_GetTicks() < abortms) ) { | ||
137 | if ( SDL_NAME(arts_suspend)() ) { | ||
138 | break; | ||
139 | } | ||
140 | } | ||
141 | |||
142 | return SDL_NAME(arts_suspended)(); | ||
143 | } | ||
144 | |||
145 | static int Audio_Available(void) | ||
146 | { | ||
147 | int available = 0; | ||
148 | |||
149 | if ( LoadARTSLibrary() < 0 ) { | ||
150 | return available; | ||
151 | } | ||
152 | if ( SDL_NAME(arts_init)() == 0 ) { | ||
153 | if ( ARTS_Suspend() ) { | ||
154 | /* Play a stream so aRts doesn't crash */ | ||
155 | arts_stream_t stream2; | ||
156 | stream2=SDL_NAME(arts_play_stream)(44100, 16, 2, "SDL"); | ||
157 | SDL_NAME(arts_write)(stream2, "", 0); | ||
158 | SDL_NAME(arts_close_stream)(stream2); | ||
159 | available = 1; | ||
160 | } | ||
161 | SDL_NAME(arts_free)(); | ||
162 | } | ||
163 | UnloadARTSLibrary(); | ||
164 | |||
165 | return available; | ||
166 | } | ||
167 | |||
168 | static void Audio_DeleteDevice(SDL_AudioDevice *device) | ||
169 | { | ||
170 | SDL_free(device->hidden); | ||
171 | SDL_free(device); | ||
172 | UnloadARTSLibrary(); | ||
173 | } | ||
174 | |||
175 | static SDL_AudioDevice *Audio_CreateDevice(int devindex) | ||
176 | { | ||
177 | SDL_AudioDevice *this; | ||
178 | |||
179 | /* Initialize all variables that we clean on shutdown */ | ||
180 | LoadARTSLibrary(); | ||
181 | this = (SDL_AudioDevice *)SDL_malloc(sizeof(SDL_AudioDevice)); | ||
182 | if ( this ) { | ||
183 | SDL_memset(this, 0, (sizeof *this)); | ||
184 | this->hidden = (struct SDL_PrivateAudioData *) | ||
185 | SDL_malloc((sizeof *this->hidden)); | ||
186 | } | ||
187 | if ( (this == NULL) || (this->hidden == NULL) ) { | ||
188 | SDL_OutOfMemory(); | ||
189 | if ( this ) { | ||
190 | SDL_free(this); | ||
191 | } | ||
192 | return(0); | ||
193 | } | ||
194 | SDL_memset(this->hidden, 0, (sizeof *this->hidden)); | ||
195 | stream = 0; | ||
196 | |||
197 | /* Set the function pointers */ | ||
198 | this->OpenAudio = ARTS_OpenAudio; | ||
199 | this->WaitAudio = ARTS_WaitAudio; | ||
200 | this->PlayAudio = ARTS_PlayAudio; | ||
201 | this->GetAudioBuf = ARTS_GetAudioBuf; | ||
202 | this->CloseAudio = ARTS_CloseAudio; | ||
203 | |||
204 | this->free = Audio_DeleteDevice; | ||
205 | |||
206 | return this; | ||
207 | } | ||
208 | |||
209 | AudioBootStrap ARTS_bootstrap = { | ||
210 | ARTS_DRIVER_NAME, "Analog Realtime Synthesizer", | ||
211 | Audio_Available, Audio_CreateDevice | ||
212 | }; | ||
213 | |||
214 | /* This function waits until it is possible to write a full sound buffer */ | ||
215 | static void ARTS_WaitAudio(_THIS) | ||
216 | { | ||
217 | Sint32 ticks; | ||
218 | |||
219 | /* Check to see if the thread-parent process is still alive */ | ||
220 | { static int cnt = 0; | ||
221 | /* Note that this only works with thread implementations | ||
222 | that use a different process id for each thread. | ||
223 | */ | ||
224 | if (parent && (((++cnt)%10) == 0)) { /* Check every 10 loops */ | ||
225 | if ( kill(parent, 0) < 0 ) { | ||
226 | this->enabled = 0; | ||
227 | } | ||
228 | } | ||
229 | } | ||
230 | |||
231 | /* Use timer for general audio synchronization */ | ||
232 | ticks = ((Sint32)(next_frame - SDL_GetTicks()))-FUDGE_TICKS; | ||
233 | if ( ticks > 0 ) { | ||
234 | SDL_Delay(ticks); | ||
235 | } | ||
236 | } | ||
237 | |||
238 | static void ARTS_PlayAudio(_THIS) | ||
239 | { | ||
240 | int written; | ||
241 | |||
242 | /* Write the audio data */ | ||
243 | written = SDL_NAME(arts_write)(stream, mixbuf, mixlen); | ||
244 | |||
245 | /* If timer synchronization is enabled, set the next write frame */ | ||
246 | if ( frame_ticks ) { | ||
247 | next_frame += frame_ticks; | ||
248 | } | ||
249 | |||
250 | /* If we couldn't write, assume fatal error for now */ | ||
251 | if ( written < 0 ) { | ||
252 | this->enabled = 0; | ||
253 | } | ||
254 | #ifdef DEBUG_AUDIO | ||
255 | fprintf(stderr, "Wrote %d bytes of audio data\n", written); | ||
256 | #endif | ||
257 | } | ||
258 | |||
259 | static Uint8 *ARTS_GetAudioBuf(_THIS) | ||
260 | { | ||
261 | return(mixbuf); | ||
262 | } | ||
263 | |||
264 | static void ARTS_CloseAudio(_THIS) | ||
265 | { | ||
266 | if ( mixbuf != NULL ) { | ||
267 | SDL_FreeAudioMem(mixbuf); | ||
268 | mixbuf = NULL; | ||
269 | } | ||
270 | if ( stream ) { | ||
271 | SDL_NAME(arts_close_stream)(stream); | ||
272 | stream = 0; | ||
273 | } | ||
274 | SDL_NAME(arts_free)(); | ||
275 | } | ||
276 | |||
277 | static int ARTS_OpenAudio(_THIS, SDL_AudioSpec *spec) | ||
278 | { | ||
279 | int bits, frag_spec; | ||
280 | Uint16 test_format, format; | ||
281 | int error_code; | ||
282 | |||
283 | /* Reset the timer synchronization flag */ | ||
284 | frame_ticks = 0.0; | ||
285 | |||
286 | mixbuf = NULL; | ||
287 | |||
288 | /* Try for a closest match on audio format */ | ||
289 | format = 0; | ||
290 | bits = 0; | ||
291 | for ( test_format = SDL_FirstAudioFormat(spec->format); | ||
292 | ! format && test_format; ) { | ||
293 | #ifdef DEBUG_AUDIO | ||
294 | fprintf(stderr, "Trying format 0x%4.4x\n", test_format); | ||
295 | #endif | ||
296 | switch ( test_format ) { | ||
297 | case AUDIO_U8: | ||
298 | bits = 8; | ||
299 | format = 1; | ||
300 | break; | ||
301 | case AUDIO_S16LSB: | ||
302 | bits = 16; | ||
303 | format = 1; | ||
304 | break; | ||
305 | default: | ||
306 | format = 0; | ||
307 | break; | ||
308 | } | ||
309 | if ( ! format ) { | ||
310 | test_format = SDL_NextAudioFormat(); | ||
311 | } | ||
312 | } | ||
313 | if ( format == 0 ) { | ||
314 | SDL_SetError("Couldn't find any hardware audio formats"); | ||
315 | return(-1); | ||
316 | } | ||
317 | spec->format = test_format; | ||
318 | |||
319 | error_code = SDL_NAME(arts_init)(); | ||
320 | if ( error_code != 0 ) { | ||
321 | SDL_SetError("Unable to initialize ARTS: %s", SDL_NAME(arts_error_text)(error_code)); | ||
322 | return(-1); | ||
323 | } | ||
324 | if ( ! ARTS_Suspend() ) { | ||
325 | SDL_SetError("ARTS can not open audio device"); | ||
326 | return(-1); | ||
327 | } | ||
328 | stream = SDL_NAME(arts_play_stream)(spec->freq, bits, spec->channels, "SDL"); | ||
329 | |||
330 | /* Calculate the final parameters for this audio specification */ | ||
331 | SDL_CalculateAudioSpec(spec); | ||
332 | |||
333 | /* Determine the power of two of the fragment size */ | ||
334 | for ( frag_spec = 0; (0x01<<frag_spec) < spec->size; ++frag_spec ); | ||
335 | if ( (0x01<<frag_spec) != spec->size ) { | ||
336 | SDL_SetError("Fragment size must be a power of two"); | ||
337 | return(-1); | ||
338 | } | ||
339 | frag_spec |= 0x00020000; /* two fragments, for low latency */ | ||
340 | |||
341 | #ifdef ARTS_P_PACKET_SETTINGS | ||
342 | SDL_NAME(arts_stream_set)(stream, ARTS_P_PACKET_SETTINGS, frag_spec); | ||
343 | #else | ||
344 | SDL_NAME(arts_stream_set)(stream, ARTS_P_PACKET_SIZE, frag_spec&0xffff); | ||
345 | SDL_NAME(arts_stream_set)(stream, ARTS_P_PACKET_COUNT, frag_spec>>16); | ||
346 | #endif | ||
347 | spec->size = SDL_NAME(arts_stream_get)(stream, ARTS_P_PACKET_SIZE); | ||
348 | |||
349 | /* Allocate mixing buffer */ | ||
350 | mixlen = spec->size; | ||
351 | mixbuf = (Uint8 *)SDL_AllocAudioMem(mixlen); | ||
352 | if ( mixbuf == NULL ) { | ||
353 | return(-1); | ||
354 | } | ||
355 | SDL_memset(mixbuf, spec->silence, spec->size); | ||
356 | |||
357 | /* Get the parent process id (we're the parent of the audio thread) */ | ||
358 | parent = getpid(); | ||
359 | |||
360 | /* We're ready to rock and roll. :-) */ | ||
361 | return(0); | ||
362 | } | ||
diff --git a/apps/plugins/sdl/src/audio/arts/SDL_artsaudio.h b/apps/plugins/sdl/src/audio/arts/SDL_artsaudio.h deleted file mode 100644 index de3b22822c..0000000000 --- a/apps/plugins/sdl/src/audio/arts/SDL_artsaudio.h +++ /dev/null | |||
@@ -1,60 +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 Lesser General Public | ||
7 | License as published by the Free Software Foundation; either | ||
8 | version 2.1 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 | Lesser General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU Lesser General Public | ||
16 | License along with this library; if not, write to the Free Software | ||
17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
18 | |||
19 | Sam Lantinga | ||
20 | slouken@libsdl.org | ||
21 | */ | ||
22 | #include "SDL_config.h" | ||
23 | |||
24 | #ifndef _SDL_artscaudio_h | ||
25 | #define _SDL_artscaudio_h | ||
26 | |||
27 | #include <artsc.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 stream descriptor for the audio device */ | ||
36 | arts_stream_t stream; | ||
37 | |||
38 | /* The parent process id, to detect when application quits */ | ||
39 | pid_t parent; | ||
40 | |||
41 | /* Raw mixing buffer */ | ||
42 | Uint8 *mixbuf; | ||
43 | int mixlen; | ||
44 | |||
45 | /* Support for audio timing using a timer, in addition to select() */ | ||
46 | float frame_ticks; | ||
47 | float next_frame; | ||
48 | }; | ||
49 | #define FUDGE_TICKS 10 /* The scheduler overhead ticks per frame */ | ||
50 | |||
51 | /* Old variable names */ | ||
52 | #define stream (this->hidden->stream) | ||
53 | #define parent (this->hidden->parent) | ||
54 | #define mixbuf (this->hidden->mixbuf) | ||
55 | #define mixlen (this->hidden->mixlen) | ||
56 | #define frame_ticks (this->hidden->frame_ticks) | ||
57 | #define next_frame (this->hidden->next_frame) | ||
58 | |||
59 | #endif /* _SDL_artscaudio_h */ | ||
60 | |||
diff --git a/apps/plugins/sdl/src/audio/baudio/SDL_beaudio.cc b/apps/plugins/sdl/src/audio/baudio/SDL_beaudio.cc deleted file mode 100644 index de635f8bad..0000000000 --- a/apps/plugins/sdl/src/audio/baudio/SDL_beaudio.cc +++ /dev/null | |||
@@ -1,225 +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 Lesser General Public | ||
7 | License as published by the Free Software Foundation; either | ||
8 | version 2.1 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 | Lesser General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU Lesser General Public | ||
16 | License along with this library; if not, write to the Free Software | ||
17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
18 | |||
19 | Sam Lantinga | ||
20 | slouken@libsdl.org | ||
21 | */ | ||
22 | #include "SDL_config.h" | ||
23 | |||
24 | /* Allow access to the audio stream on BeOS */ | ||
25 | |||
26 | #include <SoundPlayer.h> | ||
27 | |||
28 | #include "../../main/beos/SDL_BeApp.h" | ||
29 | |||
30 | extern "C" { | ||
31 | |||
32 | #include "SDL_audio.h" | ||
33 | #include "../SDL_audio_c.h" | ||
34 | #include "../SDL_sysaudio.h" | ||
35 | #include "../../thread/beos/SDL_systhread_c.h" | ||
36 | #include "SDL_beaudio.h" | ||
37 | |||
38 | |||
39 | /* Audio driver functions */ | ||
40 | static int BE_OpenAudio(_THIS, SDL_AudioSpec *spec); | ||
41 | static void BE_WaitAudio(_THIS); | ||
42 | static void BE_PlayAudio(_THIS); | ||
43 | static Uint8 *BE_GetAudioBuf(_THIS); | ||
44 | static void BE_CloseAudio(_THIS); | ||
45 | |||
46 | /* Audio driver bootstrap functions */ | ||
47 | |||
48 | static int Audio_Available(void) | ||
49 | { | ||
50 | return(1); | ||
51 | } | ||
52 | |||
53 | static void Audio_DeleteDevice(SDL_AudioDevice *device) | ||
54 | { | ||
55 | SDL_free(device->hidden); | ||
56 | SDL_free(device); | ||
57 | } | ||
58 | |||
59 | static SDL_AudioDevice *Audio_CreateDevice(int devindex) | ||
60 | { | ||
61 | SDL_AudioDevice *device; | ||
62 | |||
63 | /* Initialize all variables that we clean on shutdown */ | ||
64 | device = (SDL_AudioDevice *)SDL_malloc(sizeof(SDL_AudioDevice)); | ||
65 | if ( device ) { | ||
66 | SDL_memset(device, 0, (sizeof *device)); | ||
67 | device->hidden = (struct SDL_PrivateAudioData *) | ||
68 | SDL_malloc((sizeof *device->hidden)); | ||
69 | } | ||
70 | if ( (device == NULL) || (device->hidden == NULL) ) { | ||
71 | SDL_OutOfMemory(); | ||
72 | if ( device ) { | ||
73 | SDL_free(device); | ||
74 | } | ||
75 | return(0); | ||
76 | } | ||
77 | SDL_memset(device->hidden, 0, (sizeof *device->hidden)); | ||
78 | |||
79 | /* Set the function pointers */ | ||
80 | device->OpenAudio = BE_OpenAudio; | ||
81 | device->WaitAudio = BE_WaitAudio; | ||
82 | device->PlayAudio = BE_PlayAudio; | ||
83 | device->GetAudioBuf = BE_GetAudioBuf; | ||
84 | device->CloseAudio = BE_CloseAudio; | ||
85 | |||
86 | device->free = Audio_DeleteDevice; | ||
87 | |||
88 | return device; | ||
89 | } | ||
90 | |||
91 | AudioBootStrap BAUDIO_bootstrap = { | ||
92 | "baudio", "BeOS BSoundPlayer", | ||
93 | Audio_Available, Audio_CreateDevice | ||
94 | }; | ||
95 | |||
96 | /* The BeOS callback for handling the audio buffer */ | ||
97 | static void FillSound(void *device, void *stream, size_t len, | ||
98 | const media_raw_audio_format &format) | ||
99 | { | ||
100 | SDL_AudioDevice *audio = (SDL_AudioDevice *)device; | ||
101 | |||
102 | /* Silence the buffer, since it's ours */ | ||
103 | SDL_memset(stream, audio->spec.silence, len); | ||
104 | |||
105 | /* Only do soemthing if audio is enabled */ | ||
106 | if ( ! audio->enabled ) | ||
107 | return; | ||
108 | |||
109 | if ( ! audio->paused ) { | ||
110 | if ( audio->convert.needed ) { | ||
111 | SDL_mutexP(audio->mixer_lock); | ||
112 | (*audio->spec.callback)(audio->spec.userdata, | ||
113 | (Uint8 *)audio->convert.buf,audio->convert.len); | ||
114 | SDL_mutexV(audio->mixer_lock); | ||
115 | SDL_ConvertAudio(&audio->convert); | ||
116 | SDL_memcpy(stream,audio->convert.buf,audio->convert.len_cvt); | ||
117 | } else { | ||
118 | SDL_mutexP(audio->mixer_lock); | ||
119 | (*audio->spec.callback)(audio->spec.userdata, | ||
120 | (Uint8 *)stream, len); | ||
121 | SDL_mutexV(audio->mixer_lock); | ||
122 | } | ||
123 | } | ||
124 | return; | ||
125 | } | ||
126 | |||
127 | /* Dummy functions -- we don't use thread-based audio */ | ||
128 | void BE_WaitAudio(_THIS) | ||
129 | { | ||
130 | return; | ||
131 | } | ||
132 | void BE_PlayAudio(_THIS) | ||
133 | { | ||
134 | return; | ||
135 | } | ||
136 | Uint8 *BE_GetAudioBuf(_THIS) | ||
137 | { | ||
138 | return(NULL); | ||
139 | } | ||
140 | |||
141 | void BE_CloseAudio(_THIS) | ||
142 | { | ||
143 | if ( audio_obj ) { | ||
144 | audio_obj->Stop(); | ||
145 | delete audio_obj; | ||
146 | audio_obj = NULL; | ||
147 | } | ||
148 | |||
149 | /* Quit the Be Application, if there's nothing left to do */ | ||
150 | SDL_QuitBeApp(); | ||
151 | } | ||
152 | |||
153 | int BE_OpenAudio(_THIS, SDL_AudioSpec *spec) | ||
154 | { | ||
155 | int valid_datatype = 0; | ||
156 | media_raw_audio_format format; | ||
157 | Uint16 test_format = SDL_FirstAudioFormat(spec->format); | ||
158 | |||
159 | /* Parse the audio format and fill the Be raw audio format */ | ||
160 | memset(&format, '\0', sizeof (media_raw_audio_format)); | ||
161 | format.byte_order = B_MEDIA_LITTLE_ENDIAN; | ||
162 | format.frame_rate = (float) spec->freq; | ||
163 | format.channel_count = spec->channels; /* !!! FIXME: support > 2? */ | ||
164 | while ((!valid_datatype) && (test_format)) { | ||
165 | valid_datatype = 1; | ||
166 | spec->format = test_format; | ||
167 | switch (test_format) { | ||
168 | case AUDIO_S8: | ||
169 | format.format = media_raw_audio_format::B_AUDIO_CHAR; | ||
170 | break; | ||
171 | |||
172 | case AUDIO_U8: | ||
173 | format.format = media_raw_audio_format::B_AUDIO_UCHAR; | ||
174 | break; | ||
175 | |||
176 | case AUDIO_S16LSB: | ||
177 | format.format = media_raw_audio_format::B_AUDIO_SHORT; | ||
178 | break; | ||
179 | |||
180 | case AUDIO_S16MSB: | ||
181 | format.format = media_raw_audio_format::B_AUDIO_SHORT; | ||
182 | format.byte_order = B_MEDIA_BIG_ENDIAN; | ||
183 | break; | ||
184 | |||
185 | default: | ||
186 | valid_datatype = 0; | ||
187 | test_format = SDL_NextAudioFormat(); | ||
188 | break; | ||
189 | } | ||
190 | } | ||
191 | |||
192 | if (!valid_datatype) { /* shouldn't happen, but just in case... */ | ||
193 | SDL_SetError("Unsupported audio format"); | ||
194 | return (-1); | ||
195 | } | ||
196 | |||
197 | /* Initialize the Be Application, if it's not already started */ | ||
198 | if (SDL_InitBeApp() < 0) { | ||
199 | return (-1); | ||
200 | } | ||
201 | |||
202 | format.buffer_size = spec->samples; | ||
203 | |||
204 | /* Calculate the final parameters for this audio specification */ | ||
205 | SDL_CalculateAudioSpec(spec); | ||
206 | |||
207 | /* Subscribe to the audio stream (creates a new thread) */ | ||
208 | { sigset_t omask; | ||
209 | SDL_MaskSignals(&omask); | ||
210 | audio_obj = new BSoundPlayer(&format, "SDL Audio", FillSound, | ||
211 | NULL, _this); | ||
212 | SDL_UnmaskSignals(&omask); | ||
213 | } | ||
214 | if ( audio_obj->Start() == B_NO_ERROR ) { | ||
215 | audio_obj->SetHasData(true); | ||
216 | } else { | ||
217 | SDL_SetError("Unable to start Be audio"); | ||
218 | return(-1); | ||
219 | } | ||
220 | |||
221 | /* We're running! */ | ||
222 | return(1); | ||
223 | } | ||
224 | |||
225 | }; /* Extern C */ | ||
diff --git a/apps/plugins/sdl/src/audio/baudio/SDL_beaudio.h b/apps/plugins/sdl/src/audio/baudio/SDL_beaudio.h deleted file mode 100644 index adaf1dee5d..0000000000 --- a/apps/plugins/sdl/src/audio/baudio/SDL_beaudio.h +++ /dev/null | |||
@@ -1,39 +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 Lesser General Public | ||
7 | License as published by the Free Software Foundation; either | ||
8 | version 2.1 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 | Lesser General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU Lesser General Public | ||
16 | License along with this library; if not, write to the Free Software | ||
17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
18 | |||
19 | Sam Lantinga | ||
20 | slouken@libsdl.org | ||
21 | */ | ||
22 | #include "SDL_config.h" | ||
23 | |||
24 | #ifndef _SDL_lowaudio_h | ||
25 | #define _SDL_lowaudio_h | ||
26 | |||
27 | #include "../SDL_sysaudio.h" | ||
28 | |||
29 | /* Hidden "this" pointer for the video functions */ | ||
30 | #define _THIS SDL_AudioDevice *_this | ||
31 | |||
32 | struct SDL_PrivateAudioData { | ||
33 | BSoundPlayer *audio_obj; | ||
34 | }; | ||
35 | |||
36 | /* Old variable names */ | ||
37 | #define audio_obj (_this->hidden->audio_obj) | ||
38 | |||
39 | #endif /* _SDL_lowaudio_h */ | ||
diff --git a/apps/plugins/sdl/src/audio/bsd/SDL_bsdaudio.c b/apps/plugins/sdl/src/audio/bsd/SDL_bsdaudio.c deleted file mode 100644 index e5e0d9480a..0000000000 --- a/apps/plugins/sdl/src/audio/bsd/SDL_bsdaudio.c +++ /dev/null | |||
@@ -1,404 +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 | /* | ||
25 | * Driver for native OpenBSD/NetBSD audio(4). | ||
26 | * vedge@vedge.com.ar. | ||
27 | */ | ||
28 | |||
29 | #include <errno.h> | ||
30 | #include <unistd.h> | ||
31 | #include <fcntl.h> | ||
32 | #include <sys/time.h> | ||
33 | #include <sys/ioctl.h> | ||
34 | #include <sys/stat.h> | ||
35 | #include <sys/types.h> | ||
36 | #include <sys/audioio.h> | ||
37 | |||
38 | #include "SDL_timer.h" | ||
39 | #include "SDL_audio.h" | ||
40 | #include "../SDL_audiomem.h" | ||
41 | #include "../SDL_audio_c.h" | ||
42 | #include "../SDL_audiodev_c.h" | ||
43 | #include "SDL_bsdaudio.h" | ||
44 | |||
45 | /* The tag name used by NetBSD/OpenBSD audio */ | ||
46 | #ifdef __NetBSD__ | ||
47 | #define BSD_AUDIO_DRIVER_NAME "netbsd" | ||
48 | #define BSD_AUDIO_DRIVER_DESC "Native NetBSD audio" | ||
49 | #else | ||
50 | #define BSD_AUDIO_DRIVER_NAME "openbsd" | ||
51 | #define BSD_AUDIO_DRIVER_DESC "Native OpenBSD audio" | ||
52 | #endif | ||
53 | |||
54 | /* Open the audio device for playback, and don't block if busy */ | ||
55 | /* #define USE_BLOCKING_WRITES */ | ||
56 | |||
57 | /* Use timer for synchronization */ | ||
58 | /* #define USE_TIMER_SYNC */ | ||
59 | |||
60 | /* #define DEBUG_AUDIO */ | ||
61 | /* #define DEBUG_AUDIO_STREAM */ | ||
62 | |||
63 | #ifdef USE_BLOCKING_WRITES | ||
64 | #define OPEN_FLAGS O_WRONLY | ||
65 | #else | ||
66 | #define OPEN_FLAGS (O_WRONLY|O_NONBLOCK) | ||
67 | #endif | ||
68 | |||
69 | /* Audio driver functions */ | ||
70 | static void OBSD_WaitAudio(_THIS); | ||
71 | static int OBSD_OpenAudio(_THIS, SDL_AudioSpec *spec); | ||
72 | static void OBSD_PlayAudio(_THIS); | ||
73 | static Uint8 *OBSD_GetAudioBuf(_THIS); | ||
74 | static void OBSD_CloseAudio(_THIS); | ||
75 | |||
76 | #ifdef DEBUG_AUDIO | ||
77 | static void OBSD_Status(_THIS); | ||
78 | #endif | ||
79 | |||
80 | /* Audio driver bootstrap functions */ | ||
81 | |||
82 | static int | ||
83 | Audio_Available(void) | ||
84 | { | ||
85 | int fd; | ||
86 | int available; | ||
87 | |||
88 | available = 0; | ||
89 | fd = SDL_OpenAudioPath(NULL, 0, OPEN_FLAGS, 0); | ||
90 | if(fd >= 0) { | ||
91 | available = 1; | ||
92 | close(fd); | ||
93 | } | ||
94 | return(available); | ||
95 | } | ||
96 | |||
97 | static void | ||
98 | Audio_DeleteDevice(SDL_AudioDevice *device) | ||
99 | { | ||
100 | SDL_free(device->hidden); | ||
101 | SDL_free(device); | ||
102 | } | ||
103 | |||
104 | static SDL_AudioDevice | ||
105 | *Audio_CreateDevice(int devindex) | ||
106 | { | ||
107 | SDL_AudioDevice *this; | ||
108 | |||
109 | /* Initialize all variables that we clean on shutdown */ | ||
110 | this = (SDL_AudioDevice*)SDL_malloc(sizeof(SDL_AudioDevice)); | ||
111 | if(this) { | ||
112 | SDL_memset(this, 0, (sizeof *this)); | ||
113 | this->hidden = | ||
114 | (struct SDL_PrivateAudioData*)SDL_malloc((sizeof *this->hidden)); | ||
115 | } | ||
116 | if((this == NULL) || (this->hidden == NULL)) { | ||
117 | SDL_OutOfMemory(); | ||
118 | if(this) SDL_free(this); | ||
119 | return(0); | ||
120 | } | ||
121 | SDL_memset(this->hidden, 0, (sizeof *this->hidden)); | ||
122 | audio_fd = -1; | ||
123 | |||
124 | /* Set the function pointers */ | ||
125 | this->OpenAudio = OBSD_OpenAudio; | ||
126 | this->WaitAudio = OBSD_WaitAudio; | ||
127 | this->PlayAudio = OBSD_PlayAudio; | ||
128 | this->GetAudioBuf = OBSD_GetAudioBuf; | ||
129 | this->CloseAudio = OBSD_CloseAudio; | ||
130 | |||
131 | this->free = Audio_DeleteDevice; | ||
132 | |||
133 | return this; | ||
134 | } | ||
135 | |||
136 | AudioBootStrap BSD_AUDIO_bootstrap = { | ||
137 | BSD_AUDIO_DRIVER_NAME, BSD_AUDIO_DRIVER_DESC, | ||
138 | Audio_Available, Audio_CreateDevice | ||
139 | }; | ||
140 | |||
141 | /* This function waits until it is possible to write a full sound buffer */ | ||
142 | static void | ||
143 | OBSD_WaitAudio(_THIS) | ||
144 | { | ||
145 | #ifndef USE_BLOCKING_WRITES /* Not necessary when using blocking writes */ | ||
146 | /* See if we need to use timed audio synchronization */ | ||
147 | if ( frame_ticks ) { | ||
148 | /* Use timer for general audio synchronization */ | ||
149 | Sint32 ticks; | ||
150 | |||
151 | ticks = ((Sint32)(next_frame - SDL_GetTicks()))-FUDGE_TICKS; | ||
152 | if ( ticks > 0 ) { | ||
153 | SDL_Delay(ticks); | ||
154 | } | ||
155 | } else { | ||
156 | /* Use select() for audio synchronization */ | ||
157 | fd_set fdset; | ||
158 | struct timeval timeout; | ||
159 | |||
160 | FD_ZERO(&fdset); | ||
161 | FD_SET(audio_fd, &fdset); | ||
162 | timeout.tv_sec = 10; | ||
163 | timeout.tv_usec = 0; | ||
164 | #ifdef DEBUG_AUDIO | ||
165 | fprintf(stderr, "Waiting for audio to get ready\n"); | ||
166 | #endif | ||
167 | if ( select(audio_fd+1, NULL, &fdset, NULL, &timeout) <= 0 ) { | ||
168 | const char *message = | ||
169 | "Audio timeout - buggy audio driver? (disabled)"; | ||
170 | /* In general we should never print to the screen, | ||
171 | but in this case we have no other way of letting | ||
172 | the user know what happened. | ||
173 | */ | ||
174 | fprintf(stderr, "SDL: %s\n", message); | ||
175 | this->enabled = 0; | ||
176 | /* Don't try to close - may hang */ | ||
177 | audio_fd = -1; | ||
178 | #ifdef DEBUG_AUDIO | ||
179 | fprintf(stderr, "Done disabling audio\n"); | ||
180 | #endif | ||
181 | } | ||
182 | #ifdef DEBUG_AUDIO | ||
183 | fprintf(stderr, "Ready!\n"); | ||
184 | #endif | ||
185 | } | ||
186 | #endif /* !USE_BLOCKING_WRITES */ | ||
187 | } | ||
188 | |||
189 | static void | ||
190 | OBSD_PlayAudio(_THIS) | ||
191 | { | ||
192 | int written, p=0; | ||
193 | |||
194 | /* Write the audio data, checking for EAGAIN on broken audio drivers */ | ||
195 | do { | ||
196 | written = write(audio_fd, &mixbuf[p], mixlen-p); | ||
197 | if (written>0) | ||
198 | p += written; | ||
199 | if (written == -1 && errno != 0 && errno != EAGAIN && errno != EINTR) | ||
200 | { | ||
201 | /* Non recoverable error has occurred. It should be reported!!! */ | ||
202 | perror("audio"); | ||
203 | break; | ||
204 | } | ||
205 | |||
206 | if ( p < written || ((written < 0) && ((errno == 0) || (errno == EAGAIN))) ) { | ||
207 | SDL_Delay(1); /* Let a little CPU time go by */ | ||
208 | } | ||
209 | } while ( p < written ); | ||
210 | |||
211 | /* If timer synchronization is enabled, set the next write frame */ | ||
212 | if ( frame_ticks ) { | ||
213 | next_frame += frame_ticks; | ||
214 | } | ||
215 | |||
216 | /* If we couldn't write, assume fatal error for now */ | ||
217 | if ( written < 0 ) { | ||
218 | this->enabled = 0; | ||
219 | } | ||
220 | #ifdef DEBUG_AUDIO | ||
221 | fprintf(stderr, "Wrote %d bytes of audio data\n", written); | ||
222 | #endif | ||
223 | } | ||
224 | |||
225 | static Uint8 | ||
226 | *OBSD_GetAudioBuf(_THIS) | ||
227 | { | ||
228 | return(mixbuf); | ||
229 | } | ||
230 | |||
231 | static void | ||
232 | OBSD_CloseAudio(_THIS) | ||
233 | { | ||
234 | if(mixbuf != NULL) { | ||
235 | SDL_FreeAudioMem(mixbuf); | ||
236 | mixbuf = NULL; | ||
237 | } | ||
238 | if(audio_fd >= 0) { | ||
239 | close(audio_fd); | ||
240 | audio_fd = -1; | ||
241 | } | ||
242 | } | ||
243 | |||
244 | #ifdef DEBUG_AUDIO | ||
245 | void | ||
246 | OBSD_Status(_THIS) | ||
247 | { | ||
248 | audio_info_t info; | ||
249 | |||
250 | if(ioctl(audio_fd, AUDIO_GETINFO, &info) < 0) { | ||
251 | fprintf(stderr,"AUDIO_GETINFO failed.\n"); | ||
252 | return; | ||
253 | } | ||
254 | |||
255 | fprintf(stderr,"\n" | ||
256 | "[play/record info]\n" | ||
257 | "buffer size : %d bytes\n" | ||
258 | "sample rate : %i Hz\n" | ||
259 | "channels : %i\n" | ||
260 | "precision : %i-bit\n" | ||
261 | "encoding : 0x%x\n" | ||
262 | "seek : %i\n" | ||
263 | "sample count : %i\n" | ||
264 | "EOF count : %i\n" | ||
265 | "paused : %s\n" | ||
266 | "error occured : %s\n" | ||
267 | "waiting : %s\n" | ||
268 | "active : %s\n" | ||
269 | "", | ||
270 | info.play.buffer_size, | ||
271 | info.play.sample_rate, | ||
272 | info.play.channels, | ||
273 | info.play.precision, | ||
274 | info.play.encoding, | ||
275 | info.play.seek, | ||
276 | info.play.samples, | ||
277 | info.play.eof, | ||
278 | info.play.pause ? "yes" : "no", | ||
279 | info.play.error ? "yes" : "no", | ||
280 | info.play.waiting ? "yes" : "no", | ||
281 | info.play.active ? "yes": "no"); | ||
282 | |||
283 | fprintf(stderr,"\n" | ||
284 | "[audio info]\n" | ||
285 | "monitor_gain : %i\n" | ||
286 | "hw block size : %d bytes\n" | ||
287 | "hi watermark : %i\n" | ||
288 | "lo watermark : %i\n" | ||
289 | "audio mode : %s\n" | ||
290 | "", | ||
291 | info.monitor_gain, | ||
292 | info.blocksize, | ||
293 | info.hiwat, info.lowat, | ||
294 | (info.mode == AUMODE_PLAY) ? "PLAY" | ||
295 | : (info.mode = AUMODE_RECORD) ? "RECORD" | ||
296 | : (info.mode == AUMODE_PLAY_ALL ? "PLAY_ALL" | ||
297 | : "?")); | ||
298 | } | ||
299 | #endif /* DEBUG_AUDIO */ | ||
300 | |||
301 | static int | ||
302 | OBSD_OpenAudio(_THIS, SDL_AudioSpec *spec) | ||
303 | { | ||
304 | char audiodev[64]; | ||
305 | Uint16 format; | ||
306 | audio_info_t info; | ||
307 | |||
308 | AUDIO_INITINFO(&info); | ||
309 | |||
310 | /* Calculate the final parameters for this audio specification */ | ||
311 | SDL_CalculateAudioSpec(spec); | ||
312 | |||
313 | #ifdef USE_TIMER_SYNC | ||
314 | frame_ticks = 0.0; | ||
315 | #endif | ||
316 | |||
317 | /* Open the audio device */ | ||
318 | audio_fd = SDL_OpenAudioPath(audiodev, sizeof(audiodev), OPEN_FLAGS, 0); | ||
319 | if(audio_fd < 0) { | ||
320 | SDL_SetError("Couldn't open %s: %s", audiodev, strerror(errno)); | ||
321 | return(-1); | ||
322 | } | ||
323 | |||
324 | /* Set to play mode */ | ||
325 | info.mode = AUMODE_PLAY; | ||
326 | if(ioctl(audio_fd, AUDIO_SETINFO, &info) < 0) { | ||
327 | SDL_SetError("Couldn't put device into play mode"); | ||
328 | return(-1); | ||
329 | } | ||
330 | |||
331 | mixbuf = NULL; | ||
332 | AUDIO_INITINFO(&info); | ||
333 | for (format = SDL_FirstAudioFormat(spec->format); | ||
334 | format; format = SDL_NextAudioFormat()) | ||
335 | { | ||
336 | switch(format) { | ||
337 | case AUDIO_U8: | ||
338 | info.play.encoding = AUDIO_ENCODING_ULINEAR; | ||
339 | info.play.precision = 8; | ||
340 | break; | ||
341 | case AUDIO_S8: | ||
342 | info.play.encoding = AUDIO_ENCODING_SLINEAR; | ||
343 | info.play.precision = 8; | ||
344 | break; | ||
345 | case AUDIO_S16LSB: | ||
346 | info.play.encoding = AUDIO_ENCODING_SLINEAR_LE; | ||
347 | info.play.precision = 16; | ||
348 | break; | ||
349 | case AUDIO_S16MSB: | ||
350 | info.play.encoding = AUDIO_ENCODING_SLINEAR_BE; | ||
351 | info.play.precision = 16; | ||
352 | break; | ||
353 | case AUDIO_U16LSB: | ||
354 | info.play.encoding = AUDIO_ENCODING_ULINEAR_LE; | ||
355 | info.play.precision = 16; | ||
356 | break; | ||
357 | case AUDIO_U16MSB: | ||
358 | info.play.encoding = AUDIO_ENCODING_ULINEAR_BE; | ||
359 | info.play.precision = 16; | ||
360 | break; | ||
361 | default: | ||
362 | continue; | ||
363 | } | ||
364 | if (ioctl(audio_fd, AUDIO_SETINFO, &info) == 0) | ||
365 | break; | ||
366 | } | ||
367 | |||
368 | if(!format) { | ||
369 | SDL_SetError("No supported encoding for 0x%x", spec->format); | ||
370 | return(-1); | ||
371 | } | ||
372 | |||
373 | spec->format = format; | ||
374 | |||
375 | AUDIO_INITINFO(&info); | ||
376 | info.play.channels = spec->channels; | ||
377 | if (ioctl(audio_fd, AUDIO_SETINFO, &info) == -1) | ||
378 | spec->channels = 1; | ||
379 | AUDIO_INITINFO(&info); | ||
380 | info.play.sample_rate = spec->freq; | ||
381 | info.blocksize = spec->size; | ||
382 | info.hiwat = 5; | ||
383 | info.lowat = 3; | ||
384 | (void)ioctl(audio_fd, AUDIO_SETINFO, &info); | ||
385 | (void)ioctl(audio_fd, AUDIO_GETINFO, &info); | ||
386 | spec->freq = info.play.sample_rate; | ||
387 | /* Allocate mixing buffer */ | ||
388 | mixlen = spec->size; | ||
389 | mixbuf = (Uint8*)SDL_AllocAudioMem(mixlen); | ||
390 | if(mixbuf == NULL) { | ||
391 | return(-1); | ||
392 | } | ||
393 | SDL_memset(mixbuf, spec->silence, spec->size); | ||
394 | |||
395 | /* Get the parent process id (we're the parent of the audio thread) */ | ||
396 | parent = getpid(); | ||
397 | |||
398 | #ifdef DEBUG_AUDIO | ||
399 | OBSD_Status(this); | ||
400 | #endif | ||
401 | |||
402 | /* We're ready to rock and roll. :-) */ | ||
403 | return(0); | ||
404 | } | ||
diff --git a/apps/plugins/sdl/src/audio/bsd/SDL_bsdaudio.h b/apps/plugins/sdl/src/audio/bsd/SDL_bsdaudio.h deleted file mode 100644 index c9f69cf544..0000000000 --- a/apps/plugins/sdl/src/audio/bsd/SDL_bsdaudio.h +++ /dev/null | |||
@@ -1,58 +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 _SDL_openbsdaudio_h | ||
25 | #define _SDL_openbsdaudio_h | ||
26 | |||
27 | #include "../SDL_sysaudio.h" | ||
28 | |||
29 | #define _THIS SDL_AudioDevice *this | ||
30 | |||
31 | struct SDL_PrivateAudioData | ||
32 | { | ||
33 | /* The file descriptor for the audio device */ | ||
34 | int audio_fd; | ||
35 | |||
36 | /* The parent process id, to detect when application quits */ | ||
37 | pid_t parent; | ||
38 | |||
39 | /* Raw mixing buffer */ | ||
40 | Uint8 *mixbuf; | ||
41 | int mixlen; | ||
42 | |||
43 | /* Support for audio timing using a timer, in addition to select() */ | ||
44 | float frame_ticks; | ||
45 | float next_frame; | ||
46 | }; | ||
47 | |||
48 | #define FUDGE_TICKS 10 /* The scheduler overhead ticks per frame */ | ||
49 | |||
50 | /* Old variable names */ | ||
51 | #define audio_fd (this->hidden->audio_fd) | ||
52 | #define parent (this->hidden->parent) | ||
53 | #define mixbuf (this->hidden->mixbuf) | ||
54 | #define mixlen (this->hidden->mixlen) | ||
55 | #define frame_ticks (this->hidden->frame_ticks) | ||
56 | #define next_frame (this->hidden->next_frame) | ||
57 | |||
58 | #endif /* _SDL_openbsdaudio_h */ | ||
diff --git a/apps/plugins/sdl/src/audio/dart/SDL_dart.c b/apps/plugins/sdl/src/audio/dart/SDL_dart.c deleted file mode 100644 index 77e530db51..0000000000 --- a/apps/plugins/sdl/src/audio/dart/SDL_dart.c +++ /dev/null | |||
@@ -1,441 +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 Lesser General Public | ||
7 | License as published by the Free Software Foundation; either | ||
8 | version 2.1 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 | Lesser General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU Lesser General Public | ||
16 | License along with this library; if not, write to the Free Software | ||
17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 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 "SDL_timer.h" | ||
27 | #include "SDL_audio.h" | ||
28 | #include "../SDL_audio_c.h" | ||
29 | #include "SDL_dart.h" | ||
30 | |||
31 | // Buffer states: | ||
32 | #define BUFFER_EMPTY 0 | ||
33 | #define BUFFER_USED 1 | ||
34 | |||
35 | typedef struct _tMixBufferDesc { | ||
36 | int iBufferUsage; // BUFFER_EMPTY or BUFFER_USED | ||
37 | SDL_AudioDevice *pSDLAudioDevice; | ||
38 | } tMixBufferDesc, *pMixBufferDesc; | ||
39 | |||
40 | |||
41 | //--------------------------------------------------------------------- | ||
42 | // DARTEventFunc | ||
43 | // | ||
44 | // This function is called by DART, when an event occures, like end of | ||
45 | // playback of a buffer, etc... | ||
46 | //--------------------------------------------------------------------- | ||
47 | LONG APIENTRY DARTEventFunc(ULONG ulStatus, | ||
48 | PMCI_MIX_BUFFER pBuffer, | ||
49 | ULONG ulFlags) | ||
50 | { | ||
51 | if (ulFlags && MIX_WRITE_COMPLETE) | ||
52 | { // Playback of buffer completed! | ||
53 | |||
54 | // Get pointer to buffer description | ||
55 | pMixBufferDesc pBufDesc; | ||
56 | |||
57 | if (pBuffer) | ||
58 | { | ||
59 | pBufDesc = (pMixBufferDesc) (*pBuffer).ulUserParm; | ||
60 | |||
61 | if (pBufDesc) | ||
62 | { | ||
63 | SDL_AudioDevice *pSDLAudioDevice = pBufDesc->pSDLAudioDevice; | ||
64 | // Set the buffer to be empty | ||
65 | pBufDesc->iBufferUsage = BUFFER_EMPTY; | ||
66 | // And notify DART feeder thread that it will have to work a bit. | ||
67 | if (pSDLAudioDevice) | ||
68 | DosPostEventSem(pSDLAudioDevice->hidden->hevAudioBufferPlayed); | ||
69 | } | ||
70 | } | ||
71 | } | ||
72 | return TRUE; | ||
73 | } | ||
74 | |||
75 | |||
76 | int DART_OpenAudio(_THIS, SDL_AudioSpec *spec) | ||
77 | { | ||
78 | Uint16 test_format = SDL_FirstAudioFormat(spec->format); | ||
79 | int valid_datatype = 0; | ||
80 | MCI_AMP_OPEN_PARMS AmpOpenParms; | ||
81 | MCI_GENERIC_PARMS GenericParms; | ||
82 | int iDeviceOrd = 0; // Default device to be used | ||
83 | int bOpenShared = 1; // Try opening it shared | ||
84 | int iBits = 16; // Default is 16 bits signed | ||
85 | int iFreq = 44100; // Default is 44KHz | ||
86 | int iChannels = 2; // Default is 2 channels (Stereo) | ||
87 | int iNumBufs = 2; // Number of audio buffers: 2 | ||
88 | int iBufSize; | ||
89 | int iOpenMode; | ||
90 | int iSilence; | ||
91 | int rc; | ||
92 | |||
93 | // First thing is to try to open a given DART device! | ||
94 | SDL_memset(&AmpOpenParms, 0, sizeof(MCI_AMP_OPEN_PARMS)); | ||
95 | // pszDeviceType should contain the device type in low word, and device ordinal in high word! | ||
96 | AmpOpenParms.pszDeviceType = (PSZ) (MCI_DEVTYPE_AUDIO_AMPMIX | (iDeviceOrd << 16)); | ||
97 | |||
98 | iOpenMode = MCI_WAIT | MCI_OPEN_TYPE_ID; | ||
99 | if (bOpenShared) iOpenMode |= MCI_OPEN_SHAREABLE; | ||
100 | |||
101 | rc = mciSendCommand( 0, MCI_OPEN, | ||
102 | iOpenMode, | ||
103 | (PVOID) &AmpOpenParms, 0); | ||
104 | if (rc!=MCIERR_SUCCESS) // No audio available?? | ||
105 | return (-1); | ||
106 | // Save the device ID we got from DART! | ||
107 | // We will use this in the next calls! | ||
108 | iDeviceOrd = AmpOpenParms.usDeviceID; | ||
109 | |||
110 | // Determine the audio parameters from the AudioSpec | ||
111 | if (spec->channels > 2) | ||
112 | spec->channels = 2; // !!! FIXME: more than stereo support in OS/2? | ||
113 | |||
114 | while ((!valid_datatype) && (test_format)) { | ||
115 | spec->format = test_format; | ||
116 | valid_datatype = 1; | ||
117 | switch (test_format) { | ||
118 | case AUDIO_U8: | ||
119 | // Unsigned 8 bit audio data | ||
120 | iSilence = 0x80; | ||
121 | iBits = 8; | ||
122 | break; | ||
123 | |||
124 | case AUDIO_S16LSB: | ||
125 | // Signed 16 bit audio data | ||
126 | iSilence = 0x00; | ||
127 | iBits = 16; | ||
128 | break; | ||
129 | |||
130 | default: | ||
131 | valid_datatype = 0; | ||
132 | test_format = SDL_NextAudioFormat(); | ||
133 | break; | ||
134 | } | ||
135 | } | ||
136 | |||
137 | if (!valid_datatype) { // shouldn't happen, but just in case... | ||
138 | // Close DART, and exit with error code! | ||
139 | mciSendCommand(iDeviceOrd, MCI_CLOSE, MCI_WAIT, &GenericParms, 0); | ||
140 | SDL_SetError("Unsupported audio format"); | ||
141 | return (-1); | ||
142 | } | ||
143 | |||
144 | iFreq = spec->freq; | ||
145 | iChannels = spec->channels; | ||
146 | /* Update the fragment size as size in bytes */ | ||
147 | SDL_CalculateAudioSpec(spec); | ||
148 | iBufSize = spec->size; | ||
149 | |||
150 | // Now query this device if it supports the given freq/bits/channels! | ||
151 | SDL_memset(&(_this->hidden->MixSetupParms), 0, sizeof(MCI_MIXSETUP_PARMS)); | ||
152 | _this->hidden->MixSetupParms.ulBitsPerSample = iBits; | ||
153 | _this->hidden->MixSetupParms.ulFormatTag = MCI_WAVE_FORMAT_PCM; | ||
154 | _this->hidden->MixSetupParms.ulSamplesPerSec = iFreq; | ||
155 | _this->hidden->MixSetupParms.ulChannels = iChannels; | ||
156 | _this->hidden->MixSetupParms.ulFormatMode = MCI_PLAY; | ||
157 | _this->hidden->MixSetupParms.ulDeviceType = MCI_DEVTYPE_WAVEFORM_AUDIO; | ||
158 | _this->hidden->MixSetupParms.pmixEvent = DARTEventFunc; | ||
159 | rc = mciSendCommand (iDeviceOrd, MCI_MIXSETUP, | ||
160 | MCI_WAIT | MCI_MIXSETUP_QUERYMODE, | ||
161 | &(_this->hidden->MixSetupParms), 0); | ||
162 | if (rc!=MCIERR_SUCCESS) | ||
163 | { // The device cannot handle this format! | ||
164 | // Close DART, and exit with error code! | ||
165 | mciSendCommand(iDeviceOrd, MCI_CLOSE, MCI_WAIT, &GenericParms, 0); | ||
166 | SDL_SetError("Audio device doesn't support requested audio format"); | ||
167 | return(-1); | ||
168 | } | ||
169 | // The device can handle this format, so initialize! | ||
170 | rc = mciSendCommand(iDeviceOrd, MCI_MIXSETUP, | ||
171 | MCI_WAIT | MCI_MIXSETUP_INIT, | ||
172 | &(_this->hidden->MixSetupParms), 0); | ||
173 | if (rc!=MCIERR_SUCCESS) | ||
174 | { // The device could not be opened! | ||
175 | // Close DART, and exit with error code! | ||
176 | mciSendCommand(iDeviceOrd, MCI_CLOSE, MCI_WAIT, &GenericParms, 0); | ||
177 | SDL_SetError("Audio device could not be set up"); | ||
178 | return(-1); | ||
179 | } | ||
180 | // Ok, the device is initialized. | ||
181 | // Now we should allocate buffers. For this, we need a place where | ||
182 | // the buffer descriptors will be: | ||
183 | _this->hidden->pMixBuffers = (MCI_MIX_BUFFER *) SDL_malloc(sizeof(MCI_MIX_BUFFER)*iNumBufs); | ||
184 | if (!(_this->hidden->pMixBuffers)) | ||
185 | { // Not enough memory! | ||
186 | // Close DART, and exit with error code! | ||
187 | mciSendCommand(iDeviceOrd, MCI_CLOSE, MCI_WAIT, &GenericParms, 0); | ||
188 | SDL_SetError("Not enough memory for audio buffer descriptors"); | ||
189 | return(-1); | ||
190 | } | ||
191 | // Now that we have the place for buffer list, we can ask DART for the | ||
192 | // buffers! | ||
193 | _this->hidden->BufferParms.ulNumBuffers = iNumBufs; // Number of buffers | ||
194 | _this->hidden->BufferParms.ulBufferSize = iBufSize; // each with this size | ||
195 | _this->hidden->BufferParms.pBufList = _this->hidden->pMixBuffers; // getting descriptorts into this list | ||
196 | // Allocate buffers! | ||
197 | rc = mciSendCommand(iDeviceOrd, MCI_BUFFER, | ||
198 | MCI_WAIT | MCI_ALLOCATE_MEMORY, | ||
199 | &(_this->hidden->BufferParms), 0); | ||
200 | if ((rc!=MCIERR_SUCCESS) || (iNumBufs != _this->hidden->BufferParms.ulNumBuffers) || (_this->hidden->BufferParms.ulBufferSize==0)) | ||
201 | { // Could not allocate memory! | ||
202 | // Close DART, and exit with error code! | ||
203 | SDL_free(_this->hidden->pMixBuffers); _this->hidden->pMixBuffers = NULL; | ||
204 | mciSendCommand(iDeviceOrd, MCI_CLOSE, MCI_WAIT, &GenericParms, 0); | ||
205 | SDL_SetError("DART could not allocate buffers"); | ||
206 | return(-1); | ||
207 | } | ||
208 | // Ok, we have all the buffers allocated, let's mark them! | ||
209 | { | ||
210 | int i; | ||
211 | for (i=0; i<iNumBufs; i++) | ||
212 | { | ||
213 | pMixBufferDesc pBufferDesc = (pMixBufferDesc) SDL_malloc(sizeof(tMixBufferDesc));; | ||
214 | // Check if this buffer was really allocated by DART | ||
215 | if ((!(_this->hidden->pMixBuffers[i].pBuffer)) || (!pBufferDesc)) | ||
216 | { // Wrong buffer! | ||
217 | // Close DART, and exit with error code! | ||
218 | // Free buffer descriptions | ||
219 | { int j; | ||
220 | for (j=0; j<i; j++) SDL_free((void *)(_this->hidden->pMixBuffers[j].ulUserParm)); | ||
221 | } | ||
222 | // and cleanup | ||
223 | mciSendCommand(iDeviceOrd, MCI_BUFFER, MCI_WAIT | MCI_DEALLOCATE_MEMORY, &(_this->hidden->BufferParms), 0); | ||
224 | SDL_free(_this->hidden->pMixBuffers); _this->hidden->pMixBuffers = NULL; | ||
225 | mciSendCommand(iDeviceOrd, MCI_CLOSE, MCI_WAIT, &GenericParms, 0); | ||
226 | SDL_SetError("Error at internal buffer check"); | ||
227 | return(-1); | ||
228 | } | ||
229 | pBufferDesc->iBufferUsage = BUFFER_EMPTY; | ||
230 | pBufferDesc->pSDLAudioDevice = _this; | ||
231 | |||
232 | _this->hidden->pMixBuffers[i].ulBufferLength = _this->hidden->BufferParms.ulBufferSize; | ||
233 | _this->hidden->pMixBuffers[i].ulUserParm = (ULONG) pBufferDesc; // User parameter: Description of buffer | ||
234 | _this->hidden->pMixBuffers[i].ulFlags = 0; // Some stuff should be flagged here for DART, like end of | ||
235 | // audio data, but as we will continously send | ||
236 | // audio data, there will be no end.:) | ||
237 | SDL_memset(_this->hidden->pMixBuffers[i].pBuffer, iSilence, iBufSize); | ||
238 | } | ||
239 | } | ||
240 | _this->hidden->iNextFreeBuffer = 0; | ||
241 | _this->hidden->iLastPlayedBuf = -1; | ||
242 | // Create event semaphore | ||
243 | if (DosCreateEventSem(NULL, &(_this->hidden->hevAudioBufferPlayed), 0, FALSE)!=NO_ERROR) | ||
244 | { | ||
245 | // Could not create event semaphore! | ||
246 | { | ||
247 | int i; | ||
248 | for (i=0; i<iNumBufs; i++) SDL_free((void *)(_this->hidden->pMixBuffers[i].ulUserParm)); | ||
249 | } | ||
250 | mciSendCommand(iDeviceOrd, MCI_BUFFER, MCI_WAIT | MCI_DEALLOCATE_MEMORY, &(_this->hidden->BufferParms), 0); | ||
251 | SDL_free(_this->hidden->pMixBuffers); _this->hidden->pMixBuffers = NULL; | ||
252 | mciSendCommand(iDeviceOrd, MCI_CLOSE, MCI_WAIT, &GenericParms, 0); | ||
253 | SDL_SetError("Could not create event semaphore"); | ||
254 | return(-1); | ||
255 | } | ||
256 | |||
257 | // Store the new settings in global variables | ||
258 | _this->hidden->iCurrDeviceOrd = iDeviceOrd; | ||
259 | _this->hidden->iCurrFreq = iFreq; | ||
260 | _this->hidden->iCurrBits = iBits; | ||
261 | _this->hidden->iCurrChannels = iChannels; | ||
262 | _this->hidden->iCurrNumBufs = iNumBufs; | ||
263 | _this->hidden->iCurrBufSize = iBufSize; | ||
264 | |||
265 | return (0); | ||
266 | } | ||
267 | |||
268 | |||
269 | |||
270 | void DART_ThreadInit(_THIS) | ||
271 | { | ||
272 | return; | ||
273 | } | ||
274 | |||
275 | /* This function waits until it is possible to write a full sound buffer */ | ||
276 | void DART_WaitAudio(_THIS) | ||
277 | { | ||
278 | int i; | ||
279 | pMixBufferDesc pBufDesc; | ||
280 | ULONG ulPostCount; | ||
281 | |||
282 | DosResetEventSem(_this->hidden->hevAudioBufferPlayed, &ulPostCount); | ||
283 | // If there is already an empty buffer, then return now! | ||
284 | for (i=0; i<_this->hidden->iCurrNumBufs; i++) | ||
285 | { | ||
286 | pBufDesc = (pMixBufferDesc) _this->hidden->pMixBuffers[i].ulUserParm; | ||
287 | if (pBufDesc->iBufferUsage == BUFFER_EMPTY) | ||
288 | return; | ||
289 | } | ||
290 | // If there is no empty buffer, wait for one to be empty! | ||
291 | DosWaitEventSem(_this->hidden->hevAudioBufferPlayed, 1000); // Wait max 1 sec!!! Important! | ||
292 | return; | ||
293 | } | ||
294 | |||
295 | void DART_PlayAudio(_THIS) | ||
296 | { | ||
297 | int iFreeBuf = _this->hidden->iNextFreeBuffer; | ||
298 | pMixBufferDesc pBufDesc; | ||
299 | |||
300 | pBufDesc = (pMixBufferDesc) _this->hidden->pMixBuffers[iFreeBuf].ulUserParm; | ||
301 | pBufDesc->iBufferUsage = BUFFER_USED; | ||
302 | // Send it to DART to be queued | ||
303 | _this->hidden->MixSetupParms.pmixWrite(_this->hidden->MixSetupParms.ulMixHandle, | ||
304 | &(_this->hidden->pMixBuffers[iFreeBuf]), 1); | ||
305 | |||
306 | _this->hidden->iLastPlayedBuf = iFreeBuf; | ||
307 | iFreeBuf = (iFreeBuf+1) % _this->hidden->iCurrNumBufs; | ||
308 | _this->hidden->iNextFreeBuffer = iFreeBuf; | ||
309 | } | ||
310 | |||
311 | Uint8 *DART_GetAudioBuf(_THIS) | ||
312 | { | ||
313 | int iFreeBuf; | ||
314 | Uint8 *pResult; | ||
315 | pMixBufferDesc pBufDesc; | ||
316 | |||
317 | if (_this) | ||
318 | { | ||
319 | if (_this->hidden) | ||
320 | { | ||
321 | iFreeBuf = _this->hidden->iNextFreeBuffer; | ||
322 | pBufDesc = (pMixBufferDesc) _this->hidden->pMixBuffers[iFreeBuf].ulUserParm; | ||
323 | |||
324 | if (pBufDesc) | ||
325 | { | ||
326 | if (pBufDesc->iBufferUsage == BUFFER_EMPTY) | ||
327 | { | ||
328 | pResult = _this->hidden->pMixBuffers[iFreeBuf].pBuffer; | ||
329 | return pResult; | ||
330 | } | ||
331 | } else | ||
332 | printf("[DART_GetAudioBuf] : ERROR! pBufDesc = %p\n", pBufDesc); | ||
333 | } else | ||
334 | printf("[DART_GetAudioBuf] : ERROR! _this->hidden = %p\n", _this->hidden); | ||
335 | } else | ||
336 | printf("[DART_GetAudioBuf] : ERROR! _this = %p\n", _this); | ||
337 | return NULL; | ||
338 | } | ||
339 | |||
340 | void DART_WaitDone(_THIS) | ||
341 | { | ||
342 | pMixBufferDesc pBufDesc; | ||
343 | ULONG ulPostCount; | ||
344 | APIRET rc; | ||
345 | |||
346 | pBufDesc = (pMixBufferDesc) _this->hidden->pMixBuffers[_this->hidden->iLastPlayedBuf].ulUserParm; | ||
347 | rc = NO_ERROR; | ||
348 | while ((pBufDesc->iBufferUsage != BUFFER_EMPTY) && (rc==NO_ERROR)) | ||
349 | { | ||
350 | DosResetEventSem(_this->hidden->hevAudioBufferPlayed, &ulPostCount); | ||
351 | rc = DosWaitEventSem(_this->hidden->hevAudioBufferPlayed, 1000); // 1 sec timeout! Important! | ||
352 | } | ||
353 | } | ||
354 | |||
355 | void DART_CloseAudio(_THIS) | ||
356 | { | ||
357 | MCI_GENERIC_PARMS GenericParms; | ||
358 | int rc; | ||
359 | |||
360 | // Stop DART playback | ||
361 | rc = mciSendCommand(_this->hidden->iCurrDeviceOrd, MCI_STOP, MCI_WAIT, &GenericParms, 0); | ||
362 | if (rc!=MCIERR_SUCCESS) | ||
363 | { | ||
364 | #ifdef SFX_DEBUG_BUILD | ||
365 | printf("Could not stop DART playback!\n"); | ||
366 | fflush(stdout); | ||
367 | #endif | ||
368 | } | ||
369 | |||
370 | // Close event semaphore | ||
371 | DosCloseEventSem(_this->hidden->hevAudioBufferPlayed); | ||
372 | |||
373 | // Free memory of buffer descriptions | ||
374 | { | ||
375 | int i; | ||
376 | for (i=0; i<_this->hidden->iCurrNumBufs; i++) SDL_free((void *)(_this->hidden->pMixBuffers[i].ulUserParm)); | ||
377 | } | ||
378 | |||
379 | // Deallocate buffers | ||
380 | rc = mciSendCommand(_this->hidden->iCurrDeviceOrd, MCI_BUFFER, MCI_WAIT | MCI_DEALLOCATE_MEMORY, &(_this->hidden->BufferParms), 0); | ||
381 | |||
382 | // Free bufferlist | ||
383 | SDL_free(_this->hidden->pMixBuffers); _this->hidden->pMixBuffers = NULL; | ||
384 | |||
385 | // Close dart | ||
386 | rc = mciSendCommand(_this->hidden->iCurrDeviceOrd, MCI_CLOSE, MCI_WAIT, &(GenericParms), 0); | ||
387 | } | ||
388 | |||
389 | /* Audio driver bootstrap functions */ | ||
390 | |||
391 | int Audio_Available(void) | ||
392 | { | ||
393 | return(1); | ||
394 | } | ||
395 | |||
396 | void Audio_DeleteDevice(SDL_AudioDevice *device) | ||
397 | { | ||
398 | SDL_free(device->hidden); | ||
399 | SDL_free(device); | ||
400 | } | ||
401 | |||
402 | SDL_AudioDevice *Audio_CreateDevice(int devindex) | ||
403 | { | ||
404 | SDL_AudioDevice *this; | ||
405 | |||
406 | /* Initialize all variables that we clean on shutdown */ | ||
407 | this = (SDL_AudioDevice *)SDL_malloc(sizeof(SDL_AudioDevice)); | ||
408 | if ( this ) | ||
409 | { | ||
410 | SDL_memset(this, 0, (sizeof *this)); | ||
411 | this->hidden = (struct SDL_PrivateAudioData *) | ||
412 | SDL_malloc((sizeof *this->hidden)); | ||
413 | } | ||
414 | if ( (this == NULL) || (this->hidden == NULL) ) | ||
415 | { | ||
416 | SDL_OutOfMemory(); | ||
417 | if ( this ) | ||
418 | SDL_free(this); | ||
419 | return(0); | ||
420 | } | ||
421 | SDL_memset(this->hidden, 0, (sizeof *this->hidden)); | ||
422 | |||
423 | /* Set the function pointers */ | ||
424 | this->OpenAudio = DART_OpenAudio; | ||
425 | this->ThreadInit = DART_ThreadInit; | ||
426 | this->WaitAudio = DART_WaitAudio; | ||
427 | this->PlayAudio = DART_PlayAudio; | ||
428 | this->GetAudioBuf = DART_GetAudioBuf; | ||
429 | this->WaitDone = DART_WaitDone; | ||
430 | this->CloseAudio = DART_CloseAudio; | ||
431 | |||
432 | this->free = Audio_DeleteDevice; | ||
433 | |||
434 | return this; | ||
435 | } | ||
436 | |||
437 | AudioBootStrap DART_bootstrap = { | ||
438 | "dart", "OS/2 Direct Audio RouTines (DART)", | ||
439 | Audio_Available, Audio_CreateDevice | ||
440 | }; | ||
441 | |||
diff --git a/apps/plugins/sdl/src/audio/dart/SDL_dart.h b/apps/plugins/sdl/src/audio/dart/SDL_dart.h deleted file mode 100644 index 68c27bd9d3..0000000000 --- a/apps/plugins/sdl/src/audio/dart/SDL_dart.h +++ /dev/null | |||
@@ -1,63 +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 Lesser General Public | ||
7 | License as published by the Free Software Foundation; either | ||
8 | version 2.1 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 | Lesser General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU Lesser General Public | ||
16 | License along with this library; if not, write to the Free Software | ||
17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
18 | |||
19 | Sam Lantinga | ||
20 | slouken@libsdl.org | ||
21 | */ | ||
22 | #include "SDL_config.h" | ||
23 | |||
24 | #ifndef _SDL_lowaudio_h | ||
25 | #define _SDL_lowaudio_h | ||
26 | |||
27 | #define INCL_TYPES | ||
28 | #define INCL_DOSSEMAPHORES | ||
29 | #define INCL_DOSRESOURCES | ||
30 | #define INCL_DOSMISC | ||
31 | #define INCL_DOSERRORS | ||
32 | |||
33 | #define INCL_OS2MM | ||
34 | #define INCL_MMIOOS2 | ||
35 | #define INCL_MCIOS2 | ||
36 | #include <os2.h> | ||
37 | #include <os2me.h> // DART stuff and MMIO stuff | ||
38 | |||
39 | #include "../SDL_sysaudio.h" | ||
40 | |||
41 | /* Hidden "this" pointer for the audio functions */ | ||
42 | #define _THIS SDL_AudioDevice *_this | ||
43 | |||
44 | /* The DirectSound objects */ | ||
45 | struct SDL_PrivateAudioData | ||
46 | { | ||
47 | int iCurrDeviceOrd; | ||
48 | int iCurrFreq; | ||
49 | int iCurrBits; | ||
50 | int iCurrChannels; | ||
51 | int iCurrNumBufs; | ||
52 | int iCurrBufSize; | ||
53 | |||
54 | int iLastPlayedBuf; | ||
55 | int iNextFreeBuffer; | ||
56 | |||
57 | MCI_BUFFER_PARMS BufferParms; // Sound buffer parameters | ||
58 | MCI_MIX_BUFFER *pMixBuffers; // Sound buffers | ||
59 | MCI_MIXSETUP_PARMS MixSetupParms; // Mixer setup parameters | ||
60 | HEV hevAudioBufferPlayed; // Event semaphore to indicate that an audio buffer has been played by DART | ||
61 | }; | ||
62 | |||
63 | #endif /* _SDL_lowaudio_h */ | ||
diff --git a/apps/plugins/sdl/src/audio/dc/SDL_dcaudio.c b/apps/plugins/sdl/src/audio/dc/SDL_dcaudio.c deleted file mode 100644 index 88daa8723a..0000000000 --- a/apps/plugins/sdl/src/audio/dc/SDL_dcaudio.c +++ /dev/null | |||
@@ -1,246 +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 Lesser General Public | ||
7 | License as published by the Free Software Foundation; either | ||
8 | version 2.1 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 | Lesser General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU Lesser General Public | ||
16 | License along with this library; if not, write to the Free Software | ||
17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
18 | |||
19 | Sam Lantinga | ||
20 | slouken@libsdl.org | ||
21 | |||
22 | */ | ||
23 | #include "SDL_config.h" | ||
24 | |||
25 | /* Output dreamcast aica */ | ||
26 | |||
27 | #include "SDL_timer.h" | ||
28 | #include "SDL_audio.h" | ||
29 | #include "../SDL_audiomem.h" | ||
30 | #include "../SDL_audio_c.h" | ||
31 | #include "../SDL_audiodev_c.h" | ||
32 | #include "SDL_dcaudio.h" | ||
33 | |||
34 | #include "aica.h" | ||
35 | #include <dc/spu.h> | ||
36 | |||
37 | /* Audio driver functions */ | ||
38 | static int DCAUD_OpenAudio(_THIS, SDL_AudioSpec *spec); | ||
39 | static void DCAUD_WaitAudio(_THIS); | ||
40 | static void DCAUD_PlayAudio(_THIS); | ||
41 | static Uint8 *DCAUD_GetAudioBuf(_THIS); | ||
42 | static void DCAUD_CloseAudio(_THIS); | ||
43 | |||
44 | /* Audio driver bootstrap functions */ | ||
45 | static int DCAUD_Available(void) | ||
46 | { | ||
47 | return 1; | ||
48 | } | ||
49 | |||
50 | static void DCAUD_DeleteDevice(SDL_AudioDevice *device) | ||
51 | { | ||
52 | SDL_free(device->hidden); | ||
53 | SDL_free(device); | ||
54 | } | ||
55 | |||
56 | static SDL_AudioDevice *DCAUD_CreateDevice(int devindex) | ||
57 | { | ||
58 | SDL_AudioDevice *this; | ||
59 | |||
60 | /* Initialize all variables that we clean on shutdown */ | ||
61 | this = (SDL_AudioDevice *)SDL_malloc(sizeof(SDL_AudioDevice)); | ||
62 | if ( this ) { | ||
63 | SDL_memset(this, 0, (sizeof *this)); | ||
64 | this->hidden = (struct SDL_PrivateAudioData *) | ||
65 | SDL_malloc((sizeof *this->hidden)); | ||
66 | } | ||
67 | if ( (this == NULL) || (this->hidden == NULL) ) { | ||
68 | SDL_OutOfMemory(); | ||
69 | if ( this ) { | ||
70 | SDL_free(this); | ||
71 | } | ||
72 | return(0); | ||
73 | } | ||
74 | SDL_memset(this->hidden, 0, (sizeof *this->hidden)); | ||
75 | |||
76 | /* Set the function pointers */ | ||
77 | this->OpenAudio = DCAUD_OpenAudio; | ||
78 | this->WaitAudio = DCAUD_WaitAudio; | ||
79 | this->PlayAudio = DCAUD_PlayAudio; | ||
80 | this->GetAudioBuf = DCAUD_GetAudioBuf; | ||
81 | this->CloseAudio = DCAUD_CloseAudio; | ||
82 | |||
83 | this->free = DCAUD_DeleteDevice; | ||
84 | |||
85 | spu_init(); | ||
86 | |||
87 | return this; | ||
88 | } | ||
89 | |||
90 | AudioBootStrap DCAUD_bootstrap = { | ||
91 | "dcaudio", "Dreamcast AICA audio", | ||
92 | DCAUD_Available, DCAUD_CreateDevice | ||
93 | }; | ||
94 | |||
95 | /* This function waits until it is possible to write a full sound buffer */ | ||
96 | static void DCAUD_WaitAudio(_THIS) | ||
97 | { | ||
98 | if (this->hidden->playing) { | ||
99 | /* wait */ | ||
100 | while(aica_get_pos(0)/this->spec.samples == this->hidden->nextbuf) { | ||
101 | thd_pass(); | ||
102 | } | ||
103 | } | ||
104 | } | ||
105 | |||
106 | #define SPU_RAM_BASE 0xa0800000 | ||
107 | |||
108 | static void spu_memload_stereo8(int leftpos,int rightpos,void *src0,size_t size) | ||
109 | { | ||
110 | uint8 *src = src0; | ||
111 | uint32 *left = (uint32*)(leftpos +SPU_RAM_BASE); | ||
112 | uint32 *right = (uint32*)(rightpos+SPU_RAM_BASE); | ||
113 | size = (size+7)/8; | ||
114 | while(size--) { | ||
115 | unsigned lval,rval; | ||
116 | lval = *src++; | ||
117 | rval = *src++; | ||
118 | lval|= (*src++)<<8; | ||
119 | rval|= (*src++)<<8; | ||
120 | lval|= (*src++)<<16; | ||
121 | rval|= (*src++)<<16; | ||
122 | lval|= (*src++)<<24; | ||
123 | rval|= (*src++)<<24; | ||
124 | g2_write_32(left++,lval); | ||
125 | g2_write_32(right++,rval); | ||
126 | g2_fifo_wait(); | ||
127 | } | ||
128 | } | ||
129 | |||
130 | static void spu_memload_stereo16(int leftpos,int rightpos,void *src0,size_t size) | ||
131 | { | ||
132 | uint16 *src = src0; | ||
133 | uint32 *left = (uint32*)(leftpos +SPU_RAM_BASE); | ||
134 | uint32 *right = (uint32*)(rightpos+SPU_RAM_BASE); | ||
135 | size = (size+7)/8; | ||
136 | while(size--) { | ||
137 | unsigned lval,rval; | ||
138 | lval = *src++; | ||
139 | rval = *src++; | ||
140 | lval|= (*src++)<<16; | ||
141 | rval|= (*src++)<<16; | ||
142 | g2_write_32(left++,lval); | ||
143 | g2_write_32(right++,rval); | ||
144 | g2_fifo_wait(); | ||
145 | } | ||
146 | } | ||
147 | |||
148 | static void DCAUD_PlayAudio(_THIS) | ||
149 | { | ||
150 | SDL_AudioSpec *spec = &this->spec; | ||
151 | unsigned int offset; | ||
152 | |||
153 | if (this->hidden->playing) { | ||
154 | /* wait */ | ||
155 | while(aica_get_pos(0)/spec->samples == this->hidden->nextbuf) { | ||
156 | thd_pass(); | ||
157 | } | ||
158 | } | ||
159 | |||
160 | offset = this->hidden->nextbuf*spec->size; | ||
161 | this->hidden->nextbuf^=1; | ||
162 | /* Write the audio data, checking for EAGAIN on broken audio drivers */ | ||
163 | if (spec->channels==1) { | ||
164 | spu_memload(this->hidden->leftpos+offset,this->hidden->mixbuf,this->hidden->mixlen); | ||
165 | } else { | ||
166 | offset/=2; | ||
167 | if ((this->spec.format&255)==8) { | ||
168 | spu_memload_stereo8(this->hidden->leftpos+offset,this->hidden->rightpos+offset,this->hidden->mixbuf,this->hidden->mixlen); | ||
169 | } else { | ||
170 | spu_memload_stereo16(this->hidden->leftpos+offset,this->hidden->rightpos+offset,this->hidden->mixbuf,this->hidden->mixlen); | ||
171 | } | ||
172 | } | ||
173 | |||
174 | if (!this->hidden->playing) { | ||
175 | int mode; | ||
176 | this->hidden->playing = 1; | ||
177 | mode = (spec->format==AUDIO_S8)?SM_8BIT:SM_16BIT; | ||
178 | if (spec->channels==1) { | ||
179 | aica_play(0,mode,this->hidden->leftpos,0,spec->samples*2,spec->freq,255,128,1); | ||
180 | } else { | ||
181 | aica_play(0,mode,this->hidden->leftpos ,0,spec->samples*2,spec->freq,255,0,1); | ||
182 | aica_play(1,mode,this->hidden->rightpos,0,spec->samples*2,spec->freq,255,255,1); | ||
183 | } | ||
184 | } | ||
185 | } | ||
186 | |||
187 | static Uint8 *DCAUD_GetAudioBuf(_THIS) | ||
188 | { | ||
189 | return(this->hidden->mixbuf); | ||
190 | } | ||
191 | |||
192 | static void DCAUD_CloseAudio(_THIS) | ||
193 | { | ||
194 | aica_stop(0); | ||
195 | if (this->spec.channels==2) aica_stop(1); | ||
196 | if ( this->hidden->mixbuf != NULL ) { | ||
197 | SDL_FreeAudioMem(this->hidden->mixbuf); | ||
198 | this->hidden->mixbuf = NULL; | ||
199 | } | ||
200 | } | ||
201 | |||
202 | static int DCAUD_OpenAudio(_THIS, SDL_AudioSpec *spec) | ||
203 | { | ||
204 | Uint16 test_format = SDL_FirstAudioFormat(spec->format); | ||
205 | int valid_datatype = 0; | ||
206 | while ((!valid_datatype) && (test_format)) { | ||
207 | spec->format = test_format; | ||
208 | switch (test_format) { | ||
209 | /* only formats Dreamcast accepts... */ | ||
210 | case AUDIO_S8: | ||
211 | case AUDIO_S16LSB: | ||
212 | valid_datatype = 1; | ||
213 | break; | ||
214 | |||
215 | default: | ||
216 | test_format = SDL_NextAudioFormat(); | ||
217 | break; | ||
218 | } | ||
219 | } | ||
220 | |||
221 | if (!valid_datatype) { /* shouldn't happen, but just in case... */ | ||
222 | SDL_SetError("Unsupported audio format"); | ||
223 | return (-1); | ||
224 | } | ||
225 | |||
226 | if (spec->channels > 2) | ||
227 | spec->channels = 2; /* no more than stereo on the Dreamcast. */ | ||
228 | |||
229 | /* Update the fragment size as size in bytes */ | ||
230 | SDL_CalculateAudioSpec(spec); | ||
231 | |||
232 | /* Allocate mixing buffer */ | ||
233 | this->hidden->mixlen = spec->size; | ||
234 | this->hidden->mixbuf = (Uint8 *) SDL_AllocAudioMem(this->hidden->mixlen); | ||
235 | if ( this->hidden->mixbuf == NULL ) { | ||
236 | return(-1); | ||
237 | } | ||
238 | SDL_memset(this->hidden->mixbuf, spec->silence, spec->size); | ||
239 | this->hidden->leftpos = 0x11000; | ||
240 | this->hidden->rightpos = 0x11000+spec->size; | ||
241 | this->hidden->playing = 0; | ||
242 | this->hidden->nextbuf = 0; | ||
243 | |||
244 | /* We're ready to rock and roll. :-) */ | ||
245 | return(0); | ||
246 | } | ||
diff --git a/apps/plugins/sdl/src/audio/dc/SDL_dcaudio.h b/apps/plugins/sdl/src/audio/dc/SDL_dcaudio.h deleted file mode 100644 index fba95b3eda..0000000000 --- a/apps/plugins/sdl/src/audio/dc/SDL_dcaudio.h +++ /dev/null | |||
@@ -1,41 +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 Lesser General Public | ||
7 | License as published by the Free Software Foundation; either | ||
8 | version 2.1 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 | Lesser General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU Lesser General Public | ||
16 | License along with this library; if not, write to the Free Software | ||
17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
18 | |||
19 | Sam Lantinga | ||
20 | slouken@libsdl.org | ||
21 | */ | ||
22 | #include "SDL_config.h" | ||
23 | |||
24 | #ifndef _SDL_dcaudio_h | ||
25 | #define _SDL_dcaudio_h | ||
26 | |||
27 | #include "../SDL_sysaudio.h" | ||
28 | |||
29 | /* Hidden "this" pointer for the video functions */ | ||
30 | #define _THIS SDL_AudioDevice *this | ||
31 | |||
32 | struct SDL_PrivateAudioData { | ||
33 | /* The file descriptor for the audio device */ | ||
34 | Uint8 *mixbuf; | ||
35 | Uint32 mixlen; | ||
36 | int playing; | ||
37 | int leftpos,rightpos; | ||
38 | int nextbuf; | ||
39 | }; | ||
40 | |||
41 | #endif /* _SDL_dcaudio_h */ | ||
diff --git a/apps/plugins/sdl/src/audio/dc/aica.c b/apps/plugins/sdl/src/audio/dc/aica.c deleted file mode 100644 index b6a1c93644..0000000000 --- a/apps/plugins/sdl/src/audio/dc/aica.c +++ /dev/null | |||
@@ -1,271 +0,0 @@ | |||
1 | /* This file is part of the Dreamcast function library. | ||
2 | * Please see libdream.c for further details. | ||
3 | * | ||
4 | * (c)2000 Dan Potter | ||
5 | * modify BERO | ||
6 | */ | ||
7 | #include "aica.h" | ||
8 | |||
9 | #include <arch/irq.h> | ||
10 | #include <dc/spu.h> | ||
11 | |||
12 | /* #define dc_snd_base ((volatile unsigned char *)0x00800000) */ /* arm side */ | ||
13 | #define dc_snd_base ((volatile unsigned char *)0xa0700000) /* dc side */ | ||
14 | |||
15 | /* Some convienence macros */ | ||
16 | #define SNDREGADDR(x) (0xa0700000 + (x)) | ||
17 | #define CHNREGADDR(ch,x) SNDREGADDR(0x80*(ch)+(x)) | ||
18 | |||
19 | |||
20 | #define SNDREG32(x) (*(volatile unsigned long *)SNDREGADDR(x)) | ||
21 | #define SNDREG8(x) (*(volatile unsigned char *)SNDREGADDR(x)) | ||
22 | #define CHNREG32(ch, x) (*(volatile unsigned long *)CHNREGADDR(ch,x)) | ||
23 | #define CHNREG8(ch, x) (*(volatile unsigned long *)CHNREGADDR(ch,x)) | ||
24 | |||
25 | #define G2_LOCK(OLD) \ | ||
26 | do { \ | ||
27 | if (!irq_inside_int()) \ | ||
28 | OLD = irq_disable(); \ | ||
29 | /* suspend any G2 DMA here... */ \ | ||
30 | while((*(volatile unsigned int *)0xa05f688c) & 0x20) \ | ||
31 | ; \ | ||
32 | } while(0) | ||
33 | |||
34 | #define G2_UNLOCK(OLD) \ | ||
35 | do { \ | ||
36 | /* resume any G2 DMA here... */ \ | ||
37 | if (!irq_inside_int()) \ | ||
38 | irq_restore(OLD); \ | ||
39 | } while(0) | ||
40 | |||
41 | |||
42 | void aica_init() { | ||
43 | int i, j, old = 0; | ||
44 | |||
45 | /* Initialize AICA channels */ | ||
46 | G2_LOCK(old); | ||
47 | SNDREG32(0x2800) = 0x0000; | ||
48 | |||
49 | for (i=0; i<64; i++) { | ||
50 | for (j=0; j<0x80; j+=4) { | ||
51 | if ((j&31)==0) g2_fifo_wait(); | ||
52 | CHNREG32(i, j) = 0; | ||
53 | } | ||
54 | g2_fifo_wait(); | ||
55 | CHNREG32(i,0) = 0x8000; | ||
56 | CHNREG32(i,20) = 0x1f; | ||
57 | } | ||
58 | |||
59 | SNDREG32(0x2800) = 0x000f; | ||
60 | g2_fifo_wait(); | ||
61 | G2_UNLOCK(old); | ||
62 | } | ||
63 | |||
64 | /* Translates a volume from linear form to logarithmic form (required by | ||
65 | the AICA chip */ | ||
66 | /* int logs[] = { | ||
67 | |||
68 | 0, 40, 50, 58, 63, 68, 73, 77, 80, 83, 86, 89, 92, 94, 97, 99, 101, 103, | ||
69 | 105, 107, 109, 111, 112, 114, 116, 117, 119, 120, 122, 123, 125, 126, 127, | ||
70 | 129, 130, 131, 133, 134, 135, 136, 137, 139, 140, 141, 142, 143, 144, 145, | ||
71 | 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 156, 157, 158, 159, | ||
72 | 160, 161, 162, 162, 163, 164, 165, 166, 166, 167, 168, 169, 170, 170, 171, | ||
73 | 172, 172, 173, 174, 175, 175, 176, 177, 177, 178, 179, 180, 180, 181, 182, | ||
74 | 182, 183, 183, 184, 185, 185, 186, 187, 187, 188, 188, 189, 190, 190, 191, | ||
75 | 191, 192, 193, 193, 194, 194, 195, 196, 196, 197, 197, 198, 198, 199, 199, | ||
76 | 200, 201, 201, 202, 202, 203, 203, 204, 204, 205, 205, 206, 206, 207, 207, | ||
77 | 208, 208, 209, 209, 210, 210, 211, 211, 212, 212, 213, 213, 214, 214, 215, | ||
78 | 215, 216, 216, 217, 217, 217, 218, 218, 219, 219, 220, 220, 221, 221, 222, | ||
79 | 222, 222, 223, 223, 224, 224, 225, 225, 225, 226, 226, 227, 227, 228, 228, | ||
80 | 228, 229, 229, 230, 230, 230, 231, 231, 232, 232, 232, 233, 233, 234, 234, | ||
81 | 234, 235, 235, 236, 236, 236, 237, 237, 238, 238, 238, 239, 239, 240, 240, | ||
82 | 240, 241, 241, 241, 242, 242, 243, 243, 243, 244, 244, 244, 245, 245, 245, | ||
83 | 246, 246, 247, 247, 247, 248, 248, 248, 249, 249, 249, 250, 250, 250, 251, | ||
84 | 251, 251, 252, 252, 252, 253, 253, 253, 254, 254, 254, 255 | ||
85 | |||
86 | }; */ | ||
87 | |||
88 | const static unsigned char logs[] = { | ||
89 | 0, 15, 22, 27, 31, 35, 39, 42, 45, 47, 50, 52, 55, 57, 59, 61, | ||
90 | 63, 65, 67, 69, 71, 73, 74, 76, 78, 79, 81, 82, 84, 85, 87, 88, | ||
91 | 90, 91, 92, 94, 95, 96, 98, 99, 100, 102, 103, 104, 105, 106, | ||
92 | 108, 109, 110, 111, 112, 113, 114, 116, 117, 118, 119, 120, 121, | ||
93 | 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, | ||
94 | 135, 136, 137, 138, 138, 139, 140, 141, 142, 143, 144, 145, 146, | ||
95 | 146, 147, 148, 149, 150, 151, 152, 152, 153, 154, 155, 156, 156, | ||
96 | 157, 158, 159, 160, 160, 161, 162, 163, 164, 164, 165, 166, 167, | ||
97 | 167, 168, 169, 170, 170, 171, 172, 173, 173, 174, 175, 176, 176, | ||
98 | 177, 178, 178, 179, 180, 181, 181, 182, 183, 183, 184, 185, 185, | ||
99 | 186, 187, 187, 188, 189, 189, 190, 191, 191, 192, 193, 193, 194, | ||
100 | 195, 195, 196, 197, 197, 198, 199, 199, 200, 200, 201, 202, 202, | ||
101 | 203, 204, 204, 205, 205, 206, 207, 207, 208, 209, 209, 210, 210, | ||
102 | 211, 212, 212, 213, 213, 214, 215, 215, 216, 216, 217, 217, 218, | ||
103 | 219, 219, 220, 220, 221, 221, 222, 223, 223, 224, 224, 225, 225, | ||
104 | 226, 227, 227, 228, 228, 229, 229, 230, 230, 231, 232, 232, 233, | ||
105 | 233, 234, 234, 235, 235, 236, 236, 237, 237, 238, 239, 239, 240, | ||
106 | 240, 241, 241, 242, 242, 243, 243, 244, 244, 245, 245, 246, 246, | ||
107 | 247, 247, 248, 248, 249, 249, 250, 250, 251, 251, 252, 252, 253, 254, 255 | ||
108 | }; | ||
109 | |||
110 | /* For the moment this is going to have to suffice, until we really | ||
111 | figure out what these mean. */ | ||
112 | #define AICA_PAN(x) ((x)==0x80?(0):((x)<0x80?(0x1f):(0x0f))) | ||
113 | #define AICA_VOL(x) (0xff - logs[128 + (((x) & 0xff) / 2)]) | ||
114 | //#define AICA_VOL(x) (0xff - logs[x&255]) | ||
115 | |||
116 | static inline unsigned AICA_FREQ(unsigned freq) { | ||
117 | unsigned long freq_lo, freq_base = 5644800; | ||
118 | int freq_hi = 7; | ||
119 | |||
120 | /* Need to convert frequency to floating point format | ||
121 | (freq_hi is exponent, freq_lo is mantissa) | ||
122 | Formula is ferq = 44100*2^freq_hi*(1+freq_lo/1024) */ | ||
123 | while (freq < freq_base && freq_hi > -8) { | ||
124 | freq_base >>= 1; | ||
125 | --freq_hi; | ||
126 | } | ||
127 | while (freq < freq_base && freq_hi > -8) { | ||
128 | freq_base >>= 1; | ||
129 | freq_hi--; | ||
130 | } | ||
131 | freq_lo = (freq<<10) / freq_base; | ||
132 | return (freq_hi << 11) | (freq_lo & 1023); | ||
133 | } | ||
134 | |||
135 | /* Sets up a sound channel completely. This is generally good if you want | ||
136 | a quick and dirty way to play notes. If you want a more comprehensive | ||
137 | set of routines (more like PC wavetable cards) see below. | ||
138 | |||
139 | ch is the channel to play on (0 - 63) | ||
140 | smpptr is the pointer to the sound data; if you're running off the | ||
141 | SH4, then this ought to be (ptr - 0xa0800000); otherwise it's just | ||
142 | ptr. Basically, it's an offset into sound ram. | ||
143 | mode is one of the mode constants (16 bit, 8 bit, ADPCM) | ||
144 | nsamp is the number of samples to play (not number of bytes!) | ||
145 | freq is the sampling rate of the sound | ||
146 | vol is the volume, 0 to 0xff (0xff is louder) | ||
147 | pan is a panning constant -- 0 is left, 128 is center, 255 is right. | ||
148 | |||
149 | This routine (and the similar ones) owe a lot to Marcus' sound example -- | ||
150 | I hadn't gotten quite this far into dissecting the individual regs yet. */ | ||
151 | void aica_play(int ch,int mode,unsigned long smpptr,int loopst,int loopend,int freq,int vol,int pan,int loopflag) { | ||
152 | /* int i; | ||
153 | */ | ||
154 | int val; | ||
155 | int old = 0; | ||
156 | |||
157 | /* Stop the channel (if it's already playing) */ | ||
158 | aica_stop(ch); | ||
159 | /* doesn't seem to be needed, but it's here just in case */ | ||
160 | /* | ||
161 | for (i=0; i<256; i++) { | ||
162 | asm("nop"); | ||
163 | asm("nop"); | ||
164 | asm("nop"); | ||
165 | asm("nop"); | ||
166 | } | ||
167 | */ | ||
168 | G2_LOCK(old); | ||
169 | /* Envelope setup. The first of these is the loop point, | ||
170 | e.g., where the sample starts over when it loops. The second | ||
171 | is the loop end. This is the full length of the sample when | ||
172 | you are not looping, or the loop end point when you are (though | ||
173 | storing more than that is a waste of memory if you're not doing | ||
174 | volume enveloping). */ | ||
175 | CHNREG32(ch, 8) = loopst & 0xffff; | ||
176 | CHNREG32(ch, 12) = loopend & 0xffff; | ||
177 | |||
178 | /* Write resulting values */ | ||
179 | CHNREG32(ch, 24) = AICA_FREQ(freq); | ||
180 | |||
181 | /* Set volume, pan, and some other things that we don't know what | ||
182 | they do =) */ | ||
183 | CHNREG32(ch, 36) = AICA_PAN(pan) | (0xf<<8); | ||
184 | /* Convert the incoming volume and pan into hardware values */ | ||
185 | /* Vol starts at zero so we can ramp */ | ||
186 | vol = AICA_VOL(vol); | ||
187 | CHNREG32(ch, 40) = 0x24 | (vol<<8); | ||
188 | /* Convert the incoming volume and pan into hardware values */ | ||
189 | /* Vol starts at zero so we can ramp */ | ||
190 | |||
191 | /* If we supported volume envelopes (which we don't yet) then | ||
192 | this value would set that up. The top 4 bits determine the | ||
193 | envelope speed. f is the fastest, 1 is the slowest, and 0 | ||
194 | seems to be an invalid value and does weird things). The | ||
195 | default (below) sets it into normal mode (play and terminate/loop). | ||
196 | CHNREG32(ch, 16) = 0xf010; | ||
197 | */ | ||
198 | CHNREG32(ch, 16) = 0x1f; /* No volume envelope */ | ||
199 | |||
200 | |||
201 | /* Set sample format, buffer address, and looping control. If | ||
202 | 0x0200 mask is set on reg 0, the sample loops infinitely. If | ||
203 | it's not set, the sample plays once and terminates. We'll | ||
204 | also set the bits to start playback here. */ | ||
205 | CHNREG32(ch, 4) = smpptr & 0xffff; | ||
206 | val = 0xc000 | 0x0000 | (mode<<7) | (smpptr >> 16); | ||
207 | if (loopflag) val|=0x200; | ||
208 | |||
209 | CHNREG32(ch, 0) = val; | ||
210 | |||
211 | G2_UNLOCK(old); | ||
212 | |||
213 | /* Enable playback */ | ||
214 | /* CHNREG32(ch, 0) |= 0xc000; */ | ||
215 | g2_fifo_wait(); | ||
216 | |||
217 | #if 0 | ||
218 | for (i=0xff; i>=vol; i--) { | ||
219 | if ((i&7)==0) g2_fifo_wait(); | ||
220 | CHNREG32(ch, 40) = 0x24 | (i<<8);; | ||
221 | } | ||
222 | |||
223 | g2_fifo_wait(); | ||
224 | #endif | ||
225 | } | ||
226 | |||
227 | /* Stop the sound on a given channel */ | ||
228 | void aica_stop(int ch) { | ||
229 | g2_write_32(CHNREGADDR(ch, 0),(g2_read_32(CHNREGADDR(ch, 0)) & ~0x4000) | 0x8000); | ||
230 | g2_fifo_wait(); | ||
231 | } | ||
232 | |||
233 | |||
234 | /* The rest of these routines can change the channel in mid-stride so you | ||
235 | can do things like vibrato and panning effects. */ | ||
236 | |||
237 | /* Set channel volume */ | ||
238 | void aica_vol(int ch,int vol) { | ||
239 | // g2_write_8(CHNREGADDR(ch, 41),AICA_VOL(vol)); | ||
240 | g2_write_32(CHNREGADDR(ch, 40),(g2_read_32(CHNREGADDR(ch, 40))&0xffff00ff)|(AICA_VOL(vol)<<8) ); | ||
241 | g2_fifo_wait(); | ||
242 | } | ||
243 | |||
244 | /* Set channel pan */ | ||
245 | void aica_pan(int ch,int pan) { | ||
246 | // g2_write_8(CHNREGADDR(ch, 36),AICA_PAN(pan)); | ||
247 | g2_write_32(CHNREGADDR(ch, 36),(g2_read_32(CHNREGADDR(ch, 36))&0xffffff00)|(AICA_PAN(pan)) ); | ||
248 | g2_fifo_wait(); | ||
249 | } | ||
250 | |||
251 | /* Set channel frequency */ | ||
252 | void aica_freq(int ch,int freq) { | ||
253 | g2_write_32(CHNREGADDR(ch, 24),AICA_FREQ(freq)); | ||
254 | g2_fifo_wait(); | ||
255 | } | ||
256 | |||
257 | /* Get channel position */ | ||
258 | int aica_get_pos(int ch) { | ||
259 | #if 1 | ||
260 | /* Observe channel ch */ | ||
261 | g2_write_32(SNDREGADDR(0x280c),(g2_read_32(SNDREGADDR(0x280c))&0xffff00ff) | (ch<<8)); | ||
262 | g2_fifo_wait(); | ||
263 | /* Update position counters */ | ||
264 | return g2_read_32(SNDREGADDR(0x2814)) & 0xffff; | ||
265 | #else | ||
266 | /* Observe channel ch */ | ||
267 | g2_write_8(SNDREGADDR(0x280d),ch); | ||
268 | /* Update position counters */ | ||
269 | return g2_read_32(SNDREGADDR(0x2814)) & 0xffff; | ||
270 | #endif | ||
271 | } | ||
diff --git a/apps/plugins/sdl/src/audio/dc/aica.h b/apps/plugins/sdl/src/audio/dc/aica.h deleted file mode 100644 index 2721e42821..0000000000 --- a/apps/plugins/sdl/src/audio/dc/aica.h +++ /dev/null | |||
@@ -1,40 +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 Lesser General Public | ||
7 | License as published by the Free Software Foundation; either | ||
8 | version 2.1 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 | Lesser General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU Lesser General Public | ||
16 | License along with this library; if not, write to the Free Software | ||
17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
18 | |||
19 | Sam Lantinga | ||
20 | slouken@libsdl.org | ||
21 | */ | ||
22 | #include "SDL_config.h" | ||
23 | |||
24 | #ifndef _AICA_H_ | ||
25 | #define _AICA_H_ | ||
26 | |||
27 | #define AICA_MEM 0xa0800000 | ||
28 | |||
29 | #define SM_8BIT 1 | ||
30 | #define SM_16BIT 0 | ||
31 | #define SM_ADPCM 2 | ||
32 | |||
33 | void aica_play(int ch,int mode,unsigned long smpptr,int looptst,int loopend,int freq,int vol,int pan,int loopflag); | ||
34 | void aica_stop(int ch); | ||
35 | void aica_vol(int ch,int vol); | ||
36 | void aica_pan(int ch,int pan); | ||
37 | void aica_freq(int ch,int freq); | ||
38 | int aica_get_pos(int ch); | ||
39 | |||
40 | #endif | ||
diff --git a/apps/plugins/sdl/src/audio/disk/SDL_diskaudio.c b/apps/plugins/sdl/src/audio/disk/SDL_diskaudio.c deleted file mode 100644 index c45d3f8c05..0000000000 --- a/apps/plugins/sdl/src/audio/disk/SDL_diskaudio.c +++ /dev/null | |||
@@ -1,186 +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 Lesser General Public | ||
7 | License as published by the Free Software Foundation; either | ||
8 | version 2.1 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 | Lesser General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU Lesser General Public | ||
16 | License along with this library; if not, write to the Free Software | ||
17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
18 | |||
19 | Sam Lantinga | ||
20 | slouken@libsdl.org | ||
21 | |||
22 | This file written by Ryan C. Gordon (icculus@icculus.org) | ||
23 | */ | ||
24 | #include "SDL_config.h" | ||
25 | |||
26 | /* Output raw audio data to a file. */ | ||
27 | |||
28 | #if HAVE_STDIO_H | ||
29 | #include <stdio.h> | ||
30 | #endif | ||
31 | |||
32 | #include "SDL_rwops.h" | ||
33 | #include "SDL_timer.h" | ||
34 | #include "SDL_audio.h" | ||
35 | #include "../SDL_audiomem.h" | ||
36 | #include "../SDL_audio_c.h" | ||
37 | #include "../SDL_audiodev_c.h" | ||
38 | #include "SDL_diskaudio.h" | ||
39 | |||
40 | /* The tag name used by DISK audio */ | ||
41 | #define DISKAUD_DRIVER_NAME "disk" | ||
42 | |||
43 | /* environment variables and defaults. */ | ||
44 | #define DISKENVR_OUTFILE "SDL_DISKAUDIOFILE" | ||
45 | #define DISKDEFAULT_OUTFILE "/sdlaudio.raw" | ||
46 | #define DISKENVR_WRITEDELAY "SDL_DISKAUDIODELAY" | ||
47 | #define DISKDEFAULT_WRITEDELAY 150 | ||
48 | |||
49 | /* Audio driver functions */ | ||
50 | static int DISKAUD_OpenAudio(_THIS, SDL_AudioSpec *spec); | ||
51 | static void DISKAUD_WaitAudio(_THIS); | ||
52 | static void DISKAUD_PlayAudio(_THIS); | ||
53 | static Uint8 *DISKAUD_GetAudioBuf(_THIS); | ||
54 | static void DISKAUD_CloseAudio(_THIS); | ||
55 | |||
56 | static const char *DISKAUD_GetOutputFilename(void) | ||
57 | { | ||
58 | const char *envr = SDL_getenv(DISKENVR_OUTFILE); | ||
59 | return((envr != NULL) ? envr : DISKDEFAULT_OUTFILE); | ||
60 | } | ||
61 | |||
62 | /* Audio driver bootstrap functions */ | ||
63 | static int DISKAUD_Available(void) | ||
64 | { | ||
65 | //const char *envr = SDL_getenv("SDL_AUDIODRIVER"); | ||
66 | // if (envr && (SDL_strcmp(envr, DISKAUD_DRIVER_NAME) == 0)) { | ||
67 | return(1); | ||
68 | // } | ||
69 | // return(0); | ||
70 | } | ||
71 | |||
72 | static void DISKAUD_DeleteDevice(SDL_AudioDevice *device) | ||
73 | { | ||
74 | SDL_free(device->hidden); | ||
75 | SDL_free(device); | ||
76 | } | ||
77 | |||
78 | static SDL_AudioDevice *DISKAUD_CreateDevice(int devindex) | ||
79 | { | ||
80 | SDL_AudioDevice *this; | ||
81 | const char *envr; | ||
82 | |||
83 | /* Initialize all variables that we clean on shutdown */ | ||
84 | this = (SDL_AudioDevice *)SDL_malloc(sizeof(SDL_AudioDevice)); | ||
85 | if ( this ) { | ||
86 | SDL_memset(this, 0, (sizeof *this)); | ||
87 | this->hidden = (struct SDL_PrivateAudioData *) | ||
88 | SDL_malloc((sizeof *this->hidden)); | ||
89 | } | ||
90 | if ( (this == NULL) || (this->hidden == NULL) ) { | ||
91 | SDL_OutOfMemory(); | ||
92 | if ( this ) { | ||
93 | SDL_free(this); | ||
94 | } | ||
95 | return(0); | ||
96 | } | ||
97 | SDL_memset(this->hidden, 0, (sizeof *this->hidden)); | ||
98 | |||
99 | envr = SDL_getenv(DISKENVR_WRITEDELAY); | ||
100 | this->hidden->write_delay = (envr) ? SDL_atoi(envr) : DISKDEFAULT_WRITEDELAY; | ||
101 | |||
102 | /* Set the function pointers */ | ||
103 | this->OpenAudio = DISKAUD_OpenAudio; | ||
104 | this->WaitAudio = DISKAUD_WaitAudio; | ||
105 | this->PlayAudio = DISKAUD_PlayAudio; | ||
106 | this->GetAudioBuf = DISKAUD_GetAudioBuf; | ||
107 | this->CloseAudio = DISKAUD_CloseAudio; | ||
108 | |||
109 | this->free = DISKAUD_DeleteDevice; | ||
110 | |||
111 | return this; | ||
112 | } | ||
113 | |||
114 | AudioBootStrap DISKAUD_bootstrap = { | ||
115 | DISKAUD_DRIVER_NAME, "direct-to-disk audio", | ||
116 | DISKAUD_Available, DISKAUD_CreateDevice | ||
117 | }; | ||
118 | |||
119 | /* This function waits until it is possible to write a full sound buffer */ | ||
120 | static void DISKAUD_WaitAudio(_THIS) | ||
121 | { | ||
122 | SDL_Delay(this->hidden->write_delay); | ||
123 | } | ||
124 | |||
125 | static void DISKAUD_PlayAudio(_THIS) | ||
126 | { | ||
127 | int written; | ||
128 | |||
129 | /* Write the audio data */ | ||
130 | written = SDL_RWwrite(this->hidden->output, | ||
131 | this->hidden->mixbuf, 1, | ||
132 | this->hidden->mixlen); | ||
133 | |||
134 | /* If we couldn't write, assume fatal error for now */ | ||
135 | if ( (Uint32)written != this->hidden->mixlen ) { | ||
136 | this->enabled = 0; | ||
137 | } | ||
138 | #ifdef DEBUG_AUDIO | ||
139 | fprintf(stderr, "Wrote %d bytes of audio data\n", written); | ||
140 | #endif | ||
141 | } | ||
142 | |||
143 | static Uint8 *DISKAUD_GetAudioBuf(_THIS) | ||
144 | { | ||
145 | return(this->hidden->mixbuf); | ||
146 | } | ||
147 | |||
148 | static void DISKAUD_CloseAudio(_THIS) | ||
149 | { | ||
150 | if ( this->hidden->mixbuf != NULL ) { | ||
151 | SDL_FreeAudioMem(this->hidden->mixbuf); | ||
152 | this->hidden->mixbuf = NULL; | ||
153 | } | ||
154 | if ( this->hidden->output != NULL ) { | ||
155 | SDL_RWclose(this->hidden->output); | ||
156 | this->hidden->output = NULL; | ||
157 | } | ||
158 | } | ||
159 | |||
160 | static int DISKAUD_OpenAudio(_THIS, SDL_AudioSpec *spec) | ||
161 | { | ||
162 | const char *fname = DISKAUD_GetOutputFilename(); | ||
163 | |||
164 | /* Open the audio device */ | ||
165 | this->hidden->output = SDL_RWFromFile(fname, "wb"); | ||
166 | if ( this->hidden->output == NULL ) { | ||
167 | return(-1); | ||
168 | } | ||
169 | |||
170 | #if HAVE_STDIO_H | ||
171 | fprintf(stderr, "WARNING: You are using the SDL disk writer" | ||
172 | " audio driver!\n Writing to file [%s].\n", fname); | ||
173 | #endif | ||
174 | |||
175 | /* Allocate mixing buffer */ | ||
176 | this->hidden->mixlen = spec->size; | ||
177 | this->hidden->mixbuf = (Uint8 *) SDL_AllocAudioMem(this->hidden->mixlen); | ||
178 | if ( this->hidden->mixbuf == NULL ) { | ||
179 | return(-1); | ||
180 | } | ||
181 | SDL_memset(this->hidden->mixbuf, spec->silence, spec->size); | ||
182 | |||
183 | /* We're ready to rock and roll. :-) */ | ||
184 | return(0); | ||
185 | } | ||
186 | |||
diff --git a/apps/plugins/sdl/src/audio/disk/SDL_diskaudio.h b/apps/plugins/sdl/src/audio/disk/SDL_diskaudio.h deleted file mode 100644 index 24d7c9e34d..0000000000 --- a/apps/plugins/sdl/src/audio/disk/SDL_diskaudio.h +++ /dev/null | |||
@@ -1,41 +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 Lesser General Public | ||
7 | License as published by the Free Software Foundation; either | ||
8 | version 2.1 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 | Lesser General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU Lesser General Public | ||
16 | License along with this library; if not, write to the Free Software | ||
17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
18 | |||
19 | Sam Lantinga | ||
20 | slouken@libsdl.org | ||
21 | */ | ||
22 | #include "SDL_config.h" | ||
23 | |||
24 | #ifndef _SDL_diskaudio_h | ||
25 | #define _SDL_diskaudio_h | ||
26 | |||
27 | #include "SDL_rwops.h" | ||
28 | #include "../SDL_sysaudio.h" | ||
29 | |||
30 | /* Hidden "this" pointer for the video functions */ | ||
31 | #define _THIS SDL_AudioDevice *this | ||
32 | |||
33 | struct SDL_PrivateAudioData { | ||
34 | /* The file descriptor for the audio device */ | ||
35 | SDL_RWops *output; | ||
36 | Uint8 *mixbuf; | ||
37 | Uint32 mixlen; | ||
38 | Uint32 write_delay; | ||
39 | }; | ||
40 | |||
41 | #endif /* _SDL_diskaudio_h */ | ||
diff --git a/apps/plugins/sdl/src/audio/dma/SDL_dmaaudio.c b/apps/plugins/sdl/src/audio/dma/SDL_dmaaudio.c deleted file mode 100644 index 39f81d90ce..0000000000 --- a/apps/plugins/sdl/src/audio/dma/SDL_dmaaudio.c +++ /dev/null | |||
@@ -1,455 +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 Lesser General Public | ||
7 | License as published by the Free Software Foundation; either | ||
8 | version 2.1 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 | Lesser General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU Lesser General Public | ||
16 | License along with this library; if not, write to the Free Software | ||
17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 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 <stdio.h> | ||
27 | #include <string.h> /* For strerror() */ | ||
28 | #include <errno.h> | ||
29 | #include <unistd.h> | ||
30 | #include <fcntl.h> | ||
31 | #include <signal.h> | ||
32 | #include <sys/types.h> | ||
33 | #include <sys/time.h> | ||
34 | #include <sys/ioctl.h> | ||
35 | #include <sys/stat.h> | ||
36 | #include <sys/mman.h> | ||
37 | |||
38 | #if SDL_AUDIO_DRIVER_OSS_SOUNDCARD_H | ||
39 | /* This is installed on some systems */ | ||
40 | #include <soundcard.h> | ||
41 | #else | ||
42 | /* This is recommended by OSS */ | ||
43 | #include <sys/soundcard.h> | ||
44 | #endif | ||
45 | |||
46 | #ifndef MAP_FAILED | ||
47 | #define MAP_FAILED ((Uint8 *)-1) | ||
48 | #endif | ||
49 | |||
50 | #include "SDL_timer.h" | ||
51 | #include "SDL_audio.h" | ||
52 | #include "../SDL_audio_c.h" | ||
53 | #include "../SDL_audiodev_c.h" | ||
54 | #include "SDL_dmaaudio.h" | ||
55 | |||
56 | /* The tag name used by DMA audio */ | ||
57 | #define DMA_DRIVER_NAME "dma" | ||
58 | |||
59 | /* Open the audio device for playback, and don't block if busy */ | ||
60 | #define OPEN_FLAGS (O_RDWR|O_NONBLOCK) | ||
61 | |||
62 | /* Audio driver functions */ | ||
63 | static int DMA_OpenAudio(_THIS, SDL_AudioSpec *spec); | ||
64 | static void DMA_WaitAudio(_THIS); | ||
65 | static void DMA_PlayAudio(_THIS); | ||
66 | static Uint8 *DMA_GetAudioBuf(_THIS); | ||
67 | static void DMA_CloseAudio(_THIS); | ||
68 | |||
69 | /* Audio driver bootstrap functions */ | ||
70 | |||
71 | static int Audio_Available(void) | ||
72 | { | ||
73 | int available; | ||
74 | int fd; | ||
75 | |||
76 | available = 0; | ||
77 | |||
78 | fd = SDL_OpenAudioPath(NULL, 0, OPEN_FLAGS, 0); | ||
79 | if ( fd >= 0 ) { | ||
80 | int caps; | ||
81 | struct audio_buf_info info; | ||
82 | |||
83 | if ( (ioctl(fd, SNDCTL_DSP_GETCAPS, &caps) == 0) && | ||
84 | (caps & DSP_CAP_TRIGGER) && (caps & DSP_CAP_MMAP) && | ||
85 | (ioctl(fd, SNDCTL_DSP_GETOSPACE, &info) == 0) ) { | ||
86 | available = 1; | ||
87 | } | ||
88 | close(fd); | ||
89 | } | ||
90 | return(available); | ||
91 | } | ||
92 | |||
93 | static void Audio_DeleteDevice(SDL_AudioDevice *device) | ||
94 | { | ||
95 | SDL_free(device->hidden); | ||
96 | SDL_free(device); | ||
97 | } | ||
98 | |||
99 | static SDL_AudioDevice *Audio_CreateDevice(int devindex) | ||
100 | { | ||
101 | SDL_AudioDevice *this; | ||
102 | |||
103 | /* Initialize all variables that we clean on shutdown */ | ||
104 | this = (SDL_AudioDevice *)SDL_malloc(sizeof(SDL_AudioDevice)); | ||
105 | if ( this ) { | ||
106 | SDL_memset(this, 0, (sizeof *this)); | ||
107 | this->hidden = (struct SDL_PrivateAudioData *) | ||
108 | SDL_malloc((sizeof *this->hidden)); | ||
109 | } | ||
110 | if ( (this == NULL) || (this->hidden == NULL) ) { | ||
111 | SDL_OutOfMemory(); | ||
112 | if ( this ) { | ||
113 | SDL_free(this); | ||
114 | } | ||
115 | return(0); | ||
116 | } | ||
117 | SDL_memset(this->hidden, 0, (sizeof *this->hidden)); | ||
118 | audio_fd = -1; | ||
119 | |||
120 | /* Set the function pointers */ | ||
121 | this->OpenAudio = DMA_OpenAudio; | ||
122 | this->WaitAudio = DMA_WaitAudio; | ||
123 | this->PlayAudio = DMA_PlayAudio; | ||
124 | this->GetAudioBuf = DMA_GetAudioBuf; | ||
125 | this->CloseAudio = DMA_CloseAudio; | ||
126 | |||
127 | this->free = Audio_DeleteDevice; | ||
128 | |||
129 | return this; | ||
130 | } | ||
131 | |||
132 | AudioBootStrap DMA_bootstrap = { | ||
133 | DMA_DRIVER_NAME, "OSS /dev/dsp DMA audio", | ||
134 | Audio_Available, Audio_CreateDevice | ||
135 | }; | ||
136 | |||
137 | /* This function waits until it is possible to write a full sound buffer */ | ||
138 | static void DMA_WaitAudio(_THIS) | ||
139 | { | ||
140 | fd_set fdset; | ||
141 | |||
142 | /* Check to see if the thread-parent process is still alive */ | ||
143 | { static int cnt = 0; | ||
144 | /* Note that this only works with thread implementations | ||
145 | that use a different process id for each thread. | ||
146 | */ | ||
147 | if (parent && (((++cnt)%10) == 0)) { /* Check every 10 loops */ | ||
148 | if ( kill(parent, 0) < 0 ) { | ||
149 | this->enabled = 0; | ||
150 | } | ||
151 | } | ||
152 | } | ||
153 | |||
154 | /* See if we need to use timed audio synchronization */ | ||
155 | if ( frame_ticks ) { | ||
156 | /* Use timer for general audio synchronization */ | ||
157 | Sint32 ticks; | ||
158 | |||
159 | ticks = ((Sint32)(next_frame - SDL_GetTicks()))-FUDGE_TICKS; | ||
160 | if ( ticks > 0 ) { | ||
161 | SDL_Delay(ticks); | ||
162 | } | ||
163 | } else { | ||
164 | /* Use select() for audio synchronization */ | ||
165 | struct timeval timeout; | ||
166 | FD_ZERO(&fdset); | ||
167 | FD_SET(audio_fd, &fdset); | ||
168 | timeout.tv_sec = 10; | ||
169 | timeout.tv_usec = 0; | ||
170 | #ifdef DEBUG_AUDIO | ||
171 | fprintf(stderr, "Waiting for audio to get ready\n"); | ||
172 | #endif | ||
173 | if ( select(audio_fd+1, NULL, &fdset, NULL, &timeout) <= 0 ) { | ||
174 | const char *message = | ||
175 | #ifdef AUDIO_OSPACE_HACK | ||
176 | "Audio timeout - buggy audio driver? (trying ospace)"; | ||
177 | #else | ||
178 | "Audio timeout - buggy audio driver? (disabled)"; | ||
179 | #endif | ||
180 | /* In general we should never print to the screen, | ||
181 | but in this case we have no other way of letting | ||
182 | the user know what happened. | ||
183 | */ | ||
184 | fprintf(stderr, "SDL: %s\n", message); | ||
185 | #ifdef AUDIO_OSPACE_HACK | ||
186 | /* We may be able to use GET_OSPACE trick */ | ||
187 | frame_ticks = (float)(this->spec->samples*1000) / | ||
188 | this->spec->freq; | ||
189 | next_frame = SDL_GetTicks()+frame_ticks; | ||
190 | #else | ||
191 | this->enabled = 0; | ||
192 | /* Don't try to close - may hang */ | ||
193 | audio_fd = -1; | ||
194 | #ifdef DEBUG_AUDIO | ||
195 | fprintf(stderr, "Done disabling audio\n"); | ||
196 | #endif | ||
197 | #endif /* AUDIO_OSPACE_HACK */ | ||
198 | } | ||
199 | #ifdef DEBUG_AUDIO | ||
200 | fprintf(stderr, "Ready!\n"); | ||
201 | #endif | ||
202 | } | ||
203 | } | ||
204 | |||
205 | static void DMA_PlayAudio(_THIS) | ||
206 | { | ||
207 | /* If timer synchronization is enabled, set the next write frame */ | ||
208 | if ( frame_ticks ) { | ||
209 | next_frame += frame_ticks; | ||
210 | } | ||
211 | return; | ||
212 | } | ||
213 | |||
214 | static Uint8 *DMA_GetAudioBuf(_THIS) | ||
215 | { | ||
216 | count_info info; | ||
217 | int playing; | ||
218 | int filling; | ||
219 | |||
220 | /* Get number of blocks, looping if we're not using select() */ | ||
221 | do { | ||
222 | if ( ioctl(audio_fd, SNDCTL_DSP_GETOPTR, &info) < 0 ) { | ||
223 | /* Uh oh... */ | ||
224 | this->enabled = 0; | ||
225 | return(NULL); | ||
226 | } | ||
227 | } while ( frame_ticks && (info.blocks < 1) ); | ||
228 | #ifdef DEBUG_AUDIO | ||
229 | if ( info.blocks > 1 ) { | ||
230 | printf("Warning: audio underflow (%d frags)\n", info.blocks-1); | ||
231 | } | ||
232 | #endif | ||
233 | playing = info.ptr / this->spec.size; | ||
234 | filling = (playing + 1)%num_buffers; | ||
235 | return (dma_buf + (filling * this->spec.size)); | ||
236 | } | ||
237 | |||
238 | static void DMA_CloseAudio(_THIS) | ||
239 | { | ||
240 | if ( dma_buf != NULL ) { | ||
241 | munmap(dma_buf, dma_len); | ||
242 | dma_buf = NULL; | ||
243 | } | ||
244 | if ( audio_fd >= 0 ) { | ||
245 | close(audio_fd); | ||
246 | audio_fd = -1; | ||
247 | } | ||
248 | } | ||
249 | |||
250 | static int DMA_ReopenAudio(_THIS, const char *audiodev, int format, int stereo, | ||
251 | SDL_AudioSpec *spec) | ||
252 | { | ||
253 | int frag_spec; | ||
254 | int value; | ||
255 | |||
256 | /* Close and then reopen the audio device */ | ||
257 | close(audio_fd); | ||
258 | audio_fd = open(audiodev, O_RDWR, 0); | ||
259 | if ( audio_fd < 0 ) { | ||
260 | SDL_SetError("Couldn't open %s: %s", audiodev, strerror(errno)); | ||
261 | return(-1); | ||
262 | } | ||
263 | |||
264 | /* Calculate the final parameters for this audio specification */ | ||
265 | SDL_CalculateAudioSpec(spec); | ||
266 | |||
267 | /* Determine the power of two of the fragment size */ | ||
268 | for ( frag_spec = 0; (0x01<<frag_spec) < spec->size; ++frag_spec ); | ||
269 | if ( (0x01<<frag_spec) != spec->size ) { | ||
270 | SDL_SetError("Fragment size must be a power of two"); | ||
271 | return(-1); | ||
272 | } | ||
273 | |||
274 | /* Set the audio buffering parameters */ | ||
275 | if ( ioctl(audio_fd, SNDCTL_DSP_SETFRAGMENT, &frag_spec) < 0 ) { | ||
276 | SDL_SetError("Couldn't set audio fragment spec"); | ||
277 | return(-1); | ||
278 | } | ||
279 | |||
280 | /* Set the audio format */ | ||
281 | value = format; | ||
282 | if ( (ioctl(audio_fd, SNDCTL_DSP_SETFMT, &value) < 0) || | ||
283 | (value != format) ) { | ||
284 | SDL_SetError("Couldn't set audio format"); | ||
285 | return(-1); | ||
286 | } | ||
287 | |||
288 | /* Set mono or stereo audio */ | ||
289 | value = (spec->channels > 1); | ||
290 | if ( (ioctl(audio_fd, SNDCTL_DSP_STEREO, &stereo) < 0) || | ||
291 | (value != stereo) ) { | ||
292 | SDL_SetError("Couldn't set audio channels"); | ||
293 | return(-1); | ||
294 | } | ||
295 | |||
296 | /* Set the DSP frequency */ | ||
297 | value = spec->freq; | ||
298 | if ( ioctl(audio_fd, SNDCTL_DSP_SPEED, &value) < 0 ) { | ||
299 | SDL_SetError("Couldn't set audio frequency"); | ||
300 | return(-1); | ||
301 | } | ||
302 | spec->freq = value; | ||
303 | |||
304 | /* We successfully re-opened the audio */ | ||
305 | return(0); | ||
306 | } | ||
307 | |||
308 | static int DMA_OpenAudio(_THIS, SDL_AudioSpec *spec) | ||
309 | { | ||
310 | char audiodev[1024]; | ||
311 | int format; | ||
312 | int stereo; | ||
313 | int value; | ||
314 | Uint16 test_format; | ||
315 | struct audio_buf_info info; | ||
316 | |||
317 | /* Reset the timer synchronization flag */ | ||
318 | frame_ticks = 0.0; | ||
319 | |||
320 | /* Open the audio device */ | ||
321 | audio_fd = SDL_OpenAudioPath(audiodev, sizeof(audiodev), OPEN_FLAGS, 0); | ||
322 | if ( audio_fd < 0 ) { | ||
323 | SDL_SetError("Couldn't open %s: %s", audiodev, strerror(errno)); | ||
324 | return(-1); | ||
325 | } | ||
326 | dma_buf = NULL; | ||
327 | ioctl(audio_fd, SNDCTL_DSP_RESET, 0); | ||
328 | |||
329 | /* Get a list of supported hardware formats */ | ||
330 | if ( ioctl(audio_fd, SNDCTL_DSP_GETFMTS, &value) < 0 ) { | ||
331 | SDL_SetError("Couldn't get audio format list"); | ||
332 | return(-1); | ||
333 | } | ||
334 | |||
335 | /* Try for a closest match on audio format */ | ||
336 | format = 0; | ||
337 | for ( test_format = SDL_FirstAudioFormat(spec->format); | ||
338 | ! format && test_format; ) { | ||
339 | #ifdef DEBUG_AUDIO | ||
340 | fprintf(stderr, "Trying format 0x%4.4x\n", test_format); | ||
341 | #endif | ||
342 | switch ( test_format ) { | ||
343 | case AUDIO_U8: | ||
344 | if ( value & AFMT_U8 ) { | ||
345 | format = AFMT_U8; | ||
346 | } | ||
347 | break; | ||
348 | case AUDIO_S8: | ||
349 | if ( value & AFMT_S8 ) { | ||
350 | format = AFMT_S8; | ||
351 | } | ||
352 | break; | ||
353 | case AUDIO_S16LSB: | ||
354 | if ( value & AFMT_S16_LE ) { | ||
355 | format = AFMT_S16_LE; | ||
356 | } | ||
357 | break; | ||
358 | case AUDIO_S16MSB: | ||
359 | if ( value & AFMT_S16_BE ) { | ||
360 | format = AFMT_S16_BE; | ||
361 | } | ||
362 | break; | ||
363 | case AUDIO_U16LSB: | ||
364 | if ( value & AFMT_U16_LE ) { | ||
365 | format = AFMT_U16_LE; | ||
366 | } | ||
367 | break; | ||
368 | case AUDIO_U16MSB: | ||
369 | if ( value & AFMT_U16_BE ) { | ||
370 | format = AFMT_U16_BE; | ||
371 | } | ||
372 | break; | ||
373 | default: | ||
374 | format = 0; | ||
375 | break; | ||
376 | } | ||
377 | if ( ! format ) { | ||
378 | test_format = SDL_NextAudioFormat(); | ||
379 | } | ||
380 | } | ||
381 | if ( format == 0 ) { | ||
382 | SDL_SetError("Couldn't find any hardware audio formats"); | ||
383 | return(-1); | ||
384 | } | ||
385 | spec->format = test_format; | ||
386 | |||
387 | /* Set the audio format */ | ||
388 | value = format; | ||
389 | if ( (ioctl(audio_fd, SNDCTL_DSP_SETFMT, &value) < 0) || | ||
390 | (value != format) ) { | ||
391 | SDL_SetError("Couldn't set audio format"); | ||
392 | return(-1); | ||
393 | } | ||
394 | |||
395 | /* Set mono or stereo audio (currently only two channels supported) */ | ||
396 | stereo = (spec->channels > 1); | ||
397 | ioctl(audio_fd, SNDCTL_DSP_STEREO, &stereo); | ||
398 | if ( stereo ) { | ||
399 | spec->channels = 2; | ||
400 | } else { | ||
401 | spec->channels = 1; | ||
402 | } | ||
403 | |||
404 | /* Because some drivers don't allow setting the buffer size | ||
405 | after setting the format, we must re-open the audio device | ||
406 | once we know what format and channels are supported | ||
407 | */ | ||
408 | if ( DMA_ReopenAudio(this, audiodev, format, stereo, spec) < 0 ) { | ||
409 | /* Error is set by DMA_ReopenAudio() */ | ||
410 | return(-1); | ||
411 | } | ||
412 | |||
413 | /* Memory map the audio buffer */ | ||
414 | if ( ioctl(audio_fd, SNDCTL_DSP_GETOSPACE, &info) < 0 ) { | ||
415 | SDL_SetError("Couldn't get OSPACE parameters"); | ||
416 | return(-1); | ||
417 | } | ||
418 | spec->size = info.fragsize; | ||
419 | spec->samples = spec->size / ((spec->format & 0xFF) / 8); | ||
420 | spec->samples /= spec->channels; | ||
421 | num_buffers = info.fragstotal; | ||
422 | dma_len = num_buffers*spec->size; | ||
423 | dma_buf = (Uint8 *)mmap(NULL, dma_len, PROT_WRITE, MAP_SHARED, | ||
424 | audio_fd, 0); | ||
425 | if ( dma_buf == MAP_FAILED ) { | ||
426 | SDL_SetError("DMA memory map failed"); | ||
427 | dma_buf = NULL; | ||
428 | return(-1); | ||
429 | } | ||
430 | SDL_memset(dma_buf, spec->silence, dma_len); | ||
431 | |||
432 | /* Check to see if we need to use select() workaround */ | ||
433 | { char *workaround; | ||
434 | workaround = SDL_getenv("SDL_DSP_NOSELECT"); | ||
435 | if ( workaround ) { | ||
436 | frame_ticks = (float)(spec->samples*1000)/spec->freq; | ||
437 | next_frame = SDL_GetTicks()+frame_ticks; | ||
438 | } | ||
439 | } | ||
440 | |||
441 | /* Trigger audio playback */ | ||
442 | value = 0; | ||
443 | ioctl(audio_fd, SNDCTL_DSP_SETTRIGGER, &value); | ||
444 | value = PCM_ENABLE_OUTPUT; | ||
445 | if ( ioctl(audio_fd, SNDCTL_DSP_SETTRIGGER, &value) < 0 ) { | ||
446 | SDL_SetError("Couldn't trigger audio output"); | ||
447 | return(-1); | ||
448 | } | ||
449 | |||
450 | /* Get the parent process id (we're the parent of the audio thread) */ | ||
451 | parent = getpid(); | ||
452 | |||
453 | /* We're ready to rock and roll. :-) */ | ||
454 | return(0); | ||
455 | } | ||
diff --git a/apps/plugins/sdl/src/audio/dma/SDL_dmaaudio.h b/apps/plugins/sdl/src/audio/dma/SDL_dmaaudio.h deleted file mode 100644 index 9a45f732a1..0000000000 --- a/apps/plugins/sdl/src/audio/dma/SDL_dmaaudio.h +++ /dev/null | |||
@@ -1,59 +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 Lesser General Public | ||
7 | License as published by the Free Software Foundation; either | ||
8 | version 2.1 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 | Lesser General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU Lesser General Public | ||
16 | License along with this library; if not, write to the Free Software | ||
17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
18 | |||
19 | Sam Lantinga | ||
20 | slouken@libsdl.org | ||
21 | */ | ||
22 | #include "SDL_config.h" | ||
23 | |||
24 | #ifndef _SDL_dspaudio_h | ||
25 | #define _SDL_dspaudio_h | ||
26 | |||
27 | #include "../SDL_sysaudio.h" | ||
28 | |||
29 | /* Hidden "this" pointer for the video functions */ | ||
30 | #define _THIS SDL_AudioDevice *this | ||
31 | |||
32 | struct SDL_PrivateAudioData { | ||
33 | /* The file descriptor for the audio device */ | ||
34 | int audio_fd; | ||
35 | |||
36 | /* The parent process id, to detect when application quits */ | ||
37 | pid_t parent; | ||
38 | |||
39 | /* Raw mixing buffer */ | ||
40 | Uint8 *dma_buf; | ||
41 | int dma_len; | ||
42 | int num_buffers; | ||
43 | |||
44 | /* Support for audio timing using a timer, in addition to select() */ | ||
45 | float frame_ticks; | ||
46 | float next_frame; | ||
47 | }; | ||
48 | #define FUDGE_TICKS 10 /* The scheduler overhead ticks per frame */ | ||
49 | |||
50 | /* Old variable names */ | ||
51 | #define audio_fd (this->hidden->audio_fd) | ||
52 | #define parent (this->hidden->parent) | ||
53 | #define dma_buf (this->hidden->dma_buf) | ||
54 | #define dma_len (this->hidden->dma_len) | ||
55 | #define num_buffers (this->hidden->num_buffers) | ||
56 | #define frame_ticks (this->hidden->frame_ticks) | ||
57 | #define next_frame (this->hidden->next_frame) | ||
58 | |||
59 | #endif /* _SDL_dspaudio_h */ | ||
diff --git a/apps/plugins/sdl/src/audio/dmedia/SDL_irixaudio.c b/apps/plugins/sdl/src/audio/dmedia/SDL_irixaudio.c deleted file mode 100644 index 1dcd2421ec..0000000000 --- a/apps/plugins/sdl/src/audio/dmedia/SDL_irixaudio.c +++ /dev/null | |||
@@ -1,242 +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 Lesser General Public | ||
7 | License as published by the Free Software Foundation; either | ||
8 | version 2.1 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 | Lesser General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU Lesser General Public | ||
16 | License along with this library; if not, write to the Free Software | ||
17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
18 | |||
19 | Sam Lantinga | ||
20 | slouken@libsdl.org | ||
21 | */ | ||
22 | #include "SDL_config.h" | ||
23 | |||
24 | /* Allow access to a raw mixing buffer (For IRIX 6.5 and higher) */ | ||
25 | /* patch for IRIX 5 by Georg Schwarz 18/07/2004 */ | ||
26 | |||
27 | #include "SDL_timer.h" | ||
28 | #include "SDL_audio.h" | ||
29 | #include "../SDL_audiomem.h" | ||
30 | #include "../SDL_audio_c.h" | ||
31 | #include "SDL_irixaudio.h" | ||
32 | |||
33 | |||
34 | #ifndef AL_RESOURCE /* as a test whether we use the old IRIX audio libraries */ | ||
35 | #define OLD_IRIX_AUDIO | ||
36 | #define alClosePort(x) ALcloseport(x) | ||
37 | #define alFreeConfig(x) ALfreeconfig(x) | ||
38 | #define alGetFillable(x) ALgetfillable(x) | ||
39 | #define alNewConfig() ALnewconfig() | ||
40 | #define alOpenPort(x,y,z) ALopenport(x,y,z) | ||
41 | #define alSetChannels(x,y) ALsetchannels(x,y) | ||
42 | #define alSetQueueSize(x,y) ALsetqueuesize(x,y) | ||
43 | #define alSetSampFmt(x,y) ALsetsampfmt(x,y) | ||
44 | #define alSetWidth(x,y) ALsetwidth(x,y) | ||
45 | #endif | ||
46 | |||
47 | /* Audio driver functions */ | ||
48 | static int AL_OpenAudio(_THIS, SDL_AudioSpec *spec); | ||
49 | static void AL_WaitAudio(_THIS); | ||
50 | static void AL_PlayAudio(_THIS); | ||
51 | static Uint8 *AL_GetAudioBuf(_THIS); | ||
52 | static void AL_CloseAudio(_THIS); | ||
53 | |||
54 | /* Audio driver bootstrap functions */ | ||
55 | |||
56 | static int Audio_Available(void) | ||
57 | { | ||
58 | return 1; | ||
59 | } | ||
60 | |||
61 | static void Audio_DeleteDevice(SDL_AudioDevice *device) | ||
62 | { | ||
63 | SDL_free(device->hidden); | ||
64 | SDL_free(device); | ||
65 | } | ||
66 | |||
67 | static SDL_AudioDevice *Audio_CreateDevice(int devindex) | ||
68 | { | ||
69 | SDL_AudioDevice *this; | ||
70 | |||
71 | /* Initialize all variables that we clean on shutdown */ | ||
72 | this = (SDL_AudioDevice *)SDL_malloc(sizeof(SDL_AudioDevice)); | ||
73 | if ( this ) { | ||
74 | SDL_memset(this, 0, (sizeof *this)); | ||
75 | this->hidden = (struct SDL_PrivateAudioData *) | ||
76 | SDL_malloc((sizeof *this->hidden)); | ||
77 | } | ||
78 | if ( (this == NULL) || (this->hidden == NULL) ) { | ||
79 | SDL_OutOfMemory(); | ||
80 | if ( this ) { | ||
81 | SDL_free(this); | ||
82 | } | ||
83 | return(0); | ||
84 | } | ||
85 | SDL_memset(this->hidden, 0, (sizeof *this->hidden)); | ||
86 | |||
87 | /* Set the function pointers */ | ||
88 | this->OpenAudio = AL_OpenAudio; | ||
89 | this->WaitAudio = AL_WaitAudio; | ||
90 | this->PlayAudio = AL_PlayAudio; | ||
91 | this->GetAudioBuf = AL_GetAudioBuf; | ||
92 | this->CloseAudio = AL_CloseAudio; | ||
93 | |||
94 | this->free = Audio_DeleteDevice; | ||
95 | |||
96 | return this; | ||
97 | } | ||
98 | |||
99 | AudioBootStrap DMEDIA_bootstrap = { | ||
100 | "AL", "IRIX DMedia audio", | ||
101 | Audio_Available, Audio_CreateDevice | ||
102 | }; | ||
103 | |||
104 | |||
105 | void static AL_WaitAudio(_THIS) | ||
106 | { | ||
107 | Sint32 timeleft; | ||
108 | |||
109 | timeleft = this->spec.samples - alGetFillable(audio_port); | ||
110 | if ( timeleft > 0 ) { | ||
111 | timeleft /= (this->spec.freq/1000); | ||
112 | SDL_Delay((Uint32)timeleft); | ||
113 | } | ||
114 | } | ||
115 | |||
116 | static void AL_PlayAudio(_THIS) | ||
117 | { | ||
118 | /* Write the audio data out */ | ||
119 | if ( alWriteFrames(audio_port, mixbuf, this->spec.samples) < 0 ) { | ||
120 | /* Assume fatal error, for now */ | ||
121 | this->enabled = 0; | ||
122 | } | ||
123 | } | ||
124 | |||
125 | static Uint8 *AL_GetAudioBuf(_THIS) | ||
126 | { | ||
127 | return(mixbuf); | ||
128 | } | ||
129 | |||
130 | static void AL_CloseAudio(_THIS) | ||
131 | { | ||
132 | if ( mixbuf != NULL ) { | ||
133 | SDL_FreeAudioMem(mixbuf); | ||
134 | mixbuf = NULL; | ||
135 | } | ||
136 | if ( audio_port != NULL ) { | ||
137 | alClosePort(audio_port); | ||
138 | audio_port = NULL; | ||
139 | } | ||
140 | } | ||
141 | |||
142 | static int AL_OpenAudio(_THIS, SDL_AudioSpec * spec) | ||
143 | { | ||
144 | Uint16 test_format = SDL_FirstAudioFormat(spec->format); | ||
145 | long width = 0; | ||
146 | long fmt = 0; | ||
147 | int valid = 0; | ||
148 | |||
149 | #ifdef OLD_IRIX_AUDIO | ||
150 | { | ||
151 | long audio_param[2]; | ||
152 | audio_param[0] = AL_OUTPUT_RATE; | ||
153 | audio_param[1] = spec->freq; | ||
154 | valid = (ALsetparams(AL_DEFAULT_DEVICE, audio_param, 2) < 0); | ||
155 | } | ||
156 | #else | ||
157 | { | ||
158 | ALpv audio_param; | ||
159 | audio_param.param = AL_RATE; | ||
160 | audio_param.value.i = spec->freq; | ||
161 | valid = (alSetParams(AL_DEFAULT_OUTPUT, &audio_param, 1) < 0); | ||
162 | } | ||
163 | #endif | ||
164 | |||
165 | while ((!valid) && (test_format)) { | ||
166 | valid = 1; | ||
167 | spec->format = test_format; | ||
168 | |||
169 | switch (test_format) { | ||
170 | case AUDIO_S8: | ||
171 | width = AL_SAMPLE_8; | ||
172 | fmt = AL_SAMPFMT_TWOSCOMP; | ||
173 | break; | ||
174 | |||
175 | case AUDIO_S16SYS: | ||
176 | width = AL_SAMPLE_16; | ||
177 | fmt = AL_SAMPFMT_TWOSCOMP; | ||
178 | break; | ||
179 | |||
180 | default: | ||
181 | valid = 0; | ||
182 | test_format = SDL_NextAudioFormat(); | ||
183 | break; | ||
184 | } | ||
185 | |||
186 | if (valid) { | ||
187 | ALconfig audio_config = alNewConfig(); | ||
188 | valid = 0; | ||
189 | if (audio_config) { | ||
190 | if (alSetChannels(audio_config, spec->channels) < 0) { | ||
191 | if (spec->channels > 2) { /* can't handle > stereo? */ | ||
192 | spec->channels = 2; /* try again below. */ | ||
193 | } | ||
194 | } | ||
195 | |||
196 | if ((alSetSampFmt(audio_config, fmt) >= 0) && | ||
197 | ((!width) || (alSetWidth(audio_config, width) >= 0)) && | ||
198 | (alSetQueueSize(audio_config, spec->samples * 2) >= 0) && | ||
199 | (alSetChannels(audio_config, spec->channels) >= 0)) { | ||
200 | |||
201 | audio_port = alOpenPort("SDL audio", "w", audio_config); | ||
202 | if (audio_port == NULL) { | ||
203 | /* docs say AL_BAD_CHANNELS happens here, too. */ | ||
204 | int err = oserror(); | ||
205 | if (err == AL_BAD_CHANNELS) { | ||
206 | spec->channels = 2; | ||
207 | alSetChannels(audio_config, spec->channels); | ||
208 | audio_port = alOpenPort("SDL audio", "w", | ||
209 | audio_config); | ||
210 | } | ||
211 | } | ||
212 | |||
213 | if (audio_port != NULL) { | ||
214 | valid = 1; | ||
215 | } | ||
216 | } | ||
217 | |||
218 | alFreeConfig(audio_config); | ||
219 | } | ||
220 | } | ||
221 | } | ||
222 | |||
223 | if (!valid) { | ||
224 | SDL_SetError("Unsupported audio format"); | ||
225 | return (-1); | ||
226 | } | ||
227 | |||
228 | /* Update the fragment size as size in bytes */ | ||
229 | SDL_CalculateAudioSpec(spec); | ||
230 | |||
231 | /* Allocate mixing buffer */ | ||
232 | mixbuf = (Uint8 *) SDL_AllocAudioMem(spec->size); | ||
233 | if (mixbuf == NULL) { | ||
234 | SDL_OutOfMemory(); | ||
235 | return (-1); | ||
236 | } | ||
237 | SDL_memset(mixbuf, spec->silence, spec->size); | ||
238 | |||
239 | /* We're ready to rock and roll. :-) */ | ||
240 | return (0); | ||
241 | } | ||
242 | |||
diff --git a/apps/plugins/sdl/src/audio/dmedia/SDL_irixaudio.h b/apps/plugins/sdl/src/audio/dmedia/SDL_irixaudio.h deleted file mode 100644 index c04f497cea..0000000000 --- a/apps/plugins/sdl/src/audio/dmedia/SDL_irixaudio.h +++ /dev/null | |||
@@ -1,45 +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 Lesser General Public | ||
7 | License as published by the Free Software Foundation; either | ||
8 | version 2.1 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 | Lesser General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU Lesser General Public | ||
16 | License along with this library; if not, write to the Free Software | ||
17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
18 | |||
19 | Sam Lantinga | ||
20 | slouken@libsdl.org | ||
21 | */ | ||
22 | #include "SDL_config.h" | ||
23 | |||
24 | #ifndef _SDL_lowaudio_h | ||
25 | #define _SDL_lowaudio_h | ||
26 | |||
27 | #include <dmedia/audio.h> | ||
28 | |||
29 | #include "../SDL_sysaudio.h" | ||
30 | |||
31 | /* Hidden "this" pointer for the audio functions */ | ||
32 | #define _THIS SDL_AudioDevice *this | ||
33 | |||
34 | struct SDL_PrivateAudioData { | ||
35 | /* The handle for the audio device */ | ||
36 | ALport audio_port; | ||
37 | |||
38 | Uint8 *mixbuf; /* The app mixing buffer */ | ||
39 | }; | ||
40 | |||
41 | /* Old variable names */ | ||
42 | #define audio_port (this->hidden->audio_port) | ||
43 | #define mixbuf (this->hidden->mixbuf) | ||
44 | |||
45 | #endif /* _SDL_lowaudio_h */ | ||
diff --git a/apps/plugins/sdl/src/audio/dsp/SDL_dspaudio.c b/apps/plugins/sdl/src/audio/dsp/SDL_dspaudio.c deleted file mode 100644 index 256c547f9b..0000000000 --- a/apps/plugins/sdl/src/audio/dsp/SDL_dspaudio.c +++ /dev/null | |||
@@ -1,340 +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 Lesser General Public | ||
7 | License as published by the Free Software Foundation; either | ||
8 | version 2.1 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 | Lesser General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU Lesser General Public | ||
16 | License along with this library; if not, write to the Free Software | ||
17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
18 | |||
19 | Sam Lantinga | ||
20 | slouken@libsdl.org | ||
21 | |||
22 | Modified in Oct 2004 by Hannu Savolainen | ||
23 | hannu@opensound.com | ||
24 | */ | ||
25 | #include "SDL_config.h" | ||
26 | |||
27 | /* Allow access to a raw mixing buffer */ | ||
28 | |||
29 | #include <stdio.h> /* For perror() */ | ||
30 | #include <string.h> /* For strerror() */ | ||
31 | #include <errno.h> | ||
32 | #include <unistd.h> | ||
33 | #include <fcntl.h> | ||
34 | #include <signal.h> | ||
35 | #include <sys/time.h> | ||
36 | #include <sys/ioctl.h> | ||
37 | #include <sys/stat.h> | ||
38 | |||
39 | #if SDL_AUDIO_DRIVER_OSS_SOUNDCARD_H | ||
40 | /* This is installed on some systems */ | ||
41 | #include <soundcard.h> | ||
42 | #else | ||
43 | /* This is recommended by OSS */ | ||
44 | #include <sys/soundcard.h> | ||
45 | #endif | ||
46 | |||
47 | #include "SDL_timer.h" | ||
48 | #include "SDL_audio.h" | ||
49 | #include "../SDL_audiomem.h" | ||
50 | #include "../SDL_audio_c.h" | ||
51 | #include "../SDL_audiodev_c.h" | ||
52 | #include "SDL_dspaudio.h" | ||
53 | |||
54 | /* The tag name used by DSP audio */ | ||
55 | #define DSP_DRIVER_NAME "dsp" | ||
56 | |||
57 | /* Open the audio device for playback, and don't block if busy */ | ||
58 | #define OPEN_FLAGS (O_WRONLY|O_NONBLOCK) | ||
59 | |||
60 | /* Audio driver functions */ | ||
61 | static int DSP_OpenAudio(_THIS, SDL_AudioSpec *spec); | ||
62 | static void DSP_WaitAudio(_THIS); | ||
63 | static void DSP_PlayAudio(_THIS); | ||
64 | static Uint8 *DSP_GetAudioBuf(_THIS); | ||
65 | static void DSP_CloseAudio(_THIS); | ||
66 | |||
67 | /* Audio driver bootstrap functions */ | ||
68 | |||
69 | static int Audio_Available(void) | ||
70 | { | ||
71 | int fd; | ||
72 | int available; | ||
73 | |||
74 | available = 0; | ||
75 | fd = SDL_OpenAudioPath(NULL, 0, OPEN_FLAGS, 0); | ||
76 | if ( fd >= 0 ) { | ||
77 | available = 1; | ||
78 | close(fd); | ||
79 | } | ||
80 | return(available); | ||
81 | } | ||
82 | |||
83 | static void Audio_DeleteDevice(SDL_AudioDevice *device) | ||
84 | { | ||
85 | SDL_free(device->hidden); | ||
86 | SDL_free(device); | ||
87 | } | ||
88 | |||
89 | static SDL_AudioDevice *Audio_CreateDevice(int devindex) | ||
90 | { | ||
91 | SDL_AudioDevice *this; | ||
92 | |||
93 | /* Initialize all variables that we clean on shutdown */ | ||
94 | this = (SDL_AudioDevice *)SDL_malloc(sizeof(SDL_AudioDevice)); | ||
95 | if ( this ) { | ||
96 | SDL_memset(this, 0, (sizeof *this)); | ||
97 | this->hidden = (struct SDL_PrivateAudioData *) | ||
98 | SDL_malloc((sizeof *this->hidden)); | ||
99 | } | ||
100 | if ( (this == NULL) || (this->hidden == NULL) ) { | ||
101 | SDL_OutOfMemory(); | ||
102 | if ( this ) { | ||
103 | SDL_free(this); | ||
104 | } | ||
105 | return(0); | ||
106 | } | ||
107 | SDL_memset(this->hidden, 0, (sizeof *this->hidden)); | ||
108 | audio_fd = -1; | ||
109 | |||
110 | /* Set the function pointers */ | ||
111 | this->OpenAudio = DSP_OpenAudio; | ||
112 | this->WaitAudio = DSP_WaitAudio; | ||
113 | this->PlayAudio = DSP_PlayAudio; | ||
114 | this->GetAudioBuf = DSP_GetAudioBuf; | ||
115 | this->CloseAudio = DSP_CloseAudio; | ||
116 | |||
117 | this->free = Audio_DeleteDevice; | ||
118 | |||
119 | return this; | ||
120 | } | ||
121 | |||
122 | AudioBootStrap DSP_bootstrap = { | ||
123 | DSP_DRIVER_NAME, "OSS /dev/dsp standard audio", | ||
124 | Audio_Available, Audio_CreateDevice | ||
125 | }; | ||
126 | |||
127 | /* This function waits until it is possible to write a full sound buffer */ | ||
128 | static void DSP_WaitAudio(_THIS) | ||
129 | { | ||
130 | /* Not needed at all since OSS handles waiting automagically */ | ||
131 | } | ||
132 | |||
133 | static void DSP_PlayAudio(_THIS) | ||
134 | { | ||
135 | if (write(audio_fd, mixbuf, mixlen)==-1) | ||
136 | { | ||
137 | perror("Audio write"); | ||
138 | this->enabled = 0; | ||
139 | } | ||
140 | |||
141 | #ifdef DEBUG_AUDIO | ||
142 | fprintf(stderr, "Wrote %d bytes of audio data\n", mixlen); | ||
143 | #endif | ||
144 | } | ||
145 | |||
146 | static Uint8 *DSP_GetAudioBuf(_THIS) | ||
147 | { | ||
148 | return(mixbuf); | ||
149 | } | ||
150 | |||
151 | static void DSP_CloseAudio(_THIS) | ||
152 | { | ||
153 | if ( mixbuf != NULL ) { | ||
154 | SDL_FreeAudioMem(mixbuf); | ||
155 | mixbuf = NULL; | ||
156 | } | ||
157 | if ( audio_fd >= 0 ) { | ||
158 | close(audio_fd); | ||
159 | audio_fd = -1; | ||
160 | } | ||
161 | } | ||
162 | |||
163 | static int DSP_OpenAudio(_THIS, SDL_AudioSpec *spec) | ||
164 | { | ||
165 | char audiodev[1024]; | ||
166 | int format; | ||
167 | int value; | ||
168 | int frag_spec; | ||
169 | Uint16 test_format; | ||
170 | |||
171 | /* Make sure fragment size stays a power of 2, or OSS fails. */ | ||
172 | /* I don't know which of these are actually legal values, though... */ | ||
173 | if (spec->channels > 8) | ||
174 | spec->channels = 8; | ||
175 | else if (spec->channels > 4) | ||
176 | spec->channels = 4; | ||
177 | else if (spec->channels > 2) | ||
178 | spec->channels = 2; | ||
179 | |||
180 | /* Open the audio device */ | ||
181 | audio_fd = SDL_OpenAudioPath(audiodev, sizeof(audiodev), OPEN_FLAGS, 0); | ||
182 | if ( audio_fd < 0 ) { | ||
183 | SDL_SetError("Couldn't open %s: %s", audiodev, strerror(errno)); | ||
184 | return(-1); | ||
185 | } | ||
186 | mixbuf = NULL; | ||
187 | |||
188 | /* Make the file descriptor use blocking writes with fcntl() */ | ||
189 | { long flags; | ||
190 | flags = fcntl(audio_fd, F_GETFL); | ||
191 | flags &= ~O_NONBLOCK; | ||
192 | if ( fcntl(audio_fd, F_SETFL, flags) < 0 ) { | ||
193 | SDL_SetError("Couldn't set audio blocking mode"); | ||
194 | DSP_CloseAudio(this); | ||
195 | return(-1); | ||
196 | } | ||
197 | } | ||
198 | |||
199 | /* Get a list of supported hardware formats */ | ||
200 | if ( ioctl(audio_fd, SNDCTL_DSP_GETFMTS, &value) < 0 ) { | ||
201 | perror("SNDCTL_DSP_GETFMTS"); | ||
202 | SDL_SetError("Couldn't get audio format list"); | ||
203 | DSP_CloseAudio(this); | ||
204 | return(-1); | ||
205 | } | ||
206 | |||
207 | /* Try for a closest match on audio format */ | ||
208 | format = 0; | ||
209 | for ( test_format = SDL_FirstAudioFormat(spec->format); | ||
210 | ! format && test_format; ) { | ||
211 | #ifdef DEBUG_AUDIO | ||
212 | fprintf(stderr, "Trying format 0x%4.4x\n", test_format); | ||
213 | #endif | ||
214 | switch ( test_format ) { | ||
215 | case AUDIO_U8: | ||
216 | if ( value & AFMT_U8 ) { | ||
217 | format = AFMT_U8; | ||
218 | } | ||
219 | break; | ||
220 | case AUDIO_S16LSB: | ||
221 | if ( value & AFMT_S16_LE ) { | ||
222 | format = AFMT_S16_LE; | ||
223 | } | ||
224 | break; | ||
225 | case AUDIO_S16MSB: | ||
226 | if ( value & AFMT_S16_BE ) { | ||
227 | format = AFMT_S16_BE; | ||
228 | } | ||
229 | break; | ||
230 | #if 0 | ||
231 | /* | ||
232 | * These formats are not used by any real life systems so they are not | ||
233 | * needed here. | ||
234 | */ | ||
235 | case AUDIO_S8: | ||
236 | if ( value & AFMT_S8 ) { | ||
237 | format = AFMT_S8; | ||
238 | } | ||
239 | break; | ||
240 | case AUDIO_U16LSB: | ||
241 | if ( value & AFMT_U16_LE ) { | ||
242 | format = AFMT_U16_LE; | ||
243 | } | ||
244 | break; | ||
245 | case AUDIO_U16MSB: | ||
246 | if ( value & AFMT_U16_BE ) { | ||
247 | format = AFMT_U16_BE; | ||
248 | } | ||
249 | break; | ||
250 | #endif | ||
251 | default: | ||
252 | format = 0; | ||
253 | break; | ||
254 | } | ||
255 | if ( ! format ) { | ||
256 | test_format = SDL_NextAudioFormat(); | ||
257 | } | ||
258 | } | ||
259 | if ( format == 0 ) { | ||
260 | SDL_SetError("Couldn't find any hardware audio formats"); | ||
261 | DSP_CloseAudio(this); | ||
262 | return(-1); | ||
263 | } | ||
264 | spec->format = test_format; | ||
265 | |||
266 | /* Set the audio format */ | ||
267 | value = format; | ||
268 | if ( (ioctl(audio_fd, SNDCTL_DSP_SETFMT, &value) < 0) || | ||
269 | (value != format) ) { | ||
270 | perror("SNDCTL_DSP_SETFMT"); | ||
271 | SDL_SetError("Couldn't set audio format"); | ||
272 | DSP_CloseAudio(this); | ||
273 | return(-1); | ||
274 | } | ||
275 | |||
276 | /* Set the number of channels of output */ | ||
277 | value = spec->channels; | ||
278 | if ( ioctl(audio_fd, SNDCTL_DSP_CHANNELS, &value) < 0 ) { | ||
279 | perror("SNDCTL_DSP_CHANNELS"); | ||
280 | SDL_SetError("Cannot set the number of channels"); | ||
281 | DSP_CloseAudio(this); | ||
282 | return(-1); | ||
283 | } | ||
284 | spec->channels = value; | ||
285 | |||
286 | /* Set the DSP frequency */ | ||
287 | value = spec->freq; | ||
288 | if ( ioctl(audio_fd, SNDCTL_DSP_SPEED, &value) < 0 ) { | ||
289 | perror("SNDCTL_DSP_SPEED"); | ||
290 | SDL_SetError("Couldn't set audio frequency"); | ||
291 | DSP_CloseAudio(this); | ||
292 | return(-1); | ||
293 | } | ||
294 | spec->freq = value; | ||
295 | |||
296 | /* Calculate the final parameters for this audio specification */ | ||
297 | SDL_CalculateAudioSpec(spec); | ||
298 | |||
299 | /* Determine the power of two of the fragment size */ | ||
300 | for ( frag_spec = 0; (0x01U<<frag_spec) < spec->size; ++frag_spec ); | ||
301 | if ( (0x01U<<frag_spec) != spec->size ) { | ||
302 | SDL_SetError("Fragment size must be a power of two"); | ||
303 | DSP_CloseAudio(this); | ||
304 | return(-1); | ||
305 | } | ||
306 | frag_spec |= 0x00020000; /* two fragments, for low latency */ | ||
307 | |||
308 | /* Set the audio buffering parameters */ | ||
309 | #ifdef DEBUG_AUDIO | ||
310 | fprintf(stderr, "Requesting %d fragments of size %d\n", | ||
311 | (frag_spec >> 16), 1<<(frag_spec&0xFFFF)); | ||
312 | #endif | ||
313 | if ( ioctl(audio_fd, SNDCTL_DSP_SETFRAGMENT, &frag_spec) < 0 ) { | ||
314 | perror("SNDCTL_DSP_SETFRAGMENT"); | ||
315 | } | ||
316 | #ifdef DEBUG_AUDIO | ||
317 | { audio_buf_info info; | ||
318 | ioctl(audio_fd, SNDCTL_DSP_GETOSPACE, &info); | ||
319 | fprintf(stderr, "fragments = %d\n", info.fragments); | ||
320 | fprintf(stderr, "fragstotal = %d\n", info.fragstotal); | ||
321 | fprintf(stderr, "fragsize = %d\n", info.fragsize); | ||
322 | fprintf(stderr, "bytes = %d\n", info.bytes); | ||
323 | } | ||
324 | #endif | ||
325 | |||
326 | /* Allocate mixing buffer */ | ||
327 | mixlen = spec->size; | ||
328 | mixbuf = (Uint8 *)SDL_AllocAudioMem(mixlen); | ||
329 | if ( mixbuf == NULL ) { | ||
330 | DSP_CloseAudio(this); | ||
331 | return(-1); | ||
332 | } | ||
333 | SDL_memset(mixbuf, spec->silence, spec->size); | ||
334 | |||
335 | /* Get the parent process id (we're the parent of the audio thread) */ | ||
336 | parent = getpid(); | ||
337 | |||
338 | /* We're ready to rock and roll. :-) */ | ||
339 | return(0); | ||
340 | } | ||
diff --git a/apps/plugins/sdl/src/audio/dsp/SDL_dspaudio.h b/apps/plugins/sdl/src/audio/dsp/SDL_dspaudio.h deleted file mode 100644 index 382544f967..0000000000 --- a/apps/plugins/sdl/src/audio/dsp/SDL_dspaudio.h +++ /dev/null | |||
@@ -1,53 +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 Lesser General Public | ||
7 | License as published by the Free Software Foundation; either | ||
8 | version 2.1 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 | Lesser General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU Lesser General Public | ||
16 | License along with this library; if not, write to the Free Software | ||
17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
18 | |||
19 | Sam Lantinga | ||
20 | slouken@libsdl.org | ||
21 | */ | ||
22 | #include "SDL_config.h" | ||
23 | |||
24 | #ifndef _SDL_dspaudio_h | ||
25 | #define _SDL_dspaudio_h | ||
26 | |||
27 | #include "../SDL_sysaudio.h" | ||
28 | |||
29 | /* Hidden "this" pointer for the video functions */ | ||
30 | #define _THIS SDL_AudioDevice *this | ||
31 | |||
32 | struct SDL_PrivateAudioData { | ||
33 | /* The file descriptor for the audio device */ | ||
34 | int audio_fd; | ||
35 | |||
36 | /* The parent process id, to detect when application quits */ | ||
37 | pid_t parent; | ||
38 | |||
39 | /* Raw mixing buffer */ | ||
40 | Uint8 *mixbuf; | ||
41 | int mixlen; | ||
42 | }; | ||
43 | #define FUDGE_TICKS 10 /* The scheduler overhead ticks per frame */ | ||
44 | |||
45 | /* Old variable names */ | ||
46 | #define audio_fd (this->hidden->audio_fd) | ||
47 | #define parent (this->hidden->parent) | ||
48 | #define mixbuf (this->hidden->mixbuf) | ||
49 | #define mixlen (this->hidden->mixlen) | ||
50 | #define frame_ticks (this->hidden->frame_ticks) | ||
51 | #define next_frame (this->hidden->next_frame) | ||
52 | |||
53 | #endif /* _SDL_dspaudio_h */ | ||
diff --git a/apps/plugins/sdl/src/audio/esd/SDL_esdaudio.c b/apps/plugins/sdl/src/audio/esd/SDL_esdaudio.c deleted file mode 100644 index f54b0ea9c5..0000000000 --- a/apps/plugins/sdl/src/audio/esd/SDL_esdaudio.c +++ /dev/null | |||
@@ -1,323 +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 Lesser General Public | ||
7 | License as published by the Free Software Foundation; either | ||
8 | version 2.1 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 | Lesser General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU Lesser General Public | ||
16 | License along with this library; if not, write to the Free Software | ||
17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
18 | |||
19 | Sam Lantinga | ||
20 | slouken@libsdl.org | ||
21 | */ | ||
22 | #include "SDL_config.h" | ||
23 | |||
24 | /* Allow access to an ESD network stream mixing buffer */ | ||
25 | |||
26 | #include <sys/types.h> | ||
27 | #include <unistd.h> | ||
28 | #include <signal.h> | ||
29 | #include <errno.h> | ||
30 | #include <esd.h> | ||
31 | |||
32 | #include "SDL_timer.h" | ||
33 | #include "SDL_audio.h" | ||
34 | #include "../SDL_audiomem.h" | ||
35 | #include "../SDL_audio_c.h" | ||
36 | #include "../SDL_audiodev_c.h" | ||
37 | #include "SDL_esdaudio.h" | ||
38 | |||
39 | #ifdef SDL_AUDIO_DRIVER_ESD_DYNAMIC | ||
40 | #include "SDL_name.h" | ||
41 | #include "SDL_loadso.h" | ||
42 | #else | ||
43 | #define SDL_NAME(X) X | ||
44 | #endif | ||
45 | |||
46 | /* The tag name used by ESD audio */ | ||
47 | #define ESD_DRIVER_NAME "esd" | ||
48 | |||
49 | /* Audio driver functions */ | ||
50 | static int ESD_OpenAudio(_THIS, SDL_AudioSpec *spec); | ||
51 | static void ESD_WaitAudio(_THIS); | ||
52 | static void ESD_PlayAudio(_THIS); | ||
53 | static Uint8 *ESD_GetAudioBuf(_THIS); | ||
54 | static void ESD_CloseAudio(_THIS); | ||
55 | |||
56 | #ifdef SDL_AUDIO_DRIVER_ESD_DYNAMIC | ||
57 | |||
58 | static const char *esd_library = SDL_AUDIO_DRIVER_ESD_DYNAMIC; | ||
59 | static void *esd_handle = NULL; | ||
60 | static int esd_loaded = 0; | ||
61 | |||
62 | static int (*SDL_NAME(esd_open_sound))( const char *host ); | ||
63 | static int (*SDL_NAME(esd_close))( int esd ); | ||
64 | static int (*SDL_NAME(esd_play_stream))( esd_format_t format, int rate, | ||
65 | const char *host, const char *name ); | ||
66 | static struct { | ||
67 | const char *name; | ||
68 | void **func; | ||
69 | } esd_functions[] = { | ||
70 | { "esd_open_sound", (void **)&SDL_NAME(esd_open_sound) }, | ||
71 | { "esd_close", (void **)&SDL_NAME(esd_close) }, | ||
72 | { "esd_play_stream", (void **)&SDL_NAME(esd_play_stream) }, | ||
73 | }; | ||
74 | |||
75 | static void UnloadESDLibrary() | ||
76 | { | ||
77 | if ( esd_loaded ) { | ||
78 | SDL_UnloadObject(esd_handle); | ||
79 | esd_handle = NULL; | ||
80 | esd_loaded = 0; | ||
81 | } | ||
82 | } | ||
83 | |||
84 | static int LoadESDLibrary(void) | ||
85 | { | ||
86 | int i, retval = -1; | ||
87 | |||
88 | esd_handle = SDL_LoadObject(esd_library); | ||
89 | if ( esd_handle ) { | ||
90 | esd_loaded = 1; | ||
91 | retval = 0; | ||
92 | for ( i=0; i<SDL_arraysize(esd_functions); ++i ) { | ||
93 | *esd_functions[i].func = SDL_LoadFunction(esd_handle, esd_functions[i].name); | ||
94 | if ( !*esd_functions[i].func ) { | ||
95 | retval = -1; | ||
96 | UnloadESDLibrary(); | ||
97 | break; | ||
98 | } | ||
99 | } | ||
100 | } | ||
101 | return retval; | ||
102 | } | ||
103 | |||
104 | #else | ||
105 | |||
106 | static void UnloadESDLibrary() | ||
107 | { | ||
108 | return; | ||
109 | } | ||
110 | |||
111 | static int LoadESDLibrary(void) | ||
112 | { | ||
113 | return 0; | ||
114 | } | ||
115 | |||
116 | #endif /* SDL_AUDIO_DRIVER_ESD_DYNAMIC */ | ||
117 | |||
118 | /* Audio driver bootstrap functions */ | ||
119 | |||
120 | static int Audio_Available(void) | ||
121 | { | ||
122 | int connection; | ||
123 | int available; | ||
124 | |||
125 | available = 0; | ||
126 | if ( LoadESDLibrary() < 0 ) { | ||
127 | return available; | ||
128 | } | ||
129 | connection = SDL_NAME(esd_open_sound)(NULL); | ||
130 | if ( connection >= 0 ) { | ||
131 | available = 1; | ||
132 | SDL_NAME(esd_close)(connection); | ||
133 | } | ||
134 | UnloadESDLibrary(); | ||
135 | return(available); | ||
136 | } | ||
137 | |||
138 | static void Audio_DeleteDevice(SDL_AudioDevice *device) | ||
139 | { | ||
140 | SDL_free(device->hidden); | ||
141 | SDL_free(device); | ||
142 | UnloadESDLibrary(); | ||
143 | } | ||
144 | |||
145 | static SDL_AudioDevice *Audio_CreateDevice(int devindex) | ||
146 | { | ||
147 | SDL_AudioDevice *this; | ||
148 | |||
149 | /* Initialize all variables that we clean on shutdown */ | ||
150 | LoadESDLibrary(); | ||
151 | this = (SDL_AudioDevice *)SDL_malloc(sizeof(SDL_AudioDevice)); | ||
152 | if ( this ) { | ||
153 | SDL_memset(this, 0, (sizeof *this)); | ||
154 | this->hidden = (struct SDL_PrivateAudioData *) | ||
155 | SDL_malloc((sizeof *this->hidden)); | ||
156 | } | ||
157 | if ( (this == NULL) || (this->hidden == NULL) ) { | ||
158 | SDL_OutOfMemory(); | ||
159 | if ( this ) { | ||
160 | SDL_free(this); | ||
161 | } | ||
162 | return(0); | ||
163 | } | ||
164 | SDL_memset(this->hidden, 0, (sizeof *this->hidden)); | ||
165 | audio_fd = -1; | ||
166 | |||
167 | /* Set the function pointers */ | ||
168 | this->OpenAudio = ESD_OpenAudio; | ||
169 | this->WaitAudio = ESD_WaitAudio; | ||
170 | this->PlayAudio = ESD_PlayAudio; | ||
171 | this->GetAudioBuf = ESD_GetAudioBuf; | ||
172 | this->CloseAudio = ESD_CloseAudio; | ||
173 | |||
174 | this->free = Audio_DeleteDevice; | ||
175 | |||
176 | return this; | ||
177 | } | ||
178 | |||
179 | AudioBootStrap ESD_bootstrap = { | ||
180 | ESD_DRIVER_NAME, "Enlightened Sound Daemon", | ||
181 | Audio_Available, Audio_CreateDevice | ||
182 | }; | ||
183 | |||
184 | /* This function waits until it is possible to write a full sound buffer */ | ||
185 | static void ESD_WaitAudio(_THIS) | ||
186 | { | ||
187 | Sint32 ticks; | ||
188 | |||
189 | /* Check to see if the thread-parent process is still alive */ | ||
190 | { static int cnt = 0; | ||
191 | /* Note that this only works with thread implementations | ||
192 | that use a different process id for each thread. | ||
193 | */ | ||
194 | if (parent && (((++cnt)%10) == 0)) { /* Check every 10 loops */ | ||
195 | if ( kill(parent, 0) < 0 ) { | ||
196 | this->enabled = 0; | ||
197 | } | ||
198 | } | ||
199 | } | ||
200 | |||
201 | /* Use timer for general audio synchronization */ | ||
202 | ticks = ((Sint32)(next_frame - SDL_GetTicks()))-FUDGE_TICKS; | ||
203 | if ( ticks > 0 ) { | ||
204 | SDL_Delay(ticks); | ||
205 | } | ||
206 | } | ||
207 | |||
208 | static void ESD_PlayAudio(_THIS) | ||
209 | { | ||
210 | int written; | ||
211 | |||
212 | /* Write the audio data, checking for EAGAIN on broken audio drivers */ | ||
213 | do { | ||
214 | written = write(audio_fd, mixbuf, mixlen); | ||
215 | if ( (written < 0) && ((errno == 0) || (errno == EAGAIN)) ) { | ||
216 | SDL_Delay(1); /* Let a little CPU time go by */ | ||
217 | } | ||
218 | } while ( (written < 0) && | ||
219 | ((errno == 0) || (errno == EAGAIN) || (errno == EINTR)) ); | ||
220 | |||
221 | /* Set the next write frame */ | ||
222 | next_frame += frame_ticks; | ||
223 | |||
224 | /* If we couldn't write, assume fatal error for now */ | ||
225 | if ( written < 0 ) { | ||
226 | this->enabled = 0; | ||
227 | } | ||
228 | } | ||
229 | |||
230 | static Uint8 *ESD_GetAudioBuf(_THIS) | ||
231 | { | ||
232 | return(mixbuf); | ||
233 | } | ||
234 | |||
235 | static void ESD_CloseAudio(_THIS) | ||
236 | { | ||
237 | if ( mixbuf != NULL ) { | ||
238 | SDL_FreeAudioMem(mixbuf); | ||
239 | mixbuf = NULL; | ||
240 | } | ||
241 | if ( audio_fd >= 0 ) { | ||
242 | SDL_NAME(esd_close)(audio_fd); | ||
243 | audio_fd = -1; | ||
244 | } | ||
245 | } | ||
246 | |||
247 | /* Try to get the name of the program */ | ||
248 | static char *get_progname(void) | ||
249 | { | ||
250 | char *progname = NULL; | ||
251 | #ifdef __LINUX__ | ||
252 | FILE *fp; | ||
253 | static char temp[BUFSIZ]; | ||
254 | |||
255 | SDL_snprintf(temp, SDL_arraysize(temp), "/proc/%d/cmdline", getpid()); | ||
256 | fp = fopen(temp, "r"); | ||
257 | if ( fp != NULL ) { | ||
258 | if ( fgets(temp, sizeof(temp)-1, fp) ) { | ||
259 | progname = SDL_strrchr(temp, '/'); | ||
260 | if ( progname == NULL ) { | ||
261 | progname = temp; | ||
262 | } else { | ||
263 | progname = progname+1; | ||
264 | } | ||
265 | } | ||
266 | fclose(fp); | ||
267 | } | ||
268 | #endif | ||
269 | return(progname); | ||
270 | } | ||
271 | |||
272 | static int ESD_OpenAudio(_THIS, SDL_AudioSpec *spec) | ||
273 | { | ||
274 | esd_format_t format; | ||
275 | |||
276 | /* Convert audio spec to the ESD audio format */ | ||
277 | format = (ESD_STREAM | ESD_PLAY); | ||
278 | switch ( spec->format & 0xFF ) { | ||
279 | case 8: | ||
280 | format |= ESD_BITS8; | ||
281 | break; | ||
282 | case 16: | ||
283 | format |= ESD_BITS16; | ||
284 | break; | ||
285 | default: | ||
286 | SDL_SetError("Unsupported ESD audio format"); | ||
287 | return(-1); | ||
288 | } | ||
289 | if ( spec->channels == 1 ) { | ||
290 | format |= ESD_MONO; | ||
291 | } else { | ||
292 | format |= ESD_STEREO; | ||
293 | } | ||
294 | #if 0 | ||
295 | spec->samples = ESD_BUF_SIZE; /* Darn, no way to change this yet */ | ||
296 | #endif | ||
297 | |||
298 | /* Open a connection to the ESD audio server */ | ||
299 | audio_fd = SDL_NAME(esd_play_stream)(format, spec->freq, NULL, get_progname()); | ||
300 | if ( audio_fd < 0 ) { | ||
301 | SDL_SetError("Couldn't open ESD connection"); | ||
302 | return(-1); | ||
303 | } | ||
304 | |||
305 | /* Calculate the final parameters for this audio specification */ | ||
306 | SDL_CalculateAudioSpec(spec); | ||
307 | frame_ticks = (float)(spec->samples*1000)/spec->freq; | ||
308 | next_frame = SDL_GetTicks()+frame_ticks; | ||
309 | |||
310 | /* Allocate mixing buffer */ | ||
311 | mixlen = spec->size; | ||
312 | mixbuf = (Uint8 *)SDL_AllocAudioMem(mixlen); | ||
313 | if ( mixbuf == NULL ) { | ||
314 | return(-1); | ||
315 | } | ||
316 | SDL_memset(mixbuf, spec->silence, spec->size); | ||
317 | |||
318 | /* Get the parent process id (we're the parent of the audio thread) */ | ||
319 | parent = getpid(); | ||
320 | |||
321 | /* We're ready to rock and roll. :-) */ | ||
322 | return(0); | ||
323 | } | ||
diff --git a/apps/plugins/sdl/src/audio/esd/SDL_esdaudio.h b/apps/plugins/sdl/src/audio/esd/SDL_esdaudio.h deleted file mode 100644 index da4ae6a04b..0000000000 --- a/apps/plugins/sdl/src/audio/esd/SDL_esdaudio.h +++ /dev/null | |||
@@ -1,57 +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 Lesser General Public | ||
7 | License as published by the Free Software Foundation; either | ||
8 | version 2.1 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 | Lesser General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU Lesser General Public | ||
16 | License along with this library; if not, write to the Free Software | ||
17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
18 | |||
19 | Sam Lantinga | ||
20 | slouken@libsdl.org | ||
21 | */ | ||
22 | #include "SDL_config.h" | ||
23 | |||
24 | #ifndef _SDL_esdaudio_h | ||
25 | #define _SDL_esdaudio_h | ||
26 | |||
27 | #include "../SDL_sysaudio.h" | ||
28 | |||
29 | /* Hidden "this" pointer for the video functions */ | ||
30 | #define _THIS SDL_AudioDevice *this | ||
31 | |||
32 | struct SDL_PrivateAudioData { | ||
33 | /* The file descriptor for the audio device */ | ||
34 | int audio_fd; | ||
35 | |||
36 | /* The parent process id, to detect when application quits */ | ||
37 | pid_t parent; | ||
38 | |||
39 | /* Raw mixing buffer */ | ||
40 | Uint8 *mixbuf; | ||
41 | int mixlen; | ||
42 | |||
43 | /* Support for audio timing using a timer */ | ||
44 | float frame_ticks; | ||
45 | float next_frame; | ||
46 | }; | ||
47 | #define FUDGE_TICKS 10 /* The scheduler overhead ticks per frame */ | ||
48 | |||
49 | /* Old variable names */ | ||
50 | #define audio_fd (this->hidden->audio_fd) | ||
51 | #define parent (this->hidden->parent) | ||
52 | #define mixbuf (this->hidden->mixbuf) | ||
53 | #define mixlen (this->hidden->mixlen) | ||
54 | #define frame_ticks (this->hidden->frame_ticks) | ||
55 | #define next_frame (this->hidden->next_frame) | ||
56 | |||
57 | #endif /* _SDL_esdaudio_h */ | ||
diff --git a/apps/plugins/sdl/src/audio/macosx/SDL_coreaudio.c b/apps/plugins/sdl/src/audio/macosx/SDL_coreaudio.c deleted file mode 100644 index 31316d1fd9..0000000000 --- a/apps/plugins/sdl/src/audio/macosx/SDL_coreaudio.c +++ /dev/null | |||
@@ -1,291 +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 Lesser General Public | ||
7 | License as published by the Free Software Foundation; either | ||
8 | version 2.1 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 | Lesser General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU Lesser General Public | ||
16 | License along with this library; if not, write to the Free Software | ||
17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
18 | |||
19 | Sam Lantinga | ||
20 | slouken@libsdl.org | ||
21 | */ | ||
22 | #include "SDL_config.h" | ||
23 | |||
24 | #include <CoreAudio/CoreAudio.h> | ||
25 | #include <CoreServices/CoreServices.h> | ||
26 | #include <AudioUnit/AudioUnit.h> | ||
27 | #if MAC_OS_X_VERSION_MAX_ALLOWED <= 1050 | ||
28 | #include <AudioUnit/AUNTComponent.h> | ||
29 | #endif | ||
30 | |||
31 | #include "SDL_audio.h" | ||
32 | #include "../SDL_audio_c.h" | ||
33 | #include "../SDL_sysaudio.h" | ||
34 | #include "SDL_coreaudio.h" | ||
35 | |||
36 | |||
37 | /* Audio driver functions */ | ||
38 | |||
39 | static int Core_OpenAudio(_THIS, SDL_AudioSpec *spec); | ||
40 | static void Core_WaitAudio(_THIS); | ||
41 | static void Core_PlayAudio(_THIS); | ||
42 | static Uint8 *Core_GetAudioBuf(_THIS); | ||
43 | static void Core_CloseAudio(_THIS); | ||
44 | |||
45 | /* Audio driver bootstrap functions */ | ||
46 | |||
47 | static int Audio_Available(void) | ||
48 | { | ||
49 | return(1); | ||
50 | } | ||
51 | |||
52 | static void Audio_DeleteDevice(SDL_AudioDevice *device) | ||
53 | { | ||
54 | SDL_free(device->hidden); | ||
55 | SDL_free(device); | ||
56 | } | ||
57 | |||
58 | static SDL_AudioDevice *Audio_CreateDevice(int devindex) | ||
59 | { | ||
60 | SDL_AudioDevice *this; | ||
61 | |||
62 | /* Initialize all variables that we clean on shutdown */ | ||
63 | this = (SDL_AudioDevice *)SDL_malloc(sizeof(SDL_AudioDevice)); | ||
64 | if ( this ) { | ||
65 | SDL_memset(this, 0, (sizeof *this)); | ||
66 | this->hidden = (struct SDL_PrivateAudioData *) | ||
67 | SDL_malloc((sizeof *this->hidden)); | ||
68 | } | ||
69 | if ( (this == NULL) || (this->hidden == NULL) ) { | ||
70 | SDL_OutOfMemory(); | ||
71 | if ( this ) { | ||
72 | SDL_free(this); | ||
73 | } | ||
74 | return(0); | ||
75 | } | ||
76 | SDL_memset(this->hidden, 0, (sizeof *this->hidden)); | ||
77 | |||
78 | /* Set the function pointers */ | ||
79 | this->OpenAudio = Core_OpenAudio; | ||
80 | this->WaitAudio = Core_WaitAudio; | ||
81 | this->PlayAudio = Core_PlayAudio; | ||
82 | this->GetAudioBuf = Core_GetAudioBuf; | ||
83 | this->CloseAudio = Core_CloseAudio; | ||
84 | |||
85 | this->free = Audio_DeleteDevice; | ||
86 | |||
87 | return this; | ||
88 | } | ||
89 | |||
90 | AudioBootStrap COREAUDIO_bootstrap = { | ||
91 | "coreaudio", "Mac OS X CoreAudio", | ||
92 | Audio_Available, Audio_CreateDevice | ||
93 | }; | ||
94 | |||
95 | /* The CoreAudio callback */ | ||
96 | static OSStatus audioCallback (void *inRefCon, | ||
97 | AudioUnitRenderActionFlags *ioActionFlags, | ||
98 | const AudioTimeStamp *inTimeStamp, | ||
99 | UInt32 inBusNumber, | ||
100 | UInt32 inNumberFrames, | ||
101 | AudioBufferList *ioData) | ||
102 | { | ||
103 | SDL_AudioDevice *this = (SDL_AudioDevice *)inRefCon; | ||
104 | UInt32 remaining, len; | ||
105 | AudioBuffer *abuf; | ||
106 | void *ptr; | ||
107 | UInt32 i; | ||
108 | |||
109 | /* Only do anything if audio is enabled and not paused */ | ||
110 | if ( ! this->enabled || this->paused ) { | ||
111 | for (i = 0; i < ioData->mNumberBuffers; i++) { | ||
112 | abuf = &ioData->mBuffers[i]; | ||
113 | SDL_memset(abuf->mData, this->spec.silence, abuf->mDataByteSize); | ||
114 | } | ||
115 | return 0; | ||
116 | } | ||
117 | |||
118 | /* No SDL conversion should be needed here, ever, since we accept | ||
119 | any input format in OpenAudio, and leave the conversion to CoreAudio. | ||
120 | */ | ||
121 | /* | ||
122 | assert(!this->convert.needed); | ||
123 | assert(this->spec.channels == ioData->mNumberChannels); | ||
124 | */ | ||
125 | |||
126 | for (i = 0; i < ioData->mNumberBuffers; i++) { | ||
127 | abuf = &ioData->mBuffers[i]; | ||
128 | remaining = abuf->mDataByteSize; | ||
129 | ptr = abuf->mData; | ||
130 | while (remaining > 0) { | ||
131 | if (bufferOffset >= bufferSize) { | ||
132 | /* Generate the data */ | ||
133 | SDL_memset(buffer, this->spec.silence, bufferSize); | ||
134 | SDL_mutexP(this->mixer_lock); | ||
135 | (*this->spec.callback)(this->spec.userdata, | ||
136 | buffer, bufferSize); | ||
137 | SDL_mutexV(this->mixer_lock); | ||
138 | bufferOffset = 0; | ||
139 | } | ||
140 | |||
141 | len = bufferSize - bufferOffset; | ||
142 | if (len > remaining) | ||
143 | len = remaining; | ||
144 | SDL_memcpy(ptr, (char *)buffer + bufferOffset, len); | ||
145 | ptr = (char *)ptr + len; | ||
146 | remaining -= len; | ||
147 | bufferOffset += len; | ||
148 | } | ||
149 | } | ||
150 | |||
151 | return 0; | ||
152 | } | ||
153 | |||
154 | /* Dummy functions -- we don't use thread-based audio */ | ||
155 | void Core_WaitAudio(_THIS) | ||
156 | { | ||
157 | return; | ||
158 | } | ||
159 | |||
160 | void Core_PlayAudio(_THIS) | ||
161 | { | ||
162 | return; | ||
163 | } | ||
164 | |||
165 | Uint8 *Core_GetAudioBuf(_THIS) | ||
166 | { | ||
167 | return(NULL); | ||
168 | } | ||
169 | |||
170 | void Core_CloseAudio(_THIS) | ||
171 | { | ||
172 | OSStatus result; | ||
173 | struct AURenderCallbackStruct callback; | ||
174 | |||
175 | /* stop processing the audio unit */ | ||
176 | result = AudioOutputUnitStop (outputAudioUnit); | ||
177 | if (result != noErr) { | ||
178 | SDL_SetError("Core_CloseAudio: AudioOutputUnitStop"); | ||
179 | return; | ||
180 | } | ||
181 | |||
182 | /* Remove the input callback */ | ||
183 | callback.inputProc = 0; | ||
184 | callback.inputProcRefCon = 0; | ||
185 | result = AudioUnitSetProperty (outputAudioUnit, | ||
186 | kAudioUnitProperty_SetRenderCallback, | ||
187 | kAudioUnitScope_Input, | ||
188 | 0, | ||
189 | &callback, | ||
190 | sizeof(callback)); | ||
191 | if (result != noErr) { | ||
192 | SDL_SetError("Core_CloseAudio: AudioUnitSetProperty (kAudioUnitProperty_SetInputCallback)"); | ||
193 | return; | ||
194 | } | ||
195 | |||
196 | result = CloseComponent(outputAudioUnit); | ||
197 | if (result != noErr) { | ||
198 | SDL_SetError("Core_CloseAudio: CloseComponent"); | ||
199 | return; | ||
200 | } | ||
201 | |||
202 | SDL_free(buffer); | ||
203 | } | ||
204 | |||
205 | #define CHECK_RESULT(msg) \ | ||
206 | if (result != noErr) { \ | ||
207 | SDL_SetError("Failed to start CoreAudio: " msg); \ | ||
208 | return -1; \ | ||
209 | } | ||
210 | |||
211 | |||
212 | int Core_OpenAudio(_THIS, SDL_AudioSpec *spec) | ||
213 | { | ||
214 | OSStatus result = noErr; | ||
215 | Component comp; | ||
216 | ComponentDescription desc; | ||
217 | struct AURenderCallbackStruct callback; | ||
218 | AudioStreamBasicDescription requestedDesc; | ||
219 | |||
220 | /* Setup a AudioStreamBasicDescription with the requested format */ | ||
221 | requestedDesc.mFormatID = kAudioFormatLinearPCM; | ||
222 | requestedDesc.mFormatFlags = kLinearPCMFormatFlagIsPacked; | ||
223 | requestedDesc.mChannelsPerFrame = spec->channels; | ||
224 | requestedDesc.mSampleRate = spec->freq; | ||
225 | |||
226 | requestedDesc.mBitsPerChannel = spec->format & 0xFF; | ||
227 | if (spec->format & 0x8000) | ||
228 | requestedDesc.mFormatFlags |= kLinearPCMFormatFlagIsSignedInteger; | ||
229 | if (spec->format & 0x1000) | ||
230 | requestedDesc.mFormatFlags |= kLinearPCMFormatFlagIsBigEndian; | ||
231 | |||
232 | requestedDesc.mFramesPerPacket = 1; | ||
233 | requestedDesc.mBytesPerFrame = requestedDesc.mBitsPerChannel * requestedDesc.mChannelsPerFrame / 8; | ||
234 | requestedDesc.mBytesPerPacket = requestedDesc.mBytesPerFrame * requestedDesc.mFramesPerPacket; | ||
235 | |||
236 | |||
237 | /* Locate the default output audio unit */ | ||
238 | desc.componentType = kAudioUnitType_Output; | ||
239 | desc.componentSubType = kAudioUnitSubType_DefaultOutput; | ||
240 | desc.componentManufacturer = kAudioUnitManufacturer_Apple; | ||
241 | desc.componentFlags = 0; | ||
242 | desc.componentFlagsMask = 0; | ||
243 | |||
244 | comp = FindNextComponent (NULL, &desc); | ||
245 | if (comp == NULL) { | ||
246 | SDL_SetError ("Failed to start CoreAudio: FindNextComponent returned NULL"); | ||
247 | return -1; | ||
248 | } | ||
249 | |||
250 | /* Open & initialize the default output audio unit */ | ||
251 | result = OpenAComponent (comp, &outputAudioUnit); | ||
252 | CHECK_RESULT("OpenAComponent") | ||
253 | |||
254 | result = AudioUnitInitialize (outputAudioUnit); | ||
255 | CHECK_RESULT("AudioUnitInitialize") | ||
256 | |||
257 | /* Set the input format of the audio unit. */ | ||
258 | result = AudioUnitSetProperty (outputAudioUnit, | ||
259 | kAudioUnitProperty_StreamFormat, | ||
260 | kAudioUnitScope_Input, | ||
261 | 0, | ||
262 | &requestedDesc, | ||
263 | sizeof (requestedDesc)); | ||
264 | CHECK_RESULT("AudioUnitSetProperty (kAudioUnitProperty_StreamFormat)") | ||
265 | |||
266 | /* Set the audio callback */ | ||
267 | callback.inputProc = audioCallback; | ||
268 | callback.inputProcRefCon = this; | ||
269 | result = AudioUnitSetProperty (outputAudioUnit, | ||
270 | kAudioUnitProperty_SetRenderCallback, | ||
271 | kAudioUnitScope_Input, | ||
272 | 0, | ||
273 | &callback, | ||
274 | sizeof(callback)); | ||
275 | CHECK_RESULT("AudioUnitSetProperty (kAudioUnitProperty_SetInputCallback)") | ||
276 | |||
277 | /* Calculate the final parameters for this audio specification */ | ||
278 | SDL_CalculateAudioSpec(spec); | ||
279 | |||
280 | /* Allocate a sample buffer */ | ||
281 | bufferOffset = bufferSize = this->spec.size; | ||
282 | buffer = SDL_malloc(bufferSize); | ||
283 | |||
284 | /* Finally, start processing of the audio unit */ | ||
285 | result = AudioOutputUnitStart (outputAudioUnit); | ||
286 | CHECK_RESULT("AudioOutputUnitStart") | ||
287 | |||
288 | |||
289 | /* We're running! */ | ||
290 | return(1); | ||
291 | } | ||
diff --git a/apps/plugins/sdl/src/audio/macosx/SDL_coreaudio.h b/apps/plugins/sdl/src/audio/macosx/SDL_coreaudio.h deleted file mode 100644 index c11bc03a2b..0000000000 --- a/apps/plugins/sdl/src/audio/macosx/SDL_coreaudio.h +++ /dev/null | |||
@@ -1,45 +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 Lesser General Public | ||
7 | License as published by the Free Software Foundation; either | ||
8 | version 2.1 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 | Lesser General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU Lesser General Public | ||
16 | License along with this library; if not, write to the Free Software | ||
17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
18 | |||
19 | Sam Lantinga | ||
20 | slouken@libsdl.org | ||
21 | */ | ||
22 | #include "SDL_config.h" | ||
23 | |||
24 | #ifndef _SDL_coreaudio_h | ||
25 | #define _SDL_coreaudio_h | ||
26 | |||
27 | #include "../SDL_sysaudio.h" | ||
28 | |||
29 | /* Hidden "this" pointer for the video functions */ | ||
30 | #define _THIS SDL_AudioDevice *this | ||
31 | |||
32 | struct SDL_PrivateAudioData { | ||
33 | AudioUnit outputAudioUnit; | ||
34 | void *buffer; | ||
35 | UInt32 bufferOffset; | ||
36 | UInt32 bufferSize; | ||
37 | }; | ||
38 | |||
39 | /* Old variable names */ | ||
40 | #define outputAudioUnit (this->hidden->outputAudioUnit) | ||
41 | #define buffer (this->hidden->buffer) | ||
42 | #define bufferOffset (this->hidden->bufferOffset) | ||
43 | #define bufferSize (this->hidden->bufferSize) | ||
44 | |||
45 | #endif /* _SDL_coreaudio_h */ | ||
diff --git a/apps/plugins/sdl/src/audio/macrom/SDL_romaudio.c b/apps/plugins/sdl/src/audio/macrom/SDL_romaudio.c deleted file mode 100644 index 1b3d49e198..0000000000 --- a/apps/plugins/sdl/src/audio/macrom/SDL_romaudio.c +++ /dev/null | |||
@@ -1,496 +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 Lesser General Public | ||
7 | License as published by the Free Software Foundation; either | ||
8 | version 2.1 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 | Lesser General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU Lesser General Public | ||
16 | License along with this library; if not, write to the Free Software | ||
17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
18 | |||
19 | Sam Lantinga | ||
20 | slouken@libsdl.org | ||
21 | */ | ||
22 | #include "SDL_config.h" | ||
23 | |||
24 | #if defined(__APPLE__) && defined(__MACH__) | ||
25 | # include <Carbon/Carbon.h> | ||
26 | #elif TARGET_API_MAC_CARBON && (UNIVERSAL_INTERFACES_VERSION > 0x0335) | ||
27 | # include <Carbon.h> | ||
28 | #else | ||
29 | # include <Sound.h> /* SoundManager interface */ | ||
30 | # include <Gestalt.h> | ||
31 | # include <DriverServices.h> | ||
32 | #endif | ||
33 | |||
34 | #if !defined(NewSndCallBackUPP) && (UNIVERSAL_INTERFACES_VERSION < 0x0335) | ||
35 | #if !defined(NewSndCallBackProc) /* avoid circular redefinition... */ | ||
36 | #define NewSndCallBackUPP NewSndCallBackProc | ||
37 | #endif | ||
38 | #if !defined(NewSndCallBackUPP) | ||
39 | #define NewSndCallBackUPP NewSndCallBackProc | ||
40 | #endif | ||
41 | #endif | ||
42 | |||
43 | #include "SDL_audio.h" | ||
44 | #include "../SDL_audio_c.h" | ||
45 | #include "../SDL_sysaudio.h" | ||
46 | #include "SDL_romaudio.h" | ||
47 | |||
48 | /* Audio driver functions */ | ||
49 | |||
50 | static void Mac_CloseAudio(_THIS); | ||
51 | static int Mac_OpenAudio(_THIS, SDL_AudioSpec *spec); | ||
52 | static void Mac_LockAudio(_THIS); | ||
53 | static void Mac_UnlockAudio(_THIS); | ||
54 | |||
55 | /* Audio driver bootstrap functions */ | ||
56 | |||
57 | |||
58 | static int Audio_Available(void) | ||
59 | { | ||
60 | return(1); | ||
61 | } | ||
62 | |||
63 | static void Audio_DeleteDevice(SDL_AudioDevice *device) | ||
64 | { | ||
65 | SDL_free(device->hidden); | ||
66 | SDL_free(device); | ||
67 | } | ||
68 | |||
69 | static SDL_AudioDevice *Audio_CreateDevice(int devindex) | ||
70 | { | ||
71 | SDL_AudioDevice *this; | ||
72 | |||
73 | /* Initialize all variables that we clean on shutdown */ | ||
74 | this = (SDL_AudioDevice *)SDL_malloc(sizeof(SDL_AudioDevice)); | ||
75 | if ( this ) { | ||
76 | SDL_memset(this, 0, (sizeof *this)); | ||
77 | this->hidden = (struct SDL_PrivateAudioData *) | ||
78 | SDL_malloc((sizeof *this->hidden)); | ||
79 | } | ||
80 | if ( (this == NULL) || (this->hidden == NULL) ) { | ||
81 | SDL_OutOfMemory(); | ||
82 | if ( this ) { | ||
83 | SDL_free(this); | ||
84 | } | ||
85 | return(0); | ||
86 | } | ||
87 | SDL_memset(this->hidden, 0, (sizeof *this->hidden)); | ||
88 | |||
89 | /* Set the function pointers */ | ||
90 | this->OpenAudio = Mac_OpenAudio; | ||
91 | this->CloseAudio = Mac_CloseAudio; | ||
92 | this->LockAudio = Mac_LockAudio; | ||
93 | this->UnlockAudio = Mac_UnlockAudio; | ||
94 | this->free = Audio_DeleteDevice; | ||
95 | |||
96 | #ifdef __MACOSX__ /* Mac OS X uses threaded audio, so normal thread code is okay */ | ||
97 | this->LockAudio = NULL; | ||
98 | this->UnlockAudio = NULL; | ||
99 | #endif | ||
100 | return this; | ||
101 | } | ||
102 | |||
103 | AudioBootStrap SNDMGR_bootstrap = { | ||
104 | "sndmgr", "MacOS SoundManager 3.0", | ||
105 | Audio_Available, Audio_CreateDevice | ||
106 | }; | ||
107 | |||
108 | #if defined(TARGET_API_MAC_CARBON) || defined(USE_RYANS_SOUNDCODE) | ||
109 | /* This works correctly on Mac OS X */ | ||
110 | |||
111 | #pragma options align=power | ||
112 | |||
113 | static volatile SInt32 audio_is_locked = 0; | ||
114 | static volatile SInt32 need_to_mix = 0; | ||
115 | |||
116 | static UInt8 *buffer[2]; | ||
117 | static volatile UInt32 running = 0; | ||
118 | static CmpSoundHeader header; | ||
119 | static volatile Uint32 fill_me = 0; | ||
120 | |||
121 | static void mix_buffer(SDL_AudioDevice *audio, UInt8 *buffer) | ||
122 | { | ||
123 | if ( ! audio->paused ) { | ||
124 | #ifdef __MACOSX__ | ||
125 | SDL_mutexP(audio->mixer_lock); | ||
126 | #endif | ||
127 | if ( audio->convert.needed ) { | ||
128 | audio->spec.callback(audio->spec.userdata, | ||
129 | (Uint8 *)audio->convert.buf,audio->convert.len); | ||
130 | SDL_ConvertAudio(&audio->convert); | ||
131 | if ( audio->convert.len_cvt != audio->spec.size ) { | ||
132 | /* Uh oh... probably crashes here */; | ||
133 | } | ||
134 | SDL_memcpy(buffer, audio->convert.buf, audio->convert.len_cvt); | ||
135 | } else { | ||
136 | audio->spec.callback(audio->spec.userdata, buffer, audio->spec.size); | ||
137 | } | ||
138 | #ifdef __MACOSX__ | ||
139 | SDL_mutexV(audio->mixer_lock); | ||
140 | #endif | ||
141 | } | ||
142 | |||
143 | DecrementAtomic((SInt32 *) &need_to_mix); | ||
144 | } | ||
145 | |||
146 | static void Mac_LockAudio(_THIS) | ||
147 | { | ||
148 | IncrementAtomic((SInt32 *) &audio_is_locked); | ||
149 | } | ||
150 | |||
151 | static void Mac_UnlockAudio(_THIS) | ||
152 | { | ||
153 | SInt32 oldval; | ||
154 | |||
155 | oldval = DecrementAtomic((SInt32 *) &audio_is_locked); | ||
156 | if ( oldval != 1 ) /* != 1 means audio is still locked. */ | ||
157 | return; | ||
158 | |||
159 | /* Did we miss the chance to mix in an interrupt? Do it now. */ | ||
160 | if ( BitAndAtomic (0xFFFFFFFF, (UInt32 *) &need_to_mix) ) { | ||
161 | /* | ||
162 | * Note that this could be a problem if you missed an interrupt | ||
163 | * while the audio was locked, and get preempted by a second | ||
164 | * interrupt here, but that means you locked for way too long anyhow. | ||
165 | */ | ||
166 | mix_buffer (this, buffer[fill_me]); | ||
167 | } | ||
168 | } | ||
169 | |||
170 | static void callBackProc (SndChannel *chan, SndCommand *cmd_passed ) { | ||
171 | UInt32 play_me; | ||
172 | SndCommand cmd; | ||
173 | SDL_AudioDevice *audio = (SDL_AudioDevice *)chan->userInfo; | ||
174 | |||
175 | IncrementAtomic((SInt32 *) &need_to_mix); | ||
176 | |||
177 | fill_me = cmd_passed->param2; /* buffer that has just finished playing, so fill it */ | ||
178 | play_me = ! fill_me; /* filled buffer to play _now_ */ | ||
179 | |||
180 | if ( ! audio->enabled ) { | ||
181 | return; | ||
182 | } | ||
183 | |||
184 | /* queue previously mixed buffer for playback. */ | ||
185 | header.samplePtr = (Ptr)buffer[play_me]; | ||
186 | cmd.cmd = bufferCmd; | ||
187 | cmd.param1 = 0; | ||
188 | cmd.param2 = (long)&header; | ||
189 | SndDoCommand (chan, &cmd, 0); | ||
190 | |||
191 | memset (buffer[fill_me], 0, audio->spec.size); | ||
192 | |||
193 | /* | ||
194 | * if audio device isn't locked, mix the next buffer to be queued in | ||
195 | * the memory block that just finished playing. | ||
196 | */ | ||
197 | if ( ! BitAndAtomic(0xFFFFFFFF, (UInt32 *) &audio_is_locked) ) { | ||
198 | mix_buffer (audio, buffer[fill_me]); | ||
199 | } | ||
200 | |||
201 | /* set this callback to run again when current buffer drains. */ | ||
202 | if ( running ) { | ||
203 | cmd.cmd = callBackCmd; | ||
204 | cmd.param1 = 0; | ||
205 | cmd.param2 = play_me; | ||
206 | |||
207 | SndDoCommand (chan, &cmd, 0); | ||
208 | } | ||
209 | } | ||
210 | |||
211 | static int Mac_OpenAudio(_THIS, SDL_AudioSpec *spec) { | ||
212 | |||
213 | SndCallBackUPP callback; | ||
214 | int sample_bits; | ||
215 | int i; | ||
216 | long initOptions; | ||
217 | |||
218 | /* Very few conversions are required, but... */ | ||
219 | switch (spec->format) { | ||
220 | case AUDIO_S8: | ||
221 | spec->format = AUDIO_U8; | ||
222 | break; | ||
223 | case AUDIO_U16LSB: | ||
224 | spec->format = AUDIO_S16LSB; | ||
225 | break; | ||
226 | case AUDIO_U16MSB: | ||
227 | spec->format = AUDIO_S16MSB; | ||
228 | break; | ||
229 | } | ||
230 | SDL_CalculateAudioSpec(spec); | ||
231 | |||
232 | /* initialize bufferCmd header */ | ||
233 | memset (&header, 0, sizeof(header)); | ||
234 | callback = (SndCallBackUPP) NewSndCallBackUPP (callBackProc); | ||
235 | sample_bits = spec->size / spec->samples / spec->channels * 8; | ||
236 | |||
237 | #ifdef DEBUG_AUDIO | ||
238 | fprintf(stderr, | ||
239 | "Audio format 0x%x, channels = %d, sample_bits = %d, frequency = %d\n", | ||
240 | spec->format, spec->channels, sample_bits, spec->freq); | ||
241 | #endif /* DEBUG_AUDIO */ | ||
242 | |||
243 | header.numChannels = spec->channels; | ||
244 | header.sampleSize = sample_bits; | ||
245 | header.sampleRate = spec->freq << 16; | ||
246 | header.numFrames = spec->samples; | ||
247 | header.encode = cmpSH; | ||
248 | |||
249 | /* Note that we install the 16bitLittleEndian Converter if needed. */ | ||
250 | if ( spec->format == 0x8010 ) { | ||
251 | header.compressionID = fixedCompression; | ||
252 | header.format = k16BitLittleEndianFormat; | ||
253 | } | ||
254 | |||
255 | /* allocate 2 buffers */ | ||
256 | for (i=0; i<2; i++) { | ||
257 | buffer[i] = (UInt8*)malloc (sizeof(UInt8) * spec->size); | ||
258 | if (buffer[i] == NULL) { | ||
259 | SDL_OutOfMemory(); | ||
260 | return (-1); | ||
261 | } | ||
262 | memset (buffer[i], 0, spec->size); | ||
263 | } | ||
264 | |||
265 | /* Create the sound manager channel */ | ||
266 | channel = (SndChannelPtr)SDL_malloc(sizeof(*channel)); | ||
267 | if ( channel == NULL ) { | ||
268 | SDL_OutOfMemory(); | ||
269 | return(-1); | ||
270 | } | ||
271 | if ( spec->channels >= 2 ) { | ||
272 | initOptions = initStereo; | ||
273 | } else { | ||
274 | initOptions = initMono; | ||
275 | } | ||
276 | channel->userInfo = (long)this; | ||
277 | channel->qLength = 128; | ||
278 | if ( SndNewChannel(&channel, sampledSynth, initOptions, callback) != noErr ) { | ||
279 | SDL_SetError("Unable to create audio channel"); | ||
280 | SDL_free(channel); | ||
281 | channel = NULL; | ||
282 | return(-1); | ||
283 | } | ||
284 | |||
285 | /* start playback */ | ||
286 | { | ||
287 | SndCommand cmd; | ||
288 | cmd.cmd = callBackCmd; | ||
289 | cmd.param2 = 0; | ||
290 | running = 1; | ||
291 | SndDoCommand (channel, &cmd, 0); | ||
292 | } | ||
293 | |||
294 | return 1; | ||
295 | } | ||
296 | |||
297 | static void Mac_CloseAudio(_THIS) { | ||
298 | |||
299 | int i; | ||
300 | |||
301 | running = 0; | ||
302 | |||
303 | if (channel) { | ||
304 | SndDisposeChannel (channel, true); | ||
305 | channel = NULL; | ||
306 | } | ||
307 | |||
308 | for ( i=0; i<2; ++i ) { | ||
309 | if ( buffer[i] ) { | ||
310 | SDL_free(buffer[i]); | ||
311 | buffer[i] = NULL; | ||
312 | } | ||
313 | } | ||
314 | } | ||
315 | |||
316 | #else /* !TARGET_API_MAC_CARBON && !USE_RYANS_SOUNDCODE */ | ||
317 | |||
318 | static void Mac_LockAudio(_THIS) | ||
319 | { | ||
320 | /* no-op. */ | ||
321 | } | ||
322 | |||
323 | static void Mac_UnlockAudio(_THIS) | ||
324 | { | ||
325 | /* no-op. */ | ||
326 | } | ||
327 | |||
328 | |||
329 | /* This function is called by Sound Manager when it has exhausted one of | ||
330 | the buffers, so we'll zero it to silence and fill it with audio if | ||
331 | we're not paused. | ||
332 | */ | ||
333 | static pascal | ||
334 | void sndDoubleBackProc (SndChannelPtr chan, SndDoubleBufferPtr newbuf) | ||
335 | { | ||
336 | SDL_AudioDevice *audio = (SDL_AudioDevice *)newbuf->dbUserInfo[0]; | ||
337 | |||
338 | /* If audio is quitting, don't do anything */ | ||
339 | if ( ! audio->enabled ) { | ||
340 | return; | ||
341 | } | ||
342 | memset (newbuf->dbSoundData, 0, audio->spec.size); | ||
343 | newbuf->dbNumFrames = audio->spec.samples; | ||
344 | if ( ! audio->paused ) { | ||
345 | if ( audio->convert.needed ) { | ||
346 | audio->spec.callback(audio->spec.userdata, | ||
347 | (Uint8 *)audio->convert.buf,audio->convert.len); | ||
348 | SDL_ConvertAudio(&audio->convert); | ||
349 | #if 0 | ||
350 | if ( audio->convert.len_cvt != audio->spec.size ) { | ||
351 | /* Uh oh... probably crashes here */; | ||
352 | } | ||
353 | #endif | ||
354 | SDL_memcpy(newbuf->dbSoundData, audio->convert.buf, | ||
355 | audio->convert.len_cvt); | ||
356 | } else { | ||
357 | audio->spec.callback(audio->spec.userdata, | ||
358 | (Uint8 *)newbuf->dbSoundData, audio->spec.size); | ||
359 | } | ||
360 | } | ||
361 | newbuf->dbFlags |= dbBufferReady; | ||
362 | } | ||
363 | |||
364 | static int DoubleBufferAudio_Available(void) | ||
365 | { | ||
366 | int available; | ||
367 | NumVersion sndversion; | ||
368 | long response; | ||
369 | |||
370 | available = 0; | ||
371 | sndversion = SndSoundManagerVersion(); | ||
372 | if ( sndversion.majorRev >= 3 ) { | ||
373 | if ( Gestalt(gestaltSoundAttr, &response) == noErr ) { | ||
374 | if ( (response & (1 << gestaltSndPlayDoubleBuffer)) ) { | ||
375 | available = 1; | ||
376 | } | ||
377 | } | ||
378 | } else { | ||
379 | if ( Gestalt(gestaltSoundAttr, &response) == noErr ) { | ||
380 | if ( (response & (1 << gestaltHasASC)) ) { | ||
381 | available = 1; | ||
382 | } | ||
383 | } | ||
384 | } | ||
385 | return(available); | ||
386 | } | ||
387 | |||
388 | static void Mac_CloseAudio(_THIS) | ||
389 | { | ||
390 | int i; | ||
391 | |||
392 | if ( channel != NULL ) { | ||
393 | /* Clean up the audio channel */ | ||
394 | SndDisposeChannel(channel, true); | ||
395 | channel = NULL; | ||
396 | } | ||
397 | for ( i=0; i<2; ++i ) { | ||
398 | if ( audio_buf[i] ) { | ||
399 | SDL_free(audio_buf[i]); | ||
400 | audio_buf[i] = NULL; | ||
401 | } | ||
402 | } | ||
403 | } | ||
404 | |||
405 | static int Mac_OpenAudio(_THIS, SDL_AudioSpec *spec) | ||
406 | { | ||
407 | SndDoubleBufferHeader2 audio_dbh; | ||
408 | int i; | ||
409 | long initOptions; | ||
410 | int sample_bits; | ||
411 | SndDoubleBackUPP doubleBackProc; | ||
412 | |||
413 | /* Check to make sure double-buffered audio is available */ | ||
414 | if ( ! DoubleBufferAudio_Available() ) { | ||
415 | SDL_SetError("Sound manager doesn't support double-buffering"); | ||
416 | return(-1); | ||
417 | } | ||
418 | |||
419 | /* Very few conversions are required, but... */ | ||
420 | switch (spec->format) { | ||
421 | case AUDIO_S8: | ||
422 | spec->format = AUDIO_U8; | ||
423 | break; | ||
424 | case AUDIO_U16LSB: | ||
425 | spec->format = AUDIO_S16LSB; | ||
426 | break; | ||
427 | case AUDIO_U16MSB: | ||
428 | spec->format = AUDIO_S16MSB; | ||
429 | break; | ||
430 | } | ||
431 | SDL_CalculateAudioSpec(spec); | ||
432 | |||
433 | /* initialize the double-back header */ | ||
434 | SDL_memset(&audio_dbh, 0, sizeof(audio_dbh)); | ||
435 | doubleBackProc = NewSndDoubleBackProc (sndDoubleBackProc); | ||
436 | sample_bits = spec->size / spec->samples / spec->channels * 8; | ||
437 | |||
438 | audio_dbh.dbhNumChannels = spec->channels; | ||
439 | audio_dbh.dbhSampleSize = sample_bits; | ||
440 | audio_dbh.dbhCompressionID = 0; | ||
441 | audio_dbh.dbhPacketSize = 0; | ||
442 | audio_dbh.dbhSampleRate = spec->freq << 16; | ||
443 | audio_dbh.dbhDoubleBack = doubleBackProc; | ||
444 | audio_dbh.dbhFormat = 0; | ||
445 | |||
446 | /* Note that we install the 16bitLittleEndian Converter if needed. */ | ||
447 | if ( spec->format == 0x8010 ) { | ||
448 | audio_dbh.dbhCompressionID = fixedCompression; | ||
449 | audio_dbh.dbhFormat = k16BitLittleEndianFormat; | ||
450 | } | ||
451 | |||
452 | /* allocate the 2 double-back buffers */ | ||
453 | for ( i=0; i<2; ++i ) { | ||
454 | audio_buf[i] = SDL_calloc(1, sizeof(SndDoubleBuffer)+spec->size); | ||
455 | if ( audio_buf[i] == NULL ) { | ||
456 | SDL_OutOfMemory(); | ||
457 | return(-1); | ||
458 | } | ||
459 | audio_buf[i]->dbNumFrames = spec->samples; | ||
460 | audio_buf[i]->dbFlags = dbBufferReady; | ||
461 | audio_buf[i]->dbUserInfo[0] = (long)this; | ||
462 | audio_dbh.dbhBufferPtr[i] = audio_buf[i]; | ||
463 | } | ||
464 | |||
465 | /* Create the sound manager channel */ | ||
466 | channel = (SndChannelPtr)SDL_malloc(sizeof(*channel)); | ||
467 | if ( channel == NULL ) { | ||
468 | SDL_OutOfMemory(); | ||
469 | return(-1); | ||
470 | } | ||
471 | if ( spec->channels >= 2 ) { | ||
472 | initOptions = initStereo; | ||
473 | } else { | ||
474 | initOptions = initMono; | ||
475 | } | ||
476 | channel->userInfo = 0; | ||
477 | channel->qLength = 128; | ||
478 | if ( SndNewChannel(&channel, sampledSynth, initOptions, 0L) != noErr ) { | ||
479 | SDL_SetError("Unable to create audio channel"); | ||
480 | SDL_free(channel); | ||
481 | channel = NULL; | ||
482 | return(-1); | ||
483 | } | ||
484 | |||
485 | /* Start playback */ | ||
486 | if ( SndPlayDoubleBuffer(channel, (SndDoubleBufferHeaderPtr)&audio_dbh) | ||
487 | != noErr ) { | ||
488 | SDL_SetError("Unable to play double buffered audio"); | ||
489 | return(-1); | ||
490 | } | ||
491 | |||
492 | return 1; | ||
493 | } | ||
494 | |||
495 | #endif /* TARGET_API_MAC_CARBON || USE_RYANS_SOUNDCODE */ | ||
496 | |||
diff --git a/apps/plugins/sdl/src/audio/macrom/SDL_romaudio.h b/apps/plugins/sdl/src/audio/macrom/SDL_romaudio.h deleted file mode 100644 index 90e19c0695..0000000000 --- a/apps/plugins/sdl/src/audio/macrom/SDL_romaudio.h +++ /dev/null | |||
@@ -1,50 +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 Lesser General Public | ||
7 | License as published by the Free Software Foundation; either | ||
8 | version 2.1 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 | Lesser General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU Lesser General Public | ||
16 | License along with this library; if not, write to the Free Software | ||
17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
18 | |||
19 | Sam Lantinga | ||
20 | slouken@libsdl.org | ||
21 | */ | ||
22 | #include "SDL_config.h" | ||
23 | |||
24 | #ifndef _SDL_romaudio_h | ||
25 | #define _SDL_romaudio_h | ||
26 | |||
27 | #include "../SDL_sysaudio.h" | ||
28 | |||
29 | /* This is Ryan's improved MacOS sound code, with locking support */ | ||
30 | #define USE_RYANS_SOUNDCODE | ||
31 | |||
32 | /* Hidden "this" pointer for the video functions */ | ||
33 | #define _THIS SDL_AudioDevice *this | ||
34 | |||
35 | struct SDL_PrivateAudioData { | ||
36 | /* Sound manager audio channel */ | ||
37 | SndChannelPtr channel; | ||
38 | #if defined(TARGET_API_MAC_CARBON) || defined(USE_RYANS_SOUNDCODE) | ||
39 | /* FIXME: Add Ryan's static data here */ | ||
40 | #else | ||
41 | /* Double buffering variables */ | ||
42 | SndDoubleBufferPtr audio_buf[2]; | ||
43 | #endif | ||
44 | }; | ||
45 | |||
46 | /* Old variable names */ | ||
47 | #define channel (this->hidden->channel) | ||
48 | #define audio_buf (this->hidden->audio_buf) | ||
49 | |||
50 | #endif /* _SDL_romaudio_h */ | ||
diff --git a/apps/plugins/sdl/src/audio/mint/SDL_mintaudio.c b/apps/plugins/sdl/src/audio/mint/SDL_mintaudio.c deleted file mode 100644 index 46ba690c3e..0000000000 --- a/apps/plugins/sdl/src/audio/mint/SDL_mintaudio.c +++ /dev/null | |||
@@ -1,215 +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 | /* | ||
25 | Audio interrupt variables and callback function | ||
26 | |||
27 | Patrice Mandin | ||
28 | */ | ||
29 | |||
30 | #include <unistd.h> | ||
31 | |||
32 | #include <mint/osbind.h> | ||
33 | #include <mint/falcon.h> | ||
34 | #include <mint/mintbind.h> | ||
35 | #include <mint/cookie.h> | ||
36 | |||
37 | #include "SDL_audio.h" | ||
38 | #include "SDL_mintaudio.h" | ||
39 | #include "SDL_mintaudio_stfa.h" | ||
40 | |||
41 | /* The audio device */ | ||
42 | |||
43 | SDL_AudioDevice *SDL_MintAudio_device; | ||
44 | Uint8 *SDL_MintAudio_audiobuf[2]; /* Pointers to buffers */ | ||
45 | unsigned long SDL_MintAudio_audiosize; /* Length of audio buffer=spec->size */ | ||
46 | volatile unsigned short SDL_MintAudio_numbuf; /* Buffer to play */ | ||
47 | volatile unsigned short SDL_MintAudio_mutex; | ||
48 | volatile unsigned long SDL_MintAudio_clocktics; | ||
49 | cookie_stfa_t *SDL_MintAudio_stfa; | ||
50 | unsigned short SDL_MintAudio_hasfpu; | ||
51 | |||
52 | /* MiNT thread variables */ | ||
53 | SDL_bool SDL_MintAudio_mint_present; | ||
54 | SDL_bool SDL_MintAudio_quit_thread; | ||
55 | SDL_bool SDL_MintAudio_thread_finished; | ||
56 | long SDL_MintAudio_thread_pid; | ||
57 | |||
58 | /* The callback function, called by each driver whenever needed */ | ||
59 | |||
60 | void SDL_MintAudio_Callback(void) | ||
61 | { | ||
62 | Uint8 *buffer; | ||
63 | SDL_AudioDevice *audio = SDL_MintAudio_device; | ||
64 | |||
65 | buffer = SDL_MintAudio_audiobuf[SDL_MintAudio_numbuf]; | ||
66 | SDL_memset(buffer, audio->spec.silence, audio->spec.size); | ||
67 | |||
68 | if (audio->paused) | ||
69 | return; | ||
70 | |||
71 | if (audio->convert.needed) { | ||
72 | int silence; | ||
73 | |||
74 | if ( audio->convert.src_format == AUDIO_U8 ) { | ||
75 | silence = 0x80; | ||
76 | } else { | ||
77 | silence = 0; | ||
78 | } | ||
79 | SDL_memset(audio->convert.buf, silence, audio->convert.len); | ||
80 | audio->spec.callback(audio->spec.userdata, | ||
81 | (Uint8 *)audio->convert.buf,audio->convert.len); | ||
82 | SDL_ConvertAudio(&audio->convert); | ||
83 | SDL_memcpy(buffer, audio->convert.buf, audio->convert.len_cvt); | ||
84 | } else { | ||
85 | audio->spec.callback(audio->spec.userdata, buffer, audio->spec.size); | ||
86 | } | ||
87 | } | ||
88 | |||
89 | /* Add a new frequency/clock/predivisor to the current list */ | ||
90 | void SDL_MintAudio_AddFrequency(_THIS, Uint32 frequency, Uint32 clock, | ||
91 | Uint32 prediv, int gpio_bits) | ||
92 | { | ||
93 | int i, p; | ||
94 | |||
95 | if (MINTAUDIO_freqcount==MINTAUDIO_maxfreqs) { | ||
96 | return; | ||
97 | } | ||
98 | |||
99 | /* Search where to insert the frequency (highest first) */ | ||
100 | for (p=0; p<MINTAUDIO_freqcount; p++) { | ||
101 | if (frequency > MINTAUDIO_frequencies[p].frequency) { | ||
102 | break; | ||
103 | } | ||
104 | } | ||
105 | |||
106 | /* Put all following ones farer */ | ||
107 | if (MINTAUDIO_freqcount>0) { | ||
108 | for (i=MINTAUDIO_freqcount; i>p; i--) { | ||
109 | SDL_memcpy(&MINTAUDIO_frequencies[i], &MINTAUDIO_frequencies[i-1], sizeof(mint_frequency_t)); | ||
110 | } | ||
111 | } | ||
112 | |||
113 | /* And insert new one */ | ||
114 | MINTAUDIO_frequencies[p].frequency = frequency; | ||
115 | MINTAUDIO_frequencies[p].masterclock = clock; | ||
116 | MINTAUDIO_frequencies[p].predivisor = prediv; | ||
117 | MINTAUDIO_frequencies[p].gpio_bits = gpio_bits; | ||
118 | |||
119 | MINTAUDIO_freqcount++; | ||
120 | } | ||
121 | |||
122 | /* Search for the nearest frequency */ | ||
123 | int SDL_MintAudio_SearchFrequency(_THIS, int desired_freq) | ||
124 | { | ||
125 | int i; | ||
126 | |||
127 | /* Only 1 freq ? */ | ||
128 | if (MINTAUDIO_freqcount==1) { | ||
129 | return 0; | ||
130 | } | ||
131 | |||
132 | /* Check the array */ | ||
133 | for (i=0; i<MINTAUDIO_freqcount; i++) { | ||
134 | if (desired_freq >= ((MINTAUDIO_frequencies[i].frequency+ | ||
135 | MINTAUDIO_frequencies[i+1].frequency)>>1)) { | ||
136 | return i; | ||
137 | } | ||
138 | } | ||
139 | |||
140 | /* Not in the array, give the latest */ | ||
141 | return MINTAUDIO_freqcount-1; | ||
142 | } | ||
143 | |||
144 | /* Check if FPU is present */ | ||
145 | void SDL_MintAudio_CheckFpu(void) | ||
146 | { | ||
147 | long cookie_fpu; | ||
148 | |||
149 | SDL_MintAudio_hasfpu = 0; | ||
150 | if (Getcookie(C__FPU, &cookie_fpu) != C_FOUND) { | ||
151 | return; | ||
152 | } | ||
153 | switch ((cookie_fpu>>16)&0xfffe) { | ||
154 | case 2: | ||
155 | case 4: | ||
156 | case 6: | ||
157 | case 8: | ||
158 | case 16: | ||
159 | SDL_MintAudio_hasfpu = 1; | ||
160 | break; | ||
161 | } | ||
162 | } | ||
163 | |||
164 | /* The thread function, used under MiNT with xbios */ | ||
165 | int SDL_MintAudio_Thread(long param) | ||
166 | { | ||
167 | SndBufPtr pointers; | ||
168 | SDL_bool buffers_filled[2] = {SDL_FALSE, SDL_FALSE}; | ||
169 | |||
170 | SDL_MintAudio_thread_finished = SDL_FALSE; | ||
171 | while (!SDL_MintAudio_quit_thread) { | ||
172 | if (Buffptr(&pointers)!=0) | ||
173 | continue; | ||
174 | |||
175 | if (( (unsigned long)pointers.play>=(unsigned long)SDL_MintAudio_audiobuf[0]) | ||
176 | && ( (unsigned long)pointers.play<=(unsigned long)SDL_MintAudio_audiobuf[1])) | ||
177 | { | ||
178 | /* DMA is reading buffer #0, setup buffer #1 if not already done */ | ||
179 | if (!buffers_filled[1]) { | ||
180 | SDL_MintAudio_numbuf = 1; | ||
181 | SDL_MintAudio_Callback(); | ||
182 | Setbuffer(0, SDL_MintAudio_audiobuf[1], SDL_MintAudio_audiobuf[1] + SDL_MintAudio_audiosize); | ||
183 | buffers_filled[1]=SDL_TRUE; | ||
184 | buffers_filled[0]=SDL_FALSE; | ||
185 | } | ||
186 | } else { | ||
187 | /* DMA is reading buffer #1, setup buffer #0 if not already done */ | ||
188 | if (!buffers_filled[0]) { | ||
189 | SDL_MintAudio_numbuf = 0; | ||
190 | SDL_MintAudio_Callback(); | ||
191 | Setbuffer(0, SDL_MintAudio_audiobuf[0], SDL_MintAudio_audiobuf[0] + SDL_MintAudio_audiosize); | ||
192 | buffers_filled[0]=SDL_TRUE; | ||
193 | buffers_filled[1]=SDL_FALSE; | ||
194 | } | ||
195 | } | ||
196 | |||
197 | usleep(100); | ||
198 | } | ||
199 | SDL_MintAudio_thread_finished = SDL_TRUE; | ||
200 | return 0; | ||
201 | } | ||
202 | |||
203 | void SDL_MintAudio_WaitThread(void) | ||
204 | { | ||
205 | if (!SDL_MintAudio_mint_present) | ||
206 | return; | ||
207 | |||
208 | if (SDL_MintAudio_thread_finished) | ||
209 | return; | ||
210 | |||
211 | SDL_MintAudio_quit_thread = SDL_TRUE; | ||
212 | while (!SDL_MintAudio_thread_finished) { | ||
213 | Syield(); | ||
214 | } | ||
215 | } | ||
diff --git a/apps/plugins/sdl/src/audio/mint/SDL_mintaudio.h b/apps/plugins/sdl/src/audio/mint/SDL_mintaudio.h deleted file mode 100644 index ba6056ee3a..0000000000 --- a/apps/plugins/sdl/src/audio/mint/SDL_mintaudio.h +++ /dev/null | |||
@@ -1,121 +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 | /* | ||
25 | MiNT audio driver | ||
26 | |||
27 | Patrice Mandin | ||
28 | */ | ||
29 | |||
30 | #ifndef _SDL_mintaudio_h | ||
31 | #define _SDL_mintaudio_h | ||
32 | |||
33 | #include "../SDL_sysaudio.h" | ||
34 | #include "SDL_mintaudio_stfa.h" | ||
35 | |||
36 | /* Hidden "this" pointer for the audio functions */ | ||
37 | #define _THIS SDL_AudioDevice *this | ||
38 | |||
39 | /* 16 predivisors with 3 clocks max. */ | ||
40 | #define MINTAUDIO_maxfreqs (16*3) | ||
41 | |||
42 | typedef struct { | ||
43 | Uint32 frequency; | ||
44 | Uint32 masterclock; | ||
45 | Uint32 predivisor; | ||
46 | int gpio_bits; /* in case of external clock */ | ||
47 | } mint_frequency_t; | ||
48 | |||
49 | struct SDL_PrivateAudioData { | ||
50 | mint_frequency_t frequencies[MINTAUDIO_maxfreqs]; | ||
51 | int freq_count; /* Number of frequencies in the array */ | ||
52 | int numfreq; /* Number of selected frequency */ | ||
53 | }; | ||
54 | |||
55 | /* Old variable names */ | ||
56 | |||
57 | #define MINTAUDIO_frequencies (this->hidden->frequencies) | ||
58 | #define MINTAUDIO_freqcount (this->hidden->freq_count) | ||
59 | #define MINTAUDIO_numfreq (this->hidden->numfreq) | ||
60 | |||
61 | /* _MCH cookie (values>>16) */ | ||
62 | enum { | ||
63 | MCH_ST=0, | ||
64 | MCH_STE, | ||
65 | MCH_TT, | ||
66 | MCH_F30, | ||
67 | MCH_CLONE, | ||
68 | MCH_ARANYM | ||
69 | }; | ||
70 | |||
71 | /* Master clocks for replay frequencies */ | ||
72 | #define MASTERCLOCK_STE 8010666 /* Not sure of this one */ | ||
73 | #define MASTERCLOCK_TT 16107953 /* Not sure of this one */ | ||
74 | #define MASTERCLOCK_FALCON1 25175000 | ||
75 | #define MASTERCLOCK_FALCON2 32000000 /* Only usable for DSP56K */ | ||
76 | #define MASTERCLOCK_FALCONEXT -1 /* Clock on DSP56K port, unknown */ | ||
77 | #define MASTERCLOCK_44K 22579200 /* Standard clock for 44.1 Khz */ | ||
78 | #define MASTERCLOCK_48K 24576000 /* Standard clock for 48 Khz */ | ||
79 | |||
80 | /* Master clock predivisors */ | ||
81 | #define MASTERPREDIV_STE 160 | ||
82 | #define MASTERPREDIV_TT 320 | ||
83 | #define MASTERPREDIV_FALCON 256 | ||
84 | #define MASTERPREDIV_MILAN 256 | ||
85 | |||
86 | /* Variables */ | ||
87 | extern SDL_AudioDevice *SDL_MintAudio_device; | ||
88 | extern Uint8 *SDL_MintAudio_audiobuf[2]; /* Pointers to buffers */ | ||
89 | extern unsigned long SDL_MintAudio_audiosize; /* Length of audio buffer=spec->size */ | ||
90 | extern volatile unsigned short SDL_MintAudio_numbuf; /* Buffer to play */ | ||
91 | extern volatile unsigned short SDL_MintAudio_mutex; | ||
92 | extern cookie_stfa_t *SDL_MintAudio_stfa; | ||
93 | extern volatile unsigned long SDL_MintAudio_clocktics; | ||
94 | extern unsigned short SDL_MintAudio_hasfpu; /* To preserve fpu registers if needed */ | ||
95 | |||
96 | /* MiNT thread variables */ | ||
97 | extern SDL_bool SDL_MintAudio_mint_present; | ||
98 | extern SDL_bool SDL_MintAudio_quit_thread; | ||
99 | extern SDL_bool SDL_MintAudio_thread_finished; | ||
100 | extern long SDL_MintAudio_thread_pid; | ||
101 | |||
102 | /* Functions */ | ||
103 | void SDL_MintAudio_Callback(void); | ||
104 | void SDL_MintAudio_AddFrequency(_THIS, Uint32 frequency, Uint32 clock, | ||
105 | Uint32 prediv, int gpio_bits); | ||
106 | int SDL_MintAudio_SearchFrequency(_THIS, int desired_freq); | ||
107 | void SDL_MintAudio_CheckFpu(void); | ||
108 | |||
109 | /* MiNT thread functions */ | ||
110 | int SDL_MintAudio_Thread(long param); | ||
111 | void SDL_MintAudio_WaitThread(void); | ||
112 | |||
113 | /* ASM interrupt functions */ | ||
114 | void SDL_MintAudio_GsxbInterrupt(void); | ||
115 | void SDL_MintAudio_EmptyGsxbInterrupt(void); | ||
116 | void SDL_MintAudio_XbiosInterruptMeasureClock(void); | ||
117 | void SDL_MintAudio_XbiosInterrupt(void); | ||
118 | void SDL_MintAudio_Dma8Interrupt(void); | ||
119 | void SDL_MintAudio_StfaInterrupt(void); | ||
120 | |||
121 | #endif /* _SDL_mintaudio_h */ | ||
diff --git a/apps/plugins/sdl/src/audio/mint/SDL_mintaudio_dma8.c b/apps/plugins/sdl/src/audio/mint/SDL_mintaudio_dma8.c deleted file mode 100644 index 61feba3d64..0000000000 --- a/apps/plugins/sdl/src/audio/mint/SDL_mintaudio_dma8.c +++ /dev/null | |||
@@ -1,357 +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 | /* | ||
25 | MiNT audio driver | ||
26 | using DMA 8bits (hardware access) | ||
27 | |||
28 | Patrice Mandin | ||
29 | */ | ||
30 | |||
31 | /* Mint includes */ | ||
32 | #include <mint/osbind.h> | ||
33 | #include <mint/falcon.h> | ||
34 | #include <mint/cookie.h> | ||
35 | |||
36 | #include "SDL_audio.h" | ||
37 | #include "../SDL_audio_c.h" | ||
38 | #include "../SDL_sysaudio.h" | ||
39 | |||
40 | #include "../../video/ataricommon/SDL_atarimxalloc_c.h" | ||
41 | |||
42 | #include "SDL_mintaudio.h" | ||
43 | #include "SDL_mintaudio_dma8.h" | ||
44 | |||
45 | /*--- Defines ---*/ | ||
46 | |||
47 | #define MINT_AUDIO_DRIVER_NAME "mint_dma8" | ||
48 | |||
49 | /* Debug print info */ | ||
50 | #define DEBUG_NAME "audio:dma8: " | ||
51 | #if 0 | ||
52 | #define DEBUG_PRINT(what) \ | ||
53 | { \ | ||
54 | printf what; \ | ||
55 | } | ||
56 | #else | ||
57 | #define DEBUG_PRINT(what) | ||
58 | #endif | ||
59 | |||
60 | /*--- Static variables ---*/ | ||
61 | |||
62 | static long cookie_snd, cookie_mch; | ||
63 | |||
64 | /*--- Audio driver functions ---*/ | ||
65 | |||
66 | static void Mint_CloseAudio(_THIS); | ||
67 | static int Mint_OpenAudio(_THIS, SDL_AudioSpec *spec); | ||
68 | static void Mint_LockAudio(_THIS); | ||
69 | static void Mint_UnlockAudio(_THIS); | ||
70 | |||
71 | /* To check/init hardware audio */ | ||
72 | static int Mint_CheckAudio(_THIS, SDL_AudioSpec *spec); | ||
73 | |||
74 | /* Functions called in supervisor mode */ | ||
75 | static void Mint_InitDma(void); | ||
76 | static void Mint_StopReplay(void); | ||
77 | static void Mint_StartReplay(void); | ||
78 | |||
79 | /*--- Audio driver bootstrap functions ---*/ | ||
80 | |||
81 | static int Audio_Available(void) | ||
82 | { | ||
83 | const char *envr = SDL_getenv("SDL_AUDIODRIVER"); | ||
84 | |||
85 | /* Check if user asked a different audio driver */ | ||
86 | if ((envr) && (SDL_strcmp(envr, MINT_AUDIO_DRIVER_NAME)!=0)) { | ||
87 | DEBUG_PRINT((DEBUG_NAME "user asked a different audio driver\n")); | ||
88 | return 0; | ||
89 | } | ||
90 | |||
91 | /* Cookie _MCH present ? if not, assume ST machine */ | ||
92 | if (Getcookie(C__MCH, &cookie_mch) == C_NOTFOUND) { | ||
93 | cookie_mch = MCH_ST; | ||
94 | } | ||
95 | |||
96 | /* Cookie _SND present ? if not, assume ST machine */ | ||
97 | if (Getcookie(C__SND, &cookie_snd) == C_NOTFOUND) { | ||
98 | cookie_snd = SND_PSG; | ||
99 | } | ||
100 | |||
101 | /* Check if we have 8 bits audio */ | ||
102 | if ((cookie_snd & SND_8BIT)==0) { | ||
103 | DEBUG_PRINT((DEBUG_NAME "no 8 bits sound\n")); | ||
104 | return(0); | ||
105 | } | ||
106 | |||
107 | /* Check if audio is lockable */ | ||
108 | if (cookie_snd & SND_16BIT) { | ||
109 | if (Locksnd()!=1) { | ||
110 | DEBUG_PRINT((DEBUG_NAME "audio locked by other application\n")); | ||
111 | return(0); | ||
112 | } | ||
113 | |||
114 | Unlocksnd(); | ||
115 | } | ||
116 | |||
117 | DEBUG_PRINT((DEBUG_NAME "8 bits audio available!\n")); | ||
118 | return(1); | ||
119 | } | ||
120 | |||
121 | static void Audio_DeleteDevice(SDL_AudioDevice *device) | ||
122 | { | ||
123 | SDL_free(device->hidden); | ||
124 | SDL_free(device); | ||
125 | } | ||
126 | |||
127 | static SDL_AudioDevice *Audio_CreateDevice(int devindex) | ||
128 | { | ||
129 | SDL_AudioDevice *this; | ||
130 | |||
131 | /* Initialize all variables that we clean on shutdown */ | ||
132 | this = (SDL_AudioDevice *)SDL_malloc(sizeof(SDL_AudioDevice)); | ||
133 | if ( this ) { | ||
134 | SDL_memset(this, 0, (sizeof *this)); | ||
135 | this->hidden = (struct SDL_PrivateAudioData *) | ||
136 | SDL_malloc((sizeof *this->hidden)); | ||
137 | } | ||
138 | if ( (this == NULL) || (this->hidden == NULL) ) { | ||
139 | SDL_OutOfMemory(); | ||
140 | if ( this ) { | ||
141 | SDL_free(this); | ||
142 | } | ||
143 | return(0); | ||
144 | } | ||
145 | SDL_memset(this->hidden, 0, (sizeof *this->hidden)); | ||
146 | |||
147 | /* Set the function pointers */ | ||
148 | this->OpenAudio = Mint_OpenAudio; | ||
149 | this->CloseAudio = Mint_CloseAudio; | ||
150 | this->LockAudio = Mint_LockAudio; | ||
151 | this->UnlockAudio = Mint_UnlockAudio; | ||
152 | this->free = Audio_DeleteDevice; | ||
153 | |||
154 | return this; | ||
155 | } | ||
156 | |||
157 | AudioBootStrap MINTAUDIO_DMA8_bootstrap = { | ||
158 | MINT_AUDIO_DRIVER_NAME, "MiNT DMA 8 bits audio driver", | ||
159 | Audio_Available, Audio_CreateDevice | ||
160 | }; | ||
161 | |||
162 | static void Mint_LockAudio(_THIS) | ||
163 | { | ||
164 | Supexec(Mint_StopReplay); | ||
165 | } | ||
166 | |||
167 | static void Mint_UnlockAudio(_THIS) | ||
168 | { | ||
169 | Supexec(Mint_StartReplay); | ||
170 | } | ||
171 | |||
172 | static void Mint_CloseAudio(_THIS) | ||
173 | { | ||
174 | Supexec(Mint_StopReplay); | ||
175 | |||
176 | DEBUG_PRINT((DEBUG_NAME "closeaudio: replay stopped\n")); | ||
177 | |||
178 | /* Disable interrupt */ | ||
179 | Jdisint(MFP_DMASOUND); | ||
180 | |||
181 | DEBUG_PRINT((DEBUG_NAME "closeaudio: interrupt disabled\n")); | ||
182 | |||
183 | /* Wait if currently playing sound */ | ||
184 | while (SDL_MintAudio_mutex != 0) { | ||
185 | } | ||
186 | |||
187 | DEBUG_PRINT((DEBUG_NAME "closeaudio: no more interrupt running\n")); | ||
188 | |||
189 | /* Clear buffers */ | ||
190 | if (SDL_MintAudio_audiobuf[0]) { | ||
191 | Mfree(SDL_MintAudio_audiobuf[0]); | ||
192 | SDL_MintAudio_audiobuf[0] = SDL_MintAudio_audiobuf[1] = NULL; | ||
193 | } | ||
194 | |||
195 | DEBUG_PRINT((DEBUG_NAME "closeaudio: buffers freed\n")); | ||
196 | } | ||
197 | |||
198 | static int Mint_CheckAudio(_THIS, SDL_AudioSpec *spec) | ||
199 | { | ||
200 | int i, masterprediv, sfreq; | ||
201 | unsigned long masterclock; | ||
202 | |||
203 | DEBUG_PRINT((DEBUG_NAME "asked: %d bits, ",spec->format & 0x00ff)); | ||
204 | DEBUG_PRINT(("signed=%d, ", ((spec->format & 0x8000)!=0))); | ||
205 | DEBUG_PRINT(("big endian=%d, ", ((spec->format & 0x1000)!=0))); | ||
206 | DEBUG_PRINT(("channels=%d, ", spec->channels)); | ||
207 | DEBUG_PRINT(("freq=%d\n", spec->freq)); | ||
208 | |||
209 | if (spec->channels > 2) | ||
210 | spec->channels = 2; | ||
211 | |||
212 | /* Check formats available */ | ||
213 | spec->format = AUDIO_S8; | ||
214 | |||
215 | /* Calculate and select the closest frequency */ | ||
216 | sfreq=0; | ||
217 | masterclock=MASTERCLOCK_STE; | ||
218 | masterprediv=MASTERPREDIV_STE; | ||
219 | switch(cookie_mch>>16) { | ||
220 | /* | ||
221 | case MCH_STE: | ||
222 | masterclock=MASTERCLOCK_STE; | ||
223 | masterprediv=MASTERPREDIV_STE; | ||
224 | break; | ||
225 | */ | ||
226 | case MCH_TT: | ||
227 | masterclock=MASTERCLOCK_TT; | ||
228 | masterprediv=MASTERPREDIV_TT; | ||
229 | break; | ||
230 | case MCH_F30: | ||
231 | case MCH_ARANYM: | ||
232 | masterclock=MASTERCLOCK_FALCON1; | ||
233 | masterprediv=MASTERPREDIV_FALCON; | ||
234 | sfreq=1; | ||
235 | break; | ||
236 | } | ||
237 | |||
238 | MINTAUDIO_freqcount=0; | ||
239 | for (i=sfreq;i<4;i++) { | ||
240 | SDL_MintAudio_AddFrequency(this, masterclock/(masterprediv*(1<<i)), | ||
241 | masterclock, i-sfreq, -1); | ||
242 | } | ||
243 | |||
244 | #if 1 | ||
245 | for (i=0; i<MINTAUDIO_freqcount; i++) { | ||
246 | DEBUG_PRINT((DEBUG_NAME "freq %d: %lu Hz, clock %lu, prediv %d\n", | ||
247 | i, MINTAUDIO_frequencies[i].frequency, MINTAUDIO_frequencies[i].masterclock, | ||
248 | MINTAUDIO_frequencies[i].predivisor | ||
249 | )); | ||
250 | } | ||
251 | #endif | ||
252 | |||
253 | MINTAUDIO_numfreq=SDL_MintAudio_SearchFrequency(this, spec->freq); | ||
254 | spec->freq=MINTAUDIO_frequencies[MINTAUDIO_numfreq].frequency; | ||
255 | |||
256 | DEBUG_PRINT((DEBUG_NAME "obtained: %d bits, ",spec->format & 0x00ff)); | ||
257 | DEBUG_PRINT(("signed=%d, ", ((spec->format & 0x8000)!=0))); | ||
258 | DEBUG_PRINT(("big endian=%d, ", ((spec->format & 0x1000)!=0))); | ||
259 | DEBUG_PRINT(("channels=%d, ", spec->channels)); | ||
260 | DEBUG_PRINT(("freq=%d\n", spec->freq)); | ||
261 | |||
262 | return 0; | ||
263 | } | ||
264 | |||
265 | static int Mint_OpenAudio(_THIS, SDL_AudioSpec *spec) | ||
266 | { | ||
267 | SDL_MintAudio_device = this; | ||
268 | |||
269 | /* Check audio capabilities */ | ||
270 | if (Mint_CheckAudio(this, spec)==-1) { | ||
271 | return -1; | ||
272 | } | ||
273 | |||
274 | SDL_CalculateAudioSpec(spec); | ||
275 | |||
276 | /* Allocate memory for audio buffers in DMA-able RAM */ | ||
277 | DEBUG_PRINT((DEBUG_NAME "buffer size=%d\n", spec->size)); | ||
278 | |||
279 | SDL_MintAudio_audiobuf[0] = Atari_SysMalloc(spec->size *2, MX_STRAM); | ||
280 | if (SDL_MintAudio_audiobuf[0]==NULL) { | ||
281 | SDL_SetError("MINT_OpenAudio: Not enough memory for audio buffer"); | ||
282 | return (-1); | ||
283 | } | ||
284 | SDL_MintAudio_audiobuf[1] = SDL_MintAudio_audiobuf[0] + spec->size ; | ||
285 | SDL_MintAudio_numbuf=0; | ||
286 | SDL_memset(SDL_MintAudio_audiobuf[0], spec->silence, spec->size *2); | ||
287 | SDL_MintAudio_audiosize = spec->size; | ||
288 | SDL_MintAudio_mutex = 0; | ||
289 | |||
290 | DEBUG_PRINT((DEBUG_NAME "buffer 0 at 0x%08x\n", SDL_MintAudio_audiobuf[0])); | ||
291 | DEBUG_PRINT((DEBUG_NAME "buffer 1 at 0x%08x\n", SDL_MintAudio_audiobuf[1])); | ||
292 | |||
293 | SDL_MintAudio_CheckFpu(); | ||
294 | |||
295 | /* Set replay tracks */ | ||
296 | if (cookie_snd & SND_16BIT) { | ||
297 | Settracks(0,0); | ||
298 | Setmontracks(0); | ||
299 | } | ||
300 | |||
301 | Supexec(Mint_InitDma); | ||
302 | |||
303 | /* Set interrupt */ | ||
304 | Jdisint(MFP_DMASOUND); | ||
305 | Xbtimer(XB_TIMERA, 8, 1, SDL_MintAudio_Dma8Interrupt); | ||
306 | Jenabint(MFP_DMASOUND); | ||
307 | |||
308 | if (cookie_snd & SND_16BIT) { | ||
309 | if (Setinterrupt(SI_TIMERA, SI_PLAY)<0) { | ||
310 | DEBUG_PRINT((DEBUG_NAME "Setinterrupt() failed\n")); | ||
311 | } | ||
312 | } | ||
313 | |||
314 | Supexec(Mint_StartReplay); | ||
315 | |||
316 | return(1); /* We don't use threaded audio */ | ||
317 | } | ||
318 | |||
319 | /* Functions called in supervisor mode */ | ||
320 | |||
321 | static void Mint_InitDma(void) | ||
322 | { | ||
323 | unsigned long buffer; | ||
324 | unsigned char mode; | ||
325 | SDL_AudioDevice *this = SDL_MintAudio_device; | ||
326 | |||
327 | Mint_StopReplay(); | ||
328 | |||
329 | /* Set buffer */ | ||
330 | buffer = (unsigned long) SDL_MintAudio_audiobuf[SDL_MintAudio_numbuf]; | ||
331 | DMAAUDIO_IO.start_high = (buffer>>16) & 255; | ||
332 | DMAAUDIO_IO.start_mid = (buffer>>8) & 255; | ||
333 | DMAAUDIO_IO.start_low = buffer & 255; | ||
334 | |||
335 | buffer += SDL_MintAudio_audiosize; | ||
336 | DMAAUDIO_IO.end_high = (buffer>>16) & 255; | ||
337 | DMAAUDIO_IO.end_mid = (buffer>>8) & 255; | ||
338 | DMAAUDIO_IO.end_low = buffer & 255; | ||
339 | |||
340 | mode = 3-MINTAUDIO_frequencies[MINTAUDIO_numfreq].predivisor; | ||
341 | if (this->spec.channels==1) { | ||
342 | mode |= 1<<7; | ||
343 | } | ||
344 | DMAAUDIO_IO.sound_ctrl = mode; | ||
345 | } | ||
346 | |||
347 | static void Mint_StopReplay(void) | ||
348 | { | ||
349 | /* Stop replay */ | ||
350 | DMAAUDIO_IO.control=0; | ||
351 | } | ||
352 | |||
353 | static void Mint_StartReplay(void) | ||
354 | { | ||
355 | /* Start replay */ | ||
356 | DMAAUDIO_IO.control=3; | ||
357 | } | ||
diff --git a/apps/plugins/sdl/src/audio/mint/SDL_mintaudio_dma8.h b/apps/plugins/sdl/src/audio/mint/SDL_mintaudio_dma8.h deleted file mode 100644 index a52e5db7a5..0000000000 --- a/apps/plugins/sdl/src/audio/mint/SDL_mintaudio_dma8.h +++ /dev/null | |||
@@ -1,85 +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 | /* | ||
25 | DMA 8bits and Falcon Codec audio definitions | ||
26 | |||
27 | Patrice Mandin, Didier Méquignon | ||
28 | */ | ||
29 | |||
30 | #ifndef _SDL_mintaudio_dma8_h | ||
31 | #define _SDL_mintaudio_dma8_h | ||
32 | |||
33 | #define DMAAUDIO_IO_BASE (0xffff8900) | ||
34 | struct DMAAUDIO_IO_S { | ||
35 | unsigned char int_ctrl; | ||
36 | unsigned char control; | ||
37 | |||
38 | unsigned char dummy1; | ||
39 | unsigned char start_high; | ||
40 | unsigned char dummy2; | ||
41 | unsigned char start_mid; | ||
42 | unsigned char dummy3; | ||
43 | unsigned char start_low; | ||
44 | |||
45 | unsigned char dummy4; | ||
46 | unsigned char cur_high; | ||
47 | unsigned char dummy5; | ||
48 | unsigned char cur_mid; | ||
49 | unsigned char dummy6; | ||
50 | unsigned char cur_low; | ||
51 | |||
52 | unsigned char dummy7; | ||
53 | unsigned char end_high; | ||
54 | unsigned char dummy8; | ||
55 | unsigned char end_mid; | ||
56 | unsigned char dummy9; | ||
57 | unsigned char end_low; | ||
58 | |||
59 | unsigned char dummy10[12]; | ||
60 | |||
61 | unsigned char track_ctrl; /* CODEC only */ | ||
62 | unsigned char sound_ctrl; | ||
63 | unsigned short sound_data; | ||
64 | unsigned short sound_mask; | ||
65 | |||
66 | unsigned char dummy11[10]; | ||
67 | |||
68 | unsigned short dev_ctrl; | ||
69 | unsigned short dest_ctrl; | ||
70 | unsigned short sync_div; | ||
71 | unsigned char track_rec; | ||
72 | unsigned char adderin_input; | ||
73 | unsigned char channel_input; | ||
74 | unsigned char channel_amplification; | ||
75 | unsigned char channel_reduction; | ||
76 | |||
77 | unsigned char dummy12[6]; | ||
78 | |||
79 | unsigned char data_direction; | ||
80 | unsigned char dummy13; | ||
81 | unsigned char dev_data; | ||
82 | }; | ||
83 | #define DMAAUDIO_IO ((*(volatile struct DMAAUDIO_IO_S *)DMAAUDIO_IO_BASE)) | ||
84 | |||
85 | #endif /* _SDL_mintaudio_dma8_h */ | ||
diff --git a/apps/plugins/sdl/src/audio/mint/SDL_mintaudio_gsxb.c b/apps/plugins/sdl/src/audio/mint/SDL_mintaudio_gsxb.c deleted file mode 100644 index 8d7716a137..0000000000 --- a/apps/plugins/sdl/src/audio/mint/SDL_mintaudio_gsxb.c +++ /dev/null | |||
@@ -1,436 +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 | /* | ||
25 | MiNT audio driver | ||
26 | using XBIOS functions (GSXB compatible driver) | ||
27 | |||
28 | Patrice Mandin | ||
29 | */ | ||
30 | |||
31 | /* Mint includes */ | ||
32 | #include <mint/osbind.h> | ||
33 | #include <mint/falcon.h> | ||
34 | #include <mint/cookie.h> | ||
35 | |||
36 | #include "SDL_audio.h" | ||
37 | #include "../SDL_audio_c.h" | ||
38 | #include "../SDL_sysaudio.h" | ||
39 | |||
40 | #include "../../video/ataricommon/SDL_atarimxalloc_c.h" | ||
41 | |||
42 | #include "SDL_mintaudio.h" | ||
43 | #include "SDL_mintaudio_gsxb.h" | ||
44 | |||
45 | /*--- Defines ---*/ | ||
46 | |||
47 | #define MINT_AUDIO_DRIVER_NAME "mint_gsxb" | ||
48 | |||
49 | /* Debug print info */ | ||
50 | #define DEBUG_NAME "audio:gsxb: " | ||
51 | #if 0 | ||
52 | #define DEBUG_PRINT(what) \ | ||
53 | { \ | ||
54 | printf what; \ | ||
55 | } | ||
56 | #else | ||
57 | #define DEBUG_PRINT(what) | ||
58 | #endif | ||
59 | |||
60 | /*--- Static variables ---*/ | ||
61 | |||
62 | static long cookie_snd, cookie_gsxb; | ||
63 | |||
64 | /*--- Audio driver functions ---*/ | ||
65 | |||
66 | static void Mint_CloseAudio(_THIS); | ||
67 | static int Mint_OpenAudio(_THIS, SDL_AudioSpec *spec); | ||
68 | static void Mint_LockAudio(_THIS); | ||
69 | static void Mint_UnlockAudio(_THIS); | ||
70 | |||
71 | /* To check/init hardware audio */ | ||
72 | static int Mint_CheckAudio(_THIS, SDL_AudioSpec *spec); | ||
73 | static void Mint_InitAudio(_THIS, SDL_AudioSpec *spec); | ||
74 | |||
75 | /* GSXB callbacks */ | ||
76 | static void Mint_GsxbInterrupt(void); | ||
77 | static void Mint_GsxbNullInterrupt(void); | ||
78 | |||
79 | /*--- Audio driver bootstrap functions ---*/ | ||
80 | |||
81 | static int Audio_Available(void) | ||
82 | { | ||
83 | const char *envr = SDL_getenv("SDL_AUDIODRIVER"); | ||
84 | |||
85 | /* Check if user asked a different audio driver */ | ||
86 | if ((envr) && (SDL_strcmp(envr, MINT_AUDIO_DRIVER_NAME)!=0)) { | ||
87 | DEBUG_PRINT((DEBUG_NAME "user asked a different audio driver\n")); | ||
88 | return(0); | ||
89 | } | ||
90 | |||
91 | /* Cookie _SND present ? if not, assume ST machine */ | ||
92 | if (Getcookie(C__SND, &cookie_snd) == C_NOTFOUND) { | ||
93 | cookie_snd = SND_PSG; | ||
94 | } | ||
95 | |||
96 | /* Check if we have 16 bits audio */ | ||
97 | if ((cookie_snd & SND_16BIT)==0) { | ||
98 | DEBUG_PRINT((DEBUG_NAME "no 16 bits sound\n")); | ||
99 | return(0); | ||
100 | } | ||
101 | |||
102 | /* Cookie GSXB present ? */ | ||
103 | cookie_gsxb = (Getcookie(C_GSXB, &cookie_gsxb) == C_FOUND); | ||
104 | |||
105 | /* Is it GSXB ? */ | ||
106 | if (((cookie_snd & SND_GSXB)==0) || (cookie_gsxb==0)) { | ||
107 | DEBUG_PRINT((DEBUG_NAME "no GSXB audio\n")); | ||
108 | return(0); | ||
109 | } | ||
110 | |||
111 | /* Check if audio is lockable */ | ||
112 | if (Locksnd()!=1) { | ||
113 | DEBUG_PRINT((DEBUG_NAME "audio locked by other application\n")); | ||
114 | return(0); | ||
115 | } | ||
116 | |||
117 | Unlocksnd(); | ||
118 | |||
119 | DEBUG_PRINT((DEBUG_NAME "GSXB audio available!\n")); | ||
120 | return(1); | ||
121 | } | ||
122 | |||
123 | static void Audio_DeleteDevice(SDL_AudioDevice *device) | ||
124 | { | ||
125 | SDL_free(device->hidden); | ||
126 | SDL_free(device); | ||
127 | } | ||
128 | |||
129 | static SDL_AudioDevice *Audio_CreateDevice(int devindex) | ||
130 | { | ||
131 | SDL_AudioDevice *this; | ||
132 | |||
133 | /* Initialize all variables that we clean on shutdown */ | ||
134 | this = (SDL_AudioDevice *)SDL_malloc(sizeof(SDL_AudioDevice)); | ||
135 | if ( this ) { | ||
136 | SDL_memset(this, 0, (sizeof *this)); | ||
137 | this->hidden = (struct SDL_PrivateAudioData *) | ||
138 | SDL_malloc((sizeof *this->hidden)); | ||
139 | } | ||
140 | if ( (this == NULL) || (this->hidden == NULL) ) { | ||
141 | SDL_OutOfMemory(); | ||
142 | if ( this ) { | ||
143 | SDL_free(this); | ||
144 | } | ||
145 | return(0); | ||
146 | } | ||
147 | SDL_memset(this->hidden, 0, (sizeof *this->hidden)); | ||
148 | |||
149 | /* Set the function pointers */ | ||
150 | this->OpenAudio = Mint_OpenAudio; | ||
151 | this->CloseAudio = Mint_CloseAudio; | ||
152 | this->LockAudio = Mint_LockAudio; | ||
153 | this->UnlockAudio = Mint_UnlockAudio; | ||
154 | this->free = Audio_DeleteDevice; | ||
155 | |||
156 | return this; | ||
157 | } | ||
158 | |||
159 | AudioBootStrap MINTAUDIO_GSXB_bootstrap = { | ||
160 | MINT_AUDIO_DRIVER_NAME, "MiNT GSXB audio driver", | ||
161 | Audio_Available, Audio_CreateDevice | ||
162 | }; | ||
163 | |||
164 | static void Mint_LockAudio(_THIS) | ||
165 | { | ||
166 | /* Stop replay */ | ||
167 | Buffoper(0); | ||
168 | } | ||
169 | |||
170 | static void Mint_UnlockAudio(_THIS) | ||
171 | { | ||
172 | /* Restart replay */ | ||
173 | Buffoper(SB_PLA_ENA|SB_PLA_RPT); | ||
174 | } | ||
175 | |||
176 | static void Mint_CloseAudio(_THIS) | ||
177 | { | ||
178 | /* Stop replay */ | ||
179 | Buffoper(0); | ||
180 | |||
181 | /* Uninstall interrupt */ | ||
182 | if (NSetinterrupt(2, SI_NONE, Mint_GsxbNullInterrupt)<0) { | ||
183 | DEBUG_PRINT((DEBUG_NAME "NSetinterrupt() failed in close\n")); | ||
184 | } | ||
185 | |||
186 | /* Wait if currently playing sound */ | ||
187 | while (SDL_MintAudio_mutex != 0) { | ||
188 | } | ||
189 | |||
190 | /* Clear buffers */ | ||
191 | if (SDL_MintAudio_audiobuf[0]) { | ||
192 | Mfree(SDL_MintAudio_audiobuf[0]); | ||
193 | SDL_MintAudio_audiobuf[0] = SDL_MintAudio_audiobuf[1] = NULL; | ||
194 | } | ||
195 | |||
196 | /* Unlock sound system */ | ||
197 | Unlocksnd(); | ||
198 | } | ||
199 | |||
200 | static int Mint_CheckAudio(_THIS, SDL_AudioSpec *spec) | ||
201 | { | ||
202 | long snd_format = 0; | ||
203 | int i, resolution, format_signed, format_bigendian; | ||
204 | Uint16 test_format = SDL_FirstAudioFormat(spec->format); | ||
205 | int valid_datatype = 0; | ||
206 | |||
207 | resolution = spec->format & 0x00ff; | ||
208 | format_signed = ((spec->format & 0x8000)!=0); | ||
209 | format_bigendian = ((spec->format & 0x1000)!=0); | ||
210 | |||
211 | DEBUG_PRINT((DEBUG_NAME "asked: %d bits, ",spec->format & 0x00ff)); | ||
212 | DEBUG_PRINT(("signed=%d, ", ((spec->format & 0x8000)!=0))); | ||
213 | DEBUG_PRINT(("big endian=%d, ", ((spec->format & 0x1000)!=0))); | ||
214 | DEBUG_PRINT(("channels=%d, ", spec->channels)); | ||
215 | DEBUG_PRINT(("freq=%d\n", spec->freq)); | ||
216 | |||
217 | if (spec->channels > 2) { | ||
218 | spec->channels = 2; /* no more than stereo! */ | ||
219 | } | ||
220 | |||
221 | while ((!valid_datatype) && (test_format)) { | ||
222 | /* Check formats available */ | ||
223 | snd_format = Sndstatus(SND_QUERYFORMATS); | ||
224 | spec->format = test_format; | ||
225 | resolution = spec->format & 0xff; | ||
226 | format_signed = (spec->format & (1<<15)); | ||
227 | format_bigendian = (spec->format & (1<<12)); | ||
228 | switch (test_format) { | ||
229 | case AUDIO_U8: | ||
230 | case AUDIO_S8: | ||
231 | if (snd_format & SND_FORMAT8) { | ||
232 | valid_datatype = 1; | ||
233 | snd_format = Sndstatus(SND_QUERY8BIT); | ||
234 | } | ||
235 | break; | ||
236 | |||
237 | case AUDIO_U16LSB: | ||
238 | case AUDIO_S16LSB: | ||
239 | case AUDIO_U16MSB: | ||
240 | case AUDIO_S16MSB: | ||
241 | if (snd_format & SND_FORMAT16) { | ||
242 | valid_datatype = 1; | ||
243 | snd_format = Sndstatus(SND_QUERY16BIT); | ||
244 | } | ||
245 | break; | ||
246 | |||
247 | default: | ||
248 | test_format = SDL_NextAudioFormat(); | ||
249 | break; | ||
250 | } | ||
251 | } | ||
252 | |||
253 | if (!valid_datatype) { | ||
254 | SDL_SetError("Unsupported audio format"); | ||
255 | return (-1); | ||
256 | } | ||
257 | |||
258 | /* Check signed/unsigned format */ | ||
259 | if (format_signed) { | ||
260 | if (snd_format & SND_FORMATSIGNED) { | ||
261 | /* Ok */ | ||
262 | } else if (snd_format & SND_FORMATUNSIGNED) { | ||
263 | /* Give unsigned format */ | ||
264 | spec->format = spec->format & (~0x8000); | ||
265 | } | ||
266 | } else { | ||
267 | if (snd_format & SND_FORMATUNSIGNED) { | ||
268 | /* Ok */ | ||
269 | } else if (snd_format & SND_FORMATSIGNED) { | ||
270 | /* Give signed format */ | ||
271 | spec->format |= 0x8000; | ||
272 | } | ||
273 | } | ||
274 | |||
275 | if (format_bigendian) { | ||
276 | if (snd_format & SND_FORMATBIGENDIAN) { | ||
277 | /* Ok */ | ||
278 | } else if (snd_format & SND_FORMATLITTLEENDIAN) { | ||
279 | /* Give little endian format */ | ||
280 | spec->format = spec->format & (~0x1000); | ||
281 | } | ||
282 | } else { | ||
283 | if (snd_format & SND_FORMATLITTLEENDIAN) { | ||
284 | /* Ok */ | ||
285 | } else if (snd_format & SND_FORMATBIGENDIAN) { | ||
286 | /* Give big endian format */ | ||
287 | spec->format |= 0x1000; | ||
288 | } | ||
289 | } | ||
290 | |||
291 | /* Calculate and select the closest frequency */ | ||
292 | MINTAUDIO_freqcount=0; | ||
293 | for (i=1;i<4;i++) { | ||
294 | SDL_MintAudio_AddFrequency(this, | ||
295 | MASTERCLOCK_44K/(MASTERPREDIV_MILAN*(1<<i)), MASTERCLOCK_44K, | ||
296 | (1<<i)-1, -1); | ||
297 | } | ||
298 | |||
299 | #if 1 | ||
300 | for (i=0; i<MINTAUDIO_freqcount; i++) { | ||
301 | DEBUG_PRINT((DEBUG_NAME "freq %d: %lu Hz, clock %lu, prediv %d\n", | ||
302 | i, MINTAUDIO_frequencies[i].frequency, MINTAUDIO_frequencies[i].masterclock, | ||
303 | MINTAUDIO_frequencies[i].predivisor | ||
304 | )); | ||
305 | } | ||
306 | #endif | ||
307 | |||
308 | MINTAUDIO_numfreq=SDL_MintAudio_SearchFrequency(this, spec->freq); | ||
309 | spec->freq=MINTAUDIO_frequencies[MINTAUDIO_numfreq].frequency; | ||
310 | |||
311 | DEBUG_PRINT((DEBUG_NAME "obtained: %d bits, ",spec->format & 0x00ff)); | ||
312 | DEBUG_PRINT(("signed=%d, ", ((spec->format & 0x8000)!=0))); | ||
313 | DEBUG_PRINT(("big endian=%d, ", ((spec->format & 0x1000)!=0))); | ||
314 | DEBUG_PRINT(("channels=%d, ", spec->channels)); | ||
315 | DEBUG_PRINT(("freq=%d\n", spec->freq)); | ||
316 | |||
317 | return 0; | ||
318 | } | ||
319 | |||
320 | static void Mint_InitAudio(_THIS, SDL_AudioSpec *spec) | ||
321 | { | ||
322 | int channels_mode, prediv; | ||
323 | void *buffer; | ||
324 | |||
325 | /* Stop currently playing sound */ | ||
326 | Buffoper(0); | ||
327 | |||
328 | /* Set replay tracks */ | ||
329 | Settracks(0,0); | ||
330 | Setmontracks(0); | ||
331 | |||
332 | /* Select replay format */ | ||
333 | switch (spec->format & 0xff) { | ||
334 | case 8: | ||
335 | if (spec->channels==2) { | ||
336 | channels_mode=STEREO8; | ||
337 | } else { | ||
338 | channels_mode=MONO8; | ||
339 | } | ||
340 | break; | ||
341 | case 16: | ||
342 | if (spec->channels==2) { | ||
343 | channels_mode=STEREO16; | ||
344 | } else { | ||
345 | channels_mode=MONO16; | ||
346 | } | ||
347 | break; | ||
348 | default: | ||
349 | channels_mode=STEREO16; | ||
350 | break; | ||
351 | } | ||
352 | if (Setmode(channels_mode)<0) { | ||
353 | DEBUG_PRINT((DEBUG_NAME "Setmode() failed\n")); | ||
354 | } | ||
355 | |||
356 | prediv = MINTAUDIO_frequencies[MINTAUDIO_numfreq].predivisor; | ||
357 | Devconnect(DMAPLAY, DAC, CLKEXT, prediv, 1); | ||
358 | |||
359 | /* Set buffer */ | ||
360 | buffer = SDL_MintAudio_audiobuf[SDL_MintAudio_numbuf]; | ||
361 | if (Setbuffer(0, buffer, buffer + spec->size)<0) { | ||
362 | DEBUG_PRINT((DEBUG_NAME "Setbuffer() failed\n")); | ||
363 | } | ||
364 | |||
365 | /* Install interrupt */ | ||
366 | if (NSetinterrupt(2, SI_PLAY, Mint_GsxbInterrupt)<0) { | ||
367 | DEBUG_PRINT((DEBUG_NAME "NSetinterrupt() failed\n")); | ||
368 | } | ||
369 | |||
370 | /* Go */ | ||
371 | Buffoper(SB_PLA_ENA|SB_PLA_RPT); | ||
372 | DEBUG_PRINT((DEBUG_NAME "hardware initialized\n")); | ||
373 | } | ||
374 | |||
375 | static int Mint_OpenAudio(_THIS, SDL_AudioSpec *spec) | ||
376 | { | ||
377 | /* Lock sound system */ | ||
378 | if (Locksnd()!=1) { | ||
379 | SDL_SetError("Mint_OpenAudio: Audio system already in use"); | ||
380 | return(-1); | ||
381 | } | ||
382 | |||
383 | SDL_MintAudio_device = this; | ||
384 | |||
385 | /* Check audio capabilities */ | ||
386 | if (Mint_CheckAudio(this, spec)==-1) { | ||
387 | return -1; | ||
388 | } | ||
389 | |||
390 | SDL_CalculateAudioSpec(spec); | ||
391 | |||
392 | /* Allocate memory for audio buffers in DMA-able RAM */ | ||
393 | DEBUG_PRINT((DEBUG_NAME "buffer size=%d\n", spec->size)); | ||
394 | |||
395 | SDL_MintAudio_audiobuf[0] = Atari_SysMalloc(spec->size *2, MX_STRAM); | ||
396 | if (SDL_MintAudio_audiobuf[0]==NULL) { | ||
397 | SDL_SetError("MINT_OpenAudio: Not enough memory for audio buffer"); | ||
398 | return (-1); | ||
399 | } | ||
400 | SDL_MintAudio_audiobuf[1] = SDL_MintAudio_audiobuf[0] + spec->size ; | ||
401 | SDL_MintAudio_numbuf=0; | ||
402 | SDL_memset(SDL_MintAudio_audiobuf[0], spec->silence, spec->size *2); | ||
403 | SDL_MintAudio_audiosize = spec->size; | ||
404 | SDL_MintAudio_mutex = 0; | ||
405 | |||
406 | DEBUG_PRINT((DEBUG_NAME "buffer 0 at 0x%08x\n", SDL_MintAudio_audiobuf[0])); | ||
407 | DEBUG_PRINT((DEBUG_NAME "buffer 1 at 0x%08x\n", SDL_MintAudio_audiobuf[1])); | ||
408 | |||
409 | SDL_MintAudio_CheckFpu(); | ||
410 | |||
411 | /* Setup audio hardware */ | ||
412 | Mint_InitAudio(this, spec); | ||
413 | |||
414 | return(1); /* We don't use threaded audio */ | ||
415 | } | ||
416 | |||
417 | static void Mint_GsxbInterrupt(void) | ||
418 | { | ||
419 | Uint8 *newbuf; | ||
420 | |||
421 | if (SDL_MintAudio_mutex) | ||
422 | return; | ||
423 | |||
424 | SDL_MintAudio_mutex=1; | ||
425 | |||
426 | SDL_MintAudio_numbuf ^= 1; | ||
427 | SDL_MintAudio_Callback(); | ||
428 | newbuf = SDL_MintAudio_audiobuf[SDL_MintAudio_numbuf]; | ||
429 | Setbuffer(0, newbuf, newbuf + SDL_MintAudio_audiosize); | ||
430 | |||
431 | SDL_MintAudio_mutex=0; | ||
432 | } | ||
433 | |||
434 | static void Mint_GsxbNullInterrupt(void) | ||
435 | { | ||
436 | } | ||
diff --git a/apps/plugins/sdl/src/audio/mint/SDL_mintaudio_gsxb.h b/apps/plugins/sdl/src/audio/mint/SDL_mintaudio_gsxb.h deleted file mode 100644 index aee26b7ee3..0000000000 --- a/apps/plugins/sdl/src/audio/mint/SDL_mintaudio_gsxb.h +++ /dev/null | |||
@@ -1,104 +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 Lesser General Public | ||
7 | License as published by the Free Software Foundation; either | ||
8 | version 2.1 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 | Lesser General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU Lesser General Public | ||
16 | License along with this library; if not, write to the Free Software | ||
17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
18 | |||
19 | Sam Lantinga | ||
20 | slouken@libsdl.org | ||
21 | */ | ||
22 | #include "SDL_config.h" | ||
23 | |||
24 | /* | ||
25 | * GSXB audio definitions | ||
26 | * | ||
27 | * Patrice Mandin | ||
28 | */ | ||
29 | |||
30 | #ifndef _SDL_mintaudio_gsxb_h | ||
31 | #define _SDL_mintaudio_gsxb_h | ||
32 | |||
33 | #include <mint/falcon.h> /* for trap_14_xxx macros */ | ||
34 | |||
35 | /* Bit 5 in cookie _SND */ | ||
36 | |||
37 | #define SND_GSXB (1<<5) | ||
38 | |||
39 | /* NSoundcmd modes */ | ||
40 | |||
41 | #define SETRATE 7 /* Set sample rate */ | ||
42 | #define SET8BITFORMAT 8 /* 8 bits format */ | ||
43 | #define SET16BITFORMAT 9 /* 16 bits format */ | ||
44 | #define SET24BITFORMAT 10 /* 24 bits format */ | ||
45 | #define SET32BITFORMAT 11 /* 32 bits format */ | ||
46 | #define LTATTEN_MASTER 12 /* Attenuation */ | ||
47 | #define RTATTEN_MASTER 13 | ||
48 | #define LTATTEN_MICIN 14 | ||
49 | #define RTATTEN_MICIN 15 | ||
50 | #define LTATTEN_FMGEN 16 | ||
51 | #define RTATTEN_FMGEN 17 | ||
52 | #define LTATTEN_LINEIN 18 | ||
53 | #define RTATTEN_LINEIN 19 | ||
54 | #define LTATTEN_CDIN 20 | ||
55 | #define RTATTEN_CDIN 21 | ||
56 | #define LTATTEN_VIDIN 22 | ||
57 | #define RTATTEN_VIDIN 23 | ||
58 | #define LTATTEN_AUXIN 24 | ||
59 | #define RTATTEN_AUXIN 25 | ||
60 | |||
61 | /* Setmode modes */ | ||
62 | |||
63 | #define MONO16 3 | ||
64 | #define STEREO24 4 | ||
65 | #define STEREO32 5 | ||
66 | #define MONO24 6 | ||
67 | #define MONO32 7 | ||
68 | |||
69 | /* Sndstatus modes */ | ||
70 | |||
71 | #define SND_QUERYFORMATS 2 | ||
72 | #define SND_QUERYMIXERS 3 | ||
73 | #define SND_QUERYSOURCES 4 | ||
74 | #define SND_QUERYDUPLEX 5 | ||
75 | #define SND_QUERY8BIT 8 | ||
76 | #define SND_QUERY16BIT 9 | ||
77 | #define SND_QUERY24BIT 10 | ||
78 | #define SND_QUERY32BIT 11 | ||
79 | |||
80 | #define SND_FORMAT8 (1<<0) | ||
81 | #define SND_FORMAT16 (1<<1) | ||
82 | #define SND_FORMAT24 (1<<2) | ||
83 | #define SND_FORMAT32 (1<<3) | ||
84 | |||
85 | #define SND_FORMATSIGNED (1<<0) | ||
86 | #define SND_FORMATUNSIGNED (1<<1) | ||
87 | #define SND_FORMATBIGENDIAN (1<<2) | ||
88 | #define SND_FORMATLITTLEENDIAN (1<<3) | ||
89 | |||
90 | /* Devconnect prescalers */ | ||
91 | |||
92 | #define CLK_44K 1 | ||
93 | #define CLK_22K 3 | ||
94 | #define CLK_11K 7 | ||
95 | |||
96 | /* Extra xbios functions */ | ||
97 | |||
98 | #define NSoundcmd(mode,data,data2) \ | ||
99 | (long)trap_14_wwl((short)130,(short)(mode),(short)(data),(long)(data2)) | ||
100 | #define NSetinterrupt(src_inter,cause,inth_addr) \ | ||
101 | (long)trap_14_wwwl((short)135,(short)(src_inter),(short)(cause), \ | ||
102 | (long)(inth_addr)) | ||
103 | |||
104 | #endif /* _SDL_mintaudio_gsxb_h */ | ||
diff --git a/apps/plugins/sdl/src/audio/mint/SDL_mintaudio_it.S b/apps/plugins/sdl/src/audio/mint/SDL_mintaudio_it.S deleted file mode 100644 index a2ecac4c65..0000000000 --- a/apps/plugins/sdl/src/audio/mint/SDL_mintaudio_it.S +++ /dev/null | |||
@@ -1,386 +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 | |||
23 | /* | ||
24 | Audio interrupts | ||
25 | |||
26 | Patrice Mandin, Didier Méquignon | ||
27 | */ | ||
28 | |||
29 | .text | ||
30 | |||
31 | .globl _SDL_MintAudio_Callback | ||
32 | |||
33 | .globl _SDL_MintAudio_XbiosInterrupt | ||
34 | .globl _SDL_MintAudio_XbiosInterruptMeasureClock | ||
35 | .globl _SDL_MintAudio_Dma8Interrupt | ||
36 | .globl _SDL_MintAudio_StfaInterrupt | ||
37 | |||
38 | .globl _SDL_MintAudio_mutex | ||
39 | .globl _SDL_MintAudio_audiobuf | ||
40 | .globl _SDL_MintAudio_numbuf | ||
41 | .globl _SDL_MintAudio_audiosize | ||
42 | .globl _SDL_MintAudio_clocktics | ||
43 | .globl _SDL_MintAudio_hasfpu | ||
44 | |||
45 | .globl _SDL_MintAudio_stfa | ||
46 | |||
47 | /* | ||
48 | How it works: | ||
49 | - Audio is playing buffer #0 (resp. #1) | ||
50 | - We must calculate a sample in buffer #1 (resp. #0) | ||
51 | so we first call the callback to do it | ||
52 | - Then we swap the buffers | ||
53 | */ | ||
54 | |||
55 | #define savptr 0x4a2 | ||
56 | #define savamt 0x46 | ||
57 | |||
58 | /*--- Save/restore FPU context ---*/ | ||
59 | |||
60 | #if defined(__mcoldfire__) | ||
61 | |||
62 | #define SAVE_FPU_CONTEXT \ | ||
63 | lea sp@(-216),sp; \ | ||
64 | fsave sp@; \ | ||
65 | fmovel fpiar,sp@-; \ | ||
66 | lea sp@(-64),sp; \ | ||
67 | fmovemd fp0-fp7,sp@ | ||
68 | |||
69 | #define RESTORE_FPU_CONTEXT \ | ||
70 | fmovemd sp@,fp0-fp7; \ | ||
71 | lea sp@(64),sp; \ | ||
72 | fmovel sp@+,fpiar; \ | ||
73 | frestore sp@; \ | ||
74 | lea sp@(216),sp | ||
75 | |||
76 | #else | ||
77 | |||
78 | #define SAVE_FPU_CONTEXT \ | ||
79 | .chip 68k/68881; \ | ||
80 | fsave sp@-; \ | ||
81 | fmoveml fpcr/fpsr/fpiar,sp@-; \ | ||
82 | fmovemx fp0-fp7,sp@-; \ | ||
83 | .chip 68k | ||
84 | |||
85 | #define RESTORE_FPU_CONTEXT \ | ||
86 | .chip 68k/68881; \ | ||
87 | fmovemx sp@+,fp0-fp7; \ | ||
88 | fmoveml sp@+,fpcr/fpsr/fpiar; \ | ||
89 | frestore sp@+; \ | ||
90 | .chip 68k | ||
91 | |||
92 | #endif | ||
93 | |||
94 | /*--- Xbios interrupt vector to measure Falcon external clock ---*/ | ||
95 | |||
96 | _SDL_MintAudio_XbiosInterruptMeasureClock: /* 1 mS */ | ||
97 | #if defined(__mcoldfire__) | ||
98 | movel d0,sp@- | ||
99 | |||
100 | moveql #0,d0 | ||
101 | btst d0,0xFFFF8901:w /* state DMA sound */ | ||
102 | #else | ||
103 | btst #0,0xFFFF8901:w /* state DMA sound */ | ||
104 | #endif | ||
105 | beqs SDL_MintAudio_EndIntMeasure | ||
106 | addql #1,_SDL_MintAudio_clocktics | ||
107 | SDL_MintAudio_EndIntMeasure: | ||
108 | #if defined(__mcoldfire__) | ||
109 | moveql #5,d0 | ||
110 | bclr d0,0xFFFFFA0F:w /* Clear service bit */ | ||
111 | |||
112 | movel sp@+,d0 | ||
113 | #else | ||
114 | bclr #5,0xFFFFFA0F:w /* Clear service bit */ | ||
115 | #endif | ||
116 | rte | ||
117 | |||
118 | /*--- Xbios interrupt vector ---*/ | ||
119 | |||
120 | _SDL_MintAudio_XbiosInterrupt: | ||
121 | #if defined(__mcoldfire__) | ||
122 | lea sp@(-60),sp | ||
123 | moveml d0-d7/a0-a6,sp@ | ||
124 | #else | ||
125 | moveml d0-d7/a0-a6,sp@- | ||
126 | #endif | ||
127 | |||
128 | /* Reenable interrupts, so other interrupts can work */ | ||
129 | movew #0x2300,sr | ||
130 | |||
131 | /* Clear service bit, so other MFP interrupts can work */ | ||
132 | #if defined(__mcoldfire__) | ||
133 | moveql #5,d0 | ||
134 | bclr d0,0xfffffa0f:w | ||
135 | #else | ||
136 | bclr #5,0xfffffa0f:w | ||
137 | #endif | ||
138 | |||
139 | /* Check if we are not already running */ | ||
140 | tstw _SDL_MintAudio_mutex | ||
141 | bne SDL_MintAudio_XbiosEnd | ||
142 | |||
143 | #if defined(__mcoldfire__) | ||
144 | movew _SDL_MintAudio_mutex,d0 | ||
145 | notl d0 | ||
146 | movew d0,_SDL_MintAudio_mutex | ||
147 | |||
148 | movew _SDL_MintAudio_numbuf,d1 | ||
149 | eorl #1,d1 | ||
150 | movew d1,_SDL_MintAudio_numbuf | ||
151 | #else | ||
152 | notw _SDL_MintAudio_mutex | ||
153 | |||
154 | /* Swap buffers */ | ||
155 | eorw #1,_SDL_MintAudio_numbuf | ||
156 | #endif | ||
157 | |||
158 | /* Save FPU if needed */ | ||
159 | tstw _SDL_MintAudio_hasfpu | ||
160 | beqs SDL_MintAudio_Xbios_nofpu1 | ||
161 | SAVE_FPU_CONTEXT | ||
162 | SDL_MintAudio_Xbios_nofpu1: | ||
163 | |||
164 | /* Callback */ | ||
165 | jsr _SDL_MintAudio_Callback | ||
166 | |||
167 | /* Restore FPU if needed */ | ||
168 | tstw _SDL_MintAudio_hasfpu | ||
169 | beqs SDL_MintAudio_Xbios_nofpu2 | ||
170 | RESTORE_FPU_CONTEXT | ||
171 | SDL_MintAudio_Xbios_nofpu2: | ||
172 | |||
173 | /* Reserve space for registers */ | ||
174 | #if defined(__mcoldfire__) | ||
175 | movel #savamt,d0 | ||
176 | subl d0,savptr | ||
177 | #else | ||
178 | subl #savamt,savptr | ||
179 | #endif | ||
180 | |||
181 | /* Set new buffer */ | ||
182 | |||
183 | moveq #0,d0 | ||
184 | movel _SDL_MintAudio_audiosize,d1 | ||
185 | |||
186 | movew _SDL_MintAudio_numbuf,d0 | ||
187 | lsll #2,d0 | ||
188 | lea _SDL_MintAudio_audiobuf,a0 | ||
189 | movel a0@(d0:l),a1 | ||
190 | |||
191 | lea a1@(d1:l),a2 | ||
192 | |||
193 | movel a2,sp@- | ||
194 | movel a1,sp@- | ||
195 | clrw sp@- | ||
196 | movew #131,sp@- | ||
197 | trap #14 | ||
198 | lea sp@(12),sp | ||
199 | |||
200 | /* Restore registers space */ | ||
201 | #if defined(__mcoldfire__) | ||
202 | movel #savamt,d0 | ||
203 | addl d0,savptr | ||
204 | #else | ||
205 | addl #savamt,savptr | ||
206 | #endif | ||
207 | |||
208 | clrw _SDL_MintAudio_mutex | ||
209 | SDL_MintAudio_XbiosEnd: | ||
210 | #if defined(__mcoldfire__) | ||
211 | moveml sp@,d0-d7/a0-a6 | ||
212 | lea sp@(60),sp | ||
213 | #else | ||
214 | moveml sp@+,d0-d7/a0-a6 | ||
215 | #endif | ||
216 | rte | ||
217 | |||
218 | /*--- DMA 8 bits interrupt vector ---*/ | ||
219 | |||
220 | _SDL_MintAudio_Dma8Interrupt: | ||
221 | #if defined(__mcoldfire__) | ||
222 | lea sp@(-16),sp | ||
223 | moveml d0-d1/a0-a1,sp@ | ||
224 | #else | ||
225 | moveml d0-d1/a0-a1,sp@- | ||
226 | #endif | ||
227 | |||
228 | /* Reenable interrupts, so other interrupts can work */ | ||
229 | movew #0x2300,sr | ||
230 | |||
231 | /* Clear service bit, so other MFP interrupts can work */ | ||
232 | #if defined(__mcoldfire__) | ||
233 | moveql #5,d0 | ||
234 | bclr d0,0xfffffa0f:w | ||
235 | #else | ||
236 | bclr #5,0xfffffa0f:w | ||
237 | #endif | ||
238 | /* Check if we are not already running */ | ||
239 | tstw _SDL_MintAudio_mutex | ||
240 | bne SDL_MintAudio_Dma8End | ||
241 | |||
242 | #if defined(__mcoldfire__) | ||
243 | movew _SDL_MintAudio_mutex,d0 | ||
244 | notl d0 | ||
245 | movew d0,_SDL_MintAudio_mutex | ||
246 | |||
247 | movew _SDL_MintAudio_numbuf,d1 | ||
248 | eorl #1,d1 | ||
249 | movew d1,_SDL_MintAudio_numbuf | ||
250 | #else | ||
251 | notw _SDL_MintAudio_mutex | ||
252 | |||
253 | /* Swap buffers */ | ||
254 | eorw #1,_SDL_MintAudio_numbuf | ||
255 | #endif | ||
256 | |||
257 | /* Save FPU if needed */ | ||
258 | tstw _SDL_MintAudio_hasfpu | ||
259 | beqs SDL_MintAudio_Dma8_nofpu1 | ||
260 | SAVE_FPU_CONTEXT | ||
261 | SDL_MintAudio_Dma8_nofpu1: | ||
262 | |||
263 | /* Callback */ | ||
264 | jsr _SDL_MintAudio_Callback | ||
265 | |||
266 | /* Restore FPU if needed */ | ||
267 | tstw _SDL_MintAudio_hasfpu | ||
268 | beqs SDL_MintAudio_Dma8_nofpu2 | ||
269 | RESTORE_FPU_CONTEXT | ||
270 | SDL_MintAudio_Dma8_nofpu2: | ||
271 | |||
272 | /* Set new buffer */ | ||
273 | |||
274 | moveq #0,d0 | ||
275 | |||
276 | movew _SDL_MintAudio_numbuf,d0 | ||
277 | lsll #2,d0 | ||
278 | lea _SDL_MintAudio_audiobuf,a0 | ||
279 | movel a0@(d0:l),d1 | ||
280 | |||
281 | /* Modify DMA addresses */ | ||
282 | lea 0xffff8900:w,a0 | ||
283 | |||
284 | movel d1,d0 | ||
285 | |||
286 | moveb d0,a0@(0x07) /* Start address */ | ||
287 | lsrl #8,d0 | ||
288 | moveb d0,a0@(0x05) | ||
289 | lsrl #8,d0 | ||
290 | moveb d0,a0@(0x03) | ||
291 | |||
292 | addl _SDL_MintAudio_audiosize,d1 | ||
293 | |||
294 | movel d1,d0 | ||
295 | |||
296 | moveb d0,a0@(0x13) /* End address */ | ||
297 | lsrl #8,d0 | ||
298 | moveb d0,a0@(0x11) | ||
299 | lsrl #8,d0 | ||
300 | moveb d0,a0@(0x0f) | ||
301 | |||
302 | clrw _SDL_MintAudio_mutex | ||
303 | SDL_MintAudio_Dma8End: | ||
304 | #if defined(__mcoldfire__) | ||
305 | moveml sp@,d0-d1/a0-a1 | ||
306 | lea sp@(16),sp | ||
307 | #else | ||
308 | moveml sp@+,d0-d1/a0-a1 | ||
309 | #endif | ||
310 | rte | ||
311 | |||
312 | /*--- STFA interrupt vector ---*/ | ||
313 | |||
314 | STFA_SOUND_START = 6 | ||
315 | STFA_SOUND_END = STFA_SOUND_START+8 | ||
316 | |||
317 | _SDL_MintAudio_StfaInterrupt: | ||
318 | /* Reenable interrupts, so other interrupts can work */ | ||
319 | movew #0x2300,sr | ||
320 | |||
321 | /* Check if we are not already running */ | ||
322 | tstw _SDL_MintAudio_mutex | ||
323 | |||
324 | #if defined(__mcoldfire__) | ||
325 | bne SDL_MintAudio_StfaEnd | ||
326 | |||
327 | lea sp@(-60),sp | ||
328 | moveml d0-d7/a0-a6,sp@ | ||
329 | |||
330 | movew _SDL_MintAudio_mutex,d0 | ||
331 | notl d0 | ||
332 | movew d0,_SDL_MintAudio_mutex | ||
333 | |||
334 | movew _SDL_MintAudio_numbuf,d1 | ||
335 | eorl #1,d1 | ||
336 | movew d1,_SDL_MintAudio_numbuf | ||
337 | #else | ||
338 | bnes SDL_MintAudio_StfaEnd | ||
339 | |||
340 | moveml d0-d7/a0-a6,sp@- | ||
341 | |||
342 | notw _SDL_MintAudio_mutex | ||
343 | |||
344 | /* Swap buffers */ | ||
345 | eorw #1,_SDL_MintAudio_numbuf | ||
346 | #endif | ||
347 | |||
348 | /* Save FPU if needed */ | ||
349 | tstw _SDL_MintAudio_hasfpu | ||
350 | beqs SDL_MintAudio_Stfa_nofpu1 | ||
351 | SAVE_FPU_CONTEXT | ||
352 | SDL_MintAudio_Stfa_nofpu1: | ||
353 | |||
354 | /* Callback */ | ||
355 | jsr _SDL_MintAudio_Callback | ||
356 | |||
357 | /* Restore FPU if needed */ | ||
358 | tstw _SDL_MintAudio_hasfpu | ||
359 | beqs SDL_MintAudio_Stfa_nofpu2 | ||
360 | RESTORE_FPU_CONTEXT | ||
361 | SDL_MintAudio_Stfa_nofpu2: | ||
362 | |||
363 | /* Set new buffer */ | ||
364 | |||
365 | moveq #0,d0 | ||
366 | movel _SDL_MintAudio_stfa,a1 | ||
367 | |||
368 | movew _SDL_MintAudio_numbuf,d0 | ||
369 | lsll #2,d0 | ||
370 | lea _SDL_MintAudio_audiobuf,a0 | ||
371 | movel a0@(d0:l),d1 | ||
372 | |||
373 | /* Modify STFA replay buffers */ | ||
374 | movel d1,a1@(STFA_SOUND_START) | ||
375 | addl _SDL_MintAudio_audiosize,d1 | ||
376 | movel d1,a1@(STFA_SOUND_END) | ||
377 | |||
378 | #if defined(__mcoldfire__) | ||
379 | moveml sp@,d0-d7/a0-a6 | ||
380 | lea sp@(60),sp | ||
381 | #else | ||
382 | moveml sp@+,d0-d7/a0-a6 | ||
383 | #endif | ||
384 | clrw _SDL_MintAudio_mutex | ||
385 | SDL_MintAudio_StfaEnd: | ||
386 | rte | ||
diff --git a/apps/plugins/sdl/src/audio/mint/SDL_mintaudio_mcsn.c b/apps/plugins/sdl/src/audio/mint/SDL_mintaudio_mcsn.c deleted file mode 100644 index 387609b168..0000000000 --- a/apps/plugins/sdl/src/audio/mint/SDL_mintaudio_mcsn.c +++ /dev/null | |||
@@ -1,405 +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 | /* | ||
25 | MiNT audio driver | ||
26 | using XBIOS functions (MacSound compatible driver) | ||
27 | |||
28 | Patrice Mandin | ||
29 | */ | ||
30 | |||
31 | #include <support.h> | ||
32 | |||
33 | /* Mint includes */ | ||
34 | #include <mint/osbind.h> | ||
35 | #include <mint/falcon.h> | ||
36 | #include <mint/cookie.h> | ||
37 | |||
38 | #include "SDL_audio.h" | ||
39 | #include "../SDL_audio_c.h" | ||
40 | #include "../SDL_sysaudio.h" | ||
41 | |||
42 | #include "../../video/ataricommon/SDL_atarimxalloc_c.h" | ||
43 | |||
44 | #include "SDL_mintaudio.h" | ||
45 | #include "SDL_mintaudio_mcsn.h" | ||
46 | |||
47 | /*--- Defines ---*/ | ||
48 | |||
49 | #define MINT_AUDIO_DRIVER_NAME "mint_mcsn" | ||
50 | |||
51 | /* Debug print info */ | ||
52 | #define DEBUG_NAME "audio:mcsn: " | ||
53 | #if 0 | ||
54 | #define DEBUG_PRINT(what) \ | ||
55 | { \ | ||
56 | printf what; \ | ||
57 | } | ||
58 | #else | ||
59 | #define DEBUG_PRINT(what) | ||
60 | #endif | ||
61 | |||
62 | /*--- Static variables ---*/ | ||
63 | |||
64 | static long cookie_snd, cookie_mch; | ||
65 | static cookie_mcsn_t *cookie_mcsn; | ||
66 | |||
67 | /*--- Audio driver functions ---*/ | ||
68 | |||
69 | static void Mint_CloseAudio(_THIS); | ||
70 | static int Mint_OpenAudio(_THIS, SDL_AudioSpec *spec); | ||
71 | static void Mint_LockAudio(_THIS); | ||
72 | static void Mint_UnlockAudio(_THIS); | ||
73 | |||
74 | /* To check/init hardware audio */ | ||
75 | static int Mint_CheckAudio(_THIS, SDL_AudioSpec *spec); | ||
76 | static void Mint_InitAudio(_THIS, SDL_AudioSpec *spec); | ||
77 | |||
78 | /*--- Audio driver bootstrap functions ---*/ | ||
79 | |||
80 | static int Audio_Available(void) | ||
81 | { | ||
82 | long dummy; | ||
83 | const char *envr = SDL_getenv("SDL_AUDIODRIVER"); | ||
84 | |||
85 | SDL_MintAudio_mint_present = (Getcookie(C_MiNT, &dummy) == C_FOUND); | ||
86 | |||
87 | /* We can't use XBIOS in interrupt with Magic, don't know about thread */ | ||
88 | if (Getcookie(C_MagX, &dummy) == C_FOUND) { | ||
89 | return(0); | ||
90 | } | ||
91 | |||
92 | /* Check if user asked a different audio driver */ | ||
93 | if ((envr) && (SDL_strcmp(envr, MINT_AUDIO_DRIVER_NAME)!=0)) { | ||
94 | DEBUG_PRINT((DEBUG_NAME "user asked a different audio driver\n")); | ||
95 | return(0); | ||
96 | } | ||
97 | |||
98 | /* Cookie _MCH present ? if not, assume ST machine */ | ||
99 | if (Getcookie(C__MCH, &cookie_mch) == C_NOTFOUND) { | ||
100 | cookie_mch = MCH_ST; | ||
101 | } | ||
102 | |||
103 | /* Cookie _SND present ? if not, assume ST machine */ | ||
104 | if (Getcookie(C__SND, &cookie_snd) == C_NOTFOUND) { | ||
105 | cookie_snd = SND_PSG; | ||
106 | } | ||
107 | |||
108 | /* Check if we have 16 bits audio */ | ||
109 | if ((cookie_snd & SND_16BIT)==0) { | ||
110 | DEBUG_PRINT((DEBUG_NAME "no 16 bits sound\n")); | ||
111 | return(0); | ||
112 | } | ||
113 | |||
114 | /* Cookie MCSN present ? */ | ||
115 | if (Getcookie(C_McSn, &dummy) != C_FOUND) { | ||
116 | DEBUG_PRINT((DEBUG_NAME "no MCSN audio\n")); | ||
117 | return(0); | ||
118 | } | ||
119 | cookie_mcsn = (cookie_mcsn_t *) dummy; | ||
120 | |||
121 | /* Check if interrupt at end of replay */ | ||
122 | if (cookie_mcsn->pint == 0) { | ||
123 | DEBUG_PRINT((DEBUG_NAME "no interrupt at end of replay\n")); | ||
124 | return(0); | ||
125 | } | ||
126 | |||
127 | /* Check if audio is lockable */ | ||
128 | if (Locksnd()!=1) { | ||
129 | DEBUG_PRINT((DEBUG_NAME "audio locked by other application\n")); | ||
130 | return(0); | ||
131 | } | ||
132 | |||
133 | Unlocksnd(); | ||
134 | |||
135 | DEBUG_PRINT((DEBUG_NAME "MCSN audio available!\n")); | ||
136 | return(1); | ||
137 | } | ||
138 | |||
139 | static void Audio_DeleteDevice(SDL_AudioDevice *device) | ||
140 | { | ||
141 | SDL_free(device->hidden); | ||
142 | SDL_free(device); | ||
143 | } | ||
144 | |||
145 | static SDL_AudioDevice *Audio_CreateDevice(int devindex) | ||
146 | { | ||
147 | SDL_AudioDevice *this; | ||
148 | |||
149 | /* Initialize all variables that we clean on shutdown */ | ||
150 | this = (SDL_AudioDevice *)SDL_malloc(sizeof(SDL_AudioDevice)); | ||
151 | if ( this ) { | ||
152 | SDL_memset(this, 0, (sizeof *this)); | ||
153 | this->hidden = (struct SDL_PrivateAudioData *) | ||
154 | SDL_malloc((sizeof *this->hidden)); | ||
155 | } | ||
156 | if ( (this == NULL) || (this->hidden == NULL) ) { | ||
157 | SDL_OutOfMemory(); | ||
158 | if ( this ) { | ||
159 | SDL_free(this); | ||
160 | } | ||
161 | return(0); | ||
162 | } | ||
163 | SDL_memset(this->hidden, 0, (sizeof *this->hidden)); | ||
164 | |||
165 | /* Set the function pointers */ | ||
166 | this->OpenAudio = Mint_OpenAudio; | ||
167 | this->CloseAudio = Mint_CloseAudio; | ||
168 | this->LockAudio = Mint_LockAudio; | ||
169 | this->UnlockAudio = Mint_UnlockAudio; | ||
170 | this->free = Audio_DeleteDevice; | ||
171 | |||
172 | return this; | ||
173 | } | ||
174 | |||
175 | AudioBootStrap MINTAUDIO_MCSN_bootstrap = { | ||
176 | MINT_AUDIO_DRIVER_NAME, "MiNT MCSN audio driver", | ||
177 | Audio_Available, Audio_CreateDevice | ||
178 | }; | ||
179 | |||
180 | static void Mint_LockAudio(_THIS) | ||
181 | { | ||
182 | /* Stop replay */ | ||
183 | Buffoper(0); | ||
184 | } | ||
185 | |||
186 | static void Mint_UnlockAudio(_THIS) | ||
187 | { | ||
188 | /* Restart replay */ | ||
189 | Buffoper(SB_PLA_ENA|SB_PLA_RPT); | ||
190 | } | ||
191 | |||
192 | static void Mint_CloseAudio(_THIS) | ||
193 | { | ||
194 | /* Stop replay */ | ||
195 | SDL_MintAudio_WaitThread(); | ||
196 | Buffoper(0); | ||
197 | |||
198 | if (!SDL_MintAudio_mint_present) { | ||
199 | /* Uninstall interrupt */ | ||
200 | Jdisint(MFP_DMASOUND); | ||
201 | } | ||
202 | |||
203 | /* Wait if currently playing sound */ | ||
204 | while (SDL_MintAudio_mutex != 0) { | ||
205 | } | ||
206 | |||
207 | /* Clear buffers */ | ||
208 | if (SDL_MintAudio_audiobuf[0]) { | ||
209 | Mfree(SDL_MintAudio_audiobuf[0]); | ||
210 | SDL_MintAudio_audiobuf[0] = SDL_MintAudio_audiobuf[1] = NULL; | ||
211 | } | ||
212 | |||
213 | /* Unlock sound system */ | ||
214 | Unlocksnd(); | ||
215 | } | ||
216 | |||
217 | static int Mint_CheckAudio(_THIS, SDL_AudioSpec *spec) | ||
218 | { | ||
219 | int i; | ||
220 | unsigned long masterclock, masterprediv; | ||
221 | |||
222 | DEBUG_PRINT((DEBUG_NAME "asked: %d bits, ",spec->format & 0x00ff)); | ||
223 | DEBUG_PRINT(("signed=%d, ", ((spec->format & 0x8000)!=0))); | ||
224 | DEBUG_PRINT(("big endian=%d, ", ((spec->format & 0x1000)!=0))); | ||
225 | DEBUG_PRINT(("channels=%d, ", spec->channels)); | ||
226 | DEBUG_PRINT(("freq=%d\n", spec->freq)); | ||
227 | |||
228 | if (spec->channels > 2) { | ||
229 | spec->channels = 2; /* no more than stereo! */ | ||
230 | } | ||
231 | |||
232 | /* Check formats available */ | ||
233 | MINTAUDIO_freqcount=0; | ||
234 | switch(cookie_mcsn->play) { | ||
235 | case MCSN_ST: | ||
236 | spec->channels=1; | ||
237 | spec->format=8; /* FIXME: is it signed or unsigned ? */ | ||
238 | SDL_MintAudio_AddFrequency(this, 12500, 0, 0, -1); | ||
239 | break; | ||
240 | case MCSN_TT: /* Also STE, Mega STE */ | ||
241 | spec->format=AUDIO_S8; | ||
242 | masterclock=MASTERCLOCK_STE; | ||
243 | masterprediv=MASTERPREDIV_STE; | ||
244 | if ((cookie_mch>>16)==MCH_TT) { | ||
245 | masterclock=MASTERCLOCK_TT; | ||
246 | masterprediv=MASTERPREDIV_TT; | ||
247 | } | ||
248 | for (i=0; i<4; i++) { | ||
249 | SDL_MintAudio_AddFrequency(this, masterclock/(masterprediv*(1<<i)), | ||
250 | masterclock, 3-i, -1); | ||
251 | } | ||
252 | break; | ||
253 | case MCSN_FALCON: /* Also Mac */ | ||
254 | for (i=1; i<12; i++) { | ||
255 | /* Remove unusable Falcon codec predivisors */ | ||
256 | if ((i==6) || (i==8) || (i==10)) { | ||
257 | continue; | ||
258 | } | ||
259 | SDL_MintAudio_AddFrequency(this, MASTERCLOCK_FALCON1/(MASTERPREDIV_FALCON*(i+1)), | ||
260 | CLK25M, i+1, -1); | ||
261 | } | ||
262 | if (cookie_mcsn->res1 != 0) { | ||
263 | for (i=1; i<4; i++) { | ||
264 | SDL_MintAudio_AddFrequency(this, (cookie_mcsn->res1)/(MASTERPREDIV_FALCON*(1<<i)), | ||
265 | CLKEXT, (1<<i)-1, -1); | ||
266 | } | ||
267 | } | ||
268 | spec->format |= 0x8000; /* Audio is always signed */ | ||
269 | if ((spec->format & 0x00ff)==16) { | ||
270 | spec->format |= 0x1000; /* Audio is always big endian */ | ||
271 | spec->channels=2; /* 16 bits always stereo */ | ||
272 | } | ||
273 | break; | ||
274 | } | ||
275 | |||
276 | #if 0 | ||
277 | for (i=0; i<MINTAUDIO_freqcount; i++) { | ||
278 | DEBUG_PRINT((DEBUG_NAME "freq %d: %lu Hz, clock %lu, prediv %d\n", | ||
279 | i, MINTAUDIO_frequencies[i].frequency, MINTAUDIO_frequencies[i].masterclock, | ||
280 | MINTAUDIO_frequencies[i].predivisor | ||
281 | )); | ||
282 | } | ||
283 | #endif | ||
284 | |||
285 | MINTAUDIO_numfreq=SDL_MintAudio_SearchFrequency(this, spec->freq); | ||
286 | spec->freq=MINTAUDIO_frequencies[MINTAUDIO_numfreq].frequency; | ||
287 | |||
288 | DEBUG_PRINT((DEBUG_NAME "obtained: %d bits, ",spec->format & 0x00ff)); | ||
289 | DEBUG_PRINT(("signed=%d, ", ((spec->format & 0x8000)!=0))); | ||
290 | DEBUG_PRINT(("big endian=%d, ", ((spec->format & 0x1000)!=0))); | ||
291 | DEBUG_PRINT(("channels=%d, ", spec->channels)); | ||
292 | DEBUG_PRINT(("freq=%d\n", spec->freq)); | ||
293 | |||
294 | return 0; | ||
295 | } | ||
296 | |||
297 | static void Mint_InitAudio(_THIS, SDL_AudioSpec *spec) | ||
298 | { | ||
299 | int channels_mode, prediv, dmaclock; | ||
300 | void *buffer; | ||
301 | |||
302 | /* Stop currently playing sound */ | ||
303 | SDL_MintAudio_quit_thread = SDL_FALSE; | ||
304 | SDL_MintAudio_thread_finished = SDL_TRUE; | ||
305 | SDL_MintAudio_WaitThread(); | ||
306 | Buffoper(0); | ||
307 | |||
308 | /* Set replay tracks */ | ||
309 | Settracks(0,0); | ||
310 | Setmontracks(0); | ||
311 | |||
312 | /* Select replay format */ | ||
313 | channels_mode=STEREO16; | ||
314 | switch (spec->format & 0xff) { | ||
315 | case 8: | ||
316 | if (spec->channels==2) { | ||
317 | channels_mode=STEREO8; | ||
318 | } else { | ||
319 | channels_mode=MONO8; | ||
320 | } | ||
321 | break; | ||
322 | } | ||
323 | if (Setmode(channels_mode)<0) { | ||
324 | DEBUG_PRINT((DEBUG_NAME "Setmode() failed\n")); | ||
325 | } | ||
326 | |||
327 | dmaclock = MINTAUDIO_frequencies[MINTAUDIO_numfreq].masterclock; | ||
328 | prediv = MINTAUDIO_frequencies[MINTAUDIO_numfreq].predivisor; | ||
329 | switch(cookie_mcsn->play) { | ||
330 | case MCSN_TT: | ||
331 | Devconnect(DMAPLAY, DAC, CLK25M, CLKOLD, 1); | ||
332 | Soundcmd(SETPRESCALE, prediv); | ||
333 | DEBUG_PRINT((DEBUG_NAME "STE/TT prescaler selected\n")); | ||
334 | break; | ||
335 | case MCSN_FALCON: | ||
336 | Devconnect(DMAPLAY, DAC, dmaclock, prediv, 1); | ||
337 | DEBUG_PRINT((DEBUG_NAME "Falcon prescaler selected\n")); | ||
338 | break; | ||
339 | } | ||
340 | |||
341 | /* Set buffer */ | ||
342 | buffer = SDL_MintAudio_audiobuf[SDL_MintAudio_numbuf]; | ||
343 | if (Setbuffer(0, buffer, buffer + spec->size)<0) { | ||
344 | DEBUG_PRINT((DEBUG_NAME "Setbuffer() failed\n")); | ||
345 | } | ||
346 | |||
347 | if (SDL_MintAudio_mint_present) { | ||
348 | SDL_MintAudio_thread_pid = tfork(SDL_MintAudio_Thread, 0); | ||
349 | } else { | ||
350 | /* Install interrupt */ | ||
351 | Jdisint(MFP_DMASOUND); | ||
352 | Xbtimer(XB_TIMERA, 8, 1, SDL_MintAudio_XbiosInterrupt); | ||
353 | Jenabint(MFP_DMASOUND); | ||
354 | |||
355 | if (Setinterrupt(SI_TIMERA, SI_PLAY)<0) { | ||
356 | DEBUG_PRINT((DEBUG_NAME "Setinterrupt() failed\n")); | ||
357 | } | ||
358 | } | ||
359 | |||
360 | /* Go */ | ||
361 | Buffoper(SB_PLA_ENA|SB_PLA_RPT); | ||
362 | DEBUG_PRINT((DEBUG_NAME "hardware initialized\n")); | ||
363 | } | ||
364 | |||
365 | static int Mint_OpenAudio(_THIS, SDL_AudioSpec *spec) | ||
366 | { | ||
367 | /* Lock sound system */ | ||
368 | if (Locksnd()!=1) { | ||
369 | SDL_SetError("Mint_OpenAudio: Audio system already in use"); | ||
370 | return(-1); | ||
371 | } | ||
372 | |||
373 | SDL_MintAudio_device = this; | ||
374 | |||
375 | /* Check audio capabilities */ | ||
376 | if (Mint_CheckAudio(this, spec)==-1) { | ||
377 | return -1; | ||
378 | } | ||
379 | |||
380 | SDL_CalculateAudioSpec(spec); | ||
381 | |||
382 | /* Allocate memory for audio buffers in DMA-able RAM */ | ||
383 | DEBUG_PRINT((DEBUG_NAME "buffer size=%d\n", spec->size)); | ||
384 | |||
385 | SDL_MintAudio_audiobuf[0] = Atari_SysMalloc(spec->size *2, MX_STRAM); | ||
386 | if (SDL_MintAudio_audiobuf[0]==NULL) { | ||
387 | SDL_SetError("MINT_OpenAudio: Not enough memory for audio buffer"); | ||
388 | return (-1); | ||
389 | } | ||
390 | SDL_MintAudio_audiobuf[1] = SDL_MintAudio_audiobuf[0] + spec->size ; | ||
391 | SDL_MintAudio_numbuf=0; | ||
392 | SDL_memset(SDL_MintAudio_audiobuf[0], spec->silence, spec->size *2); | ||
393 | SDL_MintAudio_audiosize = spec->size; | ||
394 | SDL_MintAudio_mutex = 0; | ||
395 | |||
396 | DEBUG_PRINT((DEBUG_NAME "buffer 0 at 0x%08x\n", SDL_MintAudio_audiobuf[0])); | ||
397 | DEBUG_PRINT((DEBUG_NAME "buffer 1 at 0x%08x\n", SDL_MintAudio_audiobuf[1])); | ||
398 | |||
399 | SDL_MintAudio_CheckFpu(); | ||
400 | |||
401 | /* Setup audio hardware */ | ||
402 | Mint_InitAudio(this, spec); | ||
403 | |||
404 | return(1); /* We don't use SDL threaded audio */ | ||
405 | } | ||
diff --git a/apps/plugins/sdl/src/audio/mint/SDL_mintaudio_mcsn.h b/apps/plugins/sdl/src/audio/mint/SDL_mintaudio_mcsn.h deleted file mode 100644 index b772fdab03..0000000000 --- a/apps/plugins/sdl/src/audio/mint/SDL_mintaudio_mcsn.h +++ /dev/null | |||
@@ -1,59 +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 | /* | ||
25 | MCSN control structure | ||
26 | |||
27 | Patrice Mandin | ||
28 | */ | ||
29 | |||
30 | #ifndef _SDL_mintaudio_mcsh_h | ||
31 | #define _SDL_mintaudio_mcsh_h | ||
32 | |||
33 | typedef struct { | ||
34 | unsigned short version; /* Version */ | ||
35 | unsigned short size; /* Size of structure */ | ||
36 | |||
37 | unsigned short play; /* Replay capability */ | ||
38 | unsigned short record; /* Record capability */ | ||
39 | unsigned short dsp; /* DSP56K present */ | ||
40 | unsigned short pint; /* Interrupt at end of replay */ | ||
41 | unsigned short rint; /* Interrupt at end of record */ | ||
42 | |||
43 | unsigned long res1; /* Frequency of external clock */ | ||
44 | unsigned long res2; | ||
45 | unsigned long res3; | ||
46 | unsigned long res4; | ||
47 | } cookie_mcsn_t; | ||
48 | |||
49 | enum { | ||
50 | MCSN_ST=0, | ||
51 | MCSN_TT, | ||
52 | MCSN_STE=MCSN_TT, | ||
53 | MCSN_FALCON, | ||
54 | MCSN_MAC=MCSN_FALCON | ||
55 | }; | ||
56 | |||
57 | #define SETSMPFREQ 7 /* Set sample frequency */ | ||
58 | |||
59 | #endif /* _SDL_mintaudio_mcsh_h */ | ||
diff --git a/apps/plugins/sdl/src/audio/mint/SDL_mintaudio_stfa.c b/apps/plugins/sdl/src/audio/mint/SDL_mintaudio_stfa.c deleted file mode 100644 index 4a581e0351..0000000000 --- a/apps/plugins/sdl/src/audio/mint/SDL_mintaudio_stfa.c +++ /dev/null | |||
@@ -1,326 +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 | /* | ||
25 | MiNT audio driver | ||
26 | using XBIOS functions (STFA driver) | ||
27 | |||
28 | Patrice Mandin | ||
29 | */ | ||
30 | |||
31 | /* Mint includes */ | ||
32 | #include <mint/osbind.h> | ||
33 | #include <mint/falcon.h> | ||
34 | #include <mint/cookie.h> | ||
35 | |||
36 | #include "SDL_audio.h" | ||
37 | #include "../SDL_audio_c.h" | ||
38 | #include "../SDL_sysaudio.h" | ||
39 | |||
40 | #include "../../video/ataricommon/SDL_atarimxalloc_c.h" | ||
41 | #include "../../video/ataricommon/SDL_atarisuper.h" | ||
42 | |||
43 | #include "SDL_mintaudio.h" | ||
44 | #include "SDL_mintaudio_stfa.h" | ||
45 | |||
46 | /*--- Defines ---*/ | ||
47 | |||
48 | #define MINT_AUDIO_DRIVER_NAME "mint_stfa" | ||
49 | |||
50 | /* Debug print info */ | ||
51 | #define DEBUG_NAME "audio:stfa: " | ||
52 | #if 0 | ||
53 | #define DEBUG_PRINT(what) \ | ||
54 | { \ | ||
55 | printf what; \ | ||
56 | } | ||
57 | #else | ||
58 | #define DEBUG_PRINT(what) | ||
59 | #endif | ||
60 | |||
61 | /*--- Static variables ---*/ | ||
62 | |||
63 | static long cookie_snd, cookie_mch; | ||
64 | static cookie_stfa_t *cookie_stfa; | ||
65 | |||
66 | static const int freqs[16]={ | ||
67 | 4995, 6269, 7493, 8192, | ||
68 | 9830, 10971, 12538, 14985, | ||
69 | 16384, 19819, 21943, 24576, | ||
70 | 30720, 32336, 43885, 49152 | ||
71 | }; | ||
72 | |||
73 | /*--- Audio driver functions ---*/ | ||
74 | |||
75 | static void Mint_CloseAudio(_THIS); | ||
76 | static int Mint_OpenAudio(_THIS, SDL_AudioSpec *spec); | ||
77 | static void Mint_LockAudio(_THIS); | ||
78 | static void Mint_UnlockAudio(_THIS); | ||
79 | |||
80 | /* To check/init hardware audio */ | ||
81 | static int Mint_CheckAudio(_THIS, SDL_AudioSpec *spec); | ||
82 | static void Mint_InitAudio(_THIS, SDL_AudioSpec *spec); | ||
83 | |||
84 | /*--- Audio driver bootstrap functions ---*/ | ||
85 | |||
86 | static int Audio_Available(void) | ||
87 | { | ||
88 | long dummy; | ||
89 | const char *envr = SDL_getenv("SDL_AUDIODRIVER"); | ||
90 | |||
91 | /* Check if user asked a different audio driver */ | ||
92 | if ((envr) && (SDL_strcmp(envr, MINT_AUDIO_DRIVER_NAME)!=0)) { | ||
93 | DEBUG_PRINT((DEBUG_NAME "user asked a different audio driver\n")); | ||
94 | return(0); | ||
95 | } | ||
96 | |||
97 | /* Cookie _MCH present ? if not, assume ST machine */ | ||
98 | if (Getcookie(C__MCH, &cookie_mch) == C_NOTFOUND) { | ||
99 | cookie_mch = MCH_ST; | ||
100 | } | ||
101 | |||
102 | /* Cookie _SND present ? if not, assume ST machine */ | ||
103 | if (Getcookie(C__SND, &cookie_snd) == C_NOTFOUND) { | ||
104 | cookie_snd = SND_PSG; | ||
105 | } | ||
106 | |||
107 | /* Cookie STFA present ? */ | ||
108 | if (Getcookie(C_STFA, &dummy) != C_FOUND) { | ||
109 | DEBUG_PRINT((DEBUG_NAME "no STFA audio\n")); | ||
110 | return(0); | ||
111 | } | ||
112 | cookie_stfa = (cookie_stfa_t *) dummy; | ||
113 | |||
114 | SDL_MintAudio_stfa = cookie_stfa; | ||
115 | |||
116 | DEBUG_PRINT((DEBUG_NAME "STFA audio available!\n")); | ||
117 | return(1); | ||
118 | } | ||
119 | |||
120 | static void Audio_DeleteDevice(SDL_AudioDevice *device) | ||
121 | { | ||
122 | SDL_free(device->hidden); | ||
123 | SDL_free(device); | ||
124 | } | ||
125 | |||
126 | static SDL_AudioDevice *Audio_CreateDevice(int devindex) | ||
127 | { | ||
128 | SDL_AudioDevice *this; | ||
129 | |||
130 | /* Initialize all variables that we clean on shutdown */ | ||
131 | this = (SDL_AudioDevice *)SDL_malloc(sizeof(SDL_AudioDevice)); | ||
132 | if ( this ) { | ||
133 | SDL_memset(this, 0, (sizeof *this)); | ||
134 | this->hidden = (struct SDL_PrivateAudioData *) | ||
135 | SDL_malloc((sizeof *this->hidden)); | ||
136 | } | ||
137 | if ( (this == NULL) || (this->hidden == NULL) ) { | ||
138 | SDL_OutOfMemory(); | ||
139 | if ( this ) { | ||
140 | SDL_free(this); | ||
141 | } | ||
142 | return(0); | ||
143 | } | ||
144 | SDL_memset(this->hidden, 0, (sizeof *this->hidden)); | ||
145 | |||
146 | /* Set the function pointers */ | ||
147 | this->OpenAudio = Mint_OpenAudio; | ||
148 | this->CloseAudio = Mint_CloseAudio; | ||
149 | this->LockAudio = Mint_LockAudio; | ||
150 | this->UnlockAudio = Mint_UnlockAudio; | ||
151 | this->free = Audio_DeleteDevice; | ||
152 | |||
153 | return this; | ||
154 | } | ||
155 | |||
156 | AudioBootStrap MINTAUDIO_STFA_bootstrap = { | ||
157 | MINT_AUDIO_DRIVER_NAME, "MiNT STFA audio driver", | ||
158 | Audio_Available, Audio_CreateDevice | ||
159 | }; | ||
160 | |||
161 | static void Mint_LockAudio(_THIS) | ||
162 | { | ||
163 | void *oldpile; | ||
164 | |||
165 | /* Stop replay */ | ||
166 | oldpile=(void *)Super(0); | ||
167 | cookie_stfa->sound_enable=STFA_PLAY_DISABLE; | ||
168 | SuperToUser(oldpile); | ||
169 | } | ||
170 | |||
171 | static void Mint_UnlockAudio(_THIS) | ||
172 | { | ||
173 | void *oldpile; | ||
174 | |||
175 | /* Restart replay */ | ||
176 | oldpile=(void *)Super(0); | ||
177 | cookie_stfa->sound_enable=STFA_PLAY_ENABLE|STFA_PLAY_REPEAT; | ||
178 | SuperToUser(oldpile); | ||
179 | } | ||
180 | |||
181 | static void Mint_CloseAudio(_THIS) | ||
182 | { | ||
183 | void *oldpile; | ||
184 | |||
185 | /* Stop replay */ | ||
186 | oldpile=(void *)Super(0); | ||
187 | cookie_stfa->sound_enable=STFA_PLAY_DISABLE; | ||
188 | SuperToUser(oldpile); | ||
189 | |||
190 | /* Wait if currently playing sound */ | ||
191 | while (SDL_MintAudio_mutex != 0) { | ||
192 | } | ||
193 | |||
194 | /* Clear buffers */ | ||
195 | if (SDL_MintAudio_audiobuf[0]) { | ||
196 | Mfree(SDL_MintAudio_audiobuf[0]); | ||
197 | SDL_MintAudio_audiobuf[0] = SDL_MintAudio_audiobuf[1] = NULL; | ||
198 | } | ||
199 | } | ||
200 | |||
201 | static int Mint_CheckAudio(_THIS, SDL_AudioSpec *spec) | ||
202 | { | ||
203 | int i; | ||
204 | |||
205 | DEBUG_PRINT((DEBUG_NAME "asked: %d bits, ",spec->format & 0x00ff)); | ||
206 | DEBUG_PRINT(("signed=%d, ", ((spec->format & 0x8000)!=0))); | ||
207 | DEBUG_PRINT(("big endian=%d, ", ((spec->format & 0x1000)!=0))); | ||
208 | DEBUG_PRINT(("channels=%d, ", spec->channels)); | ||
209 | DEBUG_PRINT(("freq=%d\n", spec->freq)); | ||
210 | |||
211 | if (spec->channels > 2) { | ||
212 | spec->channels = 2; /* no more than stereo! */ | ||
213 | } | ||
214 | |||
215 | /* Check formats available */ | ||
216 | MINTAUDIO_freqcount=0; | ||
217 | for (i=0;i<16;i++) { | ||
218 | SDL_MintAudio_AddFrequency(this, freqs[i], 0, i, -1); | ||
219 | } | ||
220 | |||
221 | #if 1 | ||
222 | for (i=0; i<MINTAUDIO_freqcount; i++) { | ||
223 | DEBUG_PRINT((DEBUG_NAME "freq %d: %lu Hz, clock %lu, prediv %d\n", | ||
224 | i, MINTAUDIO_frequencies[i].frequency, MINTAUDIO_frequencies[i].masterclock, | ||
225 | MINTAUDIO_frequencies[i].predivisor | ||
226 | )); | ||
227 | } | ||
228 | #endif | ||
229 | |||
230 | MINTAUDIO_numfreq=SDL_MintAudio_SearchFrequency(this, spec->freq); | ||
231 | spec->freq=MINTAUDIO_frequencies[MINTAUDIO_numfreq].frequency; | ||
232 | |||
233 | DEBUG_PRINT((DEBUG_NAME "obtained: %d bits, ",spec->format & 0x00ff)); | ||
234 | DEBUG_PRINT(("signed=%d, ", ((spec->format & 0x8000)!=0))); | ||
235 | DEBUG_PRINT(("big endian=%d, ", ((spec->format & 0x1000)!=0))); | ||
236 | DEBUG_PRINT(("channels=%d, ", spec->channels)); | ||
237 | DEBUG_PRINT(("freq=%d\n", spec->freq)); | ||
238 | |||
239 | return 0; | ||
240 | } | ||
241 | |||
242 | static void Mint_InitAudio(_THIS, SDL_AudioSpec *spec) | ||
243 | { | ||
244 | void *buffer; | ||
245 | void *oldpile; | ||
246 | |||
247 | buffer = SDL_MintAudio_audiobuf[SDL_MintAudio_numbuf]; | ||
248 | |||
249 | oldpile=(void *)Super(0); | ||
250 | |||
251 | /* Stop replay */ | ||
252 | cookie_stfa->sound_enable=STFA_PLAY_DISABLE; | ||
253 | |||
254 | /* Select replay format */ | ||
255 | cookie_stfa->sound_control = MINTAUDIO_frequencies[MINTAUDIO_numfreq].predivisor; | ||
256 | if ((spec->format & 0xff)==8) { | ||
257 | cookie_stfa->sound_control |= STFA_FORMAT_8BIT; | ||
258 | } else { | ||
259 | cookie_stfa->sound_control |= STFA_FORMAT_16BIT; | ||
260 | } | ||
261 | if (spec->channels==2) { | ||
262 | cookie_stfa->sound_control |= STFA_FORMAT_STEREO; | ||
263 | } else { | ||
264 | cookie_stfa->sound_control |= STFA_FORMAT_MONO; | ||
265 | } | ||
266 | if ((spec->format & 0x8000)!=0) { | ||
267 | cookie_stfa->sound_control |= STFA_FORMAT_SIGNED; | ||
268 | } else { | ||
269 | cookie_stfa->sound_control |= STFA_FORMAT_UNSIGNED; | ||
270 | } | ||
271 | if ((spec->format & 0x1000)!=0) { | ||
272 | cookie_stfa->sound_control |= STFA_FORMAT_BIGENDIAN; | ||
273 | } else { | ||
274 | cookie_stfa->sound_control |= STFA_FORMAT_LITENDIAN; | ||
275 | } | ||
276 | |||
277 | /* Set buffer */ | ||
278 | cookie_stfa->sound_start = (unsigned long) buffer; | ||
279 | cookie_stfa->sound_end = (unsigned long) (buffer + spec->size); | ||
280 | |||
281 | /* Set interrupt */ | ||
282 | cookie_stfa->stfa_it = SDL_MintAudio_StfaInterrupt; | ||
283 | |||
284 | /* Restart replay */ | ||
285 | cookie_stfa->sound_enable=STFA_PLAY_ENABLE|STFA_PLAY_REPEAT; | ||
286 | |||
287 | SuperToUser(oldpile); | ||
288 | |||
289 | DEBUG_PRINT((DEBUG_NAME "hardware initialized\n")); | ||
290 | } | ||
291 | |||
292 | static int Mint_OpenAudio(_THIS, SDL_AudioSpec *spec) | ||
293 | { | ||
294 | SDL_MintAudio_device = this; | ||
295 | |||
296 | /* Check audio capabilities */ | ||
297 | if (Mint_CheckAudio(this, spec)==-1) { | ||
298 | return -1; | ||
299 | } | ||
300 | |||
301 | SDL_CalculateAudioSpec(spec); | ||
302 | |||
303 | /* Allocate memory for audio buffers in DMA-able RAM */ | ||
304 | DEBUG_PRINT((DEBUG_NAME "buffer size=%d\n", spec->size)); | ||
305 | |||
306 | SDL_MintAudio_audiobuf[0] = Atari_SysMalloc(spec->size *2, MX_STRAM); | ||
307 | if (SDL_MintAudio_audiobuf[0]==NULL) { | ||
308 | SDL_SetError("MINT_OpenAudio: Not enough memory for audio buffer"); | ||
309 | return (-1); | ||
310 | } | ||
311 | SDL_MintAudio_audiobuf[1] = SDL_MintAudio_audiobuf[0] + spec->size ; | ||
312 | SDL_MintAudio_numbuf=0; | ||
313 | SDL_memset(SDL_MintAudio_audiobuf[0], spec->silence, spec->size *2); | ||
314 | SDL_MintAudio_audiosize = spec->size; | ||
315 | SDL_MintAudio_mutex = 0; | ||
316 | |||
317 | DEBUG_PRINT((DEBUG_NAME "buffer 0 at 0x%08x\n", SDL_MintAudio_audiobuf[0])); | ||
318 | DEBUG_PRINT((DEBUG_NAME "buffer 1 at 0x%08x\n", SDL_MintAudio_audiobuf[1])); | ||
319 | |||
320 | SDL_MintAudio_CheckFpu(); | ||
321 | |||
322 | /* Setup audio hardware */ | ||
323 | Mint_InitAudio(this, spec); | ||
324 | |||
325 | return(1); /* We don't use threaded audio */ | ||
326 | } | ||
diff --git a/apps/plugins/sdl/src/audio/mint/SDL_mintaudio_stfa.h b/apps/plugins/sdl/src/audio/mint/SDL_mintaudio_stfa.h deleted file mode 100644 index 1789b4bb41..0000000000 --- a/apps/plugins/sdl/src/audio/mint/SDL_mintaudio_stfa.h +++ /dev/null | |||
@@ -1,97 +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 | /* | ||
25 | STFA control structure | ||
26 | |||
27 | Patrice Mandin | ||
28 | */ | ||
29 | |||
30 | #ifndef _SDL_mintaudio_stfa_h | ||
31 | #define _SDL_mintaudio_stfa_h | ||
32 | |||
33 | /*--- Defines ---*/ | ||
34 | |||
35 | #define STFA_PLAY_ENABLE (1<<0) | ||
36 | #define STFA_PLAY_DISABLE (0<<0) | ||
37 | #define STFA_PLAY_REPEAT (1<<1) | ||
38 | #define STFA_PLAY_SINGLE (0<<1) | ||
39 | |||
40 | #define STFA_FORMAT_SIGNED (1<<15) | ||
41 | #define STFA_FORMAT_UNSIGNED (0<<15) | ||
42 | #define STFA_FORMAT_STEREO (1<<14) | ||
43 | #define STFA_FORMAT_MONO (0<<14) | ||
44 | #define STFA_FORMAT_16BIT (1<<13) | ||
45 | #define STFA_FORMAT_8BIT (0<<13) | ||
46 | #define STFA_FORMAT_LITENDIAN (1<<9) | ||
47 | #define STFA_FORMAT_BIGENDIAN (0<<9) | ||
48 | #define STFA_FORMAT_FREQ_MASK 0x0f | ||
49 | enum { | ||
50 | STFA_FORMAT_F4995=0, | ||
51 | STFA_FORMAT_F6269, | ||
52 | STFA_FORMAT_F7493, | ||
53 | STFA_FORMAT_F8192, | ||
54 | |||
55 | STFA_FORMAT_F9830, | ||
56 | STFA_FORMAT_F10971, | ||
57 | STFA_FORMAT_F12538, | ||
58 | STFA_FORMAT_F14985, | ||
59 | |||
60 | STFA_FORMAT_F16384, | ||
61 | STFA_FORMAT_F19819, | ||
62 | STFA_FORMAT_F21943, | ||
63 | STFA_FORMAT_F24576, | ||
64 | |||
65 | STFA_FORMAT_F30720, | ||
66 | STFA_FORMAT_F32336, | ||
67 | STFA_FORMAT_F43885, | ||
68 | STFA_FORMAT_F49152 | ||
69 | }; | ||
70 | |||
71 | /*--- Types ---*/ | ||
72 | |||
73 | typedef struct { | ||
74 | unsigned short sound_enable; | ||
75 | unsigned short sound_control; | ||
76 | unsigned short sound_output; | ||
77 | unsigned long sound_start; | ||
78 | unsigned long sound_current; | ||
79 | unsigned long sound_end; | ||
80 | unsigned short version; | ||
81 | void *old_vbl; | ||
82 | void *old_timera; | ||
83 | unsigned long old_mfp_status; | ||
84 | void *new_vbl; | ||
85 | void *drivers_list; | ||
86 | void *play_stop; | ||
87 | unsigned short frequency; | ||
88 | void *set_frequency; | ||
89 | unsigned short frequency_threshold; | ||
90 | unsigned short *custom_freq_table; | ||
91 | unsigned short stfa_on_off; | ||
92 | void *new_drivers_list; | ||
93 | unsigned long old_bit_2_of_cookie_snd; | ||
94 | void (*stfa_it)(void); | ||
95 | } cookie_stfa_t; | ||
96 | |||
97 | #endif /* _SDL_mintaudio_stfa_h */ | ||
diff --git a/apps/plugins/sdl/src/audio/mint/SDL_mintaudio_xbios.c b/apps/plugins/sdl/src/audio/mint/SDL_mintaudio_xbios.c deleted file mode 100644 index 42a0d4a2f9..0000000000 --- a/apps/plugins/sdl/src/audio/mint/SDL_mintaudio_xbios.c +++ /dev/null | |||
@@ -1,490 +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 | /* | ||
25 | MiNT audio driver | ||
26 | using XBIOS functions (Falcon) | ||
27 | |||
28 | Patrice Mandin, Didier Méquignon | ||
29 | */ | ||
30 | |||
31 | #include <unistd.h> | ||
32 | #include <support.h> | ||
33 | |||
34 | /* Mint includes */ | ||
35 | #include <mint/osbind.h> | ||
36 | #include <mint/falcon.h> | ||
37 | #include <mint/cookie.h> | ||
38 | |||
39 | #include "SDL_audio.h" | ||
40 | #include "../SDL_audio_c.h" | ||
41 | #include "../SDL_sysaudio.h" | ||
42 | |||
43 | #include "../../video/ataricommon/SDL_atarimxalloc_c.h" | ||
44 | #include "../../video/ataricommon/SDL_atarisuper.h" | ||
45 | |||
46 | #include "SDL_mintaudio.h" | ||
47 | #include "SDL_mintaudio_dma8.h" | ||
48 | |||
49 | /*--- Defines ---*/ | ||
50 | |||
51 | #define MINT_AUDIO_DRIVER_NAME "mint_xbios" | ||
52 | |||
53 | /* Debug print info */ | ||
54 | #define DEBUG_NAME "audio:xbios: " | ||
55 | #if 0 | ||
56 | #define DEBUG_PRINT(what) \ | ||
57 | { \ | ||
58 | printf what; \ | ||
59 | } | ||
60 | #else | ||
61 | #define DEBUG_PRINT(what) | ||
62 | #endif | ||
63 | |||
64 | /*--- Static variables ---*/ | ||
65 | |||
66 | static long cookie_snd; | ||
67 | |||
68 | /*--- Audio driver functions ---*/ | ||
69 | |||
70 | static void Mint_CloseAudio(_THIS); | ||
71 | static int Mint_OpenAudio(_THIS, SDL_AudioSpec *spec); | ||
72 | static void Mint_LockAudio(_THIS); | ||
73 | static void Mint_UnlockAudio(_THIS); | ||
74 | |||
75 | /* To check/init hardware audio */ | ||
76 | static int Mint_CheckAudio(_THIS, SDL_AudioSpec *spec); | ||
77 | static void Mint_InitAudio(_THIS, SDL_AudioSpec *spec); | ||
78 | |||
79 | /*--- Audio driver bootstrap functions ---*/ | ||
80 | |||
81 | static int Audio_Available(void) | ||
82 | { | ||
83 | /* unsigned long dummy;*/ | ||
84 | const char *envr = SDL_getenv("SDL_AUDIODRIVER"); | ||
85 | |||
86 | /*SDL_MintAudio_mint_present = (Getcookie(C_MiNT, &dummy) == C_FOUND);*/ | ||
87 | SDL_MintAudio_mint_present = SDL_FALSE; | ||
88 | |||
89 | /* We can't use XBIOS in interrupt with Magic, don't know about thread */ | ||
90 | /*if (Getcookie(C_MagX, &dummy) == C_FOUND) { | ||
91 | return(0); | ||
92 | }*/ | ||
93 | |||
94 | /* Check if user asked a different audio driver */ | ||
95 | if ((envr) && (SDL_strcmp(envr, MINT_AUDIO_DRIVER_NAME)!=0)) { | ||
96 | DEBUG_PRINT((DEBUG_NAME "user asked a different audio driver\n")); | ||
97 | return(0); | ||
98 | } | ||
99 | |||
100 | /* Cookie _SND present ? if not, assume ST machine */ | ||
101 | if (Getcookie(C__SND, &cookie_snd) == C_NOTFOUND) { | ||
102 | cookie_snd = SND_PSG; | ||
103 | } | ||
104 | |||
105 | /* Check if we have 16 bits audio */ | ||
106 | if ((cookie_snd & SND_16BIT)==0) { | ||
107 | DEBUG_PRINT((DEBUG_NAME "no 16 bits sound\n")); | ||
108 | return(0); | ||
109 | } | ||
110 | |||
111 | /* Check if audio is lockable */ | ||
112 | if (Locksnd()!=1) { | ||
113 | DEBUG_PRINT((DEBUG_NAME "audio locked by other application\n")); | ||
114 | return(0); | ||
115 | } | ||
116 | |||
117 | Unlocksnd(); | ||
118 | |||
119 | DEBUG_PRINT((DEBUG_NAME "XBIOS audio available!\n")); | ||
120 | return(1); | ||
121 | } | ||
122 | |||
123 | static void Audio_DeleteDevice(SDL_AudioDevice *device) | ||
124 | { | ||
125 | SDL_free(device->hidden); | ||
126 | SDL_free(device); | ||
127 | } | ||
128 | |||
129 | static SDL_AudioDevice *Audio_CreateDevice(int devindex) | ||
130 | { | ||
131 | SDL_AudioDevice *this; | ||
132 | |||
133 | /* Initialize all variables that we clean on shutdown */ | ||
134 | this = (SDL_AudioDevice *)SDL_malloc(sizeof(SDL_AudioDevice)); | ||
135 | if ( this ) { | ||
136 | SDL_memset(this, 0, (sizeof *this)); | ||
137 | this->hidden = (struct SDL_PrivateAudioData *) | ||
138 | SDL_malloc((sizeof *this->hidden)); | ||
139 | } | ||
140 | if ( (this == NULL) || (this->hidden == NULL) ) { | ||
141 | SDL_OutOfMemory(); | ||
142 | if ( this ) { | ||
143 | SDL_free(this); | ||
144 | } | ||
145 | return(0); | ||
146 | } | ||
147 | SDL_memset(this->hidden, 0, (sizeof *this->hidden)); | ||
148 | |||
149 | /* Set the function pointers */ | ||
150 | this->OpenAudio = Mint_OpenAudio; | ||
151 | this->CloseAudio = Mint_CloseAudio; | ||
152 | this->LockAudio = Mint_LockAudio; | ||
153 | this->UnlockAudio = Mint_UnlockAudio; | ||
154 | this->free = Audio_DeleteDevice; | ||
155 | |||
156 | return this; | ||
157 | } | ||
158 | |||
159 | AudioBootStrap MINTAUDIO_XBIOS_bootstrap = { | ||
160 | MINT_AUDIO_DRIVER_NAME, "MiNT XBIOS audio driver", | ||
161 | Audio_Available, Audio_CreateDevice | ||
162 | }; | ||
163 | |||
164 | static void Mint_LockAudio(_THIS) | ||
165 | { | ||
166 | /* Stop replay */ | ||
167 | Buffoper(0); | ||
168 | } | ||
169 | |||
170 | static void Mint_UnlockAudio(_THIS) | ||
171 | { | ||
172 | /* Restart replay */ | ||
173 | Buffoper(SB_PLA_ENA|SB_PLA_RPT); | ||
174 | } | ||
175 | |||
176 | static void Mint_CloseAudio(_THIS) | ||
177 | { | ||
178 | /* Stop replay */ | ||
179 | SDL_MintAudio_WaitThread(); | ||
180 | Buffoper(0); | ||
181 | |||
182 | if (!SDL_MintAudio_mint_present) { | ||
183 | /* Uninstall interrupt */ | ||
184 | Jdisint(MFP_DMASOUND); | ||
185 | } | ||
186 | |||
187 | /* Wait if currently playing sound */ | ||
188 | while (SDL_MintAudio_mutex != 0) { | ||
189 | } | ||
190 | |||
191 | /* Clear buffers */ | ||
192 | if (SDL_MintAudio_audiobuf[0]) { | ||
193 | Mfree(SDL_MintAudio_audiobuf[0]); | ||
194 | SDL_MintAudio_audiobuf[0] = SDL_MintAudio_audiobuf[1] = NULL; | ||
195 | } | ||
196 | |||
197 | /* Unlock sound system */ | ||
198 | Unlocksnd(); | ||
199 | } | ||
200 | |||
201 | /* Falcon XBIOS implementation of Devconnect() is buggy with external clock */ | ||
202 | static void Devconnect2(int src, int dst, int sclk, int pre) | ||
203 | { | ||
204 | static const unsigned short MASK1[3] = { 0, 0x6000, 0 }; | ||
205 | static const unsigned short MASK2[4] = { 0xFFF0, 0xFF8F, 0xF0FF, 0x0FFF }; | ||
206 | static const unsigned short INDEX1[4] = { 1, 3, 5, 7 }; | ||
207 | static const unsigned short INDEX2[4] = { 0, 2, 4, 6 }; | ||
208 | unsigned short sync_div,dev_ctrl,dest_ctrl; | ||
209 | void *oldstack; | ||
210 | |||
211 | if (dst==0) { | ||
212 | return; | ||
213 | } | ||
214 | |||
215 | oldstack=(void *)Super(0); | ||
216 | |||
217 | dev_ctrl = DMAAUDIO_IO.dev_ctrl; | ||
218 | dest_ctrl = DMAAUDIO_IO.dest_ctrl; | ||
219 | dev_ctrl &= MASK2[src]; | ||
220 | |||
221 | if (src==ADC) { | ||
222 | dev_ctrl |= MASK1[sclk]; | ||
223 | } else { | ||
224 | dev_ctrl |= (INDEX1[sclk] << (src<<4)); | ||
225 | } | ||
226 | |||
227 | if (dst & DMAREC) { | ||
228 | dest_ctrl &= 0xFFF0; | ||
229 | dest_ctrl |= INDEX1[src]; | ||
230 | } | ||
231 | |||
232 | if (dst & DSPRECV) { | ||
233 | dest_ctrl &= 0xFF8F; | ||
234 | dest_ctrl |= (INDEX1[src]<<4); | ||
235 | } | ||
236 | |||
237 | if (dst & EXTOUT) { | ||
238 | dest_ctrl &= 0xF0FF; | ||
239 | dest_ctrl |= (INDEX1[src]<<8); | ||
240 | } | ||
241 | |||
242 | if (dst & DAC) { | ||
243 | dev_ctrl &= 0x0FFF; | ||
244 | dev_ctrl |= MASK1[sclk]; | ||
245 | dest_ctrl &= 0x0FFF; | ||
246 | dest_ctrl |= (INDEX2[src]<<12); | ||
247 | } | ||
248 | |||
249 | sync_div = DMAAUDIO_IO.sync_div; | ||
250 | if (sclk==CLKEXT) { | ||
251 | pre<<=8; | ||
252 | sync_div &= 0xF0FF; | ||
253 | } else { | ||
254 | sync_div &= 0xFFF0; | ||
255 | } | ||
256 | sync_div |= pre; | ||
257 | |||
258 | DMAAUDIO_IO.dev_ctrl = dev_ctrl; | ||
259 | DMAAUDIO_IO.dest_ctrl = dest_ctrl; | ||
260 | DMAAUDIO_IO.sync_div = sync_div; | ||
261 | |||
262 | SuperToUser(oldstack); | ||
263 | } | ||
264 | |||
265 | static void Mint_CheckExternalClock(_THIS) | ||
266 | { | ||
267 | #define SIZE_BUF_CLOCK_MEASURE (44100/10) | ||
268 | |||
269 | char *buffer; | ||
270 | int i, j; | ||
271 | |||
272 | /* DSP present with its GPIO port ? */ | ||
273 | if ((cookie_snd & SND_DSP)==0) { | ||
274 | return; | ||
275 | } | ||
276 | |||
277 | buffer = Atari_SysMalloc(SIZE_BUF_CLOCK_MEASURE, MX_STRAM); | ||
278 | if (buffer==NULL) { | ||
279 | DEBUG_PRINT((DEBUG_NAME "Not enough memory for the measure\n")); | ||
280 | return; | ||
281 | } | ||
282 | SDL_memset(buffer, 0, SIZE_BUF_CLOCK_MEASURE); | ||
283 | |||
284 | Buffoper(0); | ||
285 | Settracks(0,0); | ||
286 | Setmontracks(0); | ||
287 | Setmode(MONO8); | ||
288 | Jdisint(MFP_TIMERA); | ||
289 | |||
290 | for (i=0; i<2; i++) { | ||
291 | Gpio(GPIO_SET,7); /* DSP port gpio outputs */ | ||
292 | Gpio(GPIO_WRITE,2+i); /* 22.5792/24.576 MHz for 44.1/48KHz */ | ||
293 | Devconnect2(DMAPLAY, DAC, CLKEXT, CLK50K); /* Matrix and clock source */ | ||
294 | Setbuffer(0, buffer, buffer + SIZE_BUF_CLOCK_MEASURE); /* Set buffer */ | ||
295 | Xbtimer(XB_TIMERA, 5, 38, SDL_MintAudio_XbiosInterruptMeasureClock); /* delay mode timer A, prediv /64, 1KHz */ | ||
296 | Jenabint(MFP_TIMERA); | ||
297 | SDL_MintAudio_clocktics = 0; | ||
298 | Buffoper(SB_PLA_ENA); | ||
299 | usleep(110000); | ||
300 | |||
301 | if((Buffoper(-1) & 1)==0) { | ||
302 | if (SDL_MintAudio_clocktics) { | ||
303 | unsigned long khz; | ||
304 | |||
305 | khz = ((SIZE_BUF_CLOCK_MEASURE/SDL_MintAudio_clocktics) +1) & 0xFFFFFFFE; | ||
306 | DEBUG_PRINT((DEBUG_NAME "measure %d: freq=%lu KHz\n", i+1, khz)); | ||
307 | |||
308 | if(khz==44) { | ||
309 | for (j=1; j<4; j++) { | ||
310 | SDL_MintAudio_AddFrequency(this, MASTERCLOCK_44K/(MASTERPREDIV_FALCON*(1<<j)), MASTERCLOCK_44K, (1<<j)-1, 2+i); | ||
311 | } | ||
312 | } else if (khz==48) { | ||
313 | for (j=1; j<4; j++) { | ||
314 | SDL_MintAudio_AddFrequency(this, MASTERCLOCK_48K/(MASTERPREDIV_FALCON*(1<<j)), MASTERCLOCK_48K, (1<<j)-1, 2+i); | ||
315 | } | ||
316 | } | ||
317 | } else { | ||
318 | DEBUG_PRINT((DEBUG_NAME "No measure\n")); | ||
319 | } | ||
320 | } else { | ||
321 | DEBUG_PRINT((DEBUG_NAME "No SDMA clock\n")); | ||
322 | } | ||
323 | |||
324 | Buffoper(0); /* stop */ | ||
325 | Jdisint(MFP_TIMERA); /* Uninstall interrupt */ | ||
326 | } | ||
327 | |||
328 | Mfree(buffer); | ||
329 | } | ||
330 | |||
331 | static int Mint_CheckAudio(_THIS, SDL_AudioSpec *spec) | ||
332 | { | ||
333 | int i; | ||
334 | |||
335 | DEBUG_PRINT((DEBUG_NAME "asked: %d bits, ",spec->format & 0x00ff)); | ||
336 | DEBUG_PRINT(("signed=%d, ", ((spec->format & 0x8000)!=0))); | ||
337 | DEBUG_PRINT(("big endian=%d, ", ((spec->format & 0x1000)!=0))); | ||
338 | DEBUG_PRINT(("channels=%d, ", spec->channels)); | ||
339 | DEBUG_PRINT(("freq=%d\n", spec->freq)); | ||
340 | |||
341 | if (spec->channels > 2) { | ||
342 | spec->channels = 2; /* no more than stereo! */ | ||
343 | } | ||
344 | |||
345 | spec->format |= 0x8000; /* Audio is always signed */ | ||
346 | if ((spec->format & 0x00ff)==16) { | ||
347 | spec->format |= 0x1000; /* Audio is always big endian */ | ||
348 | spec->channels=2; /* 16 bits always stereo */ | ||
349 | } | ||
350 | |||
351 | MINTAUDIO_freqcount=0; | ||
352 | |||
353 | /* Add external clocks if present */ | ||
354 | Mint_CheckExternalClock(this); | ||
355 | |||
356 | /* Standard clocks */ | ||
357 | for (i=1;i<12;i++) { | ||
358 | /* Remove unusable Falcon codec predivisors */ | ||
359 | if ((i==6) || (i==8) || (i==10)) { | ||
360 | continue; | ||
361 | } | ||
362 | SDL_MintAudio_AddFrequency(this, MASTERCLOCK_FALCON1/(MASTERPREDIV_FALCON*(i+1)), MASTERCLOCK_FALCON1, i, -1); | ||
363 | } | ||
364 | |||
365 | #if 1 | ||
366 | for (i=0; i<MINTAUDIO_freqcount; i++) { | ||
367 | DEBUG_PRINT((DEBUG_NAME "freq %d: %lu Hz, clock %lu, prediv %d\n", | ||
368 | i, MINTAUDIO_frequencies[i].frequency, MINTAUDIO_frequencies[i].masterclock, | ||
369 | MINTAUDIO_frequencies[i].predivisor | ||
370 | )); | ||
371 | } | ||
372 | #endif | ||
373 | |||
374 | MINTAUDIO_numfreq=SDL_MintAudio_SearchFrequency(this, spec->freq); | ||
375 | spec->freq=MINTAUDIO_frequencies[MINTAUDIO_numfreq].frequency; | ||
376 | |||
377 | DEBUG_PRINT((DEBUG_NAME "obtained: %d bits, ",spec->format & 0x00ff)); | ||
378 | DEBUG_PRINT(("signed=%d, ", ((spec->format & 0x8000)!=0))); | ||
379 | DEBUG_PRINT(("big endian=%d, ", ((spec->format & 0x1000)!=0))); | ||
380 | DEBUG_PRINT(("channels=%d, ", spec->channels)); | ||
381 | DEBUG_PRINT(("freq=%d\n", spec->freq)); | ||
382 | |||
383 | return 0; | ||
384 | } | ||
385 | |||
386 | static void Mint_InitAudio(_THIS, SDL_AudioSpec *spec) | ||
387 | { | ||
388 | int channels_mode, prediv; | ||
389 | void *buffer; | ||
390 | |||
391 | /* Stop currently playing sound */ | ||
392 | SDL_MintAudio_quit_thread = SDL_FALSE; | ||
393 | SDL_MintAudio_thread_finished = SDL_TRUE; | ||
394 | SDL_MintAudio_WaitThread(); | ||
395 | Buffoper(0); | ||
396 | |||
397 | /* Set replay tracks */ | ||
398 | Settracks(0,0); | ||
399 | Setmontracks(0); | ||
400 | |||
401 | /* Select replay format */ | ||
402 | channels_mode=STEREO16; | ||
403 | switch (spec->format & 0xff) { | ||
404 | case 8: | ||
405 | if (spec->channels==2) { | ||
406 | channels_mode=STEREO8; | ||
407 | } else { | ||
408 | channels_mode=MONO8; | ||
409 | } | ||
410 | break; | ||
411 | } | ||
412 | if (Setmode(channels_mode)<0) { | ||
413 | DEBUG_PRINT((DEBUG_NAME "Setmode() failed\n")); | ||
414 | } | ||
415 | |||
416 | prediv = MINTAUDIO_frequencies[MINTAUDIO_numfreq].predivisor; | ||
417 | if (MINTAUDIO_frequencies[MINTAUDIO_numfreq].gpio_bits != -1) { | ||
418 | Gpio(GPIO_SET,7); /* DSP port gpio outputs */ | ||
419 | Gpio(GPIO_WRITE, MINTAUDIO_frequencies[MINTAUDIO_numfreq].gpio_bits); | ||
420 | Devconnect2(DMAPLAY, DAC|EXTOUT, CLKEXT, prediv); | ||
421 | } else { | ||
422 | Devconnect2(DMAPLAY, DAC, CLK25M, prediv); | ||
423 | } | ||
424 | |||
425 | /* Set buffer */ | ||
426 | buffer = SDL_MintAudio_audiobuf[SDL_MintAudio_numbuf]; | ||
427 | if (Setbuffer(0, buffer, buffer + spec->size)<0) { | ||
428 | DEBUG_PRINT((DEBUG_NAME "Setbuffer() failed\n")); | ||
429 | } | ||
430 | |||
431 | if (SDL_MintAudio_mint_present) { | ||
432 | SDL_MintAudio_thread_pid = tfork(SDL_MintAudio_Thread, 0); | ||
433 | } else { | ||
434 | /* Install interrupt */ | ||
435 | Jdisint(MFP_DMASOUND); | ||
436 | /*Xbtimer(XB_TIMERA, 8, 1, SDL_MintAudio_XbiosInterrupt);*/ | ||
437 | Xbtimer(XB_TIMERA, 8, 1, SDL_MintAudio_Dma8Interrupt); | ||
438 | Jenabint(MFP_DMASOUND); | ||
439 | |||
440 | if (Setinterrupt(SI_TIMERA, SI_PLAY)<0) { | ||
441 | DEBUG_PRINT((DEBUG_NAME "Setinterrupt() failed\n")); | ||
442 | } | ||
443 | } | ||
444 | |||
445 | /* Go */ | ||
446 | Buffoper(SB_PLA_ENA|SB_PLA_RPT); | ||
447 | DEBUG_PRINT((DEBUG_NAME "hardware initialized\n")); | ||
448 | } | ||
449 | |||
450 | static int Mint_OpenAudio(_THIS, SDL_AudioSpec *spec) | ||
451 | { | ||
452 | /* Lock sound system */ | ||
453 | if (Locksnd()!=1) { | ||
454 | SDL_SetError("Mint_OpenAudio: Audio system already in use"); | ||
455 | return(-1); | ||
456 | } | ||
457 | |||
458 | SDL_MintAudio_device = this; | ||
459 | |||
460 | /* Check audio capabilities */ | ||
461 | if (Mint_CheckAudio(this, spec)==-1) { | ||
462 | return -1; | ||
463 | } | ||
464 | |||
465 | SDL_CalculateAudioSpec(spec); | ||
466 | |||
467 | /* Allocate memory for audio buffers in DMA-able RAM */ | ||
468 | DEBUG_PRINT((DEBUG_NAME "buffer size=%d\n", spec->size)); | ||
469 | |||
470 | SDL_MintAudio_audiobuf[0] = Atari_SysMalloc(spec->size *2, MX_STRAM); | ||
471 | if (SDL_MintAudio_audiobuf[0]==NULL) { | ||
472 | SDL_SetError("MINT_OpenAudio: Not enough memory for audio buffer"); | ||
473 | return (-1); | ||
474 | } | ||
475 | SDL_MintAudio_audiobuf[1] = SDL_MintAudio_audiobuf[0] + spec->size ; | ||
476 | SDL_MintAudio_numbuf=0; | ||
477 | SDL_memset(SDL_MintAudio_audiobuf[0], spec->silence, spec->size *2); | ||
478 | SDL_MintAudio_audiosize = spec->size; | ||
479 | SDL_MintAudio_mutex = 0; | ||
480 | |||
481 | DEBUG_PRINT((DEBUG_NAME "buffer 0 at 0x%08x\n", SDL_MintAudio_audiobuf[0])); | ||
482 | DEBUG_PRINT((DEBUG_NAME "buffer 1 at 0x%08x\n", SDL_MintAudio_audiobuf[1])); | ||
483 | |||
484 | SDL_MintAudio_CheckFpu(); | ||
485 | |||
486 | /* Setup audio hardware */ | ||
487 | Mint_InitAudio(this, spec); | ||
488 | |||
489 | return(1); /* We don't use SDL threaded audio */ | ||
490 | } | ||
diff --git a/apps/plugins/sdl/src/audio/mme/SDL_mmeaudio.c b/apps/plugins/sdl/src/audio/mme/SDL_mmeaudio.c deleted file mode 100644 index 64a0ecc36d..0000000000 --- a/apps/plugins/sdl/src/audio/mme/SDL_mmeaudio.c +++ /dev/null | |||
@@ -1,264 +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 | /* Tru64 UNIX MME support */ | ||
25 | #include <mme_api.h> | ||
26 | |||
27 | #include "SDL_timer.h" | ||
28 | #include "SDL_audio.h" | ||
29 | #include "../SDL_audio_c.h" | ||
30 | #include "SDL_mmeaudio.h" | ||
31 | |||
32 | static BOOL inUse[NUM_BUFFERS]; | ||
33 | |||
34 | /* Audio driver functions */ | ||
35 | static int MME_OpenAudio(_THIS, SDL_AudioSpec *spec); | ||
36 | static void MME_WaitAudio(_THIS); | ||
37 | static Uint8 *MME_GetAudioBuf(_THIS); | ||
38 | static void MME_PlayAudio(_THIS); | ||
39 | static void MME_WaitDone(_THIS); | ||
40 | static void MME_CloseAudio(_THIS); | ||
41 | |||
42 | /* Audio driver bootstrap functions */ | ||
43 | static int Audio_Available(void) | ||
44 | { | ||
45 | return(1); | ||
46 | } | ||
47 | |||
48 | static void Audio_DeleteDevice(SDL_AudioDevice *device) | ||
49 | { | ||
50 | if ( device ) { | ||
51 | if ( device->hidden ) { | ||
52 | SDL_free(device->hidden); | ||
53 | device->hidden = NULL; | ||
54 | } | ||
55 | SDL_free(device); | ||
56 | device = NULL; | ||
57 | } | ||
58 | } | ||
59 | |||
60 | static SDL_AudioDevice *Audio_CreateDevice(int devindex) | ||
61 | { | ||
62 | SDL_AudioDevice *this; | ||
63 | |||
64 | /* Initialize all variables that we clean on shutdown */ | ||
65 | this = SDL_malloc(sizeof(SDL_AudioDevice)); | ||
66 | if ( this ) { | ||
67 | SDL_memset(this, 0, (sizeof *this)); | ||
68 | this->hidden = SDL_malloc((sizeof *this->hidden)); | ||
69 | } | ||
70 | if ( (this == NULL) || (this->hidden == NULL) ) { | ||
71 | SDL_OutOfMemory(); | ||
72 | if ( this ) { | ||
73 | SDL_free(this); | ||
74 | } | ||
75 | return(0); | ||
76 | } | ||
77 | SDL_memset(this->hidden, 0, (sizeof *this->hidden)); | ||
78 | /* Set the function pointers */ | ||
79 | this->OpenAudio = MME_OpenAudio; | ||
80 | this->WaitAudio = MME_WaitAudio; | ||
81 | this->PlayAudio = MME_PlayAudio; | ||
82 | this->GetAudioBuf = MME_GetAudioBuf; | ||
83 | this->WaitDone = MME_WaitDone; | ||
84 | this->CloseAudio = MME_CloseAudio; | ||
85 | this->free = Audio_DeleteDevice; | ||
86 | |||
87 | return this; | ||
88 | } | ||
89 | |||
90 | AudioBootStrap MMEAUDIO_bootstrap = { | ||
91 | "waveout", "Tru64 MME WaveOut", | ||
92 | Audio_Available, Audio_CreateDevice | ||
93 | }; | ||
94 | |||
95 | static void SetMMerror(char *function, MMRESULT code) | ||
96 | { | ||
97 | int len; | ||
98 | char errbuf[MAXERRORLENGTH]; | ||
99 | |||
100 | SDL_snprintf(errbuf, SDL_arraysize(errbuf), "%s: ", function); | ||
101 | len = SDL_strlen(errbuf); | ||
102 | waveOutGetErrorText(code, errbuf+len, MAXERRORLENGTH-len); | ||
103 | SDL_SetError("%s",errbuf); | ||
104 | } | ||
105 | |||
106 | static void CALLBACK MME_CALLBACK(HWAVEOUT hwo, | ||
107 | UINT uMsg, | ||
108 | DWORD dwInstance, | ||
109 | LPARAM dwParam1, | ||
110 | LPARAM dwParam2) | ||
111 | { | ||
112 | WAVEHDR *wp = (WAVEHDR *) dwParam1; | ||
113 | |||
114 | if ( uMsg == WOM_DONE ) | ||
115 | inUse[wp->dwUser] = FALSE; | ||
116 | } | ||
117 | |||
118 | static int MME_OpenAudio(_THIS, SDL_AudioSpec *spec) | ||
119 | { | ||
120 | MMRESULT result; | ||
121 | int i; | ||
122 | |||
123 | mixbuf = NULL; | ||
124 | |||
125 | /* Set basic WAVE format parameters */ | ||
126 | shm = mmeAllocMem(sizeof(*shm)); | ||
127 | if ( shm == NULL ) { | ||
128 | SDL_SetError("Out of memory: shm"); | ||
129 | return(-1); | ||
130 | } | ||
131 | shm->sound = 0; | ||
132 | shm->wFmt.wf.wFormatTag = WAVE_FORMAT_PCM; | ||
133 | |||
134 | /* Determine the audio parameters from the AudioSpec */ | ||
135 | switch ( spec->format & 0xFF ) { | ||
136 | case 8: | ||
137 | /* Unsigned 8 bit audio data */ | ||
138 | spec->format = AUDIO_U8; | ||
139 | shm->wFmt.wBitsPerSample = 8; | ||
140 | break; | ||
141 | case 16: | ||
142 | /* Signed 16 bit audio data */ | ||
143 | spec->format = AUDIO_S16; | ||
144 | shm->wFmt.wBitsPerSample = 16; | ||
145 | break; | ||
146 | default: | ||
147 | SDL_SetError("Unsupported audio format"); | ||
148 | return(-1); | ||
149 | } | ||
150 | |||
151 | shm->wFmt.wf.nChannels = spec->channels; | ||
152 | shm->wFmt.wf.nSamplesPerSec = spec->freq; | ||
153 | shm->wFmt.wf.nBlockAlign = | ||
154 | shm->wFmt.wf.nChannels * shm->wFmt.wBitsPerSample / 8; | ||
155 | shm->wFmt.wf.nAvgBytesPerSec = | ||
156 | shm->wFmt.wf.nSamplesPerSec * shm->wFmt.wf.nBlockAlign; | ||
157 | |||
158 | /* Check the buffer size -- minimum of 1/4 second (word aligned) */ | ||
159 | if ( spec->samples < (spec->freq/4) ) | ||
160 | spec->samples = ((spec->freq/4)+3)&~3; | ||
161 | |||
162 | /* Update the fragment size as size in bytes */ | ||
163 | SDL_CalculateAudioSpec(spec); | ||
164 | |||
165 | /* Open the audio device */ | ||
166 | result = waveOutOpen(&(shm->sound), | ||
167 | WAVE_MAPPER, | ||
168 | &(shm->wFmt.wf), | ||
169 | MME_CALLBACK, | ||
170 | NULL, | ||
171 | (CALLBACK_FUNCTION|WAVE_OPEN_SHAREABLE)); | ||
172 | if ( result != MMSYSERR_NOERROR ) { | ||
173 | SetMMerror("waveOutOpen()", result); | ||
174 | return(-1); | ||
175 | } | ||
176 | |||
177 | /* Create the sound buffers */ | ||
178 | mixbuf = (Uint8 *)mmeAllocBuffer(NUM_BUFFERS * (spec->size)); | ||
179 | if ( mixbuf == NULL ) { | ||
180 | SDL_SetError("Out of memory: mixbuf"); | ||
181 | return(-1); | ||
182 | } | ||
183 | |||
184 | for (i = 0; i < NUM_BUFFERS; i++) { | ||
185 | shm->wHdr[i].lpData = &mixbuf[i * (spec->size)]; | ||
186 | shm->wHdr[i].dwBufferLength = spec->size; | ||
187 | shm->wHdr[i].dwFlags = 0; | ||
188 | shm->wHdr[i].dwUser = i; | ||
189 | shm->wHdr[i].dwLoops = 0; /* loop control counter */ | ||
190 | shm->wHdr[i].lpNext = NULL; /* reserved for driver */ | ||
191 | shm->wHdr[i].reserved = 0; | ||
192 | inUse[i] = FALSE; | ||
193 | } | ||
194 | next_buffer = 0; | ||
195 | return 0; | ||
196 | } | ||
197 | |||
198 | static void MME_WaitAudio(_THIS) | ||
199 | { | ||
200 | while ( inUse[next_buffer] ) { | ||
201 | mmeWaitForCallbacks(); | ||
202 | mmeProcessCallbacks(); | ||
203 | } | ||
204 | } | ||
205 | |||
206 | static Uint8 *MME_GetAudioBuf(_THIS) | ||
207 | { | ||
208 | Uint8 *retval; | ||
209 | |||
210 | inUse[next_buffer] = TRUE; | ||
211 | retval = (Uint8 *)(shm->wHdr[next_buffer].lpData); | ||
212 | return retval; | ||
213 | } | ||
214 | |||
215 | static void MME_PlayAudio(_THIS) | ||
216 | { | ||
217 | /* Queue it up */ | ||
218 | waveOutWrite(shm->sound, &(shm->wHdr[next_buffer]), sizeof(WAVEHDR)); | ||
219 | next_buffer = (next_buffer+1)%NUM_BUFFERS; | ||
220 | } | ||
221 | |||
222 | static void MME_WaitDone(_THIS) | ||
223 | { | ||
224 | MMRESULT result; | ||
225 | int i; | ||
226 | |||
227 | if ( shm->sound ) { | ||
228 | for (i = 0; i < NUM_BUFFERS; i++) | ||
229 | while ( inUse[i] ) { | ||
230 | mmeWaitForCallbacks(); | ||
231 | mmeProcessCallbacks(); | ||
232 | } | ||
233 | result = waveOutReset(shm->sound); | ||
234 | if ( result != MMSYSERR_NOERROR ) | ||
235 | SetMMerror("waveOutReset()", result); | ||
236 | mmeProcessCallbacks(); | ||
237 | } | ||
238 | } | ||
239 | |||
240 | static void MME_CloseAudio(_THIS) | ||
241 | { | ||
242 | MMRESULT result; | ||
243 | |||
244 | if ( mixbuf ) { | ||
245 | result = mmeFreeBuffer(mixbuf); | ||
246 | if (result != MMSYSERR_NOERROR ) | ||
247 | SetMMerror("mmeFreeBuffer", result); | ||
248 | mixbuf = NULL; | ||
249 | } | ||
250 | |||
251 | if ( shm ) { | ||
252 | if ( shm->sound ) { | ||
253 | result = waveOutClose(shm->sound); | ||
254 | if (result != MMSYSERR_NOERROR ) | ||
255 | SetMMerror("waveOutClose()", result); | ||
256 | mmeProcessCallbacks(); | ||
257 | } | ||
258 | result = mmeFreeMem(shm); | ||
259 | if (result != MMSYSERR_NOERROR ) | ||
260 | SetMMerror("mmeFreeMem()", result); | ||
261 | shm = NULL; | ||
262 | } | ||
263 | } | ||
264 | |||
diff --git a/apps/plugins/sdl/src/audio/mme/SDL_mmeaudio.h b/apps/plugins/sdl/src/audio/mme/SDL_mmeaudio.h deleted file mode 100644 index 6bfaed32e0..0000000000 --- a/apps/plugins/sdl/src/audio/mme/SDL_mmeaudio.h +++ /dev/null | |||
@@ -1,51 +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 | #ifndef _SDL_lowaudio_h | ||
27 | #define _SDL_lowaudio_h | ||
28 | |||
29 | #include "../SDL_sysaudio.h" | ||
30 | |||
31 | /* Hidden "this" pointer for the video functions */ | ||
32 | #define _THIS SDL_AudioDevice *this | ||
33 | #define NUM_BUFFERS 2 | ||
34 | |||
35 | struct SharedMem { | ||
36 | HWAVEOUT sound; | ||
37 | WAVEHDR wHdr[NUM_BUFFERS]; | ||
38 | PCMWAVEFORMAT wFmt; | ||
39 | }; | ||
40 | |||
41 | struct SDL_PrivateAudioData { | ||
42 | Uint8 *mixbuf; /* The raw allocated mixing buffer */ | ||
43 | struct SharedMem *shm; | ||
44 | int next_buffer; | ||
45 | }; | ||
46 | |||
47 | #define shm (this->hidden->shm) | ||
48 | #define mixbuf (this->hidden->mixbuf) | ||
49 | #define next_buffer (this->hidden->next_buffer) | ||
50 | /* Old variable names */ | ||
51 | #endif /* _SDL_lowaudio_h */ | ||
diff --git a/apps/plugins/sdl/src/audio/nas/SDL_nasaudio.c b/apps/plugins/sdl/src/audio/nas/SDL_nasaudio.c deleted file mode 100644 index a561e62984..0000000000 --- a/apps/plugins/sdl/src/audio/nas/SDL_nasaudio.c +++ /dev/null | |||
@@ -1,423 +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 Lesser General Public | ||
7 | License as published by the Free Software Foundation; either | ||
8 | version 2.1 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 | Lesser General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU Lesser General Public | ||
16 | License along with this library; if not, write to the Free Software | ||
17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
18 | |||
19 | Sam Lantinga | ||
20 | slouken@libsdl.org | ||
21 | |||
22 | This driver was written by: | ||
23 | Erik Inge Bolsø | ||
24 | knan@mo.himolde.no | ||
25 | */ | ||
26 | #include "SDL_config.h" | ||
27 | |||
28 | /* Allow access to a raw mixing buffer */ | ||
29 | |||
30 | #include <signal.h> | ||
31 | #include <unistd.h> | ||
32 | |||
33 | #include "SDL_timer.h" | ||
34 | #include "SDL_audio.h" | ||
35 | #include "../SDL_audiomem.h" | ||
36 | #include "../SDL_audio_c.h" | ||
37 | #include "../SDL_audiodev_c.h" | ||
38 | #include "SDL_nasaudio.h" | ||
39 | |||
40 | #ifdef SDL_AUDIO_DRIVER_NAS_DYNAMIC | ||
41 | #include "SDL_loadso.h" | ||
42 | #endif | ||
43 | |||
44 | /* The tag name used by artsc audio */ | ||
45 | #define NAS_DRIVER_NAME "nas" | ||
46 | |||
47 | static struct SDL_PrivateAudioData *this2 = NULL; | ||
48 | |||
49 | static void (*NAS_AuCloseServer) (AuServer *); | ||
50 | static void (*NAS_AuNextEvent) (AuServer *, AuBool, AuEvent *); | ||
51 | static AuBool(*NAS_AuDispatchEvent) (AuServer *, AuEvent *); | ||
52 | static AuFlowID(*NAS_AuCreateFlow) (AuServer *, AuStatus *); | ||
53 | static void (*NAS_AuStartFlow) (AuServer *, AuFlowID, AuStatus *); | ||
54 | static void (*NAS_AuSetElements) | ||
55 | (AuServer *, AuFlowID, AuBool, int, AuElement *, AuStatus *); | ||
56 | static void (*NAS_AuWriteElement) | ||
57 | (AuServer *, AuFlowID, int, AuUint32, AuPointer, AuBool, AuStatus *); | ||
58 | static AuServer *(*NAS_AuOpenServer) | ||
59 | (_AuConst char *, int, _AuConst char *, int, _AuConst char *, char **); | ||
60 | static AuEventHandlerRec *(*NAS_AuRegisterEventHandler) | ||
61 | (AuServer *, AuMask, int, AuID, AuEventHandlerCallback, AuPointer); | ||
62 | |||
63 | |||
64 | #ifdef SDL_AUDIO_DRIVER_NAS_DYNAMIC | ||
65 | |||
66 | static const char *nas_library = SDL_AUDIO_DRIVER_NAS_DYNAMIC; | ||
67 | static void *nas_handle = NULL; | ||
68 | |||
69 | static int | ||
70 | load_nas_sym(const char *fn, void **addr) | ||
71 | { | ||
72 | *addr = SDL_LoadFunction(nas_handle, fn); | ||
73 | if (*addr == NULL) { | ||
74 | return 0; | ||
75 | } | ||
76 | return 1; | ||
77 | } | ||
78 | |||
79 | /* cast funcs to char* first, to please GCC's strict aliasing rules. */ | ||
80 | #define SDL_NAS_SYM(x) \ | ||
81 | if (!load_nas_sym(#x, (void **) (char *) &NAS_##x)) return -1 | ||
82 | #else | ||
83 | #define SDL_NAS_SYM(x) NAS_##x = x | ||
84 | #endif | ||
85 | |||
86 | static int | ||
87 | load_nas_syms(void) | ||
88 | { | ||
89 | SDL_NAS_SYM(AuCloseServer); | ||
90 | SDL_NAS_SYM(AuNextEvent); | ||
91 | SDL_NAS_SYM(AuDispatchEvent); | ||
92 | SDL_NAS_SYM(AuCreateFlow); | ||
93 | SDL_NAS_SYM(AuStartFlow); | ||
94 | SDL_NAS_SYM(AuSetElements); | ||
95 | SDL_NAS_SYM(AuWriteElement); | ||
96 | SDL_NAS_SYM(AuOpenServer); | ||
97 | SDL_NAS_SYM(AuRegisterEventHandler); | ||
98 | return 0; | ||
99 | } | ||
100 | |||
101 | #undef SDL_NAS_SYM | ||
102 | |||
103 | #ifdef SDL_AUDIO_DRIVER_NAS_DYNAMIC | ||
104 | |||
105 | static void | ||
106 | UnloadNASLibrary(void) | ||
107 | { | ||
108 | if (nas_handle != NULL) { | ||
109 | SDL_UnloadObject(nas_handle); | ||
110 | nas_handle = NULL; | ||
111 | } | ||
112 | } | ||
113 | |||
114 | static int | ||
115 | LoadNASLibrary(void) | ||
116 | { | ||
117 | int retval = 0; | ||
118 | if (nas_handle == NULL) { | ||
119 | nas_handle = SDL_LoadObject(nas_library); | ||
120 | if (nas_handle == NULL) { | ||
121 | /* Copy error string so we can use it in a new SDL_SetError(). */ | ||
122 | char *origerr = SDL_GetError(); | ||
123 | size_t len = SDL_strlen(origerr) + 1; | ||
124 | char *err = (char *) alloca(len); | ||
125 | SDL_strlcpy(err, origerr, len); | ||
126 | retval = -1; | ||
127 | SDL_SetError("NAS: SDL_LoadObject('%s') failed: %s\n", | ||
128 | nas_library, err); | ||
129 | } else { | ||
130 | retval = load_nas_syms(); | ||
131 | if (retval < 0) { | ||
132 | UnloadNASLibrary(); | ||
133 | } | ||
134 | } | ||
135 | } | ||
136 | return retval; | ||
137 | } | ||
138 | |||
139 | #else | ||
140 | |||
141 | static void | ||
142 | UnloadNASLibrary(void) | ||
143 | { | ||
144 | } | ||
145 | |||
146 | static int | ||
147 | LoadNASLibrary(void) | ||
148 | { | ||
149 | load_nas_syms(); | ||
150 | return 0; | ||
151 | } | ||
152 | |||
153 | #endif /* SDL_AUDIO_DRIVER_NAS_DYNAMIC */ | ||
154 | |||
155 | |||
156 | /* Audio driver functions */ | ||
157 | static int NAS_OpenAudio(_THIS, SDL_AudioSpec *spec); | ||
158 | static void NAS_WaitAudio(_THIS); | ||
159 | static void NAS_PlayAudio(_THIS); | ||
160 | static Uint8 *NAS_GetAudioBuf(_THIS); | ||
161 | static void NAS_CloseAudio(_THIS); | ||
162 | |||
163 | /* Audio driver bootstrap functions */ | ||
164 | |||
165 | static int Audio_Available(void) | ||
166 | { | ||
167 | if (LoadNASLibrary() == 0) { | ||
168 | AuServer *aud = NAS_AuOpenServer("", 0, NULL, 0, NULL, NULL); | ||
169 | if (!aud) { | ||
170 | UnloadNASLibrary(); | ||
171 | return 0; | ||
172 | } | ||
173 | NAS_AuCloseServer(aud); | ||
174 | UnloadNASLibrary(); | ||
175 | return 1; | ||
176 | } | ||
177 | return 0; | ||
178 | } | ||
179 | |||
180 | static void Audio_DeleteDevice(SDL_AudioDevice *device) | ||
181 | { | ||
182 | UnloadNASLibrary(); | ||
183 | SDL_free(device->hidden); | ||
184 | SDL_free(device); | ||
185 | } | ||
186 | |||
187 | static SDL_AudioDevice *Audio_CreateDevice(int devindex) | ||
188 | { | ||
189 | SDL_AudioDevice *this; | ||
190 | |||
191 | if (LoadNASLibrary() < 0) { | ||
192 | return NULL; | ||
193 | } | ||
194 | |||
195 | /* Initialize all variables that we clean on shutdown */ | ||
196 | this = (SDL_AudioDevice *)SDL_malloc(sizeof(SDL_AudioDevice)); | ||
197 | if ( this ) { | ||
198 | SDL_memset(this, 0, (sizeof *this)); | ||
199 | this->hidden = (struct SDL_PrivateAudioData *) | ||
200 | SDL_malloc((sizeof *this->hidden)); | ||
201 | } | ||
202 | if ( (this == NULL) || (this->hidden == NULL) ) { | ||
203 | SDL_OutOfMemory(); | ||
204 | if ( this ) { | ||
205 | SDL_free(this); | ||
206 | } | ||
207 | return NULL; | ||
208 | } | ||
209 | SDL_memset(this->hidden, 0, (sizeof *this->hidden)); | ||
210 | |||
211 | /* Set the function pointers */ | ||
212 | this->OpenAudio = NAS_OpenAudio; | ||
213 | this->WaitAudio = NAS_WaitAudio; | ||
214 | this->PlayAudio = NAS_PlayAudio; | ||
215 | this->GetAudioBuf = NAS_GetAudioBuf; | ||
216 | this->CloseAudio = NAS_CloseAudio; | ||
217 | |||
218 | this->free = Audio_DeleteDevice; | ||
219 | |||
220 | return this; | ||
221 | } | ||
222 | |||
223 | AudioBootStrap NAS_bootstrap = { | ||
224 | NAS_DRIVER_NAME, "Network Audio System", | ||
225 | Audio_Available, Audio_CreateDevice | ||
226 | }; | ||
227 | |||
228 | /* This function waits until it is possible to write a full sound buffer */ | ||
229 | static void NAS_WaitAudio(_THIS) | ||
230 | { | ||
231 | while ( this->hidden->buf_free < this->hidden->mixlen ) { | ||
232 | AuEvent ev; | ||
233 | NAS_AuNextEvent(this->hidden->aud, AuTrue, &ev); | ||
234 | NAS_AuDispatchEvent(this->hidden->aud, &ev); | ||
235 | } | ||
236 | } | ||
237 | |||
238 | static void NAS_PlayAudio(_THIS) | ||
239 | { | ||
240 | while (this->hidden->mixlen > this->hidden->buf_free) { /* We think the buffer is full? Yikes! Ask the server for events, | ||
241 | in the hope that some of them is LowWater events telling us more | ||
242 | of the buffer is free now than what we think. */ | ||
243 | AuEvent ev; | ||
244 | NAS_AuNextEvent(this->hidden->aud, AuTrue, &ev); | ||
245 | NAS_AuDispatchEvent(this->hidden->aud, &ev); | ||
246 | } | ||
247 | this->hidden->buf_free -= this->hidden->mixlen; | ||
248 | |||
249 | /* Write the audio data */ | ||
250 | NAS_AuWriteElement(this->hidden->aud, this->hidden->flow, 0, this->hidden->mixlen, this->hidden->mixbuf, AuFalse, NULL); | ||
251 | |||
252 | this->hidden->written += this->hidden->mixlen; | ||
253 | |||
254 | #ifdef DEBUG_AUDIO | ||
255 | fprintf(stderr, "Wrote %d bytes of audio data\n", this->hidden->mixlen); | ||
256 | #endif | ||
257 | } | ||
258 | |||
259 | static Uint8 *NAS_GetAudioBuf(_THIS) | ||
260 | { | ||
261 | return(this->hidden->mixbuf); | ||
262 | } | ||
263 | |||
264 | static void NAS_CloseAudio(_THIS) | ||
265 | { | ||
266 | if ( this->hidden->mixbuf != NULL ) { | ||
267 | SDL_FreeAudioMem(this->hidden->mixbuf); | ||
268 | this->hidden->mixbuf = NULL; | ||
269 | } | ||
270 | if ( this->hidden->aud ) { | ||
271 | NAS_AuCloseServer(this->hidden->aud); | ||
272 | this->hidden->aud = 0; | ||
273 | } | ||
274 | } | ||
275 | |||
276 | static unsigned char sdlformat_to_auformat(unsigned int fmt) | ||
277 | { | ||
278 | switch (fmt) | ||
279 | { | ||
280 | case AUDIO_U8: | ||
281 | return AuFormatLinearUnsigned8; | ||
282 | case AUDIO_S8: | ||
283 | return AuFormatLinearSigned8; | ||
284 | case AUDIO_U16LSB: | ||
285 | return AuFormatLinearUnsigned16LSB; | ||
286 | case AUDIO_U16MSB: | ||
287 | return AuFormatLinearUnsigned16MSB; | ||
288 | case AUDIO_S16LSB: | ||
289 | return AuFormatLinearSigned16LSB; | ||
290 | case AUDIO_S16MSB: | ||
291 | return AuFormatLinearSigned16MSB; | ||
292 | } | ||
293 | return AuNone; | ||
294 | } | ||
295 | |||
296 | static AuBool | ||
297 | event_handler(AuServer* aud, AuEvent* ev, AuEventHandlerRec* hnd) | ||
298 | { | ||
299 | switch (ev->type) { | ||
300 | case AuEventTypeElementNotify: { | ||
301 | AuElementNotifyEvent* event = (AuElementNotifyEvent *)ev; | ||
302 | |||
303 | switch (event->kind) { | ||
304 | case AuElementNotifyKindLowWater: | ||
305 | if (this2->buf_free >= 0) { | ||
306 | this2->really += event->num_bytes; | ||
307 | gettimeofday(&this2->last_tv, 0); | ||
308 | this2->buf_free += event->num_bytes; | ||
309 | } else { | ||
310 | this2->buf_free = event->num_bytes; | ||
311 | } | ||
312 | break; | ||
313 | case AuElementNotifyKindState: | ||
314 | switch (event->cur_state) { | ||
315 | case AuStatePause: | ||
316 | if (event->reason != AuReasonUser) { | ||
317 | if (this2->buf_free >= 0) { | ||
318 | this2->really += event->num_bytes; | ||
319 | gettimeofday(&this2->last_tv, 0); | ||
320 | this2->buf_free += event->num_bytes; | ||
321 | } else { | ||
322 | this2->buf_free = event->num_bytes; | ||
323 | } | ||
324 | } | ||
325 | break; | ||
326 | } | ||
327 | } | ||
328 | } | ||
329 | } | ||
330 | return AuTrue; | ||
331 | } | ||
332 | |||
333 | static AuDeviceID | ||
334 | find_device(_THIS, int nch) | ||
335 | { | ||
336 | /* These "Au" things are all macros, not functions... */ | ||
337 | int i; | ||
338 | for (i = 0; i < AuServerNumDevices(this->hidden->aud); i++) { | ||
339 | if ((AuDeviceKind(AuServerDevice(this->hidden->aud, i)) == | ||
340 | AuComponentKindPhysicalOutput) && | ||
341 | AuDeviceNumTracks(AuServerDevice(this->hidden->aud, i)) == nch) { | ||
342 | return AuDeviceIdentifier(AuServerDevice(this->hidden->aud, i)); | ||
343 | } | ||
344 | } | ||
345 | return AuNone; | ||
346 | } | ||
347 | |||
348 | static int NAS_OpenAudio(_THIS, SDL_AudioSpec *spec) | ||
349 | { | ||
350 | AuElement elms[3]; | ||
351 | int buffer_size; | ||
352 | Uint16 test_format, format; | ||
353 | |||
354 | this->hidden->mixbuf = NULL; | ||
355 | |||
356 | /* Try for a closest match on audio format */ | ||
357 | format = 0; | ||
358 | for ( test_format = SDL_FirstAudioFormat(spec->format); | ||
359 | ! format && test_format; ) { | ||
360 | format = sdlformat_to_auformat(test_format); | ||
361 | |||
362 | if (format == AuNone) { | ||
363 | test_format = SDL_NextAudioFormat(); | ||
364 | } | ||
365 | } | ||
366 | if ( format == 0 ) { | ||
367 | SDL_SetError("Couldn't find any hardware audio formats"); | ||
368 | return(-1); | ||
369 | } | ||
370 | spec->format = test_format; | ||
371 | |||
372 | this->hidden->aud = NAS_AuOpenServer("", 0, NULL, 0, NULL, NULL); | ||
373 | if (this->hidden->aud == 0) | ||
374 | { | ||
375 | SDL_SetError("Couldn't open connection to NAS server"); | ||
376 | return (-1); | ||
377 | } | ||
378 | |||
379 | this->hidden->dev = find_device(this, spec->channels); | ||
380 | if ((this->hidden->dev == AuNone) || (!(this->hidden->flow = NAS_AuCreateFlow(this->hidden->aud, NULL)))) { | ||
381 | NAS_AuCloseServer(this->hidden->aud); | ||
382 | this->hidden->aud = 0; | ||
383 | SDL_SetError("Couldn't find a fitting playback device on NAS server"); | ||
384 | return (-1); | ||
385 | } | ||
386 | |||
387 | buffer_size = spec->freq; | ||
388 | if (buffer_size < 4096) | ||
389 | buffer_size = 4096; | ||
390 | |||
391 | if (buffer_size > 32768) | ||
392 | buffer_size = 32768; /* So that the buffer won't get unmanageably big. */ | ||
393 | |||
394 | /* Calculate the final parameters for this audio specification */ | ||
395 | SDL_CalculateAudioSpec(spec); | ||
396 | |||
397 | this2 = this->hidden; | ||
398 | |||
399 | /* These "Au" things without a NAS_ prefix are macros, not functions... */ | ||
400 | AuMakeElementImportClient(elms, spec->freq, format, spec->channels, AuTrue, | ||
401 | buffer_size, buffer_size / 4, 0, NULL); | ||
402 | AuMakeElementExportDevice(elms+1, 0, this->hidden->dev, spec->freq, | ||
403 | AuUnlimitedSamples, 0, NULL); | ||
404 | NAS_AuSetElements(this->hidden->aud, this->hidden->flow, AuTrue, 2, elms, NULL); | ||
405 | NAS_AuRegisterEventHandler(this->hidden->aud, AuEventHandlerIDMask, 0, this->hidden->flow, | ||
406 | event_handler, (AuPointer) NULL); | ||
407 | |||
408 | NAS_AuStartFlow(this->hidden->aud, this->hidden->flow, NULL); | ||
409 | |||
410 | /* Allocate mixing buffer */ | ||
411 | this->hidden->mixlen = spec->size; | ||
412 | this->hidden->mixbuf = (Uint8 *)SDL_AllocAudioMem(this->hidden->mixlen); | ||
413 | if ( this->hidden->mixbuf == NULL ) { | ||
414 | return(-1); | ||
415 | } | ||
416 | SDL_memset(this->hidden->mixbuf, spec->silence, spec->size); | ||
417 | |||
418 | /* Get the parent process id (we're the parent of the audio thread) */ | ||
419 | this->hidden->parent = getpid(); | ||
420 | |||
421 | /* We're ready to rock and roll. :-) */ | ||
422 | return(0); | ||
423 | } | ||
diff --git a/apps/plugins/sdl/src/audio/nas/SDL_nasaudio.h b/apps/plugins/sdl/src/audio/nas/SDL_nasaudio.h deleted file mode 100644 index 1c09630880..0000000000 --- a/apps/plugins/sdl/src/audio/nas/SDL_nasaudio.h +++ /dev/null | |||
@@ -1,62 +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 Lesser General Public | ||
7 | License as published by the Free Software Foundation; either | ||
8 | version 2.1 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 | Lesser General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU Lesser General Public | ||
16 | License along with this library; if not, write to the Free Software | ||
17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
18 | |||
19 | Sam Lantinga | ||
20 | slouken@libsdl.org | ||
21 | |||
22 | This driver was written by: | ||
23 | Erik Inge Bolsø | ||
24 | knan@mo.himolde.no | ||
25 | */ | ||
26 | #include "SDL_config.h" | ||
27 | |||
28 | #ifndef _SDL_nasaudio_h | ||
29 | #define _SDL_nasaudio_h | ||
30 | |||
31 | #ifdef __sgi | ||
32 | #include <nas/audiolib.h> | ||
33 | #else | ||
34 | #include <audio/audiolib.h> | ||
35 | #endif | ||
36 | #include <sys/time.h> | ||
37 | |||
38 | #include "../SDL_sysaudio.h" | ||
39 | |||
40 | /* Hidden "this" pointer for the video functions */ | ||
41 | #define _THIS SDL_AudioDevice *this | ||
42 | |||
43 | struct SDL_PrivateAudioData { | ||
44 | AuServer* aud; | ||
45 | AuFlowID flow; | ||
46 | AuDeviceID dev; | ||
47 | |||
48 | /* The parent process id, to detect when application quits */ | ||
49 | pid_t parent; | ||
50 | |||
51 | /* Raw mixing buffer */ | ||
52 | Uint8 *mixbuf; | ||
53 | int mixlen; | ||
54 | |||
55 | int written; | ||
56 | int really; | ||
57 | int bps; | ||
58 | struct timeval last_tv; | ||
59 | int buf_free; | ||
60 | }; | ||
61 | #endif /* _SDL_nasaudio_h */ | ||
62 | |||
diff --git a/apps/plugins/sdl/src/audio/nds/SDL_ndsaudio.c b/apps/plugins/sdl/src/audio/nds/SDL_ndsaudio.c deleted file mode 100644 index afe141a567..0000000000 --- a/apps/plugins/sdl/src/audio/nds/SDL_ndsaudio.c +++ /dev/null | |||
@@ -1,335 +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 Lesser General Public | ||
7 | License as published by the Free Software Foundation; either | ||
8 | version 2.1 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 | Lesser General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU Lesser General Public | ||
16 | License along with this library; if not, write to the Free Software | ||
17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 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 | #include <nds.h> | ||
26 | #include "SDL.h" | ||
27 | #include "SDL_endian.h" | ||
28 | #include "SDL_timer.h" | ||
29 | #include "SDL_audio.h" | ||
30 | #include "../SDL_audiomem.h" | ||
31 | #include "../SDL_audio_c.h" | ||
32 | #include "SDL_ndsaudio.h" | ||
33 | #include "soundcommon.h" | ||
34 | |||
35 | |||
36 | /* Audio driver functions */ | ||
37 | static int NDS_OpenAudio(_THIS, SDL_AudioSpec *spec); | ||
38 | static void NDS_WaitAudio(_THIS); | ||
39 | static void NDS_PlayAudio(_THIS); | ||
40 | static Uint8 *NDS_GetAudioBuf(_THIS); | ||
41 | static void NDS_CloseAudio(_THIS); | ||
42 | |||
43 | /* Audio driver bootstrap functions */ | ||
44 | |||
45 | u32 framecounter = 0,soundoffset = 0; | ||
46 | static SDL_AudioDevice *sdl_nds_audiodevice; | ||
47 | |||
48 | //void SoundMixCallback(void *stream,u32 size) | ||
49 | //{ | ||
50 | // //printf("SoundMixCallback\n"); | ||
51 | // | ||
52 | // Uint8 *buffer; | ||
53 | // | ||
54 | // buffer = sdl_nds_audiodevice->hidden->mixbuf; | ||
55 | // memset(buffer, sdl_nds_audiodevice->spec.silence, size); | ||
56 | // | ||
57 | // if (!sdl_nds_audiodevice->paused){ | ||
58 | // | ||
59 | // | ||
60 | // //if (sdl_nds_audiodevice->convert.needed) { | ||
61 | // // int silence; | ||
62 | // | ||
63 | // // if (sdl_nds_audiodevice->convert.src_format == AUDIO_U8 ) { | ||
64 | // // silence = 0x80; | ||
65 | // // } else { | ||
66 | // // silence = 0; | ||
67 | // // } | ||
68 | // // memset(sdl_nds_audiodevice->convert.buf, silence, sdl_nds_audiodevice->convert.len); | ||
69 | // // sdl_nds_audiodevice->spec.callback(sdl_nds_audiodevice->spec.userdata, | ||
70 | // // (Uint8 *)sdl_nds_audiodevice->convert.buf,sdl_nds_audiodevice->convert.len); | ||
71 | // // SDL_ConvertAudio(&sdl_nds_audiodevice->convert); | ||
72 | // // memcpy(buffer, sdl_nds_audiodevice->convert.buf, sdl_nds_audiodevice->convert.len_cvt); | ||
73 | // //} else | ||
74 | // { | ||
75 | // sdl_nds_audiodevice->spec.callback(sdl_nds_audiodevice->spec.userdata, buffer, size); | ||
76 | // //memcpy((Sint16 *)stream,buffer, size); | ||
77 | // } | ||
78 | // | ||
79 | // } | ||
80 | // | ||
81 | // if(soundsystem->format == 8) | ||
82 | // { | ||
83 | // int i; | ||
84 | // s32 *buffer32 = (s32 *)buffer; | ||
85 | // s32 *stream32 = (s32 *)stream; | ||
86 | // for(i=0;i<size/4;i++){ *stream32++ = buffer32[i] ^ 0x80808080;} | ||
87 | // //for(i = 0; i < size; i++) | ||
88 | // // ((s8*)stream)[i]=(buffer[i]^0x80); | ||
89 | // } | ||
90 | // else | ||
91 | // { | ||
92 | // int i; | ||
93 | // for(i = 0; i < size; i++){ | ||
94 | // //((short*)stream)[i] =(short)buffer[i] << 8; // sound 8bit ---> buffer 16bit | ||
95 | // //if (buffer[i] &0x80) | ||
96 | // //((Sint16*)stream)[i] = 0xff00 | buffer[i]; | ||
97 | // ((Sint16*)stream)[i] = (buffer[i] - 128) << 8; | ||
98 | // | ||
99 | // //else | ||
100 | // // ((Sint16*)stream)[i] = buffer[i]; | ||
101 | // } | ||
102 | // //register signed char *pSrc =buffer; | ||
103 | // //register short *pDest =stream; | ||
104 | // //int x; | ||
105 | // // for (x=size; x>0; x--) | ||
106 | // // { | ||
107 | // // register short temp = (((short)*pSrc)-128)<<8; | ||
108 | // // pSrc++; | ||
109 | // // *pDest++ = temp; | ||
110 | // // } | ||
111 | // | ||
112 | // //memcpy((Sint16 *)stream,buffer, size); | ||
113 | // } | ||
114 | //} | ||
115 | |||
116 | void SoundMixCallback(void *stream,u32 len) | ||
117 | { | ||
118 | SDL_AudioDevice *audio = (SDL_AudioDevice *)sdl_nds_audiodevice; | ||
119 | |||
120 | /* Silence the buffer, since it's ours */ | ||
121 | SDL_memset(stream, audio->spec.silence, len); | ||
122 | |||
123 | /* Only do soemthing if audio is enabled */ | ||
124 | if ( ! audio->enabled ) | ||
125 | return; | ||
126 | |||
127 | if ( ! audio->paused ) { | ||
128 | if ( audio->convert.needed ) { | ||
129 | //fprintf(stderr,"converting audio\n"); | ||
130 | SDL_mutexP(audio->mixer_lock); | ||
131 | (*audio->spec.callback)(audio->spec.userdata, | ||
132 | (Uint8 *)audio->convert.buf,audio->convert.len); | ||
133 | SDL_mutexV(audio->mixer_lock); | ||
134 | SDL_ConvertAudio(&audio->convert); | ||
135 | SDL_memcpy(stream,audio->convert.buf,audio->convert.len_cvt); | ||
136 | } else { | ||
137 | SDL_mutexP(audio->mixer_lock); | ||
138 | (*audio->spec.callback)(audio->spec.userdata, | ||
139 | (Uint8 *)stream, len); | ||
140 | SDL_mutexV(audio->mixer_lock); | ||
141 | } | ||
142 | } | ||
143 | return; | ||
144 | } | ||
145 | void MixSound(void) | ||
146 | { | ||
147 | int remain; | ||
148 | |||
149 | if(soundsystem->format == 8) | ||
150 | { | ||
151 | if((soundsystem->soundcursor + soundsystem->numsamples) > soundsystem->buffersize) | ||
152 | { | ||
153 | SoundMixCallback(&soundsystem->mixbuffer[soundsystem->soundcursor],soundsystem->buffersize - soundsystem->soundcursor); | ||
154 | remain = soundsystem->numsamples - (soundsystem->buffersize - soundsystem->soundcursor); | ||
155 | SoundMixCallback(soundsystem->mixbuffer,remain); | ||
156 | } | ||
157 | else | ||
158 | { | ||
159 | SoundMixCallback(&soundsystem->mixbuffer[soundsystem->soundcursor],soundsystem->numsamples); | ||
160 | } | ||
161 | } | ||
162 | else | ||
163 | { | ||
164 | if((soundsystem->soundcursor + soundsystem->numsamples) > (soundsystem->buffersize >> 1)) | ||
165 | { | ||
166 | SoundMixCallback(&soundsystem->mixbuffer[soundsystem->soundcursor << 1],(soundsystem->buffersize >> 1) - soundsystem->soundcursor); | ||
167 | remain = soundsystem->numsamples - ((soundsystem->buffersize >> 1) - soundsystem->soundcursor); | ||
168 | SoundMixCallback(soundsystem->mixbuffer,remain); | ||
169 | } | ||
170 | else | ||
171 | { | ||
172 | SoundMixCallback(&soundsystem->mixbuffer[soundsystem->soundcursor << 1],soundsystem->numsamples); | ||
173 | } | ||
174 | } | ||
175 | } | ||
176 | |||
177 | void InterruptHandler(void) | ||
178 | { | ||
179 | framecounter++; | ||
180 | } | ||
181 | void FiFoHandler(void) | ||
182 | { | ||
183 | u32 command; | ||
184 | while ( !(REG_IPC_FIFO_CR & (IPC_FIFO_RECV_EMPTY)) ) | ||
185 | { | ||
186 | command = REG_IPC_FIFO_RX; | ||
187 | |||
188 | switch(command) | ||
189 | { | ||
190 | case FIFO_NONE: | ||
191 | break; | ||
192 | case UPDATEON_ARM9: | ||
193 | REG_IME = 0; | ||
194 | MixSound(); | ||
195 | REG_IME = 1; | ||
196 | SendCommandToArm7(MIXCOMPLETE_ONARM9); | ||
197 | break; | ||
198 | } | ||
199 | } | ||
200 | } | ||
201 | |||
202 | |||
203 | |||
204 | |||
205 | |||
206 | static int Audio_Available(void) | ||
207 | { | ||
208 | return(1); | ||
209 | } | ||
210 | |||
211 | static void Audio_DeleteDevice(SDL_AudioDevice *device) | ||
212 | { | ||
213 | } | ||
214 | |||
215 | static SDL_AudioDevice *Audio_CreateDevice(int devindex) | ||
216 | { | ||
217 | |||
218 | SDL_AudioDevice *this; | ||
219 | |||
220 | /* Initialize all variables that we clean on shutdown */ | ||
221 | this = (SDL_AudioDevice *)malloc(sizeof(SDL_AudioDevice)); | ||
222 | if ( this ) { | ||
223 | SDL_memset(this, 0, (sizeof *this)); | ||
224 | this->hidden = (struct SDL_PrivateAudioData *) | ||
225 | SDL_malloc((sizeof *this->hidden)); | ||
226 | } | ||
227 | if ( (this == NULL) || (this->hidden == NULL) ) { | ||
228 | SDL_OutOfMemory(); | ||
229 | if ( this ) { | ||
230 | SDL_free(this); | ||
231 | } | ||
232 | return(0); | ||
233 | } | ||
234 | SDL_memset(this->hidden, 0, (sizeof *this->hidden)); | ||
235 | |||
236 | /* Set the function pointers */ | ||
237 | this->OpenAudio = NDS_OpenAudio; | ||
238 | this->WaitAudio = NDS_WaitAudio; | ||
239 | this->PlayAudio = NDS_PlayAudio; | ||
240 | this->GetAudioBuf = NDS_GetAudioBuf; | ||
241 | this->CloseAudio = NDS_CloseAudio; | ||
242 | |||
243 | this->free = Audio_DeleteDevice; | ||
244 | //fprintf(stderr,"Audio_CreateDevice\n"); | ||
245 | return this; | ||
246 | } | ||
247 | |||
248 | AudioBootStrap NDSAUD_bootstrap = { | ||
249 | "nds", "NDS audio", | ||
250 | Audio_Available, Audio_CreateDevice | ||
251 | }; | ||
252 | |||
253 | |||
254 | void static NDS_WaitAudio(_THIS) | ||
255 | { | ||
256 | //printf("NDS_WaitAudio\n"); | ||
257 | } | ||
258 | |||
259 | static void NDS_PlayAudio(_THIS) | ||
260 | { | ||
261 | //printf("playing audio\n"); | ||
262 | if (this->paused) | ||
263 | return; | ||
264 | |||
265 | } | ||
266 | |||
267 | static Uint8 *NDS_GetAudioBuf(_THIS) | ||
268 | { | ||
269 | return NULL;//(this->hidden->mixbuf); | ||
270 | } | ||
271 | |||
272 | static void NDS_CloseAudio(_THIS) | ||
273 | { | ||
274 | /* if ( this->hidden->mixbuf != NULL ) { | ||
275 | SDL_FreeAudioMem(this->hidden->mixbuf); | ||
276 | this->hidden->mixbuf = NULL; | ||
277 | }*/ | ||
278 | } | ||
279 | |||
280 | static int NDS_OpenAudio(_THIS, SDL_AudioSpec *spec) | ||
281 | { | ||
282 | //printf("NDS_OpenAudio\n"); | ||
283 | int format = 0; | ||
284 | //switch(spec->format&0xff) { | ||
285 | //case 8: spec->format = AUDIO_S8;format=8; break; | ||
286 | //case 16: spec->format = AUDIO_S16LSB;format=16; break; | ||
287 | //default: | ||
288 | // SDL_SetError("Unsupported audio format"); | ||
289 | // return(-1); | ||
290 | //} | ||
291 | switch (spec->format&~0x1000) { | ||
292 | case AUDIO_S8: | ||
293 | /* Signed 8-bit audio supported */ | ||
294 | format=8; | ||
295 | break; | ||
296 | case AUDIO_U8: | ||
297 | spec->format ^= 0x80;format=8; | ||
298 | break; | ||
299 | case AUDIO_U16: | ||
300 | /* Unsigned 16-bit audio unsupported, convert to S16 */ | ||
301 | spec->format ^=0x8000;format=16; | ||
302 | case AUDIO_S16: | ||
303 | /* Signed 16-bit audio supported */ | ||
304 | format=16; | ||
305 | break; | ||
306 | } | ||
307 | /* Update the fragment size as size in bytes */ | ||
308 | SDL_CalculateAudioSpec(spec); | ||
309 | |||
310 | /* Allocate mixing buffer */ | ||
311 | //this->hidden->mixlen = spec->size; | ||
312 | //this->hidden->mixbuf = (Uint8 *) SDL_AllocAudioMem(this->hidden->mixlen); | ||
313 | //if ( this->hidden->mixbuf == NULL ) { | ||
314 | // SDL_SetError("Out of Memory"); | ||
315 | // return(-1); | ||
316 | //} | ||
317 | |||
318 | SDL_NDSAudio_mutex = 0; | ||
319 | sdl_nds_audiodevice=this; | ||
320 | |||
321 | irqInit(); | ||
322 | irqSet(IRQ_VBLANK,&InterruptHandler); | ||
323 | irqSet(IRQ_FIFO_NOT_EMPTY,&FiFoHandler); | ||
324 | irqEnable(IRQ_FIFO_NOT_EMPTY); | ||
325 | |||
326 | REG_IPC_FIFO_CR = IPC_FIFO_ENABLE | IPC_FIFO_SEND_CLEAR | IPC_FIFO_RECV_IRQ; | ||
327 | |||
328 | |||
329 | |||
330 | SoundSystemInit(spec->freq,spec->size,0,format); | ||
331 | SoundStartMixer(); | ||
332 | |||
333 | |||
334 | return(1); | ||
335 | } | ||
diff --git a/apps/plugins/sdl/src/audio/nds/SDL_ndsaudio.h b/apps/plugins/sdl/src/audio/nds/SDL_ndsaudio.h deleted file mode 100644 index cb6d1ea858..0000000000 --- a/apps/plugins/sdl/src/audio/nds/SDL_ndsaudio.h +++ /dev/null | |||
@@ -1,40 +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 Lesser General Public | ||
7 | License as published by the Free Software Foundation; either | ||
8 | version 2.1 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 | Lesser General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU Lesser General Public | ||
16 | License along with this library; if not, write to the Free Software | ||
17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
18 | |||
19 | Sam Lantinga | ||
20 | slouken@libsdl.org | ||
21 | */ | ||
22 | #include "SDL_config.h" | ||
23 | |||
24 | #ifndef _SDL_lowaudio_h | ||
25 | #define _SDL_lowaudio_h | ||
26 | |||
27 | #include "../SDL_sysaudio.h" | ||
28 | |||
29 | /* Hidden "this" pointer for the audio functions */ | ||
30 | #define _THIS SDL_AudioDevice *this | ||
31 | |||
32 | struct SDL_PrivateAudioData { | ||
33 | /* The file descriptor for the audio device */ | ||
34 | //Uint8 *mixbuf; | ||
35 | //Uint32 mixlen; | ||
36 | }; | ||
37 | unsigned short SDL_NDSAudio_mutex=0; | ||
38 | |||
39 | |||
40 | #endif /* _SDL_lowaudio_h */ | ||
diff --git a/apps/plugins/sdl/src/audio/nds/sound9.c b/apps/plugins/sdl/src/audio/nds/sound9.c deleted file mode 100644 index 59c1c219ae..0000000000 --- a/apps/plugins/sdl/src/audio/nds/sound9.c +++ /dev/null | |||
@@ -1,61 +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 Lesser General Public | ||
7 | License as published by the Free Software Foundation; either | ||
8 | version 2.1 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 | Lesser General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU Lesser General Public | ||
16 | License along with this library; if not, write to the Free Software | ||
17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
18 | |||
19 | Sam Lantinga | ||
20 | slouken@libsdl.org | ||
21 | */ | ||
22 | #include "SDL_config.h" | ||
23 | #include "SDL_stdinc.h" | ||
24 | |||
25 | #include "soundcommon.h" | ||
26 | |||
27 | void SoundSystemInit(u32 rate,u32 buffersize,u8 channel,u8 format) | ||
28 | { | ||
29 | soundsystem->rate = rate; | ||
30 | |||
31 | if(format == 8) | ||
32 | soundsystem->buffersize = buffersize; | ||
33 | else if(format == 16) | ||
34 | soundsystem->buffersize = buffersize * sizeof(short); | ||
35 | |||
36 | soundsystem->mixbuffer = (s8*)SDL_malloc(soundsystem->buffersize); | ||
37 | //soundsystem->soundbuffer = soundsystem->mixbuffer; | ||
38 | soundsystem->format = format; | ||
39 | soundsystem->channel = channel; | ||
40 | soundsystem->prevtimer = 0; | ||
41 | soundsystem->soundcursor = 0; | ||
42 | soundsystem->numsamples = 0; | ||
43 | soundsystem->period = 0x1000000 / rate; | ||
44 | soundsystem->cmd = INIT; | ||
45 | } | ||
46 | |||
47 | void SoundStartMixer(void) | ||
48 | { | ||
49 | soundsystem->cmd |= MIX; | ||
50 | } | ||
51 | |||
52 | void SendCommandToArm7(u32 command) | ||
53 | { | ||
54 | while (REG_IPC_FIFO_CR & IPC_FIFO_SEND_FULL); | ||
55 | if (REG_IPC_FIFO_CR & IPC_FIFO_ERROR) | ||
56 | { | ||
57 | REG_IPC_FIFO_CR |= IPC_FIFO_SEND_CLEAR; | ||
58 | } | ||
59 | |||
60 | REG_IPC_FIFO_TX = command; | ||
61 | } | ||
diff --git a/apps/plugins/sdl/src/audio/nds/soundcommon.h b/apps/plugins/sdl/src/audio/nds/soundcommon.h deleted file mode 100644 index d38e37cf68..0000000000 --- a/apps/plugins/sdl/src/audio/nds/soundcommon.h +++ /dev/null | |||
@@ -1,80 +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 Lesser General Public | ||
7 | License as published by the Free Software Foundation; either | ||
8 | version 2.1 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 | Lesser General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU Lesser General Public | ||
16 | License along with this library; if not, write to the Free Software | ||
17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
18 | |||
19 | Sam Lantinga | ||
20 | slouken@libsdl.org | ||
21 | */ | ||
22 | #include "SDL_config.h" | ||
23 | |||
24 | #ifndef __SOUNDCOMMON_H | ||
25 | #define __SOUNDCOMMON_H | ||
26 | |||
27 | #include <nds.h> | ||
28 | |||
29 | #define CLOCK (1 << 25) | ||
30 | |||
31 | #ifdef __cplusplus | ||
32 | extern "C" { | ||
33 | #endif | ||
34 | |||
35 | typedef enum | ||
36 | { | ||
37 | NONE = 0, | ||
38 | INIT = 1, | ||
39 | MIX = 2, | ||
40 | MIXING = 4, | ||
41 | STOP = 8 | ||
42 | }CommandType; | ||
43 | |||
44 | typedef enum | ||
45 | { | ||
46 | FIFO_NONE = 0, | ||
47 | UPDATEON_ARM9 = 1, | ||
48 | MIXCOMPLETE_ONARM9 = 2, | ||
49 | }FifoType; | ||
50 | |||
51 | typedef struct | ||
52 | { | ||
53 | s8 *mixbuffer;//,*soundbuffer; | ||
54 | u32 rate; | ||
55 | u32 buffersize; | ||
56 | u32 cmd; | ||
57 | u8 channel,format; | ||
58 | u32 soundcursor,numsamples; | ||
59 | s32 prevtimer; | ||
60 | s16 period; | ||
61 | }S_SoundSystem; | ||
62 | |||
63 | #define soundsystem ((S_SoundSystem*)((u32)(IPC)+sizeof(TransferRegion))) | ||
64 | |||
65 | #ifdef ARM9 | ||
66 | extern void SoundSystemInit(u32 rate,u32 buffersize,u8 channel,u8 format); | ||
67 | extern void SoundStartMixer(void); | ||
68 | extern void SendCommandToArm7(u32 command); | ||
69 | #else | ||
70 | extern void SoundVBlankIrq(void); | ||
71 | extern void SoundSwapAndMix(void); | ||
72 | extern void SoundSetTimer(int period); | ||
73 | extern void SoundFifoHandler(void); | ||
74 | extern void SendCommandToArm9(u32 command); | ||
75 | #endif | ||
76 | |||
77 | #ifdef __cplusplus | ||
78 | } | ||
79 | #endif | ||
80 | #endif | ||
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 | } | ||
diff --git a/apps/plugins/sdl/src/audio/nto/SDL_nto_audio.h b/apps/plugins/sdl/src/audio/nto/SDL_nto_audio.h deleted file mode 100644 index cfd592c96b..0000000000 --- a/apps/plugins/sdl/src/audio/nto/SDL_nto_audio.h +++ /dev/null | |||
@@ -1,68 +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 __SDL_NTO_AUDIO_H__ | ||
25 | #define __SDL_NTO_AUDIO_H__ | ||
26 | |||
27 | #include <sys/asoundlib.h> | ||
28 | |||
29 | #include "../SDL_sysaudio.h" | ||
30 | |||
31 | /* Hidden "this" pointer for the audio functions */ | ||
32 | #define _THIS SDL_AudioDevice *this | ||
33 | |||
34 | struct SDL_PrivateAudioData | ||
35 | { | ||
36 | /* The audio device handle */ | ||
37 | int cardno; | ||
38 | int deviceno; | ||
39 | snd_pcm_t* audio_handle; | ||
40 | |||
41 | /* The audio file descriptor */ | ||
42 | int audio_fd; | ||
43 | |||
44 | /* The parent process id, to detect when application quits */ | ||
45 | pid_t parent; | ||
46 | |||
47 | /* Raw mixing buffer */ | ||
48 | Uint8* pcm_buf; | ||
49 | Uint32 pcm_len; | ||
50 | |||
51 | /* QSA parameters */ | ||
52 | snd_pcm_channel_status_t cstatus; | ||
53 | snd_pcm_channel_params_t cparams; | ||
54 | snd_pcm_channel_setup_t csetup; | ||
55 | }; | ||
56 | |||
57 | #define cardno (this->hidden->cardno) | ||
58 | #define deviceno (this->hidden->deviceno) | ||
59 | #define audio_handle (this->hidden->audio_handle) | ||
60 | #define audio_fd (this->hidden->audio_fd) | ||
61 | #define parent (this->hidden->parent) | ||
62 | #define pcm_buf (this->hidden->pcm_buf) | ||
63 | #define pcm_len (this->hidden->pcm_len) | ||
64 | #define cstatus (this->hidden->cstatus) | ||
65 | #define cparams (this->hidden->cparams) | ||
66 | #define csetup (this->hidden->csetup) | ||
67 | |||
68 | #endif /* __SDL_NTO_AUDIO_H__ */ | ||
diff --git a/apps/plugins/sdl/src/audio/paudio/SDL_paudio.c b/apps/plugins/sdl/src/audio/paudio/SDL_paudio.c deleted file mode 100644 index 6270d8c0a8..0000000000 --- a/apps/plugins/sdl/src/audio/paudio/SDL_paudio.c +++ /dev/null | |||
@@ -1,511 +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 Lesser General Public | ||
7 | License as published by the Free Software Foundation; either | ||
8 | version 2.1 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 | Lesser General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU Lesser General Public | ||
16 | License along with this library; if not, write to the Free Software | ||
17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
18 | |||
19 | Carsten Griwodz | ||
20 | griff@kom.tu-darmstadt.de | ||
21 | |||
22 | based on linux/SDL_dspaudio.c by Sam Lantinga | ||
23 | */ | ||
24 | #include "SDL_config.h" | ||
25 | |||
26 | /* Allow access to a raw mixing buffer */ | ||
27 | |||
28 | #include <errno.h> | ||
29 | #include <unistd.h> | ||
30 | #include <fcntl.h> | ||
31 | #include <sys/time.h> | ||
32 | #include <sys/ioctl.h> | ||
33 | #include <sys/stat.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_audiodev_c.h" | ||
40 | #include "SDL_paudio.h" | ||
41 | |||
42 | #define DEBUG_AUDIO 1 | ||
43 | |||
44 | /* A conflict within AIX 4.3.3 <sys/> headers and probably others as well. | ||
45 | * I guess nobody ever uses audio... Shame over AIX header files. */ | ||
46 | #include <sys/machine.h> | ||
47 | #undef BIG_ENDIAN | ||
48 | #include <sys/audio.h> | ||
49 | |||
50 | /* The tag name used by paud audio */ | ||
51 | #define Paud_DRIVER_NAME "paud" | ||
52 | |||
53 | /* Open the audio device for playback, and don't block if busy */ | ||
54 | /* #define OPEN_FLAGS (O_WRONLY|O_NONBLOCK) */ | ||
55 | #define OPEN_FLAGS O_WRONLY | ||
56 | |||
57 | /* Audio driver functions */ | ||
58 | static int Paud_OpenAudio(_THIS, SDL_AudioSpec *spec); | ||
59 | static void Paud_WaitAudio(_THIS); | ||
60 | static void Paud_PlayAudio(_THIS); | ||
61 | static Uint8 *Paud_GetAudioBuf(_THIS); | ||
62 | static void Paud_CloseAudio(_THIS); | ||
63 | |||
64 | /* Audio driver bootstrap functions */ | ||
65 | |||
66 | static int Audio_Available(void) | ||
67 | { | ||
68 | int fd; | ||
69 | int available; | ||
70 | |||
71 | available = 0; | ||
72 | fd = SDL_OpenAudioPath(NULL, 0, OPEN_FLAGS, 0); | ||
73 | if ( fd >= 0 ) { | ||
74 | available = 1; | ||
75 | close(fd); | ||
76 | } | ||
77 | return(available); | ||
78 | } | ||
79 | |||
80 | static void Audio_DeleteDevice(SDL_AudioDevice *device) | ||
81 | { | ||
82 | SDL_free(device->hidden); | ||
83 | SDL_free(device); | ||
84 | } | ||
85 | |||
86 | static SDL_AudioDevice *Audio_CreateDevice(int devindex) | ||
87 | { | ||
88 | SDL_AudioDevice *this; | ||
89 | |||
90 | /* Initialize all variables that we clean on shutdown */ | ||
91 | this = (SDL_AudioDevice *)SDL_malloc(sizeof(SDL_AudioDevice)); | ||
92 | if ( this ) { | ||
93 | SDL_memset(this, 0, (sizeof *this)); | ||
94 | this->hidden = (struct SDL_PrivateAudioData *) | ||
95 | SDL_malloc((sizeof *this->hidden)); | ||
96 | } | ||
97 | if ( (this == NULL) || (this->hidden == NULL) ) { | ||
98 | SDL_OutOfMemory(); | ||
99 | if ( this ) { | ||
100 | SDL_free(this); | ||
101 | } | ||
102 | return(0); | ||
103 | } | ||
104 | SDL_memset(this->hidden, 0, (sizeof *this->hidden)); | ||
105 | audio_fd = -1; | ||
106 | |||
107 | /* Set the function pointers */ | ||
108 | this->OpenAudio = Paud_OpenAudio; | ||
109 | this->WaitAudio = Paud_WaitAudio; | ||
110 | this->PlayAudio = Paud_PlayAudio; | ||
111 | this->GetAudioBuf = Paud_GetAudioBuf; | ||
112 | this->CloseAudio = Paud_CloseAudio; | ||
113 | |||
114 | this->free = Audio_DeleteDevice; | ||
115 | |||
116 | return this; | ||
117 | } | ||
118 | |||
119 | AudioBootStrap Paud_bootstrap = { | ||
120 | Paud_DRIVER_NAME, "AIX Paudio", | ||
121 | Audio_Available, Audio_CreateDevice | ||
122 | }; | ||
123 | |||
124 | /* This function waits until it is possible to write a full sound buffer */ | ||
125 | static void Paud_WaitAudio(_THIS) | ||
126 | { | ||
127 | fd_set fdset; | ||
128 | |||
129 | /* See if we need to use timed audio synchronization */ | ||
130 | if ( frame_ticks ) { | ||
131 | /* Use timer for general audio synchronization */ | ||
132 | Sint32 ticks; | ||
133 | |||
134 | ticks = ((Sint32)(next_frame - SDL_GetTicks()))-FUDGE_TICKS; | ||
135 | if ( ticks > 0 ) { | ||
136 | SDL_Delay(ticks); | ||
137 | } | ||
138 | } else { | ||
139 | audio_buffer paud_bufinfo; | ||
140 | |||
141 | /* Use select() for audio synchronization */ | ||
142 | struct timeval timeout; | ||
143 | FD_ZERO(&fdset); | ||
144 | FD_SET(audio_fd, &fdset); | ||
145 | |||
146 | if ( ioctl(audio_fd, AUDIO_BUFFER, &paud_bufinfo) < 0 ) { | ||
147 | #ifdef DEBUG_AUDIO | ||
148 | fprintf(stderr, "Couldn't get audio buffer information\n"); | ||
149 | #endif | ||
150 | timeout.tv_sec = 10; | ||
151 | timeout.tv_usec = 0; | ||
152 | } else { | ||
153 | long ms_in_buf = paud_bufinfo.write_buf_time; | ||
154 | timeout.tv_sec = ms_in_buf/1000; | ||
155 | ms_in_buf = ms_in_buf - timeout.tv_sec*1000; | ||
156 | timeout.tv_usec = ms_in_buf*1000; | ||
157 | #ifdef DEBUG_AUDIO | ||
158 | fprintf( stderr, | ||
159 | "Waiting for write_buf_time=%ld,%ld\n", | ||
160 | timeout.tv_sec, | ||
161 | timeout.tv_usec ); | ||
162 | #endif | ||
163 | } | ||
164 | |||
165 | #ifdef DEBUG_AUDIO | ||
166 | fprintf(stderr, "Waiting for audio to get ready\n"); | ||
167 | #endif | ||
168 | if ( select(audio_fd+1, NULL, &fdset, NULL, &timeout) <= 0 ) { | ||
169 | const char *message = "Audio timeout - buggy audio driver? (disabled)"; | ||
170 | /* | ||
171 | * In general we should never print to the screen, | ||
172 | * but in this case we have no other way of letting | ||
173 | * the user know what happened. | ||
174 | */ | ||
175 | fprintf(stderr, "SDL: %s - %s\n", strerror(errno), message); | ||
176 | this->enabled = 0; | ||
177 | /* Don't try to close - may hang */ | ||
178 | audio_fd = -1; | ||
179 | #ifdef DEBUG_AUDIO | ||
180 | fprintf(stderr, "Done disabling audio\n"); | ||
181 | #endif | ||
182 | } | ||
183 | #ifdef DEBUG_AUDIO | ||
184 | fprintf(stderr, "Ready!\n"); | ||
185 | #endif | ||
186 | } | ||
187 | } | ||
188 | |||
189 | static void Paud_PlayAudio(_THIS) | ||
190 | { | ||
191 | int written; | ||
192 | |||
193 | /* Write the audio data, checking for EAGAIN on broken audio drivers */ | ||
194 | do { | ||
195 | written = write(audio_fd, mixbuf, mixlen); | ||
196 | if ( (written < 0) && ((errno == 0) || (errno == EAGAIN)) ) { | ||
197 | SDL_Delay(1); /* Let a little CPU time go by */ | ||
198 | } | ||
199 | } while ( (written < 0) && | ||
200 | ((errno == 0) || (errno == EAGAIN) || (errno == EINTR)) ); | ||
201 | |||
202 | /* If timer synchronization is enabled, set the next write frame */ | ||
203 | if ( frame_ticks ) { | ||
204 | next_frame += frame_ticks; | ||
205 | } | ||
206 | |||
207 | /* If we couldn't write, assume fatal error for now */ | ||
208 | if ( written < 0 ) { | ||
209 | this->enabled = 0; | ||
210 | } | ||
211 | #ifdef DEBUG_AUDIO | ||
212 | fprintf(stderr, "Wrote %d bytes of audio data\n", written); | ||
213 | #endif | ||
214 | } | ||
215 | |||
216 | static Uint8 *Paud_GetAudioBuf(_THIS) | ||
217 | { | ||
218 | return mixbuf; | ||
219 | } | ||
220 | |||
221 | static void Paud_CloseAudio(_THIS) | ||
222 | { | ||
223 | if ( mixbuf != NULL ) { | ||
224 | SDL_FreeAudioMem(mixbuf); | ||
225 | mixbuf = NULL; | ||
226 | } | ||
227 | if ( audio_fd >= 0 ) { | ||
228 | close(audio_fd); | ||
229 | audio_fd = -1; | ||
230 | } | ||
231 | } | ||
232 | |||
233 | static int Paud_OpenAudio(_THIS, SDL_AudioSpec *spec) | ||
234 | { | ||
235 | char audiodev[1024]; | ||
236 | int format; | ||
237 | int bytes_per_sample; | ||
238 | Uint16 test_format; | ||
239 | audio_init paud_init; | ||
240 | audio_buffer paud_bufinfo; | ||
241 | audio_status paud_status; | ||
242 | audio_control paud_control; | ||
243 | audio_change paud_change; | ||
244 | |||
245 | /* Reset the timer synchronization flag */ | ||
246 | frame_ticks = 0.0; | ||
247 | |||
248 | /* Open the audio device */ | ||
249 | audio_fd = SDL_OpenAudioPath(audiodev, sizeof(audiodev), OPEN_FLAGS, 0); | ||
250 | if ( audio_fd < 0 ) { | ||
251 | SDL_SetError("Couldn't open %s: %s", audiodev, strerror(errno)); | ||
252 | return -1; | ||
253 | } | ||
254 | |||
255 | /* | ||
256 | * We can't set the buffer size - just ask the device for the maximum | ||
257 | * that we can have. | ||
258 | */ | ||
259 | if ( ioctl(audio_fd, AUDIO_BUFFER, &paud_bufinfo) < 0 ) { | ||
260 | SDL_SetError("Couldn't get audio buffer information"); | ||
261 | return -1; | ||
262 | } | ||
263 | |||
264 | mixbuf = NULL; | ||
265 | |||
266 | if ( spec->channels > 1 ) | ||
267 | spec->channels = 2; | ||
268 | else | ||
269 | spec->channels = 1; | ||
270 | |||
271 | /* | ||
272 | * Fields in the audio_init structure: | ||
273 | * | ||
274 | * Ignored by us: | ||
275 | * | ||
276 | * paud.loadpath[LOAD_PATH]; * DSP code to load, MWave chip only? | ||
277 | * paud.slot_number; * slot number of the adapter | ||
278 | * paud.device_id; * adapter identification number | ||
279 | * | ||
280 | * Input: | ||
281 | * | ||
282 | * paud.srate; * the sampling rate in Hz | ||
283 | * paud.bits_per_sample; * 8, 16, 32, ... | ||
284 | * paud.bsize; * block size for this rate | ||
285 | * paud.mode; * ADPCM, PCM, MU_LAW, A_LAW, SOURCE_MIX | ||
286 | * paud.channels; * 1=mono, 2=stereo | ||
287 | * paud.flags; * FIXED - fixed length data | ||
288 | * * LEFT_ALIGNED, RIGHT_ALIGNED (var len only) | ||
289 | * * TWOS_COMPLEMENT - 2's complement data | ||
290 | * * SIGNED - signed? comment seems wrong in sys/audio.h | ||
291 | * * BIG_ENDIAN | ||
292 | * paud.operation; * PLAY, RECORD | ||
293 | * | ||
294 | * Output: | ||
295 | * | ||
296 | * paud.flags; * PITCH - pitch is supported | ||
297 | * * INPUT - input is supported | ||
298 | * * OUTPUT - output is supported | ||
299 | * * MONITOR - monitor is supported | ||
300 | * * VOLUME - volume is supported | ||
301 | * * VOLUME_DELAY - volume delay is supported | ||
302 | * * BALANCE - balance is supported | ||
303 | * * BALANCE_DELAY - balance delay is supported | ||
304 | * * TREBLE - treble control is supported | ||
305 | * * BASS - bass control is supported | ||
306 | * * BESTFIT_PROVIDED - best fit returned | ||
307 | * * LOAD_CODE - DSP load needed | ||
308 | * paud.rc; * NO_PLAY - DSP code can't do play requests | ||
309 | * * NO_RECORD - DSP code can't do record requests | ||
310 | * * INVALID_REQUEST - request was invalid | ||
311 | * * CONFLICT - conflict with open's flags | ||
312 | * * OVERLOADED - out of DSP MIPS or memory | ||
313 | * paud.position_resolution; * smallest increment for position | ||
314 | */ | ||
315 | |||
316 | paud_init.srate = spec->freq; | ||
317 | paud_init.mode = PCM; | ||
318 | paud_init.operation = PLAY; | ||
319 | paud_init.channels = spec->channels; | ||
320 | |||
321 | /* Try for a closest match on audio format */ | ||
322 | format = 0; | ||
323 | for ( test_format = SDL_FirstAudioFormat(spec->format); | ||
324 | ! format && test_format; ) { | ||
325 | #ifdef DEBUG_AUDIO | ||
326 | fprintf(stderr, "Trying format 0x%4.4x\n", test_format); | ||
327 | #endif | ||
328 | switch ( test_format ) { | ||
329 | case AUDIO_U8: | ||
330 | bytes_per_sample = 1; | ||
331 | paud_init.bits_per_sample = 8; | ||
332 | paud_init.flags = TWOS_COMPLEMENT | FIXED; | ||
333 | format = 1; | ||
334 | break; | ||
335 | case AUDIO_S8: | ||
336 | bytes_per_sample = 1; | ||
337 | paud_init.bits_per_sample = 8; | ||
338 | paud_init.flags = SIGNED | | ||
339 | TWOS_COMPLEMENT | FIXED; | ||
340 | format = 1; | ||
341 | break; | ||
342 | case AUDIO_S16LSB: | ||
343 | bytes_per_sample = 2; | ||
344 | paud_init.bits_per_sample = 16; | ||
345 | paud_init.flags = SIGNED | | ||
346 | TWOS_COMPLEMENT | FIXED; | ||
347 | format = 1; | ||
348 | break; | ||
349 | case AUDIO_S16MSB: | ||
350 | bytes_per_sample = 2; | ||
351 | paud_init.bits_per_sample = 16; | ||
352 | paud_init.flags = BIG_ENDIAN | | ||
353 | SIGNED | | ||
354 | TWOS_COMPLEMENT | FIXED; | ||
355 | format = 1; | ||
356 | break; | ||
357 | case AUDIO_U16LSB: | ||
358 | bytes_per_sample = 2; | ||
359 | paud_init.bits_per_sample = 16; | ||
360 | paud_init.flags = TWOS_COMPLEMENT | FIXED; | ||
361 | format = 1; | ||
362 | break; | ||
363 | case AUDIO_U16MSB: | ||
364 | bytes_per_sample = 2; | ||
365 | paud_init.bits_per_sample = 16; | ||
366 | paud_init.flags = BIG_ENDIAN | | ||
367 | TWOS_COMPLEMENT | FIXED; | ||
368 | format = 1; | ||
369 | break; | ||
370 | default: | ||
371 | break; | ||
372 | } | ||
373 | if ( ! format ) { | ||
374 | test_format = SDL_NextAudioFormat(); | ||
375 | } | ||
376 | } | ||
377 | if ( format == 0 ) { | ||
378 | #ifdef DEBUG_AUDIO | ||
379 | fprintf(stderr, "Couldn't find any hardware audio formats\n"); | ||
380 | #endif | ||
381 | SDL_SetError("Couldn't find any hardware audio formats"); | ||
382 | return -1; | ||
383 | } | ||
384 | spec->format = test_format; | ||
385 | |||
386 | /* | ||
387 | * We know the buffer size and the max number of subsequent writes | ||
388 | * that can be pending. If more than one can pend, allow the application | ||
389 | * to do something like double buffering between our write buffer and | ||
390 | * the device's own buffer that we are filling with write() anyway. | ||
391 | * | ||
392 | * We calculate spec->samples like this because SDL_CalculateAudioSpec() | ||
393 | * will give put paud_bufinfo.write_buf_cap (or paud_bufinfo.write_buf_cap/2) | ||
394 | * into spec->size in return. | ||
395 | */ | ||
396 | if ( paud_bufinfo.request_buf_cap == 1 ) | ||
397 | { | ||
398 | spec->samples = paud_bufinfo.write_buf_cap | ||
399 | / bytes_per_sample | ||
400 | / spec->channels; | ||
401 | } | ||
402 | else | ||
403 | { | ||
404 | spec->samples = paud_bufinfo.write_buf_cap | ||
405 | / bytes_per_sample | ||
406 | / spec->channels | ||
407 | / 2; | ||
408 | } | ||
409 | paud_init.bsize = bytes_per_sample * spec->channels; | ||
410 | |||
411 | SDL_CalculateAudioSpec(spec); | ||
412 | |||
413 | /* | ||
414 | * The AIX paud device init can't modify the values of the audio_init | ||
415 | * structure that we pass to it. So we don't need any recalculation | ||
416 | * of this stuff and no reinit call as in linux dsp and dma code. | ||
417 | * | ||
418 | * /dev/paud supports all of the encoding formats, so we don't need | ||
419 | * to do anything like reopening the device, either. | ||
420 | */ | ||
421 | if ( ioctl(audio_fd, AUDIO_INIT, &paud_init) < 0 ) { | ||
422 | switch ( paud_init.rc ) | ||
423 | { | ||
424 | case 1 : | ||
425 | SDL_SetError("Couldn't set audio format: DSP can't do play requests"); | ||
426 | return -1; | ||
427 | break; | ||
428 | case 2 : | ||
429 | SDL_SetError("Couldn't set audio format: DSP can't do record requests"); | ||
430 | return -1; | ||
431 | break; | ||
432 | case 4 : | ||
433 | SDL_SetError("Couldn't set audio format: request was invalid"); | ||
434 | return -1; | ||
435 | break; | ||
436 | case 5 : | ||
437 | SDL_SetError("Couldn't set audio format: conflict with open's flags"); | ||
438 | return -1; | ||
439 | break; | ||
440 | case 6 : | ||
441 | SDL_SetError("Couldn't set audio format: out of DSP MIPS or memory"); | ||
442 | return -1; | ||
443 | break; | ||
444 | default : | ||
445 | SDL_SetError("Couldn't set audio format: not documented in sys/audio.h"); | ||
446 | return -1; | ||
447 | break; | ||
448 | } | ||
449 | } | ||
450 | |||
451 | /* Allocate mixing buffer */ | ||
452 | mixlen = spec->size; | ||
453 | mixbuf = (Uint8 *)SDL_AllocAudioMem(mixlen); | ||
454 | if ( mixbuf == NULL ) { | ||
455 | return -1; | ||
456 | } | ||
457 | SDL_memset(mixbuf, spec->silence, spec->size); | ||
458 | |||
459 | /* | ||
460 | * Set some paramters: full volume, first speaker that we can find. | ||
461 | * Ignore the other settings for now. | ||
462 | */ | ||
463 | paud_change.input = AUDIO_IGNORE; /* the new input source */ | ||
464 | paud_change.output = OUTPUT_1; /* EXTERNAL_SPEAKER,INTERNAL_SPEAKER,OUTPUT_1 */ | ||
465 | paud_change.monitor = AUDIO_IGNORE; /* the new monitor state */ | ||
466 | paud_change.volume = 0x7fffffff; /* volume level [0-0x7fffffff] */ | ||
467 | paud_change.volume_delay = AUDIO_IGNORE; /* the new volume delay */ | ||
468 | paud_change.balance = 0x3fffffff; /* the new balance */ | ||
469 | paud_change.balance_delay = AUDIO_IGNORE; /* the new balance delay */ | ||
470 | paud_change.treble = AUDIO_IGNORE; /* the new treble state */ | ||
471 | paud_change.bass = AUDIO_IGNORE; /* the new bass state */ | ||
472 | paud_change.pitch = AUDIO_IGNORE; /* the new pitch state */ | ||
473 | |||
474 | paud_control.ioctl_request = AUDIO_CHANGE; | ||
475 | paud_control.request_info = (char*)&paud_change; | ||
476 | if ( ioctl(audio_fd, AUDIO_CONTROL, &paud_control) < 0 ) { | ||
477 | #ifdef DEBUG_AUDIO | ||
478 | fprintf(stderr, "Can't change audio display settings\n" ); | ||
479 | #endif | ||
480 | } | ||
481 | |||
482 | /* | ||
483 | * Tell the device to expect data. Actual start will wait for | ||
484 | * the first write() call. | ||
485 | */ | ||
486 | paud_control.ioctl_request = AUDIO_START; | ||
487 | paud_control.position = 0; | ||
488 | if ( ioctl(audio_fd, AUDIO_CONTROL, &paud_control) < 0 ) { | ||
489 | #ifdef DEBUG_AUDIO | ||
490 | fprintf(stderr, "Can't start audio play\n" ); | ||
491 | #endif | ||
492 | SDL_SetError("Can't start audio play"); | ||
493 | return -1; | ||
494 | } | ||
495 | |||
496 | /* Check to see if we need to use select() workaround */ | ||
497 | { char *workaround; | ||
498 | workaround = SDL_getenv("SDL_DSP_NOSELECT"); | ||
499 | if ( workaround ) { | ||
500 | frame_ticks = (float)(spec->samples*1000)/spec->freq; | ||
501 | next_frame = SDL_GetTicks()+frame_ticks; | ||
502 | } | ||
503 | } | ||
504 | |||
505 | /* Get the parent process id (we're the parent of the audio thread) */ | ||
506 | parent = getpid(); | ||
507 | |||
508 | /* We're ready to rock and roll. :-) */ | ||
509 | return 0; | ||
510 | } | ||
511 | |||
diff --git a/apps/plugins/sdl/src/audio/paudio/SDL_paudio.h b/apps/plugins/sdl/src/audio/paudio/SDL_paudio.h deleted file mode 100644 index 72eff1ddef..0000000000 --- a/apps/plugins/sdl/src/audio/paudio/SDL_paudio.h +++ /dev/null | |||
@@ -1,57 +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 Lesser General Public | ||
7 | License as published by the Free Software Foundation; either | ||
8 | version 2.1 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 | Lesser General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU Lesser General Public | ||
16 | License along with this library; if not, write to the Free Software | ||
17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
18 | |||
19 | Sam Lantinga | ||
20 | slouken@libsdl.org | ||
21 | */ | ||
22 | #include "SDL_config.h" | ||
23 | |||
24 | #ifndef _SDL_paudaudio_h | ||
25 | #define _SDL_paudaudio_h | ||
26 | |||
27 | #include "../SDL_sysaudio.h" | ||
28 | |||
29 | /* Hidden "this" pointer for the video functions */ | ||
30 | #define _THIS SDL_AudioDevice *this | ||
31 | |||
32 | struct SDL_PrivateAudioData { | ||
33 | /* The file descriptor for the audio device */ | ||
34 | int audio_fd; | ||
35 | |||
36 | /* The parent process id, to detect when application quits */ | ||
37 | pid_t parent; | ||
38 | |||
39 | /* Raw mixing buffer */ | ||
40 | Uint8 *mixbuf; | ||
41 | int mixlen; | ||
42 | |||
43 | /* Support for audio timing using a timer, in addition to select() */ | ||
44 | float frame_ticks; | ||
45 | float next_frame; | ||
46 | }; | ||
47 | #define FUDGE_TICKS 10 /* The scheduler overhead ticks per frame */ | ||
48 | |||
49 | /* Old variable names */ | ||
50 | #define audio_fd (this->hidden->audio_fd) | ||
51 | #define parent (this->hidden->parent) | ||
52 | #define mixbuf (this->hidden->mixbuf) | ||
53 | #define mixlen (this->hidden->mixlen) | ||
54 | #define frame_ticks (this->hidden->frame_ticks) | ||
55 | #define next_frame (this->hidden->next_frame) | ||
56 | |||
57 | #endif /* _SDL_paudaudio_h */ | ||
diff --git a/apps/plugins/sdl/src/audio/pulse/SDL_pulseaudio.c b/apps/plugins/sdl/src/audio/pulse/SDL_pulseaudio.c deleted file mode 100644 index 29373f37fd..0000000000 --- a/apps/plugins/sdl/src/audio/pulse/SDL_pulseaudio.c +++ /dev/null | |||
@@ -1,570 +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 Lesser General Public | ||
7 | License as published by the Free Software Foundation; either | ||
8 | version 2.1 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 | Lesser General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU Lesser General Public | ||
16 | License along with this library; if not, write to the Free Software | ||
17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
18 | |||
19 | Stéphan Kochen | ||
20 | stephan@kochen.nl | ||
21 | |||
22 | Based on parts of the ALSA and ESounD output drivers. | ||
23 | */ | ||
24 | #include "SDL_config.h" | ||
25 | |||
26 | /* Allow access to an PulseAudio network stream mixing buffer */ | ||
27 | |||
28 | #include <sys/types.h> | ||
29 | #include <unistd.h> | ||
30 | #include <signal.h> | ||
31 | #include <errno.h> | ||
32 | #include <pulse/pulseaudio.h> | ||
33 | #include <pulse/simple.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_audiodev_c.h" | ||
40 | #include "../../../include/SDL_video.h" /* for SDL_WM_GetCaption(). */ | ||
41 | #include "SDL_pulseaudio.h" | ||
42 | |||
43 | #ifdef SDL_AUDIO_DRIVER_PULSE_DYNAMIC | ||
44 | #include "SDL_name.h" | ||
45 | #include "SDL_loadso.h" | ||
46 | #else | ||
47 | #define SDL_NAME(X) X | ||
48 | #endif | ||
49 | |||
50 | /* The tag name used by the driver */ | ||
51 | #define PULSE_DRIVER_NAME "pulse" | ||
52 | |||
53 | /* Audio driver functions */ | ||
54 | static int PULSE_OpenAudio(_THIS, SDL_AudioSpec *spec); | ||
55 | static void PULSE_WaitAudio(_THIS); | ||
56 | static void PULSE_PlayAudio(_THIS); | ||
57 | static Uint8 *PULSE_GetAudioBuf(_THIS); | ||
58 | static void PULSE_CloseAudio(_THIS); | ||
59 | static void PULSE_WaitDone(_THIS); | ||
60 | static void PULSE_SetCaption(_THIS, const char *str); | ||
61 | |||
62 | #ifdef SDL_AUDIO_DRIVER_PULSE_DYNAMIC | ||
63 | |||
64 | static const char *pulse_library = SDL_AUDIO_DRIVER_PULSE_DYNAMIC; | ||
65 | static void *pulse_handle = NULL; | ||
66 | static int pulse_loaded = 0; | ||
67 | |||
68 | static pa_simple* (*SDL_NAME(pa_simple_new))( | ||
69 | const char *server, | ||
70 | const char *name, | ||
71 | pa_stream_direction_t dir, | ||
72 | const char *dev, | ||
73 | const char *stream_name, | ||
74 | const pa_sample_spec *ss, | ||
75 | const pa_channel_map *map, | ||
76 | const pa_buffer_attr *attr, | ||
77 | int *error | ||
78 | ); | ||
79 | static void (*SDL_NAME(pa_simple_free))(pa_simple *s); | ||
80 | |||
81 | static pa_channel_map* (*SDL_NAME(pa_channel_map_init_auto))( | ||
82 | pa_channel_map *m, | ||
83 | unsigned channels, | ||
84 | pa_channel_map_def_t def | ||
85 | ); | ||
86 | |||
87 | static pa_mainloop * (*SDL_NAME(pa_mainloop_new))(void); | ||
88 | static pa_mainloop_api * (*SDL_NAME(pa_mainloop_get_api))(pa_mainloop *m); | ||
89 | static int (*SDL_NAME(pa_mainloop_iterate))(pa_mainloop *m, int block, int *retval); | ||
90 | static void (*SDL_NAME(pa_mainloop_free))(pa_mainloop *m); | ||
91 | |||
92 | static pa_operation_state_t (*SDL_NAME(pa_operation_get_state))(pa_operation *o); | ||
93 | static void (*SDL_NAME(pa_operation_cancel))(pa_operation *o); | ||
94 | static void (*SDL_NAME(pa_operation_unref))(pa_operation *o); | ||
95 | |||
96 | static pa_context * (*SDL_NAME(pa_context_new))( | ||
97 | pa_mainloop_api *m, const char *name); | ||
98 | static int (*SDL_NAME(pa_context_connect))( | ||
99 | pa_context *c, const char *server, | ||
100 | pa_context_flags_t flags, const pa_spawn_api *api); | ||
101 | static pa_context_state_t (*SDL_NAME(pa_context_get_state))(pa_context *c); | ||
102 | static void (*SDL_NAME(pa_context_disconnect))(pa_context *c); | ||
103 | static void (*SDL_NAME(pa_context_unref))(pa_context *c); | ||
104 | |||
105 | static pa_stream * (*SDL_NAME(pa_stream_new))(pa_context *c, | ||
106 | const char *name, const pa_sample_spec *ss, const pa_channel_map *map); | ||
107 | static int (*SDL_NAME(pa_stream_connect_playback))(pa_stream *s, const char *dev, | ||
108 | const pa_buffer_attr *attr, pa_stream_flags_t flags, | ||
109 | pa_cvolume *volume, pa_stream *sync_stream); | ||
110 | static pa_stream_state_t (*SDL_NAME(pa_stream_get_state))(pa_stream *s); | ||
111 | static size_t (*SDL_NAME(pa_stream_writable_size))(pa_stream *s); | ||
112 | static int (*SDL_NAME(pa_stream_write))(pa_stream *s, const void *data, size_t nbytes, | ||
113 | pa_free_cb_t free_cb, int64_t offset, pa_seek_mode_t seek); | ||
114 | static pa_operation * (*SDL_NAME(pa_stream_drain))(pa_stream *s, | ||
115 | pa_stream_success_cb_t cb, void *userdata); | ||
116 | static int (*SDL_NAME(pa_stream_disconnect))(pa_stream *s); | ||
117 | static void (*SDL_NAME(pa_stream_unref))(pa_stream *s); | ||
118 | static pa_operation* (*SDL_NAME(pa_context_set_name))(pa_context *c, | ||
119 | const char *name, pa_context_success_cb_t cb, void *userdata); | ||
120 | |||
121 | static struct { | ||
122 | const char *name; | ||
123 | void **func; | ||
124 | } pulse_functions[] = { | ||
125 | { "pa_simple_new", | ||
126 | (void **)&SDL_NAME(pa_simple_new) }, | ||
127 | { "pa_simple_free", | ||
128 | (void **)&SDL_NAME(pa_simple_free) }, | ||
129 | { "pa_channel_map_init_auto", | ||
130 | (void **)&SDL_NAME(pa_channel_map_init_auto) }, | ||
131 | { "pa_mainloop_new", | ||
132 | (void **)&SDL_NAME(pa_mainloop_new) }, | ||
133 | { "pa_mainloop_get_api", | ||
134 | (void **)&SDL_NAME(pa_mainloop_get_api) }, | ||
135 | { "pa_mainloop_iterate", | ||
136 | (void **)&SDL_NAME(pa_mainloop_iterate) }, | ||
137 | { "pa_mainloop_free", | ||
138 | (void **)&SDL_NAME(pa_mainloop_free) }, | ||
139 | { "pa_operation_get_state", | ||
140 | (void **)&SDL_NAME(pa_operation_get_state) }, | ||
141 | { "pa_operation_cancel", | ||
142 | (void **)&SDL_NAME(pa_operation_cancel) }, | ||
143 | { "pa_operation_unref", | ||
144 | (void **)&SDL_NAME(pa_operation_unref) }, | ||
145 | { "pa_context_new", | ||
146 | (void **)&SDL_NAME(pa_context_new) }, | ||
147 | { "pa_context_connect", | ||
148 | (void **)&SDL_NAME(pa_context_connect) }, | ||
149 | { "pa_context_get_state", | ||
150 | (void **)&SDL_NAME(pa_context_get_state) }, | ||
151 | { "pa_context_disconnect", | ||
152 | (void **)&SDL_NAME(pa_context_disconnect) }, | ||
153 | { "pa_context_unref", | ||
154 | (void **)&SDL_NAME(pa_context_unref) }, | ||
155 | { "pa_stream_new", | ||
156 | (void **)&SDL_NAME(pa_stream_new) }, | ||
157 | { "pa_stream_connect_playback", | ||
158 | (void **)&SDL_NAME(pa_stream_connect_playback) }, | ||
159 | { "pa_stream_get_state", | ||
160 | (void **)&SDL_NAME(pa_stream_get_state) }, | ||
161 | { "pa_stream_writable_size", | ||
162 | (void **)&SDL_NAME(pa_stream_writable_size) }, | ||
163 | { "pa_stream_write", | ||
164 | (void **)&SDL_NAME(pa_stream_write) }, | ||
165 | { "pa_stream_drain", | ||
166 | (void **)&SDL_NAME(pa_stream_drain) }, | ||
167 | { "pa_stream_disconnect", | ||
168 | (void **)&SDL_NAME(pa_stream_disconnect) }, | ||
169 | { "pa_stream_unref", | ||
170 | (void **)&SDL_NAME(pa_stream_unref) }, | ||
171 | { "pa_context_set_name", | ||
172 | (void **)&SDL_NAME(pa_context_set_name) }, | ||
173 | }; | ||
174 | |||
175 | static void UnloadPulseLibrary() | ||
176 | { | ||
177 | if ( pulse_loaded ) { | ||
178 | SDL_UnloadObject(pulse_handle); | ||
179 | pulse_handle = NULL; | ||
180 | pulse_loaded = 0; | ||
181 | } | ||
182 | } | ||
183 | |||
184 | static int LoadPulseLibrary(void) | ||
185 | { | ||
186 | int i, retval = -1; | ||
187 | |||
188 | pulse_handle = SDL_LoadObject(pulse_library); | ||
189 | if ( pulse_handle ) { | ||
190 | pulse_loaded = 1; | ||
191 | retval = 0; | ||
192 | for ( i=0; i<SDL_arraysize(pulse_functions); ++i ) { | ||
193 | *pulse_functions[i].func = SDL_LoadFunction(pulse_handle, pulse_functions[i].name); | ||
194 | if ( !*pulse_functions[i].func ) { | ||
195 | retval = -1; | ||
196 | UnloadPulseLibrary(); | ||
197 | break; | ||
198 | } | ||
199 | } | ||
200 | } | ||
201 | return retval; | ||
202 | } | ||
203 | |||
204 | #else | ||
205 | |||
206 | static void UnloadPulseLibrary() | ||
207 | { | ||
208 | return; | ||
209 | } | ||
210 | |||
211 | static int LoadPulseLibrary(void) | ||
212 | { | ||
213 | return 0; | ||
214 | } | ||
215 | |||
216 | #endif /* SDL_AUDIO_DRIVER_PULSE_DYNAMIC */ | ||
217 | |||
218 | /* Audio driver bootstrap functions */ | ||
219 | |||
220 | static int Audio_Available(void) | ||
221 | { | ||
222 | pa_sample_spec paspec; | ||
223 | pa_simple *connection; | ||
224 | int available; | ||
225 | |||
226 | available = 0; | ||
227 | if ( LoadPulseLibrary() < 0 ) { | ||
228 | return available; | ||
229 | } | ||
230 | |||
231 | /* Connect with a dummy format. */ | ||
232 | paspec.format = PA_SAMPLE_U8; | ||
233 | paspec.rate = 11025; | ||
234 | paspec.channels = 1; | ||
235 | connection = SDL_NAME(pa_simple_new)( | ||
236 | NULL, /* server */ | ||
237 | "Test stream", /* application name */ | ||
238 | PA_STREAM_PLAYBACK, /* playback mode */ | ||
239 | NULL, /* device on the server */ | ||
240 | "Simple DirectMedia Layer", /* stream description */ | ||
241 | &paspec, /* sample format spec */ | ||
242 | NULL, /* channel map */ | ||
243 | NULL, /* buffering attributes */ | ||
244 | NULL /* error code */ | ||
245 | ); | ||
246 | if ( connection != NULL ) { | ||
247 | available = 1; | ||
248 | SDL_NAME(pa_simple_free)(connection); | ||
249 | } | ||
250 | |||
251 | UnloadPulseLibrary(); | ||
252 | return(available); | ||
253 | } | ||
254 | |||
255 | static void Audio_DeleteDevice(SDL_AudioDevice *device) | ||
256 | { | ||
257 | SDL_free(device->hidden->caption); | ||
258 | SDL_free(device->hidden); | ||
259 | SDL_free(device); | ||
260 | UnloadPulseLibrary(); | ||
261 | } | ||
262 | |||
263 | static SDL_AudioDevice *Audio_CreateDevice(int devindex) | ||
264 | { | ||
265 | SDL_AudioDevice *this; | ||
266 | |||
267 | /* Initialize all variables that we clean on shutdown */ | ||
268 | LoadPulseLibrary(); | ||
269 | this = (SDL_AudioDevice *)SDL_malloc(sizeof(SDL_AudioDevice)); | ||
270 | if ( this ) { | ||
271 | SDL_memset(this, 0, (sizeof *this)); | ||
272 | this->hidden = (struct SDL_PrivateAudioData *) | ||
273 | SDL_malloc((sizeof *this->hidden)); | ||
274 | } | ||
275 | if ( (this == NULL) || (this->hidden == NULL) ) { | ||
276 | SDL_OutOfMemory(); | ||
277 | if ( this ) { | ||
278 | SDL_free(this); | ||
279 | } | ||
280 | return(0); | ||
281 | } | ||
282 | SDL_memset(this->hidden, 0, (sizeof *this->hidden)); | ||
283 | |||
284 | /* Set the function pointers */ | ||
285 | this->OpenAudio = PULSE_OpenAudio; | ||
286 | this->WaitAudio = PULSE_WaitAudio; | ||
287 | this->PlayAudio = PULSE_PlayAudio; | ||
288 | this->GetAudioBuf = PULSE_GetAudioBuf; | ||
289 | this->CloseAudio = PULSE_CloseAudio; | ||
290 | this->WaitDone = PULSE_WaitDone; | ||
291 | this->SetCaption = PULSE_SetCaption; | ||
292 | |||
293 | this->free = Audio_DeleteDevice; | ||
294 | |||
295 | return this; | ||
296 | } | ||
297 | |||
298 | AudioBootStrap PULSE_bootstrap = { | ||
299 | PULSE_DRIVER_NAME, "PulseAudio", | ||
300 | Audio_Available, Audio_CreateDevice | ||
301 | }; | ||
302 | |||
303 | /* This function waits until it is possible to write a full sound buffer */ | ||
304 | static void PULSE_WaitAudio(_THIS) | ||
305 | { | ||
306 | int size; | ||
307 | while(1) { | ||
308 | if (SDL_NAME(pa_context_get_state)(context) != PA_CONTEXT_READY || | ||
309 | SDL_NAME(pa_stream_get_state)(stream) != PA_STREAM_READY || | ||
310 | SDL_NAME(pa_mainloop_iterate)(mainloop, 1, NULL) < 0) { | ||
311 | this->enabled = 0; | ||
312 | return; | ||
313 | } | ||
314 | size = SDL_NAME(pa_stream_writable_size)(stream); | ||
315 | if (size >= mixlen) | ||
316 | return; | ||
317 | } | ||
318 | } | ||
319 | |||
320 | static void PULSE_PlayAudio(_THIS) | ||
321 | { | ||
322 | /* Write the audio data */ | ||
323 | if (SDL_NAME(pa_stream_write)(stream, mixbuf, mixlen, NULL, 0LL, PA_SEEK_RELATIVE) < 0) | ||
324 | this->enabled = 0; | ||
325 | } | ||
326 | |||
327 | static Uint8 *PULSE_GetAudioBuf(_THIS) | ||
328 | { | ||
329 | return(mixbuf); | ||
330 | } | ||
331 | |||
332 | static void PULSE_CloseAudio(_THIS) | ||
333 | { | ||
334 | if ( mixbuf != NULL ) { | ||
335 | SDL_FreeAudioMem(mixbuf); | ||
336 | mixbuf = NULL; | ||
337 | } | ||
338 | if ( stream != NULL ) { | ||
339 | SDL_NAME(pa_stream_disconnect)(stream); | ||
340 | SDL_NAME(pa_stream_unref)(stream); | ||
341 | stream = NULL; | ||
342 | } | ||
343 | if (context != NULL) { | ||
344 | SDL_NAME(pa_context_disconnect)(context); | ||
345 | SDL_NAME(pa_context_unref)(context); | ||
346 | context = NULL; | ||
347 | } | ||
348 | if (mainloop != NULL) { | ||
349 | SDL_NAME(pa_mainloop_free)(mainloop); | ||
350 | mainloop = NULL; | ||
351 | } | ||
352 | } | ||
353 | |||
354 | /* Try to get the name of the program */ | ||
355 | static char *get_progname(void) | ||
356 | { | ||
357 | #ifdef __LINUX__ | ||
358 | char *progname = NULL; | ||
359 | FILE *fp; | ||
360 | static char temp[BUFSIZ]; | ||
361 | |||
362 | SDL_snprintf(temp, SDL_arraysize(temp), "/proc/%d/cmdline", getpid()); | ||
363 | fp = fopen(temp, "r"); | ||
364 | if ( fp != NULL ) { | ||
365 | if ( fgets(temp, sizeof(temp)-1, fp) ) { | ||
366 | progname = SDL_strrchr(temp, '/'); | ||
367 | if ( progname == NULL ) { | ||
368 | progname = temp; | ||
369 | } else { | ||
370 | progname = progname+1; | ||
371 | } | ||
372 | } | ||
373 | fclose(fp); | ||
374 | } | ||
375 | return(progname); | ||
376 | #elif defined(__NetBSD__) | ||
377 | return getprogname(); | ||
378 | #else | ||
379 | return("unknown"); | ||
380 | #endif | ||
381 | } | ||
382 | |||
383 | static void caption_set_complete(pa_context *c, int success, void *userdata) | ||
384 | { | ||
385 | /* no-op. */ | ||
386 | } | ||
387 | |||
388 | static void PULSE_SetCaption(_THIS, const char *str) | ||
389 | { | ||
390 | SDL_free(this->hidden->caption); | ||
391 | if ((str == NULL) || (*str == '\0')) { | ||
392 | str = get_progname(); /* set a default so SOMETHING shows up. */ | ||
393 | } | ||
394 | this->hidden->caption = SDL_strdup(str); | ||
395 | if (context != NULL) { | ||
396 | SDL_NAME(pa_context_set_name)(context, this->hidden->caption, | ||
397 | caption_set_complete, 0); | ||
398 | } | ||
399 | } | ||
400 | |||
401 | static void stream_drain_complete(pa_stream *s, int success, void *userdata) | ||
402 | { | ||
403 | /* no-op. */ | ||
404 | } | ||
405 | |||
406 | static void PULSE_WaitDone(_THIS) | ||
407 | { | ||
408 | pa_operation *o; | ||
409 | |||
410 | o = SDL_NAME(pa_stream_drain)(stream, stream_drain_complete, NULL); | ||
411 | if (!o) | ||
412 | return; | ||
413 | |||
414 | while (SDL_NAME(pa_operation_get_state)(o) != PA_OPERATION_DONE) { | ||
415 | if (SDL_NAME(pa_context_get_state)(context) != PA_CONTEXT_READY || | ||
416 | SDL_NAME(pa_stream_get_state)(stream) != PA_STREAM_READY || | ||
417 | SDL_NAME(pa_mainloop_iterate)(mainloop, 1, NULL) < 0) { | ||
418 | SDL_NAME(pa_operation_cancel)(o); | ||
419 | break; | ||
420 | } | ||
421 | } | ||
422 | SDL_NAME(pa_operation_unref)(o); | ||
423 | } | ||
424 | |||
425 | static int PULSE_OpenAudio(_THIS, SDL_AudioSpec *spec) | ||
426 | { | ||
427 | int state; | ||
428 | Uint16 test_format; | ||
429 | pa_sample_spec paspec; | ||
430 | pa_buffer_attr paattr; | ||
431 | pa_channel_map pacmap; | ||
432 | pa_stream_flags_t flags = 0; | ||
433 | |||
434 | paspec.format = PA_SAMPLE_INVALID; | ||
435 | for ( test_format = SDL_FirstAudioFormat(spec->format); test_format; ) { | ||
436 | switch ( test_format ) { | ||
437 | case AUDIO_U8: | ||
438 | paspec.format = PA_SAMPLE_U8; | ||
439 | break; | ||
440 | case AUDIO_S16LSB: | ||
441 | paspec.format = PA_SAMPLE_S16LE; | ||
442 | break; | ||
443 | case AUDIO_S16MSB: | ||
444 | paspec.format = PA_SAMPLE_S16BE; | ||
445 | break; | ||
446 | } | ||
447 | if ( paspec.format != PA_SAMPLE_INVALID ) | ||
448 | break; | ||
449 | test_format = SDL_NextAudioFormat(); | ||
450 | } | ||
451 | if (paspec.format == PA_SAMPLE_INVALID ) { | ||
452 | SDL_SetError("Couldn't find any suitable audio formats"); | ||
453 | return(-1); | ||
454 | } | ||
455 | spec->format = test_format; | ||
456 | |||
457 | paspec.channels = spec->channels; | ||
458 | paspec.rate = spec->freq; | ||
459 | |||
460 | /* Calculate the final parameters for this audio specification */ | ||
461 | #ifdef PA_STREAM_ADJUST_LATENCY | ||
462 | spec->samples /= 2; /* Mix in smaller chunck to avoid underruns */ | ||
463 | #endif | ||
464 | SDL_CalculateAudioSpec(spec); | ||
465 | |||
466 | /* Allocate mixing buffer */ | ||
467 | mixlen = spec->size; | ||
468 | mixbuf = (Uint8 *)SDL_AllocAudioMem(mixlen); | ||
469 | if ( mixbuf == NULL ) { | ||
470 | return(-1); | ||
471 | } | ||
472 | SDL_memset(mixbuf, spec->silence, spec->size); | ||
473 | |||
474 | /* Reduced prebuffering compared to the defaults. */ | ||
475 | #ifdef PA_STREAM_ADJUST_LATENCY | ||
476 | paattr.tlength = mixlen * 4; /* 2x original requested bufsize */ | ||
477 | paattr.prebuf = -1; | ||
478 | paattr.maxlength = -1; | ||
479 | paattr.minreq = mixlen; /* -1 can lead to pa_stream_writable_size() | ||
480 | >= mixlen never becoming true */ | ||
481 | flags = PA_STREAM_ADJUST_LATENCY; | ||
482 | #else | ||
483 | paattr.tlength = mixlen*2; | ||
484 | paattr.prebuf = mixlen*2; | ||
485 | paattr.maxlength = mixlen*2; | ||
486 | paattr.minreq = mixlen; | ||
487 | #endif | ||
488 | |||
489 | /* The SDL ALSA output hints us that we use Windows' channel mapping */ | ||
490 | /* http://bugzilla.libsdl.org/show_bug.cgi?id=110 */ | ||
491 | SDL_NAME(pa_channel_map_init_auto)( | ||
492 | &pacmap, spec->channels, PA_CHANNEL_MAP_WAVEEX); | ||
493 | |||
494 | /* Set up a new main loop */ | ||
495 | if (!(mainloop = SDL_NAME(pa_mainloop_new)())) { | ||
496 | PULSE_CloseAudio(this); | ||
497 | SDL_SetError("pa_mainloop_new() failed"); | ||
498 | return(-1); | ||
499 | } | ||
500 | |||
501 | if (this->hidden->caption == NULL) { | ||
502 | char *title = NULL; | ||
503 | SDL_WM_GetCaption(&title, NULL); | ||
504 | PULSE_SetCaption(this, title); | ||
505 | } | ||
506 | |||
507 | mainloop_api = SDL_NAME(pa_mainloop_get_api)(mainloop); | ||
508 | if (!(context = SDL_NAME(pa_context_new)(mainloop_api, | ||
509 | this->hidden->caption))) { | ||
510 | PULSE_CloseAudio(this); | ||
511 | SDL_SetError("pa_context_new() failed"); | ||
512 | return(-1); | ||
513 | } | ||
514 | |||
515 | /* Connect to the PulseAudio server */ | ||
516 | if (SDL_NAME(pa_context_connect)(context, NULL, 0, NULL) < 0) { | ||
517 | PULSE_CloseAudio(this); | ||
518 | SDL_SetError("Could not setup connection to PulseAudio"); | ||
519 | return(-1); | ||
520 | } | ||
521 | |||
522 | do { | ||
523 | if (SDL_NAME(pa_mainloop_iterate)(mainloop, 1, NULL) < 0) { | ||
524 | PULSE_CloseAudio(this); | ||
525 | SDL_SetError("pa_mainloop_iterate() failed"); | ||
526 | return(-1); | ||
527 | } | ||
528 | state = SDL_NAME(pa_context_get_state)(context); | ||
529 | if (!PA_CONTEXT_IS_GOOD(state)) { | ||
530 | PULSE_CloseAudio(this); | ||
531 | SDL_SetError("Could not connect to PulseAudio"); | ||
532 | return(-1); | ||
533 | } | ||
534 | } while (state != PA_CONTEXT_READY); | ||
535 | |||
536 | stream = SDL_NAME(pa_stream_new)( | ||
537 | context, | ||
538 | "Simple DirectMedia Layer", /* stream description */ | ||
539 | &paspec, /* sample format spec */ | ||
540 | &pacmap /* channel map */ | ||
541 | ); | ||
542 | if ( stream == NULL ) { | ||
543 | PULSE_CloseAudio(this); | ||
544 | SDL_SetError("Could not setup PulseAudio stream"); | ||
545 | return(-1); | ||
546 | } | ||
547 | |||
548 | if (SDL_NAME(pa_stream_connect_playback)(stream, NULL, &paattr, flags, | ||
549 | NULL, NULL) < 0) { | ||
550 | PULSE_CloseAudio(this); | ||
551 | SDL_SetError("Could not connect PulseAudio stream"); | ||
552 | return(-1); | ||
553 | } | ||
554 | |||
555 | do { | ||
556 | if (SDL_NAME(pa_mainloop_iterate)(mainloop, 1, NULL) < 0) { | ||
557 | PULSE_CloseAudio(this); | ||
558 | SDL_SetError("pa_mainloop_iterate() failed"); | ||
559 | return(-1); | ||
560 | } | ||
561 | state = SDL_NAME(pa_stream_get_state)(stream); | ||
562 | if (!PA_STREAM_IS_GOOD(state)) { | ||
563 | PULSE_CloseAudio(this); | ||
564 | SDL_SetError("Could not create to PulseAudio stream"); | ||
565 | return(-1); | ||
566 | } | ||
567 | } while (state != PA_STREAM_READY); | ||
568 | |||
569 | return(0); | ||
570 | } | ||
diff --git a/apps/plugins/sdl/src/audio/pulse/SDL_pulseaudio.h b/apps/plugins/sdl/src/audio/pulse/SDL_pulseaudio.h deleted file mode 100644 index 63ee751ef6..0000000000 --- a/apps/plugins/sdl/src/audio/pulse/SDL_pulseaudio.h +++ /dev/null | |||
@@ -1,73 +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 Lesser General Public | ||
7 | License as published by the Free Software Foundation; either | ||
8 | version 2.1 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 | Lesser General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU Lesser General Public | ||
16 | License along with this library; if not, write to the Free Software | ||
17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
18 | |||
19 | Stéphan Kochen | ||
20 | stephan@kochen.nl | ||
21 | |||
22 | Based on parts of the ALSA and ESounD output drivers. | ||
23 | */ | ||
24 | #include "SDL_config.h" | ||
25 | |||
26 | #ifndef _SDL_pulseaudio_h | ||
27 | #define _SDL_pulseaudio_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 | pa_mainloop *mainloop; | ||
36 | pa_mainloop_api *mainloop_api; | ||
37 | pa_context *context; | ||
38 | pa_stream *stream; | ||
39 | |||
40 | char *caption; | ||
41 | |||
42 | /* Raw mixing buffer */ | ||
43 | Uint8 *mixbuf; | ||
44 | int mixlen; | ||
45 | }; | ||
46 | |||
47 | #if (PA_API_VERSION < 12) | ||
48 | /** Return non-zero if the passed state is one of the connected states */ | ||
49 | static inline int PA_CONTEXT_IS_GOOD(pa_context_state_t x) { | ||
50 | return | ||
51 | x == PA_CONTEXT_CONNECTING || | ||
52 | x == PA_CONTEXT_AUTHORIZING || | ||
53 | x == PA_CONTEXT_SETTING_NAME || | ||
54 | x == PA_CONTEXT_READY; | ||
55 | } | ||
56 | /** Return non-zero if the passed state is one of the connected states */ | ||
57 | static inline int PA_STREAM_IS_GOOD(pa_stream_state_t x) { | ||
58 | return | ||
59 | x == PA_STREAM_CREATING || | ||
60 | x == PA_STREAM_READY; | ||
61 | } | ||
62 | #endif /* pulseaudio <= 0.9.10 */ | ||
63 | |||
64 | /* Old variable names */ | ||
65 | #define mainloop (this->hidden->mainloop) | ||
66 | #define mainloop_api (this->hidden->mainloop_api) | ||
67 | #define context (this->hidden->context) | ||
68 | #define stream (this->hidden->stream) | ||
69 | #define mixbuf (this->hidden->mixbuf) | ||
70 | #define mixlen (this->hidden->mixlen) | ||
71 | |||
72 | #endif /* _SDL_pulseaudio_h */ | ||
73 | |||
diff --git a/apps/plugins/sdl/src/audio/sun/SDL_sunaudio.c b/apps/plugins/sdl/src/audio/sun/SDL_sunaudio.c deleted file mode 100644 index 7a39e71d1b..0000000000 --- a/apps/plugins/sdl/src/audio/sun/SDL_sunaudio.c +++ /dev/null | |||
@@ -1,432 +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 Lesser General Public | ||
7 | License as published by the Free Software Foundation; either | ||
8 | version 2.1 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 | Lesser General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU Lesser General Public | ||
16 | License along with this library; if not, write to the Free Software | ||
17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 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 <fcntl.h> | ||
27 | #include <errno.h> | ||
28 | #ifdef __NETBSD__ | ||
29 | #include <sys/ioctl.h> | ||
30 | #include <sys/audioio.h> | ||
31 | #endif | ||
32 | #ifdef __SVR4 | ||
33 | #include <sys/audioio.h> | ||
34 | #else | ||
35 | #include <sys/time.h> | ||
36 | #include <sys/types.h> | ||
37 | #endif | ||
38 | #include <unistd.h> | ||
39 | |||
40 | #include "SDL_timer.h" | ||
41 | #include "SDL_audio.h" | ||
42 | #include "../SDL_audiomem.h" | ||
43 | #include "../SDL_audio_c.h" | ||
44 | #include "../SDL_audiodev_c.h" | ||
45 | #include "SDL_sunaudio.h" | ||
46 | |||
47 | /* Open the audio device for playback, and don't block if busy */ | ||
48 | #define OPEN_FLAGS (O_WRONLY|O_NONBLOCK) | ||
49 | |||
50 | /* Audio driver functions */ | ||
51 | static int DSP_OpenAudio(_THIS, SDL_AudioSpec *spec); | ||
52 | static void DSP_WaitAudio(_THIS); | ||
53 | static void DSP_PlayAudio(_THIS); | ||
54 | static Uint8 *DSP_GetAudioBuf(_THIS); | ||
55 | static void DSP_CloseAudio(_THIS); | ||
56 | |||
57 | static Uint8 snd2au(int sample); | ||
58 | |||
59 | /* Audio driver bootstrap functions */ | ||
60 | |||
61 | static int Audio_Available(void) | ||
62 | { | ||
63 | int fd; | ||
64 | int available; | ||
65 | |||
66 | available = 0; | ||
67 | fd = SDL_OpenAudioPath(NULL, 0, OPEN_FLAGS, 1); | ||
68 | if ( fd >= 0 ) { | ||
69 | available = 1; | ||
70 | close(fd); | ||
71 | } | ||
72 | return(available); | ||
73 | } | ||
74 | |||
75 | static void Audio_DeleteDevice(SDL_AudioDevice *device) | ||
76 | { | ||
77 | SDL_free(device->hidden); | ||
78 | SDL_free(device); | ||
79 | } | ||
80 | |||
81 | static SDL_AudioDevice *Audio_CreateDevice(int devindex) | ||
82 | { | ||
83 | SDL_AudioDevice *this; | ||
84 | |||
85 | /* Initialize all variables that we clean on shutdown */ | ||
86 | this = (SDL_AudioDevice *)SDL_malloc(sizeof(SDL_AudioDevice)); | ||
87 | if ( this ) { | ||
88 | SDL_memset(this, 0, (sizeof *this)); | ||
89 | this->hidden = (struct SDL_PrivateAudioData *) | ||
90 | SDL_malloc((sizeof *this->hidden)); | ||
91 | } | ||
92 | if ( (this == NULL) || (this->hidden == NULL) ) { | ||
93 | SDL_OutOfMemory(); | ||
94 | if ( this ) { | ||
95 | SDL_free(this); | ||
96 | } | ||
97 | return(0); | ||
98 | } | ||
99 | SDL_memset(this->hidden, 0, (sizeof *this->hidden)); | ||
100 | audio_fd = -1; | ||
101 | |||
102 | /* Set the function pointers */ | ||
103 | this->OpenAudio = DSP_OpenAudio; | ||
104 | this->WaitAudio = DSP_WaitAudio; | ||
105 | this->PlayAudio = DSP_PlayAudio; | ||
106 | this->GetAudioBuf = DSP_GetAudioBuf; | ||
107 | this->CloseAudio = DSP_CloseAudio; | ||
108 | |||
109 | this->free = Audio_DeleteDevice; | ||
110 | |||
111 | return this; | ||
112 | } | ||
113 | |||
114 | AudioBootStrap SUNAUDIO_bootstrap = { | ||
115 | "audio", "UNIX /dev/audio interface", | ||
116 | Audio_Available, Audio_CreateDevice | ||
117 | }; | ||
118 | |||
119 | #ifdef DEBUG_AUDIO | ||
120 | void CheckUnderflow(_THIS) | ||
121 | { | ||
122 | #ifdef AUDIO_GETINFO | ||
123 | audio_info_t info; | ||
124 | int left; | ||
125 | |||
126 | ioctl(audio_fd, AUDIO_GETINFO, &info); | ||
127 | left = (written - info.play.samples); | ||
128 | if ( written && (left == 0) ) { | ||
129 | fprintf(stderr, "audio underflow!\n"); | ||
130 | } | ||
131 | #endif | ||
132 | } | ||
133 | #endif | ||
134 | |||
135 | void DSP_WaitAudio(_THIS) | ||
136 | { | ||
137 | #ifdef AUDIO_GETINFO | ||
138 | #define SLEEP_FUDGE 10 /* 10 ms scheduling fudge factor */ | ||
139 | audio_info_t info; | ||
140 | Sint32 left; | ||
141 | |||
142 | ioctl(audio_fd, AUDIO_GETINFO, &info); | ||
143 | left = (written - info.play.samples); | ||
144 | if ( left > fragsize ) { | ||
145 | Sint32 sleepy; | ||
146 | |||
147 | sleepy = ((left - fragsize)/frequency); | ||
148 | sleepy -= SLEEP_FUDGE; | ||
149 | if ( sleepy > 0 ) { | ||
150 | SDL_Delay(sleepy); | ||
151 | } | ||
152 | } | ||
153 | #else | ||
154 | fd_set fdset; | ||
155 | |||
156 | FD_ZERO(&fdset); | ||
157 | FD_SET(audio_fd, &fdset); | ||
158 | select(audio_fd+1, NULL, &fdset, NULL, NULL); | ||
159 | #endif | ||
160 | } | ||
161 | |||
162 | void DSP_PlayAudio(_THIS) | ||
163 | { | ||
164 | /* Write the audio data */ | ||
165 | if ( ulaw_only ) { | ||
166 | /* Assuming that this->spec.freq >= 8000 Hz */ | ||
167 | int accum, incr, pos; | ||
168 | Uint8 *aubuf; | ||
169 | |||
170 | accum = 0; | ||
171 | incr = this->spec.freq/8; | ||
172 | aubuf = ulaw_buf; | ||
173 | switch (audio_fmt & 0xFF) { | ||
174 | case 8: { | ||
175 | Uint8 *sndbuf; | ||
176 | |||
177 | sndbuf = mixbuf; | ||
178 | for ( pos=0; pos < fragsize; ++pos ) { | ||
179 | *aubuf = snd2au((0x80-*sndbuf)*64); | ||
180 | accum += incr; | ||
181 | while ( accum > 0 ) { | ||
182 | accum -= 1000; | ||
183 | sndbuf += 1; | ||
184 | } | ||
185 | aubuf += 1; | ||
186 | } | ||
187 | } | ||
188 | break; | ||
189 | case 16: { | ||
190 | Sint16 *sndbuf; | ||
191 | |||
192 | sndbuf = (Sint16 *)mixbuf; | ||
193 | for ( pos=0; pos < fragsize; ++pos ) { | ||
194 | *aubuf = snd2au(*sndbuf/4); | ||
195 | accum += incr; | ||
196 | while ( accum > 0 ) { | ||
197 | accum -= 1000; | ||
198 | sndbuf += 1; | ||
199 | } | ||
200 | aubuf += 1; | ||
201 | } | ||
202 | } | ||
203 | break; | ||
204 | } | ||
205 | #ifdef DEBUG_AUDIO | ||
206 | CheckUnderflow(this); | ||
207 | #endif | ||
208 | if ( write(audio_fd, ulaw_buf, fragsize) < 0 ) { | ||
209 | /* Assume fatal error, for now */ | ||
210 | this->enabled = 0; | ||
211 | } | ||
212 | written += fragsize; | ||
213 | } else { | ||
214 | #ifdef DEBUG_AUDIO | ||
215 | CheckUnderflow(this); | ||
216 | #endif | ||
217 | if ( write(audio_fd, mixbuf, this->spec.size) < 0 ) { | ||
218 | /* Assume fatal error, for now */ | ||
219 | this->enabled = 0; | ||
220 | } | ||
221 | written += fragsize; | ||
222 | } | ||
223 | } | ||
224 | |||
225 | Uint8 *DSP_GetAudioBuf(_THIS) | ||
226 | { | ||
227 | return(mixbuf); | ||
228 | } | ||
229 | |||
230 | void DSP_CloseAudio(_THIS) | ||
231 | { | ||
232 | if ( mixbuf != NULL ) { | ||
233 | SDL_FreeAudioMem(mixbuf); | ||
234 | mixbuf = NULL; | ||
235 | } | ||
236 | if ( ulaw_buf != NULL ) { | ||
237 | SDL_free(ulaw_buf); | ||
238 | ulaw_buf = NULL; | ||
239 | } | ||
240 | close(audio_fd); | ||
241 | } | ||
242 | |||
243 | int DSP_OpenAudio(_THIS, SDL_AudioSpec *spec) | ||
244 | { | ||
245 | char audiodev[1024]; | ||
246 | #ifdef AUDIO_SETINFO | ||
247 | int enc; | ||
248 | #endif | ||
249 | int desired_freq = spec->freq; | ||
250 | |||
251 | /* Initialize our freeable variables, in case we fail*/ | ||
252 | audio_fd = -1; | ||
253 | mixbuf = NULL; | ||
254 | ulaw_buf = NULL; | ||
255 | |||
256 | /* Determine the audio parameters from the AudioSpec */ | ||
257 | switch ( spec->format & 0xFF ) { | ||
258 | |||
259 | case 8: { /* Unsigned 8 bit audio data */ | ||
260 | spec->format = AUDIO_U8; | ||
261 | #ifdef AUDIO_SETINFO | ||
262 | enc = AUDIO_ENCODING_LINEAR8; | ||
263 | #endif | ||
264 | } | ||
265 | break; | ||
266 | |||
267 | case 16: { /* Signed 16 bit audio data */ | ||
268 | spec->format = AUDIO_S16SYS; | ||
269 | #ifdef AUDIO_SETINFO | ||
270 | enc = AUDIO_ENCODING_LINEAR; | ||
271 | #endif | ||
272 | } | ||
273 | break; | ||
274 | |||
275 | default: { | ||
276 | SDL_SetError("Unsupported audio format"); | ||
277 | return(-1); | ||
278 | } | ||
279 | } | ||
280 | audio_fmt = spec->format; | ||
281 | |||
282 | /* Open the audio device */ | ||
283 | audio_fd = SDL_OpenAudioPath(audiodev, sizeof(audiodev), OPEN_FLAGS, 1); | ||
284 | if ( audio_fd < 0 ) { | ||
285 | SDL_SetError("Couldn't open %s: %s", audiodev, | ||
286 | strerror(errno)); | ||
287 | return(-1); | ||
288 | } | ||
289 | |||
290 | ulaw_only = 0; /* modern Suns do support linear audio */ | ||
291 | #ifdef AUDIO_SETINFO | ||
292 | for(;;) { | ||
293 | audio_info_t info; | ||
294 | AUDIO_INITINFO(&info); /* init all fields to "no change" */ | ||
295 | |||
296 | /* Try to set the requested settings */ | ||
297 | info.play.sample_rate = spec->freq; | ||
298 | info.play.channels = spec->channels; | ||
299 | info.play.precision = (enc == AUDIO_ENCODING_ULAW) | ||
300 | ? 8 : spec->format & 0xff; | ||
301 | info.play.encoding = enc; | ||
302 | if( ioctl(audio_fd, AUDIO_SETINFO, &info) == 0 ) { | ||
303 | |||
304 | /* Check to be sure we got what we wanted */ | ||
305 | if(ioctl(audio_fd, AUDIO_GETINFO, &info) < 0) { | ||
306 | SDL_SetError("Error getting audio parameters: %s", | ||
307 | strerror(errno)); | ||
308 | return -1; | ||
309 | } | ||
310 | if(info.play.encoding == enc | ||
311 | && info.play.precision == (spec->format & 0xff) | ||
312 | && info.play.channels == spec->channels) { | ||
313 | /* Yow! All seems to be well! */ | ||
314 | spec->freq = info.play.sample_rate; | ||
315 | break; | ||
316 | } | ||
317 | } | ||
318 | |||
319 | switch(enc) { | ||
320 | case AUDIO_ENCODING_LINEAR8: | ||
321 | /* unsigned 8bit apparently not supported here */ | ||
322 | enc = AUDIO_ENCODING_LINEAR; | ||
323 | spec->format = AUDIO_S16SYS; | ||
324 | break; /* try again */ | ||
325 | |||
326 | case AUDIO_ENCODING_LINEAR: | ||
327 | /* linear 16bit didn't work either, resort to µ-law */ | ||
328 | enc = AUDIO_ENCODING_ULAW; | ||
329 | spec->channels = 1; | ||
330 | spec->freq = 8000; | ||
331 | spec->format = AUDIO_U8; | ||
332 | ulaw_only = 1; | ||
333 | break; | ||
334 | |||
335 | default: | ||
336 | /* oh well... */ | ||
337 | SDL_SetError("Error setting audio parameters: %s", | ||
338 | strerror(errno)); | ||
339 | return -1; | ||
340 | } | ||
341 | } | ||
342 | #endif /* AUDIO_SETINFO */ | ||
343 | written = 0; | ||
344 | |||
345 | /* We can actually convert on-the-fly to U-Law */ | ||
346 | if ( ulaw_only ) { | ||
347 | spec->freq = desired_freq; | ||
348 | fragsize = (spec->samples*1000)/(spec->freq/8); | ||
349 | frequency = 8; | ||
350 | ulaw_buf = (Uint8 *)SDL_malloc(fragsize); | ||
351 | if ( ulaw_buf == NULL ) { | ||
352 | SDL_OutOfMemory(); | ||
353 | return(-1); | ||
354 | } | ||
355 | spec->channels = 1; | ||
356 | } else { | ||
357 | fragsize = spec->samples; | ||
358 | frequency = spec->freq/1000; | ||
359 | } | ||
360 | #ifdef DEBUG_AUDIO | ||
361 | fprintf(stderr, "Audio device %s U-Law only\n", | ||
362 | ulaw_only ? "is" : "is not"); | ||
363 | fprintf(stderr, "format=0x%x chan=%d freq=%d\n", | ||
364 | spec->format, spec->channels, spec->freq); | ||
365 | #endif | ||
366 | |||
367 | /* Update the fragment size as size in bytes */ | ||
368 | SDL_CalculateAudioSpec(spec); | ||
369 | |||
370 | /* Allocate mixing buffer */ | ||
371 | mixbuf = (Uint8 *)SDL_AllocAudioMem(spec->size); | ||
372 | if ( mixbuf == NULL ) { | ||
373 | SDL_OutOfMemory(); | ||
374 | return(-1); | ||
375 | } | ||
376 | SDL_memset(mixbuf, spec->silence, spec->size); | ||
377 | |||
378 | /* We're ready to rock and roll. :-) */ | ||
379 | return(0); | ||
380 | } | ||
381 | |||
382 | /************************************************************************/ | ||
383 | /* This function (snd2au()) copyrighted: */ | ||
384 | /************************************************************************/ | ||
385 | /* Copyright 1989 by Rich Gopstein and Harris Corporation */ | ||
386 | /* */ | ||
387 | /* Permission to use, copy, modify, and distribute this software */ | ||
388 | /* and its documentation for any purpose and without fee is */ | ||
389 | /* hereby granted, provided that the above copyright notice */ | ||
390 | /* appears in all copies and that both that copyright notice and */ | ||
391 | /* this permission notice appear in supporting documentation, and */ | ||
392 | /* that the name of Rich Gopstein and Harris Corporation not be */ | ||
393 | /* used in advertising or publicity pertaining to distribution */ | ||
394 | /* of the software without specific, written prior permission. */ | ||
395 | /* Rich Gopstein and Harris Corporation make no representations */ | ||
396 | /* about the suitability of this software for any purpose. It */ | ||
397 | /* provided "as is" without express or implied warranty. */ | ||
398 | /************************************************************************/ | ||
399 | |||
400 | static Uint8 snd2au(int sample) | ||
401 | { | ||
402 | |||
403 | int mask; | ||
404 | |||
405 | if (sample < 0) { | ||
406 | sample = -sample; | ||
407 | mask = 0x7f; | ||
408 | } else { | ||
409 | mask = 0xff; | ||
410 | } | ||
411 | |||
412 | if (sample < 32) { | ||
413 | sample = 0xF0 | (15 - sample / 2); | ||
414 | } else if (sample < 96) { | ||
415 | sample = 0xE0 | (15 - (sample - 32) / 4); | ||
416 | } else if (sample < 224) { | ||
417 | sample = 0xD0 | (15 - (sample - 96) / 8); | ||
418 | } else if (sample < 480) { | ||
419 | sample = 0xC0 | (15 - (sample - 224) / 16); | ||
420 | } else if (sample < 992) { | ||
421 | sample = 0xB0 | (15 - (sample - 480) / 32); | ||
422 | } else if (sample < 2016) { | ||
423 | sample = 0xA0 | (15 - (sample - 992) / 64); | ||
424 | } else if (sample < 4064) { | ||
425 | sample = 0x90 | (15 - (sample - 2016) / 128); | ||
426 | } else if (sample < 8160) { | ||
427 | sample = 0x80 | (15 - (sample - 4064) / 256); | ||
428 | } else { | ||
429 | sample = 0x80; | ||
430 | } | ||
431 | return (mask & sample); | ||
432 | } | ||
diff --git a/apps/plugins/sdl/src/audio/sun/SDL_sunaudio.h b/apps/plugins/sdl/src/audio/sun/SDL_sunaudio.h deleted file mode 100644 index e6be419376..0000000000 --- a/apps/plugins/sdl/src/audio/sun/SDL_sunaudio.h +++ /dev/null | |||
@@ -1,55 +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 Lesser General Public | ||
7 | License as published by the Free Software Foundation; either | ||
8 | version 2.1 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 | Lesser General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU Lesser General Public | ||
16 | License along with this library; if not, write to the Free Software | ||
17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
18 | |||
19 | Sam Lantinga | ||
20 | slouken@libsdl.org | ||
21 | */ | ||
22 | #include "SDL_config.h" | ||
23 | |||
24 | #ifndef _SDL_lowaudio_h | ||
25 | #define _SDL_lowaudio_h | ||
26 | |||
27 | #include "../SDL_sysaudio.h" | ||
28 | |||
29 | /* Hidden "this" pointer for the video functions */ | ||
30 | #define _THIS SDL_AudioDevice *this | ||
31 | |||
32 | struct SDL_PrivateAudioData { | ||
33 | /* The file descriptor for the audio device */ | ||
34 | int audio_fd; | ||
35 | |||
36 | Uint16 audio_fmt; /* The app audio format */ | ||
37 | Uint8 *mixbuf; /* The app mixing buffer */ | ||
38 | int ulaw_only; /* Flag -- does hardware only output U-law? */ | ||
39 | Uint8 *ulaw_buf; /* The U-law mixing buffer */ | ||
40 | Sint32 written; /* The number of samples written */ | ||
41 | int fragsize; /* The audio fragment size in samples */ | ||
42 | int frequency; /* The audio frequency in KHz */ | ||
43 | }; | ||
44 | |||
45 | /* Old variable names */ | ||
46 | #define audio_fd (this->hidden->audio_fd) | ||
47 | #define audio_fmt (this->hidden->audio_fmt) | ||
48 | #define mixbuf (this->hidden->mixbuf) | ||
49 | #define ulaw_only (this->hidden->ulaw_only) | ||
50 | #define ulaw_buf (this->hidden->ulaw_buf) | ||
51 | #define written (this->hidden->written) | ||
52 | #define fragsize (this->hidden->fragsize) | ||
53 | #define frequency (this->hidden->frequency) | ||
54 | |||
55 | #endif /* _SDL_lowaudio_h */ | ||
diff --git a/apps/plugins/sdl/src/audio/symbian/SDL_epocaudio.cpp b/apps/plugins/sdl/src/audio/symbian/SDL_epocaudio.cpp deleted file mode 100644 index 72a4eaf4e1..0000000000 --- a/apps/plugins/sdl/src/audio/symbian/SDL_epocaudio.cpp +++ /dev/null | |||
@@ -1,614 +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@devolution.com | ||
21 | */ | ||
22 | |||
23 | /* | ||
24 | SDL_epocaudio.cpp | ||
25 | Epoc based SDL audio driver implementation | ||
26 | |||
27 | Markus Mertama | ||
28 | */ | ||
29 | |||
30 | #ifdef SAVE_RCSID | ||
31 | static char rcsid = | ||
32 | "@(#) $Id: SDL_epocaudio.c,v 0.0.0.0 2001/06/19 17:19:56 hercules Exp $"; | ||
33 | #endif | ||
34 | |||
35 | |||
36 | #include <stdlib.h> | ||
37 | #include <stdio.h> | ||
38 | #include <string.h> | ||
39 | #include <errno.h> | ||
40 | #include <unistd.h> | ||
41 | #include <fcntl.h> | ||
42 | #include <signal.h> | ||
43 | #include <sys/time.h> | ||
44 | #include <sys/ioctl.h> | ||
45 | #include <sys/stat.h> | ||
46 | |||
47 | #include "epoc_sdl.h" | ||
48 | |||
49 | #include <e32hal.h> | ||
50 | |||
51 | |||
52 | extern "C" { | ||
53 | #include "SDL_audio.h" | ||
54 | #include "SDL_error.h" | ||
55 | #include "SDL_audiomem.h" | ||
56 | #include "SDL_audio_c.h" | ||
57 | #include "SDL_timer.h" | ||
58 | #include "SDL_audiodev_c.h" | ||
59 | } | ||
60 | |||
61 | #include "SDL_epocaudio.h" | ||
62 | |||
63 | #include "streamplayer.h" | ||
64 | |||
65 | |||
66 | //#define DEBUG_AUDIO | ||
67 | |||
68 | |||
69 | /* Audio driver functions */ | ||
70 | |||
71 | static int EPOC_OpenAudio(SDL_AudioDevice *thisdevice, SDL_AudioSpec *spec); | ||
72 | static void EPOC_WaitAudio(SDL_AudioDevice *thisdevice); | ||
73 | static void EPOC_PlayAudio(SDL_AudioDevice *thisdevice); | ||
74 | static Uint8 *EPOC_GetAudioBuf(SDL_AudioDevice *thisdevice); | ||
75 | static void EPOC_CloseAudio(SDL_AudioDevice *thisdevice); | ||
76 | static void EPOC_ThreadInit(SDL_AudioDevice *thisdevice); | ||
77 | |||
78 | static int Audio_Available(void); | ||
79 | static SDL_AudioDevice *Audio_CreateDevice(int devindex); | ||
80 | static void Audio_DeleteDevice(SDL_AudioDevice *device); | ||
81 | |||
82 | |||
83 | //void sos_adump(SDL_AudioDevice* thisdevice, void* data, int len); | ||
84 | |||
85 | #ifdef __WINS__ | ||
86 | #define DODUMP | ||
87 | #endif | ||
88 | |||
89 | #ifdef DODUMP | ||
90 | NONSHARABLE_CLASS(TDump) | ||
91 | { | ||
92 | public: | ||
93 | TInt Open(); | ||
94 | void Close(); | ||
95 | void Dump(const TDesC8& aDes); | ||
96 | private: | ||
97 | RFile iFile; | ||
98 | RFs iFs; | ||
99 | }; | ||
100 | |||
101 | TInt TDump::Open() | ||
102 | { | ||
103 | TInt err = iFs.Connect(); | ||
104 | if(err == KErrNone) | ||
105 | { | ||
106 | #ifdef __WINS__ | ||
107 | _LIT(target, "C:\\sdlau.raw"); | ||
108 | #else | ||
109 | _LIT(target, "E:\\sdlau.raw"); | ||
110 | #endif | ||
111 | err = iFile.Replace(iFs, target, EFileWrite); | ||
112 | } | ||
113 | return err; | ||
114 | } | ||
115 | void TDump::Close() | ||
116 | { | ||
117 | iFile.Close(); | ||
118 | iFs.Close(); | ||
119 | } | ||
120 | void TDump::Dump(const TDesC8& aDes) | ||
121 | { | ||
122 | iFile.Write(aDes); | ||
123 | } | ||
124 | #endif | ||
125 | |||
126 | |||
127 | NONSHARABLE_CLASS(CSimpleWait) : public CTimer | ||
128 | { | ||
129 | public: | ||
130 | void Wait(TTimeIntervalMicroSeconds32 aWait); | ||
131 | static CSimpleWait* NewL(); | ||
132 | private: | ||
133 | CSimpleWait(); | ||
134 | void RunL(); | ||
135 | }; | ||
136 | |||
137 | |||
138 | CSimpleWait* CSimpleWait::NewL() | ||
139 | { | ||
140 | CSimpleWait* wait = new (ELeave) CSimpleWait(); | ||
141 | CleanupStack::PushL(wait); | ||
142 | wait->ConstructL(); | ||
143 | CleanupStack::Pop(); | ||
144 | return wait; | ||
145 | } | ||
146 | |||
147 | void CSimpleWait::Wait(TTimeIntervalMicroSeconds32 aWait) | ||
148 | { | ||
149 | After(aWait); | ||
150 | CActiveScheduler::Start(); | ||
151 | } | ||
152 | |||
153 | CSimpleWait::CSimpleWait() : CTimer(CActive::EPriorityStandard) | ||
154 | { | ||
155 | CActiveScheduler::Add(this); | ||
156 | } | ||
157 | |||
158 | void CSimpleWait::RunL() | ||
159 | { | ||
160 | CActiveScheduler::Stop(); | ||
161 | } | ||
162 | |||
163 | const TInt KAudioBuffers(2); | ||
164 | |||
165 | |||
166 | NONSHARABLE_CLASS(CEpocAudio) : public CBase, public MStreamObs, public MStreamProvider | ||
167 | { | ||
168 | public: | ||
169 | static void* NewL(TInt BufferSize, TInt aFill); | ||
170 | inline static CEpocAudio& Current(SDL_AudioDevice* thisdevice); | ||
171 | |||
172 | static void Free(SDL_AudioDevice* thisdevice); | ||
173 | |||
174 | void Wait(); | ||
175 | void Play(); | ||
176 | // void SetBuffer(const TDesC8& aBuffer); | ||
177 | void ThreadInitL(TAny* aDevice); | ||
178 | void Open(TInt iRate, TInt iChannels, TUint32 aType, TInt aBytes); | ||
179 | ~CEpocAudio(); | ||
180 | TUint8* Buffer(); | ||
181 | TBool SetPause(TBool aPause); | ||
182 | #ifdef DODUMP | ||
183 | void Dump(const TDesC8& aBuf) {iDump.Dump(aBuf);} | ||
184 | #endif | ||
185 | private: | ||
186 | CEpocAudio(TInt aBufferSize); | ||
187 | void Complete(TInt aState, TInt aError); | ||
188 | TPtrC8 Data(); | ||
189 | void ConstructL(TInt aFill); | ||
190 | private: | ||
191 | TInt iBufferSize; | ||
192 | CStreamPlayer* iPlayer; | ||
193 | TInt iBufferRate; | ||
194 | TInt iRate; | ||
195 | TInt iChannels; | ||
196 | TUint32 iType; | ||
197 | TInt iPosition; | ||
198 | TThreadId iTid; | ||
199 | TUint8* iAudioPtr; | ||
200 | TUint8* iBuffer; | ||
201 | // TTimeIntervalMicroSeconds iStart; | ||
202 | TTime iStart; | ||
203 | TInt iTune; | ||
204 | CSimpleWait* iWait; | ||
205 | #ifdef DODUMP | ||
206 | TDump iDump; | ||
207 | #endif | ||
208 | }; | ||
209 | |||
210 | inline CEpocAudio& CEpocAudio::Current(SDL_AudioDevice* thisdevice) | ||
211 | { | ||
212 | return *static_cast<CEpocAudio*>((void*)thisdevice->hidden); | ||
213 | } | ||
214 | |||
215 | /* | ||
216 | |||
217 | TBool EndSc(TAny*) | ||
218 | { | ||
219 | CActiveScheduler::Stop(); | ||
220 | } | ||
221 | |||
222 | LOCAL_C void CleanScL() | ||
223 | { | ||
224 | CIdle* d = CIdle::NewLC(CActive:::EPriorityIdle); | ||
225 | d->Start(TCallBack(EndSc)); | ||
226 | CActiveScheduler::Start(); | ||
227 | |||
228 | } | ||
229 | */ | ||
230 | |||
231 | void CEpocAudio::Free(SDL_AudioDevice* thisdevice) | ||
232 | { | ||
233 | CEpocAudio* ea = static_cast<CEpocAudio*>((void*)thisdevice->hidden); | ||
234 | if(ea) | ||
235 | { | ||
236 | ASSERT(ea->iTid == RThread().Id()); | ||
237 | delete ea; | ||
238 | thisdevice->hidden = NULL; | ||
239 | |||
240 | CActiveScheduler* as = CActiveScheduler::Current(); | ||
241 | ASSERT(as->StackDepth() == 0); | ||
242 | delete as; | ||
243 | CActiveScheduler::Install(NULL); | ||
244 | } | ||
245 | ASSERT(thisdevice->hidden == NULL); | ||
246 | } | ||
247 | |||
248 | CEpocAudio::CEpocAudio(TInt aBufferSize) : iBufferSize(aBufferSize), iPosition(-1) | ||
249 | { | ||
250 | } | ||
251 | |||
252 | void* CEpocAudio::NewL(TInt aBufferSize, TInt aFill) | ||
253 | { | ||
254 | CEpocAudio* eAudioLib = new (ELeave) CEpocAudio(aBufferSize); | ||
255 | CleanupStack::PushL(eAudioLib); | ||
256 | eAudioLib->ConstructL(aFill); | ||
257 | CleanupStack::Pop(); | ||
258 | return eAudioLib; | ||
259 | } | ||
260 | |||
261 | void CEpocAudio::ConstructL(TInt aFill) | ||
262 | { | ||
263 | iBuffer = (TUint8*) User::AllocL(KAudioBuffers * iBufferSize); | ||
264 | memset(iBuffer, aFill, KAudioBuffers * iBufferSize); | ||
265 | iAudioPtr = iBuffer; | ||
266 | } | ||
267 | |||
268 | |||
269 | TBool CEpocAudio::SetPause(TBool aPause) | ||
270 | { | ||
271 | if(aPause && iPosition >= 0) | ||
272 | { | ||
273 | iPosition = -1; | ||
274 | if(iPlayer != NULL) | ||
275 | iPlayer->Stop(); | ||
276 | } | ||
277 | if(!aPause && iPosition < 0) | ||
278 | { | ||
279 | iPosition = 0; | ||
280 | if(iPlayer != NULL) | ||
281 | iPlayer->Start(); | ||
282 | } | ||
283 | return iPosition < 0; | ||
284 | } | ||
285 | |||
286 | void CEpocAudio::ThreadInitL(TAny* aDevice) | ||
287 | { | ||
288 | iTid = RThread().Id(); | ||
289 | CActiveScheduler* as = new (ELeave) CActiveScheduler(); | ||
290 | CActiveScheduler::Install(as); | ||
291 | |||
292 | EpocSdlEnv::AppendCleanupItem(TSdlCleanupItem((TSdlCleanupOperation)EPOC_CloseAudio, aDevice)); | ||
293 | |||
294 | iWait = CSimpleWait::NewL(); | ||
295 | |||
296 | iPlayer = new (ELeave) CStreamPlayer(*this, *this); | ||
297 | iPlayer->ConstructL(); | ||
298 | iPlayer->OpenStream(iRate, iChannels, iType); | ||
299 | |||
300 | #ifdef DODUMP | ||
301 | User::LeaveIfError(iDump.Open()); | ||
302 | #endif | ||
303 | } | ||
304 | |||
305 | |||
306 | |||
307 | TUint8* CEpocAudio::Buffer() | ||
308 | { | ||
309 | iStart.UniversalTime(); | ||
310 | // iStart = iPlayer->Position(); | ||
311 | return iAudioPtr; | ||
312 | |||
313 | } | ||
314 | |||
315 | CEpocAudio::~CEpocAudio() | ||
316 | { | ||
317 | if(iWait != NULL) | ||
318 | iWait->Cancel(); | ||
319 | delete iWait; | ||
320 | if(iPlayer != NULL) | ||
321 | iPlayer->Close(); | ||
322 | delete iPlayer; | ||
323 | delete iBuffer; | ||
324 | } | ||
325 | |||
326 | void CEpocAudio::Complete(TInt aState, TInt aError) | ||
327 | { | ||
328 | if(aState == MStreamObs::EClose) | ||
329 | { | ||
330 | } | ||
331 | if(iPlayer->Closed()) | ||
332 | return; | ||
333 | switch(aError) | ||
334 | { | ||
335 | case KErrUnderflow: | ||
336 | case KErrInUse: | ||
337 | iPlayer->Start(); | ||
338 | break; | ||
339 | case KErrAbort: | ||
340 | iPlayer->Open(); | ||
341 | } | ||
342 | } | ||
343 | |||
344 | |||
345 | void sos_adump(SDL_AudioDevice* thisdevice, void* data, int len) | ||
346 | { | ||
347 | #ifdef DODUMP | ||
348 | const TPtrC8 buf((TUint8*)data, len); | ||
349 | CEpocAudio::Current(thisdevice).Dump(buf); | ||
350 | #endif | ||
351 | } | ||
352 | |||
353 | const TInt KClip(256); | ||
354 | |||
355 | TPtrC8 CEpocAudio::Data() | ||
356 | { | ||
357 | if(iPosition < 0) | ||
358 | return KNullDesC8(); | ||
359 | |||
360 | TPtrC8 data(iAudioPtr + iPosition, KClip); | ||
361 | |||
362 | #ifdef DODUMP | ||
363 | iDump.Dump(data); | ||
364 | #endif | ||
365 | |||
366 | iPosition += KClip; | ||
367 | if(iPosition >= iBufferSize) | ||
368 | { | ||
369 | |||
370 | /* if(iAudioPtr == iBuffer) | ||
371 | iAudioPtr = iBuffer + iBufferSize; | ||
372 | else | ||
373 | iAudioPtr = iBuffer; | ||
374 | */ | ||
375 | iAudioPtr += iBufferSize; | ||
376 | |||
377 | if((iAudioPtr - iBuffer) >= KAudioBuffers * iBufferSize) | ||
378 | iAudioPtr = iBuffer; | ||
379 | |||
380 | iPosition = -1; | ||
381 | if(iWait->IsActive()) | ||
382 | { | ||
383 | iWait->Cancel(); | ||
384 | CActiveScheduler::Stop(); | ||
385 | } | ||
386 | } | ||
387 | return data; | ||
388 | } | ||
389 | |||
390 | |||
391 | |||
392 | |||
393 | void CEpocAudio::Play() | ||
394 | { | ||
395 | iPosition = 0; | ||
396 | } | ||
397 | |||
398 | void CEpocAudio::Wait() | ||
399 | { | ||
400 | if(iPosition >= 0 /*&& iPlayer->Playing()*/) | ||
401 | { | ||
402 | const TInt64 bufMs = TInt64(iBufferSize - KClip) * TInt64(1000000); | ||
403 | const TInt64 specTime = bufMs / TInt64(iRate * iChannels * 2); | ||
404 | iWait->After(specTime); | ||
405 | |||
406 | CActiveScheduler::Start(); | ||
407 | TTime end; | ||
408 | end.UniversalTime(); | ||
409 | const TTimeIntervalMicroSeconds delta = end.MicroSecondsFrom(iStart); | ||
410 | |||
411 | |||
412 | // const TTimeIntervalMicroSeconds end = iPlayer->Position(); | ||
413 | |||
414 | |||
415 | |||
416 | |||
417 | const TInt diff = specTime - delta.Int64(); | ||
418 | |||
419 | if(diff > 0 && diff < 200000) | ||
420 | { | ||
421 | User::After(diff); | ||
422 | } | ||
423 | |||
424 | } | ||
425 | else | ||
426 | { | ||
427 | User::After(10000); | ||
428 | // iWait->Wait(10000); //just give some time... | ||
429 | } | ||
430 | } | ||
431 | |||
432 | void CEpocAudio::Open(TInt aRate, TInt aChannels, TUint32 aType, TInt aBytes) | ||
433 | { | ||
434 | iRate = aRate; | ||
435 | iChannels = aChannels; | ||
436 | iType = aType; | ||
437 | iBufferRate = iRate * iChannels * aBytes; //1/x | ||
438 | } | ||
439 | |||
440 | |||
441 | /* Audio driver bootstrap functions */ | ||
442 | |||
443 | AudioBootStrap EPOCAudio_bootstrap = { | ||
444 | "epoc\0\0\0", | ||
445 | "EPOC streaming audio\0\0\0", | ||
446 | Audio_Available, | ||
447 | Audio_CreateDevice | ||
448 | }; | ||
449 | |||
450 | |||
451 | static SDL_AudioDevice *Audio_CreateDevice(int /*devindex*/) | ||
452 | { | ||
453 | SDL_AudioDevice *thisdevice; | ||
454 | |||
455 | /* Initialize all variables that we clean on shutdown */ | ||
456 | thisdevice = (SDL_AudioDevice *)malloc(sizeof(SDL_AudioDevice)); | ||
457 | if ( thisdevice ) { | ||
458 | memset(thisdevice, 0, (sizeof *thisdevice)); | ||
459 | thisdevice->hidden = NULL; /*(struct SDL_PrivateAudioData *) | ||
460 | malloc((sizeof thisdevice->hidden)); */ | ||
461 | } | ||
462 | if ( (thisdevice == NULL) /*|| (thisdevice->hidden == NULL) */) { | ||
463 | SDL_OutOfMemory(); | ||
464 | if ( thisdevice ) { | ||
465 | free(thisdevice); | ||
466 | } | ||
467 | return(0); | ||
468 | } | ||
469 | // memset(thisdevice->hidden, 0, (sizeof *thisdevice->hidden)); | ||
470 | |||
471 | /* Set the function pointers */ | ||
472 | thisdevice->OpenAudio = EPOC_OpenAudio; | ||
473 | thisdevice->WaitAudio = EPOC_WaitAudio; | ||
474 | thisdevice->PlayAudio = EPOC_PlayAudio; | ||
475 | thisdevice->GetAudioBuf = EPOC_GetAudioBuf; | ||
476 | thisdevice->CloseAudio = EPOC_CloseAudio; | ||
477 | thisdevice->ThreadInit = EPOC_ThreadInit; | ||
478 | thisdevice->free = Audio_DeleteDevice; | ||
479 | |||
480 | return thisdevice; | ||
481 | } | ||
482 | |||
483 | |||
484 | static void Audio_DeleteDevice(SDL_AudioDevice *device) | ||
485 | { | ||
486 | //free(device->hidden); | ||
487 | free(device); | ||
488 | } | ||
489 | |||
490 | static int Audio_Available(void) | ||
491 | { | ||
492 | return(1); // Audio stream modules should be always there! | ||
493 | } | ||
494 | |||
495 | |||
496 | static int EPOC_OpenAudio(SDL_AudioDevice *thisdevice, SDL_AudioSpec *spec) | ||
497 | { | ||
498 | SDL_TRACE("SDL:EPOC_OpenAudio"); | ||
499 | |||
500 | |||
501 | TUint32 type = KMMFFourCCCodePCM16; | ||
502 | TInt bytes = 2; | ||
503 | |||
504 | switch(spec->format) | ||
505 | { | ||
506 | case AUDIO_U16LSB: | ||
507 | type = KMMFFourCCCodePCMU16; | ||
508 | break; | ||
509 | case AUDIO_S16LSB: | ||
510 | type = KMMFFourCCCodePCM16; | ||
511 | break; | ||
512 | case AUDIO_U16MSB: | ||
513 | type = KMMFFourCCCodePCMU16B; | ||
514 | break; | ||
515 | case AUDIO_S16MSB: | ||
516 | type = KMMFFourCCCodePCM16B; | ||
517 | break; | ||
518 | //8 bit not supported! | ||
519 | case AUDIO_U8: | ||
520 | case AUDIO_S8: | ||
521 | default: | ||
522 | spec->format = AUDIO_S16LSB; | ||
523 | }; | ||
524 | |||
525 | |||
526 | |||
527 | if(spec->channels > 2) | ||
528 | spec->channels = 2; | ||
529 | |||
530 | spec->freq = CStreamPlayer::ClosestSupportedRate(spec->freq); | ||
531 | |||
532 | |||
533 | /* Allocate mixing buffer */ | ||
534 | const TInt buflen = spec->size;// * bytes * spec->channels; | ||
535 | // audiobuf = NULL; | ||
536 | |||
537 | TRAPD(err, thisdevice->hidden = static_cast<SDL_PrivateAudioData*>(CEpocAudio::NewL(buflen, spec->silence))); | ||
538 | if(err != KErrNone) | ||
539 | return -1; | ||
540 | |||
541 | CEpocAudio::Current(thisdevice).Open(spec->freq, spec->channels, type, bytes); | ||
542 | |||
543 | CEpocAudio::Current(thisdevice).SetPause(ETrue); | ||
544 | |||
545 | // isSDLAudioPaused = 1; | ||
546 | |||
547 | thisdevice->enabled = 0; /* enable only after audio engine has been initialized!*/ | ||
548 | |||
549 | /* We're ready to rock and roll. :-) */ | ||
550 | return(0); | ||
551 | } | ||
552 | |||
553 | |||
554 | static void EPOC_CloseAudio(SDL_AudioDevice* thisdevice) | ||
555 | { | ||
556 | #ifdef DEBUG_AUDIO | ||
557 | SDL_TRACE("Close audio\n"); | ||
558 | #endif | ||
559 | |||
560 | CEpocAudio::Free(thisdevice); | ||
561 | } | ||
562 | |||
563 | |||
564 | static void EPOC_ThreadInit(SDL_AudioDevice *thisdevice) | ||
565 | { | ||
566 | SDL_TRACE("SDL:EPOC_ThreadInit"); | ||
567 | CEpocAudio::Current(thisdevice).ThreadInitL(thisdevice); | ||
568 | RThread().SetPriority(EPriorityMore); | ||
569 | thisdevice->enabled = 1; | ||
570 | } | ||
571 | |||
572 | /* This function waits until it is possible to write a full sound buffer */ | ||
573 | static void EPOC_WaitAudio(SDL_AudioDevice* thisdevice) | ||
574 | { | ||
575 | #ifdef DEBUG_AUDIO | ||
576 | SDL_TRACE1("wait %d audio\n", CEpocAudio::AudioLib().StreamPlayer(KSfxChannel).SyncTime()); | ||
577 | TInt tics = User::TickCount(); | ||
578 | #endif | ||
579 | |||
580 | CEpocAudio::Current(thisdevice).Wait(); | ||
581 | |||
582 | #ifdef DEBUG_AUDIO | ||
583 | TInt ntics = User::TickCount() - tics; | ||
584 | SDL_TRACE1("audio waited %d\n", ntics); | ||
585 | SDL_TRACE1("audio at %d\n", tics); | ||
586 | #endif | ||
587 | } | ||
588 | |||
589 | |||
590 | |||
591 | static void EPOC_PlayAudio(SDL_AudioDevice* thisdevice) | ||
592 | { | ||
593 | if(CEpocAudio::Current(thisdevice).SetPause(SDL_GetAudioStatus() == SDL_AUDIO_PAUSED)) | ||
594 | SDL_Delay(500); //hold on the busy loop | ||
595 | else | ||
596 | CEpocAudio::Current(thisdevice).Play(); | ||
597 | |||
598 | #ifdef DEBUG_AUDIO | ||
599 | SDL_TRACE("buffer has audio data\n"); | ||
600 | #endif | ||
601 | |||
602 | |||
603 | #ifdef DEBUG_AUDIO | ||
604 | SDL_TRACE1("Wrote %d bytes of audio data\n", buflen); | ||
605 | #endif | ||
606 | } | ||
607 | |||
608 | static Uint8 *EPOC_GetAudioBuf(SDL_AudioDevice* thisdevice) | ||
609 | { | ||
610 | return CEpocAudio::Current(thisdevice).Buffer(); | ||
611 | } | ||
612 | |||
613 | |||
614 | |||
diff --git a/apps/plugins/sdl/src/audio/symbian/SDL_epocaudio.h b/apps/plugins/sdl/src/audio/symbian/SDL_epocaudio.h deleted file mode 100644 index 5c95c86158..0000000000 --- a/apps/plugins/sdl/src/audio/symbian/SDL_epocaudio.h +++ /dev/null | |||
@@ -1,37 +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@devolution.com | ||
21 | */ | ||
22 | |||
23 | |||
24 | #ifdef SAVE_RCSID | ||
25 | static char rcsid = | ||
26 | "@(#) $Id: SDL_epocaudio.h,v 1.1.2.2 2001/02/10 07:20:03 hercules Exp $"; | ||
27 | #endif | ||
28 | |||
29 | #ifndef _SDL_EPOCAUDIO_H | ||
30 | #define _SDL_EPOCAUDIO_H | ||
31 | |||
32 | extern "C" { | ||
33 | #include "SDL_sysaudio.h" | ||
34 | } | ||
35 | |||
36 | |||
37 | #endif /* _SDL_EPOCAUDIO_H */ | ||
diff --git a/apps/plugins/sdl/src/audio/symbian/streamplayer.cpp b/apps/plugins/sdl/src/audio/symbian/streamplayer.cpp deleted file mode 100644 index dd733a1d17..0000000000 --- a/apps/plugins/sdl/src/audio/symbian/streamplayer.cpp +++ /dev/null | |||
@@ -1,279 +0,0 @@ | |||
1 | #include "streamplayer.h" | ||
2 | #include<mda/common/audio.h> | ||
3 | |||
4 | |||
5 | |||
6 | const TInt KMaxVolume(256); | ||
7 | |||
8 | LOCAL_C TInt GetSampleRate(TInt aRate) | ||
9 | { | ||
10 | switch(aRate) | ||
11 | { | ||
12 | case 8000: return TMdaAudioDataSettings::ESampleRate8000Hz; | ||
13 | case 11025: return TMdaAudioDataSettings::ESampleRate11025Hz; | ||
14 | case 12000: return TMdaAudioDataSettings::ESampleRate12000Hz; | ||
15 | case 16000: return TMdaAudioDataSettings::ESampleRate16000Hz; | ||
16 | case 22050: return TMdaAudioDataSettings::ESampleRate22050Hz; | ||
17 | case 24000: return TMdaAudioDataSettings::ESampleRate24000Hz; | ||
18 | case 32000: return TMdaAudioDataSettings::ESampleRate32000Hz; | ||
19 | case 44100: return TMdaAudioDataSettings::ESampleRate44100Hz; | ||
20 | case 48000: return TMdaAudioDataSettings::ESampleRate48000Hz; | ||
21 | case 96000: return TMdaAudioDataSettings::ESampleRate96000Hz; | ||
22 | case 64000: return TMdaAudioDataSettings::ESampleRate64000Hz; | ||
23 | } | ||
24 | return KErrNotFound; | ||
25 | } | ||
26 | |||
27 | LOCAL_C TInt GetChannels(TInt aChannels) | ||
28 | { | ||
29 | switch(aChannels) | ||
30 | { | ||
31 | case 1: return TMdaAudioDataSettings::EChannelsMono; | ||
32 | case 2: return TMdaAudioDataSettings::EChannelsStereo; | ||
33 | } | ||
34 | return KErrNotFound; | ||
35 | } | ||
36 | |||
37 | TInt CStreamPlayer::ClosestSupportedRate(TInt aRate) | ||
38 | { | ||
39 | if(aRate > 96000) | ||
40 | return 96000; | ||
41 | TInt rate = aRate; | ||
42 | while(GetSampleRate(rate) == KErrNotFound) | ||
43 | { | ||
44 | ++rate; | ||
45 | } | ||
46 | return rate; | ||
47 | } | ||
48 | |||
49 | CStreamPlayer::CStreamPlayer(MStreamProvider& aProvider, MStreamObs& aObs) : | ||
50 | iProvider(aProvider), iObs(aObs), iVolume(KMaxVolume) | ||
51 | { | ||
52 | } | ||
53 | |||
54 | CStreamPlayer::~CStreamPlayer() | ||
55 | { | ||
56 | iState |= EDied; | ||
57 | if(iState & EInited) | ||
58 | Close(); | ||
59 | User::After(100000); //wait buffer to be flushed | ||
60 | ASSERT(iPtr.Length() == 0); | ||
61 | delete iStream; | ||
62 | } | ||
63 | |||
64 | |||
65 | void CStreamPlayer::ConstructL() | ||
66 | { | ||
67 | iStream = CMdaAudioOutputStream::NewL(*this, EMdaPriorityMax); | ||
68 | iSilence.SetMax(); | ||
69 | iSilence.FillZ(); | ||
70 | } | ||
71 | |||
72 | |||
73 | TInt CStreamPlayer::OpenStream(TInt aRate, TInt aChannels, TUint32 aType) | ||
74 | { | ||
75 | Close(); | ||
76 | |||
77 | iType = aType; | ||
78 | |||
79 | iRate = GetSampleRate(aRate); | ||
80 | if(iRate == KErrNotFound) | ||
81 | return KErrNotSupported; | ||
82 | |||
83 | iChannels = GetChannels(aChannels); | ||
84 | if(iChannels == KErrNotFound) | ||
85 | return KErrNotSupported; | ||
86 | |||
87 | Open(); | ||
88 | |||
89 | return KErrNone; | ||
90 | } | ||
91 | |||
92 | |||
93 | TInt CStreamPlayer::MaxVolume() const | ||
94 | { | ||
95 | return KMaxVolume; | ||
96 | } | ||
97 | |||
98 | void CStreamPlayer::SetVolume(TInt aNew) | ||
99 | { | ||
100 | |||
101 | const TInt maxi = MaxVolume(); | ||
102 | if(aNew > maxi) | ||
103 | return; | ||
104 | if(aNew < 0) | ||
105 | return; | ||
106 | |||
107 | iVolume = aNew; | ||
108 | |||
109 | iState |= EVolumeChange; | ||
110 | } | ||
111 | |||
112 | TInt CStreamPlayer::Volume() const | ||
113 | { | ||
114 | return iVolume; | ||
115 | } | ||
116 | |||
117 | void CStreamPlayer::Open() | ||
118 | { | ||
119 | TMdaAudioDataSettings audioSettings; | ||
120 | audioSettings.Query(); | ||
121 | audioSettings.iCaps = TMdaAudioDataSettings::ERealTime | | ||
122 | TMdaAudioDataSettings::ESampleRateFixed; | ||
123 | audioSettings.iSampleRate = iRate; | ||
124 | audioSettings.iChannels = iChannels; | ||
125 | audioSettings.iFlags = TMdaAudioDataSettings::ENoNetworkRouting; | ||
126 | audioSettings.iVolume = 0; | ||
127 | |||
128 | iState &= ~EStopped; | ||
129 | iStream->Open(&audioSettings); | ||
130 | } | ||
131 | |||
132 | void CStreamPlayer::Stop() | ||
133 | { | ||
134 | if(iState & (EStarted | EInited)) | ||
135 | { | ||
136 | Close(); | ||
137 | iState |= EStopped; | ||
138 | } | ||
139 | } | ||
140 | |||
141 | void CStreamPlayer::Start() | ||
142 | { | ||
143 | if(iPtr.Length() == 0) | ||
144 | { | ||
145 | iState |= EStarted; | ||
146 | if(iState & EInited) | ||
147 | { | ||
148 | Request(); | ||
149 | } | ||
150 | else if(iState & EStopped) | ||
151 | { | ||
152 | Open(); | ||
153 | } | ||
154 | } | ||
155 | } | ||
156 | |||
157 | void CStreamPlayer::Close() | ||
158 | { | ||
159 | iState &= ~EInited; | ||
160 | iStream->Stop(); | ||
161 | iState &= ~EStarted; | ||
162 | } | ||
163 | |||
164 | void CStreamPlayer::Request() | ||
165 | { | ||
166 | if(iState & EInited) | ||
167 | { | ||
168 | iPtr.Set(KNullDesC8); | ||
169 | |||
170 | if(iState & EVolumeChange) | ||
171 | { | ||
172 | const TReal newVol = iVolume; | ||
173 | const TReal newMax = MaxVolume(); | ||
174 | const TInt maxVol = iStream->MaxVolume(); | ||
175 | const TReal max = static_cast<TReal>(maxVol); | ||
176 | const TReal newvolume = (newVol * max) / newMax; | ||
177 | const TInt vol = static_cast<TReal>(newvolume); | ||
178 | iStream->SetVolume(vol); | ||
179 | iState &= ~EVolumeChange; | ||
180 | } | ||
181 | |||
182 | if(iState & EStarted) | ||
183 | { | ||
184 | iPtr.Set(iProvider.Data()); | ||
185 | } | ||
186 | if(iPtr.Length() == 0) | ||
187 | { | ||
188 | iPtr.Set(iSilence); | ||
189 | } | ||
190 | TRAPD(err, iStream->WriteL(iPtr)); | ||
191 | if(err != KErrNone) | ||
192 | { | ||
193 | iObs.Complete(MStreamObs::EWrite, err); | ||
194 | } | ||
195 | /* else | ||
196 | { | ||
197 | iProvider.Written(iPtr.Length()); | ||
198 | }*/ | ||
199 | } | ||
200 | } | ||
201 | |||
202 | |||
203 | void CStreamPlayer::SetCapsL() | ||
204 | { | ||
205 | iStream->SetDataTypeL(iType); | ||
206 | iStream->SetAudioPropertiesL(iRate, iChannels); | ||
207 | } | ||
208 | |||
209 | void CStreamPlayer::MaoscOpenComplete(TInt aError) | ||
210 | { | ||
211 | if(aError == KErrNone) | ||
212 | { | ||
213 | TRAPD(err, SetCapsL()); | ||
214 | if(err == KErrNone) | ||
215 | { | ||
216 | iStream->SetPriority(EPriorityNormal, EMdaPriorityPreferenceTime); | ||
217 | iState |= EInited; | ||
218 | |||
219 | |||
220 | SetVolume(Volume()); | ||
221 | |||
222 | if(iState & EStarted) | ||
223 | { | ||
224 | Request(); | ||
225 | } | ||
226 | |||
227 | } | ||
228 | aError = err; | ||
229 | } | ||
230 | if(!(iState & EDied)) | ||
231 | iObs.Complete(MStreamObs::EInit, aError); | ||
232 | } | ||
233 | |||
234 | void CStreamPlayer::MaoscBufferCopied(TInt aError, const TDesC8& /*aBuffer*/) | ||
235 | { | ||
236 | iPtr.Set(KNullDesC8); | ||
237 | if(aError == KErrNone) | ||
238 | { | ||
239 | if(iState & EInited) | ||
240 | Request(); | ||
241 | else | ||
242 | iStream->Stop(); | ||
243 | } | ||
244 | else if(!(iState & EDied)) | ||
245 | iObs.Complete(MStreamObs::EPlay, aError); | ||
246 | } | ||
247 | |||
248 | void CStreamPlayer::MaoscPlayComplete(TInt aError) | ||
249 | { | ||
250 | iPtr.Set(KNullDesC8); | ||
251 | iState &= ~EStarted; | ||
252 | if(!(iState & EDied)) | ||
253 | iObs.Complete(MStreamObs::EClose, aError); | ||
254 | } | ||
255 | |||
256 | TBool CStreamPlayer::Playing() const | ||
257 | { | ||
258 | return (iState & EInited) && (iState & EStarted); | ||
259 | } | ||
260 | |||
261 | TBool CStreamPlayer::Closed() const | ||
262 | { | ||
263 | return !(iState & EInited) && !(iState & EDied); | ||
264 | } | ||
265 | |||
266 | /* | ||
267 | void CStreamPlayer::Request() | ||
268 | { | ||
269 | SetActive(); | ||
270 | TRequestStatus* s = &iStatus; | ||
271 | User::RequestComplete(s, KErrNone); | ||
272 | } | ||
273 | // iTimer.After(0); | ||
274 | */ | ||
275 | |||
276 | |||
277 | |||
278 | |||
279 | |||
diff --git a/apps/plugins/sdl/src/audio/symbian/streamplayer.h b/apps/plugins/sdl/src/audio/symbian/streamplayer.h deleted file mode 100644 index 8c6e74f920..0000000000 --- a/apps/plugins/sdl/src/audio/symbian/streamplayer.h +++ /dev/null | |||
@@ -1,89 +0,0 @@ | |||
1 | #ifndef STREAMPLAYER_H | ||
2 | #define STREAMPLAYER_H | ||
3 | |||
4 | #include<MdaAudioOutputStream.h> | ||
5 | |||
6 | const TInt KSilenceBuffer = 256; | ||
7 | |||
8 | class MStreamObs | ||
9 | { | ||
10 | public: | ||
11 | enum | ||
12 | { | ||
13 | EInit, | ||
14 | EPlay, | ||
15 | EWrite, | ||
16 | EClose, | ||
17 | }; | ||
18 | virtual void Complete(TInt aState, TInt aError) = 0; | ||
19 | }; | ||
20 | |||
21 | class MStreamProvider | ||
22 | { | ||
23 | public: | ||
24 | virtual TPtrC8 Data() = 0; | ||
25 | }; | ||
26 | |||
27 | NONSHARABLE_CLASS(CStreamPlayer) : public CBase, public MMdaAudioOutputStreamCallback | ||
28 | { | ||
29 | public: | ||
30 | CStreamPlayer(MStreamProvider& aProvider, MStreamObs& aObs); | ||
31 | ~CStreamPlayer(); | ||
32 | void ConstructL(); | ||
33 | |||
34 | static TInt ClosestSupportedRate(TInt aRate); | ||
35 | |||
36 | TInt OpenStream(TInt aRate, TInt aChannels, TUint32 aType = KMMFFourCCCodePCM16); | ||
37 | |||
38 | void SetVolume(TInt aNew); | ||
39 | TInt Volume() const; | ||
40 | TInt MaxVolume() const; | ||
41 | |||
42 | void Stop(); | ||
43 | void Start(); | ||
44 | void Open(); | ||
45 | void Close(); | ||
46 | |||
47 | TBool Playing() const; | ||
48 | TBool Closed() const; | ||
49 | |||
50 | private: | ||
51 | |||
52 | void MaoscOpenComplete(TInt aError) ; | ||
53 | void MaoscBufferCopied(TInt aError, const TDesC8& aBuffer); | ||
54 | void MaoscPlayComplete(TInt aError); | ||
55 | |||
56 | private: | ||
57 | void Request(); | ||
58 | void SetCapsL(); | ||
59 | |||
60 | private: | ||
61 | MStreamProvider& iProvider; | ||
62 | MStreamObs& iObs; | ||
63 | TInt iVolume; | ||
64 | |||
65 | CMdaAudioOutputStream* iStream; | ||
66 | |||
67 | TInt iRate; | ||
68 | TInt iChannels; | ||
69 | TUint32 iType; | ||
70 | |||
71 | enum | ||
72 | { | ||
73 | ENone = 0, | ||
74 | EInited = 0x1, | ||
75 | EStarted = 0x2, | ||
76 | EStopped = 0x4, | ||
77 | EVolumeChange = 0x8, | ||
78 | EDied = 0x10 | ||
79 | }; | ||
80 | |||
81 | TInt iState; | ||
82 | TBuf8<KSilenceBuffer> iSilence; | ||
83 | TPtrC8 iPtr; | ||
84 | |||
85 | }; | ||
86 | |||
87 | |||
88 | #endif | ||
89 | |||
diff --git a/apps/plugins/sdl/src/audio/ums/SDL_umsaudio.c b/apps/plugins/sdl/src/audio/ums/SDL_umsaudio.c deleted file mode 100644 index 9488911db6..0000000000 --- a/apps/plugins/sdl/src/audio/ums/SDL_umsaudio.c +++ /dev/null | |||
@@ -1,547 +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 Lesser General Public | ||
7 | License as published by the Free Software Foundation; either | ||
8 | version 2.1 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 | Lesser General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU Lesser General Public | ||
16 | License along with this library; if not, write to the Free Software | ||
17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
18 | |||
19 | Carsten Griwodz | ||
20 | griff@kom.tu-darmstadt.de | ||
21 | |||
22 | based on linux/SDL_dspaudio.c by Sam Lantinga | ||
23 | */ | ||
24 | #include "SDL_config.h" | ||
25 | |||
26 | /* Allow access to a raw mixing buffer */ | ||
27 | |||
28 | #include <errno.h> | ||
29 | #include <unistd.h> | ||
30 | #include <fcntl.h> | ||
31 | #include <sys/types.h> | ||
32 | #include <sys/time.h> | ||
33 | #include <sys/ioctl.h> | ||
34 | #include <sys/stat.h> | ||
35 | #include <sys/mman.h> | ||
36 | |||
37 | #include "SDL_audio.h" | ||
38 | #include "../SDL_audio_c.h" | ||
39 | #include "../SDL_audiodev_c.h" | ||
40 | #include "SDL_umsaudio.h" | ||
41 | |||
42 | /* The tag name used by UMS audio */ | ||
43 | #define UMS_DRIVER_NAME "ums" | ||
44 | |||
45 | #define DEBUG_AUDIO 1 | ||
46 | |||
47 | /* Audio driver functions */ | ||
48 | static int UMS_OpenAudio(_THIS, SDL_AudioSpec *spec); | ||
49 | static void UMS_PlayAudio(_THIS); | ||
50 | static Uint8 *UMS_GetAudioBuf(_THIS); | ||
51 | static void UMS_CloseAudio(_THIS); | ||
52 | |||
53 | static UMSAudioDevice_ReturnCode UADOpen(_THIS, string device, string mode, long flags); | ||
54 | static UMSAudioDevice_ReturnCode UADClose(_THIS); | ||
55 | static UMSAudioDevice_ReturnCode UADGetBitsPerSample(_THIS, long* bits); | ||
56 | static UMSAudioDevice_ReturnCode UADSetBitsPerSample(_THIS, long bits); | ||
57 | static UMSAudioDevice_ReturnCode UADSetSampleRate(_THIS, long rate, long* set_rate); | ||
58 | static UMSAudioDevice_ReturnCode UADSetByteOrder(_THIS, string byte_order); | ||
59 | static UMSAudioDevice_ReturnCode UADSetAudioFormatType(_THIS, string fmt); | ||
60 | static UMSAudioDevice_ReturnCode UADSetNumberFormat(_THIS, string fmt); | ||
61 | static UMSAudioDevice_ReturnCode UADInitialize(_THIS); | ||
62 | static UMSAudioDevice_ReturnCode UADStart(_THIS); | ||
63 | static UMSAudioDevice_ReturnCode UADStop(_THIS); | ||
64 | static UMSAudioDevice_ReturnCode UADSetTimeFormat(_THIS, UMSAudioTypes_TimeFormat fmt ); | ||
65 | static UMSAudioDevice_ReturnCode UADWriteBuffSize(_THIS, long* buff_size ); | ||
66 | static UMSAudioDevice_ReturnCode UADWriteBuffRemain(_THIS, long* buff_size ); | ||
67 | static UMSAudioDevice_ReturnCode UADWriteBuffUsed(_THIS, long* buff_size ); | ||
68 | static UMSAudioDevice_ReturnCode UADSetDMABufferSize(_THIS, long bytes, long* bytes_ret ); | ||
69 | static UMSAudioDevice_ReturnCode UADSetVolume(_THIS, long volume ); | ||
70 | static UMSAudioDevice_ReturnCode UADSetBalance(_THIS, long balance ); | ||
71 | static UMSAudioDevice_ReturnCode UADSetChannels(_THIS, long channels ); | ||
72 | static UMSAudioDevice_ReturnCode UADPlayRemainingData(_THIS, boolean block ); | ||
73 | static UMSAudioDevice_ReturnCode UADEnableOutput(_THIS, string output, long* left_gain, long* right_gain); | ||
74 | static UMSAudioDevice_ReturnCode UADWrite(_THIS, UMSAudioTypes_Buffer* buff, long samples, long* samples_written); | ||
75 | |||
76 | /* Audio driver bootstrap functions */ | ||
77 | static int Audio_Available(void) | ||
78 | { | ||
79 | return 1; | ||
80 | } | ||
81 | |||
82 | static void Audio_DeleteDevice(_THIS) | ||
83 | { | ||
84 | if(this->hidden->playbuf._buffer) SDL_free(this->hidden->playbuf._buffer); | ||
85 | if(this->hidden->fillbuf._buffer) SDL_free(this->hidden->fillbuf._buffer); | ||
86 | _somFree( this->hidden->umsdev ); | ||
87 | SDL_free(this->hidden); | ||
88 | SDL_free(this); | ||
89 | } | ||
90 | |||
91 | static SDL_AudioDevice *Audio_CreateDevice(int devindex) | ||
92 | { | ||
93 | SDL_AudioDevice *this; | ||
94 | |||
95 | /* | ||
96 | * Allocate and initialize management storage and private management | ||
97 | * storage for this SDL-using library. | ||
98 | */ | ||
99 | this = (SDL_AudioDevice *)SDL_malloc(sizeof(SDL_AudioDevice)); | ||
100 | if ( this ) { | ||
101 | SDL_memset(this, 0, (sizeof *this)); | ||
102 | this->hidden = (struct SDL_PrivateAudioData *)SDL_malloc((sizeof *this->hidden)); | ||
103 | } | ||
104 | if ( (this == NULL) || (this->hidden == NULL) ) { | ||
105 | SDL_OutOfMemory(); | ||
106 | if ( this ) { | ||
107 | SDL_free(this); | ||
108 | } | ||
109 | return(0); | ||
110 | } | ||
111 | SDL_memset(this->hidden, 0, (sizeof *this->hidden)); | ||
112 | #ifdef DEBUG_AUDIO | ||
113 | fprintf(stderr, "Creating UMS Audio device\n"); | ||
114 | #endif | ||
115 | |||
116 | /* | ||
117 | * Calls for UMS env initialization and audio object construction. | ||
118 | */ | ||
119 | this->hidden->ev = somGetGlobalEnvironment(); | ||
120 | this->hidden->umsdev = UMSAudioDeviceNew(); | ||
121 | |||
122 | /* | ||
123 | * Set the function pointers. | ||
124 | */ | ||
125 | this->OpenAudio = UMS_OpenAudio; | ||
126 | this->WaitAudio = NULL; /* we do blocking output */ | ||
127 | this->PlayAudio = UMS_PlayAudio; | ||
128 | this->GetAudioBuf = UMS_GetAudioBuf; | ||
129 | this->CloseAudio = UMS_CloseAudio; | ||
130 | this->free = Audio_DeleteDevice; | ||
131 | |||
132 | #ifdef DEBUG_AUDIO | ||
133 | fprintf(stderr, "done\n"); | ||
134 | #endif | ||
135 | return this; | ||
136 | } | ||
137 | |||
138 | AudioBootStrap UMS_bootstrap = { | ||
139 | UMS_DRIVER_NAME, "AIX UMS audio", | ||
140 | Audio_Available, Audio_CreateDevice | ||
141 | }; | ||
142 | |||
143 | static Uint8 *UMS_GetAudioBuf(_THIS) | ||
144 | { | ||
145 | #ifdef DEBUG_AUDIO | ||
146 | fprintf(stderr, "enter UMS_GetAudioBuf\n"); | ||
147 | #endif | ||
148 | return this->hidden->fillbuf._buffer; | ||
149 | /* | ||
150 | long bufSize; | ||
151 | UMSAudioDevice_ReturnCode rc; | ||
152 | |||
153 | rc = UADSetTimeFormat(this, UMSAudioTypes_Bytes ); | ||
154 | rc = UADWriteBuffSize(this, bufSize ); | ||
155 | */ | ||
156 | } | ||
157 | |||
158 | static void UMS_CloseAudio(_THIS) | ||
159 | { | ||
160 | UMSAudioDevice_ReturnCode rc; | ||
161 | |||
162 | #ifdef DEBUG_AUDIO | ||
163 | fprintf(stderr, "enter UMS_CloseAudio\n"); | ||
164 | #endif | ||
165 | rc = UADPlayRemainingData(this, TRUE); | ||
166 | rc = UADStop(this); | ||
167 | rc = UADClose(this); | ||
168 | } | ||
169 | |||
170 | static void UMS_PlayAudio(_THIS) | ||
171 | { | ||
172 | UMSAudioDevice_ReturnCode rc; | ||
173 | long samplesToWrite; | ||
174 | long samplesWritten; | ||
175 | UMSAudioTypes_Buffer swpbuf; | ||
176 | |||
177 | #ifdef DEBUG_AUDIO | ||
178 | fprintf(stderr, "enter UMS_PlayAudio\n"); | ||
179 | #endif | ||
180 | samplesToWrite = this->hidden->playbuf._length/this->hidden->bytesPerSample; | ||
181 | do | ||
182 | { | ||
183 | rc = UADWrite(this, &this->hidden->playbuf, | ||
184 | samplesToWrite, | ||
185 | &samplesWritten ); | ||
186 | samplesToWrite -= samplesWritten; | ||
187 | |||
188 | /* rc values: UMSAudioDevice_Success | ||
189 | * UMSAudioDevice_Failure | ||
190 | * UMSAudioDevice_Preempted | ||
191 | * UMSAudioDevice_Interrupted | ||
192 | * UMSAudioDevice_DeviceError | ||
193 | */ | ||
194 | if ( rc == UMSAudioDevice_DeviceError ) { | ||
195 | #ifdef DEBUG_AUDIO | ||
196 | fprintf(stderr, "Returning from PlayAudio with devices error\n"); | ||
197 | #endif | ||
198 | return; | ||
199 | } | ||
200 | } | ||
201 | while(samplesToWrite>0); | ||
202 | |||
203 | SDL_LockAudio(); | ||
204 | SDL_memcpy( &swpbuf, &this->hidden->playbuf, sizeof(UMSAudioTypes_Buffer) ); | ||
205 | SDL_memcpy( &this->hidden->playbuf, &this->hidden->fillbuf, sizeof(UMSAudioTypes_Buffer) ); | ||
206 | SDL_memcpy( &this->hidden->fillbuf, &swpbuf, sizeof(UMSAudioTypes_Buffer) ); | ||
207 | SDL_UnlockAudio(); | ||
208 | |||
209 | #ifdef DEBUG_AUDIO | ||
210 | fprintf(stderr, "Wrote audio data and swapped buffer\n"); | ||
211 | #endif | ||
212 | } | ||
213 | |||
214 | #if 0 | ||
215 | // /* Set the DSP frequency */ | ||
216 | // value = spec->freq; | ||
217 | // if ( ioctl(this->hidden->audio_fd, SOUND_PCM_WRITE_RATE, &value) < 0 ) { | ||
218 | // SDL_SetError("Couldn't set audio frequency"); | ||
219 | // return(-1); | ||
220 | // } | ||
221 | // spec->freq = value; | ||
222 | #endif | ||
223 | |||
224 | static int UMS_OpenAudio(_THIS, SDL_AudioSpec *spec) | ||
225 | { | ||
226 | char* audiodev = "/dev/paud0"; | ||
227 | long lgain; | ||
228 | long rgain; | ||
229 | long outRate; | ||
230 | long outBufSize; | ||
231 | long bitsPerSample; | ||
232 | long samplesPerSec; | ||
233 | long success; | ||
234 | Uint16 test_format; | ||
235 | int frag_spec; | ||
236 | UMSAudioDevice_ReturnCode rc; | ||
237 | |||
238 | #ifdef DEBUG_AUDIO | ||
239 | fprintf(stderr, "enter UMS_OpenAudio\n"); | ||
240 | #endif | ||
241 | rc = UADOpen(this, audiodev,"PLAY", UMSAudioDevice_BlockingIO); | ||
242 | if ( rc != UMSAudioDevice_Success ) { | ||
243 | SDL_SetError("Couldn't open %s: %s", audiodev, strerror(errno)); | ||
244 | return -1; | ||
245 | } | ||
246 | |||
247 | rc = UADSetAudioFormatType(this, "PCM"); | ||
248 | |||
249 | success = 0; | ||
250 | test_format = SDL_FirstAudioFormat(spec->format); | ||
251 | do | ||
252 | { | ||
253 | #ifdef DEBUG_AUDIO | ||
254 | fprintf(stderr, "Trying format 0x%4.4x\n", test_format); | ||
255 | #endif | ||
256 | switch ( test_format ) | ||
257 | { | ||
258 | case AUDIO_U8: | ||
259 | /* from the mac code: better ? */ | ||
260 | /* sample_bits = spec->size / spec->samples / spec->channels * 8; */ | ||
261 | success = 1; | ||
262 | bitsPerSample = 8; | ||
263 | rc = UADSetSampleRate(this, spec->freq << 16, &outRate ); | ||
264 | rc = UADSetByteOrder(this, "MSB"); /* irrelevant */ | ||
265 | rc = UADSetNumberFormat(this, "UNSIGNED"); | ||
266 | break; | ||
267 | case AUDIO_S8: | ||
268 | success = 1; | ||
269 | bitsPerSample = 8; | ||
270 | rc = UADSetSampleRate(this, spec->freq << 16, &outRate ); | ||
271 | rc = UADSetByteOrder(this, "MSB"); /* irrelevant */ | ||
272 | rc = UADSetNumberFormat(this, "SIGNED"); | ||
273 | break; | ||
274 | case AUDIO_S16LSB: | ||
275 | success = 1; | ||
276 | bitsPerSample = 16; | ||
277 | rc = UADSetSampleRate(this, spec->freq << 16, &outRate ); | ||
278 | rc = UADSetByteOrder(this, "LSB"); | ||
279 | rc = UADSetNumberFormat(this, "SIGNED"); | ||
280 | break; | ||
281 | case AUDIO_S16MSB: | ||
282 | success = 1; | ||
283 | bitsPerSample = 16; | ||
284 | rc = UADSetSampleRate(this, spec->freq << 16, &outRate ); | ||
285 | rc = UADSetByteOrder(this, "MSB"); | ||
286 | rc = UADSetNumberFormat(this, "SIGNED"); | ||
287 | break; | ||
288 | case AUDIO_U16LSB: | ||
289 | success = 1; | ||
290 | bitsPerSample = 16; | ||
291 | rc = UADSetSampleRate(this, spec->freq << 16, &outRate ); | ||
292 | rc = UADSetByteOrder(this, "LSB"); | ||
293 | rc = UADSetNumberFormat(this, "UNSIGNED"); | ||
294 | break; | ||
295 | case AUDIO_U16MSB: | ||
296 | success = 1; | ||
297 | bitsPerSample = 16; | ||
298 | rc = UADSetSampleRate(this, spec->freq << 16, &outRate ); | ||
299 | rc = UADSetByteOrder(this, "MSB"); | ||
300 | rc = UADSetNumberFormat(this, "UNSIGNED"); | ||
301 | break; | ||
302 | default: | ||
303 | break; | ||
304 | } | ||
305 | if ( ! success ) { | ||
306 | test_format = SDL_NextAudioFormat(); | ||
307 | } | ||
308 | } | ||
309 | while ( ! success && test_format ); | ||
310 | |||
311 | if ( success == 0 ) { | ||
312 | SDL_SetError("Couldn't find any hardware audio formats"); | ||
313 | return -1; | ||
314 | } | ||
315 | |||
316 | spec->format = test_format; | ||
317 | |||
318 | for ( frag_spec = 0; (0x01<<frag_spec) < spec->size; ++frag_spec ); | ||
319 | if ( (0x01<<frag_spec) != spec->size ) { | ||
320 | SDL_SetError("Fragment size must be a power of two"); | ||
321 | return -1; | ||
322 | } | ||
323 | if ( frag_spec > 2048 ) frag_spec = 2048; | ||
324 | |||
325 | this->hidden->bytesPerSample = (bitsPerSample / 8) * spec->channels; | ||
326 | samplesPerSec = this->hidden->bytesPerSample * outRate; | ||
327 | |||
328 | this->hidden->playbuf._length = 0; | ||
329 | this->hidden->playbuf._maximum = spec->size; | ||
330 | this->hidden->playbuf._buffer = (unsigned char*)SDL_malloc(spec->size); | ||
331 | this->hidden->fillbuf._length = 0; | ||
332 | this->hidden->fillbuf._maximum = spec->size; | ||
333 | this->hidden->fillbuf._buffer = (unsigned char*)SDL_malloc(spec->size); | ||
334 | |||
335 | rc = UADSetBitsPerSample(this, bitsPerSample ); | ||
336 | rc = UADSetDMABufferSize(this, frag_spec, &outBufSize ); | ||
337 | rc = UADSetChannels(this, spec->channels); /* functions reduces to mono or stereo */ | ||
338 | |||
339 | lgain = 100; /*maximum left input gain*/ | ||
340 | rgain = 100; /*maimum right input gain*/ | ||
341 | rc = UADEnableOutput(this, "LINE_OUT",&lgain,&rgain); | ||
342 | rc = UADInitialize(this); | ||
343 | rc = UADStart(this); | ||
344 | rc = UADSetVolume(this, 100); | ||
345 | rc = UADSetBalance(this, 0); | ||
346 | |||
347 | /* We're ready to rock and roll. :-) */ | ||
348 | return 0; | ||
349 | } | ||
350 | |||
351 | |||
352 | static UMSAudioDevice_ReturnCode UADGetBitsPerSample(_THIS, long* bits) | ||
353 | { | ||
354 | return UMSAudioDevice_get_bits_per_sample( this->hidden->umsdev, | ||
355 | this->hidden->ev, | ||
356 | bits ); | ||
357 | } | ||
358 | |||
359 | static UMSAudioDevice_ReturnCode UADSetBitsPerSample(_THIS, long bits) | ||
360 | { | ||
361 | return UMSAudioDevice_set_bits_per_sample( this->hidden->umsdev, | ||
362 | this->hidden->ev, | ||
363 | bits ); | ||
364 | } | ||
365 | |||
366 | static UMSAudioDevice_ReturnCode UADSetSampleRate(_THIS, long rate, long* set_rate) | ||
367 | { | ||
368 | /* from the mac code: sample rate = spec->freq << 16; */ | ||
369 | return UMSAudioDevice_set_sample_rate( this->hidden->umsdev, | ||
370 | this->hidden->ev, | ||
371 | rate, | ||
372 | set_rate ); | ||
373 | } | ||
374 | |||
375 | static UMSAudioDevice_ReturnCode UADSetByteOrder(_THIS, string byte_order) | ||
376 | { | ||
377 | return UMSAudioDevice_set_byte_order( this->hidden->umsdev, | ||
378 | this->hidden->ev, | ||
379 | byte_order ); | ||
380 | } | ||
381 | |||
382 | static UMSAudioDevice_ReturnCode UADSetAudioFormatType(_THIS, string fmt) | ||
383 | { | ||
384 | /* possible PCM, A_LAW or MU_LAW */ | ||
385 | return UMSAudioDevice_set_audio_format_type( this->hidden->umsdev, | ||
386 | this->hidden->ev, | ||
387 | fmt ); | ||
388 | } | ||
389 | |||
390 | static UMSAudioDevice_ReturnCode UADSetNumberFormat(_THIS, string fmt) | ||
391 | { | ||
392 | /* possible SIGNED, UNSIGNED, or TWOS_COMPLEMENT */ | ||
393 | return UMSAudioDevice_set_number_format( this->hidden->umsdev, | ||
394 | this->hidden->ev, | ||
395 | fmt ); | ||
396 | } | ||
397 | |||
398 | static UMSAudioDevice_ReturnCode UADInitialize(_THIS) | ||
399 | { | ||
400 | return UMSAudioDevice_initialize( this->hidden->umsdev, | ||
401 | this->hidden->ev ); | ||
402 | } | ||
403 | |||
404 | static UMSAudioDevice_ReturnCode UADStart(_THIS) | ||
405 | { | ||
406 | return UMSAudioDevice_start( this->hidden->umsdev, | ||
407 | this->hidden->ev ); | ||
408 | } | ||
409 | |||
410 | static UMSAudioDevice_ReturnCode UADSetTimeFormat(_THIS, UMSAudioTypes_TimeFormat fmt ) | ||
411 | { | ||
412 | /* | ||
413 | * Switches the time format to the new format, immediately. | ||
414 | * possible UMSAudioTypes_Msecs, UMSAudioTypes_Bytes or UMSAudioTypes_Samples | ||
415 | */ | ||
416 | return UMSAudioDevice_set_time_format( this->hidden->umsdev, | ||
417 | this->hidden->ev, | ||
418 | fmt ); | ||
419 | } | ||
420 | |||
421 | static UMSAudioDevice_ReturnCode UADWriteBuffSize(_THIS, long* buff_size ) | ||
422 | { | ||
423 | /* | ||
424 | * returns write buffer size in the current time format | ||
425 | */ | ||
426 | return UMSAudioDevice_write_buff_size( this->hidden->umsdev, | ||
427 | this->hidden->ev, | ||
428 | buff_size ); | ||
429 | } | ||
430 | |||
431 | static UMSAudioDevice_ReturnCode UADWriteBuffRemain(_THIS, long* buff_size ) | ||
432 | { | ||
433 | /* | ||
434 | * returns amount of available space in the write buffer | ||
435 | * in the current time format | ||
436 | */ | ||
437 | return UMSAudioDevice_write_buff_remain( this->hidden->umsdev, | ||
438 | this->hidden->ev, | ||
439 | buff_size ); | ||
440 | } | ||
441 | |||
442 | static UMSAudioDevice_ReturnCode UADWriteBuffUsed(_THIS, long* buff_size ) | ||
443 | { | ||
444 | /* | ||
445 | * returns amount of filled space in the write buffer | ||
446 | * in the current time format | ||
447 | */ | ||
448 | return UMSAudioDevice_write_buff_used( this->hidden->umsdev, | ||
449 | this->hidden->ev, | ||
450 | buff_size ); | ||
451 | } | ||
452 | |||
453 | static UMSAudioDevice_ReturnCode UADSetDMABufferSize(_THIS, long bytes, long* bytes_ret ) | ||
454 | { | ||
455 | /* | ||
456 | * Request a new DMA buffer size, maximum requested size 2048. | ||
457 | * Takes effect with next initialize() call. | ||
458 | * Devices may or may not support DMA. | ||
459 | */ | ||
460 | return UMSAudioDevice_set_DMA_buffer_size( this->hidden->umsdev, | ||
461 | this->hidden->ev, | ||
462 | bytes, | ||
463 | bytes_ret ); | ||
464 | } | ||
465 | |||
466 | static UMSAudioDevice_ReturnCode UADSetVolume(_THIS, long volume ) | ||
467 | { | ||
468 | /* | ||
469 | * Set the volume. | ||
470 | * Takes effect immediately. | ||
471 | */ | ||
472 | return UMSAudioDevice_set_volume( this->hidden->umsdev, | ||
473 | this->hidden->ev, | ||
474 | volume ); | ||
475 | } | ||
476 | |||
477 | static UMSAudioDevice_ReturnCode UADSetBalance(_THIS, long balance ) | ||
478 | { | ||
479 | /* | ||
480 | * Set the balance. | ||
481 | * Takes effect immediately. | ||
482 | */ | ||
483 | return UMSAudioDevice_set_balance( this->hidden->umsdev, | ||
484 | this->hidden->ev, | ||
485 | balance ); | ||
486 | } | ||
487 | |||
488 | static UMSAudioDevice_ReturnCode UADSetChannels(_THIS, long channels ) | ||
489 | { | ||
490 | /* | ||
491 | * Set mono or stereo. | ||
492 | * Takes effect with next initialize() call. | ||
493 | */ | ||
494 | if ( channels != 1 ) channels = 2; | ||
495 | return UMSAudioDevice_set_number_of_channels( this->hidden->umsdev, | ||
496 | this->hidden->ev, | ||
497 | channels ); | ||
498 | } | ||
499 | |||
500 | static UMSAudioDevice_ReturnCode UADOpen(_THIS, string device, string mode, long flags) | ||
501 | { | ||
502 | return UMSAudioDevice_open( this->hidden->umsdev, | ||
503 | this->hidden->ev, | ||
504 | device, | ||
505 | mode, | ||
506 | flags ); | ||
507 | } | ||
508 | |||
509 | static UMSAudioDevice_ReturnCode UADWrite(_THIS, UMSAudioTypes_Buffer* buff, | ||
510 | long samples, | ||
511 | long* samples_written) | ||
512 | { | ||
513 | return UMSAudioDevice_write( this->hidden->umsdev, | ||
514 | this->hidden->ev, | ||
515 | buff, | ||
516 | samples, | ||
517 | samples_written ); | ||
518 | } | ||
519 | |||
520 | static UMSAudioDevice_ReturnCode UADPlayRemainingData(_THIS, boolean block ) | ||
521 | { | ||
522 | return UMSAudioDevice_play_remaining_data( this->hidden->umsdev, | ||
523 | this->hidden->ev, | ||
524 | block); | ||
525 | } | ||
526 | |||
527 | static UMSAudioDevice_ReturnCode UADStop(_THIS) | ||
528 | { | ||
529 | return UMSAudioDevice_stop( this->hidden->umsdev, | ||
530 | this->hidden->ev ); | ||
531 | } | ||
532 | |||
533 | static UMSAudioDevice_ReturnCode UADClose(_THIS) | ||
534 | { | ||
535 | return UMSAudioDevice_close( this->hidden->umsdev, | ||
536 | this->hidden->ev ); | ||
537 | } | ||
538 | |||
539 | static UMSAudioDevice_ReturnCode UADEnableOutput(_THIS, string output, long* left_gain, long* right_gain) | ||
540 | { | ||
541 | return UMSAudioDevice_enable_output( this->hidden->umsdev, | ||
542 | this->hidden->ev, | ||
543 | output, | ||
544 | left_gain, | ||
545 | right_gain ); | ||
546 | } | ||
547 | |||
diff --git a/apps/plugins/sdl/src/audio/ums/SDL_umsaudio.h b/apps/plugins/sdl/src/audio/ums/SDL_umsaudio.h deleted file mode 100644 index 367fe853b6..0000000000 --- a/apps/plugins/sdl/src/audio/ums/SDL_umsaudio.h +++ /dev/null | |||
@@ -1,50 +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 Lesser General Public | ||
7 | License as published by the Free Software Foundation; either | ||
8 | version 2.1 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 | Lesser General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU Lesser General Public | ||
16 | License along with this library; if not, write to the Free Software | ||
17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
18 | |||
19 | Carsten Griwodz | ||
20 | griff@kom.tu-darmstadt.de | ||
21 | |||
22 | based on linux/SDL_dspaudio.h by Sam Lantinga | ||
23 | */ | ||
24 | #include "SDL_config.h" | ||
25 | |||
26 | #ifndef _SDL_UMSaudio_h | ||
27 | #define _SDL_UMSaudio_h | ||
28 | |||
29 | #include <UMS/UMSAudioDevice.h> | ||
30 | |||
31 | #include "../SDL_sysaudio.h" | ||
32 | |||
33 | /* Hidden "this" pointer for the video functions */ | ||
34 | #define _THIS SDL_AudioDevice *this | ||
35 | |||
36 | struct SDL_PrivateAudioData | ||
37 | { | ||
38 | /* Pointer to the (open) UMS audio device */ | ||
39 | Environment* ev; | ||
40 | UMSAudioDevice umsdev; | ||
41 | |||
42 | /* Raw mixing buffer */ | ||
43 | UMSAudioTypes_Buffer playbuf; | ||
44 | UMSAudioTypes_Buffer fillbuf; | ||
45 | |||
46 | long bytesPerSample; | ||
47 | }; | ||
48 | |||
49 | #endif /* _SDL_UMSaudio_h */ | ||
50 | |||
diff --git a/apps/plugins/sdl/src/audio/windib/SDL_dibaudio.c b/apps/plugins/sdl/src/audio/windib/SDL_dibaudio.c deleted file mode 100644 index 51a9a4d60a..0000000000 --- a/apps/plugins/sdl/src/audio/windib/SDL_dibaudio.c +++ /dev/null | |||
@@ -1,322 +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 Lesser General Public | ||
7 | License as published by the Free Software Foundation; either | ||
8 | version 2.1 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 | Lesser General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU Lesser General Public | ||
16 | License along with this library; if not, write to the Free Software | ||
17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 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 | #define WIN32_LEAN_AND_MEAN | ||
27 | #include <windows.h> | ||
28 | #include <mmsystem.h> | ||
29 | |||
30 | #include "SDL_timer.h" | ||
31 | #include "SDL_audio.h" | ||
32 | #include "../SDL_audio_c.h" | ||
33 | #include "SDL_dibaudio.h" | ||
34 | #if defined(_WIN32_WCE) && (_WIN32_WCE < 300) | ||
35 | #include "win_ce_semaphore.h" | ||
36 | #endif | ||
37 | |||
38 | |||
39 | /* Audio driver functions */ | ||
40 | static int DIB_OpenAudio(_THIS, SDL_AudioSpec *spec); | ||
41 | static void DIB_ThreadInit(_THIS); | ||
42 | static void DIB_WaitAudio(_THIS); | ||
43 | static Uint8 *DIB_GetAudioBuf(_THIS); | ||
44 | static void DIB_PlayAudio(_THIS); | ||
45 | static void DIB_WaitDone(_THIS); | ||
46 | static void DIB_CloseAudio(_THIS); | ||
47 | |||
48 | /* Audio driver bootstrap functions */ | ||
49 | |||
50 | static int Audio_Available(void) | ||
51 | { | ||
52 | return(1); | ||
53 | } | ||
54 | |||
55 | static void Audio_DeleteDevice(SDL_AudioDevice *device) | ||
56 | { | ||
57 | SDL_free(device->hidden); | ||
58 | SDL_free(device); | ||
59 | } | ||
60 | |||
61 | static SDL_AudioDevice *Audio_CreateDevice(int devindex) | ||
62 | { | ||
63 | SDL_AudioDevice *this; | ||
64 | |||
65 | /* Initialize all variables that we clean on shutdown */ | ||
66 | this = (SDL_AudioDevice *)SDL_malloc(sizeof(SDL_AudioDevice)); | ||
67 | if ( this ) { | ||
68 | SDL_memset(this, 0, (sizeof *this)); | ||
69 | this->hidden = (struct SDL_PrivateAudioData *) | ||
70 | SDL_malloc((sizeof *this->hidden)); | ||
71 | } | ||
72 | if ( (this == NULL) || (this->hidden == NULL) ) { | ||
73 | SDL_OutOfMemory(); | ||
74 | if ( this ) { | ||
75 | SDL_free(this); | ||
76 | } | ||
77 | return(0); | ||
78 | } | ||
79 | SDL_memset(this->hidden, 0, (sizeof *this->hidden)); | ||
80 | |||
81 | /* Set the function pointers */ | ||
82 | this->OpenAudio = DIB_OpenAudio; | ||
83 | this->ThreadInit = DIB_ThreadInit; | ||
84 | this->WaitAudio = DIB_WaitAudio; | ||
85 | this->PlayAudio = DIB_PlayAudio; | ||
86 | this->GetAudioBuf = DIB_GetAudioBuf; | ||
87 | this->WaitDone = DIB_WaitDone; | ||
88 | this->CloseAudio = DIB_CloseAudio; | ||
89 | |||
90 | this->free = Audio_DeleteDevice; | ||
91 | |||
92 | return this; | ||
93 | } | ||
94 | |||
95 | AudioBootStrap WAVEOUT_bootstrap = { | ||
96 | "waveout", "Win95/98/NT/2000 WaveOut", | ||
97 | Audio_Available, Audio_CreateDevice | ||
98 | }; | ||
99 | |||
100 | |||
101 | /* The Win32 callback for filling the WAVE device */ | ||
102 | static void CALLBACK FillSound(HWAVEOUT hwo, UINT uMsg, DWORD_PTR dwInstance, | ||
103 | DWORD dwParam1, DWORD dwParam2) | ||
104 | { | ||
105 | SDL_AudioDevice *this = (SDL_AudioDevice *)dwInstance; | ||
106 | |||
107 | /* Only service "buffer done playing" messages */ | ||
108 | if ( uMsg != WOM_DONE ) | ||
109 | return; | ||
110 | |||
111 | /* Signal that we are done playing a buffer */ | ||
112 | #if defined(_WIN32_WCE) && (_WIN32_WCE < 300) | ||
113 | ReleaseSemaphoreCE(audio_sem, 1, NULL); | ||
114 | #else | ||
115 | ReleaseSemaphore(audio_sem, 1, NULL); | ||
116 | #endif | ||
117 | } | ||
118 | |||
119 | static void SetMMerror(char *function, MMRESULT code) | ||
120 | { | ||
121 | size_t len; | ||
122 | char errbuf[MAXERRORLENGTH]; | ||
123 | #ifdef _WIN32_WCE | ||
124 | wchar_t werrbuf[MAXERRORLENGTH]; | ||
125 | #endif | ||
126 | |||
127 | SDL_snprintf(errbuf, SDL_arraysize(errbuf), "%s: ", function); | ||
128 | len = SDL_strlen(errbuf); | ||
129 | |||
130 | #ifdef _WIN32_WCE | ||
131 | /* UNICODE version */ | ||
132 | waveOutGetErrorText(code, werrbuf, MAXERRORLENGTH-len); | ||
133 | WideCharToMultiByte(CP_ACP,0,werrbuf,-1,errbuf+len,MAXERRORLENGTH-len,NULL,NULL); | ||
134 | #else | ||
135 | waveOutGetErrorText(code, errbuf+len, (UINT)(MAXERRORLENGTH-len)); | ||
136 | #endif | ||
137 | |||
138 | SDL_SetError("%s",errbuf); | ||
139 | } | ||
140 | |||
141 | /* Set high priority for the audio thread */ | ||
142 | static void DIB_ThreadInit(_THIS) | ||
143 | { | ||
144 | SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_HIGHEST); | ||
145 | } | ||
146 | |||
147 | void DIB_WaitAudio(_THIS) | ||
148 | { | ||
149 | /* Wait for an audio chunk to finish */ | ||
150 | #if defined(_WIN32_WCE) && (_WIN32_WCE < 300) | ||
151 | WaitForSemaphoreCE(audio_sem, INFINITE); | ||
152 | #else | ||
153 | WaitForSingleObject(audio_sem, INFINITE); | ||
154 | #endif | ||
155 | } | ||
156 | |||
157 | Uint8 *DIB_GetAudioBuf(_THIS) | ||
158 | { | ||
159 | Uint8 *retval; | ||
160 | |||
161 | retval = (Uint8 *)(wavebuf[next_buffer].lpData); | ||
162 | return retval; | ||
163 | } | ||
164 | |||
165 | void DIB_PlayAudio(_THIS) | ||
166 | { | ||
167 | /* Queue it up */ | ||
168 | waveOutWrite(sound, &wavebuf[next_buffer], sizeof(wavebuf[0])); | ||
169 | next_buffer = (next_buffer+1)%NUM_BUFFERS; | ||
170 | } | ||
171 | |||
172 | void DIB_WaitDone(_THIS) | ||
173 | { | ||
174 | int i, left; | ||
175 | |||
176 | do { | ||
177 | left = NUM_BUFFERS; | ||
178 | for ( i=0; i<NUM_BUFFERS; ++i ) { | ||
179 | if ( wavebuf[i].dwFlags & WHDR_DONE ) { | ||
180 | --left; | ||
181 | } | ||
182 | } | ||
183 | if ( left > 0 ) { | ||
184 | SDL_Delay(100); | ||
185 | } | ||
186 | } while ( left > 0 ); | ||
187 | } | ||
188 | |||
189 | void DIB_CloseAudio(_THIS) | ||
190 | { | ||
191 | int i; | ||
192 | |||
193 | /* Close up audio */ | ||
194 | if ( audio_sem ) { | ||
195 | #if defined(_WIN32_WCE) && (_WIN32_WCE < 300) | ||
196 | CloseSynchHandle(audio_sem); | ||
197 | #else | ||
198 | CloseHandle(audio_sem); | ||
199 | #endif | ||
200 | } | ||
201 | if ( sound ) { | ||
202 | waveOutClose(sound); | ||
203 | } | ||
204 | |||
205 | /* Clean up mixing buffers */ | ||
206 | for ( i=0; i<NUM_BUFFERS; ++i ) { | ||
207 | if ( wavebuf[i].dwUser != 0xFFFF ) { | ||
208 | waveOutUnprepareHeader(sound, &wavebuf[i], | ||
209 | sizeof(wavebuf[i])); | ||
210 | wavebuf[i].dwUser = 0xFFFF; | ||
211 | } | ||
212 | } | ||
213 | /* Free raw mixing buffer */ | ||
214 | if ( mixbuf != NULL ) { | ||
215 | SDL_free(mixbuf); | ||
216 | mixbuf = NULL; | ||
217 | } | ||
218 | } | ||
219 | |||
220 | int DIB_OpenAudio(_THIS, SDL_AudioSpec *spec) | ||
221 | { | ||
222 | MMRESULT result; | ||
223 | int i; | ||
224 | WAVEFORMATEX waveformat; | ||
225 | |||
226 | /* Initialize the wavebuf structures for closing */ | ||
227 | sound = NULL; | ||
228 | audio_sem = NULL; | ||
229 | for ( i = 0; i < NUM_BUFFERS; ++i ) | ||
230 | wavebuf[i].dwUser = 0xFFFF; | ||
231 | mixbuf = NULL; | ||
232 | |||
233 | /* Set basic WAVE format parameters */ | ||
234 | SDL_memset(&waveformat, 0, sizeof(waveformat)); | ||
235 | waveformat.wFormatTag = WAVE_FORMAT_PCM; | ||
236 | |||
237 | /* Determine the audio parameters from the AudioSpec */ | ||
238 | switch ( spec->format & 0xFF ) { | ||
239 | case 8: | ||
240 | /* Unsigned 8 bit audio data */ | ||
241 | spec->format = AUDIO_U8; | ||
242 | waveformat.wBitsPerSample = 8; | ||
243 | break; | ||
244 | case 16: | ||
245 | /* Signed 16 bit audio data */ | ||
246 | spec->format = AUDIO_S16; | ||
247 | waveformat.wBitsPerSample = 16; | ||
248 | break; | ||
249 | default: | ||
250 | SDL_SetError("Unsupported audio format"); | ||
251 | return(-1); | ||
252 | } | ||
253 | waveformat.nChannels = spec->channels; | ||
254 | waveformat.nSamplesPerSec = spec->freq; | ||
255 | waveformat.nBlockAlign = | ||
256 | waveformat.nChannels * (waveformat.wBitsPerSample/8); | ||
257 | waveformat.nAvgBytesPerSec = | ||
258 | waveformat.nSamplesPerSec * waveformat.nBlockAlign; | ||
259 | |||
260 | /* Check the buffer size -- minimum of 1/4 second (word aligned) */ | ||
261 | if ( spec->samples < (spec->freq/4) ) | ||
262 | spec->samples = ((spec->freq/4)+3)&~3; | ||
263 | |||
264 | /* Update the fragment size as size in bytes */ | ||
265 | SDL_CalculateAudioSpec(spec); | ||
266 | |||
267 | /* Open the audio device */ | ||
268 | result = waveOutOpen(&sound, WAVE_MAPPER, &waveformat, | ||
269 | (DWORD_PTR)FillSound, (DWORD_PTR)this, CALLBACK_FUNCTION); | ||
270 | if ( result != MMSYSERR_NOERROR ) { | ||
271 | SetMMerror("waveOutOpen()", result); | ||
272 | return(-1); | ||
273 | } | ||
274 | |||
275 | #ifdef SOUND_DEBUG | ||
276 | /* Check the sound device we retrieved */ | ||
277 | { | ||
278 | WAVEOUTCAPS caps; | ||
279 | |||
280 | result = waveOutGetDevCaps((UINT)sound, &caps, sizeof(caps)); | ||
281 | if ( result != MMSYSERR_NOERROR ) { | ||
282 | SetMMerror("waveOutGetDevCaps()", result); | ||
283 | return(-1); | ||
284 | } | ||
285 | printf("Audio device: %s\n", caps.szPname); | ||
286 | } | ||
287 | #endif | ||
288 | |||
289 | /* Create the audio buffer semaphore */ | ||
290 | #if defined(_WIN32_WCE) && (_WIN32_WCE < 300) | ||
291 | audio_sem = CreateSemaphoreCE(NULL, NUM_BUFFERS-1, NUM_BUFFERS, NULL); | ||
292 | #else | ||
293 | audio_sem = CreateSemaphore(NULL, NUM_BUFFERS-1, NUM_BUFFERS, NULL); | ||
294 | #endif | ||
295 | if ( audio_sem == NULL ) { | ||
296 | SDL_SetError("Couldn't create semaphore"); | ||
297 | return(-1); | ||
298 | } | ||
299 | |||
300 | /* Create the sound buffers */ | ||
301 | mixbuf = (Uint8 *)SDL_malloc(NUM_BUFFERS*spec->size); | ||
302 | if ( mixbuf == NULL ) { | ||
303 | SDL_SetError("Out of memory"); | ||
304 | return(-1); | ||
305 | } | ||
306 | for ( i = 0; i < NUM_BUFFERS; ++i ) { | ||
307 | SDL_memset(&wavebuf[i], 0, sizeof(wavebuf[i])); | ||
308 | wavebuf[i].lpData = (LPSTR) &mixbuf[i*spec->size]; | ||
309 | wavebuf[i].dwBufferLength = spec->size; | ||
310 | wavebuf[i].dwFlags = WHDR_DONE; | ||
311 | result = waveOutPrepareHeader(sound, &wavebuf[i], | ||
312 | sizeof(wavebuf[i])); | ||
313 | if ( result != MMSYSERR_NOERROR ) { | ||
314 | SetMMerror("waveOutPrepareHeader()", result); | ||
315 | return(-1); | ||
316 | } | ||
317 | } | ||
318 | |||
319 | /* Ready to go! */ | ||
320 | next_buffer = 0; | ||
321 | return(0); | ||
322 | } | ||
diff --git a/apps/plugins/sdl/src/audio/windib/SDL_dibaudio.h b/apps/plugins/sdl/src/audio/windib/SDL_dibaudio.h deleted file mode 100644 index d2c62280b5..0000000000 --- a/apps/plugins/sdl/src/audio/windib/SDL_dibaudio.h +++ /dev/null | |||
@@ -1,49 +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 Lesser General Public | ||
7 | License as published by the Free Software Foundation; either | ||
8 | version 2.1 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 | Lesser General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU Lesser General Public | ||
16 | License along with this library; if not, write to the Free Software | ||
17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
18 | |||
19 | Sam Lantinga | ||
20 | slouken@libsdl.org | ||
21 | */ | ||
22 | #include "SDL_config.h" | ||
23 | |||
24 | #ifndef _SDL_lowaudio_h | ||
25 | #define _SDL_lowaudio_h | ||
26 | |||
27 | #include "../SDL_sysaudio.h" | ||
28 | |||
29 | /* Hidden "this" pointer for the video functions */ | ||
30 | #define _THIS SDL_AudioDevice *this | ||
31 | |||
32 | #define NUM_BUFFERS 2 /* -- Don't lower this! */ | ||
33 | |||
34 | struct SDL_PrivateAudioData { | ||
35 | HWAVEOUT sound; | ||
36 | HANDLE audio_sem; | ||
37 | Uint8 *mixbuf; /* The raw allocated mixing buffer */ | ||
38 | WAVEHDR wavebuf[NUM_BUFFERS]; /* Wave audio fragments */ | ||
39 | int next_buffer; | ||
40 | }; | ||
41 | |||
42 | /* Old variable names */ | ||
43 | #define sound (this->hidden->sound) | ||
44 | #define audio_sem (this->hidden->audio_sem) | ||
45 | #define mixbuf (this->hidden->mixbuf) | ||
46 | #define wavebuf (this->hidden->wavebuf) | ||
47 | #define next_buffer (this->hidden->next_buffer) | ||
48 | |||
49 | #endif /* _SDL_lowaudio_h */ | ||
diff --git a/apps/plugins/sdl/src/audio/windx5/SDL_dx5audio.c b/apps/plugins/sdl/src/audio/windx5/SDL_dx5audio.c deleted file mode 100644 index c3d42aeda1..0000000000 --- a/apps/plugins/sdl/src/audio/windx5/SDL_dx5audio.c +++ /dev/null | |||
@@ -1,705 +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 Lesser General Public | ||
7 | License as published by the Free Software Foundation; either | ||
8 | version 2.1 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 | Lesser General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU Lesser General Public | ||
16 | License along with this library; if not, write to the Free Software | ||
17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 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 "SDL_timer.h" | ||
27 | #include "SDL_audio.h" | ||
28 | #include "../SDL_audio_c.h" | ||
29 | #include "SDL_dx5audio.h" | ||
30 | |||
31 | /* Define this if you want to use DirectX 6 DirectSoundNotify interface */ | ||
32 | //#define USE_POSITION_NOTIFY | ||
33 | |||
34 | /* DirectX function pointers for audio */ | ||
35 | HRESULT (WINAPI *DSoundCreate)(LPGUID, LPDIRECTSOUND *, LPUNKNOWN); | ||
36 | |||
37 | /* Audio driver functions */ | ||
38 | static int DX5_OpenAudio(_THIS, SDL_AudioSpec *spec); | ||
39 | static void DX5_ThreadInit(_THIS); | ||
40 | static void DX5_WaitAudio_BusyWait(_THIS); | ||
41 | #ifdef USE_POSITION_NOTIFY | ||
42 | static void DX6_WaitAudio_EventWait(_THIS); | ||
43 | #endif | ||
44 | static void DX5_PlayAudio(_THIS); | ||
45 | static Uint8 *DX5_GetAudioBuf(_THIS); | ||
46 | static void DX5_WaitDone(_THIS); | ||
47 | static void DX5_CloseAudio(_THIS); | ||
48 | |||
49 | /* Audio driver bootstrap functions */ | ||
50 | |||
51 | static int Audio_Available(void) | ||
52 | { | ||
53 | HINSTANCE DSoundDLL; | ||
54 | int dsound_ok; | ||
55 | |||
56 | /* Version check DSOUND.DLL (Is DirectX okay?) */ | ||
57 | dsound_ok = 0; | ||
58 | DSoundDLL = LoadLibrary(TEXT("DSOUND.DLL")); | ||
59 | if ( DSoundDLL != NULL ) { | ||
60 | /* We just use basic DirectSound, we're okay */ | ||
61 | /* Yay! */ | ||
62 | /* Unfortunately, the sound drivers on NT have | ||
63 | higher latencies than the audio buffers used | ||
64 | by many SDL applications, so there are gaps | ||
65 | in the audio - it sounds terrible. Punt for now. | ||
66 | */ | ||
67 | OSVERSIONINFO ver; | ||
68 | ver.dwOSVersionInfoSize = sizeof (OSVERSIONINFO); | ||
69 | GetVersionEx(&ver); | ||
70 | switch (ver.dwPlatformId) { | ||
71 | case VER_PLATFORM_WIN32_NT: | ||
72 | if ( ver.dwMajorVersion > 4 ) { | ||
73 | /* Win2K */ | ||
74 | dsound_ok = 1; | ||
75 | } else { | ||
76 | /* WinNT */ | ||
77 | dsound_ok = 0; | ||
78 | } | ||
79 | break; | ||
80 | default: | ||
81 | /* Win95 or Win98 */ | ||
82 | dsound_ok = 1; | ||
83 | break; | ||
84 | } | ||
85 | /* Now check for DirectX 5 or better - otherwise | ||
86 | * we will fail later in DX5_OpenAudio without a chance | ||
87 | * to fall back to the DIB driver. */ | ||
88 | if (dsound_ok) { | ||
89 | /* DirectSoundCaptureCreate was added in DX5 */ | ||
90 | if (!GetProcAddress(DSoundDLL, TEXT("DirectSoundCaptureCreate"))) | ||
91 | dsound_ok = 0; | ||
92 | |||
93 | } | ||
94 | /* Clean up.. */ | ||
95 | FreeLibrary(DSoundDLL); | ||
96 | } | ||
97 | return(dsound_ok); | ||
98 | } | ||
99 | |||
100 | /* Functions for loading the DirectX functions dynamically */ | ||
101 | static HINSTANCE DSoundDLL = NULL; | ||
102 | |||
103 | static void DX5_Unload(void) | ||
104 | { | ||
105 | if ( DSoundDLL != NULL ) { | ||
106 | FreeLibrary(DSoundDLL); | ||
107 | DSoundCreate = NULL; | ||
108 | DSoundDLL = NULL; | ||
109 | } | ||
110 | } | ||
111 | static int DX5_Load(void) | ||
112 | { | ||
113 | int status; | ||
114 | |||
115 | DX5_Unload(); | ||
116 | DSoundDLL = LoadLibrary(TEXT("DSOUND.DLL")); | ||
117 | if ( DSoundDLL != NULL ) { | ||
118 | DSoundCreate = (void *)GetProcAddress(DSoundDLL, | ||
119 | TEXT("DirectSoundCreate")); | ||
120 | } | ||
121 | if ( DSoundDLL && DSoundCreate ) { | ||
122 | status = 0; | ||
123 | } else { | ||
124 | DX5_Unload(); | ||
125 | status = -1; | ||
126 | } | ||
127 | return status; | ||
128 | } | ||
129 | |||
130 | static void Audio_DeleteDevice(SDL_AudioDevice *device) | ||
131 | { | ||
132 | DX5_Unload(); | ||
133 | SDL_free(device->hidden); | ||
134 | SDL_free(device); | ||
135 | } | ||
136 | |||
137 | static SDL_AudioDevice *Audio_CreateDevice(int devindex) | ||
138 | { | ||
139 | SDL_AudioDevice *this; | ||
140 | |||
141 | /* Load DirectX */ | ||
142 | if ( DX5_Load() < 0 ) { | ||
143 | return(NULL); | ||
144 | } | ||
145 | |||
146 | /* Initialize all variables that we clean on shutdown */ | ||
147 | this = (SDL_AudioDevice *)SDL_malloc(sizeof(SDL_AudioDevice)); | ||
148 | if ( this ) { | ||
149 | SDL_memset(this, 0, (sizeof *this)); | ||
150 | this->hidden = (struct SDL_PrivateAudioData *) | ||
151 | SDL_malloc((sizeof *this->hidden)); | ||
152 | } | ||
153 | if ( (this == NULL) || (this->hidden == NULL) ) { | ||
154 | SDL_OutOfMemory(); | ||
155 | if ( this ) { | ||
156 | SDL_free(this); | ||
157 | } | ||
158 | return(0); | ||
159 | } | ||
160 | SDL_memset(this->hidden, 0, (sizeof *this->hidden)); | ||
161 | |||
162 | /* Set the function pointers */ | ||
163 | this->OpenAudio = DX5_OpenAudio; | ||
164 | this->ThreadInit = DX5_ThreadInit; | ||
165 | this->WaitAudio = DX5_WaitAudio_BusyWait; | ||
166 | this->PlayAudio = DX5_PlayAudio; | ||
167 | this->GetAudioBuf = DX5_GetAudioBuf; | ||
168 | this->WaitDone = DX5_WaitDone; | ||
169 | this->CloseAudio = DX5_CloseAudio; | ||
170 | |||
171 | this->free = Audio_DeleteDevice; | ||
172 | |||
173 | return this; | ||
174 | } | ||
175 | |||
176 | AudioBootStrap DSOUND_bootstrap = { | ||
177 | "dsound", "Win95/98/2000 DirectSound", | ||
178 | Audio_Available, Audio_CreateDevice | ||
179 | }; | ||
180 | |||
181 | static void SetDSerror(const char *function, int code) | ||
182 | { | ||
183 | static const char *error; | ||
184 | static char errbuf[1024]; | ||
185 | |||
186 | errbuf[0] = 0; | ||
187 | switch (code) { | ||
188 | case E_NOINTERFACE: | ||
189 | error = | ||
190 | "Unsupported interface\n-- Is DirectX 5.0 or later installed?"; | ||
191 | break; | ||
192 | case DSERR_ALLOCATED: | ||
193 | error = "Audio device in use"; | ||
194 | break; | ||
195 | case DSERR_BADFORMAT: | ||
196 | error = "Unsupported audio format"; | ||
197 | break; | ||
198 | case DSERR_BUFFERLOST: | ||
199 | error = "Mixing buffer was lost"; | ||
200 | break; | ||
201 | case DSERR_CONTROLUNAVAIL: | ||
202 | error = "Control requested is not available"; | ||
203 | break; | ||
204 | case DSERR_INVALIDCALL: | ||
205 | error = "Invalid call for the current state"; | ||
206 | break; | ||
207 | case DSERR_INVALIDPARAM: | ||
208 | error = "Invalid parameter"; | ||
209 | break; | ||
210 | case DSERR_NODRIVER: | ||
211 | error = "No audio device found"; | ||
212 | break; | ||
213 | case DSERR_OUTOFMEMORY: | ||
214 | error = "Out of memory"; | ||
215 | break; | ||
216 | case DSERR_PRIOLEVELNEEDED: | ||
217 | error = "Caller doesn't have priority"; | ||
218 | break; | ||
219 | case DSERR_UNSUPPORTED: | ||
220 | error = "Function not supported"; | ||
221 | break; | ||
222 | default: | ||
223 | SDL_snprintf(errbuf, SDL_arraysize(errbuf), | ||
224 | "%s: Unknown DirectSound error: 0x%x", | ||
225 | function, code); | ||
226 | break; | ||
227 | } | ||
228 | if ( ! errbuf[0] ) { | ||
229 | SDL_snprintf(errbuf, SDL_arraysize(errbuf), "%s: %s", function, error); | ||
230 | } | ||
231 | SDL_SetError("%s", errbuf); | ||
232 | return; | ||
233 | } | ||
234 | |||
235 | /* DirectSound needs to be associated with a window */ | ||
236 | static HWND mainwin = NULL; | ||
237 | /* */ | ||
238 | void DX5_SoundFocus(HWND hwnd) | ||
239 | { | ||
240 | mainwin = hwnd; | ||
241 | } | ||
242 | |||
243 | static void DX5_ThreadInit(_THIS) | ||
244 | { | ||
245 | SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_HIGHEST); | ||
246 | } | ||
247 | |||
248 | static void DX5_WaitAudio_BusyWait(_THIS) | ||
249 | { | ||
250 | DWORD status; | ||
251 | DWORD cursor, junk; | ||
252 | HRESULT result; | ||
253 | |||
254 | /* Semi-busy wait, since we have no way of getting play notification | ||
255 | on a primary mixing buffer located in hardware (DirectX 5.0) | ||
256 | */ | ||
257 | result = IDirectSoundBuffer_GetCurrentPosition(mixbuf, &junk, &cursor); | ||
258 | if ( result != DS_OK ) { | ||
259 | if ( result == DSERR_BUFFERLOST ) { | ||
260 | IDirectSoundBuffer_Restore(mixbuf); | ||
261 | } | ||
262 | #ifdef DEBUG_SOUND | ||
263 | SetDSerror("DirectSound GetCurrentPosition", result); | ||
264 | #endif | ||
265 | return; | ||
266 | } | ||
267 | |||
268 | while ( (cursor/mixlen) == lastchunk ) { | ||
269 | /* FIXME: find out how much time is left and sleep that long */ | ||
270 | SDL_Delay(1); | ||
271 | |||
272 | /* Try to restore a lost sound buffer */ | ||
273 | IDirectSoundBuffer_GetStatus(mixbuf, &status); | ||
274 | if ( (status&DSBSTATUS_BUFFERLOST) ) { | ||
275 | IDirectSoundBuffer_Restore(mixbuf); | ||
276 | IDirectSoundBuffer_GetStatus(mixbuf, &status); | ||
277 | if ( (status&DSBSTATUS_BUFFERLOST) ) { | ||
278 | break; | ||
279 | } | ||
280 | } | ||
281 | if ( ! (status&DSBSTATUS_PLAYING) ) { | ||
282 | result = IDirectSoundBuffer_Play(mixbuf, 0, 0, DSBPLAY_LOOPING); | ||
283 | if ( result == DS_OK ) { | ||
284 | continue; | ||
285 | } | ||
286 | #ifdef DEBUG_SOUND | ||
287 | SetDSerror("DirectSound Play", result); | ||
288 | #endif | ||
289 | return; | ||
290 | } | ||
291 | |||
292 | /* Find out where we are playing */ | ||
293 | result = IDirectSoundBuffer_GetCurrentPosition(mixbuf, | ||
294 | &junk, &cursor); | ||
295 | if ( result != DS_OK ) { | ||
296 | SetDSerror("DirectSound GetCurrentPosition", result); | ||
297 | return; | ||
298 | } | ||
299 | } | ||
300 | } | ||
301 | |||
302 | #ifdef USE_POSITION_NOTIFY | ||
303 | static void DX6_WaitAudio_EventWait(_THIS) | ||
304 | { | ||
305 | DWORD status; | ||
306 | HRESULT result; | ||
307 | |||
308 | /* Try to restore a lost sound buffer */ | ||
309 | IDirectSoundBuffer_GetStatus(mixbuf, &status); | ||
310 | if ( (status&DSBSTATUS_BUFFERLOST) ) { | ||
311 | IDirectSoundBuffer_Restore(mixbuf); | ||
312 | IDirectSoundBuffer_GetStatus(mixbuf, &status); | ||
313 | if ( (status&DSBSTATUS_BUFFERLOST) ) { | ||
314 | return; | ||
315 | } | ||
316 | } | ||
317 | if ( ! (status&DSBSTATUS_PLAYING) ) { | ||
318 | result = IDirectSoundBuffer_Play(mixbuf, 0, 0, DSBPLAY_LOOPING); | ||
319 | if ( result != DS_OK ) { | ||
320 | #ifdef DEBUG_SOUND | ||
321 | SetDSerror("DirectSound Play", result); | ||
322 | #endif | ||
323 | return; | ||
324 | } | ||
325 | } | ||
326 | WaitForSingleObject(audio_event, INFINITE); | ||
327 | } | ||
328 | #endif /* USE_POSITION_NOTIFY */ | ||
329 | |||
330 | static void DX5_PlayAudio(_THIS) | ||
331 | { | ||
332 | /* Unlock the buffer, allowing it to play */ | ||
333 | if ( locked_buf ) { | ||
334 | IDirectSoundBuffer_Unlock(mixbuf, locked_buf, mixlen, NULL, 0); | ||
335 | } | ||
336 | |||
337 | } | ||
338 | |||
339 | static Uint8 *DX5_GetAudioBuf(_THIS) | ||
340 | { | ||
341 | DWORD cursor, junk; | ||
342 | HRESULT result; | ||
343 | DWORD rawlen; | ||
344 | |||
345 | /* Figure out which blocks to fill next */ | ||
346 | locked_buf = NULL; | ||
347 | result = IDirectSoundBuffer_GetCurrentPosition(mixbuf, &junk, &cursor); | ||
348 | if ( result == DSERR_BUFFERLOST ) { | ||
349 | IDirectSoundBuffer_Restore(mixbuf); | ||
350 | result = IDirectSoundBuffer_GetCurrentPosition(mixbuf, | ||
351 | &junk, &cursor); | ||
352 | } | ||
353 | if ( result != DS_OK ) { | ||
354 | SetDSerror("DirectSound GetCurrentPosition", result); | ||
355 | return(NULL); | ||
356 | } | ||
357 | cursor /= mixlen; | ||
358 | #ifdef DEBUG_SOUND | ||
359 | /* Detect audio dropouts */ | ||
360 | { DWORD spot = cursor; | ||
361 | if ( spot < lastchunk ) { | ||
362 | spot += NUM_BUFFERS; | ||
363 | } | ||
364 | if ( spot > lastchunk+1 ) { | ||
365 | fprintf(stderr, "Audio dropout, missed %d fragments\n", | ||
366 | (spot - (lastchunk+1))); | ||
367 | } | ||
368 | } | ||
369 | #endif | ||
370 | lastchunk = cursor; | ||
371 | cursor = (cursor+1)%NUM_BUFFERS; | ||
372 | cursor *= mixlen; | ||
373 | |||
374 | /* Lock the audio buffer */ | ||
375 | result = IDirectSoundBuffer_Lock(mixbuf, cursor, mixlen, | ||
376 | (LPVOID *)&locked_buf, &rawlen, NULL, &junk, 0); | ||
377 | if ( result == DSERR_BUFFERLOST ) { | ||
378 | IDirectSoundBuffer_Restore(mixbuf); | ||
379 | result = IDirectSoundBuffer_Lock(mixbuf, cursor, mixlen, | ||
380 | (LPVOID *)&locked_buf, &rawlen, NULL, &junk, 0); | ||
381 | } | ||
382 | if ( result != DS_OK ) { | ||
383 | SetDSerror("DirectSound Lock", result); | ||
384 | return(NULL); | ||
385 | } | ||
386 | return(locked_buf); | ||
387 | } | ||
388 | |||
389 | static void DX5_WaitDone(_THIS) | ||
390 | { | ||
391 | Uint8 *stream; | ||
392 | |||
393 | /* Wait for the playing chunk to finish */ | ||
394 | stream = this->GetAudioBuf(this); | ||
395 | if ( stream != NULL ) { | ||
396 | SDL_memset(stream, silence, mixlen); | ||
397 | this->PlayAudio(this); | ||
398 | } | ||
399 | this->WaitAudio(this); | ||
400 | |||
401 | /* Stop the looping sound buffer */ | ||
402 | IDirectSoundBuffer_Stop(mixbuf); | ||
403 | } | ||
404 | |||
405 | static void DX5_CloseAudio(_THIS) | ||
406 | { | ||
407 | if ( sound != NULL ) { | ||
408 | if ( mixbuf != NULL ) { | ||
409 | /* Clean up the audio buffer */ | ||
410 | IDirectSoundBuffer_Release(mixbuf); | ||
411 | mixbuf = NULL; | ||
412 | } | ||
413 | if ( audio_event != NULL ) { | ||
414 | CloseHandle(audio_event); | ||
415 | audio_event = NULL; | ||
416 | } | ||
417 | IDirectSound_Release(sound); | ||
418 | sound = NULL; | ||
419 | } | ||
420 | } | ||
421 | |||
422 | #ifdef USE_PRIMARY_BUFFER | ||
423 | /* This function tries to create a primary audio buffer, and returns the | ||
424 | number of audio chunks available in the created buffer. | ||
425 | */ | ||
426 | static int CreatePrimary(LPDIRECTSOUND sndObj, HWND focus, | ||
427 | LPDIRECTSOUNDBUFFER *sndbuf, WAVEFORMATEX *wavefmt, Uint32 chunksize) | ||
428 | { | ||
429 | HRESULT result; | ||
430 | DSBUFFERDESC format; | ||
431 | DSBCAPS caps; | ||
432 | int numchunks; | ||
433 | |||
434 | /* Try to set primary mixing privileges */ | ||
435 | result = IDirectSound_SetCooperativeLevel(sndObj, focus, | ||
436 | DSSCL_WRITEPRIMARY); | ||
437 | if ( result != DS_OK ) { | ||
438 | #ifdef DEBUG_SOUND | ||
439 | SetDSerror("DirectSound SetCooperativeLevel", result); | ||
440 | #endif | ||
441 | return(-1); | ||
442 | } | ||
443 | |||
444 | /* Try to create the primary buffer */ | ||
445 | SDL_memset(&format, 0, sizeof(format)); | ||
446 | format.dwSize = sizeof(format); | ||
447 | format.dwFlags=(DSBCAPS_PRIMARYBUFFER|DSBCAPS_GETCURRENTPOSITION2); | ||
448 | format.dwFlags |= DSBCAPS_STICKYFOCUS; | ||
449 | #ifdef USE_POSITION_NOTIFY | ||
450 | format.dwFlags |= DSBCAPS_CTRLPOSITIONNOTIFY; | ||
451 | #endif | ||
452 | result = IDirectSound_CreateSoundBuffer(sndObj, &format, sndbuf, NULL); | ||
453 | if ( result != DS_OK ) { | ||
454 | #ifdef DEBUG_SOUND | ||
455 | SetDSerror("DirectSound CreateSoundBuffer", result); | ||
456 | #endif | ||
457 | return(-1); | ||
458 | } | ||
459 | |||
460 | /* Check the size of the fragment buffer */ | ||
461 | SDL_memset(&caps, 0, sizeof(caps)); | ||
462 | caps.dwSize = sizeof(caps); | ||
463 | result = IDirectSoundBuffer_GetCaps(*sndbuf, &caps); | ||
464 | if ( result != DS_OK ) { | ||
465 | #ifdef DEBUG_SOUND | ||
466 | SetDSerror("DirectSound GetCaps", result); | ||
467 | #endif | ||
468 | IDirectSoundBuffer_Release(*sndbuf); | ||
469 | return(-1); | ||
470 | } | ||
471 | if ( (chunksize > caps.dwBufferBytes) || | ||
472 | ((caps.dwBufferBytes%chunksize) != 0) ) { | ||
473 | /* The primary buffer size is not a multiple of 'chunksize' | ||
474 | -- this hopefully doesn't happen when 'chunksize' is a | ||
475 | power of 2. | ||
476 | */ | ||
477 | IDirectSoundBuffer_Release(*sndbuf); | ||
478 | SDL_SetError( | ||
479 | "Primary buffer size is: %d, cannot break it into chunks of %d bytes\n", | ||
480 | caps.dwBufferBytes, chunksize); | ||
481 | return(-1); | ||
482 | } | ||
483 | numchunks = (caps.dwBufferBytes/chunksize); | ||
484 | |||
485 | /* Set the primary audio format */ | ||
486 | result = IDirectSoundBuffer_SetFormat(*sndbuf, wavefmt); | ||
487 | if ( result != DS_OK ) { | ||
488 | #ifdef DEBUG_SOUND | ||
489 | SetDSerror("DirectSound SetFormat", result); | ||
490 | #endif | ||
491 | IDirectSoundBuffer_Release(*sndbuf); | ||
492 | return(-1); | ||
493 | } | ||
494 | return(numchunks); | ||
495 | } | ||
496 | #endif /* USE_PRIMARY_BUFFER */ | ||
497 | |||
498 | /* This function tries to create a secondary audio buffer, and returns the | ||
499 | number of audio chunks available in the created buffer. | ||
500 | */ | ||
501 | static int CreateSecondary(LPDIRECTSOUND sndObj, HWND focus, | ||
502 | LPDIRECTSOUNDBUFFER *sndbuf, WAVEFORMATEX *wavefmt, Uint32 chunksize) | ||
503 | { | ||
504 | const int numchunks = 8; | ||
505 | HRESULT result; | ||
506 | DSBUFFERDESC format; | ||
507 | LPVOID pvAudioPtr1, pvAudioPtr2; | ||
508 | DWORD dwAudioBytes1, dwAudioBytes2; | ||
509 | |||
510 | /* Try to set primary mixing privileges */ | ||
511 | if ( focus ) { | ||
512 | result = IDirectSound_SetCooperativeLevel(sndObj, | ||
513 | focus, DSSCL_PRIORITY); | ||
514 | } else { | ||
515 | result = IDirectSound_SetCooperativeLevel(sndObj, | ||
516 | GetDesktopWindow(), DSSCL_NORMAL); | ||
517 | } | ||
518 | if ( result != DS_OK ) { | ||
519 | #ifdef DEBUG_SOUND | ||
520 | SetDSerror("DirectSound SetCooperativeLevel", result); | ||
521 | #endif | ||
522 | return(-1); | ||
523 | } | ||
524 | |||
525 | /* Try to create the secondary buffer */ | ||
526 | SDL_memset(&format, 0, sizeof(format)); | ||
527 | format.dwSize = sizeof(format); | ||
528 | format.dwFlags = DSBCAPS_GETCURRENTPOSITION2; | ||
529 | #ifdef USE_POSITION_NOTIFY | ||
530 | format.dwFlags |= DSBCAPS_CTRLPOSITIONNOTIFY; | ||
531 | #endif | ||
532 | if ( ! focus ) { | ||
533 | format.dwFlags |= DSBCAPS_GLOBALFOCUS; | ||
534 | } else { | ||
535 | format.dwFlags |= DSBCAPS_STICKYFOCUS; | ||
536 | } | ||
537 | format.dwBufferBytes = numchunks*chunksize; | ||
538 | if ( (format.dwBufferBytes < DSBSIZE_MIN) || | ||
539 | (format.dwBufferBytes > DSBSIZE_MAX) ) { | ||
540 | SDL_SetError("Sound buffer size must be between %d and %d", | ||
541 | DSBSIZE_MIN/numchunks, DSBSIZE_MAX/numchunks); | ||
542 | return(-1); | ||
543 | } | ||
544 | format.dwReserved = 0; | ||
545 | format.lpwfxFormat = wavefmt; | ||
546 | result = IDirectSound_CreateSoundBuffer(sndObj, &format, sndbuf, NULL); | ||
547 | if ( result != DS_OK ) { | ||
548 | SetDSerror("DirectSound CreateSoundBuffer", result); | ||
549 | return(-1); | ||
550 | } | ||
551 | IDirectSoundBuffer_SetFormat(*sndbuf, wavefmt); | ||
552 | |||
553 | /* Silence the initial audio buffer */ | ||
554 | result = IDirectSoundBuffer_Lock(*sndbuf, 0, format.dwBufferBytes, | ||
555 | (LPVOID *)&pvAudioPtr1, &dwAudioBytes1, | ||
556 | (LPVOID *)&pvAudioPtr2, &dwAudioBytes2, | ||
557 | DSBLOCK_ENTIREBUFFER); | ||
558 | if ( result == DS_OK ) { | ||
559 | if ( wavefmt->wBitsPerSample == 8 ) { | ||
560 | SDL_memset(pvAudioPtr1, 0x80, dwAudioBytes1); | ||
561 | } else { | ||
562 | SDL_memset(pvAudioPtr1, 0x00, dwAudioBytes1); | ||
563 | } | ||
564 | IDirectSoundBuffer_Unlock(*sndbuf, | ||
565 | (LPVOID)pvAudioPtr1, dwAudioBytes1, | ||
566 | (LPVOID)pvAudioPtr2, dwAudioBytes2); | ||
567 | } | ||
568 | |||
569 | /* We're ready to go */ | ||
570 | return(numchunks); | ||
571 | } | ||
572 | |||
573 | /* This function tries to set position notify events on the mixing buffer */ | ||
574 | #ifdef USE_POSITION_NOTIFY | ||
575 | static int CreateAudioEvent(_THIS) | ||
576 | { | ||
577 | LPDIRECTSOUNDNOTIFY notify; | ||
578 | DSBPOSITIONNOTIFY *notify_positions; | ||
579 | int i, retval; | ||
580 | HRESULT result; | ||
581 | |||
582 | /* Default to fail on exit */ | ||
583 | retval = -1; | ||
584 | notify = NULL; | ||
585 | |||
586 | /* Query for the interface */ | ||
587 | result = IDirectSoundBuffer_QueryInterface(mixbuf, | ||
588 | &IID_IDirectSoundNotify, (void *)¬ify); | ||
589 | if ( result != DS_OK ) { | ||
590 | goto done; | ||
591 | } | ||
592 | |||
593 | /* Allocate the notify structures */ | ||
594 | notify_positions = (DSBPOSITIONNOTIFY *)SDL_malloc(NUM_BUFFERS* | ||
595 | sizeof(*notify_positions)); | ||
596 | if ( notify_positions == NULL ) { | ||
597 | goto done; | ||
598 | } | ||
599 | |||
600 | /* Create the notify event */ | ||
601 | audio_event = CreateEvent(NULL, FALSE, FALSE, NULL); | ||
602 | if ( audio_event == NULL ) { | ||
603 | goto done; | ||
604 | } | ||
605 | |||
606 | /* Set up the notify structures */ | ||
607 | for ( i=0; i<NUM_BUFFERS; ++i ) { | ||
608 | notify_positions[i].dwOffset = i*mixlen; | ||
609 | notify_positions[i].hEventNotify = audio_event; | ||
610 | } | ||
611 | result = IDirectSoundNotify_SetNotificationPositions(notify, | ||
612 | NUM_BUFFERS, notify_positions); | ||
613 | if ( result == DS_OK ) { | ||
614 | retval = 0; | ||
615 | } | ||
616 | done: | ||
617 | if ( notify != NULL ) { | ||
618 | IDirectSoundNotify_Release(notify); | ||
619 | } | ||
620 | return(retval); | ||
621 | } | ||
622 | #endif /* USE_POSITION_NOTIFY */ | ||
623 | |||
624 | static int DX5_OpenAudio(_THIS, SDL_AudioSpec *spec) | ||
625 | { | ||
626 | HRESULT result; | ||
627 | WAVEFORMATEX waveformat; | ||
628 | |||
629 | /* Set basic WAVE format parameters */ | ||
630 | SDL_memset(&waveformat, 0, sizeof(waveformat)); | ||
631 | waveformat.wFormatTag = WAVE_FORMAT_PCM; | ||
632 | |||
633 | /* Determine the audio parameters from the AudioSpec */ | ||
634 | switch ( spec->format & 0xFF ) { | ||
635 | case 8: | ||
636 | /* Unsigned 8 bit audio data */ | ||
637 | spec->format = AUDIO_U8; | ||
638 | silence = 0x80; | ||
639 | waveformat.wBitsPerSample = 8; | ||
640 | break; | ||
641 | case 16: | ||
642 | /* Signed 16 bit audio data */ | ||
643 | spec->format = AUDIO_S16; | ||
644 | silence = 0x00; | ||
645 | waveformat.wBitsPerSample = 16; | ||
646 | break; | ||
647 | default: | ||
648 | SDL_SetError("Unsupported audio format"); | ||
649 | return(-1); | ||
650 | } | ||
651 | waveformat.nChannels = spec->channels; | ||
652 | waveformat.nSamplesPerSec = spec->freq; | ||
653 | waveformat.nBlockAlign = | ||
654 | waveformat.nChannels * (waveformat.wBitsPerSample/8); | ||
655 | waveformat.nAvgBytesPerSec = | ||
656 | waveformat.nSamplesPerSec * waveformat.nBlockAlign; | ||
657 | |||
658 | /* Update the fragment size as size in bytes */ | ||
659 | SDL_CalculateAudioSpec(spec); | ||
660 | |||
661 | /* Open the audio device */ | ||
662 | result = DSoundCreate(NULL, &sound, NULL); | ||
663 | if ( result != DS_OK ) { | ||
664 | SetDSerror("DirectSoundCreate", result); | ||
665 | return(-1); | ||
666 | } | ||
667 | |||
668 | /* Create the audio buffer to which we write */ | ||
669 | NUM_BUFFERS = -1; | ||
670 | #ifdef USE_PRIMARY_BUFFER | ||
671 | if ( mainwin ) { | ||
672 | NUM_BUFFERS = CreatePrimary(sound, mainwin, &mixbuf, | ||
673 | &waveformat, spec->size); | ||
674 | } | ||
675 | #endif /* USE_PRIMARY_BUFFER */ | ||
676 | if ( NUM_BUFFERS < 0 ) { | ||
677 | NUM_BUFFERS = CreateSecondary(sound, mainwin, &mixbuf, | ||
678 | &waveformat, spec->size); | ||
679 | if ( NUM_BUFFERS < 0 ) { | ||
680 | return(-1); | ||
681 | } | ||
682 | #ifdef DEBUG_SOUND | ||
683 | fprintf(stderr, "Using secondary audio buffer\n"); | ||
684 | #endif | ||
685 | } | ||
686 | #ifdef DEBUG_SOUND | ||
687 | else | ||
688 | fprintf(stderr, "Using primary audio buffer\n"); | ||
689 | #endif | ||
690 | |||
691 | /* The buffer will auto-start playing in DX5_WaitAudio() */ | ||
692 | lastchunk = 0; | ||
693 | mixlen = spec->size; | ||
694 | |||
695 | #ifdef USE_POSITION_NOTIFY | ||
696 | /* See if we can use DirectX 6 event notification */ | ||
697 | if ( CreateAudioEvent(this) == 0 ) { | ||
698 | this->WaitAudio = DX6_WaitAudio_EventWait; | ||
699 | } else { | ||
700 | this->WaitAudio = DX5_WaitAudio_BusyWait; | ||
701 | } | ||
702 | #endif | ||
703 | return(0); | ||
704 | } | ||
705 | |||
diff --git a/apps/plugins/sdl/src/audio/windx5/SDL_dx5audio.h b/apps/plugins/sdl/src/audio/windx5/SDL_dx5audio.h deleted file mode 100644 index bc4022fc9c..0000000000 --- a/apps/plugins/sdl/src/audio/windx5/SDL_dx5audio.h +++ /dev/null | |||
@@ -1,55 +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 Lesser General Public | ||
7 | License as published by the Free Software Foundation; either | ||
8 | version 2.1 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 | Lesser General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU Lesser General Public | ||
16 | License along with this library; if not, write to the Free Software | ||
17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
18 | |||
19 | Sam Lantinga | ||
20 | slouken@libsdl.org | ||
21 | */ | ||
22 | #include "SDL_config.h" | ||
23 | |||
24 | #ifndef _SDL_lowaudio_h | ||
25 | #define _SDL_lowaudio_h | ||
26 | |||
27 | #include "directx.h" | ||
28 | |||
29 | #include "../SDL_sysaudio.h" | ||
30 | |||
31 | /* Hidden "this" pointer for the video functions */ | ||
32 | #define _THIS SDL_AudioDevice *this | ||
33 | |||
34 | /* The DirectSound objects */ | ||
35 | struct SDL_PrivateAudioData { | ||
36 | LPDIRECTSOUND sound; | ||
37 | LPDIRECTSOUNDBUFFER mixbuf; | ||
38 | int NUM_BUFFERS; | ||
39 | int mixlen, silence; | ||
40 | DWORD lastchunk; | ||
41 | Uint8 *locked_buf; | ||
42 | HANDLE audio_event; | ||
43 | }; | ||
44 | |||
45 | /* Old variable names */ | ||
46 | #define sound (this->hidden->sound) | ||
47 | #define mixbuf (this->hidden->mixbuf) | ||
48 | #define NUM_BUFFERS (this->hidden->NUM_BUFFERS) | ||
49 | #define mixlen (this->hidden->mixlen) | ||
50 | #define silence (this->hidden->silence) | ||
51 | #define lastchunk (this->hidden->lastchunk) | ||
52 | #define locked_buf (this->hidden->locked_buf) | ||
53 | #define audio_event (this->hidden->audio_event) | ||
54 | |||
55 | #endif /* _SDL_lowaudio_h */ | ||
diff --git a/apps/plugins/sdl/src/audio/windx5/directx.h b/apps/plugins/sdl/src/audio/windx5/directx.h deleted file mode 100644 index 5f339f2de8..0000000000 --- a/apps/plugins/sdl/src/audio/windx5/directx.h +++ /dev/null | |||
@@ -1,81 +0,0 @@ | |||
1 | |||
2 | #ifndef _directx_h | ||
3 | #define _directx_h | ||
4 | |||
5 | /* Include all of the DirectX 5.0 headers and adds any necessary tweaks */ | ||
6 | |||
7 | #define WIN32_LEAN_AND_MEAN | ||
8 | #include <windows.h> | ||
9 | #include <mmsystem.h> | ||
10 | #ifndef WIN32 | ||
11 | #define WIN32 | ||
12 | #endif | ||
13 | #undef WINNT | ||
14 | |||
15 | /* Far pointers don't exist in 32-bit code */ | ||
16 | #ifndef FAR | ||
17 | #define FAR | ||
18 | #endif | ||
19 | |||
20 | /* Error codes not yet included in Win32 API header files */ | ||
21 | #ifndef MAKE_HRESULT | ||
22 | #define MAKE_HRESULT(sev,fac,code) \ | ||
23 | ((HRESULT)(((unsigned long)(sev)<<31) | ((unsigned long)(fac)<<16) | ((unsigned long)(code)))) | ||
24 | #endif | ||
25 | |||
26 | #ifndef S_OK | ||
27 | #define S_OK (HRESULT)0x00000000L | ||
28 | #endif | ||
29 | |||
30 | #ifndef SUCCEEDED | ||
31 | #define SUCCEEDED(x) ((HRESULT)(x) >= 0) | ||
32 | #endif | ||
33 | #ifndef FAILED | ||
34 | #define FAILED(x) ((HRESULT)(x)<0) | ||
35 | #endif | ||
36 | |||
37 | #ifndef E_FAIL | ||
38 | #define E_FAIL (HRESULT)0x80000008L | ||
39 | #endif | ||
40 | #ifndef E_NOINTERFACE | ||
41 | #define E_NOINTERFACE (HRESULT)0x80004002L | ||
42 | #endif | ||
43 | #ifndef E_OUTOFMEMORY | ||
44 | #define E_OUTOFMEMORY (HRESULT)0x8007000EL | ||
45 | #endif | ||
46 | #ifndef E_INVALIDARG | ||
47 | #define E_INVALIDARG (HRESULT)0x80070057L | ||
48 | #endif | ||
49 | #ifndef E_NOTIMPL | ||
50 | #define E_NOTIMPL (HRESULT)0x80004001L | ||
51 | #endif | ||
52 | #ifndef REGDB_E_CLASSNOTREG | ||
53 | #define REGDB_E_CLASSNOTREG (HRESULT)0x80040154L | ||
54 | #endif | ||
55 | |||
56 | /* Severity codes */ | ||
57 | #ifndef SEVERITY_ERROR | ||
58 | #define SEVERITY_ERROR 1 | ||
59 | #endif | ||
60 | |||
61 | /* Error facility codes */ | ||
62 | #ifndef FACILITY_WIN32 | ||
63 | #define FACILITY_WIN32 7 | ||
64 | #endif | ||
65 | |||
66 | #ifndef FIELD_OFFSET | ||
67 | #define FIELD_OFFSET(type, field) ((LONG)&(((type *)0)->field)) | ||
68 | #endif | ||
69 | |||
70 | /* DirectX headers (if it isn't included, I haven't tested it yet) | ||
71 | */ | ||
72 | /* We need these defines to mark what version of DirectX API we use */ | ||
73 | #define DIRECTDRAW_VERSION 0x0700 | ||
74 | #define DIRECTSOUND_VERSION 0x0500 | ||
75 | #define DIRECTINPUT_VERSION 0x0500 | ||
76 | |||
77 | #include <ddraw.h> | ||
78 | #include <dsound.h> | ||
79 | #include <dinput.h> | ||
80 | |||
81 | #endif /* _directx_h */ | ||