Mercurial > sdl-ios-xcode
comparison src/audio/mint/SDL_mintaudio_dma8.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 | 59 |
60 /*--- Static variables ---*/ | 60 /*--- Static variables ---*/ |
61 | 61 |
62 static unsigned long cookie_snd, cookie_mch; | 62 static unsigned long cookie_snd, cookie_mch; |
63 | 63 |
64 /*--- Audio driver functions ---*/ | |
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 /*--- Audio driver bootstrap functions ---*/ | |
76 | 64 |
77 static int | 65 static int |
78 Audio_Available(void) | 66 MINTDMA8_Available(void) |
79 { | 67 { |
80 const char *envr = SDL_getenv("SDL_AUDIODRIVER"); | |
81 | |
82 /* Check if user asked a different audio driver */ | |
83 if ((envr) && (SDL_strcmp(envr, MINT_AUDIO_DRIVER_NAME) != 0)) { | |
84 DEBUG_PRINT((DEBUG_NAME "user asked a different audio driver\n")); | |
85 return 0; | |
86 } | |
87 | |
88 /* Cookie _MCH present ? if not, assume ST machine */ | 68 /* Cookie _MCH present ? if not, assume ST machine */ |
89 if (Getcookie(C__MCH, &cookie_mch) == C_NOTFOUND) { | 69 if (Getcookie(C__MCH, &cookie_mch) == C_NOTFOUND) { |
90 cookie_mch = MCH_ST; | 70 cookie_mch = MCH_ST; |
91 } | 71 } |
92 | 72 |
114 DEBUG_PRINT((DEBUG_NAME "8 bits audio available!\n")); | 94 DEBUG_PRINT((DEBUG_NAME "8 bits audio available!\n")); |
115 return (1); | 95 return (1); |
116 } | 96 } |
117 | 97 |
118 static void | 98 static void |
119 Audio_DeleteDevice(SDL_AudioDevice * device) | 99 MINTDMA8_LockDevice(_THIS) |
120 { | |
121 SDL_free(device->hidden); | |
122 SDL_free(device); | |
123 } | |
124 | |
125 static SDL_AudioDevice * | |
126 Audio_CreateDevice(int devindex) | |
127 { | |
128 SDL_AudioDevice *this; | |
129 | |
130 /* Initialize all variables that we clean on shutdown */ | |
131 this = (SDL_AudioDevice *) SDL_malloc(sizeof(SDL_AudioDevice)); | |
132 if (this) { | |
133 SDL_memset(this, 0, (sizeof *this)); | |
134 this->hidden = (struct SDL_PrivateAudioData *) | |
135 SDL_malloc((sizeof *this->hidden)); | |
136 } | |
137 if ((this == NULL) || (this->hidden == NULL)) { | |
138 SDL_OutOfMemory(); | |
139 if (this) { | |
140 SDL_free(this); | |
141 } | |
142 return (0); | |
143 } | |
144 SDL_memset(this->hidden, 0, (sizeof *this->hidden)); | |
145 | |
146 /* Set the function pointers */ | |
147 this->OpenAudio = Mint_OpenAudio; | |
148 this->CloseAudio = Mint_CloseAudio; | |
149 this->LockAudio = Mint_LockAudio; | |
150 this->UnlockAudio = Mint_UnlockAudio; | |
151 this->free = Audio_DeleteDevice; | |
152 | |
153 /* Uses interrupt driven audio, without thread */ | |
154 #if SDL_THREADS_DISABLED | |
155 this->SkipMixerLock = 1; | |
156 #endif | |
157 | |
158 return this; | |
159 } | |
160 | |
161 AudioBootStrap MINTAUDIO_DMA8_bootstrap = { | |
162 MINT_AUDIO_DRIVER_NAME, "MiNT DMA 8 bits audio driver", | |
163 Audio_Available, Audio_CreateDevice, 0 | |
164 }; | |
165 | |
166 static void | |
167 Mint_LockAudio(_THIS) | |
168 { | 100 { |
169 void *oldpile; | 101 void *oldpile; |
170 | 102 |
171 /* Stop replay */ | 103 /* Stop replay */ |
172 oldpile = (void *) Super(0); | 104 oldpile = (void *) Super(0); |
173 DMAAUDIO_IO.control = 0; | 105 DMAAUDIO_IO.control = 0; |
174 Super(oldpile); | 106 Super(oldpile); |
175 } | 107 } |
176 | 108 |
177 static void | 109 static void |
178 Mint_UnlockAudio(_THIS) | 110 MINTDMA8_UnlockDevice(_THIS) |
179 { | 111 { |
180 void *oldpile; | 112 void *oldpile; |
181 | 113 |
182 /* Restart replay */ | 114 /* Restart replay */ |
183 oldpile = (void *) Super(0); | 115 oldpile = (void *) Super(0); |
184 DMAAUDIO_IO.control = 3; | 116 DMAAUDIO_IO.control = 3; |
185 Super(oldpile); | 117 Super(oldpile); |
186 } | 118 } |
187 | 119 |
188 static void | 120 static void |
189 Mint_CloseAudio(_THIS) | 121 MINTDMA8_CloseDevice(_THIS) |
190 { | 122 { |
191 void *oldpile; | 123 if (this->hidden != NULL) { |
192 | 124 /* Stop replay */ |
193 /* Stop replay */ | 125 void *oldpile = (void *) Super(0); |
194 oldpile = (void *) Super(0); | 126 |
195 DMAAUDIO_IO.control = 0; | 127 DMAAUDIO_IO.control = 0; |
196 Super(oldpile); | 128 Super(oldpile); |
197 | 129 |
198 DEBUG_PRINT((DEBUG_NAME "closeaudio: replay stopped\n")); | 130 DEBUG_PRINT((DEBUG_NAME "closeaudio: replay stopped\n")); |
199 | 131 |
200 /* Disable interrupt */ | 132 /* Disable interrupt */ |
201 Jdisint(MFP_DMASOUND); | 133 Jdisint(MFP_DMASOUND); |
202 | 134 |
203 DEBUG_PRINT((DEBUG_NAME "closeaudio: interrupt disabled\n")); | 135 DEBUG_PRINT((DEBUG_NAME "closeaudio: interrupt disabled\n")); |
204 | 136 |
205 /* Wait if currently playing sound */ | 137 /* Wait if currently playing sound */ |
206 while (SDL_MintAudio_mutex != 0) { | 138 while (SDL_MintAudio_mutex != 0) {} |
207 } | 139 |
208 | 140 DEBUG_PRINT((DEBUG_NAME "closeaudio: no more interrupt running\n")); |
209 DEBUG_PRINT((DEBUG_NAME "closeaudio: no more interrupt running\n")); | 141 |
210 | 142 /* Clear buffers */ |
211 /* Clear buffers */ | 143 if (SDL_MintAudio_audiobuf[0]) { |
212 if (SDL_MintAudio_audiobuf[0]) { | 144 Mfree(SDL_MintAudio_audiobuf[0]); |
213 Mfree(SDL_MintAudio_audiobuf[0]); | 145 SDL_MintAudio_audiobuf[0] = SDL_MintAudio_audiobuf[1] = NULL; |
214 SDL_MintAudio_audiobuf[0] = SDL_MintAudio_audiobuf[1] = NULL; | 146 } |
215 } | 147 |
216 | 148 DEBUG_PRINT((DEBUG_NAME "closeaudio: buffers freed\n")); |
217 DEBUG_PRINT((DEBUG_NAME "closeaudio: buffers freed\n")); | 149 SDL_free(this->buffer); |
150 this->buffer = NULL; | |
151 } | |
218 } | 152 } |
219 | 153 |
220 static int | 154 static int |
221 Mint_CheckAudio(_THIS, SDL_AudioSpec * spec) | 155 MINTDMA8_CheckAudio(_THIS) |
222 { | 156 { |
223 int i, masterprediv, sfreq; | 157 int i, masterprediv, sfreq; |
224 unsigned long masterclock; | 158 unsigned long masterclock; |
225 | 159 |
226 DEBUG_PRINT((DEBUG_NAME "asked: %d bits, ", | 160 DEBUG_PRINT((DEBUG_NAME "asked: %d bits, ", |
227 SDL_AUDIO_BITSIZE(spec->format))); | 161 SDL_AUDIO_BITSIZE(this->spec.format))); |
228 DEBUG_PRINT(("float=%d, ", SDL_AUDIO_ISFLOAT(spec->format))); | 162 DEBUG_PRINT(("float=%d, ", SDL_AUDIO_ISFLOAT(this->spec.format))); |
229 DEBUG_PRINT(("signed=%d, ", SDL_AUDIO_ISSIGNED(spec->format))); | 163 DEBUG_PRINT(("signed=%d, ", SDL_AUDIO_ISSIGNED(this->spec.format))); |
230 DEBUG_PRINT(("big endian=%d, ", SDL_AUDIO_ISBIGENDIAN(spec->format))); | 164 DEBUG_PRINT(("big endian=%d, ", SDL_AUDIO_ISBIGENDIAN(this->spec.format))); |
231 DEBUG_PRINT(("channels=%d, ", spec->channels)); | 165 DEBUG_PRINT(("channels=%d, ", this->spec.channels)); |
232 DEBUG_PRINT(("freq=%d\n", spec->freq)); | 166 DEBUG_PRINT(("freq=%d\n", this->spec.freq)); |
233 | 167 |
234 if (spec->channels > 2) { | 168 if (this->spec.channels > 2) { |
235 spec->channels = 2; /* no more than stereo! */ | 169 this->spec.channels = 2; /* no more than stereo! */ |
236 } | 170 } |
237 | 171 |
238 /* Check formats available */ | 172 /* Check formats available */ |
239 spec->format = AUDIO_S8; | 173 this->spec.format = AUDIO_S8; |
240 | 174 |
241 /* Calculate and select the closest frequency */ | 175 /* Calculate and select the closest frequency */ |
242 sfreq = 0; | 176 sfreq = 0; |
243 masterclock = MASTERCLOCK_STE; | 177 masterclock = MASTERCLOCK_STE; |
244 masterprediv = MASTERPREDIV_STE; | 178 masterprediv = MASTERPREDIV_STE; |
275 MINTAUDIO_frequencies[i].masterclock, | 209 MINTAUDIO_frequencies[i].masterclock, |
276 MINTAUDIO_frequencies[i].predivisor)); | 210 MINTAUDIO_frequencies[i].predivisor)); |
277 } | 211 } |
278 #endif | 212 #endif |
279 | 213 |
280 MINTAUDIO_numfreq = SDL_MintAudio_SearchFrequency(this, spec->freq); | 214 MINTAUDIO_numfreq = SDL_MintAudio_SearchFrequency(this, this->spec.freq); |
281 spec->freq = MINTAUDIO_frequencies[MINTAUDIO_numfreq].frequency; | 215 this->spec.freq = MINTAUDIO_frequencies[MINTAUDIO_numfreq].frequency; |
282 | 216 |
283 DEBUG_PRINT((DEBUG_NAME "obtained: %d bits, ", | 217 DEBUG_PRINT((DEBUG_NAME "obtained: %d bits, ", |
284 SDL_AUDIO_BITSIZE(spec->format))); | 218 SDL_AUDIO_BITSIZE(this->spec.format))); |
285 DEBUG_PRINT(("float=%d, ", SDL_AUDIO_ISFLOAT(spec->format))); | 219 DEBUG_PRINT(("float=%d, ", SDL_AUDIO_ISFLOAT(this->spec.format))); |
286 DEBUG_PRINT(("signed=%d, ", SDL_AUDIO_ISSIGNED(spec->format))); | 220 DEBUG_PRINT(("signed=%d, ", SDL_AUDIO_ISSIGNED(this->spec.format))); |
287 DEBUG_PRINT(("big endian=%d, ", SDL_AUDIO_ISBIGENDIAN(spec->format))); | 221 DEBUG_PRINT(("big endian=%d, ", SDL_AUDIO_ISBIGENDIAN(this->spec.format))); |
288 DEBUG_PRINT(("channels=%d, ", spec->channels)); | 222 DEBUG_PRINT(("channels=%d, ", this->spec.channels)); |
289 DEBUG_PRINT(("freq=%d\n", spec->freq)); | 223 DEBUG_PRINT(("freq=%d\n", this->spec.freq)); |
290 | 224 |
291 return 0; | 225 return 0; |
292 } | 226 } |
293 | 227 |
294 static void | 228 static void |
295 Mint_InitAudio(_THIS, SDL_AudioSpec * spec) | 229 MINTDMA8_InitAudio(_THIS) |
296 { | 230 { |
297 void *oldpile; | 231 void *oldpile; |
298 unsigned long buffer; | 232 unsigned long buffer; |
299 unsigned char mode; | 233 unsigned char mode; |
300 | 234 |
319 DMAAUDIO_IO.end_high = (buffer >> 16) & 255; | 253 DMAAUDIO_IO.end_high = (buffer >> 16) & 255; |
320 DMAAUDIO_IO.end_mid = (buffer >> 8) & 255; | 254 DMAAUDIO_IO.end_mid = (buffer >> 8) & 255; |
321 DMAAUDIO_IO.end_low = buffer & 255; | 255 DMAAUDIO_IO.end_low = buffer & 255; |
322 | 256 |
323 mode = 3 - MINTAUDIO_frequencies[MINTAUDIO_numfreq].predivisor; | 257 mode = 3 - MINTAUDIO_frequencies[MINTAUDIO_numfreq].predivisor; |
324 if (spec->channels == 1) { | 258 if (this->spec.channels == 1) { |
325 mode |= 1 << 7; | 259 mode |= 1 << 7; |
326 } | 260 } |
327 DMAAUDIO_IO.sound_ctrl = mode; | 261 DMAAUDIO_IO.sound_ctrl = mode; |
328 | 262 |
329 /* Set interrupt */ | 263 /* Set interrupt */ |
342 | 276 |
343 Super(oldpile); | 277 Super(oldpile); |
344 } | 278 } |
345 | 279 |
346 static int | 280 static int |
347 Mint_OpenAudio(_THIS, SDL_AudioSpec * spec) | 281 MINTDMA8_OpenDevice(_THIS, const char *devname, int iscapture) |
348 { | 282 { |
349 SDL_MintAudio_device = this; | 283 SDL_MintAudio_device = this; |
350 | 284 |
351 /* Check audio capabilities */ | 285 /* Check audio capabilities */ |
352 if (Mint_CheckAudio(this, spec) == -1) { | 286 if (MINTDMA8_CheckAudio(this) == -1) { |
353 return -1; | 287 return 0; |
354 } | 288 } |
355 | 289 |
356 SDL_CalculateAudioSpec(spec); | 290 /* Initialize all variables that we clean on shutdown */ |
291 this->hidden = (struct SDL_PrivateAudioData *) | |
292 SDL_malloc((sizeof *this->hidden)); | |
293 if (this->hidden == NULL) { | |
294 SDL_OutOfMemory(); | |
295 return 0; | |
296 } | |
297 SDL_memset(this->hidden, 0, (sizeof *this->hidden)); | |
298 | |
299 SDL_CalculateAudioSpec(&this->spec); | |
357 | 300 |
358 /* Allocate memory for audio buffers in DMA-able RAM */ | 301 /* Allocate memory for audio buffers in DMA-able RAM */ |
359 DEBUG_PRINT((DEBUG_NAME "buffer size=%d\n", spec->size)); | 302 DEBUG_PRINT((DEBUG_NAME "buffer size=%d\n", this->spec.size)); |
360 | 303 |
361 SDL_MintAudio_audiobuf[0] = Atari_SysMalloc(spec->size * 2, MX_STRAM); | 304 SDL_MintAudio_audiobuf[0] = Atari_SysMalloc(this->spec.size * 2, MX_STRAM); |
362 if (SDL_MintAudio_audiobuf[0] == NULL) { | 305 if (SDL_MintAudio_audiobuf[0] == NULL) { |
363 SDL_SetError("MINT_OpenAudio: Not enough memory for audio buffer"); | 306 SDL_free(this->hidden); |
364 return (-1); | 307 this->hidden = NULL; |
365 } | 308 SDL_OutOfMemory(); |
366 SDL_MintAudio_audiobuf[1] = SDL_MintAudio_audiobuf[0] + spec->size; | 309 return 0; |
310 } | |
311 SDL_MintAudio_audiobuf[1] = SDL_MintAudio_audiobuf[0] + this->spec.size; | |
367 SDL_MintAudio_numbuf = 0; | 312 SDL_MintAudio_numbuf = 0; |
368 SDL_memset(SDL_MintAudio_audiobuf[0], spec->silence, spec->size * 2); | 313 SDL_memset(SDL_MintAudio_audiobuf[0],this->spec.silence,this->spec.size*2); |
369 SDL_MintAudio_audiosize = spec->size; | 314 SDL_MintAudio_audiosize = this->spec.size; |
370 SDL_MintAudio_mutex = 0; | 315 SDL_MintAudio_mutex = 0; |
371 | 316 |
372 DEBUG_PRINT((DEBUG_NAME "buffer 0 at 0x%08x\n", | 317 DEBUG_PRINT((DEBUG_NAME "buffer 0 at 0x%08x\n", |
373 SDL_MintAudio_audiobuf[0])); | 318 SDL_MintAudio_audiobuf[0])); |
374 DEBUG_PRINT((DEBUG_NAME "buffer 1 at 0x%08x\n", | 319 DEBUG_PRINT((DEBUG_NAME "buffer 1 at 0x%08x\n", |
375 SDL_MintAudio_audiobuf[1])); | 320 SDL_MintAudio_audiobuf[1])); |
376 | 321 |
377 SDL_MintAudio_CheckFpu(); | 322 SDL_MintAudio_CheckFpu(); |
378 | 323 |
379 /* Setup audio hardware */ | 324 /* Setup audio hardware */ |
380 Mint_InitAudio(this, spec); | 325 MINTDMA8_InitAudio(this); |
381 | 326 |
382 return (1); /* We don't use threaded audio */ | 327 return 1; /* good to go. */ |
383 } | 328 } |
329 | |
330 static int | |
331 MINTDMA8_Init(SDL_AudioDriverImpl *impl) | |
332 { | |
333 /* Set the function pointers */ | |
334 impl->OpenDevice = MINTDMA8_OpenDevice; | |
335 impl->CloseDevice = MINTDMA8_CloseDevice; | |
336 impl->LockAudio = MINTDMA8_LockAudio; | |
337 impl->UnlockAudio = MINTDMA8_UnlockAudio; | |
338 impl->OnlyHasDefaultOutputDevice = 1; | |
339 impl->ProvidesOwnCallbackThread = 1; | |
340 impl->SkipMixerLock = 1; | |
341 | |
342 return 1; | |
343 } | |
344 | |
345 AudioBootStrap MINTAUDIO_DMA8_bootstrap = { | |
346 MINT_AUDIO_DRIVER_NAME, "MiNT DMA 8 bits audio driver", | |
347 MINTDMA8_Available, MINTDMA8_Init, 0 | |
348 }; | |
384 | 349 |
385 /* vi: set ts=4 sw=4 expandtab: */ | 350 /* vi: set ts=4 sw=4 expandtab: */ |