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