Skip to content
This repository has been archived by the owner on Feb 11, 2021. It is now read-only.

Latest commit

 

History

History
348 lines (278 loc) · 9.35 KB

SDL_ahiaudio.c

File metadata and controls

348 lines (278 loc) · 9.35 KB
 
Apr 26, 2001
Apr 26, 2001
1
2
/*
SDL - Simple DirectMedia Layer
Feb 1, 2006
Feb 1, 2006
3
Copyright (C) 1997-2006 Sam Lantinga
Apr 26, 2001
Apr 26, 2001
4
5
This library is free software; you can redistribute it and/or
Feb 1, 2006
Feb 1, 2006
6
modify it under the terms of the GNU Lesser General Public
Apr 26, 2001
Apr 26, 2001
7
License as published by the Free Software Foundation; either
Feb 1, 2006
Feb 1, 2006
8
version 2.1 of the License, or (at your option) any later version.
Apr 26, 2001
Apr 26, 2001
9
10
11
12
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
Feb 1, 2006
Feb 1, 2006
13
Lesser General Public License for more details.
Apr 26, 2001
Apr 26, 2001
14
Feb 1, 2006
Feb 1, 2006
15
16
17
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Apr 26, 2001
Apr 26, 2001
18
19
Sam Lantinga
Dec 14, 2001
Dec 14, 2001
20
slouken@libsdl.org
Apr 26, 2001
Apr 26, 2001
21
*/
Feb 21, 2006
Feb 21, 2006
22
#include "SDL_config.h"
Apr 26, 2001
Apr 26, 2001
23
May 10, 2001
May 10, 2001
24
25
/* Allow access to a raw mixing buffer (for AmigaOS) */
Apr 26, 2001
Apr 26, 2001
26
#include "SDL_audio.h"
Feb 16, 2006
Feb 16, 2006
27
#include "../SDL_audio_c.h"
May 10, 2001
May 10, 2001
28
#include "SDL_ahiaudio.h"
Apr 26, 2001
Apr 26, 2001
29
30
/* Audio driver functions */
May 29, 2006
May 29, 2006
31
32
33
34
35
static int AHI_OpenAudio(_THIS, SDL_AudioSpec * spec);
static void AHI_WaitAudio(_THIS);
static void AHI_PlayAudio(_THIS);
static Uint8 *AHI_GetAudioBuf(_THIS);
static void AHI_CloseAudio(_THIS);
Apr 26, 2001
Apr 26, 2001
36
37
#ifndef __SASC
May 28, 2006
May 28, 2006
38
39
#define mymalloc(x) AllocVec(x,MEMF_PUBLIC)
#define myfree FreeVec
Apr 26, 2001
Apr 26, 2001
40
#else
May 28, 2006
May 28, 2006
41
42
#define mymalloc malloc
#define myfree free
Apr 26, 2001
Apr 26, 2001
43
44
45
46
#endif
/* Audio driver bootstrap functions */
May 28, 2006
May 28, 2006
47
static int
May 29, 2006
May 29, 2006
48
Audio_Available(void)
Apr 26, 2001
Apr 26, 2001
49
{
May 28, 2006
May 28, 2006
50
51
52
53
int ok = 0;
struct MsgPort *p;
struct AHIRequest *req;
May 29, 2006
May 29, 2006
54
if (p = CreateMsgPort()) {
May 28, 2006
May 28, 2006
55
if (req =
May 29, 2006
May 29, 2006
56
57
58
(struct AHIRequest *) CreateIORequest(p,
sizeof(struct
AHIRequest))) {
May 28, 2006
May 28, 2006
59
60
req->ahir_Version = 4;
May 29, 2006
May 29, 2006
61
62
if (!OpenDevice(AHINAME, 0, (struct IORequest *) req, NULL)) {
D(bug("AHI available.\n"));
May 28, 2006
May 28, 2006
63
ok = 1;
May 29, 2006
May 29, 2006
64
CloseDevice((struct IORequest *) req);
May 28, 2006
May 28, 2006
65
}
May 29, 2006
May 29, 2006
66
DeleteIORequest((struct IORequest *) req);
May 28, 2006
May 28, 2006
67
}
May 29, 2006
May 29, 2006
68
DeleteMsgPort(p);
May 28, 2006
May 28, 2006
69
70
}
May 29, 2006
May 29, 2006
71
D(if (!ok) bug("AHI not available\n"));
May 28, 2006
May 28, 2006
72
return ok;
Apr 26, 2001
Apr 26, 2001
73
74
}
May 28, 2006
May 28, 2006
75
static void
May 29, 2006
May 29, 2006
76
Audio_DeleteDevice(SDL_AudioDevice * device)
Apr 26, 2001
Apr 26, 2001
77
{
May 29, 2006
May 29, 2006
78
79
SDL_free(device->hidden);
SDL_free(device);
Apr 26, 2001
Apr 26, 2001
80
81
}
May 28, 2006
May 28, 2006
82
static SDL_AudioDevice *
May 29, 2006
May 29, 2006
83
Audio_CreateDevice(int devindex)
Apr 26, 2001
Apr 26, 2001
84
{
May 28, 2006
May 28, 2006
85
SDL_AudioDevice *this;
Apr 26, 2001
Apr 26, 2001
86
87
#ifndef NO_AMIGADEBUG
May 29, 2006
May 29, 2006
88
D(bug("AHI created...\n"));
Apr 26, 2001
Apr 26, 2001
89
90
#endif
May 28, 2006
May 28, 2006
91
/* Initialize all variables that we clean on shutdown */
May 29, 2006
May 29, 2006
92
this = (SDL_AudioDevice *) SDL_malloc(sizeof(SDL_AudioDevice));
May 28, 2006
May 28, 2006
93
if (this) {
May 29, 2006
May 29, 2006
94
SDL_memset(this, 0, (sizeof *this));
May 28, 2006
May 28, 2006
95
this->hidden = (struct SDL_PrivateAudioData *)
May 29, 2006
May 29, 2006
96
SDL_malloc((sizeof *this->hidden));
May 28, 2006
May 28, 2006
97
98
}
if ((this == NULL) || (this->hidden == NULL)) {
May 29, 2006
May 29, 2006
99
SDL_OutOfMemory();
May 28, 2006
May 28, 2006
100
if (this) {
May 29, 2006
May 29, 2006
101
SDL_free(this);
May 28, 2006
May 28, 2006
102
103
104
}
return (0);
}
May 29, 2006
May 29, 2006
105
SDL_memset(this->hidden, 0, (sizeof *this->hidden));
May 28, 2006
May 28, 2006
106
107
108
109
110
111
112
113
114
115
116
/* Set the function pointers */
this->OpenAudio = AHI_OpenAudio;
this->WaitAudio = AHI_WaitAudio;
this->PlayAudio = AHI_PlayAudio;
this->GetAudioBuf = AHI_GetAudioBuf;
this->CloseAudio = AHI_CloseAudio;
this->free = Audio_DeleteDevice;
return this;
Apr 26, 2001
Apr 26, 2001
117
118
119
}
AudioBootStrap AHI_bootstrap = {
May 28, 2006
May 28, 2006
120
"AHI", Audio_Available, Audio_CreateDevice
Apr 26, 2001
Apr 26, 2001
121
122
123
};
May 28, 2006
May 28, 2006
124
void static
May 29, 2006
May 29, 2006
125
AHI_WaitAudio(_THIS)
Apr 26, 2001
Apr 26, 2001
126
{
May 29, 2006
May 29, 2006
127
128
if (!CheckIO((struct IORequest *) audio_req[current_buffer])) {
WaitIO((struct IORequest *) audio_req[current_buffer]);
May 28, 2006
May 28, 2006
129
130
// AbortIO((struct IORequest *)audio_req[current_buffer]);
}
Apr 26, 2001
Apr 26, 2001
131
132
}
May 28, 2006
May 28, 2006
133
static void
May 29, 2006
May 29, 2006
134
AHI_PlayAudio(_THIS)
Apr 26, 2001
Apr 26, 2001
135
{
May 28, 2006
May 28, 2006
136
if (playing > 1)
May 29, 2006
May 29, 2006
137
WaitIO((struct IORequest *) audio_req[current_buffer]);
May 28, 2006
May 28, 2006
138
139
140
141
142
143
144
145
146
147
148
149
150
151
/* Write the audio data out */
audio_req[current_buffer]->ahir_Std.io_Message.mn_Node.ln_Pri = 60;
audio_req[current_buffer]->ahir_Std.io_Data = mixbuf[current_buffer];
audio_req[current_buffer]->ahir_Std.io_Length = this->hidden->size;
audio_req[current_buffer]->ahir_Std.io_Offset = 0;
audio_req[current_buffer]->ahir_Std.io_Command = CMD_WRITE;
audio_req[current_buffer]->ahir_Frequency = this->hidden->freq;
audio_req[current_buffer]->ahir_Volume = 0x10000;
audio_req[current_buffer]->ahir_Type = this->hidden->type;
audio_req[current_buffer]->ahir_Position = 0x8000;
audio_req[current_buffer]->ahir_Link =
(playing > 0 ? audio_req[current_buffer ^ 1] : NULL);
May 29, 2006
May 29, 2006
152
SendIO((struct IORequest *) audio_req[current_buffer]);
May 28, 2006
May 28, 2006
153
154
155
current_buffer ^= 1;
playing++;
Apr 26, 2001
Apr 26, 2001
156
157
}
May 28, 2006
May 28, 2006
158
static Uint8 *
May 29, 2006
May 29, 2006
159
AHI_GetAudioBuf(_THIS)
Apr 26, 2001
Apr 26, 2001
160
{
May 28, 2006
May 28, 2006
161
return (mixbuf[current_buffer]);
Apr 26, 2001
Apr 26, 2001
162
163
}
May 28, 2006
May 28, 2006
164
static void
May 29, 2006
May 29, 2006
165
AHI_CloseAudio(_THIS)
Apr 26, 2001
Apr 26, 2001
166
{
May 29, 2006
May 29, 2006
167
D(bug("Closing audio...\n"));
Apr 26, 2001
Apr 26, 2001
168
May 28, 2006
May 28, 2006
169
playing = 0;
Apr 26, 2001
Apr 26, 2001
170
May 28, 2006
May 28, 2006
171
172
if (audio_req[0]) {
if (audio_req[1]) {
May 29, 2006
May 29, 2006
173
D(bug("Break req[1]...\n"));
May 10, 2001
May 10, 2001
174
May 29, 2006
May 29, 2006
175
176
AbortIO((struct IORequest *) audio_req[1]);
WaitIO((struct IORequest *) audio_req[1]);
May 28, 2006
May 28, 2006
177
}
Apr 26, 2001
Apr 26, 2001
178
May 29, 2006
May 29, 2006
179
D(bug("Break req[0]...\n"));
May 10, 2001
May 10, 2001
180
May 29, 2006
May 29, 2006
181
182
AbortIO((struct IORequest *) audio_req[0]);
WaitIO((struct IORequest *) audio_req[0]);
May 10, 2001
May 10, 2001
183
May 28, 2006
May 28, 2006
184
if (audio_req[1]) {
May 29, 2006
May 29, 2006
185
186
187
D(bug("Break AGAIN req[1]...\n"));
AbortIO((struct IORequest *) audio_req[1]);
WaitIO((struct IORequest *) audio_req[1]);
May 28, 2006
May 28, 2006
188
}
May 10, 2001
May 10, 2001
189
190
// Double abort to be sure to break the dbuffering process.
May 29, 2006
May 29, 2006
191
SDL_Delay(200);
May 28, 2006
May 28, 2006
192
May 29, 2006
May 29, 2006
193
194
195
196
197
198
D(bug("Reqs breaked, closing device...\n"));
CloseDevice((struct IORequest *) audio_req[0]);
D(bug("Device closed, freeing memory...\n"));
myfree(audio_req[1]);
D(bug("Memory freed, deleting IOReq...\n"));
DeleteIORequest((struct IORequest *) audio_req[0]);
May 28, 2006
May 28, 2006
199
200
201
audio_req[0] = audio_req[1] = NULL;
}
May 29, 2006
May 29, 2006
202
D(bug("Freeing mixbuf[0]...\n"));
May 28, 2006
May 28, 2006
203
if (mixbuf[0] != NULL) {
May 29, 2006
May 29, 2006
204
myfree(mixbuf[0]);
May 28, 2006
May 28, 2006
205
206
207
208
// SDL_FreeAudioMem(mixbuf[0]);
mixbuf[0] = NULL;
}
May 29, 2006
May 29, 2006
209
D(bug("Freeing mixbuf[1]...\n"));
May 28, 2006
May 28, 2006
210
if (mixbuf[1] != NULL) {
May 29, 2006
May 29, 2006
211
myfree(mixbuf[1]);
May 28, 2006
May 28, 2006
212
213
214
215
// SDL_FreeAudioMem(mixbuf[1]);
mixbuf[1] = NULL;
}
May 29, 2006
May 29, 2006
216
D(bug("Freeing audio_port...\n"));
May 28, 2006
May 28, 2006
217
218
if (audio_port != NULL) {
May 29, 2006
May 29, 2006
219
DeleteMsgPort(audio_port);
May 28, 2006
May 28, 2006
220
221
audio_port = NULL;
}
May 29, 2006
May 29, 2006
222
D(bug("...done!\n"));
Apr 26, 2001
Apr 26, 2001
223
224
}
May 28, 2006
May 28, 2006
225
static int
May 29, 2006
May 29, 2006
226
AHI_OpenAudio(_THIS, SDL_AudioSpec * spec)
May 28, 2006
May 28, 2006
227
228
229
{
// int width;
May 29, 2006
May 29, 2006
230
D(bug("AHI opening...\n"));
May 28, 2006
May 28, 2006
231
232
233
234
235
236
/* Determine the audio parameters from the AudioSpec */
switch (spec->format & 0xFF) {
case 8:
{ /* Signed 8 bit audio data */
May 29, 2006
May 29, 2006
237
D(bug("Samples a 8 bit...\n"));
May 28, 2006
May 28, 2006
238
239
240
241
242
243
244
245
246
247
248
spec->format = AUDIO_S8;
this->hidden->bytespersample = 1;
if (spec->channels < 2)
this->hidden->type = AHIST_M8S;
else
this->hidden->type = AHIST_S8S;
}
break;
case 16:
{ /* Signed 16 bit audio data */
May 29, 2006
May 29, 2006
249
D(bug("Samples a 16 bit...\n"));
May 28, 2006
May 28, 2006
250
251
252
253
254
255
256
257
258
259
260
spec->format = AUDIO_S16MSB;
this->hidden->bytespersample = 2;
if (spec->channels < 2)
this->hidden->type = AHIST_M16S;
else
this->hidden->type = AHIST_S16S;
}
break;
default:
{
May 29, 2006
May 29, 2006
261
SDL_SetError("Unsupported audio format");
May 28, 2006
May 28, 2006
262
263
264
265
266
return (-1);
}
}
if (spec->channels != 1 && spec->channels != 2) {
May 29, 2006
May 29, 2006
267
268
D(bug("Wrong channel number!\n"));
SDL_SetError("Channel number non supported");
May 28, 2006
May 28, 2006
269
270
271
return -1;
}
May 29, 2006
May 29, 2006
272
D(bug("Before CalculateAudioSpec\n"));
May 28, 2006
May 28, 2006
273
/* Update the fragment size as size in bytes */
May 29, 2006
May 29, 2006
274
SDL_CalculateAudioSpec(spec);
May 28, 2006
May 28, 2006
275
May 29, 2006
May 29, 2006
276
D(bug("Before CreateMsgPort\n"));
May 28, 2006
May 28, 2006
277
May 29, 2006
May 29, 2006
278
279
if (!(audio_port = CreateMsgPort())) {
SDL_SetError("Unable to create a MsgPort");
May 28, 2006
May 28, 2006
280
281
282
return -1;
}
May 29, 2006
May 29, 2006
283
D(bug("Before CreateIORequest\n"));
May 28, 2006
May 28, 2006
284
285
286
if (!
(audio_req[0] =
May 29, 2006
May 29, 2006
287
288
289
290
(struct AHIRequest *) CreateIORequest(audio_port,
sizeof(struct AHIRequest)))) {
SDL_SetError("Unable to create an AHIRequest");
DeleteMsgPort(audio_port);
May 28, 2006
May 28, 2006
291
292
293
294
295
return -1;
}
audio_req[0]->ahir_Version = 4;
May 29, 2006
May 29, 2006
296
297
298
299
if (OpenDevice(AHINAME, 0, (struct IORequest *) audio_req[0], NULL)) {
SDL_SetError("Unable to open AHI device!\n");
DeleteIORequest((struct IORequest *) audio_req[0]);
DeleteMsgPort(audio_port);
May 28, 2006
May 28, 2006
300
301
302
return -1;
}
May 29, 2006
May 29, 2006
303
D(bug("AFTER opendevice\n"));
May 28, 2006
May 28, 2006
304
305
306
307
308
/* Set output frequency and size */
this->hidden->freq = spec->freq;
this->hidden->size = spec->size;
May 29, 2006
May 29, 2006
309
D(bug("Before buffer allocation\n"));
May 28, 2006
May 28, 2006
310
311
/* Allocate mixing buffer */
May 29, 2006
May 29, 2006
312
313
mixbuf[0] = (Uint8 *) mymalloc(spec->size);
mixbuf[1] = (Uint8 *) mymalloc(spec->size);
May 28, 2006
May 28, 2006
314
May 29, 2006
May 29, 2006
315
D(bug("Before audio_req allocation\n"));
May 28, 2006
May 28, 2006
316
May 29, 2006
May 29, 2006
317
318
if (!(audio_req[1] = mymalloc(sizeof(struct AHIRequest)))) {
SDL_OutOfMemory();
May 28, 2006
May 28, 2006
319
320
321
return (-1);
}
May 29, 2006
May 29, 2006
322
D(bug("Before audio_req memcpy\n"));
May 28, 2006
May 28, 2006
323
May 29, 2006
May 29, 2006
324
SDL_memcpy(audio_req[1], audio_req[0], sizeof(struct AHIRequest));
May 28, 2006
May 28, 2006
325
326
if (mixbuf[0] == NULL || mixbuf[1] == NULL) {
May 29, 2006
May 29, 2006
327
SDL_OutOfMemory();
May 28, 2006
May 28, 2006
328
329
330
return (-1);
}
May 29, 2006
May 29, 2006
331
D(bug("Before mixbuf memset\n"));
May 28, 2006
May 28, 2006
332
May 29, 2006
May 29, 2006
333
334
SDL_memset(mixbuf[0], spec->silence, spec->size);
SDL_memset(mixbuf[1], spec->silence, spec->size);
May 28, 2006
May 28, 2006
335
336
337
338
current_buffer = 0;
playing = 0;
May 29, 2006
May 29, 2006
339
340
341
342
D(bug
("AHI opened: freq:%ld mixbuf:%lx/%lx buflen:%ld bits:%ld channels:%ld\n",
spec->freq, mixbuf[0], mixbuf[1], spec->size,
this->hidden->bytespersample * 8, spec->channels));
May 28, 2006
May 28, 2006
343
344
345
/* We're ready to rock and roll. :-) */
return (0);
Apr 26, 2001
Apr 26, 2001
346
}
May 28, 2006
May 28, 2006
347
348
/* vi: set ts=4 sw=4 expandtab: */