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