Mercurial > sdl-ios-xcode
comparison src/audio/mint/SDL_mintaudio_stfa.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 |
---|---|
57 #define DEBUG_PRINT(what) | 57 #define DEBUG_PRINT(what) |
58 #endif | 58 #endif |
59 | 59 |
60 /*--- Static variables ---*/ | 60 /*--- Static variables ---*/ |
61 | 61 |
62 static unsigned long cookie_snd, cookie_mch; | 62 static unsigned long cookie_snd = 0; |
63 static cookie_stfa_t *cookie_stfa; | 63 static unsigned long cookie_mch = 0; |
64 static cookie_stfa_t *cookie_stfa = NULL; | |
64 | 65 |
65 static const int freqs[16] = { | 66 static const int freqs[16] = { |
66 4995, 6269, 7493, 8192, | 67 4995, 6269, 7493, 8192, |
67 9830, 10971, 12538, 14985, | 68 9830, 10971, 12538, 14985, |
68 16384, 19819, 21943, 24576, | 69 16384, 19819, 21943, 24576, |
69 30720, 32336, 43885, 49152 | 70 30720, 32336, 43885, 49152 |
70 }; | 71 }; |
71 | 72 |
72 /*--- Audio driver functions ---*/ | |
73 | |
74 static void Mint_CloseAudio(_THIS); | |
75 static int Mint_OpenAudio(_THIS, SDL_AudioSpec * spec); | |
76 static void Mint_LockAudio(_THIS); | |
77 static void Mint_UnlockAudio(_THIS); | |
78 | |
79 /* To check/init hardware audio */ | |
80 static int Mint_CheckAudio(_THIS, SDL_AudioSpec * spec); | |
81 static void Mint_InitAudio(_THIS, SDL_AudioSpec * spec); | |
82 | |
83 /*--- Audio driver bootstrap functions ---*/ | |
84 | |
85 static int | |
86 Audio_Available(void) | |
87 { | |
88 const char *envr = SDL_getenv("SDL_AUDIODRIVER"); | |
89 | |
90 /* Check if user asked a different audio driver */ | |
91 if ((envr) && (SDL_strcmp(envr, MINT_AUDIO_DRIVER_NAME) != 0)) { | |
92 DEBUG_PRINT((DEBUG_NAME "user asked a different audio driver\n")); | |
93 return (0); | |
94 } | |
95 | |
96 /* Cookie _MCH present ? if not, assume ST machine */ | |
97 if (Getcookie(C__MCH, &cookie_mch) == C_NOTFOUND) { | |
98 cookie_mch = MCH_ST; | |
99 } | |
100 | |
101 /* Cookie _SND present ? if not, assume ST machine */ | |
102 if (Getcookie(C__SND, &cookie_snd) == C_NOTFOUND) { | |
103 cookie_snd = SND_PSG; | |
104 } | |
105 | |
106 /* Cookie STFA present ? */ | |
107 if (Getcookie(C_STFA, (long *) &cookie_stfa) != C_FOUND) { | |
108 DEBUG_PRINT((DEBUG_NAME "no STFA audio\n")); | |
109 return (0); | |
110 } | |
111 | |
112 SDL_MintAudio_stfa = cookie_stfa; | |
113 | |
114 DEBUG_PRINT((DEBUG_NAME "STFA audio available!\n")); | |
115 return (1); | |
116 } | |
117 | |
118 static void | 73 static void |
119 Audio_DeleteDevice(SDL_AudioDevice * device) | 74 MINTSTFA_LockDevice(_THIS) |
120 { | 75 { |
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_STFA_bootstrap = { | |
157 MINT_AUDIO_DRIVER_NAME, "MiNT STFA audio driver", | |
158 Audio_Available, Audio_CreateDevice | |
159 }; | |
160 | |
161 static void | |
162 Mint_LockAudio(_THIS) | |
163 { | |
164 void *oldpile; | |
165 | |
166 /* Stop replay */ | 76 /* Stop replay */ |
167 oldpile = (void *) Super(0); | 77 void *oldpile = (void *) Super(0); |
168 cookie_stfa->sound_enable = STFA_PLAY_DISABLE; | 78 cookie_stfa->sound_enable = STFA_PLAY_DISABLE; |
169 Super(oldpile); | 79 Super(oldpile); |
170 } | 80 } |
171 | 81 |
172 static void | 82 static void |
173 Mint_UnlockAudio(_THIS) | 83 MINTSTFA_UnlockDevice(_THIS) |
174 { | 84 { |
175 void *oldpile; | |
176 | |
177 /* Restart replay */ | 85 /* Restart replay */ |
178 oldpile = (void *) Super(0); | 86 void *oldpile = (void *) Super(0); |
179 cookie_stfa->sound_enable = STFA_PLAY_ENABLE | STFA_PLAY_REPEAT; | 87 cookie_stfa->sound_enable = STFA_PLAY_ENABLE | STFA_PLAY_REPEAT; |
180 Super(oldpile); | 88 Super(oldpile); |
181 } | 89 } |
182 | 90 |
183 static void | 91 static void |
184 Mint_CloseAudio(_THIS) | 92 MINTSTFA_CloseDevice(_THIS) |
185 { | 93 { |
186 void *oldpile; | 94 if (this->hidden != NULL) { |
187 | 95 /* Stop replay */ |
188 /* Stop replay */ | 96 void *oldpile = (void *) Super(0); |
189 oldpile = (void *) Super(0); | 97 cookie_stfa->sound_enable = STFA_PLAY_DISABLE; |
190 cookie_stfa->sound_enable = STFA_PLAY_DISABLE; | 98 Super(oldpile); |
191 Super(oldpile); | 99 |
192 | 100 /* Wait if currently playing sound */ |
193 /* Wait if currently playing sound */ | 101 while (SDL_MintAudio_mutex != 0) {} |
194 while (SDL_MintAudio_mutex != 0) { | 102 |
195 } | 103 /* Clear buffers */ |
196 | 104 if (SDL_MintAudio_audiobuf[0]) { |
197 /* Clear buffers */ | 105 Mfree(SDL_MintAudio_audiobuf[0]); |
198 if (SDL_MintAudio_audiobuf[0]) { | 106 SDL_MintAudio_audiobuf[0] = SDL_MintAudio_audiobuf[1] = NULL; |
199 Mfree(SDL_MintAudio_audiobuf[0]); | 107 } |
200 SDL_MintAudio_audiobuf[0] = SDL_MintAudio_audiobuf[1] = NULL; | 108 |
109 SDL_free(this->hidden); | |
110 this->hidden = NULL; | |
201 } | 111 } |
202 } | 112 } |
203 | 113 |
204 static int | 114 static int |
205 Mint_CheckAudio(_THIS, SDL_AudioSpec * spec) | 115 MINTSTFA_CheckAudio(_THIS) |
206 { | 116 { |
207 int i; | 117 int i; |
208 | 118 |
209 DEBUG_PRINT((DEBUG_NAME "asked: %d bits, ", | 119 DEBUG_PRINT((DEBUG_NAME "asked: %d bits, ", |
210 SDL_AUDIO_BITSIZE(spec->format))); | 120 SDL_AUDIO_BITSIZE(this->spec.format))); |
211 DEBUG_PRINT(("float=%d, ", SDL_AUDIO_ISFLOAT(spec->format))); | 121 DEBUG_PRINT(("float=%d, ", SDL_AUDIO_ISFLOAT(this->spec.format))); |
212 DEBUG_PRINT(("signed=%d, ", SDL_AUDIO_ISSIGNED(spec->format))); | 122 DEBUG_PRINT(("signed=%d, ", SDL_AUDIO_ISSIGNED(this->spec.format))); |
213 DEBUG_PRINT(("big endian=%d, ", SDL_AUDIO_ISBIGENDIAN(spec->format))); | 123 DEBUG_PRINT(("big endian=%d, ", SDL_AUDIO_ISBIGENDIAN(this->spec.format))); |
214 DEBUG_PRINT(("channels=%d, ", spec->channels)); | 124 DEBUG_PRINT(("channels=%d, ", this->spec.channels)); |
215 DEBUG_PRINT(("freq=%d\n", spec->freq)); | 125 DEBUG_PRINT(("freq=%d\n", this->spec.freq)); |
216 | 126 |
217 if (SDL_AUDIO_BITSIZE(spec->format) > 16) { | 127 if (SDL_AUDIO_BITSIZE(this->spec.format) > 16) { |
218 spec->format = AUDIO_S16SYS; /* clamp out int32/float32 ... */ | 128 this->spec.format = AUDIO_S16SYS; /* clamp out int32/float32 ... */ |
219 } | 129 } |
220 | 130 |
221 if (spec->channels > 2) { | 131 if (this->spec.channels > 2) { |
222 spec->channels = 2; /* no more than stereo! */ | 132 this->spec.channels = 2; /* no more than stereo! */ |
223 } | 133 } |
224 | 134 |
225 /* Check formats available */ | 135 /* Check formats available */ |
226 MINTAUDIO_freqcount = 0; | 136 MINTAUDIO_freqcount = 0; |
227 for (i = 0; i < 16; i++) { | 137 for (i = 0; i < 16; i++) { |
235 MINTAUDIO_frequencies[i].masterclock, | 145 MINTAUDIO_frequencies[i].masterclock, |
236 MINTAUDIO_frequencies[i].predivisor)); | 146 MINTAUDIO_frequencies[i].predivisor)); |
237 } | 147 } |
238 #endif | 148 #endif |
239 | 149 |
240 MINTAUDIO_numfreq = SDL_MintAudio_SearchFrequency(this, spec->freq); | 150 MINTAUDIO_numfreq = SDL_MintAudio_SearchFrequency(this, this->spec.freq); |
241 spec->freq = MINTAUDIO_frequencies[MINTAUDIO_numfreq].frequency; | 151 this->spec.freq = MINTAUDIO_frequencies[MINTAUDIO_numfreq].frequency; |
242 | 152 |
243 DEBUG_PRINT((DEBUG_NAME "obtained: %d bits, ", | 153 DEBUG_PRINT((DEBUG_NAME "obtained: %d bits, ", |
244 SDL_AUDIO_BITSIZE(spec->format))); | 154 SDL_AUDIO_BITSIZE(this->spec.format))); |
245 DEBUG_PRINT(("float=%d, ", SDL_AUDIO_ISFLOAT(spec->format))); | 155 DEBUG_PRINT(("float=%d, ", SDL_AUDIO_ISFLOAT(this->spec.format))); |
246 DEBUG_PRINT(("signed=%d, ", SDL_AUDIO_ISSIGNED(spec->format))); | 156 DEBUG_PRINT(("signed=%d, ", SDL_AUDIO_ISSIGNED(this->spec.format))); |
247 DEBUG_PRINT(("big endian=%d, ", SDL_AUDIO_ISBIGENDIAN(spec->format))); | 157 DEBUG_PRINT(("big endian=%d, ", SDL_AUDIO_ISBIGENDIAN(this->spec.format))); |
248 DEBUG_PRINT(("channels=%d, ", spec->channels)); | 158 DEBUG_PRINT(("channels=%d, ", this->spec.channels)); |
249 DEBUG_PRINT(("freq=%d\n", spec->freq)); | 159 DEBUG_PRINT(("freq=%d\n", this->spec.freq)); |
250 | 160 |
251 return 0; | 161 return 0; |
252 } | 162 } |
253 | 163 |
254 static void | 164 static void |
255 Mint_InitAudio(_THIS, SDL_AudioSpec * spec) | 165 MINTSTFA_InitAudio(_THIS) |
256 { | 166 { |
257 void *buffer; | 167 void *buffer = SDL_MintAudio_audiobuf[SDL_MintAudio_numbuf]; |
258 void *oldpile; | 168 void *oldpile = (void *) Super(0); |
259 | |
260 buffer = SDL_MintAudio_audiobuf[SDL_MintAudio_numbuf]; | |
261 | |
262 oldpile = (void *) Super(0); | |
263 | 169 |
264 /* Stop replay */ | 170 /* Stop replay */ |
265 cookie_stfa->sound_enable = STFA_PLAY_DISABLE; | 171 cookie_stfa->sound_enable = STFA_PLAY_DISABLE; |
266 | 172 |
267 /* Select replay format */ | 173 /* Select replay format */ |
268 cookie_stfa->sound_control = | 174 cookie_stfa->sound_control = |
269 MINTAUDIO_frequencies[MINTAUDIO_numfreq].predivisor; | 175 MINTAUDIO_frequencies[MINTAUDIO_numfreq].predivisor; |
270 if (SDL_AUDIO_BITSIZE(spec->format) == 8) { | 176 if (SDL_AUDIO_BITSIZE(this->spec.format) == 8) { |
271 cookie_stfa->sound_control |= STFA_FORMAT_8BIT; | 177 cookie_stfa->sound_control |= STFA_FORMAT_8BIT; |
272 } else { | 178 } else { |
273 cookie_stfa->sound_control |= STFA_FORMAT_16BIT; | 179 cookie_stfa->sound_control |= STFA_FORMAT_16BIT; |
274 } | 180 } |
275 if (spec->channels == 2) { | 181 if (this->spec.channels == 2) { |
276 cookie_stfa->sound_control |= STFA_FORMAT_STEREO; | 182 cookie_stfa->sound_control |= STFA_FORMAT_STEREO; |
277 } else { | 183 } else { |
278 cookie_stfa->sound_control |= STFA_FORMAT_MONO; | 184 cookie_stfa->sound_control |= STFA_FORMAT_MONO; |
279 } | 185 } |
280 if (SDL_AUDIO_ISSIGNED(spec->format) != 0) { | 186 if (SDL_AUDIO_ISSIGNED(this->spec.format) != 0) { |
281 cookie_stfa->sound_control |= STFA_FORMAT_SIGNED; | 187 cookie_stfa->sound_control |= STFA_FORMAT_SIGNED; |
282 } else { | 188 } else { |
283 cookie_stfa->sound_control |= STFA_FORMAT_UNSIGNED; | 189 cookie_stfa->sound_control |= STFA_FORMAT_UNSIGNED; |
284 } | 190 } |
285 if (SDL_AUDIO_ISBIGENDIAN(spec->format) != 0) { | 191 if (SDL_AUDIO_ISBIGENDIAN(this->spec.format) != 0) { |
286 cookie_stfa->sound_control |= STFA_FORMAT_BIGENDIAN; | 192 cookie_stfa->sound_control |= STFA_FORMAT_BIGENDIAN; |
287 } else { | 193 } else { |
288 cookie_stfa->sound_control |= STFA_FORMAT_LITENDIAN; | 194 cookie_stfa->sound_control |= STFA_FORMAT_LITENDIAN; |
289 } | 195 } |
290 | 196 |
291 /* Set buffer */ | 197 /* Set buffer */ |
292 cookie_stfa->sound_start = (unsigned long) buffer; | 198 cookie_stfa->sound_start = (unsigned long) buffer; |
293 cookie_stfa->sound_end = (unsigned long) (buffer + spec->size); | 199 cookie_stfa->sound_end = (unsigned long) (buffer + this->spec.size); |
294 | 200 |
295 /* Set interrupt */ | 201 /* Set interrupt */ |
296 cookie_stfa->stfa_it = SDL_MintAudio_StfaInterrupt; | 202 cookie_stfa->stfa_it = SDL_MintAudio_StfaInterrupt; |
297 | 203 |
298 /* Restart replay */ | 204 /* Restart replay */ |
302 | 208 |
303 DEBUG_PRINT((DEBUG_NAME "hardware initialized\n")); | 209 DEBUG_PRINT((DEBUG_NAME "hardware initialized\n")); |
304 } | 210 } |
305 | 211 |
306 static int | 212 static int |
307 Mint_OpenAudio(_THIS, SDL_AudioSpec * spec) | 213 MINTSTFA_OpenDevice(_THIS, const char *devname, int iscapture) |
308 { | 214 { |
309 SDL_MintAudio_device = this; | 215 SDL_MintAudio_device = this; |
310 | 216 |
311 /* Check audio capabilities */ | 217 /* Check audio capabilities */ |
312 if (Mint_CheckAudio(this, spec) == -1) { | 218 if (MINTSTFA_CheckAudio(this) == -1) { |
313 return -1; | 219 return 0; |
314 } | 220 } |
315 | 221 |
316 SDL_CalculateAudioSpec(spec); | 222 /* Initialize all variables that we clean on shutdown */ |
223 this->hidden = (struct SDL_PrivateAudioData *) | |
224 SDL_malloc((sizeof *this->hidden)); | |
225 if (this->hidden == NULL) { | |
226 SDL_OutOfMemory(); | |
227 return 0; | |
228 } | |
229 SDL_memset(this->hidden, 0, (sizeof *this->hidden)); | |
230 | |
231 SDL_CalculateAudioSpec(&this->spec); | |
317 | 232 |
318 /* Allocate memory for audio buffers in DMA-able RAM */ | 233 /* Allocate memory for audio buffers in DMA-able RAM */ |
319 DEBUG_PRINT((DEBUG_NAME "buffer size=%d\n", spec->size)); | 234 DEBUG_PRINT((DEBUG_NAME "buffer size=%d\n", this->spec.size)); |
320 | 235 |
321 SDL_MintAudio_audiobuf[0] = Atari_SysMalloc(spec->size * 2, MX_STRAM); | 236 SDL_MintAudio_audiobuf[0] = Atari_SysMalloc(this->spec.size * 2, MX_STRAM); |
322 if (SDL_MintAudio_audiobuf[0] == NULL) { | 237 if (SDL_MintAudio_audiobuf[0] == NULL) { |
323 SDL_SetError("MINT_OpenAudio: Not enough memory for audio buffer"); | 238 SDL_OutOfMemory() |
324 return (-1); | 239 SDL_free(this->hidden); |
325 } | 240 this->hidden = NULL; |
326 SDL_MintAudio_audiobuf[1] = SDL_MintAudio_audiobuf[0] + spec->size; | 241 return 0; |
242 } | |
243 SDL_MintAudio_audiobuf[1] = SDL_MintAudio_audiobuf[0] + this->spec.size; | |
327 SDL_MintAudio_numbuf = 0; | 244 SDL_MintAudio_numbuf = 0; |
328 SDL_memset(SDL_MintAudio_audiobuf[0], spec->silence, spec->size * 2); | 245 SDL_memset(SDL_MintAudio_audiobuf[0],this->spec.silence,this->spec.size*2); |
329 SDL_MintAudio_audiosize = spec->size; | 246 SDL_MintAudio_audiosize = this->spec.size; |
330 SDL_MintAudio_mutex = 0; | 247 SDL_MintAudio_mutex = 0; |
331 | 248 |
332 DEBUG_PRINT((DEBUG_NAME "buffer 0 at 0x%08x\n", | 249 DEBUG_PRINT((DEBUG_NAME "buffer 0 at 0x%08x\n", |
333 SDL_MintAudio_audiobuf[0])); | 250 SDL_MintAudio_audiobuf[0])); |
334 DEBUG_PRINT((DEBUG_NAME "buffer 1 at 0x%08x\n", | 251 DEBUG_PRINT((DEBUG_NAME "buffer 1 at 0x%08x\n", |
335 SDL_MintAudio_audiobuf[1])); | 252 SDL_MintAudio_audiobuf[1])); |
336 | 253 |
337 SDL_MintAudio_CheckFpu(); | 254 SDL_MintAudio_CheckFpu(); |
338 | 255 |
339 /* Setup audio hardware */ | 256 /* Setup audio hardware */ |
340 Mint_InitAudio(this, spec); | 257 MINTSTFA_InitAudio(this); |
341 | 258 |
342 return (1); /* We don't use threaded audio */ | 259 return 1; /* good to go. */ |
343 } | 260 } |
261 | |
262 | |
263 static int | |
264 MINTSTFA_Init(SDL_AudioDriverImpl *impl) | |
265 { | |
266 /* Cookie _MCH present ? if not, assume ST machine */ | |
267 if (Getcookie(C__MCH, &cookie_mch) == C_NOTFOUND) { | |
268 cookie_mch = MCH_ST; | |
269 } | |
270 | |
271 /* Cookie _SND present ? if not, assume ST machine */ | |
272 if (Getcookie(C__SND, &cookie_snd) == C_NOTFOUND) { | |
273 cookie_snd = SND_PSG; | |
274 } | |
275 | |
276 /* Cookie STFA present ? */ | |
277 if (Getcookie(C_STFA, (long *) &cookie_stfa) != C_FOUND) { | |
278 SDL_SetError(DEBUG_NAME "no STFA audio"); | |
279 return (0); | |
280 } | |
281 | |
282 SDL_MintAudio_stfa = cookie_stfa; | |
283 | |
284 DEBUG_PRINT((DEBUG_NAME "STFA audio available!\n")); | |
285 | |
286 /* Set the function pointers */ | |
287 impl->OpenDevice = MINTSTFA_OpenDevice; | |
288 impl->CloseDevice = MINTSTFA_CloseDevice; | |
289 impl->LockAudio = MINTSTFA_LockAudio; | |
290 impl->UnlockAudio = MINTSTFA_UnlockAudio; | |
291 impl->OnlyHasDefaultOutputDevice = 1; | |
292 impl->ProvidesOwnCallbackThread = 1; | |
293 impl->SkipMixerLock = 1; | |
294 | |
295 return 1; | |
296 } | |
297 | |
298 AudioBootStrap MINTAUDIO_STFA_bootstrap = { | |
299 MINT_AUDIO_DRIVER_NAME, "MiNT STFA audio driver", MINTSTFA_Init, 0 | |
300 }; | |
344 | 301 |
345 /* vi: set ts=4 sw=4 expandtab: */ | 302 /* vi: set ts=4 sw=4 expandtab: */ |