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 */
May 29, 2006
May 29, 2006
35
36
37
38
39
40
static int MME_OpenAudio(_THIS, SDL_AudioSpec * spec);
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);
41
42
/* Audio driver bootstrap functions */
May 28, 2006
May 28, 2006
43
static int
May 29, 2006
May 29, 2006
44
Audio_Available(void)
May 28, 2006
May 28, 2006
46
return (1);
May 28, 2006
May 28, 2006
49
static void
May 29, 2006
May 29, 2006
50
Audio_DeleteDevice(SDL_AudioDevice * device)
May 28, 2006
May 28, 2006
52
53
if (device) {
if (device->hidden) {
May 29, 2006
May 29, 2006
54
SDL_free(device->hidden);
May 28, 2006
May 28, 2006
55
56
device->hidden = NULL;
}
May 29, 2006
May 29, 2006
57
SDL_free(device);
May 28, 2006
May 28, 2006
58
device = NULL;
May 28, 2006
May 28, 2006
62
static SDL_AudioDevice *
May 29, 2006
May 29, 2006
63
Audio_CreateDevice(int devindex)
64
65
66
67
{
SDL_AudioDevice *this;
/* Initialize all variables that we clean on shutdown */
May 29, 2006
May 29, 2006
68
this = SDL_malloc(sizeof(SDL_AudioDevice));
May 28, 2006
May 28, 2006
69
if (this) {
May 29, 2006
May 29, 2006
70
71
SDL_memset(this, 0, (sizeof *this));
this->hidden = SDL_malloc((sizeof *this->hidden));
May 28, 2006
May 28, 2006
73
if ((this == NULL) || (this->hidden == NULL)) {
May 29, 2006
May 29, 2006
74
SDL_OutOfMemory();
May 28, 2006
May 28, 2006
75
if (this) {
May 29, 2006
May 29, 2006
76
SDL_free(this);
May 28, 2006
May 28, 2006
77
78
}
return (0);
May 29, 2006
May 29, 2006
80
SDL_memset(this->hidden, 0, (sizeof *this->hidden));
81
/* Set the function pointers */
May 28, 2006
May 28, 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
};
May 28, 2006
May 28, 2006
98
static void
May 29, 2006
May 29, 2006
99
SetMMerror(char *function, MMRESULT code)
100
101
102
103
{
int len;
char errbuf[MAXERRORLENGTH];
May 29, 2006
May 29, 2006
104
105
106
107
SDL_snprintf(errbuf, SDL_arraysize(errbuf), "%s: ", function);
len = SDL_strlen(errbuf);
waveOutGetErrorText(code, errbuf + len, MAXERRORLENGTH - len);
SDL_SetError("%s", errbuf);
May 28, 2006
May 28, 2006
110
static void CALLBACK
May 29, 2006
May 29, 2006
111
112
MME_CALLBACK(HWAVEOUT hwo,
UINT uMsg, DWORD dwInstance, LPARAM dwParam1, LPARAM dwParam2)
113
114
115
{
WAVEHDR *wp = (WAVEHDR *) dwParam1;
May 28, 2006
May 28, 2006
116
117
if (uMsg == WOM_DONE)
inUse[wp->dwUser] = FALSE;
May 28, 2006
May 28, 2006
120
static int
May 29, 2006
May 29, 2006
121
MME_OpenAudio(_THIS, SDL_AudioSpec * spec)
122
123
124
125
126
127
128
{
MMRESULT result;
int i;
mixbuf = NULL;
/* Set basic WAVE format parameters */
May 29, 2006
May 29, 2006
129
shm = mmeAllocMem(sizeof(*shm));
May 28, 2006
May 28, 2006
130
if (shm == NULL) {
May 29, 2006
May 29, 2006
131
SDL_SetError("Out of memory: shm");
May 28, 2006
May 28, 2006
132
return (-1);
133
134
135
136
137
}
shm->sound = 0;
shm->wFmt.wf.wFormatTag = WAVE_FORMAT_PCM;
/* Determine the audio parameters from the AudioSpec */
May 28, 2006
May 28, 2006
138
139
140
141
142
143
144
145
146
147
148
149
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:
May 29, 2006
May 29, 2006
150
SDL_SetError("Unsupported audio format");
May 28, 2006
May 28, 2006
151
return (-1);
152
153
154
155
156
}
shm->wFmt.wf.nChannels = spec->channels;
shm->wFmt.wf.nSamplesPerSec = spec->freq;
shm->wFmt.wf.nBlockAlign =
May 28, 2006
May 28, 2006
157
shm->wFmt.wf.nChannels * shm->wFmt.wBitsPerSample / 8;
158
shm->wFmt.wf.nAvgBytesPerSec =
May 28, 2006
May 28, 2006
159
shm->wFmt.wf.nSamplesPerSec * shm->wFmt.wf.nBlockAlign;
160
161
/* Check the buffer size -- minimum of 1/4 second (word aligned) */
May 28, 2006
May 28, 2006
162
163
if (spec->samples < (spec->freq / 4))
spec->samples = ((spec->freq / 4) + 3) & ~3;
164
165
/* Update the fragment size as size in bytes */
May 29, 2006
May 29, 2006
166
SDL_CalculateAudioSpec(spec);
167
168
/* Open the audio device */
May 29, 2006
May 29, 2006
169
170
171
172
173
result = waveOutOpen(&(shm->sound),
WAVE_MAPPER,
&(shm->wFmt.wf),
MME_CALLBACK,
NULL, (CALLBACK_FUNCTION | WAVE_OPEN_SHAREABLE));
May 28, 2006
May 28, 2006
174
if (result != MMSYSERR_NOERROR) {
May 29, 2006
May 29, 2006
175
SetMMerror("waveOutOpen()", result);
May 28, 2006
May 28, 2006
176
return (-1);
177
178
179
}
/* Create the sound buffers */
May 29, 2006
May 29, 2006
180
mixbuf = (Uint8 *) mmeAllocBuffer(NUM_BUFFERS * (spec->size));
May 28, 2006
May 28, 2006
181
if (mixbuf == NULL) {
May 29, 2006
May 29, 2006
182
SDL_SetError("Out of memory: mixbuf");
May 28, 2006
May 28, 2006
183
return (-1);
184
185
186
}
for (i = 0; i < NUM_BUFFERS; i++) {
May 28, 2006
May 28, 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;
}
May 28, 2006
May 28, 2006
200
static void
May 29, 2006
May 29, 2006
201
MME_WaitAudio(_THIS)
May 28, 2006
May 28, 2006
203
while (inUse[next_buffer]) {
May 29, 2006
May 29, 2006
204
205
mmeWaitForCallbacks();
mmeProcessCallbacks();
Dec 14, 2003
Dec 14, 2003
206
}
May 28, 2006
May 28, 2006
209
static Uint8 *
May 29, 2006
May 29, 2006
210
MME_GetAudioBuf(_THIS)
211
212
213
214
{
Uint8 *retval;
inUse[next_buffer] = TRUE;
May 28, 2006
May 28, 2006
215
retval = (Uint8 *) (shm->wHdr[next_buffer].lpData);
216
217
218
return retval;
}
May 28, 2006
May 28, 2006
219
static void
May 29, 2006
May 29, 2006
220
MME_PlayAudio(_THIS)
221
222
{
/* Queue it up */
May 29, 2006
May 29, 2006
223
waveOutWrite(shm->sound, &(shm->wHdr[next_buffer]), sizeof(WAVEHDR));
May 28, 2006
May 28, 2006
224
next_buffer = (next_buffer + 1) % NUM_BUFFERS;
May 28, 2006
May 28, 2006
227
static void
May 29, 2006
May 29, 2006
228
MME_WaitDone(_THIS)
229
230
231
232
{
MMRESULT result;
int i;
May 28, 2006
May 28, 2006
233
234
235
if (shm->sound) {
for (i = 0; i < NUM_BUFFERS; i++)
while (inUse[i]) {
May 29, 2006
May 29, 2006
236
237
mmeWaitForCallbacks();
mmeProcessCallbacks();
May 28, 2006
May 28, 2006
238
}
May 29, 2006
May 29, 2006
239
result = waveOutReset(shm->sound);
May 28, 2006
May 28, 2006
240
if (result != MMSYSERR_NOERROR)
May 29, 2006
May 29, 2006
241
242
SetMMerror("waveOutReset()", result);
mmeProcessCallbacks();
May 28, 2006
May 28, 2006
246
static void
May 29, 2006
May 29, 2006
247
MME_CloseAudio(_THIS)
248
249
250
{
MMRESULT result;
May 28, 2006
May 28, 2006
251
if (mixbuf) {
May 29, 2006
May 29, 2006
252
result = mmeFreeBuffer(mixbuf);
May 28, 2006
May 28, 2006
253
if (result != MMSYSERR_NOERROR)
May 29, 2006
May 29, 2006
254
SetMMerror("mmeFreeBuffer", result);
May 28, 2006
May 28, 2006
255
mixbuf = NULL;
May 28, 2006
May 28, 2006
258
259
if (shm) {
if (shm->sound) {
May 29, 2006
May 29, 2006
260
result = waveOutClose(shm->sound);
May 28, 2006
May 28, 2006
261
if (result != MMSYSERR_NOERROR)
May 29, 2006
May 29, 2006
262
263
SetMMerror("waveOutClose()", result);
mmeProcessCallbacks();
May 28, 2006
May 28, 2006
264
}
May 29, 2006
May 29, 2006
265
result = mmeFreeMem(shm);
May 28, 2006
May 28, 2006
266
if (result != MMSYSERR_NOERROR)
May 29, 2006
May 29, 2006
267
SetMMerror("mmeFreeMem()", result);
May 28, 2006
May 28, 2006
268
shm = NULL;
May 28, 2006
May 28, 2006
272
/* vi: set ts=4 sw=4 expandtab: */