Mercurial > sdl-ios-xcode
comparison src/audio/mint/SDL_mintaudio_stfa.c @ 3820:1f156fd874fa SDL-ryan-multiple-audio-device
Moved more audio drivers to 1.3 API (all 5 MiNT backends, BSD, IRIX...), and
some other tweaks in already-converted drivers.
author | Ryan C. Gordon <icculus@icculus.org> |
---|---|
date | Sat, 07 Oct 2006 05:36:36 +0000 |
parents | c8b3d3d13ed1 |
children | 66fb40445587 |
comparison
equal
deleted
inserted
replaced
3819:b225d9820ee3 | 3820:1f156fd874fa |
---|---|
57 #define DEBUG_PRINT(what) | 57 #define DEBUG_PRINT(what) |
58 #endif | 58 #endif |
59 | 59 |
60 /*--- Static variables ---*/ | 60 /*--- Static variables ---*/ |
61 | 61 |
62 static unsigned long cookie_snd, cookie_mch; | 62 static unsigned long cookie_snd = 0; |
63 static cookie_stfa_t *cookie_stfa; | 63 static unsigned long cookie_mch = 0; |
64 static cookie_stfa_t *cookie_stfa = NULL; | |
64 | 65 |
65 static const int freqs[16] = { | 66 static const int freqs[16] = { |
66 4995, 6269, 7493, 8192, | 67 4995, 6269, 7493, 8192, |
67 9830, 10971, 12538, 14985, | 68 9830, 10971, 12538, 14985, |
68 16384, 19819, 21943, 24576, | 69 16384, 19819, 21943, 24576, |
69 30720, 32336, 43885, 49152 | 70 30720, 32336, 43885, 49152 |
70 }; | 71 }; |
71 | 72 |
72 /*--- Audio driver functions ---*/ | |
73 | |
74 static void Mint_CloseAudio(_THIS); | |
75 static int Mint_OpenAudio(_THIS, SDL_AudioSpec * spec); | |
76 static void Mint_LockAudio(_THIS); | |
77 static void Mint_UnlockAudio(_THIS); | |
78 | |
79 /* To check/init hardware audio */ | |
80 static int Mint_CheckAudio(_THIS, SDL_AudioSpec * spec); | |
81 static void Mint_InitAudio(_THIS, SDL_AudioSpec * spec); | |
82 | |
83 /*--- Audio driver bootstrap functions ---*/ | |
84 | |
85 static int | 73 static int |
86 Audio_Available(void) | 74 MINTSTFA_Available(void) |
87 { | 75 { |
88 const char *envr = SDL_getenv("SDL_AUDIODRIVER"); | |
89 | |
90 /* Check if user asked a different audio driver */ | |
91 if ((envr) && (SDL_strcmp(envr, MINT_AUDIO_DRIVER_NAME) != 0)) { | |
92 DEBUG_PRINT((DEBUG_NAME "user asked a different audio driver\n")); | |
93 return (0); | |
94 } | |
95 | |
96 /* Cookie _MCH present ? if not, assume ST machine */ | 76 /* Cookie _MCH present ? if not, assume ST machine */ |
97 if (Getcookie(C__MCH, &cookie_mch) == C_NOTFOUND) { | 77 if (Getcookie(C__MCH, &cookie_mch) == C_NOTFOUND) { |
98 cookie_mch = MCH_ST; | 78 cookie_mch = MCH_ST; |
99 } | 79 } |
100 | 80 |
114 DEBUG_PRINT((DEBUG_NAME "STFA audio available!\n")); | 94 DEBUG_PRINT((DEBUG_NAME "STFA audio available!\n")); |
115 return (1); | 95 return (1); |
116 } | 96 } |
117 | 97 |
118 static void | 98 static void |
119 Audio_DeleteDevice(SDL_AudioDevice * device) | 99 MINTSTFA_LockDevice(_THIS) |
120 { | 100 { |
121 SDL_free(device->hidden); | |
122 SDL_free(device); | |
123 } | |
124 | |
125 static SDL_AudioDevice * | |
126 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 /* Uses interrupt driven audio, without thread */ | |
154 #if SDL_THREADS_DISABLED | |
155 this->SkipMixerLock = 1; | |
156 #endif | |
157 | |
158 return this; | |
159 } | |
160 | |
161 AudioBootStrap MINTAUDIO_STFA_bootstrap = { | |
162 MINT_AUDIO_DRIVER_NAME, "MiNT STFA audio driver", | |
163 Audio_Available, Audio_CreateDevice, 0 | |
164 }; | |
165 | |
166 static void | |
167 Mint_LockAudio(_THIS) | |
168 { | |
169 void *oldpile; | |
170 | |
171 /* Stop replay */ | 101 /* Stop replay */ |
172 oldpile = (void *) Super(0); | 102 void *oldpile = (void *) Super(0); |
173 cookie_stfa->sound_enable = STFA_PLAY_DISABLE; | 103 cookie_stfa->sound_enable = STFA_PLAY_DISABLE; |
174 Super(oldpile); | 104 Super(oldpile); |
175 } | 105 } |
176 | 106 |
177 static void | 107 static void |
178 Mint_UnlockAudio(_THIS) | 108 MINTSTFA_UnlockDevice(_THIS) |
179 { | 109 { |
180 void *oldpile; | |
181 | |
182 /* Restart replay */ | 110 /* Restart replay */ |
183 oldpile = (void *) Super(0); | 111 void *oldpile = (void *) Super(0); |
184 cookie_stfa->sound_enable = STFA_PLAY_ENABLE | STFA_PLAY_REPEAT; | 112 cookie_stfa->sound_enable = STFA_PLAY_ENABLE | STFA_PLAY_REPEAT; |
185 Super(oldpile); | 113 Super(oldpile); |
186 } | 114 } |
187 | 115 |
188 static void | 116 static void |
189 Mint_CloseAudio(_THIS) | 117 MINTSTFA_CloseDevice(_THIS) |
190 { | 118 { |
191 void *oldpile; | 119 if (this->hidden != NULL) { |
192 | 120 /* Stop replay */ |
193 /* Stop replay */ | 121 void *oldpile = (void *) Super(0); |
194 oldpile = (void *) Super(0); | 122 cookie_stfa->sound_enable = STFA_PLAY_DISABLE; |
195 cookie_stfa->sound_enable = STFA_PLAY_DISABLE; | 123 Super(oldpile); |
196 Super(oldpile); | 124 |
197 | 125 /* Wait if currently playing sound */ |
198 /* Wait if currently playing sound */ | 126 while (SDL_MintAudio_mutex != 0) {} |
199 while (SDL_MintAudio_mutex != 0) { | 127 |
200 } | 128 /* Clear buffers */ |
201 | 129 if (SDL_MintAudio_audiobuf[0]) { |
202 /* Clear buffers */ | 130 Mfree(SDL_MintAudio_audiobuf[0]); |
203 if (SDL_MintAudio_audiobuf[0]) { | 131 SDL_MintAudio_audiobuf[0] = SDL_MintAudio_audiobuf[1] = NULL; |
204 Mfree(SDL_MintAudio_audiobuf[0]); | 132 } |
205 SDL_MintAudio_audiobuf[0] = SDL_MintAudio_audiobuf[1] = NULL; | 133 |
134 SDL_free(this->hidden); | |
135 this->hidden = NULL; | |
206 } | 136 } |
207 } | 137 } |
208 | 138 |
209 static int | 139 static int |
210 Mint_CheckAudio(_THIS, SDL_AudioSpec * spec) | 140 MINTSTFA_CheckAudio(_THIS) |
211 { | 141 { |
212 int i; | 142 int i; |
213 | 143 |
214 DEBUG_PRINT((DEBUG_NAME "asked: %d bits, ", | 144 DEBUG_PRINT((DEBUG_NAME "asked: %d bits, ", |
215 SDL_AUDIO_BITSIZE(spec->format))); | 145 SDL_AUDIO_BITSIZE(this->spec.format))); |
216 DEBUG_PRINT(("float=%d, ", SDL_AUDIO_ISFLOAT(spec->format))); | 146 DEBUG_PRINT(("float=%d, ", SDL_AUDIO_ISFLOAT(this->spec.format))); |
217 DEBUG_PRINT(("signed=%d, ", SDL_AUDIO_ISSIGNED(spec->format))); | 147 DEBUG_PRINT(("signed=%d, ", SDL_AUDIO_ISSIGNED(this->spec.format))); |
218 DEBUG_PRINT(("big endian=%d, ", SDL_AUDIO_ISBIGENDIAN(spec->format))); | 148 DEBUG_PRINT(("big endian=%d, ", SDL_AUDIO_ISBIGENDIAN(this->spec.format))); |
219 DEBUG_PRINT(("channels=%d, ", spec->channels)); | 149 DEBUG_PRINT(("channels=%d, ", this->spec.channels)); |
220 DEBUG_PRINT(("freq=%d\n", spec->freq)); | 150 DEBUG_PRINT(("freq=%d\n", this->spec.freq)); |
221 | 151 |
222 if (SDL_AUDIO_BITSIZE(spec->format) > 16) { | 152 if (SDL_AUDIO_BITSIZE(this->spec.format) > 16) { |
223 spec->format = AUDIO_S16SYS; /* clamp out int32/float32 ... */ | 153 this->spec.format = AUDIO_S16SYS; /* clamp out int32/float32 ... */ |
224 } | 154 } |
225 | 155 |
226 if (spec->channels > 2) { | 156 if (this->spec.channels > 2) { |
227 spec->channels = 2; /* no more than stereo! */ | 157 this->spec.channels = 2; /* no more than stereo! */ |
228 } | 158 } |
229 | 159 |
230 /* Check formats available */ | 160 /* Check formats available */ |
231 MINTAUDIO_freqcount = 0; | 161 MINTAUDIO_freqcount = 0; |
232 for (i = 0; i < 16; i++) { | 162 for (i = 0; i < 16; i++) { |
240 MINTAUDIO_frequencies[i].masterclock, | 170 MINTAUDIO_frequencies[i].masterclock, |
241 MINTAUDIO_frequencies[i].predivisor)); | 171 MINTAUDIO_frequencies[i].predivisor)); |
242 } | 172 } |
243 #endif | 173 #endif |
244 | 174 |
245 MINTAUDIO_numfreq = SDL_MintAudio_SearchFrequency(this, spec->freq); | 175 MINTAUDIO_numfreq = SDL_MintAudio_SearchFrequency(this, this->spec.freq); |
246 spec->freq = MINTAUDIO_frequencies[MINTAUDIO_numfreq].frequency; | 176 this->spec.freq = MINTAUDIO_frequencies[MINTAUDIO_numfreq].frequency; |
247 | 177 |
248 DEBUG_PRINT((DEBUG_NAME "obtained: %d bits, ", | 178 DEBUG_PRINT((DEBUG_NAME "obtained: %d bits, ", |
249 SDL_AUDIO_BITSIZE(spec->format))); | 179 SDL_AUDIO_BITSIZE(this->spec.format))); |
250 DEBUG_PRINT(("float=%d, ", SDL_AUDIO_ISFLOAT(spec->format))); | 180 DEBUG_PRINT(("float=%d, ", SDL_AUDIO_ISFLOAT(this->spec.format))); |
251 DEBUG_PRINT(("signed=%d, ", SDL_AUDIO_ISSIGNED(spec->format))); | 181 DEBUG_PRINT(("signed=%d, ", SDL_AUDIO_ISSIGNED(this->spec.format))); |
252 DEBUG_PRINT(("big endian=%d, ", SDL_AUDIO_ISBIGENDIAN(spec->format))); | 182 DEBUG_PRINT(("big endian=%d, ", SDL_AUDIO_ISBIGENDIAN(this->spec.format))); |
253 DEBUG_PRINT(("channels=%d, ", spec->channels)); | 183 DEBUG_PRINT(("channels=%d, ", this->spec.channels)); |
254 DEBUG_PRINT(("freq=%d\n", spec->freq)); | 184 DEBUG_PRINT(("freq=%d\n", this->spec.freq)); |
255 | 185 |
256 return 0; | 186 return 0; |
257 } | 187 } |
258 | 188 |
259 static void | 189 static void |
260 Mint_InitAudio(_THIS, SDL_AudioSpec * spec) | 190 MINTSTFA_InitAudio(_THIS) |
261 { | 191 { |
262 void *buffer; | 192 void *buffer = SDL_MintAudio_audiobuf[SDL_MintAudio_numbuf]; |
263 void *oldpile; | 193 void *oldpile = (void *) Super(0); |
264 | |
265 buffer = SDL_MintAudio_audiobuf[SDL_MintAudio_numbuf]; | |
266 | |
267 oldpile = (void *) Super(0); | |
268 | 194 |
269 /* Stop replay */ | 195 /* Stop replay */ |
270 cookie_stfa->sound_enable = STFA_PLAY_DISABLE; | 196 cookie_stfa->sound_enable = STFA_PLAY_DISABLE; |
271 | 197 |
272 /* Select replay format */ | 198 /* Select replay format */ |
273 cookie_stfa->sound_control = | 199 cookie_stfa->sound_control = |
274 MINTAUDIO_frequencies[MINTAUDIO_numfreq].predivisor; | 200 MINTAUDIO_frequencies[MINTAUDIO_numfreq].predivisor; |
275 if (SDL_AUDIO_BITSIZE(spec->format) == 8) { | 201 if (SDL_AUDIO_BITSIZE(this->spec.format) == 8) { |
276 cookie_stfa->sound_control |= STFA_FORMAT_8BIT; | 202 cookie_stfa->sound_control |= STFA_FORMAT_8BIT; |
277 } else { | 203 } else { |
278 cookie_stfa->sound_control |= STFA_FORMAT_16BIT; | 204 cookie_stfa->sound_control |= STFA_FORMAT_16BIT; |
279 } | 205 } |
280 if (spec->channels == 2) { | 206 if (this->spec.channels == 2) { |
281 cookie_stfa->sound_control |= STFA_FORMAT_STEREO; | 207 cookie_stfa->sound_control |= STFA_FORMAT_STEREO; |
282 } else { | 208 } else { |
283 cookie_stfa->sound_control |= STFA_FORMAT_MONO; | 209 cookie_stfa->sound_control |= STFA_FORMAT_MONO; |
284 } | 210 } |
285 if (SDL_AUDIO_ISSIGNED(spec->format) != 0) { | 211 if (SDL_AUDIO_ISSIGNED(this->spec.format) != 0) { |
286 cookie_stfa->sound_control |= STFA_FORMAT_SIGNED; | 212 cookie_stfa->sound_control |= STFA_FORMAT_SIGNED; |
287 } else { | 213 } else { |
288 cookie_stfa->sound_control |= STFA_FORMAT_UNSIGNED; | 214 cookie_stfa->sound_control |= STFA_FORMAT_UNSIGNED; |
289 } | 215 } |
290 if (SDL_AUDIO_ISBIGENDIAN(spec->format) != 0) { | 216 if (SDL_AUDIO_ISBIGENDIAN(this->spec.format) != 0) { |
291 cookie_stfa->sound_control |= STFA_FORMAT_BIGENDIAN; | 217 cookie_stfa->sound_control |= STFA_FORMAT_BIGENDIAN; |
292 } else { | 218 } else { |
293 cookie_stfa->sound_control |= STFA_FORMAT_LITENDIAN; | 219 cookie_stfa->sound_control |= STFA_FORMAT_LITENDIAN; |
294 } | 220 } |
295 | 221 |
296 /* Set buffer */ | 222 /* Set buffer */ |
297 cookie_stfa->sound_start = (unsigned long) buffer; | 223 cookie_stfa->sound_start = (unsigned long) buffer; |
298 cookie_stfa->sound_end = (unsigned long) (buffer + spec->size); | 224 cookie_stfa->sound_end = (unsigned long) (buffer + this->spec.size); |
299 | 225 |
300 /* Set interrupt */ | 226 /* Set interrupt */ |
301 cookie_stfa->stfa_it = SDL_MintAudio_StfaInterrupt; | 227 cookie_stfa->stfa_it = SDL_MintAudio_StfaInterrupt; |
302 | 228 |
303 /* Restart replay */ | 229 /* Restart replay */ |
307 | 233 |
308 DEBUG_PRINT((DEBUG_NAME "hardware initialized\n")); | 234 DEBUG_PRINT((DEBUG_NAME "hardware initialized\n")); |
309 } | 235 } |
310 | 236 |
311 static int | 237 static int |
312 Mint_OpenAudio(_THIS, SDL_AudioSpec * spec) | 238 MINTSTFA_OpenDevice(_THIS, const char *devname, int iscapture) |
313 { | 239 { |
314 SDL_MintAudio_device = this; | 240 SDL_MintAudio_device = this; |
315 | 241 |
316 /* Check audio capabilities */ | 242 /* Check audio capabilities */ |
317 if (Mint_CheckAudio(this, spec) == -1) { | 243 if (MINTSTFA_CheckAudio(this) == -1) { |
318 return -1; | 244 return 0; |
319 } | 245 } |
320 | 246 |
321 SDL_CalculateAudioSpec(spec); | 247 /* Initialize all variables that we clean on shutdown */ |
248 this->hidden = (struct SDL_PrivateAudioData *) | |
249 SDL_malloc((sizeof *this->hidden)); | |
250 if (this->hidden == NULL) { | |
251 SDL_OutOfMemory(); | |
252 return 0; | |
253 } | |
254 SDL_memset(this->hidden, 0, (sizeof *this->hidden)); | |
255 | |
256 SDL_CalculateAudioSpec(&this->spec); | |
322 | 257 |
323 /* Allocate memory for audio buffers in DMA-able RAM */ | 258 /* Allocate memory for audio buffers in DMA-able RAM */ |
324 DEBUG_PRINT((DEBUG_NAME "buffer size=%d\n", spec->size)); | 259 DEBUG_PRINT((DEBUG_NAME "buffer size=%d\n", this->spec.size)); |
325 | 260 |
326 SDL_MintAudio_audiobuf[0] = Atari_SysMalloc(spec->size * 2, MX_STRAM); | 261 SDL_MintAudio_audiobuf[0] = Atari_SysMalloc(this->spec.size * 2, MX_STRAM); |
327 if (SDL_MintAudio_audiobuf[0] == NULL) { | 262 if (SDL_MintAudio_audiobuf[0] == NULL) { |
328 SDL_SetError("MINT_OpenAudio: Not enough memory for audio buffer"); | 263 SDL_OutOfMemory() |
329 return (-1); | 264 SDL_free(this->hidden); |
330 } | 265 this->hidden = NULL; |
331 SDL_MintAudio_audiobuf[1] = SDL_MintAudio_audiobuf[0] + spec->size; | 266 return 0; |
267 } | |
268 SDL_MintAudio_audiobuf[1] = SDL_MintAudio_audiobuf[0] + this->spec.size; | |
332 SDL_MintAudio_numbuf = 0; | 269 SDL_MintAudio_numbuf = 0; |
333 SDL_memset(SDL_MintAudio_audiobuf[0], spec->silence, spec->size * 2); | 270 SDL_memset(SDL_MintAudio_audiobuf[0],this->spec.silence,this->spec.size*2); |
334 SDL_MintAudio_audiosize = spec->size; | 271 SDL_MintAudio_audiosize = this->spec.size; |
335 SDL_MintAudio_mutex = 0; | 272 SDL_MintAudio_mutex = 0; |
336 | 273 |
337 DEBUG_PRINT((DEBUG_NAME "buffer 0 at 0x%08x\n", | 274 DEBUG_PRINT((DEBUG_NAME "buffer 0 at 0x%08x\n", |
338 SDL_MintAudio_audiobuf[0])); | 275 SDL_MintAudio_audiobuf[0])); |
339 DEBUG_PRINT((DEBUG_NAME "buffer 1 at 0x%08x\n", | 276 DEBUG_PRINT((DEBUG_NAME "buffer 1 at 0x%08x\n", |
340 SDL_MintAudio_audiobuf[1])); | 277 SDL_MintAudio_audiobuf[1])); |
341 | 278 |
342 SDL_MintAudio_CheckFpu(); | 279 SDL_MintAudio_CheckFpu(); |
343 | 280 |
344 /* Setup audio hardware */ | 281 /* Setup audio hardware */ |
345 Mint_InitAudio(this, spec); | 282 MINTSTFA_InitAudio(this); |
346 | 283 |
347 return (1); /* We don't use threaded audio */ | 284 return 1; /* good to go. */ |
348 } | 285 } |
286 | |
287 | |
288 static int | |
289 MINTSTFA_Init(SDL_AudioDriverImpl *impl) | |
290 { | |
291 /* Set the function pointers */ | |
292 impl->OpenDevice = MINTSTFA_OpenDevice; | |
293 impl->CloseDevice = MINTSTFA_CloseDevice; | |
294 impl->LockAudio = MINTSTFA_LockAudio; | |
295 impl->UnlockAudio = MINTSTFA_UnlockAudio; | |
296 impl->OnlyHasDefaultOutputDevice = 1; | |
297 impl->ProvidesOwnCallbackThread = 1; | |
298 impl->SkipMixerLock = 1; | |
299 | |
300 return 1; | |
301 } | |
302 | |
303 AudioBootStrap MINTAUDIO_STFA_bootstrap = { | |
304 MINT_AUDIO_DRIVER_NAME, "MiNT STFA audio driver", | |
305 MINTSTFA_Available, MINTSTFA_Init, 0 | |
306 }; | |
349 | 307 |
350 /* vi: set ts=4 sw=4 expandtab: */ | 308 /* vi: set ts=4 sw=4 expandtab: */ |