This repository has been archived by the owner on Feb 11, 2021. It is now read-only.
/
SDL_mintaudio_stfa.c
307 lines (248 loc) · 8.58 KB
1
2
/*
SDL - Simple DirectMedia Layer
3
Copyright (C) 1997-2004 Sam Lantinga
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Sam Lantinga
slouken@libsdl.org
*/
22
#include "SDL_config.h"
23
24
25
26
27
28
29
30
31
32
33
34
35
36
/*
MiNT audio driver
using XBIOS functions (STFA driver)
Patrice Mandin
*/
/* Mint includes */
#include <mint/osbind.h>
#include <mint/falcon.h>
#include <mint/cookie.h>
#include "SDL_audio.h"
37
38
#include "../SDL_audio_c.h"
#include "../SDL_sysaudio.h"
39
40
#include "../../video/ataricommon/SDL_atarimxalloc_c.h"
41
42
43
44
45
46
47
48
49
50
#include "SDL_mintaudio.h"
#include "SDL_mintaudio_stfa.h"
/*--- Defines ---*/
#define MINT_AUDIO_DRIVER_NAME "mint_stfa"
/* Debug print info */
#define DEBUG_NAME "audio:stfa: "
51
#if 0
52
53
54
55
56
57
58
59
60
61
#define DEBUG_PRINT(what) \
{ \
printf what; \
}
#else
#define DEBUG_PRINT(what)
#endif
/*--- Static variables ---*/
62
63
64
static unsigned long cookie_snd = 0;
static unsigned long cookie_mch = 0;
static cookie_stfa_t *cookie_stfa = NULL;
65
66
67
68
69
70
static const int freqs[16] = {
4995, 6269, 7493, 8192,
9830, 10971, 12538, 14985,
16384, 19819, 21943, 24576,
30720, 32336, 43885, 49152
71
72
};
73
static void
74
MINTSTFA_LockDevice(_THIS)
75
{
76
/* Stop replay */
77
void *oldpile = (void *) Super(0);
78
79
cookie_stfa->sound_enable = STFA_PLAY_DISABLE;
Super(oldpile);
80
81
}
82
static void
83
MINTSTFA_UnlockDevice(_THIS)
84
{
85
/* Restart replay */
86
void *oldpile = (void *) Super(0);
87
88
cookie_stfa->sound_enable = STFA_PLAY_ENABLE | STFA_PLAY_REPEAT;
Super(oldpile);
89
90
}
91
static void
92
MINTSTFA_CloseDevice(_THIS)
93
{
94
95
96
97
98
99
100
if (this->hidden != NULL) {
/* Stop replay */
void *oldpile = (void *) Super(0);
cookie_stfa->sound_enable = STFA_PLAY_DISABLE;
Super(oldpile);
/* Wait if currently playing sound */
101
102
while (SDL_MintAudio_mutex != 0) {
}
103
104
105
106
107
108
/* Clear buffers */
if (SDL_MintAudio_audiobuf[0]) {
Mfree(SDL_MintAudio_audiobuf[0]);
SDL_MintAudio_audiobuf[0] = SDL_MintAudio_audiobuf[1] = NULL;
}
109
110
111
SDL_free(this->hidden);
this->hidden = NULL;
112
}
113
114
}
115
static int
116
MINTSTFA_CheckAudio(_THIS)
117
{
118
119
int i;
120
DEBUG_PRINT((DEBUG_NAME "asked: %d bits, ",
121
122
123
SDL_AUDIO_BITSIZE(this->spec.format)));
DEBUG_PRINT(("float=%d, ", SDL_AUDIO_ISFLOAT(this->spec.format)));
DEBUG_PRINT(("signed=%d, ", SDL_AUDIO_ISSIGNED(this->spec.format)));
124
125
DEBUG_PRINT(("big endian=%d, ",
SDL_AUDIO_ISBIGENDIAN(this->spec.format)));
126
127
128
129
DEBUG_PRINT(("channels=%d, ", this->spec.channels));
DEBUG_PRINT(("freq=%d\n", this->spec.freq));
if (SDL_AUDIO_BITSIZE(this->spec.format) > 16) {
130
this->spec.format = AUDIO_S16SYS; /* clamp out int32/float32 ... */
131
132
}
133
if (this->spec.channels > 2) {
134
this->spec.channels = 2; /* no more than stereo! */
135
136
}
137
138
139
140
141
/* Check formats available */
MINTAUDIO_freqcount = 0;
for (i = 0; i < 16; i++) {
SDL_MintAudio_AddFrequency(this, freqs[i], 0, i, -1);
}
142
143
#if 1
144
145
146
147
148
149
for (i = 0; i < MINTAUDIO_freqcount; i++) {
DEBUG_PRINT((DEBUG_NAME "freq %d: %lu Hz, clock %lu, prediv %d\n",
i, MINTAUDIO_frequencies[i].frequency,
MINTAUDIO_frequencies[i].masterclock,
MINTAUDIO_frequencies[i].predivisor));
}
150
151
#endif
152
153
MINTAUDIO_numfreq = SDL_MintAudio_SearchFrequency(this, this->spec.freq);
this->spec.freq = MINTAUDIO_frequencies[MINTAUDIO_numfreq].frequency;
154
155
DEBUG_PRINT((DEBUG_NAME "obtained: %d bits, ",
156
157
158
SDL_AUDIO_BITSIZE(this->spec.format)));
DEBUG_PRINT(("float=%d, ", SDL_AUDIO_ISFLOAT(this->spec.format)));
DEBUG_PRINT(("signed=%d, ", SDL_AUDIO_ISSIGNED(this->spec.format)));
159
160
DEBUG_PRINT(("big endian=%d, ",
SDL_AUDIO_ISBIGENDIAN(this->spec.format)));
161
162
DEBUG_PRINT(("channels=%d, ", this->spec.channels));
DEBUG_PRINT(("freq=%d\n", this->spec.freq));
163
164
return 0;
165
166
}
167
static void
168
MINTSTFA_InitAudio(_THIS)
169
{
170
171
void *buffer = SDL_MintAudio_audiobuf[SDL_MintAudio_numbuf];
void *oldpile = (void *) Super(0);
172
173
174
/* Stop replay */
cookie_stfa->sound_enable = STFA_PLAY_DISABLE;
175
176
177
178
/* Select replay format */
cookie_stfa->sound_control =
MINTAUDIO_frequencies[MINTAUDIO_numfreq].predivisor;
179
if (SDL_AUDIO_BITSIZE(this->spec.format) == 8) {
180
181
182
183
cookie_stfa->sound_control |= STFA_FORMAT_8BIT;
} else {
cookie_stfa->sound_control |= STFA_FORMAT_16BIT;
}
184
if (this->spec.channels == 2) {
185
186
187
188
cookie_stfa->sound_control |= STFA_FORMAT_STEREO;
} else {
cookie_stfa->sound_control |= STFA_FORMAT_MONO;
}
189
if (SDL_AUDIO_ISSIGNED(this->spec.format) != 0) {
190
191
192
193
cookie_stfa->sound_control |= STFA_FORMAT_SIGNED;
} else {
cookie_stfa->sound_control |= STFA_FORMAT_UNSIGNED;
}
194
if (SDL_AUDIO_ISBIGENDIAN(this->spec.format) != 0) {
195
196
197
198
cookie_stfa->sound_control |= STFA_FORMAT_BIGENDIAN;
} else {
cookie_stfa->sound_control |= STFA_FORMAT_LITENDIAN;
}
199
200
201
/* Set buffer */
cookie_stfa->sound_start = (unsigned long) buffer;
202
cookie_stfa->sound_end = (unsigned long) (buffer + this->spec.size);
203
204
205
/* Set interrupt */
cookie_stfa->stfa_it = SDL_MintAudio_StfaInterrupt;
206
207
208
/* Restart replay */
cookie_stfa->sound_enable = STFA_PLAY_ENABLE | STFA_PLAY_REPEAT;
209
210
Super(oldpile);
211
212
DEBUG_PRINT((DEBUG_NAME "hardware initialized\n"));
213
214
}
215
static int
216
MINTSTFA_OpenDevice(_THIS, const char *devname, int iscapture)
217
{
218
SDL_MintAudio_device = this;
219
220
/* Check audio capabilities */
221
222
223
224
225
226
if (MINTSTFA_CheckAudio(this) == -1) {
return 0;
}
/* Initialize all variables that we clean on shutdown */
this->hidden = (struct SDL_PrivateAudioData *)
227
SDL_malloc((sizeof *this->hidden));
228
229
230
if (this->hidden == NULL) {
SDL_OutOfMemory();
return 0;
231
}
232
SDL_memset(this->hidden, 0, (sizeof *this->hidden));
233
234
SDL_CalculateAudioSpec(&this->spec);
235
236
/* Allocate memory for audio buffers in DMA-able RAM */
237
DEBUG_PRINT((DEBUG_NAME "buffer size=%d\n", this->spec.size));
238
239
240
SDL_MintAudio_audiobuf[0] =
Atari_SysMalloc(this->spec.size * 2, MX_STRAM);
241
if (SDL_MintAudio_audiobuf[0] == NULL) {
242
SDL_OutOfMemory()
243
SDL_free(this->hidden);
244
245
this->hidden = NULL;
return 0;
246
}
247
SDL_MintAudio_audiobuf[1] = SDL_MintAudio_audiobuf[0] + this->spec.size;
248
SDL_MintAudio_numbuf = 0;
249
250
SDL_memset(SDL_MintAudio_audiobuf[0], this->spec.silence,
this->spec.size * 2);
251
SDL_MintAudio_audiosize = this->spec.size;
252
SDL_MintAudio_mutex = 0;
253
254
255
256
257
DEBUG_PRINT((DEBUG_NAME "buffer 0 at 0x%08x\n",
SDL_MintAudio_audiobuf[0]));
DEBUG_PRINT((DEBUG_NAME "buffer 1 at 0x%08x\n",
SDL_MintAudio_audiobuf[1]));
258
259
260
SDL_MintAudio_CheckFpu();
261
/* Setup audio hardware */
262
MINTSTFA_InitAudio(this);
263
264
return 1; /* good to go. */
265
}
266
267
268
static int
269
MINTSTFA_Init(SDL_AudioDriverImpl * impl)
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
{
/* Cookie _MCH present ? if not, assume ST machine */
if (Getcookie(C__MCH, &cookie_mch) == C_NOTFOUND) {
cookie_mch = MCH_ST;
}
/* Cookie _SND present ? if not, assume ST machine */
if (Getcookie(C__SND, &cookie_snd) == C_NOTFOUND) {
cookie_snd = SND_PSG;
}
/* Cookie STFA present ? */
if (Getcookie(C_STFA, (long *) &cookie_stfa) != C_FOUND) {
SDL_SetError(DEBUG_NAME "no STFA audio");
return (0);
}
SDL_MintAudio_stfa = cookie_stfa;
DEBUG_PRINT((DEBUG_NAME "STFA audio available!\n"));
/* Set the function pointers */
impl->OpenDevice = MINTSTFA_OpenDevice;
impl->CloseDevice = MINTSTFA_CloseDevice;
impl->LockAudio = MINTSTFA_LockAudio;
impl->UnlockAudio = MINTSTFA_UnlockAudio;
impl->OnlyHasDefaultOutputDevice = 1;
impl->ProvidesOwnCallbackThread = 1;
impl->SkipMixerLock = 1;
return 1;
}
AudioBootStrap MINTAUDIO_STFA_bootstrap = {
MINT_AUDIO_DRIVER_NAME, "MiNT STFA audio driver", MINTSTFA_Init, 0
};
307
/* vi: set ts=4 sw=4 expandtab: */