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