comparison src/audio/mint/SDL_mintaudio_dma8.c @ 1895:c121d94672cb

SDL 1.2 is moving to a branch, and SDL 1.3 is becoming the head.
author Sam Lantinga <slouken@libsdl.org>
date Mon, 10 Jul 2006 21:04:37 +0000
parents a8181c4040b8
children 45af7d69f8eb
comparison
equal deleted inserted replaced
1894:c69cee13dd76 1895:c121d94672cb
62 static unsigned long cookie_snd, cookie_mch; 62 static unsigned long cookie_snd, cookie_mch;
63 63
64 /*--- Audio driver functions ---*/ 64 /*--- Audio driver functions ---*/
65 65
66 static void Mint_CloseAudio(_THIS); 66 static void Mint_CloseAudio(_THIS);
67 static int Mint_OpenAudio(_THIS, SDL_AudioSpec *spec); 67 static int Mint_OpenAudio(_THIS, SDL_AudioSpec * spec);
68 static void Mint_LockAudio(_THIS); 68 static void Mint_LockAudio(_THIS);
69 static void Mint_UnlockAudio(_THIS); 69 static void Mint_UnlockAudio(_THIS);
70 70
71 /* To check/init hardware audio */ 71 /* To check/init hardware audio */
72 static int Mint_CheckAudio(_THIS, SDL_AudioSpec *spec); 72 static int Mint_CheckAudio(_THIS, SDL_AudioSpec * spec);
73 static void Mint_InitAudio(_THIS, SDL_AudioSpec *spec); 73 static void Mint_InitAudio(_THIS, SDL_AudioSpec * spec);
74 74
75 /*--- Audio driver bootstrap functions ---*/ 75 /*--- Audio driver bootstrap functions ---*/
76 76
77 static int Audio_Available(void) 77 static int
78 { 78 Audio_Available(void)
79 const char *envr = SDL_getenv("SDL_AUDIODRIVER"); 79 {
80 80 const char *envr = SDL_getenv("SDL_AUDIODRIVER");
81 /* Check if user asked a different audio driver */ 81
82 if ((envr) && (SDL_strcmp(envr, MINT_AUDIO_DRIVER_NAME)!=0)) { 82 /* Check if user asked a different audio driver */
83 DEBUG_PRINT((DEBUG_NAME "user asked a different audio driver\n")); 83 if ((envr) && (SDL_strcmp(envr, MINT_AUDIO_DRIVER_NAME) != 0)) {
84 return 0; 84 DEBUG_PRINT((DEBUG_NAME "user asked a different audio driver\n"));
85 } 85 return 0;
86 86 }
87 /* Cookie _MCH present ? if not, assume ST machine */ 87
88 if (Getcookie(C__MCH, &cookie_mch) == C_NOTFOUND) { 88 /* Cookie _MCH present ? if not, assume ST machine */
89 cookie_mch = MCH_ST; 89 if (Getcookie(C__MCH, &cookie_mch) == C_NOTFOUND) {
90 } 90 cookie_mch = MCH_ST;
91 91 }
92 /* Cookie _SND present ? if not, assume ST machine */ 92
93 if (Getcookie(C__SND, &cookie_snd) == C_NOTFOUND) { 93 /* Cookie _SND present ? if not, assume ST machine */
94 cookie_snd = SND_PSG; 94 if (Getcookie(C__SND, &cookie_snd) == C_NOTFOUND) {
95 } 95 cookie_snd = SND_PSG;
96 96 }
97 /* Check if we have 8 bits audio */ 97
98 if ((cookie_snd & SND_8BIT)==0) { 98 /* Check if we have 8 bits audio */
99 DEBUG_PRINT((DEBUG_NAME "no 8 bits sound\n")); 99 if ((cookie_snd & SND_8BIT) == 0) {
100 return(0); 100 DEBUG_PRINT((DEBUG_NAME "no 8 bits sound\n"));
101 } 101 return (0);
102 102 }
103 /* Check if audio is lockable */ 103
104 if (cookie_snd & SND_16BIT) { 104 /* Check if audio is lockable */
105 if (Locksnd()!=1) { 105 if (cookie_snd & SND_16BIT) {
106 DEBUG_PRINT((DEBUG_NAME "audio locked by other application\n")); 106 if (Locksnd() != 1) {
107 return(0); 107 DEBUG_PRINT((DEBUG_NAME "audio locked by other application\n"));
108 } 108 return (0);
109 109 }
110 Unlocksnd(); 110
111 } 111 Unlocksnd();
112 112 }
113 DEBUG_PRINT((DEBUG_NAME "8 bits audio available!\n")); 113
114 return(1); 114 DEBUG_PRINT((DEBUG_NAME "8 bits audio available!\n"));
115 } 115 return (1);
116 116 }
117 static void Audio_DeleteDevice(SDL_AudioDevice *device) 117
118 static void
119 Audio_DeleteDevice(SDL_AudioDevice * device)
118 { 120 {
119 SDL_free(device->hidden); 121 SDL_free(device->hidden);
120 SDL_free(device); 122 SDL_free(device);
121 } 123 }
122 124
123 static SDL_AudioDevice *Audio_CreateDevice(int devindex) 125 static SDL_AudioDevice *
124 { 126 Audio_CreateDevice(int devindex)
125 SDL_AudioDevice *this; 127 {
126 128 SDL_AudioDevice *this;
127 /* Initialize all variables that we clean on shutdown */ 129
128 this = (SDL_AudioDevice *)SDL_malloc(sizeof(SDL_AudioDevice)); 130 /* Initialize all variables that we clean on shutdown */
129 if ( this ) { 131 this = (SDL_AudioDevice *) SDL_malloc(sizeof(SDL_AudioDevice));
132 if (this) {
130 SDL_memset(this, 0, (sizeof *this)); 133 SDL_memset(this, 0, (sizeof *this));
131 this->hidden = (struct SDL_PrivateAudioData *) 134 this->hidden = (struct SDL_PrivateAudioData *)
132 SDL_malloc((sizeof *this->hidden)); 135 SDL_malloc((sizeof *this->hidden));
133 } 136 }
134 if ( (this == NULL) || (this->hidden == NULL) ) { 137 if ((this == NULL) || (this->hidden == NULL)) {
135 SDL_OutOfMemory(); 138 SDL_OutOfMemory();
136 if ( this ) { 139 if (this) {
137 SDL_free(this); 140 SDL_free(this);
138 } 141 }
139 return(0); 142 return (0);
140 } 143 }
141 SDL_memset(this->hidden, 0, (sizeof *this->hidden)); 144 SDL_memset(this->hidden, 0, (sizeof *this->hidden));
142 145
143 /* Set the function pointers */ 146 /* Set the function pointers */
144 this->OpenAudio = Mint_OpenAudio; 147 this->OpenAudio = Mint_OpenAudio;
145 this->CloseAudio = Mint_CloseAudio; 148 this->CloseAudio = Mint_CloseAudio;
146 this->LockAudio = Mint_LockAudio; 149 this->LockAudio = Mint_LockAudio;
147 this->UnlockAudio = Mint_UnlockAudio; 150 this->UnlockAudio = Mint_UnlockAudio;
148 this->free = Audio_DeleteDevice; 151 this->free = Audio_DeleteDevice;
149 152
150 return this; 153 return this;
151 } 154 }
152 155
153 AudioBootStrap MINTAUDIO_DMA8_bootstrap = { 156 AudioBootStrap MINTAUDIO_DMA8_bootstrap = {
154 MINT_AUDIO_DRIVER_NAME, "MiNT DMA 8 bits audio driver", 157 MINT_AUDIO_DRIVER_NAME, "MiNT DMA 8 bits audio driver",
155 Audio_Available, Audio_CreateDevice 158 Audio_Available, Audio_CreateDevice
156 }; 159 };
157 160
158 static void Mint_LockAudio(_THIS) 161 static void
159 { 162 Mint_LockAudio(_THIS)
160 void *oldpile; 163 {
161 164 void *oldpile;
162 /* Stop replay */ 165
163 oldpile=(void *)Super(0); 166 /* Stop replay */
164 DMAAUDIO_IO.control=0; 167 oldpile = (void *) Super(0);
165 Super(oldpile); 168 DMAAUDIO_IO.control = 0;
166 } 169 Super(oldpile);
167 170 }
168 static void Mint_UnlockAudio(_THIS) 171
169 { 172 static void
170 void *oldpile; 173 Mint_UnlockAudio(_THIS)
171 174 {
172 /* Restart replay */ 175 void *oldpile;
173 oldpile=(void *)Super(0); 176
174 DMAAUDIO_IO.control=3; 177 /* Restart replay */
175 Super(oldpile); 178 oldpile = (void *) Super(0);
176 } 179 DMAAUDIO_IO.control = 3;
177 180 Super(oldpile);
178 static void Mint_CloseAudio(_THIS) 181 }
179 { 182
180 void *oldpile; 183 static void
181 184 Mint_CloseAudio(_THIS)
182 /* Stop replay */ 185 {
183 oldpile=(void *)Super(0); 186 void *oldpile;
184 DMAAUDIO_IO.control=0; 187
185 Super(oldpile); 188 /* Stop replay */
186 189 oldpile = (void *) Super(0);
187 DEBUG_PRINT((DEBUG_NAME "closeaudio: replay stopped\n")); 190 DMAAUDIO_IO.control = 0;
188 191 Super(oldpile);
189 /* Disable interrupt */ 192
190 Jdisint(MFP_DMASOUND); 193 DEBUG_PRINT((DEBUG_NAME "closeaudio: replay stopped\n"));
191 194
192 DEBUG_PRINT((DEBUG_NAME "closeaudio: interrupt disabled\n")); 195 /* Disable interrupt */
193 196 Jdisint(MFP_DMASOUND);
194 /* Wait if currently playing sound */ 197
195 while (SDL_MintAudio_mutex != 0) { 198 DEBUG_PRINT((DEBUG_NAME "closeaudio: interrupt disabled\n"));
196 } 199
197 200 /* Wait if currently playing sound */
198 DEBUG_PRINT((DEBUG_NAME "closeaudio: no more interrupt running\n")); 201 while (SDL_MintAudio_mutex != 0) {
199 202 }
200 /* Clear buffers */ 203
201 if (SDL_MintAudio_audiobuf[0]) { 204 DEBUG_PRINT((DEBUG_NAME "closeaudio: no more interrupt running\n"));
202 Mfree(SDL_MintAudio_audiobuf[0]); 205
203 SDL_MintAudio_audiobuf[0] = SDL_MintAudio_audiobuf[1] = NULL; 206 /* Clear buffers */
204 } 207 if (SDL_MintAudio_audiobuf[0]) {
205 208 Mfree(SDL_MintAudio_audiobuf[0]);
206 DEBUG_PRINT((DEBUG_NAME "closeaudio: buffers freed\n")); 209 SDL_MintAudio_audiobuf[0] = SDL_MintAudio_audiobuf[1] = NULL;
207 } 210 }
208 211
209 static int Mint_CheckAudio(_THIS, SDL_AudioSpec *spec) 212 DEBUG_PRINT((DEBUG_NAME "closeaudio: buffers freed\n"));
210 { 213 }
211 int i, masterprediv, sfreq; 214
212 unsigned long masterclock; 215 static int
213 216 Mint_CheckAudio(_THIS, SDL_AudioSpec * spec)
214 DEBUG_PRINT((DEBUG_NAME "asked: %d bits, ",spec->format & 0x00ff)); 217 {
215 DEBUG_PRINT(("signed=%d, ", ((spec->format & 0x8000)!=0))); 218 int i, masterprediv, sfreq;
216 DEBUG_PRINT(("big endian=%d, ", ((spec->format & 0x1000)!=0))); 219 unsigned long masterclock;
217 DEBUG_PRINT(("channels=%d, ", spec->channels)); 220
218 DEBUG_PRINT(("freq=%d\n", spec->freq)); 221 DEBUG_PRINT((DEBUG_NAME "asked: %d bits, ", spec->format & 0x00ff));
219 222 DEBUG_PRINT(("signed=%d, ", ((spec->format & 0x8000) != 0)));
220 /* Check formats available */ 223 DEBUG_PRINT(("big endian=%d, ", ((spec->format & 0x1000) != 0)));
221 spec->format = AUDIO_S8; 224 DEBUG_PRINT(("channels=%d, ", spec->channels));
222 225 DEBUG_PRINT(("freq=%d\n", spec->freq));
223 /* Calculate and select the closest frequency */ 226
224 sfreq=0; 227 /* Check formats available */
225 masterclock=MASTERCLOCK_STE; 228 spec->format = AUDIO_S8;
226 masterprediv=MASTERPREDIV_STE; 229
227 switch(cookie_mch>>16) { 230 /* Calculate and select the closest frequency */
231 sfreq = 0;
232 masterclock = MASTERCLOCK_STE;
233 masterprediv = MASTERPREDIV_STE;
234 switch (cookie_mch >> 16) {
228 /* 235 /*
229 case MCH_STE: 236 case MCH_STE:
230 masterclock=MASTERCLOCK_STE; 237 masterclock=MASTERCLOCK_STE;
231 masterprediv=MASTERPREDIV_STE; 238 masterprediv=MASTERPREDIV_STE;
232 break; 239 break;
233 */ 240 */
234 case MCH_TT: 241 case MCH_TT:
235 masterclock=MASTERCLOCK_TT; 242 masterclock = MASTERCLOCK_TT;
236 masterprediv=MASTERPREDIV_TT; 243 masterprediv = MASTERPREDIV_TT;
237 break; 244 break;
238 case MCH_F30: 245 case MCH_F30:
239 case MCH_ARANYM: 246 case MCH_ARANYM:
240 masterclock=MASTERCLOCK_FALCON1; 247 masterclock = MASTERCLOCK_FALCON1;
241 masterprediv=MASTERPREDIV_FALCON; 248 masterprediv = MASTERPREDIV_FALCON;
242 sfreq=1; 249 sfreq = 1;
243 break; 250 break;
244 } 251 }
245 252
246 MINTAUDIO_freqcount=0; 253 MINTAUDIO_freqcount = 0;
247 for (i=sfreq;i<4;i++) { 254 for (i = sfreq; i < 4; i++) {
248 SDL_MintAudio_AddFrequency(this, masterclock/(masterprediv*(1<<i)), 255 SDL_MintAudio_AddFrequency(this,
249 masterclock, i-sfreq, -1); 256 masterclock / (masterprediv * (1 << i)),
250 } 257 masterclock, i - sfreq, -1);
258 }
251 259
252 #if 1 260 #if 1
253 for (i=0; i<MINTAUDIO_freqcount; i++) { 261 for (i = 0; i < MINTAUDIO_freqcount; i++) {
254 DEBUG_PRINT((DEBUG_NAME "freq %d: %lu Hz, clock %lu, prediv %d\n", 262 DEBUG_PRINT((DEBUG_NAME "freq %d: %lu Hz, clock %lu, prediv %d\n",
255 i, MINTAUDIO_frequencies[i].frequency, MINTAUDIO_frequencies[i].masterclock, 263 i, MINTAUDIO_frequencies[i].frequency,
256 MINTAUDIO_frequencies[i].predivisor 264 MINTAUDIO_frequencies[i].masterclock,
257 )); 265 MINTAUDIO_frequencies[i].predivisor));
258 } 266 }
259 #endif 267 #endif
260 268
261 MINTAUDIO_numfreq=SDL_MintAudio_SearchFrequency(this, spec->freq); 269 MINTAUDIO_numfreq = SDL_MintAudio_SearchFrequency(this, spec->freq);
262 spec->freq=MINTAUDIO_frequencies[MINTAUDIO_numfreq].frequency; 270 spec->freq = MINTAUDIO_frequencies[MINTAUDIO_numfreq].frequency;
263 271
264 DEBUG_PRINT((DEBUG_NAME "obtained: %d bits, ",spec->format & 0x00ff)); 272 DEBUG_PRINT((DEBUG_NAME "obtained: %d bits, ", spec->format & 0x00ff));
265 DEBUG_PRINT(("signed=%d, ", ((spec->format & 0x8000)!=0))); 273 DEBUG_PRINT(("signed=%d, ", ((spec->format & 0x8000) != 0)));
266 DEBUG_PRINT(("big endian=%d, ", ((spec->format & 0x1000)!=0))); 274 DEBUG_PRINT(("big endian=%d, ", ((spec->format & 0x1000) != 0)));
267 DEBUG_PRINT(("channels=%d, ", spec->channels)); 275 DEBUG_PRINT(("channels=%d, ", spec->channels));
268 DEBUG_PRINT(("freq=%d\n", spec->freq)); 276 DEBUG_PRINT(("freq=%d\n", spec->freq));
269 277
270 return 0; 278 return 0;
271 } 279 }
272 280
273 static void Mint_InitAudio(_THIS, SDL_AudioSpec *spec) 281 static void
274 { 282 Mint_InitAudio(_THIS, SDL_AudioSpec * spec)
275 void *oldpile; 283 {
276 unsigned long buffer; 284 void *oldpile;
277 unsigned char mode; 285 unsigned long buffer;
278 286 unsigned char mode;
279 /* Set replay tracks */ 287
280 if (cookie_snd & SND_16BIT) { 288 /* Set replay tracks */
281 Settracks(0,0); 289 if (cookie_snd & SND_16BIT) {
282 Setmontracks(0); 290 Settracks(0, 0);
283 } 291 Setmontracks(0);
284 292 }
285 oldpile=(void *)Super(0); 293
286 294 oldpile = (void *) Super(0);
287 /* Stop currently playing sound */ 295
288 DMAAUDIO_IO.control=0; 296 /* Stop currently playing sound */
289 297 DMAAUDIO_IO.control = 0;
290 /* Set buffer */ 298
291 buffer = (unsigned long) SDL_MintAudio_audiobuf[SDL_MintAudio_numbuf]; 299 /* Set buffer */
292 DMAAUDIO_IO.start_high = (buffer>>16) & 255; 300 buffer = (unsigned long) SDL_MintAudio_audiobuf[SDL_MintAudio_numbuf];
293 DMAAUDIO_IO.start_mid = (buffer>>8) & 255; 301 DMAAUDIO_IO.start_high = (buffer >> 16) & 255;
294 DMAAUDIO_IO.start_low = buffer & 255; 302 DMAAUDIO_IO.start_mid = (buffer >> 8) & 255;
295 303 DMAAUDIO_IO.start_low = buffer & 255;
296 buffer += SDL_MintAudio_audiosize; 304
297 DMAAUDIO_IO.end_high = (buffer>>16) & 255; 305 buffer += SDL_MintAudio_audiosize;
298 DMAAUDIO_IO.end_mid = (buffer>>8) & 255; 306 DMAAUDIO_IO.end_high = (buffer >> 16) & 255;
299 DMAAUDIO_IO.end_low = buffer & 255; 307 DMAAUDIO_IO.end_mid = (buffer >> 8) & 255;
300 308 DMAAUDIO_IO.end_low = buffer & 255;
301 mode = 3-MINTAUDIO_frequencies[MINTAUDIO_numfreq].predivisor; 309
302 if (spec->channels==1) { 310 mode = 3 - MINTAUDIO_frequencies[MINTAUDIO_numfreq].predivisor;
303 mode |= 1<<7; 311 if (spec->channels == 1) {
304 } 312 mode |= 1 << 7;
305 DMAAUDIO_IO.sound_ctrl = mode; 313 }
306 314 DMAAUDIO_IO.sound_ctrl = mode;
307 /* Set interrupt */ 315
308 Jdisint(MFP_DMASOUND); 316 /* Set interrupt */
309 Xbtimer(XB_TIMERA, 8, 1, SDL_MintAudio_Dma8Interrupt); 317 Jdisint(MFP_DMASOUND);
310 Jenabint(MFP_DMASOUND); 318 Xbtimer(XB_TIMERA, 8, 1, SDL_MintAudio_Dma8Interrupt);
311 319 Jenabint(MFP_DMASOUND);
312 if (cookie_snd & SND_16BIT) { 320
313 if (Setinterrupt(SI_TIMERA, SI_PLAY)<0) { 321 if (cookie_snd & SND_16BIT) {
314 DEBUG_PRINT((DEBUG_NAME "Setinterrupt() failed\n")); 322 if (Setinterrupt(SI_TIMERA, SI_PLAY) < 0) {
315 } 323 DEBUG_PRINT((DEBUG_NAME "Setinterrupt() failed\n"));
316 } 324 }
317 325 }
318 /* Go */ 326
319 DMAAUDIO_IO.control = 3; /* playback + repeat */ 327 /* Go */
320 328 DMAAUDIO_IO.control = 3; /* playback + repeat */
321 Super(oldpile); 329
322 } 330 Super(oldpile);
323 331 }
324 static int Mint_OpenAudio(_THIS, SDL_AudioSpec *spec) 332
325 { 333 static int
326 SDL_MintAudio_device = this; 334 Mint_OpenAudio(_THIS, SDL_AudioSpec * spec)
327 335 {
328 /* Check audio capabilities */ 336 SDL_MintAudio_device = this;
329 if (Mint_CheckAudio(this, spec)==-1) { 337
330 return -1; 338 /* Check audio capabilities */
331 } 339 if (Mint_CheckAudio(this, spec) == -1) {
332 340 return -1;
333 SDL_CalculateAudioSpec(spec); 341 }
334 342
335 /* Allocate memory for audio buffers in DMA-able RAM */ 343 SDL_CalculateAudioSpec(spec);
336 DEBUG_PRINT((DEBUG_NAME "buffer size=%d\n", spec->size)); 344
337 345 /* Allocate memory for audio buffers in DMA-able RAM */
338 SDL_MintAudio_audiobuf[0] = Atari_SysMalloc(spec->size *2, MX_STRAM); 346 DEBUG_PRINT((DEBUG_NAME "buffer size=%d\n", spec->size));
339 if (SDL_MintAudio_audiobuf[0]==NULL) { 347
340 SDL_SetError("MINT_OpenAudio: Not enough memory for audio buffer"); 348 SDL_MintAudio_audiobuf[0] = Atari_SysMalloc(spec->size * 2, MX_STRAM);
341 return (-1); 349 if (SDL_MintAudio_audiobuf[0] == NULL) {
342 } 350 SDL_SetError("MINT_OpenAudio: Not enough memory for audio buffer");
343 SDL_MintAudio_audiobuf[1] = SDL_MintAudio_audiobuf[0] + spec->size ; 351 return (-1);
344 SDL_MintAudio_numbuf=0; 352 }
345 SDL_memset(SDL_MintAudio_audiobuf[0], spec->silence, spec->size *2); 353 SDL_MintAudio_audiobuf[1] = SDL_MintAudio_audiobuf[0] + spec->size;
346 SDL_MintAudio_audiosize = spec->size; 354 SDL_MintAudio_numbuf = 0;
347 SDL_MintAudio_mutex = 0; 355 SDL_memset(SDL_MintAudio_audiobuf[0], spec->silence, spec->size * 2);
348 356 SDL_MintAudio_audiosize = spec->size;
349 DEBUG_PRINT((DEBUG_NAME "buffer 0 at 0x%08x\n", SDL_MintAudio_audiobuf[0])); 357 SDL_MintAudio_mutex = 0;
350 DEBUG_PRINT((DEBUG_NAME "buffer 1 at 0x%08x\n", SDL_MintAudio_audiobuf[1])); 358
351 359 DEBUG_PRINT((DEBUG_NAME "buffer 0 at 0x%08x\n",
352 /* Setup audio hardware */ 360 SDL_MintAudio_audiobuf[0]));
353 Mint_InitAudio(this, spec); 361 DEBUG_PRINT((DEBUG_NAME "buffer 1 at 0x%08x\n",
354 362 SDL_MintAudio_audiobuf[1]));
355 return(1); /* We don't use threaded audio */ 363
356 } 364 /* Setup audio hardware */
365 Mint_InitAudio(this, spec);
366
367 return (1); /* We don't use threaded audio */
368 }
369
370 /* vi: set ts=4 sw=4 expandtab: */