Mercurial > sdl-ios-xcode
annotate src/audio/SDL_audio.c @ 315:3333b6e68289
Date: Sat, 23 Mar 2002 13:53:37 +0200
From: "Mike Gorchak" <mike@malva.ua>
Subject: Big QNX patch again.
Added 8bit palette emulation code for window mode with bpp>=15.
Added store/restore original palette for 8bit modes.
Added more information about photon API call fails.
Rewroten change palette code, slow but works.
Fixed bug with set caption before window was inited.
Fixed bugs with some initial state of variables.
Fixed bug with storing old video mode settings.
Fixed bug with switching to fullscreen mode and back.
Fixed few double SEGFAULTS during parachute mode.
Removed compilation warning with no PgWaitHWIdle prototype.
Removed pack of dead unusable code.
Cleanups SDL_PrivateVideoData structure, some headers.
Some code formatting.
author | Sam Lantinga <slouken@libsdl.org> |
---|---|
date | Sat, 23 Mar 2002 20:19:44 +0000 |
parents | f6ffac90895c |
children | fd93a09655e3 |
rev | line source |
---|---|
0 | 1 /* |
2 SDL - Simple DirectMedia Layer | |
297
f6ffac90895c
Updated copyright information for 2002
Sam Lantinga <slouken@libsdl.org>
parents:
262
diff
changeset
|
3 Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 Sam Lantinga |
0 | 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 | |
252
e8157fcb3114
Updated the source with the correct e-mail address
Sam Lantinga <slouken@libsdl.org>
parents:
148
diff
changeset
|
20 slouken@libsdl.org |
0 | 21 */ |
22 | |
23 #ifdef SAVE_RCSID | |
24 static char rcsid = | |
25 "@(#) $Id$"; | |
26 #endif | |
27 | |
28 /* Allow access to a raw mixing buffer */ | |
29 #include <stdlib.h> | |
30 #include <stdio.h> | |
31 #include <string.h> | |
32 | |
33 #include "SDL.h" | |
34 #include "SDL_audio.h" | |
35 #include "SDL_timer.h" | |
36 #include "SDL_error.h" | |
37 #include "SDL_audio_c.h" | |
38 #include "SDL_audiomem.h" | |
39 #include "SDL_sysaudio.h" | |
40 | |
41 /* Available audio drivers */ | |
42 static AudioBootStrap *bootstrap[] = { | |
121
43febd46d49d
Name changed from OBSD to OPENBSD_AUDIO
Sam Lantinga <slouken@libsdl.org>
parents:
94
diff
changeset
|
43 #ifdef OPENBSD_AUDIO_SUPPORT |
43febd46d49d
Name changed from OBSD to OPENBSD_AUDIO
Sam Lantinga <slouken@libsdl.org>
parents:
94
diff
changeset
|
44 &OPENBSD_AUDIO_bootstrap, |
94
ae6e6b73333f
Cleaned up the OpenBSD port, thanks to Peter Valchev
Sam Lantinga <slouken@lokigames.com>
parents:
68
diff
changeset
|
45 #endif |
0 | 46 #ifdef OSS_SUPPORT |
47 &DSP_bootstrap, | |
48 &DMA_bootstrap, | |
49 #endif | |
50 #ifdef ALSA_SUPPORT | |
51 &ALSA_bootstrap, | |
52 #endif | |
148
8758b8d42cd9
Audio subsystem no longer assumes sun audio API on UNIX systems
Sam Lantinga <slouken@libsdl.org>
parents:
121
diff
changeset
|
53 #ifdef SUNAUDIO_SUPPORT |
8758b8d42cd9
Audio subsystem no longer assumes sun audio API on UNIX systems
Sam Lantinga <slouken@libsdl.org>
parents:
121
diff
changeset
|
54 &SUNAUDIO_bootstrap, |
8758b8d42cd9
Audio subsystem no longer assumes sun audio API on UNIX systems
Sam Lantinga <slouken@libsdl.org>
parents:
121
diff
changeset
|
55 #endif |
8758b8d42cd9
Audio subsystem no longer assumes sun audio API on UNIX systems
Sam Lantinga <slouken@libsdl.org>
parents:
121
diff
changeset
|
56 #ifdef DMEDIA_SUPPORT |
8758b8d42cd9
Audio subsystem no longer assumes sun audio API on UNIX systems
Sam Lantinga <slouken@libsdl.org>
parents:
121
diff
changeset
|
57 &DMEDIA_bootstrap, |
35
d3bc792e136d
Added detection of Open Sound System on Solaris x86
Sam Lantinga <slouken@lokigames.com>
parents:
21
diff
changeset
|
58 #endif |
0 | 59 #ifdef ARTSC_SUPPORT |
60 &ARTSC_bootstrap, | |
61 #endif | |
62 #ifdef ESD_SUPPORT | |
63 &ESD_bootstrap, | |
64 #endif | |
65 #ifdef NAS_SUPPORT | |
66 &NAS_bootstrap, | |
67 #endif | |
68 #ifdef ENABLE_DIRECTX | |
69 &DSOUND_bootstrap, | |
70 #endif | |
71 #ifdef ENABLE_WINDIB | |
72 &WAVEOUT_bootstrap, | |
73 #endif | |
74 #ifdef __BEOS__ | |
75 &BAUDIO_bootstrap, | |
76 #endif | |
77 #if defined(macintosh) || TARGET_API_MAC_CARBON | |
78 &SNDMGR_bootstrap, | |
79 #endif | |
80 #ifdef _AIX | |
81 &Paud_bootstrap, | |
82 #endif | |
21
75a95f82bc1f
Updated the Amiga OS port of SDL (thanks Gabriele)
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
83 #ifdef ENABLE_AHI |
75a95f82bc1f
Updated the Amiga OS port of SDL (thanks Gabriele)
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
84 &AHI_bootstrap, |
75a95f82bc1f
Updated the Amiga OS port of SDL (thanks Gabriele)
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
85 #endif |
68
ac6645260d31
Added an audio driver that writes to disk (thanks Ryan!)
Sam Lantinga <slouken@lokigames.com>
parents:
38
diff
changeset
|
86 #ifdef DISKAUD_SUPPORT |
ac6645260d31
Added an audio driver that writes to disk (thanks Ryan!)
Sam Lantinga <slouken@lokigames.com>
parents:
38
diff
changeset
|
87 &DISKAUD_bootstrap, |
ac6645260d31
Added an audio driver that writes to disk (thanks Ryan!)
Sam Lantinga <slouken@lokigames.com>
parents:
38
diff
changeset
|
88 #endif |
0 | 89 NULL |
90 }; | |
91 SDL_AudioDevice *current_audio = NULL; | |
92 | |
93 /* Various local functions */ | |
94 int SDL_AudioInit(const char *driver_name); | |
95 void SDL_AudioQuit(void); | |
96 | |
21
75a95f82bc1f
Updated the Amiga OS port of SDL (thanks Gabriele)
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
97 #ifdef ENABLE_AHI |
75a95f82bc1f
Updated the Amiga OS port of SDL (thanks Gabriele)
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
98 static int audio_configured = 0; |
75a95f82bc1f
Updated the Amiga OS port of SDL (thanks Gabriele)
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
99 #endif |
0 | 100 |
101 /* The general mixing thread function */ | |
102 int SDL_RunAudio(void *audiop) | |
103 { | |
104 SDL_AudioDevice *audio = (SDL_AudioDevice *)audiop; | |
105 Uint8 *stream; | |
106 int stream_len; | |
107 void *udata; | |
108 void (*fill)(void *userdata,Uint8 *stream, int len); | |
109 int silence; | |
21
75a95f82bc1f
Updated the Amiga OS port of SDL (thanks Gabriele)
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
110 #ifdef ENABLE_AHI |
75a95f82bc1f
Updated the Amiga OS port of SDL (thanks Gabriele)
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
111 int started = 0; |
75a95f82bc1f
Updated the Amiga OS port of SDL (thanks Gabriele)
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
112 |
75a95f82bc1f
Updated the Amiga OS port of SDL (thanks Gabriele)
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
113 /* AmigaOS NEEDS that the audio driver is opened in the thread that uses it! */ |
75a95f82bc1f
Updated the Amiga OS port of SDL (thanks Gabriele)
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
114 |
75a95f82bc1f
Updated the Amiga OS port of SDL (thanks Gabriele)
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
115 D(bug("Task audio started audio struct:<%lx>...\n",audiop)); |
75a95f82bc1f
Updated the Amiga OS port of SDL (thanks Gabriele)
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
116 |
75a95f82bc1f
Updated the Amiga OS port of SDL (thanks Gabriele)
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
117 D(bug("Before Openaudio...")); |
75a95f82bc1f
Updated the Amiga OS port of SDL (thanks Gabriele)
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
118 if(audio->OpenAudio(audio, &audio->spec)==-1) |
75a95f82bc1f
Updated the Amiga OS port of SDL (thanks Gabriele)
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
119 { |
75a95f82bc1f
Updated the Amiga OS port of SDL (thanks Gabriele)
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
120 D(bug("Open audio failed...\n")); |
75a95f82bc1f
Updated the Amiga OS port of SDL (thanks Gabriele)
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
121 return(-1); |
75a95f82bc1f
Updated the Amiga OS port of SDL (thanks Gabriele)
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
122 } |
75a95f82bc1f
Updated the Amiga OS port of SDL (thanks Gabriele)
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
123 D(bug("OpenAudio...OK\n")); |
75a95f82bc1f
Updated the Amiga OS port of SDL (thanks Gabriele)
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
124 #endif |
0 | 125 |
126 /* Perform any thread setup */ | |
127 if ( audio->ThreadInit ) { | |
128 audio->ThreadInit(audio); | |
129 } | |
130 audio->threadid = SDL_ThreadID(); | |
131 | |
132 /* Set up the mixing function */ | |
133 fill = audio->spec.callback; | |
134 udata = audio->spec.userdata; | |
21
75a95f82bc1f
Updated the Amiga OS port of SDL (thanks Gabriele)
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
135 |
75a95f82bc1f
Updated the Amiga OS port of SDL (thanks Gabriele)
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
136 #ifdef ENABLE_AHI |
75a95f82bc1f
Updated the Amiga OS port of SDL (thanks Gabriele)
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
137 audio_configured = 1; |
75a95f82bc1f
Updated the Amiga OS port of SDL (thanks Gabriele)
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
138 |
75a95f82bc1f
Updated the Amiga OS port of SDL (thanks Gabriele)
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
139 D(bug("Audio configured... Checking for conversion\n")); |
75a95f82bc1f
Updated the Amiga OS port of SDL (thanks Gabriele)
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
140 SDL_mutexP(audio->mixer_lock); |
75a95f82bc1f
Updated the Amiga OS port of SDL (thanks Gabriele)
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
141 D(bug("Semaphore obtained...\n")); |
75a95f82bc1f
Updated the Amiga OS port of SDL (thanks Gabriele)
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
142 #endif |
75a95f82bc1f
Updated the Amiga OS port of SDL (thanks Gabriele)
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
143 |
0 | 144 if ( audio->convert.needed ) { |
145 if ( audio->convert.src_format == AUDIO_U8 ) { | |
146 silence = 0x80; | |
147 } else { | |
148 silence = 0; | |
149 } | |
150 stream_len = audio->convert.len; | |
151 } else { | |
152 silence = audio->spec.silence; | |
153 stream_len = audio->spec.size; | |
154 } | |
155 stream = audio->fake_stream; | |
156 | |
21
75a95f82bc1f
Updated the Amiga OS port of SDL (thanks Gabriele)
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
157 #ifdef ENABLE_AHI |
75a95f82bc1f
Updated the Amiga OS port of SDL (thanks Gabriele)
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
158 SDL_mutexV(audio->mixer_lock); |
75a95f82bc1f
Updated the Amiga OS port of SDL (thanks Gabriele)
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
159 D(bug("Entering audio loop...\n")); |
75a95f82bc1f
Updated the Amiga OS port of SDL (thanks Gabriele)
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
160 #endif |
75a95f82bc1f
Updated the Amiga OS port of SDL (thanks Gabriele)
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
161 |
75a95f82bc1f
Updated the Amiga OS port of SDL (thanks Gabriele)
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
162 |
0 | 163 /* Loop, filling the audio buffers */ |
164 while ( audio->enabled ) { | |
165 | |
166 /* Wait for new current buffer to finish playing */ | |
167 if ( stream == audio->fake_stream ) { | |
168 SDL_Delay((audio->spec.samples*1000)/audio->spec.freq); | |
169 } else { | |
21
75a95f82bc1f
Updated the Amiga OS port of SDL (thanks Gabriele)
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
170 #ifdef ENABLE_AHI |
75a95f82bc1f
Updated the Amiga OS port of SDL (thanks Gabriele)
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
171 if ( started > 1 ) |
75a95f82bc1f
Updated the Amiga OS port of SDL (thanks Gabriele)
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
172 #endif |
0 | 173 audio->WaitAudio(audio); |
174 } | |
175 | |
176 /* Fill the current buffer with sound */ | |
177 if ( audio->convert.needed ) { | |
178 if ( audio->convert.buf ) { | |
179 stream = audio->convert.buf; | |
180 } else { | |
181 continue; | |
182 } | |
183 } else { | |
184 stream = audio->GetAudioBuf(audio); | |
185 if ( stream == NULL ) { | |
186 stream = audio->fake_stream; | |
187 } | |
188 } | |
189 memset(stream, silence, stream_len); | |
190 | |
191 if ( ! audio->paused ) { | |
192 SDL_mutexP(audio->mixer_lock); | |
193 (*fill)(udata, stream, stream_len); | |
194 SDL_mutexV(audio->mixer_lock); | |
195 } | |
196 | |
197 /* Convert the audio if necessary */ | |
198 if ( audio->convert.needed ) { | |
199 SDL_ConvertAudio(&audio->convert); | |
200 stream = audio->GetAudioBuf(audio); | |
201 if ( stream == NULL ) { | |
202 stream = audio->fake_stream; | |
203 } | |
204 memcpy(stream, audio->convert.buf, | |
205 audio->convert.len_cvt); | |
206 } | |
207 | |
208 /* Ready current buffer for play and change current buffer */ | |
209 if ( stream != audio->fake_stream ) { | |
210 audio->PlayAudio(audio); | |
21
75a95f82bc1f
Updated the Amiga OS port of SDL (thanks Gabriele)
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
211 #ifdef ENABLE_AHI |
75a95f82bc1f
Updated the Amiga OS port of SDL (thanks Gabriele)
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
212 /* AmigaOS don't have to wait the first time audio is played! */ |
75a95f82bc1f
Updated the Amiga OS port of SDL (thanks Gabriele)
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
213 started++; |
75a95f82bc1f
Updated the Amiga OS port of SDL (thanks Gabriele)
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
214 #endif |
0 | 215 } |
216 } | |
217 /* Wait for the audio to drain.. */ | |
218 if ( audio->WaitDone ) { | |
219 audio->WaitDone(audio); | |
220 } | |
21
75a95f82bc1f
Updated the Amiga OS port of SDL (thanks Gabriele)
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
221 |
75a95f82bc1f
Updated the Amiga OS port of SDL (thanks Gabriele)
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
222 #ifdef ENABLE_AHI |
75a95f82bc1f
Updated the Amiga OS port of SDL (thanks Gabriele)
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
223 D(bug("WaitAudio...Done\n")); |
75a95f82bc1f
Updated the Amiga OS port of SDL (thanks Gabriele)
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
224 |
75a95f82bc1f
Updated the Amiga OS port of SDL (thanks Gabriele)
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
225 audio->CloseAudio(audio); |
75a95f82bc1f
Updated the Amiga OS port of SDL (thanks Gabriele)
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
226 |
75a95f82bc1f
Updated the Amiga OS port of SDL (thanks Gabriele)
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
227 D(bug("CloseAudio..Done, subtask exiting...\n")); |
75a95f82bc1f
Updated the Amiga OS port of SDL (thanks Gabriele)
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
228 audio_configured = 0; |
75a95f82bc1f
Updated the Amiga OS port of SDL (thanks Gabriele)
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
229 #endif |
0 | 230 return(0); |
231 } | |
232 | |
233 int SDL_AudioInit(const char *driver_name) | |
234 { | |
235 SDL_AudioDevice *audio; | |
236 int i = 0, idx; | |
237 | |
238 /* Check to make sure we don't overwrite 'current_audio' */ | |
239 if ( current_audio != NULL ) { | |
240 SDL_AudioQuit(); | |
241 } | |
242 | |
243 /* Select the proper audio driver */ | |
244 audio = NULL; | |
245 idx = 0; | |
246 #ifdef unix | |
247 if ( (driver_name == NULL) && (getenv("ESPEAKER") != NULL) ) { | |
248 /* Ahem, we know that if ESPEAKER is set, user probably wants | |
249 to use ESD, but don't start it if it's not already running. | |
250 This probably isn't the place to do this, but... Shh! :) | |
251 */ | |
252 for ( i=0; bootstrap[i]; ++i ) { | |
253 if ( strcmp(bootstrap[i]->name, "esd") == 0 ) { | |
254 const char *esd_no_spawn; | |
255 | |
256 /* Don't start ESD if it's not running */ | |
257 esd_no_spawn = getenv("ESD_NO_SPAWN"); | |
258 if ( esd_no_spawn == NULL ) { | |
259 putenv("ESD_NO_SPAWN=1"); | |
260 } | |
261 if ( bootstrap[i]->available() ) { | |
262 audio = bootstrap[i]->create(0); | |
263 break; | |
264 } | |
265 #ifdef linux /* No unsetenv() on most platforms */ | |
266 if ( esd_no_spawn == NULL ) { | |
267 unsetenv("ESD_NO_SPAWN"); | |
268 } | |
269 #endif | |
270 } | |
271 } | |
272 } | |
273 #endif /* unix */ | |
274 if ( audio == NULL ) { | |
275 if ( driver_name != NULL ) { | |
276 #if 0 /* This will be replaced with a better driver selection API */ | |
277 if ( strrchr(driver_name, ':') != NULL ) { | |
278 idx = atoi(strrchr(driver_name, ':')+1); | |
279 } | |
280 #endif | |
281 for ( i=0; bootstrap[i]; ++i ) { | |
282 if (strncmp(bootstrap[i]->name, driver_name, | |
283 strlen(bootstrap[i]->name)) == 0) { | |
284 if ( bootstrap[i]->available() ) { | |
285 audio=bootstrap[i]->create(idx); | |
286 break; | |
287 } | |
288 } | |
289 } | |
290 } else { | |
291 for ( i=0; bootstrap[i]; ++i ) { | |
292 if ( bootstrap[i]->available() ) { | |
293 audio = bootstrap[i]->create(idx); | |
294 if ( audio != NULL ) { | |
295 break; | |
296 } | |
297 } | |
298 } | |
299 } | |
300 if ( audio == NULL ) { | |
301 SDL_SetError("No available audio device"); | |
302 #if 0 /* Don't fail SDL_Init() if audio isn't available. | |
303 SDL_OpenAudio() will handle it at that point. *sigh* | |
304 */ | |
305 return(-1); | |
306 #endif | |
307 } | |
308 } | |
309 current_audio = audio; | |
310 if ( current_audio ) { | |
311 current_audio->name = bootstrap[i]->name; | |
312 } | |
313 return(0); | |
314 } | |
315 | |
316 char *SDL_AudioDriverName(char *namebuf, int maxlen) | |
317 { | |
318 if ( current_audio != NULL ) { | |
319 strncpy(namebuf, current_audio->name, maxlen-1); | |
320 namebuf[maxlen-1] = '\0'; | |
321 return(namebuf); | |
322 } | |
323 return(NULL); | |
324 } | |
325 | |
326 int SDL_OpenAudio(SDL_AudioSpec *desired, SDL_AudioSpec *obtained) | |
327 { | |
328 SDL_AudioDevice *audio; | |
329 | |
330 /* Start up the audio driver, if necessary */ | |
331 if ( ! current_audio ) { | |
332 if ( (SDL_InitSubSystem(SDL_INIT_AUDIO) < 0) || | |
333 (current_audio == NULL) ) { | |
334 return(-1); | |
335 } | |
336 } | |
337 audio = current_audio; | |
338 | |
262
ba5363e21df8
Don't allow multiple audio opens to succeed (until SDL 1.3)
Sam Lantinga <slouken@libsdl.org>
parents:
252
diff
changeset
|
339 if (audio->opened) { |
ba5363e21df8
Don't allow multiple audio opens to succeed (until SDL 1.3)
Sam Lantinga <slouken@libsdl.org>
parents:
252
diff
changeset
|
340 SDL_SetError("Audio device is already opened"); |
ba5363e21df8
Don't allow multiple audio opens to succeed (until SDL 1.3)
Sam Lantinga <slouken@libsdl.org>
parents:
252
diff
changeset
|
341 return(-1); |
ba5363e21df8
Don't allow multiple audio opens to succeed (until SDL 1.3)
Sam Lantinga <slouken@libsdl.org>
parents:
252
diff
changeset
|
342 } |
ba5363e21df8
Don't allow multiple audio opens to succeed (until SDL 1.3)
Sam Lantinga <slouken@libsdl.org>
parents:
252
diff
changeset
|
343 |
0 | 344 /* Verify some parameters */ |
345 if ( desired->callback == NULL ) { | |
346 SDL_SetError("SDL_OpenAudio() passed a NULL callback"); | |
347 return(-1); | |
348 } | |
349 switch ( desired->channels ) { | |
350 case 1: /* Mono */ | |
351 case 2: /* Stereo */ | |
352 break; | |
353 default: | |
354 SDL_SetError("1 (mono) and 2 (stereo) channels supported"); | |
355 return(-1); | |
356 } | |
357 | |
358 #ifdef macintosh | |
359 /* FIXME: Need to implement PPC interrupt asm for SDL_LockAudio() */ | |
360 #else | |
361 /* Create a semaphore for locking the sound buffers */ | |
362 audio->mixer_lock = SDL_CreateMutex(); | |
363 if ( audio->mixer_lock == NULL ) { | |
364 SDL_SetError("Couldn't create mixer lock"); | |
365 SDL_CloseAudio(); | |
366 return(-1); | |
367 } | |
368 #endif | |
369 | |
370 /* Calculate the silence and size of the audio specification */ | |
371 SDL_CalculateAudioSpec(desired); | |
372 | |
373 /* Open the audio subsystem */ | |
374 memcpy(&audio->spec, desired, sizeof(audio->spec)); | |
375 audio->convert.needed = 0; | |
376 audio->enabled = 1; | |
377 audio->paused = 1; | |
21
75a95f82bc1f
Updated the Amiga OS port of SDL (thanks Gabriele)
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
378 |
75a95f82bc1f
Updated the Amiga OS port of SDL (thanks Gabriele)
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
379 #ifndef ENABLE_AHI |
75a95f82bc1f
Updated the Amiga OS port of SDL (thanks Gabriele)
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
380 |
75a95f82bc1f
Updated the Amiga OS port of SDL (thanks Gabriele)
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
381 /* AmigaOS opens audio inside the main loop */ |
0 | 382 audio->opened = audio->OpenAudio(audio, &audio->spec)+1; |
21
75a95f82bc1f
Updated the Amiga OS port of SDL (thanks Gabriele)
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
383 |
0 | 384 if ( ! audio->opened ) { |
385 SDL_CloseAudio(); | |
386 return(-1); | |
387 } | |
21
75a95f82bc1f
Updated the Amiga OS port of SDL (thanks Gabriele)
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
388 #else |
75a95f82bc1f
Updated the Amiga OS port of SDL (thanks Gabriele)
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
389 D(bug("Locking semaphore...")); |
75a95f82bc1f
Updated the Amiga OS port of SDL (thanks Gabriele)
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
390 SDL_mutexP(audio->mixer_lock); |
75a95f82bc1f
Updated the Amiga OS port of SDL (thanks Gabriele)
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
391 |
75a95f82bc1f
Updated the Amiga OS port of SDL (thanks Gabriele)
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
392 audio->thread = SDL_CreateThread(SDL_RunAudio, audio); |
75a95f82bc1f
Updated the Amiga OS port of SDL (thanks Gabriele)
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
393 D(bug("Created thread...\n")); |
75a95f82bc1f
Updated the Amiga OS port of SDL (thanks Gabriele)
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
394 |
75a95f82bc1f
Updated the Amiga OS port of SDL (thanks Gabriele)
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
395 if ( audio->thread == NULL ) { |
75a95f82bc1f
Updated the Amiga OS port of SDL (thanks Gabriele)
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
396 SDL_mutexV(audio->mixer_lock); |
75a95f82bc1f
Updated the Amiga OS port of SDL (thanks Gabriele)
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
397 SDL_CloseAudio(); |
75a95f82bc1f
Updated the Amiga OS port of SDL (thanks Gabriele)
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
398 SDL_SetError("Couldn't create audio thread"); |
75a95f82bc1f
Updated the Amiga OS port of SDL (thanks Gabriele)
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
399 return(-1); |
75a95f82bc1f
Updated the Amiga OS port of SDL (thanks Gabriele)
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
400 } |
75a95f82bc1f
Updated the Amiga OS port of SDL (thanks Gabriele)
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
401 |
75a95f82bc1f
Updated the Amiga OS port of SDL (thanks Gabriele)
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
402 while(!audio_configured) |
75a95f82bc1f
Updated the Amiga OS port of SDL (thanks Gabriele)
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
403 SDL_Delay(100); |
75a95f82bc1f
Updated the Amiga OS port of SDL (thanks Gabriele)
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
404 #endif |
0 | 405 |
406 /* If the audio driver changes the buffer size, accept it */ | |
407 if ( audio->spec.samples != desired->samples ) { | |
408 desired->samples = audio->spec.samples; | |
409 SDL_CalculateAudioSpec(desired); | |
410 } | |
411 | |
412 /* Allocate a fake audio memory buffer */ | |
413 audio->fake_stream = SDL_AllocAudioMem(audio->spec.size); | |
414 if ( audio->fake_stream == NULL ) { | |
415 SDL_CloseAudio(); | |
416 SDL_OutOfMemory(); | |
417 return(-1); | |
418 } | |
419 | |
420 /* See if we need to do any conversion */ | |
421 if ( memcmp(desired, &audio->spec, sizeof(audio->spec)) == 0 ) { | |
422 /* Just copy over the desired audio specification */ | |
423 if ( obtained != NULL ) { | |
424 memcpy(obtained, &audio->spec, sizeof(audio->spec)); | |
425 } | |
426 } else { | |
427 /* Copy over the audio specification if possible */ | |
428 if ( obtained != NULL ) { | |
429 memcpy(obtained, &audio->spec, sizeof(audio->spec)); | |
430 } else { | |
431 /* Build an audio conversion block */ | |
432 if ( SDL_BuildAudioCVT(&audio->convert, | |
433 desired->format, desired->channels, | |
434 desired->freq, | |
435 audio->spec.format, audio->spec.channels, | |
436 audio->spec.freq) < 0 ) { | |
437 SDL_CloseAudio(); | |
438 return(-1); | |
439 } | |
440 if ( audio->convert.needed ) { | |
441 audio->convert.len = desired->size; | |
442 audio->convert.buf =(Uint8 *)SDL_AllocAudioMem( | |
443 audio->convert.len*audio->convert.len_mult); | |
444 if ( audio->convert.buf == NULL ) { | |
445 SDL_CloseAudio(); | |
446 SDL_OutOfMemory(); | |
447 return(-1); | |
448 } | |
449 } | |
450 } | |
451 } | |
452 | |
21
75a95f82bc1f
Updated the Amiga OS port of SDL (thanks Gabriele)
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
453 #ifndef ENABLE_AHI |
0 | 454 /* Start the audio thread if necessary */ |
455 switch (audio->opened) { | |
456 case 1: | |
457 /* Start the audio thread */ | |
458 audio->thread = SDL_CreateThread(SDL_RunAudio, audio); | |
459 if ( audio->thread == NULL ) { | |
460 SDL_CloseAudio(); | |
461 SDL_SetError("Couldn't create audio thread"); | |
462 return(-1); | |
463 } | |
464 break; | |
465 | |
466 default: | |
467 /* The audio is now playing */ | |
468 break; | |
469 } | |
21
75a95f82bc1f
Updated the Amiga OS port of SDL (thanks Gabriele)
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
470 #else |
75a95f82bc1f
Updated the Amiga OS port of SDL (thanks Gabriele)
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
471 SDL_mutexV(audio->mixer_lock); |
75a95f82bc1f
Updated the Amiga OS port of SDL (thanks Gabriele)
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
472 D(bug("SDL_OpenAudio USCITA...\n")); |
75a95f82bc1f
Updated the Amiga OS port of SDL (thanks Gabriele)
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
473 |
75a95f82bc1f
Updated the Amiga OS port of SDL (thanks Gabriele)
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
474 #endif |
75a95f82bc1f
Updated the Amiga OS port of SDL (thanks Gabriele)
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
475 |
0 | 476 return(0); |
477 } | |
478 | |
479 SDL_audiostatus SDL_GetAudioStatus(void) | |
480 { | |
481 SDL_AudioDevice *audio = current_audio; | |
482 SDL_audiostatus status; | |
483 | |
484 status = SDL_AUDIO_STOPPED; | |
485 if ( audio && audio->enabled ) { | |
486 if ( audio->paused ) { | |
487 status = SDL_AUDIO_PAUSED; | |
488 } else { | |
489 status = SDL_AUDIO_PLAYING; | |
490 } | |
491 } | |
492 return(status); | |
493 } | |
494 | |
495 void SDL_PauseAudio (int pause_on) | |
496 { | |
497 SDL_AudioDevice *audio = current_audio; | |
498 | |
499 if ( audio ) { | |
500 audio->paused = pause_on; | |
501 } | |
502 } | |
503 | |
504 void SDL_LockAudio (void) | |
505 { | |
506 SDL_AudioDevice *audio = current_audio; | |
507 | |
508 /* Obtain a lock on the mixing buffers */ | |
509 if ( audio ) { | |
510 if ( audio->thread && (SDL_ThreadID() == audio->threadid) ) { | |
511 return; | |
512 } | |
513 SDL_mutexP(audio->mixer_lock); | |
514 } | |
515 } | |
516 | |
517 void SDL_UnlockAudio (void) | |
518 { | |
519 SDL_AudioDevice *audio = current_audio; | |
520 | |
521 /* Release lock on the mixing buffers */ | |
522 if ( audio ) { | |
523 if ( audio->thread && (SDL_ThreadID() == audio->threadid) ) { | |
524 return; | |
525 } | |
526 SDL_mutexV(audio->mixer_lock); | |
527 } | |
528 } | |
529 | |
530 void SDL_CloseAudio (void) | |
531 { | |
532 SDL_QuitSubSystem(SDL_INIT_AUDIO); | |
533 } | |
534 | |
535 void SDL_AudioQuit(void) | |
536 { | |
537 SDL_AudioDevice *audio = current_audio; | |
538 | |
539 if ( audio ) { | |
540 audio->enabled = 0; | |
541 if ( audio->thread != NULL ) { | |
542 SDL_WaitThread(audio->thread, NULL); | |
543 } | |
544 if ( audio->mixer_lock != NULL ) { | |
545 SDL_DestroyMutex(audio->mixer_lock); | |
546 } | |
547 if ( audio->fake_stream != NULL ) { | |
548 SDL_FreeAudioMem(audio->fake_stream); | |
549 } | |
550 if ( audio->convert.needed ) { | |
551 SDL_FreeAudioMem(audio->convert.buf); | |
21
75a95f82bc1f
Updated the Amiga OS port of SDL (thanks Gabriele)
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
552 |
0 | 553 } |
21
75a95f82bc1f
Updated the Amiga OS port of SDL (thanks Gabriele)
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
554 #ifndef ENABLE_AHI |
0 | 555 if ( audio->opened ) { |
556 audio->CloseAudio(audio); | |
557 audio->opened = 0; | |
558 } | |
21
75a95f82bc1f
Updated the Amiga OS port of SDL (thanks Gabriele)
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
559 #endif |
0 | 560 /* Free the driver data */ |
561 audio->free(audio); | |
562 current_audio = NULL; | |
563 } | |
564 } | |
565 | |
566 #define NUM_FORMATS 6 | |
567 static int format_idx; | |
568 static int format_idx_sub; | |
569 static Uint16 format_list[NUM_FORMATS][NUM_FORMATS] = { | |
570 { AUDIO_U8, AUDIO_S8, AUDIO_S16LSB, AUDIO_S16MSB, AUDIO_U16LSB, AUDIO_U16MSB }, | |
571 { AUDIO_S8, AUDIO_U8, AUDIO_S16LSB, AUDIO_S16MSB, AUDIO_U16LSB, AUDIO_U16MSB }, | |
572 { AUDIO_S16LSB, AUDIO_S16MSB, AUDIO_U16LSB, AUDIO_U16MSB, AUDIO_U8, AUDIO_S8 }, | |
573 { AUDIO_S16MSB, AUDIO_S16LSB, AUDIO_U16MSB, AUDIO_U16LSB, AUDIO_U8, AUDIO_S8 }, | |
574 { AUDIO_U16LSB, AUDIO_U16MSB, AUDIO_S16LSB, AUDIO_S16MSB, AUDIO_U8, AUDIO_S8 }, | |
575 { AUDIO_U16MSB, AUDIO_U16LSB, AUDIO_S16MSB, AUDIO_S16LSB, AUDIO_U8, AUDIO_S8 }, | |
576 }; | |
577 | |
578 Uint16 SDL_FirstAudioFormat(Uint16 format) | |
579 { | |
580 for ( format_idx=0; format_idx < NUM_FORMATS; ++format_idx ) { | |
581 if ( format_list[format_idx][0] == format ) { | |
582 break; | |
583 } | |
584 } | |
585 format_idx_sub = 0; | |
586 return(SDL_NextAudioFormat()); | |
587 } | |
588 | |
589 Uint16 SDL_NextAudioFormat(void) | |
590 { | |
591 if ( (format_idx == NUM_FORMATS) || (format_idx_sub == NUM_FORMATS) ) { | |
592 return(0); | |
593 } | |
594 return(format_list[format_idx][format_idx_sub++]); | |
595 } | |
596 | |
597 void SDL_CalculateAudioSpec(SDL_AudioSpec *spec) | |
598 { | |
599 switch (spec->format) { | |
600 case AUDIO_U8: | |
601 spec->silence = 0x80; | |
602 break; | |
603 default: | |
604 spec->silence = 0x00; | |
605 break; | |
606 } | |
607 spec->size = (spec->format&0xFF)/8; | |
608 spec->size *= spec->channels; | |
609 spec->size *= spec->samples; | |
610 } |