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: */