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