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

Latest commit

 

History

History
272 lines (234 loc) · 6.97 KB

SDL_mmeaudio.c

File metadata and controls

272 lines (234 loc) · 6.97 KB
 
1
2
/*
SDL - Simple DirectMedia Layer
Jan 4, 2004
Jan 4, 2004
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
*/
Feb 21, 2006
Feb 21, 2006
22
#include "SDL_config.h"
23
24
/* Tru64 UNIX MME support */
Feb 7, 2006
Feb 7, 2006
25
26
27
#include <mme_api.h>
#include "SDL_timer.h"
Feb 10, 2006
Feb 10, 2006
28
#include "SDL_audio.h"
Feb 16, 2006
Feb 16, 2006
29
#include "../SDL_audio_c.h"
30
31
32
33
34
#include "SDL_mmeaudio.h"
static BOOL inUse[NUM_BUFFERS];
/* Audio driver functions */
Jul 10, 2006
Jul 10, 2006
35
static int MME_OpenAudio(_THIS, SDL_AudioSpec * spec);
36
37
38
39
40
41
42
static void MME_WaitAudio(_THIS);
static Uint8 *MME_GetAudioBuf(_THIS);
static void MME_PlayAudio(_THIS);
static void MME_WaitDone(_THIS);
static void MME_CloseAudio(_THIS);
/* Audio driver bootstrap functions */
Jul 10, 2006
Jul 10, 2006
43
44
static int
Audio_Available(void)
Jul 10, 2006
Jul 10, 2006
46
return (1);
Jul 10, 2006
Jul 10, 2006
49
50
static void
Audio_DeleteDevice(SDL_AudioDevice * device)
Jul 10, 2006
Jul 10, 2006
52
53
54
55
56
57
58
if (device) {
if (device->hidden) {
SDL_free(device->hidden);
device->hidden = NULL;
}
SDL_free(device);
device = NULL;
Jul 10, 2006
Jul 10, 2006
62
63
static SDL_AudioDevice *
Audio_CreateDevice(int devindex)
64
65
66
67
{
SDL_AudioDevice *this;
/* Initialize all variables that we clean on shutdown */
Feb 7, 2006
Feb 7, 2006
68
this = SDL_malloc(sizeof(SDL_AudioDevice));
Jul 10, 2006
Jul 10, 2006
69
70
71
if (this) {
SDL_memset(this, 0, (sizeof *this));
this->hidden = SDL_malloc((sizeof *this->hidden));
Jul 10, 2006
Jul 10, 2006
73
74
75
76
77
78
if ((this == NULL) || (this->hidden == NULL)) {
SDL_OutOfMemory();
if (this) {
SDL_free(this);
}
return (0);
Feb 7, 2006
Feb 7, 2006
80
SDL_memset(this->hidden, 0, (sizeof *this->hidden));
81
/* Set the function pointers */
Jul 10, 2006
Jul 10, 2006
82
83
84
85
86
87
88
this->OpenAudio = MME_OpenAudio;
this->WaitAudio = MME_WaitAudio;
this->PlayAudio = MME_PlayAudio;
this->GetAudioBuf = MME_GetAudioBuf;
this->WaitDone = MME_WaitDone;
this->CloseAudio = MME_CloseAudio;
this->free = Audio_DeleteDevice;
89
90
91
92
93
94
95
96
97
return this;
}
AudioBootStrap MMEAUDIO_bootstrap = {
"waveout", "Tru64 MME WaveOut",
Audio_Available, Audio_CreateDevice
};
Jul 10, 2006
Jul 10, 2006
98
99
static void
SetMMerror(char *function, MMRESULT code)
100
101
102
103
{
int len;
char errbuf[MAXERRORLENGTH];
Feb 7, 2006
Feb 7, 2006
104
SDL_snprintf(errbuf, SDL_arraysize(errbuf), "%s: ", function);
Feb 7, 2006
Feb 7, 2006
105
len = SDL_strlen(errbuf);
Jul 10, 2006
Jul 10, 2006
106
107
waveOutGetErrorText(code, errbuf + len, MAXERRORLENGTH - len);
SDL_SetError("%s", errbuf);
Jul 10, 2006
Jul 10, 2006
110
111
112
static void CALLBACK
MME_CALLBACK(HWAVEOUT hwo,
UINT uMsg, DWORD dwInstance, LPARAM dwParam1, LPARAM dwParam2)
113
114
115
{
WAVEHDR *wp = (WAVEHDR *) dwParam1;
Jul 10, 2006
Jul 10, 2006
116
117
if (uMsg == WOM_DONE)
inUse[wp->dwUser] = FALSE;
Jul 10, 2006
Jul 10, 2006
120
121
static int
MME_OpenAudio(_THIS, SDL_AudioSpec * spec)
122
123
124
125
126
127
128
129
{
MMRESULT result;
int i;
mixbuf = NULL;
/* Set basic WAVE format parameters */
shm = mmeAllocMem(sizeof(*shm));
Jul 10, 2006
Jul 10, 2006
130
131
132
if (shm == NULL) {
SDL_SetError("Out of memory: shm");
return (-1);
133
134
135
136
137
}
shm->sound = 0;
shm->wFmt.wf.wFormatTag = WAVE_FORMAT_PCM;
/* Determine the audio parameters from the AudioSpec */
Jul 10, 2006
Jul 10, 2006
138
139
140
141
142
143
144
145
146
147
148
149
150
151
switch (spec->format & 0xFF) {
case 8:
/* Unsigned 8 bit audio data */
spec->format = AUDIO_U8;
shm->wFmt.wBitsPerSample = 8;
break;
case 16:
/* Signed 16 bit audio data */
spec->format = AUDIO_S16;
shm->wFmt.wBitsPerSample = 16;
break;
default:
SDL_SetError("Unsupported audio format");
return (-1);
152
153
154
155
156
}
shm->wFmt.wf.nChannels = spec->channels;
shm->wFmt.wf.nSamplesPerSec = spec->freq;
shm->wFmt.wf.nBlockAlign =
Jul 10, 2006
Jul 10, 2006
157
shm->wFmt.wf.nChannels * shm->wFmt.wBitsPerSample / 8;
158
shm->wFmt.wf.nAvgBytesPerSec =
Jul 10, 2006
Jul 10, 2006
159
shm->wFmt.wf.nSamplesPerSec * shm->wFmt.wf.nBlockAlign;
160
161
/* Check the buffer size -- minimum of 1/4 second (word aligned) */
Jul 10, 2006
Jul 10, 2006
162
163
if (spec->samples < (spec->freq / 4))
spec->samples = ((spec->freq / 4) + 3) & ~3;
164
165
166
167
168
169
/* Update the fragment size as size in bytes */
SDL_CalculateAudioSpec(spec);
/* Open the audio device */
result = waveOutOpen(&(shm->sound),
Jul 10, 2006
Jul 10, 2006
170
171
172
173
174
175
176
WAVE_MAPPER,
&(shm->wFmt.wf),
MME_CALLBACK,
NULL, (CALLBACK_FUNCTION | WAVE_OPEN_SHAREABLE));
if (result != MMSYSERR_NOERROR) {
SetMMerror("waveOutOpen()", result);
return (-1);
177
178
179
}
/* Create the sound buffers */
Jul 10, 2006
Jul 10, 2006
180
181
182
183
mixbuf = (Uint8 *) mmeAllocBuffer(NUM_BUFFERS * (spec->size));
if (mixbuf == NULL) {
SDL_SetError("Out of memory: mixbuf");
return (-1);
184
185
186
}
for (i = 0; i < NUM_BUFFERS; i++) {
Jul 10, 2006
Jul 10, 2006
187
188
189
190
191
192
193
194
shm->wHdr[i].lpData = &mixbuf[i * (spec->size)];
shm->wHdr[i].dwBufferLength = spec->size;
shm->wHdr[i].dwFlags = 0;
shm->wHdr[i].dwUser = i;
shm->wHdr[i].dwLoops = 0; /* loop control counter */
shm->wHdr[i].lpNext = NULL; /* reserved for driver */
shm->wHdr[i].reserved = 0;
inUse[i] = FALSE;
195
196
197
198
199
}
next_buffer = 0;
return 0;
}
Jul 10, 2006
Jul 10, 2006
200
201
static void
MME_WaitAudio(_THIS)
Jul 10, 2006
Jul 10, 2006
203
204
205
while (inUse[next_buffer]) {
mmeWaitForCallbacks();
mmeProcessCallbacks();
Dec 14, 2003
Dec 14, 2003
206
}
Jul 10, 2006
Jul 10, 2006
209
210
static Uint8 *
MME_GetAudioBuf(_THIS)
211
212
213
214
{
Uint8 *retval;
inUse[next_buffer] = TRUE;
Jul 10, 2006
Jul 10, 2006
215
retval = (Uint8 *) (shm->wHdr[next_buffer].lpData);
216
217
218
return retval;
}
Jul 10, 2006
Jul 10, 2006
219
220
static void
MME_PlayAudio(_THIS)
221
222
223
{
/* Queue it up */
waveOutWrite(shm->sound, &(shm->wHdr[next_buffer]), sizeof(WAVEHDR));
Jul 10, 2006
Jul 10, 2006
224
next_buffer = (next_buffer + 1) % NUM_BUFFERS;
Jul 10, 2006
Jul 10, 2006
227
228
static void
MME_WaitDone(_THIS)
229
230
231
232
{
MMRESULT result;
int i;
Jul 10, 2006
Jul 10, 2006
233
234
235
236
237
238
239
240
241
242
if (shm->sound) {
for (i = 0; i < NUM_BUFFERS; i++)
while (inUse[i]) {
mmeWaitForCallbacks();
mmeProcessCallbacks();
}
result = waveOutReset(shm->sound);
if (result != MMSYSERR_NOERROR)
SetMMerror("waveOutReset()", result);
mmeProcessCallbacks();
Jul 10, 2006
Jul 10, 2006
246
247
static void
MME_CloseAudio(_THIS)
248
249
250
{
MMRESULT result;
Jul 10, 2006
Jul 10, 2006
251
252
253
254
255
if (mixbuf) {
result = mmeFreeBuffer(mixbuf);
if (result != MMSYSERR_NOERROR)
SetMMerror("mmeFreeBuffer", result);
mixbuf = NULL;
Jul 10, 2006
Jul 10, 2006
258
259
260
261
262
263
264
265
266
267
268
if (shm) {
if (shm->sound) {
result = waveOutClose(shm->sound);
if (result != MMSYSERR_NOERROR)
SetMMerror("waveOutClose()", result);
mmeProcessCallbacks();
}
result = mmeFreeMem(shm);
if (result != MMSYSERR_NOERROR)
SetMMerror("mmeFreeMem()", result);
shm = NULL;
Jul 10, 2006
Jul 10, 2006
272
/* vi: set ts=4 sw=4 expandtab: */