Mercurial > sdl-ios-xcode
comparison src/audio/mint/SDL_mintaudio_xbios.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 |
---|---|
58 } | 58 } |
59 #else | 59 #else |
60 #define DEBUG_PRINT(what) | 60 #define DEBUG_PRINT(what) |
61 #endif | 61 #endif |
62 | 62 |
63 /*--- Static variables ---*/ | 63 static unsigned long cookie_snd = 0; |
64 | |
65 static unsigned long cookie_snd; | |
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 | 64 |
80 static int | 65 static int |
81 Audio_Available(void) | 66 MINTXBIOS_Available(void) |
82 { | 67 { |
83 unsigned long dummy; | 68 unsigned long dummy = 0; |
84 const char *envr = SDL_getenv("SDL_AUDIODRIVER"); | |
85 | |
86 /*SDL_MintAudio_mint_present = (Getcookie(C_MiNT, &dummy) == C_FOUND); */ | 69 /*SDL_MintAudio_mint_present = (Getcookie(C_MiNT, &dummy) == C_FOUND); */ |
87 SDL_MintAudio_mint_present = SDL_FALSE; | 70 SDL_MintAudio_mint_present = SDL_FALSE; |
88 | 71 |
89 /* We can't use XBIOS in interrupt with Magic, don't know about thread */ | 72 /* We can't use XBIOS in interrupt with Magic, don't know about thread */ |
90 if (Getcookie(C_MagX, &dummy) == C_FOUND) { | 73 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); | 74 return (0); |
98 } | 75 } |
99 | 76 |
100 /* Cookie _SND present ? if not, assume ST machine */ | 77 /* Cookie _SND present ? if not, assume ST machine */ |
101 if (Getcookie(C__SND, &cookie_snd) == C_NOTFOUND) { | 78 if (Getcookie(C__SND, &cookie_snd) == C_NOTFOUND) { |
119 DEBUG_PRINT((DEBUG_NAME "XBIOS audio available!\n")); | 96 DEBUG_PRINT((DEBUG_NAME "XBIOS audio available!\n")); |
120 return (1); | 97 return (1); |
121 } | 98 } |
122 | 99 |
123 static void | 100 static void |
124 Audio_DeleteDevice(SDL_AudioDevice * device) | 101 MINTXBIOS_LockDevice(_THIS) |
125 { | |
126 SDL_free(device->hidden); | |
127 SDL_free(device); | |
128 } | |
129 | |
130 static SDL_AudioDevice * | |
131 Audio_CreateDevice(int devindex) | |
132 { | |
133 SDL_AudioDevice *this; | |
134 | |
135 /* Initialize all variables that we clean on shutdown */ | |
136 this = (SDL_AudioDevice *) SDL_malloc(sizeof(SDL_AudioDevice)); | |
137 if (this) { | |
138 SDL_memset(this, 0, (sizeof *this)); | |
139 this->hidden = (struct SDL_PrivateAudioData *) | |
140 SDL_malloc((sizeof *this->hidden)); | |
141 } | |
142 if ((this == NULL) || (this->hidden == NULL)) { | |
143 SDL_OutOfMemory(); | |
144 if (this) { | |
145 SDL_free(this); | |
146 } | |
147 return (0); | |
148 } | |
149 SDL_memset(this->hidden, 0, (sizeof *this->hidden)); | |
150 | |
151 /* Set the function pointers */ | |
152 this->OpenAudio = Mint_OpenAudio; | |
153 this->CloseAudio = Mint_CloseAudio; | |
154 this->LockAudio = Mint_LockAudio; | |
155 this->UnlockAudio = Mint_UnlockAudio; | |
156 this->free = Audio_DeleteDevice; | |
157 | |
158 /* Uses interrupt driven audio, without thread */ | |
159 #if SDL_THREADS_DISABLED | |
160 this->SkipMixerLock = 1; | |
161 #endif | |
162 | |
163 return this; | |
164 } | |
165 | |
166 AudioBootStrap MINTAUDIO_XBIOS_bootstrap = { | |
167 MINT_AUDIO_DRIVER_NAME, "MiNT XBIOS audio driver", | |
168 Audio_Available, Audio_CreateDevice, 0 | |
169 }; | |
170 | |
171 static void | |
172 Mint_LockAudio(_THIS) | |
173 { | 102 { |
174 /* Stop replay */ | 103 /* Stop replay */ |
175 Buffoper(0); | 104 Buffoper(0); |
176 } | 105 } |
177 | 106 |
178 static void | 107 static void |
179 Mint_UnlockAudio(_THIS) | 108 MINTXBIOS_UnlockDevice(_THIS) |
180 { | 109 { |
181 /* Restart replay */ | 110 /* Restart replay */ |
182 Buffoper(SB_PLA_ENA | SB_PLA_RPT); | 111 Buffoper(SB_PLA_ENA | SB_PLA_RPT); |
183 } | 112 } |
184 | 113 |
185 static void | 114 static void |
186 Mint_CloseAudio(_THIS) | 115 MINTXBIOS_CloseDevice(_THIS) |
187 { | 116 { |
188 /* Stop replay */ | 117 if (this->hidden != NULL) { |
189 SDL_MintAudio_WaitThread(); | 118 /* Stop replay */ |
190 Buffoper(0); | 119 SDL_MintAudio_WaitThread(); |
191 | 120 Buffoper(0); |
192 if (!SDL_MintAudio_mint_present) { | 121 |
193 /* Uninstall interrupt */ | 122 if (!SDL_MintAudio_mint_present) { |
194 Jdisint(MFP_DMASOUND); | 123 /* Uninstall interrupt */ |
195 } | 124 Jdisint(MFP_DMASOUND); |
196 | 125 } |
197 /* Wait if currently playing sound */ | 126 |
198 while (SDL_MintAudio_mutex != 0) { | 127 /* Wait if currently playing sound */ |
199 } | 128 while (SDL_MintAudio_mutex != 0) {} |
200 | 129 |
201 /* Clear buffers */ | 130 /* Clear buffers */ |
202 if (SDL_MintAudio_audiobuf[0]) { | 131 if (SDL_MintAudio_audiobuf[0]) { |
203 Mfree(SDL_MintAudio_audiobuf[0]); | 132 Mfree(SDL_MintAudio_audiobuf[0]); |
204 SDL_MintAudio_audiobuf[0] = SDL_MintAudio_audiobuf[1] = NULL; | 133 SDL_MintAudio_audiobuf[0] = SDL_MintAudio_audiobuf[1] = NULL; |
205 } | 134 } |
206 | 135 |
207 /* Unlock sound system */ | 136 /* Unlock sound system */ |
208 Unlocksnd(); | 137 Unlocksnd(); |
138 | |
139 SDL_free(this->hidden); | |
140 this->hidden = NULL; | |
141 } | |
209 } | 142 } |
210 | 143 |
211 /* Falcon XBIOS implementation of Devconnect() is buggy with external clock */ | 144 /* Falcon XBIOS implementation of Devconnect() is buggy with external clock */ |
212 static void | 145 static void |
213 Devconnect2(int src, int dst, int sclk, int pre) | 146 Devconnect2(int src, int dst, int sclk, int pre) |
272 | 205 |
273 Super(oldstack); | 206 Super(oldstack); |
274 } | 207 } |
275 | 208 |
276 static void | 209 static void |
277 Mint_CheckExternalClock(_THIS) | 210 MINTXBIOS_CheckExternalClock(_THIS) |
278 { | 211 { |
279 #define SIZE_BUF_CLOCK_MEASURE (44100/10) | 212 #define SIZE_BUF_CLOCK_MEASURE (44100/10) |
280 | 213 |
281 unsigned long cookie_snd; | 214 unsigned long cookie_snd; |
282 char *buffer; | 215 char *buffer; |
358 | 291 |
359 Mfree(buffer); | 292 Mfree(buffer); |
360 } | 293 } |
361 | 294 |
362 static int | 295 static int |
363 Mint_CheckAudio(_THIS, SDL_AudioSpec * spec) | 296 MINTXBIOS_CheckAudio(_THIS) |
364 { | 297 { |
365 int i; | 298 int i; |
366 Uint32 extclock; | 299 Uint32 extclock; |
367 | 300 |
368 DEBUG_PRINT((DEBUG_NAME "asked: %d bits, ", | 301 DEBUG_PRINT((DEBUG_NAME "asked: %d bits, ", |
369 SDL_AUDIO_BITSIZE(spec->format))); | 302 SDL_AUDIO_BITSIZE(this->spec.format))); |
370 DEBUG_PRINT(("float=%d, ", SDL_AUDIO_ISFLOAT(spec->format))); | 303 DEBUG_PRINT(("float=%d, ", SDL_AUDIO_ISFLOAT(this->spec.format))); |
371 DEBUG_PRINT(("signed=%d, ", SDL_AUDIO_ISSIGNED(spec->format))); | 304 DEBUG_PRINT(("signed=%d, ", SDL_AUDIO_ISSIGNED(this->spec.format))); |
372 DEBUG_PRINT(("big endian=%d, ", SDL_AUDIO_ISBIGENDIAN(spec->format))); | 305 DEBUG_PRINT(("big endian=%d, ", SDL_AUDIO_ISBIGENDIAN(this->spec.format))); |
373 DEBUG_PRINT(("channels=%d, ", spec->channels)); | 306 DEBUG_PRINT(("channels=%d, ", this->spec.channels)); |
374 DEBUG_PRINT(("freq=%d\n", spec->freq)); | 307 DEBUG_PRINT(("freq=%d\n", this->spec.freq)); |
375 | 308 |
376 spec->format |= SDL_AUDIO_MASK_SIGNED; /* Audio is always signed */ | 309 this->spec.format |= SDL_AUDIO_MASK_SIGNED; /* Audio is always signed */ |
377 | 310 |
378 /* clamp out int32/float32 */ | 311 /* clamp out int32/float32 */ |
379 if (SDL_AUDIO_BITSIZE(spec->format) >= 16) { | 312 if (SDL_AUDIO_BITSIZE(this->spec.format) >= 16) { |
380 spec->format = AUDIO_S16MSB; /* Audio is always big endian */ | 313 this->spec.format = AUDIO_S16MSB; /* Audio is always big endian */ |
381 spec->channels = 2; /* 16 bits always stereo */ | 314 this->spec.channels = 2; /* 16 bits always stereo */ |
382 } else if (spec->channels > 2) { | 315 } else if (this->spec.channels > 2) { |
383 spec->channels = 2; /* no more than stereo! */ | 316 this->spec.channels = 2; /* no more than stereo! */ |
384 } | 317 } |
385 | 318 |
386 MINTAUDIO_freqcount = 0; | 319 MINTAUDIO_freqcount = 0; |
387 | 320 |
388 /* Add external clocks if present */ | 321 /* Add external clocks if present */ |
389 Mint_CheckExternalClock(this); | 322 MINTXBIOS_CheckExternalClock(this); |
390 | 323 |
391 /* Standard clocks */ | 324 /* Standard clocks */ |
392 for (i = 1; i < 12; i++) { | 325 for (i = 1; i < 12; i++) { |
393 /* Remove unusable Falcon codec predivisors */ | 326 /* Remove unusable Falcon codec predivisors */ |
394 if ((i == 6) || (i == 8) || (i == 10)) { | 327 if ((i == 6) || (i == 8) || (i == 10)) { |
407 MINTAUDIO_frequencies[i].masterclock, | 340 MINTAUDIO_frequencies[i].masterclock, |
408 MINTAUDIO_frequencies[i].predivisor)); | 341 MINTAUDIO_frequencies[i].predivisor)); |
409 } | 342 } |
410 #endif | 343 #endif |
411 | 344 |
412 MINTAUDIO_numfreq = SDL_MintAudio_SearchFrequency(this, spec->freq); | 345 MINTAUDIO_numfreq = SDL_MintAudio_SearchFrequency(this, this->spec.freq); |
413 spec->freq = MINTAUDIO_frequencies[MINTAUDIO_numfreq].frequency; | 346 this->spec.freq = MINTAUDIO_frequencies[MINTAUDIO_numfreq].frequency; |
414 | 347 |
415 DEBUG_PRINT((DEBUG_NAME "obtained: %d bits, ", | 348 DEBUG_PRINT((DEBUG_NAME "obtained: %d bits, ", |
416 SDL_AUDIO_BITSIZE(spec->format))); | 349 SDL_AUDIO_BITSIZE(this->spec.format))); |
417 DEBUG_PRINT(("float=%d, ", SDL_AUDIO_ISFLOAT(spec->format))); | 350 DEBUG_PRINT(("float=%d, ", SDL_AUDIO_ISFLOAT(this->spec.format))); |
418 DEBUG_PRINT(("signed=%d, ", SDL_AUDIO_ISSIGNED(spec->format))); | 351 DEBUG_PRINT(("signed=%d, ", SDL_AUDIO_ISSIGNED(this->spec.format))); |
419 DEBUG_PRINT(("big endian=%d, ", SDL_AUDIO_ISBIGENDIAN(spec->format))); | 352 DEBUG_PRINT(("big endian=%d, ", SDL_AUDIO_ISBIGENDIAN(this->spec.format))); |
420 DEBUG_PRINT(("channels=%d, ", spec->channels)); | 353 DEBUG_PRINT(("channels=%d, ", this->spec.channels)); |
421 DEBUG_PRINT(("freq=%d\n", spec->freq)); | 354 DEBUG_PRINT(("freq=%d\n", this->spec.freq)); |
422 | 355 |
423 return 0; | 356 return 0; |
424 } | 357 } |
425 | 358 |
426 static void | 359 static void |
427 Mint_InitAudio(_THIS, SDL_AudioSpec * spec) | 360 MINTXBIOS_InitAudio(_THIS) |
428 { | 361 { |
429 int channels_mode, dmaclock, prediv; | 362 int channels_mode, dmaclock, prediv; |
430 void *buffer; | 363 void *buffer; |
431 | 364 |
432 /* Stop currently playing sound */ | 365 /* Stop currently playing sound */ |
439 Settracks(0, 0); | 372 Settracks(0, 0); |
440 Setmontracks(0); | 373 Setmontracks(0); |
441 | 374 |
442 /* Select replay format */ | 375 /* Select replay format */ |
443 channels_mode = STEREO16; | 376 channels_mode = STEREO16; |
444 switch (SDL_AUDIO_BITSIZE(spec->format)) { | 377 switch (SDL_AUDIO_BITSIZE(this->spec.format)) { |
445 case 8: | 378 case 8: |
446 if (spec->channels == 2) { | 379 if (this->spec.channels == 2) { |
447 channels_mode = STEREO8; | 380 channels_mode = STEREO8; |
448 } else { | 381 } else { |
449 channels_mode = MONO8; | 382 channels_mode = MONO8; |
450 } | 383 } |
451 break; | 384 break; |
464 Devconnect2(DMAPLAY, DAC, CLK25M, prediv); | 397 Devconnect2(DMAPLAY, DAC, CLK25M, prediv); |
465 } | 398 } |
466 | 399 |
467 /* Set buffer */ | 400 /* Set buffer */ |
468 buffer = SDL_MintAudio_audiobuf[SDL_MintAudio_numbuf]; | 401 buffer = SDL_MintAudio_audiobuf[SDL_MintAudio_numbuf]; |
469 if (Setbuffer(0, buffer, buffer + spec->size) < 0) { | 402 if (Setbuffer(0, buffer, buffer + this->spec.size) < 0) { |
470 DEBUG_PRINT((DEBUG_NAME "Setbuffer() failed\n")); | 403 DEBUG_PRINT((DEBUG_NAME "Setbuffer() failed\n")); |
471 } | 404 } |
472 | 405 |
473 if (SDL_MintAudio_mint_present) { | 406 if (SDL_MintAudio_mint_present) { |
474 SDL_MintAudio_thread_pid = tfork(SDL_MintAudio_Thread, 0); | 407 SDL_MintAudio_thread_pid = tfork(SDL_MintAudio_Thread, 0); |
488 Buffoper(SB_PLA_ENA | SB_PLA_RPT); | 421 Buffoper(SB_PLA_ENA | SB_PLA_RPT); |
489 DEBUG_PRINT((DEBUG_NAME "hardware initialized\n")); | 422 DEBUG_PRINT((DEBUG_NAME "hardware initialized\n")); |
490 } | 423 } |
491 | 424 |
492 static int | 425 static int |
493 Mint_OpenAudio(_THIS, SDL_AudioSpec * spec) | 426 MINTXBIOS_OpenDevice(_THIS, const char *devname, int iscapture) |
494 { | 427 { |
495 /* Lock sound system */ | 428 /* Lock sound system */ |
496 if (Locksnd() != 1) { | 429 if (Locksnd() != 1) { |
497 SDL_SetError("Mint_OpenAudio: Audio system already in use"); | 430 SDL_SetError("MINTXBIOS_OpenAudio: Audio system already in use"); |
498 return (-1); | 431 return 0; |
499 } | 432 } |
500 | 433 |
501 SDL_MintAudio_device = this; | 434 SDL_MintAudio_device = this; |
502 | 435 |
503 /* Check audio capabilities */ | 436 /* Check audio capabilities */ |
504 if (Mint_CheckAudio(this, spec) == -1) { | 437 if (MINTXBIOS_CheckAudio(this) == -1) { |
505 return -1; | 438 return 0; |
506 } | 439 } |
507 | 440 |
508 SDL_CalculateAudioSpec(spec); | 441 /* Initialize all variables that we clean on shutdown */ |
442 this->hidden = (struct SDL_PrivateAudioData *) | |
443 SDL_malloc((sizeof *this->hidden)); | |
444 if (this->hidden == NULL) { | |
445 SDL_OutOfMemory(); | |
446 return 0; | |
447 } | |
448 SDL_memset(this->hidden, 0, (sizeof *this->hidden)); | |
449 | |
450 SDL_CalculateAudioSpec(&this->spec); | |
509 | 451 |
510 /* Allocate memory for audio buffers in DMA-able RAM */ | 452 /* Allocate memory for audio buffers in DMA-able RAM */ |
511 DEBUG_PRINT((DEBUG_NAME "buffer size=%d\n", spec->size)); | 453 DEBUG_PRINT((DEBUG_NAME "buffer size=%d\n", this->spec.size)); |
512 | 454 |
513 SDL_MintAudio_audiobuf[0] = Atari_SysMalloc(spec->size * 2, MX_STRAM); | 455 SDL_MintAudio_audiobuf[0] = Atari_SysMalloc(this->spec.size * 2, MX_STRAM); |
514 if (SDL_MintAudio_audiobuf[0] == NULL) { | 456 if (SDL_MintAudio_audiobuf[0] == NULL) { |
515 SDL_SetError("MINT_OpenAudio: Not enough memory for audio buffer"); | 457 SDL_free(this->hidden); |
516 return (-1); | 458 this->hidden = NULL; |
517 } | 459 SDL_OutOfMemory(); |
518 SDL_MintAudio_audiobuf[1] = SDL_MintAudio_audiobuf[0] + spec->size; | 460 return 0; |
461 } | |
462 SDL_MintAudio_audiobuf[1] = SDL_MintAudio_audiobuf[0] + this->spec.size; | |
519 SDL_MintAudio_numbuf = 0; | 463 SDL_MintAudio_numbuf = 0; |
520 SDL_memset(SDL_MintAudio_audiobuf[0], spec->silence, spec->size * 2); | 464 SDL_memset(SDL_MintAudio_audiobuf[0],this->spec.silence,this->spec.size*2); |
521 SDL_MintAudio_audiosize = spec->size; | 465 SDL_MintAudio_audiosize = this->spec.size; |
522 SDL_MintAudio_mutex = 0; | 466 SDL_MintAudio_mutex = 0; |
523 | 467 |
524 DEBUG_PRINT((DEBUG_NAME "buffer 0 at 0x%08x\n", | 468 DEBUG_PRINT((DEBUG_NAME "buffer 0 at 0x%08x\n", |
525 SDL_MintAudio_audiobuf[0])); | 469 SDL_MintAudio_audiobuf[0])); |
526 DEBUG_PRINT((DEBUG_NAME "buffer 1 at 0x%08x\n", | 470 DEBUG_PRINT((DEBUG_NAME "buffer 1 at 0x%08x\n", |
527 SDL_MintAudio_audiobuf[1])); | 471 SDL_MintAudio_audiobuf[1])); |
528 | 472 |
529 SDL_MintAudio_CheckFpu(); | 473 SDL_MintAudio_CheckFpu(); |
530 | 474 |
531 /* Setup audio hardware */ | 475 /* Setup audio hardware */ |
532 Mint_InitAudio(this, spec); | 476 MINTXBIOS_InitAudio(this); |
533 | 477 |
534 return (1); /* We don't use SDL threaded audio */ | 478 return 1; /* good to go. */ |
535 } | 479 } |
480 | |
481 static int | |
482 MINTXBIOS_Init(SDL_AudioDriverImpl *impl) | |
483 { | |
484 /* Set the function pointers */ | |
485 impl->OpenDevice = MINTXBIOS_OpenDevice; | |
486 impl->CloseDevice = MINTXBIOS_CloseDevice; | |
487 impl->LockAudio = MINTXBIOS_LockAudio; | |
488 impl->UnlockAudio = MINTXBIOS_UnlockAudio; | |
489 impl->OnlyHasDefaultOutputDevice = 1; | |
490 impl->ProvidesOwnCallbackThread = 1; | |
491 impl->SkipMixerLock = 1; | |
492 | |
493 return 1; | |
494 } | |
495 | |
496 AudioBootStrap MINTAUDIO_XBIOS_bootstrap = { | |
497 MINT_AUDIO_DRIVER_NAME, "MiNT XBIOS audio driver", | |
498 MINTXBIOS_Available, MINTXBIOS_Init, 0 | |
499 }; | |
536 | 500 |
537 /* vi: set ts=4 sw=4 expandtab: */ | 501 /* vi: set ts=4 sw=4 expandtab: */ |