comparison src/audio/mint/SDL_mintaudio_stfa.c @ 644:594422ab8f9f

Atari MiNT: added more audio drivers
author Patrice Mandin <patmandin@gmail.com>
date Mon, 07 Jul 2003 19:16:03 +0000
parents
children c4803992e09c
comparison
equal deleted inserted replaced
643:564716cfb502 644:594422ab8f9f
1 /*
2 SDL - Simple DirectMedia Layer
3 Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 Sam Lantinga
4
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Library General Public
7 License as published by the Free Software Foundation; either
8 version 2 of the License, or (at your option) any later version.
9
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Library General Public License for more details.
14
15 You should have received a copy of the GNU Library General Public
16 License along with this library; if not, write to the Free
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18
19 Sam Lantinga
20 slouken@libsdl.org
21 */
22
23 /*
24 MiNT audio driver
25 using XBIOS functions (STFA driver)
26
27 Patrice Mandin
28 */
29
30 #include <stdlib.h>
31 #include <stdio.h>
32 #include <string.h>
33
34 /* Mint includes */
35 #include <mint/osbind.h>
36 #include <mint/falcon.h>
37 #include <mint/cookie.h>
38
39 #include "SDL_endian.h"
40 #include "SDL_audio.h"
41 #include "SDL_audio_c.h"
42 #include "SDL_audiomem.h"
43 #include "SDL_sysaudio.h"
44
45 #include "SDL_atarimxalloc_c.h"
46
47 #include "SDL_mintaudio.h"
48 #include "SDL_mintaudio_stfa.h"
49
50 /*--- Defines ---*/
51
52 #define MINT_AUDIO_DRIVER_NAME "mint_stfa"
53
54 /* Debug print info */
55 #define DEBUG_NAME "audio:stfa: "
56 #if 0
57 #define DEBUG_PRINT(what) \
58 { \
59 printf what; \
60 }
61 #else
62 #define DEBUG_PRINT(what)
63 #endif
64
65 /*--- Static variables ---*/
66
67 static unsigned long cookie_snd, cookie_mch;
68 static cookie_stfa_t *cookie_stfa;
69
70 static const int freqs[16]={
71 4995, 6269, 7493, 8192,
72 9830, 10971, 12538, 14985,
73 16384, 19819, 21943, 24576,
74 30720, 32336, 43885, 49152
75 };
76
77 /*--- Audio driver functions ---*/
78
79 static void Mint_CloseAudio(_THIS);
80 static int Mint_OpenAudio(_THIS, SDL_AudioSpec *spec);
81 static void Mint_LockAudio(_THIS);
82 static void Mint_UnlockAudio(_THIS);
83
84 /* To check/init hardware audio */
85 static int Mint_CheckAudio(_THIS, SDL_AudioSpec *spec);
86 static void Mint_InitAudio(_THIS, SDL_AudioSpec *spec);
87
88 /*--- Audio driver bootstrap functions ---*/
89
90 static int Audio_Available(void)
91 {
92 const char *envr = getenv("SDL_AUDIODRIVER");
93
94 /* Check if user asked a different audio driver */
95 if ((envr) && (strcmp(envr, MINT_AUDIO_DRIVER_NAME)!=0)) {
96 DEBUG_PRINT((DEBUG_NAME "user asked a different audio driver\n"));
97 return(0);
98 }
99
100 /* Cookie _MCH present ? if not, assume ST machine */
101 if (Getcookie(C__MCH, &cookie_mch) == C_NOTFOUND) {
102 cookie_mch = MCH_ST;
103 }
104
105 /* Cookie _SND present ? if not, assume ST machine */
106 if (Getcookie(C__SND, &cookie_snd) == C_NOTFOUND) {
107 cookie_snd = SND_PSG;
108 }
109
110 /* Cookie STFA present ? */
111 if (Getcookie(C_STFA, (long *) &cookie_stfa) != C_FOUND) {
112 DEBUG_PRINT((DEBUG_NAME "no STFA audio\n"));
113 return(0);
114 }
115
116 SDL_MintAudio_stfa = cookie_stfa;
117
118 DEBUG_PRINT((DEBUG_NAME "STFA audio available!\n"));
119 return(1);
120 }
121
122 static void Audio_DeleteDevice(SDL_AudioDevice *device)
123 {
124 free(device->hidden);
125 free(device);
126 }
127
128 static SDL_AudioDevice *Audio_CreateDevice(int devindex)
129 {
130 SDL_AudioDevice *this;
131
132 /* Initialize all variables that we clean on shutdown */
133 this = (SDL_AudioDevice *)malloc(sizeof(SDL_AudioDevice));
134 if ( this ) {
135 memset(this, 0, (sizeof *this));
136 this->hidden = (struct SDL_PrivateAudioData *)
137 malloc((sizeof *this->hidden));
138 }
139 if ( (this == NULL) || (this->hidden == NULL) ) {
140 SDL_OutOfMemory();
141 if ( this ) {
142 free(this);
143 }
144 return(0);
145 }
146 memset(this->hidden, 0, (sizeof *this->hidden));
147
148 /* Set the function pointers */
149 this->OpenAudio = Mint_OpenAudio;
150 this->CloseAudio = Mint_CloseAudio;
151 this->LockAudio = Mint_LockAudio;
152 this->UnlockAudio = Mint_UnlockAudio;
153 this->free = Audio_DeleteDevice;
154
155 return this;
156 }
157
158 AudioBootStrap MINTAUDIO_STFA_bootstrap = {
159 MINT_AUDIO_DRIVER_NAME, "MiNT STFA audio driver",
160 Audio_Available, Audio_CreateDevice
161 };
162
163 static void Mint_LockAudio(_THIS)
164 {
165 void *oldpile;
166
167 /* Stop replay */
168 oldpile=(void *)Super(0);
169 cookie_stfa->sound_enable=STFA_PLAY_DISABLE;
170 Super(oldpile);
171 }
172
173 static void Mint_UnlockAudio(_THIS)
174 {
175 void *oldpile;
176
177 /* Restart replay */
178 oldpile=(void *)Super(0);
179 cookie_stfa->sound_enable=STFA_PLAY_ENABLE|STFA_PLAY_REPEAT;
180 Super(oldpile);
181 }
182
183 static void Mint_CloseAudio(_THIS)
184 {
185 void *oldpile;
186
187 /* Stop replay */
188 oldpile=(void *)Super(0);
189 cookie_stfa->sound_enable=STFA_PLAY_DISABLE;
190 Super(oldpile);
191
192 /* Wait if currently playing sound */
193 while (SDL_MintAudio_mutex != 0) {
194 }
195
196 /* Clear buffers */
197 if (SDL_MintAudio_audiobuf[0]) {
198 Mfree(SDL_MintAudio_audiobuf[0]);
199 SDL_MintAudio_audiobuf[0] = SDL_MintAudio_audiobuf[1] = NULL;
200 }
201 }
202
203 static int Mint_CheckAudio(_THIS, SDL_AudioSpec *spec)
204 {
205 int i;
206
207 DEBUG_PRINT((DEBUG_NAME "asked: %d bits, ",spec->format & 0x00ff));
208 DEBUG_PRINT(("signed=%d, ", ((spec->format & 0x8000)!=0)));
209 DEBUG_PRINT(("big endian=%d, ", ((spec->format & 0x8000)!=0)));
210 DEBUG_PRINT(("channels=%d, ", spec->channels));
211 DEBUG_PRINT(("freq=%d\n", spec->freq));
212
213 /* Check formats available */
214 MINTAUDIO_nfreq=16;
215 MINTAUDIO_sfreq=0;
216 for (i=MINTAUDIO_sfreq;i<MINTAUDIO_nfreq;i++) {
217 MINTAUDIO_hardfreq[i]=freqs[15-i];
218 DEBUG_PRINT((DEBUG_NAME "calc:freq(%d)=%lu\n", i, MINTAUDIO_hardfreq[i]));
219 }
220
221 MINTAUDIO_numfreq=SDL_MintAudio_SearchFrequency(this, 0, spec->freq);
222 spec->freq=MINTAUDIO_hardfreq[MINTAUDIO_numfreq];
223
224 DEBUG_PRINT((DEBUG_NAME "obtained: %d bits, ",spec->format & 0x00ff));
225 DEBUG_PRINT(("signed=%d, ", ((spec->format & 0x8000)!=0)));
226 DEBUG_PRINT(("big endian=%d, ", ((spec->format & 0x8000)!=0)));
227 DEBUG_PRINT(("channels=%d, ", spec->channels));
228 DEBUG_PRINT(("freq=%d\n", spec->freq));
229
230 return 0;
231 }
232
233 static void Mint_InitAudio(_THIS, SDL_AudioSpec *spec)
234 {
235 void *buffer;
236 void *oldpile;
237
238 buffer = SDL_MintAudio_audiobuf[SDL_MintAudio_numbuf];
239
240 oldpile=(void *)Super(0);
241
242 /* Stop replay */
243 cookie_stfa->sound_enable=STFA_PLAY_DISABLE;
244
245 /* Select replay format */
246 cookie_stfa->sound_control = 15-MINTAUDIO_numfreq;
247 if ((spec->format & 0xff)==8) {
248 cookie_stfa->sound_control |= STFA_FORMAT_8BIT;
249 } else {
250 cookie_stfa->sound_control |= STFA_FORMAT_16BIT;
251 }
252 if (spec->channels==2) {
253 cookie_stfa->sound_control |= STFA_FORMAT_STEREO;
254 } else {
255 cookie_stfa->sound_control |= STFA_FORMAT_MONO;
256 }
257 if (spec->format & 0x8000) {
258 cookie_stfa->sound_control |= STFA_FORMAT_SIGNED;
259 } else {
260 cookie_stfa->sound_control |= STFA_FORMAT_UNSIGNED;
261 }
262 if (spec->format & 0x1000) {
263 cookie_stfa->sound_control |= STFA_FORMAT_LITENDIAN;
264 } else {
265 cookie_stfa->sound_control |= STFA_FORMAT_BIGENDIAN;
266 }
267
268 /* Set buffer */
269 cookie_stfa->sound_start = (unsigned long) buffer;
270 cookie_stfa->sound_end = (unsigned long) (buffer + spec->size);
271
272 /* Set interrupt */
273 cookie_stfa->stfa_it = SDL_MintAudio_StfaInterrupt;
274
275 /* Restart replay */
276 cookie_stfa->sound_enable=STFA_PLAY_ENABLE|STFA_PLAY_REPEAT;
277
278 Super(oldpile);
279
280 DEBUG_PRINT((DEBUG_NAME "hardware initialized\n"));
281 }
282
283 static int Mint_OpenAudio(_THIS, SDL_AudioSpec *spec)
284 {
285 SDL_MintAudio_device = this;
286
287 /* Check audio capabilities */
288 if (Mint_CheckAudio(this, spec)==-1) {
289 return -1;
290 }
291
292 SDL_CalculateAudioSpec(spec);
293
294 /* Allocate memory for audio buffers in DMA-able RAM */
295 spec->size = spec->samples;
296 spec->size *= spec->channels;
297 spec->size *= (spec->format & 0xFF)/8;
298
299 DEBUG_PRINT((DEBUG_NAME "buffer size=%d\n", spec->size));
300
301 SDL_MintAudio_audiobuf[0] = Atari_SysMalloc(spec->size *2, MX_STRAM);
302 if (SDL_MintAudio_audiobuf[0]==NULL) {
303 SDL_SetError("MINT_OpenAudio: Not enough memory for audio buffer");
304 return (-1);
305 }
306 SDL_MintAudio_audiobuf[1] = SDL_MintAudio_audiobuf[0] + spec->size ;
307 SDL_MintAudio_numbuf=0;
308 memset(SDL_MintAudio_audiobuf[0], spec->silence, spec->size *2);
309 SDL_MintAudio_audiosize = spec->size;
310 SDL_MintAudio_mutex = 0;
311
312 DEBUG_PRINT((DEBUG_NAME "buffer 0 at 0x%08x\n", SDL_MintAudio_audiobuf[0]));
313 DEBUG_PRINT((DEBUG_NAME "buffer 1 at 0x%08x\n", SDL_MintAudio_audiobuf[1]));
314
315 /* Setup audio hardware */
316 Mint_InitAudio(this, spec);
317
318 return(1); /* We don't use threaded audio */
319 }