Mercurial > sdl-ios-xcode
comparison src/audio/mint/SDL_mintaudio_mcsn.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 |
---|---|
59 #define DEBUG_PRINT(what) | 59 #define DEBUG_PRINT(what) |
60 #endif | 60 #endif |
61 | 61 |
62 /*--- Static variables ---*/ | 62 /*--- Static variables ---*/ |
63 | 63 |
64 static unsigned long cookie_snd, cookie_mch; | 64 static unsigned long cookie_snd = 0; |
65 static cookie_mcsn_t *cookie_mcsn; | 65 static unsigned long cookie_mch = 0; |
66 | 66 static cookie_mcsn_t *cookie_mcsn = NULL; |
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 | 67 |
80 static int | 68 static int |
81 Audio_Available(void) | 69 MINTMCSN_Available(void) |
82 { | 70 { |
83 unsigned long dummy; | 71 unsigned long dummy = 0; |
84 const char *envr = SDL_getenv("SDL_AUDIODRIVER"); | |
85 | 72 |
86 SDL_MintAudio_mint_present = (Getcookie(C_MiNT, &dummy) == C_FOUND); | 73 SDL_MintAudio_mint_present = (Getcookie(C_MiNT, &dummy) == C_FOUND); |
87 | 74 |
88 /* We can't use XBIOS in interrupt with Magic, don't know about thread */ | 75 /* We can't use XBIOS in interrupt with Magic, don't know about thread */ |
89 if (Getcookie(C_MagX, &dummy) == C_FOUND) { | 76 if (Getcookie(C_MagX, &dummy) == C_FOUND) { |
90 return (0); | |
91 } | |
92 | |
93 /* Check if user asked a different audio driver */ | |
94 if ((envr) && (SDL_strcmp(envr, MINT_AUDIO_DRIVER_NAME) != 0)) { | |
95 DEBUG_PRINT((DEBUG_NAME "user asked a different audio driver\n")); | |
96 return (0); | 77 return (0); |
97 } | 78 } |
98 | 79 |
99 /* Cookie _MCH present ? if not, assume ST machine */ | 80 /* Cookie _MCH present ? if not, assume ST machine */ |
100 if (Getcookie(C__MCH, &cookie_mch) == C_NOTFOUND) { | 81 if (Getcookie(C__MCH, &cookie_mch) == C_NOTFOUND) { |
135 DEBUG_PRINT((DEBUG_NAME "MCSN audio available!\n")); | 116 DEBUG_PRINT((DEBUG_NAME "MCSN audio available!\n")); |
136 return (1); | 117 return (1); |
137 } | 118 } |
138 | 119 |
139 static void | 120 static void |
140 Audio_DeleteDevice(SDL_AudioDevice * device) | 121 MINTMCSN_LockDevice(_THIS) |
141 { | |
142 SDL_free(device->hidden); | |
143 SDL_free(device); | |
144 } | |
145 | |
146 static SDL_AudioDevice * | |
147 Audio_CreateDevice(int devindex) | |
148 { | |
149 SDL_AudioDevice *this; | |
150 | |
151 /* Initialize all variables that we clean on shutdown */ | |
152 this = (SDL_AudioDevice *) SDL_malloc(sizeof(SDL_AudioDevice)); | |
153 if (this) { | |
154 SDL_memset(this, 0, (sizeof *this)); | |
155 this->hidden = (struct SDL_PrivateAudioData *) | |
156 SDL_malloc((sizeof *this->hidden)); | |
157 } | |
158 if ((this == NULL) || (this->hidden == NULL)) { | |
159 SDL_OutOfMemory(); | |
160 if (this) { | |
161 SDL_free(this); | |
162 } | |
163 return (0); | |
164 } | |
165 SDL_memset(this->hidden, 0, (sizeof *this->hidden)); | |
166 | |
167 /* Set the function pointers */ | |
168 this->OpenAudio = Mint_OpenAudio; | |
169 this->CloseAudio = Mint_CloseAudio; | |
170 this->LockAudio = Mint_LockAudio; | |
171 this->UnlockAudio = Mint_UnlockAudio; | |
172 this->free = Audio_DeleteDevice; | |
173 | |
174 /* Uses interrupt driven audio, without thread */ | |
175 #if SDL_THREADS_DISABLED | |
176 this->SkipMixerLock = 1; | |
177 #endif | |
178 | |
179 return this; | |
180 } | |
181 | |
182 AudioBootStrap MINTAUDIO_MCSN_bootstrap = { | |
183 MINT_AUDIO_DRIVER_NAME, "MiNT MCSN audio driver", | |
184 Audio_Available, Audio_CreateDevice, 0 | |
185 }; | |
186 | |
187 static void | |
188 Mint_LockAudio(_THIS) | |
189 { | 122 { |
190 /* Stop replay */ | 123 /* Stop replay */ |
191 Buffoper(0); | 124 Buffoper(0); |
192 } | 125 } |
193 | 126 |
194 static void | 127 static void |
195 Mint_UnlockAudio(_THIS) | 128 MINTMCSN_UnlockDevice(_THIS) |
196 { | 129 { |
197 /* Restart replay */ | 130 /* Restart replay */ |
198 Buffoper(SB_PLA_ENA | SB_PLA_RPT); | 131 Buffoper(SB_PLA_ENA | SB_PLA_RPT); |
199 } | 132 } |
200 | 133 |
201 static void | 134 static void |
202 Mint_CloseAudio(_THIS) | 135 MINTMCSN_CloseDevice(_THIS) |
203 { | 136 { |
204 /* Stop replay */ | 137 if (this->hidden != NULL) { |
205 SDL_MintAudio_WaitThread(); | 138 /* Stop replay */ |
206 Buffoper(0); | 139 SDL_MintAudio_WaitThread(); |
207 | 140 Buffoper(0); |
208 if (!SDL_MintAudio_mint_present) { | 141 |
209 /* Uninstall interrupt */ | 142 if (!SDL_MintAudio_mint_present) { |
210 Jdisint(MFP_DMASOUND); | 143 /* Uninstall interrupt */ |
211 } | 144 Jdisint(MFP_DMASOUND); |
212 | 145 } |
213 /* Wait if currently playing sound */ | 146 |
214 while (SDL_MintAudio_mutex != 0) { | 147 /* Wait if currently playing sound */ |
215 } | 148 while (SDL_MintAudio_mutex != 0) {} |
216 | 149 |
217 /* Clear buffers */ | 150 /* Clear buffers */ |
218 if (SDL_MintAudio_audiobuf[0]) { | 151 if (SDL_MintAudio_audiobuf[0]) { |
219 Mfree(SDL_MintAudio_audiobuf[0]); | 152 Mfree(SDL_MintAudio_audiobuf[0]); |
220 SDL_MintAudio_audiobuf[0] = SDL_MintAudio_audiobuf[1] = NULL; | 153 SDL_MintAudio_audiobuf[0] = SDL_MintAudio_audiobuf[1] = NULL; |
221 } | 154 } |
222 | 155 |
223 /* Unlock sound system */ | 156 /* Unlock sound system */ |
224 Unlocksnd(); | 157 Unlocksnd(); |
158 | |
159 SDL_free(this->hidden); | |
160 this->hidden = NULL; | |
161 } | |
225 } | 162 } |
226 | 163 |
227 static int | 164 static int |
228 Mint_CheckAudio(_THIS, SDL_AudioSpec * spec) | 165 MINTMCSN_CheckAudio(_THIS) |
229 { | 166 { |
230 int i; | 167 int i; |
231 unsigned long masterclock, masterprediv; | 168 unsigned long masterclock, masterprediv; |
232 | 169 |
233 DEBUG_PRINT((DEBUG_NAME "asked: %d bits, ", | 170 DEBUG_PRINT((DEBUG_NAME "asked: %d bits, ", |
234 SDL_AUDIO_BITSIZE(spec->format))); | 171 SDL_AUDIO_BITSIZE(this->spec.format))); |
235 DEBUG_PRINT(("float=%d, ", SDL_AUDIO_ISFLOAT(spec->format))); | 172 DEBUG_PRINT(("float=%d, ", SDL_AUDIO_ISFLOAT(this->spec.format))); |
236 DEBUG_PRINT(("signed=%d, ", SDL_AUDIO_ISSIGNED(spec->format))); | 173 DEBUG_PRINT(("signed=%d, ", SDL_AUDIO_ISSIGNED(this->spec.format))); |
237 DEBUG_PRINT(("big endian=%d, ", SDL_AUDIO_ISBIGENDIAN(spec->format))); | 174 DEBUG_PRINT(("big endian=%d, ", SDL_AUDIO_ISBIGENDIAN(this->spec.format))); |
238 DEBUG_PRINT(("channels=%d, ", spec->channels)); | 175 DEBUG_PRINT(("channels=%d, ", this->spec.channels)); |
239 DEBUG_PRINT(("freq=%d\n", spec->freq)); | 176 DEBUG_PRINT(("freq=%d\n", this->spec.freq)); |
240 | 177 |
241 if (spec->channels > 2) { | 178 if (this->spec.channels > 2) { |
242 spec->channels = 2; /* no more than stereo! */ | 179 this->spec.channels = 2; /* no more than stereo! */ |
243 } | 180 } |
244 | 181 |
245 /* Check formats available */ | 182 /* Check formats available */ |
246 MINTAUDIO_freqcount = 0; | 183 MINTAUDIO_freqcount = 0; |
247 switch (cookie_mcsn->play) { | 184 switch (cookie_mcsn->play) { |
248 case MCSN_ST: | 185 case MCSN_ST: |
249 spec->channels = 1; | 186 this->spec.channels = 1; |
250 spec->format = AUDIO_S8; /* FIXME: is it signed or unsigned ? */ | 187 this->spec.format = AUDIO_S8; /* FIXME: is it signed or unsigned ? */ |
251 SDL_MintAudio_AddFrequency(this, 12500, 0, 0, -1); | 188 SDL_MintAudio_AddFrequency(this, 12500, 0, 0, -1); |
252 break; | 189 break; |
253 case MCSN_TT: /* Also STE, Mega STE */ | 190 case MCSN_TT: /* Also STE, Mega STE */ |
254 spec->format = AUDIO_S8; | 191 this->spec.format = AUDIO_S8; |
255 masterclock = MASTERCLOCK_STE; | 192 masterclock = MASTERCLOCK_STE; |
256 masterprediv = MASTERPREDIV_STE; | 193 masterprediv = MASTERPREDIV_STE; |
257 if ((cookie_mch >> 16) == MCH_TT) { | 194 if ((cookie_mch >> 16) == MCH_TT) { |
258 masterclock = MASTERCLOCK_TT; | 195 masterclock = MASTERCLOCK_TT; |
259 masterprediv = MASTERPREDIV_TT; | 196 masterprediv = MASTERPREDIV_TT; |
283 (MASTERPREDIV_FALCON * | 220 (MASTERPREDIV_FALCON * |
284 (1 << i)), CLKEXT, | 221 (1 << i)), CLKEXT, |
285 (1 << i) - 1, -1); | 222 (1 << i) - 1, -1); |
286 } | 223 } |
287 } | 224 } |
288 spec->format |= SDL_AUDIO_MASK_SIGNED; /* Audio is always signed */ | 225 this->spec.format |= SDL_AUDIO_MASK_SIGNED; /* Audio is always signed */ |
289 if ((SDL_AUDIO_BITSIZE(spec->format)) == 16) { | 226 if ((SDL_AUDIO_BITSIZE(this->spec.format)) == 16) { |
290 spec->format |= SDL_AUDIO_MASK_ENDIAN; /* Audio is always big endian */ | 227 this->spec.format |= SDL_AUDIO_MASK_ENDIAN; /* Audio is always big endian */ |
291 spec->channels = 2; /* 16 bits always stereo */ | 228 this->spec.channels = 2; /* 16 bits always stereo */ |
292 } | 229 } |
293 break; | 230 break; |
294 } | 231 } |
295 | 232 |
296 #if 1 | 233 #if 1 |
300 MINTAUDIO_frequencies[i].masterclock, | 237 MINTAUDIO_frequencies[i].masterclock, |
301 MINTAUDIO_frequencies[i].predivisor)); | 238 MINTAUDIO_frequencies[i].predivisor)); |
302 } | 239 } |
303 #endif | 240 #endif |
304 | 241 |
305 MINTAUDIO_numfreq = SDL_MintAudio_SearchFrequency(this, spec->freq); | 242 MINTAUDIO_numfreq = SDL_MintAudio_SearchFrequency(this, this->spec.freq); |
306 spec->freq = MINTAUDIO_frequencies[MINTAUDIO_numfreq].frequency; | 243 this->spec.freq = MINTAUDIO_frequencies[MINTAUDIO_numfreq].frequency; |
307 | 244 |
308 DEBUG_PRINT((DEBUG_NAME "obtained: %d bits, ", | 245 DEBUG_PRINT((DEBUG_NAME "obtained: %d bits, ", |
309 SDL_AUDIO_BITSIZE(spec->format))); | 246 SDL_AUDIO_BITSIZE(this->spec.format))); |
310 DEBUG_PRINT(("float=%d, ", SDL_AUDIO_ISFLOAT(spec->format))); | 247 DEBUG_PRINT(("float=%d, ", SDL_AUDIO_ISFLOAT(this->spec.format))); |
311 DEBUG_PRINT(("signed=%d, ", SDL_AUDIO_ISSIGNED(spec->format))); | 248 DEBUG_PRINT(("signed=%d, ", SDL_AUDIO_ISSIGNED(this->spec.format))); |
312 DEBUG_PRINT(("big endian=%d, ", SDL_AUDIO_ISBIGENDIAN(spec->format))); | 249 DEBUG_PRINT(("big endian=%d, ", SDL_AUDIO_ISBIGENDIAN(this->spec.format))); |
313 DEBUG_PRINT(("channels=%d, ", spec->channels)); | 250 DEBUG_PRINT(("channels=%d, ", this->spec.channels)); |
314 DEBUG_PRINT(("freq=%d\n", spec->freq)); | 251 DEBUG_PRINT(("freq=%d\n", this->spec.freq)); |
315 | 252 |
316 return 0; | 253 return 0; |
317 } | 254 } |
318 | 255 |
319 static void | 256 static void |
320 Mint_InitAudio(_THIS, SDL_AudioSpec * spec) | 257 MINTMCSN_InitAudio(_THIS) |
321 { | 258 { |
322 int channels_mode, prediv, dmaclock; | 259 int channels_mode, prediv, dmaclock; |
323 void *buffer; | 260 void *buffer; |
324 | 261 |
325 /* Stop currently playing sound */ | 262 /* Stop currently playing sound */ |
332 Settracks(0, 0); | 269 Settracks(0, 0); |
333 Setmontracks(0); | 270 Setmontracks(0); |
334 | 271 |
335 /* Select replay format */ | 272 /* Select replay format */ |
336 channels_mode = STEREO16; | 273 channels_mode = STEREO16; |
337 switch (SDL_AUDIO_BITSIZE(spec->format)) { | 274 switch (SDL_AUDIO_BITSIZE(this->spec.format)) { |
338 case 8: | 275 case 8: |
339 if (spec->channels == 2) { | 276 if (this->spec.channels == 2) { |
340 channels_mode = STEREO8; | 277 channels_mode = STEREO8; |
341 } else { | 278 } else { |
342 channels_mode = MONO8; | 279 channels_mode = MONO8; |
343 } | 280 } |
344 break; | 281 break; |
361 break; | 298 break; |
362 } | 299 } |
363 | 300 |
364 /* Set buffer */ | 301 /* Set buffer */ |
365 buffer = SDL_MintAudio_audiobuf[SDL_MintAudio_numbuf]; | 302 buffer = SDL_MintAudio_audiobuf[SDL_MintAudio_numbuf]; |
366 if (Setbuffer(0, buffer, buffer + spec->size) < 0) { | 303 if (Setbuffer(0, buffer, buffer + this->spec.size) < 0) { |
367 DEBUG_PRINT((DEBUG_NAME "Setbuffer() failed\n")); | 304 DEBUG_PRINT((DEBUG_NAME "Setbuffer() failed\n")); |
368 } | 305 } |
369 | 306 |
370 if (SDL_MintAudio_mint_present) { | 307 if (SDL_MintAudio_mint_present) { |
371 SDL_MintAudio_thread_pid = tfork(SDL_MintAudio_Thread, 0); | 308 SDL_MintAudio_thread_pid = tfork(SDL_MintAudio_Thread, 0); |
384 Buffoper(SB_PLA_ENA | SB_PLA_RPT); | 321 Buffoper(SB_PLA_ENA | SB_PLA_RPT); |
385 DEBUG_PRINT((DEBUG_NAME "hardware initialized\n")); | 322 DEBUG_PRINT((DEBUG_NAME "hardware initialized\n")); |
386 } | 323 } |
387 | 324 |
388 static int | 325 static int |
389 Mint_OpenAudio(_THIS, SDL_AudioSpec * spec) | 326 MINTMCSN_OpenDevice(_THIS, const char *devname, int iscapture) |
390 { | 327 { |
391 /* Lock sound system */ | 328 /* Lock sound system */ |
392 if (Locksnd() != 1) { | 329 if (Locksnd() != 1) { |
393 SDL_SetError("Mint_OpenAudio: Audio system already in use"); | 330 SDL_SetError("MINTMCSN_OpenDevice: Audio system already in use"); |
394 return (-1); | 331 return 0; |
395 } | 332 } |
396 | 333 |
397 SDL_MintAudio_device = this; | 334 SDL_MintAudio_device = this; |
398 | 335 |
399 /* Check audio capabilities */ | 336 /* Check audio capabilities */ |
400 if (Mint_CheckAudio(this, spec) == -1) { | 337 if (MINTMCSN_CheckAudio(this) == -1) { |
401 return -1; | 338 return 0; |
402 } | 339 } |
403 | 340 |
404 SDL_CalculateAudioSpec(spec); | 341 /* Initialize all variables that we clean on shutdown */ |
342 this->hidden = (struct SDL_PrivateAudioData *) | |
343 SDL_malloc((sizeof *this->hidden)); | |
344 if (this->hidden == NULL) { | |
345 SDL_OutOfMemory(); | |
346 return 0; | |
347 } | |
348 SDL_memset(this->hidden, 0, (sizeof *this->hidden)); | |
349 | |
350 SDL_CalculateAudioSpec(&this->spec); | |
405 | 351 |
406 /* Allocate memory for audio buffers in DMA-able RAM */ | 352 /* Allocate memory for audio buffers in DMA-able RAM */ |
407 DEBUG_PRINT((DEBUG_NAME "buffer size=%d\n", spec->size)); | 353 DEBUG_PRINT((DEBUG_NAME "buffer size=%d\n", this->spec.size)); |
408 | 354 |
409 SDL_MintAudio_audiobuf[0] = Atari_SysMalloc(spec->size * 2, MX_STRAM); | 355 SDL_MintAudio_audiobuf[0] = Atari_SysMalloc(this->spec.size * 2, MX_STRAM); |
410 if (SDL_MintAudio_audiobuf[0] == NULL) { | 356 if (SDL_MintAudio_audiobuf[0] == NULL) { |
411 SDL_SetError("MINT_OpenAudio: Not enough memory for audio buffer"); | 357 SDL_free(this->hidden); |
412 return (-1); | 358 this->hidden = NULL; |
413 } | 359 SDL_OutOfMemory(); |
414 SDL_MintAudio_audiobuf[1] = SDL_MintAudio_audiobuf[0] + spec->size; | 360 return 0; |
361 } | |
362 SDL_MintAudio_audiobuf[1] = SDL_MintAudio_audiobuf[0] + this->spec.size; | |
415 SDL_MintAudio_numbuf = 0; | 363 SDL_MintAudio_numbuf = 0; |
416 SDL_memset(SDL_MintAudio_audiobuf[0], spec->silence, spec->size * 2); | 364 SDL_memset(SDL_MintAudio_audiobuf[0],this->spec.silence,this->spec.size*2); |
417 SDL_MintAudio_audiosize = spec->size; | 365 SDL_MintAudio_audiosize = this->spec.size; |
418 SDL_MintAudio_mutex = 0; | 366 SDL_MintAudio_mutex = 0; |
419 | 367 |
420 DEBUG_PRINT((DEBUG_NAME "buffer 0 at 0x%08x\n", | 368 DEBUG_PRINT((DEBUG_NAME "buffer 0 at 0x%08x\n", |
421 SDL_MintAudio_audiobuf[0])); | 369 SDL_MintAudio_audiobuf[0])); |
422 DEBUG_PRINT((DEBUG_NAME "buffer 1 at 0x%08x\n", | 370 DEBUG_PRINT((DEBUG_NAME "buffer 1 at 0x%08x\n", |
423 SDL_MintAudio_audiobuf[1])); | 371 SDL_MintAudio_audiobuf[1])); |
424 | 372 |
425 SDL_MintAudio_CheckFpu(); | 373 SDL_MintAudio_CheckFpu(); |
426 | 374 |
427 /* Setup audio hardware */ | 375 /* Setup audio hardware */ |
428 Mint_InitAudio(this, spec); | 376 MINTMCSN_InitAudio(this); |
429 | 377 |
430 return (1); /* We don't use SDL threaded audio */ | 378 return 1; /* good to go. */ |
431 } | 379 } |
380 | |
381 static int | |
382 MINTMCSN_Init(SDL_AudioDriverImpl *impl) | |
383 { | |
384 /* Set the function pointers */ | |
385 impl->OpenDevice = MINTMCSN_OpenDevice; | |
386 impl->CloseDevice = MINTMCSN_CloseDevice; | |
387 impl->LockAudio = MINTMCSN_LockAudio; | |
388 impl->UnlockAudio = MINTMCSN_UnlockAudio; | |
389 impl->OnlyHasDefaultOutputDevice = 1; | |
390 impl->ProvidesOwnCallbackThread = 1; | |
391 impl->SkipMixerLock = 1; | |
392 | |
393 return 1; | |
394 } | |
395 | |
396 AudioBootStrap MINTAUDIO_MCSN_bootstrap = { | |
397 MINT_AUDIO_DRIVER_NAME, "MiNT MCSN audio driver", | |
398 MINTMCSN_Available, MINTMCSN_Init, 0 | |
399 }; | |
432 | 400 |
433 /* vi: set ts=4 sw=4 expandtab: */ | 401 /* vi: set ts=4 sw=4 expandtab: */ |