comparison src/audio/mint/SDL_mintaudio_gsxb.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
61 61
62 static unsigned long cookie_snd, cookie_gsxb; 62 static unsigned long cookie_snd, cookie_gsxb;
63 63
64 /*--- Audio driver functions ---*/ 64 /*--- Audio driver functions ---*/
65 65
66 static void Mint_CloseAudio(_THIS);
67 static int Mint_OpenAudio(_THIS, SDL_AudioSpec * spec);
68 static void Mint_LockAudio(_THIS);
69 static void Mint_UnlockAudio(_THIS);
70
71 /* To check/init hardware audio */
72 static int Mint_CheckAudio(_THIS, SDL_AudioSpec * spec);
73 static void Mint_InitAudio(_THIS, SDL_AudioSpec * spec);
74
75 /* GSXB callbacks */ 66 /* GSXB callbacks */
76 static void Mint_GsxbInterrupt(void); 67 static void MINTGSXB_GsxbInterrupt(void);
77 static void Mint_GsxbNullInterrupt(void); 68 static void MINTGSXB_GsxbNullInterrupt(void);
78 69
79 /*--- Audio driver bootstrap functions ---*/
80 70
81 static int 71 static int
82 Audio_Available(void) 72 MINTGSXB_Available(void)
83 { 73 {
84 const char *envr = SDL_getenv("SDL_AUDIODRIVER");
85
86 /* Check if user asked a different audio driver */
87 if ((envr) && (SDL_strcmp(envr, MINT_AUDIO_DRIVER_NAME) != 0)) {
88 DEBUG_PRINT((DEBUG_NAME "user asked a different audio driver\n"));
89 return (0);
90 }
91
92 /* Cookie _SND present ? if not, assume ST machine */ 74 /* Cookie _SND present ? if not, assume ST machine */
93 if (Getcookie(C__SND, &cookie_snd) == C_NOTFOUND) { 75 if (Getcookie(C__SND, &cookie_snd) == C_NOTFOUND) {
94 cookie_snd = SND_PSG; 76 cookie_snd = SND_PSG;
95 } 77 }
96 78
119 101
120 DEBUG_PRINT((DEBUG_NAME "GSXB audio available!\n")); 102 DEBUG_PRINT((DEBUG_NAME "GSXB audio available!\n"));
121 return (1); 103 return (1);
122 } 104 }
123 105
124 static void 106
125 Audio_DeleteDevice(SDL_AudioDevice * device) 107 static void
126 { 108 MINTGSXB_LockDevice(_THIS)
127 SDL_free(device->hidden);
128 SDL_free(device);
129 }
130
131 static SDL_AudioDevice *
132 Audio_CreateDevice(int devindex)
133 {
134 SDL_AudioDevice *this;
135
136 /* Initialize all variables that we clean on shutdown */
137 this = (SDL_AudioDevice *) SDL_malloc(sizeof(SDL_AudioDevice));
138 if (this) {
139 SDL_memset(this, 0, (sizeof *this));
140 this->hidden = (struct SDL_PrivateAudioData *)
141 SDL_malloc((sizeof *this->hidden));
142 }
143 if ((this == NULL) || (this->hidden == NULL)) {
144 SDL_OutOfMemory();
145 if (this) {
146 SDL_free(this);
147 }
148 return (0);
149 }
150 SDL_memset(this->hidden, 0, (sizeof *this->hidden));
151
152 /* Set the function pointers */
153 this->OpenAudio = Mint_OpenAudio;
154 this->CloseAudio = Mint_CloseAudio;
155 this->LockAudio = Mint_LockAudio;
156 this->UnlockAudio = Mint_UnlockAudio;
157 this->free = Audio_DeleteDevice;
158
159 /* Uses interrupt driven audio, without thread */
160 #if SDL_THREADS_DISABLED
161 this->SkipMixerLock = 1;
162 #endif
163
164 return this;
165 }
166
167 AudioBootStrap MINTAUDIO_GSXB_bootstrap = {
168 MINT_AUDIO_DRIVER_NAME, "MiNT GSXB audio driver",
169 Audio_Available, Audio_CreateDevice, 0
170 };
171
172 static void
173 Mint_LockAudio(_THIS)
174 { 109 {
175 /* Stop replay */ 110 /* Stop replay */
176 Buffoper(0); 111 Buffoper(0);
177 } 112 }
178 113
179 static void 114 static void
180 Mint_UnlockAudio(_THIS) 115 MINTGSXB_UnlockDevice(_THIS)
181 { 116 {
182 /* Restart replay */ 117 /* Restart replay */
183 Buffoper(SB_PLA_ENA | SB_PLA_RPT); 118 Buffoper(SB_PLA_ENA | SB_PLA_RPT);
184 } 119 }
185 120
186 static void 121 static void
187 Mint_CloseAudio(_THIS) 122 MINTGSXB_CloseDevice(_THIS)
188 { 123 {
189 /* Stop replay */ 124 if (this->hidden != NULL) {
190 Buffoper(0); 125 /* Stop replay */
191 126 Buffoper(0);
192 /* Uninstall interrupt */ 127
193 if (NSetinterrupt(2, SI_NONE, Mint_GsxbNullInterrupt) < 0) { 128 /* Uninstall interrupt */
194 DEBUG_PRINT((DEBUG_NAME "NSetinterrupt() failed in close\n")); 129 if (NSetinterrupt(2, SI_NONE, MINTGSXB_GsxbNullInterrupt) < 0) {
195 } 130 DEBUG_PRINT((DEBUG_NAME "NSetinterrupt() failed in close\n"));
196 131 }
197 /* Wait if currently playing sound */ 132
198 while (SDL_MintAudio_mutex != 0) { 133 /* Wait if currently playing sound */
199 } 134 while (SDL_MintAudio_mutex != 0) {}
200 135
201 /* Clear buffers */ 136 /* Clear buffers */
202 if (SDL_MintAudio_audiobuf[0]) { 137 if (SDL_MintAudio_audiobuf[0]) {
203 Mfree(SDL_MintAudio_audiobuf[0]); 138 Mfree(SDL_MintAudio_audiobuf[0]);
204 SDL_MintAudio_audiobuf[0] = SDL_MintAudio_audiobuf[1] = NULL; 139 SDL_MintAudio_audiobuf[0] = SDL_MintAudio_audiobuf[1] = NULL;
205 } 140 }
206 141
207 /* Unlock sound system */ 142 /* Unlock sound system */
208 Unlocksnd(); 143 Unlocksnd();
144
145 SDL_free(this->hidden);
146 this->hidden = NULL;
147 }
209 } 148 }
210 149
211 static int 150 static int
212 Mint_CheckAudio(_THIS, SDL_AudioSpec * spec) 151 MINTGSXB_CheckAudio(_THIS)
213 { 152 {
214 long snd_format; 153 long snd_format;
215 int i, resolution, format_signed, format_bigendian; 154 int i, resolution, format_signed, format_bigendian;
216 SDL_AudioFormat test_format = SDL_FirstAudioFormat(spec->format); 155 SDL_AudioFormat test_format = SDL_FirstAudioFormat(this->spec.format);
217 int valid_datatype = 0; 156 int valid_datatype = 0;
218 157
219 resolution = SDL_AUDIO_BITSIZE(spec->format); 158 resolution = SDL_AUDIO_BITSIZE(this->spec.format);
220 format_signed = SDL_AUDIO_ISSIGNED(spec->format); 159 format_signed = SDL_AUDIO_ISSIGNED(this->spec.format);
221 format_bigendian = SDL_AUDIO_ISBIGENDIAN(spec->format); 160 format_bigendian = SDL_AUDIO_ISBIGENDIAN(this->spec.format);
222 161
223 DEBUG_PRINT((DEBUG_NAME "asked: %d bits, ", resolution)); 162 DEBUG_PRINT((DEBUG_NAME "asked: %d bits, ", resolution));
224 DEBUG_PRINT(("float=%d, ", SDL_AUDIO_ISFLOAT(spec->format))); 163 DEBUG_PRINT(("float=%d, ", SDL_AUDIO_ISFLOAT(this->spec.format)));
225 DEBUG_PRINT(("signed=%d, ", format_signed)); 164 DEBUG_PRINT(("signed=%d, ", format_signed));
226 DEBUG_PRINT(("big endian=%d, ", format_bigendian)); 165 DEBUG_PRINT(("big endian=%d, ", format_bigendian));
227 DEBUG_PRINT(("channels=%d, ", spec->channels)); 166 DEBUG_PRINT(("channels=%d, ", this->spec.channels));
228 DEBUG_PRINT(("freq=%d\n", spec->freq)); 167 DEBUG_PRINT(("freq=%d\n", this->spec.freq));
229 168
230 if (spec->channels > 2) { 169 if (this->spec.channels > 2) {
231 spec->channels = 2; /* no more than stereo! */ 170 this->spec.channels = 2; /* no more than stereo! */
232 } 171 }
233 172
234 while ((!valid_datatype) && (test_format)) { 173 while ((!valid_datatype) && (test_format)) {
235 /* Check formats available */ 174 /* Check formats available */
236 snd_format = Sndstatus(SND_QUERYFORMATS); 175 snd_format = Sndstatus(SND_QUERYFORMATS);
237 spec->format = test_format; 176 this->spec.format = test_format;
238 resolution = SDL_AUDIO_BITSIZE(spec->format); 177 resolution = SDL_AUDIO_BITSIZE(this->spec.format);
239 format_signed = SDL_AUDIO_ISSIGNED(spec->format); 178 format_signed = SDL_AUDIO_ISSIGNED(this->spec.format);
240 format_bigendian = SDL_AUDIO_ISBIGENDIAN(spec->format); 179 format_bigendian = SDL_AUDIO_ISBIGENDIAN(this->spec.format);
241 switch (test_format) { 180 switch (test_format) {
242 case AUDIO_U8: 181 case AUDIO_U8:
243 case AUDIO_S8: 182 case AUDIO_S8:
244 if (snd_format & SND_FORMAT8) { 183 if (snd_format & SND_FORMAT8) {
245 valid_datatype = 1; 184 valid_datatype = 1;
282 if (format_signed) { 221 if (format_signed) {
283 if (snd_format & SND_FORMATSIGNED) { 222 if (snd_format & SND_FORMATSIGNED) {
284 /* Ok */ 223 /* Ok */
285 } else if (snd_format & SND_FORMATUNSIGNED) { 224 } else if (snd_format & SND_FORMATUNSIGNED) {
286 /* Give unsigned format */ 225 /* Give unsigned format */
287 spec->format = spec->format & (~SDL_AUDIO_MASK_SIGNED); 226 this->spec.format = this->spec.format & (~SDL_AUDIO_MASK_SIGNED);
288 } 227 }
289 } else { 228 } else {
290 if (snd_format & SND_FORMATUNSIGNED) { 229 if (snd_format & SND_FORMATUNSIGNED) {
291 /* Ok */ 230 /* Ok */
292 } else if (snd_format & SND_FORMATSIGNED) { 231 } else if (snd_format & SND_FORMATSIGNED) {
293 /* Give signed format */ 232 /* Give signed format */
294 spec->format |= SDL_AUDIO_MASK_SIGNED; 233 this->spec.format |= SDL_AUDIO_MASK_SIGNED;
295 } 234 }
296 } 235 }
297 236
298 if (format_bigendian) { 237 if (format_bigendian) {
299 if (snd_format & SND_FORMATBIGENDIAN) { 238 if (snd_format & SND_FORMATBIGENDIAN) {
300 /* Ok */ 239 /* Ok */
301 } else if (snd_format & SND_FORMATLITTLEENDIAN) { 240 } else if (snd_format & SND_FORMATLITTLEENDIAN) {
302 /* Give little endian format */ 241 /* Give little endian format */
303 spec->format = spec->format & (~SDL_AUDIO_MASK_ENDIAN); 242 this->spec.format = this->spec.format & (~SDL_AUDIO_MASK_ENDIAN);
304 } 243 }
305 } else { 244 } else {
306 if (snd_format & SND_FORMATLITTLEENDIAN) { 245 if (snd_format & SND_FORMATLITTLEENDIAN) {
307 /* Ok */ 246 /* Ok */
308 } else if (snd_format & SND_FORMATBIGENDIAN) { 247 } else if (snd_format & SND_FORMATBIGENDIAN) {
309 /* Give big endian format */ 248 /* Give big endian format */
310 spec->format |= SDL_AUDIO_MASK_ENDIAN; 249 this->spec.format |= SDL_AUDIO_MASK_ENDIAN;
311 } 250 }
312 } 251 }
313 252
314 /* Calculate and select the closest frequency */ 253 /* Calculate and select the closest frequency */
315 MINTAUDIO_freqcount = 0; 254 MINTAUDIO_freqcount = 0;
327 MINTAUDIO_frequencies[i].masterclock, 266 MINTAUDIO_frequencies[i].masterclock,
328 MINTAUDIO_frequencies[i].predivisor)); 267 MINTAUDIO_frequencies[i].predivisor));
329 } 268 }
330 #endif 269 #endif
331 270
332 MINTAUDIO_numfreq = SDL_MintAudio_SearchFrequency(this, spec->freq); 271 MINTAUDIO_numfreq = SDL_MintAudio_SearchFrequency(this, this->spec.freq);
333 spec->freq = MINTAUDIO_frequencies[MINTAUDIO_numfreq].frequency; 272 this->spec.freq = MINTAUDIO_frequencies[MINTAUDIO_numfreq].frequency;
334 273
335 DEBUG_PRINT((DEBUG_NAME "obtained: %d bits, ", 274 DEBUG_PRINT((DEBUG_NAME "obtained: %d bits, ",
336 SDL_AUDIO_BITSIZE(spec->format))); 275 SDL_AUDIO_BITSIZE(this->spec.format)));
337 DEBUG_PRINT(("float=%d, ", SDL_AUDIO_ISFLOAT(spec->format))); 276 DEBUG_PRINT(("float=%d, ", SDL_AUDIO_ISFLOAT(this->spec.format)));
338 DEBUG_PRINT(("signed=%d, ", SDL_AUDIO_ISSIGNED(spec->format))); 277 DEBUG_PRINT(("signed=%d, ", SDL_AUDIO_ISSIGNED(this->spec.format)));
339 DEBUG_PRINT(("big endian=%d, ", SDL_AUDIO_ISBIGENDIAN(spec->format))); 278 DEBUG_PRINT(("big endian=%d, ", SDL_AUDIO_ISBIGENDIAN(this->spec.format)));
340 DEBUG_PRINT(("channels=%d, ", spec->channels)); 279 DEBUG_PRINT(("channels=%d, ", this->spec.channels));
341 DEBUG_PRINT(("freq=%d\n", spec->freq)); 280 DEBUG_PRINT(("freq=%d\n", this->spec.freq));
342 281
343 return 0; 282 return 0;
344 } 283 }
345 284
346 static void 285 static void
347 Mint_InitAudio(_THIS, SDL_AudioSpec * spec) 286 MINTGSXB_InitAudio(_THIS)
348 { 287 {
349 int channels_mode, prediv; 288 int channels_mode, prediv;
350 void *buffer; 289 void *buffer;
351 290
352 /* Stop currently playing sound */ 291 /* Stop currently playing sound */
355 /* Set replay tracks */ 294 /* Set replay tracks */
356 Settracks(0, 0); 295 Settracks(0, 0);
357 Setmontracks(0); 296 Setmontracks(0);
358 297
359 /* Select replay format */ 298 /* Select replay format */
360 switch (SDL_AUDIO_BITSIZE(spec->format)) { 299 switch (SDL_AUDIO_BITSIZE(this->spec.format)) {
361 case 8: 300 case 8:
362 if (spec->channels == 2) { 301 if (this->spec.channels == 2) {
363 channels_mode = STEREO8; 302 channels_mode = STEREO8;
364 } else { 303 } else {
365 channels_mode = MONO8; 304 channels_mode = MONO8;
366 } 305 }
367 break; 306 break;
368 case 16: 307 case 16:
369 if (spec->channels == 2) { 308 if (this->spec.channels == 2) {
370 channels_mode = STEREO16; 309 channels_mode = STEREO16;
371 } else { 310 } else {
372 channels_mode = MONO16; 311 channels_mode = MONO16;
373 } 312 }
374 break; 313 break;
375 case 32: 314 case 32:
376 if (spec->channels == 2) { 315 if (this->spec.channels == 2) {
377 channels_mode = STEREO32; 316 channels_mode = STEREO32;
378 } else { 317 } else {
379 channels_mode = MONO32; 318 channels_mode = MONO32;
380 } 319 }
381 break; 320 break;
390 prediv = MINTAUDIO_frequencies[MINTAUDIO_numfreq].predivisor; 329 prediv = MINTAUDIO_frequencies[MINTAUDIO_numfreq].predivisor;
391 Devconnect(DMAPLAY, DAC, CLKEXT, prediv, 1); 330 Devconnect(DMAPLAY, DAC, CLKEXT, prediv, 1);
392 331
393 /* Set buffer */ 332 /* Set buffer */
394 buffer = SDL_MintAudio_audiobuf[SDL_MintAudio_numbuf]; 333 buffer = SDL_MintAudio_audiobuf[SDL_MintAudio_numbuf];
395 if (Setbuffer(0, buffer, buffer + spec->size) < 0) { 334 if (Setbuffer(0, buffer, buffer + this->spec.size) < 0) {
396 DEBUG_PRINT((DEBUG_NAME "Setbuffer() failed\n")); 335 DEBUG_PRINT((DEBUG_NAME "Setbuffer() failed\n"));
397 } 336 }
398 337
399 /* Install interrupt */ 338 /* Install interrupt */
400 if (NSetinterrupt(2, SI_PLAY, Mint_GsxbInterrupt) < 0) { 339 if (NSetinterrupt(2, SI_PLAY, MINTGSXB_GsxbInterrupt) < 0) {
401 DEBUG_PRINT((DEBUG_NAME "NSetinterrupt() failed\n")); 340 DEBUG_PRINT((DEBUG_NAME "NSetinterrupt() failed\n"));
402 } 341 }
403 342
404 /* Go */ 343 /* Go */
405 Buffoper(SB_PLA_ENA | SB_PLA_RPT); 344 Buffoper(SB_PLA_ENA | SB_PLA_RPT);
406 DEBUG_PRINT((DEBUG_NAME "hardware initialized\n")); 345 DEBUG_PRINT((DEBUG_NAME "hardware initialized\n"));
407 } 346 }
408 347
409 static int 348 static int
410 Mint_OpenAudio(_THIS, SDL_AudioSpec * spec) 349 MINTGSXB_OpenDevice(_THIS, const char *devname, int iscapture)
411 { 350 {
412 /* Lock sound system */ 351 /* Lock sound system */
413 if (Locksnd() != 1) { 352 if (Locksnd() != 1) {
414 SDL_SetError("Mint_OpenAudio: Audio system already in use"); 353 SDL_SetError("MINTGSXB_OpenDevice: Audio system already in use");
415 return (-1); 354 return 0;
416 } 355 }
417 356
418 SDL_MintAudio_device = this; 357 SDL_MintAudio_device = this;
419 358
420 /* Check audio capabilities */ 359 /* Check audio capabilities */
421 if (Mint_CheckAudio(this, spec) == -1) { 360 if (MINTGSXB_CheckAudio(this) == -1) {
422 return -1; 361 return 0;
423 } 362 }
424 363
425 SDL_CalculateAudioSpec(spec); 364 /* Initialize all variables that we clean on shutdown */
365 this->hidden = (struct SDL_PrivateAudioData *)
366 SDL_malloc((sizeof *this->hidden));
367 if (this->hidden == NULL) {
368 SDL_OutOfMemory();
369 return 0;
370 }
371 SDL_memset(this->hidden, 0, (sizeof *this->hidden));
372
373 SDL_CalculateAudioSpec(&this->spec);
426 374
427 /* Allocate memory for audio buffers in DMA-able RAM */ 375 /* Allocate memory for audio buffers in DMA-able RAM */
428 DEBUG_PRINT((DEBUG_NAME "buffer size=%d\n", spec->size)); 376 DEBUG_PRINT((DEBUG_NAME "buffer size=%d\n", this->spec.size));
429 377
430 SDL_MintAudio_audiobuf[0] = Atari_SysMalloc(spec->size * 2, MX_STRAM); 378 SDL_MintAudio_audiobuf[0] = Atari_SysMalloc(this->spec.size * 2, MX_STRAM);
431 if (SDL_MintAudio_audiobuf[0] == NULL) { 379 if (SDL_MintAudio_audiobuf[0] == NULL) {
432 SDL_SetError("MINT_OpenAudio: Not enough memory for audio buffer"); 380 SDL_free(this->hidden);
433 return (-1); 381 this->hidden = NULL;
434 } 382 SDL_OutOfMemory();
435 SDL_MintAudio_audiobuf[1] = SDL_MintAudio_audiobuf[0] + spec->size; 383 return 0;
384 }
385 SDL_MintAudio_audiobuf[1] = SDL_MintAudio_audiobuf[0] + this->spec.size;
436 SDL_MintAudio_numbuf = 0; 386 SDL_MintAudio_numbuf = 0;
437 SDL_memset(SDL_MintAudio_audiobuf[0], spec->silence, spec->size * 2); 387 SDL_memset(SDL_MintAudio_audiobuf[0],this->spec.silence,this->spec.size*2);
438 SDL_MintAudio_audiosize = spec->size; 388 SDL_MintAudio_audiosize = this->spec.size;
439 SDL_MintAudio_mutex = 0; 389 SDL_MintAudio_mutex = 0;
440 390
441 DEBUG_PRINT((DEBUG_NAME "buffer 0 at 0x%08x\n", 391 DEBUG_PRINT((DEBUG_NAME "buffer 0 at 0x%08x\n",
442 SDL_MintAudio_audiobuf[0])); 392 SDL_MintAudio_audiobuf[0]));
443 DEBUG_PRINT((DEBUG_NAME "buffer 1 at 0x%08x\n", 393 DEBUG_PRINT((DEBUG_NAME "buffer 1 at 0x%08x\n",
444 SDL_MintAudio_audiobuf[1])); 394 SDL_MintAudio_audiobuf[1]));
445 395
446 SDL_MintAudio_CheckFpu(); 396 SDL_MintAudio_CheckFpu();
447 397
448 /* Setup audio hardware */ 398 /* Setup audio hardware */
449 Mint_InitAudio(this, spec); 399 MINTGSXB_InitAudio(this);
450 400
451 return (1); /* We don't use threaded audio */ 401 return 1; /* good to go. */
452 } 402 }
453 403
454 static void 404 static void
455 Mint_GsxbInterrupt(void) 405 MINTGSXB_GsxbInterrupt(void)
456 { 406 {
457 Uint8 *newbuf; 407 Uint8 *newbuf;
458 408
459 if (SDL_MintAudio_mutex) 409 if (SDL_MintAudio_mutex)
460 return; 410 return;
468 418
469 SDL_MintAudio_mutex = 0; 419 SDL_MintAudio_mutex = 0;
470 } 420 }
471 421
472 static void 422 static void
473 Mint_GsxbNullInterrupt(void) 423 MINTGSXB_GsxbNullInterrupt(void)
474 { 424 {
475 } 425 }
426
427 static int
428 MINTGSXB_Init(SDL_AudioDriverImpl *impl)
429 {
430 /* Set the function pointers */
431 impl->OpenDevice = MINTGSXB_OpenDevice;
432 impl->CloseDevice = MINTGSXB_CloseDevice;
433 impl->LockAudio = MINTGSXB_LockAudio;
434 impl->UnlockAudio = MINTGSXB_UnlockAudio;
435 impl->OnlyHasDefaultOutputDevice = 1;
436 impl->ProvidesOwnCallbackThread = 1;
437 impl->SkipMixerLock = 1;
438
439 return 1;
440 }
441
442 AudioBootStrap MINTAUDIO_GSXB_bootstrap = {
443 MINT_AUDIO_DRIVER_NAME, "MiNT GSXB audio driver",
444 MINTGSXB_Available, MINTGSXB_Init, 0
445 };
476 446
477 /* vi: set ts=4 sw=4 expandtab: */ 447 /* vi: set ts=4 sw=4 expandtab: */