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