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