Mercurial > sdl-ios-xcode
comparison src/audio/windx5/SDL_dx5audio.c @ 1668:4da1ee79c9af SDL-1.3
more tweaking indent options
author | Sam Lantinga <slouken@libsdl.org> |
---|---|
date | Mon, 29 May 2006 04:04:35 +0000 |
parents | 782fd950bd46 |
children | 442248d4e738 |
comparison
equal
deleted
inserted
replaced
1667:1fddae038bc8 | 1668:4da1ee79c9af |
---|---|
30 | 30 |
31 /* Define this if you want to use DirectX 6 DirectSoundNotify interface */ | 31 /* Define this if you want to use DirectX 6 DirectSoundNotify interface */ |
32 //#define USE_POSITION_NOTIFY | 32 //#define USE_POSITION_NOTIFY |
33 | 33 |
34 /* DirectX function pointers for audio */ | 34 /* DirectX function pointers for audio */ |
35 HRESULT (WINAPI * DSoundCreate) (LPGUID, LPDIRECTSOUND *, LPUNKNOWN); | 35 HRESULT(WINAPI * DSoundCreate) (LPGUID, LPDIRECTSOUND *, LPUNKNOWN); |
36 | 36 |
37 /* Audio driver functions */ | 37 /* Audio driver functions */ |
38 static int DX5_OpenAudio (_THIS, SDL_AudioSpec * spec); | 38 static int DX5_OpenAudio(_THIS, SDL_AudioSpec * spec); |
39 static void DX5_ThreadInit (_THIS); | 39 static void DX5_ThreadInit(_THIS); |
40 static void DX5_WaitAudio_BusyWait (_THIS); | 40 static void DX5_WaitAudio_BusyWait(_THIS); |
41 #ifdef USE_POSITION_NOTIFY | 41 #ifdef USE_POSITION_NOTIFY |
42 static void DX6_WaitAudio_EventWait (_THIS); | 42 static void DX6_WaitAudio_EventWait(_THIS); |
43 #endif | 43 #endif |
44 static void DX5_PlayAudio (_THIS); | 44 static void DX5_PlayAudio(_THIS); |
45 static Uint8 *DX5_GetAudioBuf (_THIS); | 45 static Uint8 *DX5_GetAudioBuf(_THIS); |
46 static void DX5_WaitDone (_THIS); | 46 static void DX5_WaitDone(_THIS); |
47 static void DX5_CloseAudio (_THIS); | 47 static void DX5_CloseAudio(_THIS); |
48 | 48 |
49 /* Audio driver bootstrap functions */ | 49 /* Audio driver bootstrap functions */ |
50 | 50 |
51 static int | 51 static int |
52 Audio_Available (void) | 52 Audio_Available(void) |
53 { | 53 { |
54 HINSTANCE DSoundDLL; | 54 HINSTANCE DSoundDLL; |
55 int dsound_ok; | 55 int dsound_ok; |
56 | 56 |
57 /* Version check DSOUND.DLL (Is DirectX okay?) */ | 57 /* Version check DSOUND.DLL (Is DirectX okay?) */ |
58 dsound_ok = 0; | 58 dsound_ok = 0; |
59 DSoundDLL = LoadLibrary (TEXT ("DSOUND.DLL")); | 59 DSoundDLL = LoadLibrary(TEXT("DSOUND.DLL")); |
60 if (DSoundDLL != NULL) { | 60 if (DSoundDLL != NULL) { |
61 /* We just use basic DirectSound, we're okay */ | 61 /* We just use basic DirectSound, we're okay */ |
62 /* Yay! */ | 62 /* Yay! */ |
63 /* Unfortunately, the sound drivers on NT have | 63 /* Unfortunately, the sound drivers on NT have |
64 higher latencies than the audio buffers used | 64 higher latencies than the audio buffers used |
65 by many SDL applications, so there are gaps | 65 by many SDL applications, so there are gaps |
66 in the audio - it sounds terrible. Punt for now. | 66 in the audio - it sounds terrible. Punt for now. |
67 */ | 67 */ |
68 OSVERSIONINFO ver; | 68 OSVERSIONINFO ver; |
69 ver.dwOSVersionInfoSize = sizeof (OSVERSIONINFO); | 69 ver.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); |
70 GetVersionEx (&ver); | 70 GetVersionEx(&ver); |
71 switch (ver.dwPlatformId) { | 71 switch (ver.dwPlatformId) { |
72 case VER_PLATFORM_WIN32_NT: | 72 case VER_PLATFORM_WIN32_NT: |
73 if (ver.dwMajorVersion > 4) { | 73 if (ver.dwMajorVersion > 4) { |
74 /* Win2K */ | 74 /* Win2K */ |
75 dsound_ok = 1; | 75 dsound_ok = 1; |
86 /* Now check for DirectX 5 or better - otherwise | 86 /* Now check for DirectX 5 or better - otherwise |
87 * we will fail later in DX5_OpenAudio without a chance | 87 * we will fail later in DX5_OpenAudio without a chance |
88 * to fall back to the DIB driver. */ | 88 * to fall back to the DIB driver. */ |
89 if (dsound_ok) { | 89 if (dsound_ok) { |
90 /* DirectSoundCaptureCreate was added in DX5 */ | 90 /* DirectSoundCaptureCreate was added in DX5 */ |
91 if (!GetProcAddress | 91 if (!GetProcAddress(DSoundDLL, TEXT("DirectSoundCaptureCreate"))) |
92 (DSoundDLL, TEXT ("DirectSoundCaptureCreate"))) | |
93 dsound_ok = 0; | 92 dsound_ok = 0; |
94 | 93 |
95 } | 94 } |
96 /* Clean up.. */ | 95 /* Clean up.. */ |
97 FreeLibrary (DSoundDLL); | 96 FreeLibrary(DSoundDLL); |
98 } | 97 } |
99 return (dsound_ok); | 98 return (dsound_ok); |
100 } | 99 } |
101 | 100 |
102 /* Functions for loading the DirectX functions dynamically */ | 101 /* Functions for loading the DirectX functions dynamically */ |
103 static HINSTANCE DSoundDLL = NULL; | 102 static HINSTANCE DSoundDLL = NULL; |
104 | 103 |
105 static void | 104 static void |
106 DX5_Unload (void) | 105 DX5_Unload(void) |
107 { | 106 { |
108 if (DSoundDLL != NULL) { | 107 if (DSoundDLL != NULL) { |
109 FreeLibrary (DSoundDLL); | 108 FreeLibrary(DSoundDLL); |
110 DSoundCreate = NULL; | 109 DSoundCreate = NULL; |
111 DSoundDLL = NULL; | 110 DSoundDLL = NULL; |
112 } | 111 } |
113 } | 112 } |
114 static int | 113 static int |
115 DX5_Load (void) | 114 DX5_Load(void) |
116 { | 115 { |
117 int status; | 116 int status; |
118 | 117 |
119 DX5_Unload (); | 118 DX5_Unload(); |
120 DSoundDLL = LoadLibrary (TEXT ("DSOUND.DLL")); | 119 DSoundDLL = LoadLibrary(TEXT("DSOUND.DLL")); |
121 if (DSoundDLL != NULL) { | 120 if (DSoundDLL != NULL) { |
122 DSoundCreate = (void *) GetProcAddress (DSoundDLL, | 121 DSoundCreate = (void *) GetProcAddress(DSoundDLL, |
123 TEXT ("DirectSoundCreate")); | 122 TEXT("DirectSoundCreate")); |
124 } | 123 } |
125 if (DSoundDLL && DSoundCreate) { | 124 if (DSoundDLL && DSoundCreate) { |
126 status = 0; | 125 status = 0; |
127 } else { | 126 } else { |
128 DX5_Unload (); | 127 DX5_Unload(); |
129 status = -1; | 128 status = -1; |
130 } | 129 } |
131 return status; | 130 return status; |
132 } | 131 } |
133 | 132 |
134 static void | 133 static void |
135 Audio_DeleteDevice (SDL_AudioDevice * device) | 134 Audio_DeleteDevice(SDL_AudioDevice * device) |
136 { | 135 { |
137 DX5_Unload (); | 136 DX5_Unload(); |
138 SDL_free (device->hidden); | 137 SDL_free(device->hidden); |
139 SDL_free (device); | 138 SDL_free(device); |
140 } | 139 } |
141 | 140 |
142 static SDL_AudioDevice * | 141 static SDL_AudioDevice * |
143 Audio_CreateDevice (int devindex) | 142 Audio_CreateDevice(int devindex) |
144 { | 143 { |
145 SDL_AudioDevice *this; | 144 SDL_AudioDevice *this; |
146 | 145 |
147 /* Load DirectX */ | 146 /* Load DirectX */ |
148 if (DX5_Load () < 0) { | 147 if (DX5_Load() < 0) { |
149 return (NULL); | 148 return (NULL); |
150 } | 149 } |
151 | 150 |
152 /* Initialize all variables that we clean on shutdown */ | 151 /* Initialize all variables that we clean on shutdown */ |
153 this = (SDL_AudioDevice *) SDL_malloc (sizeof (SDL_AudioDevice)); | 152 this = (SDL_AudioDevice *) SDL_malloc(sizeof(SDL_AudioDevice)); |
154 if (this) { | 153 if (this) { |
155 SDL_memset (this, 0, (sizeof *this)); | 154 SDL_memset(this, 0, (sizeof *this)); |
156 this->hidden = (struct SDL_PrivateAudioData *) | 155 this->hidden = (struct SDL_PrivateAudioData *) |
157 SDL_malloc ((sizeof *this->hidden)); | 156 SDL_malloc((sizeof *this->hidden)); |
158 } | 157 } |
159 if ((this == NULL) || (this->hidden == NULL)) { | 158 if ((this == NULL) || (this->hidden == NULL)) { |
160 SDL_OutOfMemory (); | 159 SDL_OutOfMemory(); |
161 if (this) { | 160 if (this) { |
162 SDL_free (this); | 161 SDL_free(this); |
163 } | 162 } |
164 return (0); | 163 return (0); |
165 } | 164 } |
166 SDL_memset (this->hidden, 0, (sizeof *this->hidden)); | 165 SDL_memset(this->hidden, 0, (sizeof *this->hidden)); |
167 | 166 |
168 /* Set the function pointers */ | 167 /* Set the function pointers */ |
169 this->OpenAudio = DX5_OpenAudio; | 168 this->OpenAudio = DX5_OpenAudio; |
170 this->ThreadInit = DX5_ThreadInit; | 169 this->ThreadInit = DX5_ThreadInit; |
171 this->WaitAudio = DX5_WaitAudio_BusyWait; | 170 this->WaitAudio = DX5_WaitAudio_BusyWait; |
183 "dsound", "Win95/98/2000 DirectSound", | 182 "dsound", "Win95/98/2000 DirectSound", |
184 Audio_Available, Audio_CreateDevice | 183 Audio_Available, Audio_CreateDevice |
185 }; | 184 }; |
186 | 185 |
187 static void | 186 static void |
188 SetDSerror (const char *function, int code) | 187 SetDSerror(const char *function, int code) |
189 { | 188 { |
190 static const char *error; | 189 static const char *error; |
191 static char errbuf[1024]; | 190 static char errbuf[1024]; |
192 | 191 |
193 errbuf[0] = 0; | 192 errbuf[0] = 0; |
225 break; | 224 break; |
226 case DSERR_UNSUPPORTED: | 225 case DSERR_UNSUPPORTED: |
227 error = "Function not supported"; | 226 error = "Function not supported"; |
228 break; | 227 break; |
229 default: | 228 default: |
230 SDL_snprintf (errbuf, SDL_arraysize (errbuf), | 229 SDL_snprintf(errbuf, SDL_arraysize(errbuf), |
231 "%s: Unknown DirectSound error: 0x%x", function, code); | 230 "%s: Unknown DirectSound error: 0x%x", function, code); |
232 break; | 231 break; |
233 } | 232 } |
234 if (!errbuf[0]) { | 233 if (!errbuf[0]) { |
235 SDL_snprintf (errbuf, SDL_arraysize (errbuf), "%s: %s", function, | 234 SDL_snprintf(errbuf, SDL_arraysize(errbuf), "%s: %s", function, |
236 error); | 235 error); |
237 } | 236 } |
238 SDL_SetError ("%s", errbuf); | 237 SDL_SetError("%s", errbuf); |
239 return; | 238 return; |
240 } | 239 } |
241 | 240 |
242 /* DirectSound needs to be associated with a window */ | 241 /* DirectSound needs to be associated with a window */ |
243 static HWND mainwin = NULL; | 242 static HWND mainwin = NULL; |
244 /* */ | 243 /* */ |
245 void | 244 void |
246 DX5_SoundFocus (HWND hwnd) | 245 DX5_SoundFocus(HWND hwnd) |
247 { | 246 { |
248 mainwin = hwnd; | 247 mainwin = hwnd; |
249 } | 248 } |
250 | 249 |
251 static void | 250 static void |
252 DX5_ThreadInit (_THIS) | 251 DX5_ThreadInit(_THIS) |
253 { | 252 { |
254 SetThreadPriority (GetCurrentThread (), THREAD_PRIORITY_HIGHEST); | 253 SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_HIGHEST); |
255 } | 254 } |
256 | 255 |
257 static void | 256 static void |
258 DX5_WaitAudio_BusyWait (_THIS) | 257 DX5_WaitAudio_BusyWait(_THIS) |
259 { | 258 { |
260 DWORD status; | 259 DWORD status; |
261 DWORD cursor, junk; | 260 DWORD cursor, junk; |
262 HRESULT result; | 261 HRESULT result; |
263 | 262 |
264 /* Semi-busy wait, since we have no way of getting play notification | 263 /* Semi-busy wait, since we have no way of getting play notification |
265 on a primary mixing buffer located in hardware (DirectX 5.0) | 264 on a primary mixing buffer located in hardware (DirectX 5.0) |
266 */ | 265 */ |
267 result = IDirectSoundBuffer_GetCurrentPosition (mixbuf, &cursor, &junk); | 266 result = IDirectSoundBuffer_GetCurrentPosition(mixbuf, &cursor, &junk); |
268 if (result != DS_OK) { | 267 if (result != DS_OK) { |
269 if (result == DSERR_BUFFERLOST) { | 268 if (result == DSERR_BUFFERLOST) { |
270 IDirectSoundBuffer_Restore (mixbuf); | 269 IDirectSoundBuffer_Restore(mixbuf); |
271 } | 270 } |
272 #ifdef DEBUG_SOUND | 271 #ifdef DEBUG_SOUND |
273 SetDSerror ("DirectSound GetCurrentPosition", result); | 272 SetDSerror("DirectSound GetCurrentPosition", result); |
274 #endif | 273 #endif |
275 return; | 274 return; |
276 } | 275 } |
277 cursor /= mixlen; | 276 cursor /= mixlen; |
278 | 277 |
279 while (cursor == playing) { | 278 while (cursor == playing) { |
280 /* FIXME: find out how much time is left and sleep that long */ | 279 /* FIXME: find out how much time is left and sleep that long */ |
281 SDL_Delay (10); | 280 SDL_Delay(10); |
282 | 281 |
283 /* Try to restore a lost sound buffer */ | 282 /* Try to restore a lost sound buffer */ |
284 IDirectSoundBuffer_GetStatus (mixbuf, &status); | 283 IDirectSoundBuffer_GetStatus(mixbuf, &status); |
285 if ((status & DSBSTATUS_BUFFERLOST)) { | 284 if ((status & DSBSTATUS_BUFFERLOST)) { |
286 IDirectSoundBuffer_Restore (mixbuf); | 285 IDirectSoundBuffer_Restore(mixbuf); |
287 IDirectSoundBuffer_GetStatus (mixbuf, &status); | 286 IDirectSoundBuffer_GetStatus(mixbuf, &status); |
288 if ((status & DSBSTATUS_BUFFERLOST)) { | 287 if ((status & DSBSTATUS_BUFFERLOST)) { |
289 break; | 288 break; |
290 } | 289 } |
291 } | 290 } |
292 if (!(status & DSBSTATUS_PLAYING)) { | 291 if (!(status & DSBSTATUS_PLAYING)) { |
293 result = IDirectSoundBuffer_Play (mixbuf, 0, 0, DSBPLAY_LOOPING); | 292 result = IDirectSoundBuffer_Play(mixbuf, 0, 0, DSBPLAY_LOOPING); |
294 if (result == DS_OK) { | 293 if (result == DS_OK) { |
295 continue; | 294 continue; |
296 } | 295 } |
297 #ifdef DEBUG_SOUND | 296 #ifdef DEBUG_SOUND |
298 SetDSerror ("DirectSound Play", result); | 297 SetDSerror("DirectSound Play", result); |
299 #endif | 298 #endif |
300 return; | 299 return; |
301 } | 300 } |
302 | 301 |
303 /* Find out where we are playing */ | 302 /* Find out where we are playing */ |
304 result = IDirectSoundBuffer_GetCurrentPosition (mixbuf, | 303 result = IDirectSoundBuffer_GetCurrentPosition(mixbuf, |
305 &cursor, &junk); | 304 &cursor, &junk); |
306 if (result != DS_OK) { | 305 if (result != DS_OK) { |
307 SetDSerror ("DirectSound GetCurrentPosition", result); | 306 SetDSerror("DirectSound GetCurrentPosition", result); |
308 return; | 307 return; |
309 } | 308 } |
310 cursor /= mixlen; | 309 cursor /= mixlen; |
311 } | 310 } |
312 } | 311 } |
313 | 312 |
314 #ifdef USE_POSITION_NOTIFY | 313 #ifdef USE_POSITION_NOTIFY |
315 static void | 314 static void |
316 DX6_WaitAudio_EventWait (_THIS) | 315 DX6_WaitAudio_EventWait(_THIS) |
317 { | 316 { |
318 DWORD status; | 317 DWORD status; |
319 HRESULT result; | 318 HRESULT result; |
320 | 319 |
321 /* Try to restore a lost sound buffer */ | 320 /* Try to restore a lost sound buffer */ |
322 IDirectSoundBuffer_GetStatus (mixbuf, &status); | 321 IDirectSoundBuffer_GetStatus(mixbuf, &status); |
323 if ((status & DSBSTATUS_BUFFERLOST)) { | 322 if ((status & DSBSTATUS_BUFFERLOST)) { |
324 IDirectSoundBuffer_Restore (mixbuf); | 323 IDirectSoundBuffer_Restore(mixbuf); |
325 IDirectSoundBuffer_GetStatus (mixbuf, &status); | 324 IDirectSoundBuffer_GetStatus(mixbuf, &status); |
326 if ((status & DSBSTATUS_BUFFERLOST)) { | 325 if ((status & DSBSTATUS_BUFFERLOST)) { |
327 return; | 326 return; |
328 } | 327 } |
329 } | 328 } |
330 if (!(status & DSBSTATUS_PLAYING)) { | 329 if (!(status & DSBSTATUS_PLAYING)) { |
331 result = IDirectSoundBuffer_Play (mixbuf, 0, 0, DSBPLAY_LOOPING); | 330 result = IDirectSoundBuffer_Play(mixbuf, 0, 0, DSBPLAY_LOOPING); |
332 if (result != DS_OK) { | 331 if (result != DS_OK) { |
333 #ifdef DEBUG_SOUND | 332 #ifdef DEBUG_SOUND |
334 SetDSerror ("DirectSound Play", result); | 333 SetDSerror("DirectSound Play", result); |
335 #endif | 334 #endif |
336 return; | 335 return; |
337 } | 336 } |
338 } | 337 } |
339 WaitForSingleObject (audio_event, INFINITE); | 338 WaitForSingleObject(audio_event, INFINITE); |
340 } | 339 } |
341 #endif /* USE_POSITION_NOTIFY */ | 340 #endif /* USE_POSITION_NOTIFY */ |
342 | 341 |
343 static void | 342 static void |
344 DX5_PlayAudio (_THIS) | 343 DX5_PlayAudio(_THIS) |
345 { | 344 { |
346 /* Unlock the buffer, allowing it to play */ | 345 /* Unlock the buffer, allowing it to play */ |
347 if (locked_buf) { | 346 if (locked_buf) { |
348 IDirectSoundBuffer_Unlock (mixbuf, locked_buf, mixlen, NULL, 0); | 347 IDirectSoundBuffer_Unlock(mixbuf, locked_buf, mixlen, NULL, 0); |
349 } | 348 } |
350 | 349 |
351 } | 350 } |
352 | 351 |
353 static Uint8 * | 352 static Uint8 * |
354 DX5_GetAudioBuf (_THIS) | 353 DX5_GetAudioBuf(_THIS) |
355 { | 354 { |
356 DWORD cursor, junk; | 355 DWORD cursor, junk; |
357 HRESULT result; | 356 HRESULT result; |
358 DWORD rawlen; | 357 DWORD rawlen; |
359 | 358 |
360 /* Figure out which blocks to fill next */ | 359 /* Figure out which blocks to fill next */ |
361 locked_buf = NULL; | 360 locked_buf = NULL; |
362 result = IDirectSoundBuffer_GetCurrentPosition (mixbuf, &cursor, &junk); | 361 result = IDirectSoundBuffer_GetCurrentPosition(mixbuf, &cursor, &junk); |
363 if (result == DSERR_BUFFERLOST) { | 362 if (result == DSERR_BUFFERLOST) { |
364 IDirectSoundBuffer_Restore (mixbuf); | 363 IDirectSoundBuffer_Restore(mixbuf); |
365 result = IDirectSoundBuffer_GetCurrentPosition (mixbuf, | 364 result = IDirectSoundBuffer_GetCurrentPosition(mixbuf, |
366 &cursor, &junk); | 365 &cursor, &junk); |
367 } | 366 } |
368 if (result != DS_OK) { | 367 if (result != DS_OK) { |
369 SetDSerror ("DirectSound GetCurrentPosition", result); | 368 SetDSerror("DirectSound GetCurrentPosition", result); |
370 return (NULL); | 369 return (NULL); |
371 } | 370 } |
372 cursor /= mixlen; | 371 cursor /= mixlen; |
373 playing = cursor; | 372 playing = cursor; |
374 cursor = (cursor + 1) % NUM_BUFFERS; | 373 cursor = (cursor + 1) % NUM_BUFFERS; |
375 cursor *= mixlen; | 374 cursor *= mixlen; |
376 | 375 |
377 /* Lock the audio buffer */ | 376 /* Lock the audio buffer */ |
378 result = IDirectSoundBuffer_Lock (mixbuf, cursor, mixlen, | 377 result = IDirectSoundBuffer_Lock(mixbuf, cursor, mixlen, |
379 (LPVOID *) & locked_buf, &rawlen, NULL, | 378 (LPVOID *) & locked_buf, &rawlen, NULL, |
380 &junk, 0); | 379 &junk, 0); |
381 if (result == DSERR_BUFFERLOST) { | 380 if (result == DSERR_BUFFERLOST) { |
382 IDirectSoundBuffer_Restore (mixbuf); | 381 IDirectSoundBuffer_Restore(mixbuf); |
383 result = IDirectSoundBuffer_Lock (mixbuf, cursor, mixlen, | 382 result = IDirectSoundBuffer_Lock(mixbuf, cursor, mixlen, |
384 (LPVOID *) & locked_buf, &rawlen, | 383 (LPVOID *) & locked_buf, &rawlen, |
385 NULL, &junk, 0); | 384 NULL, &junk, 0); |
386 } | 385 } |
387 if (result != DS_OK) { | 386 if (result != DS_OK) { |
388 SetDSerror ("DirectSound Lock", result); | 387 SetDSerror("DirectSound Lock", result); |
389 return (NULL); | 388 return (NULL); |
390 } | 389 } |
391 return (locked_buf); | 390 return (locked_buf); |
392 } | 391 } |
393 | 392 |
394 static void | 393 static void |
395 DX5_WaitDone (_THIS) | 394 DX5_WaitDone(_THIS) |
396 { | 395 { |
397 Uint8 *stream; | 396 Uint8 *stream; |
398 | 397 |
399 /* Wait for the playing chunk to finish */ | 398 /* Wait for the playing chunk to finish */ |
400 stream = this->GetAudioBuf (this); | 399 stream = this->GetAudioBuf(this); |
401 if (stream != NULL) { | 400 if (stream != NULL) { |
402 SDL_memset (stream, silence, mixlen); | 401 SDL_memset(stream, silence, mixlen); |
403 this->PlayAudio (this); | 402 this->PlayAudio(this); |
404 } | 403 } |
405 this->WaitAudio (this); | 404 this->WaitAudio(this); |
406 | 405 |
407 /* Stop the looping sound buffer */ | 406 /* Stop the looping sound buffer */ |
408 IDirectSoundBuffer_Stop (mixbuf); | 407 IDirectSoundBuffer_Stop(mixbuf); |
409 } | 408 } |
410 | 409 |
411 static void | 410 static void |
412 DX5_CloseAudio (_THIS) | 411 DX5_CloseAudio(_THIS) |
413 { | 412 { |
414 if (sound != NULL) { | 413 if (sound != NULL) { |
415 if (mixbuf != NULL) { | 414 if (mixbuf != NULL) { |
416 /* Clean up the audio buffer */ | 415 /* Clean up the audio buffer */ |
417 IDirectSoundBuffer_Release (mixbuf); | 416 IDirectSoundBuffer_Release(mixbuf); |
418 mixbuf = NULL; | 417 mixbuf = NULL; |
419 } | 418 } |
420 if (audio_event != NULL) { | 419 if (audio_event != NULL) { |
421 CloseHandle (audio_event); | 420 CloseHandle(audio_event); |
422 audio_event = NULL; | 421 audio_event = NULL; |
423 } | 422 } |
424 IDirectSound_Release (sound); | 423 IDirectSound_Release(sound); |
425 sound = NULL; | 424 sound = NULL; |
426 } | 425 } |
427 } | 426 } |
428 | 427 |
429 #ifdef USE_PRIMARY_BUFFER | 428 #ifdef USE_PRIMARY_BUFFER |
430 /* This function tries to create a primary audio buffer, and returns the | 429 /* This function tries to create a primary audio buffer, and returns the |
431 number of audio chunks available in the created buffer. | 430 number of audio chunks available in the created buffer. |
432 */ | 431 */ |
433 static int | 432 static int |
434 CreatePrimary (LPDIRECTSOUND sndObj, HWND focus, | 433 CreatePrimary(LPDIRECTSOUND sndObj, HWND focus, |
435 LPDIRECTSOUNDBUFFER * sndbuf, WAVEFORMATEX * wavefmt, | 434 LPDIRECTSOUNDBUFFER * sndbuf, WAVEFORMATEX * wavefmt, |
436 Uint32 chunksize) | 435 Uint32 chunksize) |
437 { | 436 { |
438 HRESULT result; | 437 HRESULT result; |
439 DSBUFFERDESC format; | 438 DSBUFFERDESC format; |
440 DSBCAPS caps; | 439 DSBCAPS caps; |
441 int numchunks; | 440 int numchunks; |
442 | 441 |
443 /* Try to set primary mixing privileges */ | 442 /* Try to set primary mixing privileges */ |
444 result = IDirectSound_SetCooperativeLevel (sndObj, focus, | 443 result = IDirectSound_SetCooperativeLevel(sndObj, focus, |
445 DSSCL_WRITEPRIMARY); | 444 DSSCL_WRITEPRIMARY); |
446 if (result != DS_OK) { | 445 if (result != DS_OK) { |
447 #ifdef DEBUG_SOUND | 446 #ifdef DEBUG_SOUND |
448 SetDSerror ("DirectSound SetCooperativeLevel", result); | 447 SetDSerror("DirectSound SetCooperativeLevel", result); |
449 #endif | 448 #endif |
450 return (-1); | 449 return (-1); |
451 } | 450 } |
452 | 451 |
453 /* Try to create the primary buffer */ | 452 /* Try to create the primary buffer */ |
454 SDL_memset (&format, 0, sizeof (format)); | 453 SDL_memset(&format, 0, sizeof(format)); |
455 format.dwSize = sizeof (format); | 454 format.dwSize = sizeof(format); |
456 format.dwFlags = (DSBCAPS_PRIMARYBUFFER | DSBCAPS_GETCURRENTPOSITION2); | 455 format.dwFlags = (DSBCAPS_PRIMARYBUFFER | DSBCAPS_GETCURRENTPOSITION2); |
457 format.dwFlags |= DSBCAPS_STICKYFOCUS; | 456 format.dwFlags |= DSBCAPS_STICKYFOCUS; |
458 #ifdef USE_POSITION_NOTIFY | 457 #ifdef USE_POSITION_NOTIFY |
459 format.dwFlags |= DSBCAPS_CTRLPOSITIONNOTIFY; | 458 format.dwFlags |= DSBCAPS_CTRLPOSITIONNOTIFY; |
460 #endif | 459 #endif |
461 result = IDirectSound_CreateSoundBuffer (sndObj, &format, sndbuf, NULL); | 460 result = IDirectSound_CreateSoundBuffer(sndObj, &format, sndbuf, NULL); |
462 if (result != DS_OK) { | 461 if (result != DS_OK) { |
463 #ifdef DEBUG_SOUND | 462 #ifdef DEBUG_SOUND |
464 SetDSerror ("DirectSound CreateSoundBuffer", result); | 463 SetDSerror("DirectSound CreateSoundBuffer", result); |
465 #endif | 464 #endif |
466 return (-1); | 465 return (-1); |
467 } | 466 } |
468 | 467 |
469 /* Check the size of the fragment buffer */ | 468 /* Check the size of the fragment buffer */ |
470 SDL_memset (&caps, 0, sizeof (caps)); | 469 SDL_memset(&caps, 0, sizeof(caps)); |
471 caps.dwSize = sizeof (caps); | 470 caps.dwSize = sizeof(caps); |
472 result = IDirectSoundBuffer_GetCaps (*sndbuf, &caps); | 471 result = IDirectSoundBuffer_GetCaps(*sndbuf, &caps); |
473 if (result != DS_OK) { | 472 if (result != DS_OK) { |
474 #ifdef DEBUG_SOUND | 473 #ifdef DEBUG_SOUND |
475 SetDSerror ("DirectSound GetCaps", result); | 474 SetDSerror("DirectSound GetCaps", result); |
476 #endif | 475 #endif |
477 IDirectSoundBuffer_Release (*sndbuf); | 476 IDirectSoundBuffer_Release(*sndbuf); |
478 return (-1); | 477 return (-1); |
479 } | 478 } |
480 if ((chunksize > caps.dwBufferBytes) || | 479 if ((chunksize > caps.dwBufferBytes) || |
481 ((caps.dwBufferBytes % chunksize) != 0)) { | 480 ((caps.dwBufferBytes % chunksize) != 0)) { |
482 /* The primary buffer size is not a multiple of 'chunksize' | 481 /* The primary buffer size is not a multiple of 'chunksize' |
483 -- this hopefully doesn't happen when 'chunksize' is a | 482 -- this hopefully doesn't happen when 'chunksize' is a |
484 power of 2. | 483 power of 2. |
485 */ | 484 */ |
486 IDirectSoundBuffer_Release (*sndbuf); | 485 IDirectSoundBuffer_Release(*sndbuf); |
487 SDL_SetError | 486 SDL_SetError |
488 ("Primary buffer size is: %d, cannot break it into chunks of %d bytes\n", | 487 ("Primary buffer size is: %d, cannot break it into chunks of %d bytes\n", |
489 caps.dwBufferBytes, chunksize); | 488 caps.dwBufferBytes, chunksize); |
490 return (-1); | 489 return (-1); |
491 } | 490 } |
492 numchunks = (caps.dwBufferBytes / chunksize); | 491 numchunks = (caps.dwBufferBytes / chunksize); |
493 | 492 |
494 /* Set the primary audio format */ | 493 /* Set the primary audio format */ |
495 result = IDirectSoundBuffer_SetFormat (*sndbuf, wavefmt); | 494 result = IDirectSoundBuffer_SetFormat(*sndbuf, wavefmt); |
496 if (result != DS_OK) { | 495 if (result != DS_OK) { |
497 #ifdef DEBUG_SOUND | 496 #ifdef DEBUG_SOUND |
498 SetDSerror ("DirectSound SetFormat", result); | 497 SetDSerror("DirectSound SetFormat", result); |
499 #endif | 498 #endif |
500 IDirectSoundBuffer_Release (*sndbuf); | 499 IDirectSoundBuffer_Release(*sndbuf); |
501 return (-1); | 500 return (-1); |
502 } | 501 } |
503 return (numchunks); | 502 return (numchunks); |
504 } | 503 } |
505 #endif /* USE_PRIMARY_BUFFER */ | 504 #endif /* USE_PRIMARY_BUFFER */ |
506 | 505 |
507 /* This function tries to create a secondary audio buffer, and returns the | 506 /* This function tries to create a secondary audio buffer, and returns the |
508 number of audio chunks available in the created buffer. | 507 number of audio chunks available in the created buffer. |
509 */ | 508 */ |
510 static int | 509 static int |
511 CreateSecondary (LPDIRECTSOUND sndObj, HWND focus, | 510 CreateSecondary(LPDIRECTSOUND sndObj, HWND focus, |
512 LPDIRECTSOUNDBUFFER * sndbuf, WAVEFORMATEX * wavefmt, | 511 LPDIRECTSOUNDBUFFER * sndbuf, WAVEFORMATEX * wavefmt, |
513 Uint32 chunksize) | 512 Uint32 chunksize) |
514 { | 513 { |
515 const int numchunks = 2; | 514 const int numchunks = 2; |
516 HRESULT result; | 515 HRESULT result; |
517 DSBUFFERDESC format; | 516 DSBUFFERDESC format; |
518 LPVOID pvAudioPtr1, pvAudioPtr2; | 517 LPVOID pvAudioPtr1, pvAudioPtr2; |
519 DWORD dwAudioBytes1, dwAudioBytes2; | 518 DWORD dwAudioBytes1, dwAudioBytes2; |
520 | 519 |
521 /* Try to set primary mixing privileges */ | 520 /* Try to set primary mixing privileges */ |
522 if (focus) { | 521 if (focus) { |
523 result = IDirectSound_SetCooperativeLevel (sndObj, | 522 result = IDirectSound_SetCooperativeLevel(sndObj, |
524 focus, DSSCL_PRIORITY); | 523 focus, DSSCL_PRIORITY); |
525 } else { | 524 } else { |
526 result = IDirectSound_SetCooperativeLevel (sndObj, | 525 result = IDirectSound_SetCooperativeLevel(sndObj, |
527 GetDesktopWindow (), | 526 GetDesktopWindow(), |
528 DSSCL_NORMAL); | 527 DSSCL_NORMAL); |
529 } | 528 } |
530 if (result != DS_OK) { | 529 if (result != DS_OK) { |
531 #ifdef DEBUG_SOUND | 530 #ifdef DEBUG_SOUND |
532 SetDSerror ("DirectSound SetCooperativeLevel", result); | 531 SetDSerror("DirectSound SetCooperativeLevel", result); |
533 #endif | 532 #endif |
534 return (-1); | 533 return (-1); |
535 } | 534 } |
536 | 535 |
537 /* Try to create the secondary buffer */ | 536 /* Try to create the secondary buffer */ |
538 SDL_memset (&format, 0, sizeof (format)); | 537 SDL_memset(&format, 0, sizeof(format)); |
539 format.dwSize = sizeof (format); | 538 format.dwSize = sizeof(format); |
540 format.dwFlags = DSBCAPS_GETCURRENTPOSITION2; | 539 format.dwFlags = DSBCAPS_GETCURRENTPOSITION2; |
541 #ifdef USE_POSITION_NOTIFY | 540 #ifdef USE_POSITION_NOTIFY |
542 format.dwFlags |= DSBCAPS_CTRLPOSITIONNOTIFY; | 541 format.dwFlags |= DSBCAPS_CTRLPOSITIONNOTIFY; |
543 #endif | 542 #endif |
544 if (!focus) { | 543 if (!focus) { |
547 format.dwFlags |= DSBCAPS_STICKYFOCUS; | 546 format.dwFlags |= DSBCAPS_STICKYFOCUS; |
548 } | 547 } |
549 format.dwBufferBytes = numchunks * chunksize; | 548 format.dwBufferBytes = numchunks * chunksize; |
550 if ((format.dwBufferBytes < DSBSIZE_MIN) || | 549 if ((format.dwBufferBytes < DSBSIZE_MIN) || |
551 (format.dwBufferBytes > DSBSIZE_MAX)) { | 550 (format.dwBufferBytes > DSBSIZE_MAX)) { |
552 SDL_SetError ("Sound buffer size must be between %d and %d", | 551 SDL_SetError("Sound buffer size must be between %d and %d", |
553 DSBSIZE_MIN / numchunks, DSBSIZE_MAX / numchunks); | 552 DSBSIZE_MIN / numchunks, DSBSIZE_MAX / numchunks); |
554 return (-1); | 553 return (-1); |
555 } | 554 } |
556 format.dwReserved = 0; | 555 format.dwReserved = 0; |
557 format.lpwfxFormat = wavefmt; | 556 format.lpwfxFormat = wavefmt; |
558 result = IDirectSound_CreateSoundBuffer (sndObj, &format, sndbuf, NULL); | 557 result = IDirectSound_CreateSoundBuffer(sndObj, &format, sndbuf, NULL); |
559 if (result != DS_OK) { | 558 if (result != DS_OK) { |
560 SetDSerror ("DirectSound CreateSoundBuffer", result); | 559 SetDSerror("DirectSound CreateSoundBuffer", result); |
561 return (-1); | 560 return (-1); |
562 } | 561 } |
563 IDirectSoundBuffer_SetFormat (*sndbuf, wavefmt); | 562 IDirectSoundBuffer_SetFormat(*sndbuf, wavefmt); |
564 | 563 |
565 /* Silence the initial audio buffer */ | 564 /* Silence the initial audio buffer */ |
566 result = IDirectSoundBuffer_Lock (*sndbuf, 0, format.dwBufferBytes, | 565 result = IDirectSoundBuffer_Lock(*sndbuf, 0, format.dwBufferBytes, |
567 (LPVOID *) & pvAudioPtr1, | 566 (LPVOID *) & pvAudioPtr1, |
568 &dwAudioBytes1, | 567 &dwAudioBytes1, |
569 (LPVOID *) & pvAudioPtr2, | 568 (LPVOID *) & pvAudioPtr2, |
570 &dwAudioBytes2, DSBLOCK_ENTIREBUFFER); | 569 &dwAudioBytes2, DSBLOCK_ENTIREBUFFER); |
571 if (result == DS_OK) { | 570 if (result == DS_OK) { |
572 if (wavefmt->wBitsPerSample == 8) { | 571 if (wavefmt->wBitsPerSample == 8) { |
573 SDL_memset (pvAudioPtr1, 0x80, dwAudioBytes1); | 572 SDL_memset(pvAudioPtr1, 0x80, dwAudioBytes1); |
574 } else { | 573 } else { |
575 SDL_memset (pvAudioPtr1, 0x00, dwAudioBytes1); | 574 SDL_memset(pvAudioPtr1, 0x00, dwAudioBytes1); |
576 } | 575 } |
577 IDirectSoundBuffer_Unlock (*sndbuf, | 576 IDirectSoundBuffer_Unlock(*sndbuf, |
578 (LPVOID) pvAudioPtr1, dwAudioBytes1, | 577 (LPVOID) pvAudioPtr1, dwAudioBytes1, |
579 (LPVOID) pvAudioPtr2, dwAudioBytes2); | 578 (LPVOID) pvAudioPtr2, dwAudioBytes2); |
580 } | 579 } |
581 | 580 |
582 /* We're ready to go */ | 581 /* We're ready to go */ |
583 return (numchunks); | 582 return (numchunks); |
584 } | 583 } |
585 | 584 |
586 /* This function tries to set position notify events on the mixing buffer */ | 585 /* This function tries to set position notify events on the mixing buffer */ |
587 #ifdef USE_POSITION_NOTIFY | 586 #ifdef USE_POSITION_NOTIFY |
588 static int | 587 static int |
589 CreateAudioEvent (_THIS) | 588 CreateAudioEvent(_THIS) |
590 { | 589 { |
591 LPDIRECTSOUNDNOTIFY notify; | 590 LPDIRECTSOUNDNOTIFY notify; |
592 DSBPOSITIONNOTIFY *notify_positions; | 591 DSBPOSITIONNOTIFY *notify_positions; |
593 int i, retval; | 592 int i, retval; |
594 HRESULT result; | 593 HRESULT result; |
596 /* Default to fail on exit */ | 595 /* Default to fail on exit */ |
597 retval = -1; | 596 retval = -1; |
598 notify = NULL; | 597 notify = NULL; |
599 | 598 |
600 /* Query for the interface */ | 599 /* Query for the interface */ |
601 result = IDirectSoundBuffer_QueryInterface (mixbuf, | 600 result = IDirectSoundBuffer_QueryInterface(mixbuf, |
602 &IID_IDirectSoundNotify, | 601 &IID_IDirectSoundNotify, |
603 (void *) ¬ify); | 602 (void *) ¬ify); |
604 if (result != DS_OK) { | 603 if (result != DS_OK) { |
605 goto done; | 604 goto done; |
606 } | 605 } |
607 | 606 |
608 /* Allocate the notify structures */ | 607 /* Allocate the notify structures */ |
609 notify_positions = (DSBPOSITIONNOTIFY *) SDL_malloc (NUM_BUFFERS * | 608 notify_positions = (DSBPOSITIONNOTIFY *) SDL_malloc(NUM_BUFFERS * |
610 sizeof | 609 sizeof |
611 (*notify_positions)); | 610 (*notify_positions)); |
612 if (notify_positions == NULL) { | 611 if (notify_positions == NULL) { |
613 goto done; | 612 goto done; |
614 } | 613 } |
615 | 614 |
616 /* Create the notify event */ | 615 /* Create the notify event */ |
617 audio_event = CreateEvent (NULL, FALSE, FALSE, NULL); | 616 audio_event = CreateEvent(NULL, FALSE, FALSE, NULL); |
618 if (audio_event == NULL) { | 617 if (audio_event == NULL) { |
619 goto done; | 618 goto done; |
620 } | 619 } |
621 | 620 |
622 /* Set up the notify structures */ | 621 /* Set up the notify structures */ |
623 for (i = 0; i < NUM_BUFFERS; ++i) { | 622 for (i = 0; i < NUM_BUFFERS; ++i) { |
624 notify_positions[i].dwOffset = i * mixlen; | 623 notify_positions[i].dwOffset = i * mixlen; |
625 notify_positions[i].hEventNotify = audio_event; | 624 notify_positions[i].hEventNotify = audio_event; |
626 } | 625 } |
627 result = IDirectSoundNotify_SetNotificationPositions (notify, | 626 result = IDirectSoundNotify_SetNotificationPositions(notify, |
628 NUM_BUFFERS, | 627 NUM_BUFFERS, |
629 notify_positions); | 628 notify_positions); |
630 if (result == DS_OK) { | 629 if (result == DS_OK) { |
631 retval = 0; | 630 retval = 0; |
632 } | 631 } |
633 done: | 632 done: |
634 if (notify != NULL) { | 633 if (notify != NULL) { |
635 IDirectSoundNotify_Release (notify); | 634 IDirectSoundNotify_Release(notify); |
636 } | 635 } |
637 return (retval); | 636 return (retval); |
638 } | 637 } |
639 #endif /* USE_POSITION_NOTIFY */ | 638 #endif /* USE_POSITION_NOTIFY */ |
640 | 639 |
641 static int | 640 static int |
642 DX5_OpenAudio (_THIS, SDL_AudioSpec * spec) | 641 DX5_OpenAudio(_THIS, SDL_AudioSpec * spec) |
643 { | 642 { |
644 HRESULT result; | 643 HRESULT result; |
645 WAVEFORMATEX waveformat; | 644 WAVEFORMATEX waveformat; |
646 | 645 |
647 /* Set basic WAVE format parameters */ | 646 /* Set basic WAVE format parameters */ |
648 SDL_memset (&waveformat, 0, sizeof (waveformat)); | 647 SDL_memset(&waveformat, 0, sizeof(waveformat)); |
649 waveformat.wFormatTag = WAVE_FORMAT_PCM; | 648 waveformat.wFormatTag = WAVE_FORMAT_PCM; |
650 | 649 |
651 /* Determine the audio parameters from the AudioSpec */ | 650 /* Determine the audio parameters from the AudioSpec */ |
652 switch (spec->format & 0xFF) { | 651 switch (spec->format & 0xFF) { |
653 case 8: | 652 case 8: |
661 spec->format = AUDIO_S16; | 660 spec->format = AUDIO_S16; |
662 silence = 0x00; | 661 silence = 0x00; |
663 waveformat.wBitsPerSample = 16; | 662 waveformat.wBitsPerSample = 16; |
664 break; | 663 break; |
665 default: | 664 default: |
666 SDL_SetError ("Unsupported audio format"); | 665 SDL_SetError("Unsupported audio format"); |
667 return (-1); | 666 return (-1); |
668 } | 667 } |
669 waveformat.nChannels = spec->channels; | 668 waveformat.nChannels = spec->channels; |
670 waveformat.nSamplesPerSec = spec->freq; | 669 waveformat.nSamplesPerSec = spec->freq; |
671 waveformat.nBlockAlign = | 670 waveformat.nBlockAlign = |
672 waveformat.nChannels * (waveformat.wBitsPerSample / 8); | 671 waveformat.nChannels * (waveformat.wBitsPerSample / 8); |
673 waveformat.nAvgBytesPerSec = | 672 waveformat.nAvgBytesPerSec = |
674 waveformat.nSamplesPerSec * waveformat.nBlockAlign; | 673 waveformat.nSamplesPerSec * waveformat.nBlockAlign; |
675 | 674 |
676 /* Update the fragment size as size in bytes */ | 675 /* Update the fragment size as size in bytes */ |
677 SDL_CalculateAudioSpec (spec); | 676 SDL_CalculateAudioSpec(spec); |
678 | 677 |
679 /* Open the audio device */ | 678 /* Open the audio device */ |
680 result = DSoundCreate (NULL, &sound, NULL); | 679 result = DSoundCreate(NULL, &sound, NULL); |
681 if (result != DS_OK) { | 680 if (result != DS_OK) { |
682 SetDSerror ("DirectSoundCreate", result); | 681 SetDSerror("DirectSoundCreate", result); |
683 return (-1); | 682 return (-1); |
684 } | 683 } |
685 | 684 |
686 /* Create the audio buffer to which we write */ | 685 /* Create the audio buffer to which we write */ |
687 NUM_BUFFERS = -1; | 686 NUM_BUFFERS = -1; |
688 #ifdef USE_PRIMARY_BUFFER | 687 #ifdef USE_PRIMARY_BUFFER |
689 if (mainwin) { | 688 if (mainwin) { |
690 NUM_BUFFERS = CreatePrimary (sound, mainwin, &mixbuf, | 689 NUM_BUFFERS = CreatePrimary(sound, mainwin, &mixbuf, |
691 &waveformat, spec->size); | 690 &waveformat, spec->size); |
692 } | 691 } |
693 #endif /* USE_PRIMARY_BUFFER */ | 692 #endif /* USE_PRIMARY_BUFFER */ |
694 if (NUM_BUFFERS < 0) { | 693 if (NUM_BUFFERS < 0) { |
695 NUM_BUFFERS = CreateSecondary (sound, mainwin, &mixbuf, | 694 NUM_BUFFERS = CreateSecondary(sound, mainwin, &mixbuf, |
696 &waveformat, spec->size); | 695 &waveformat, spec->size); |
697 if (NUM_BUFFERS < 0) { | 696 if (NUM_BUFFERS < 0) { |
698 return (-1); | 697 return (-1); |
699 } | 698 } |
700 #ifdef DEBUG_SOUND | 699 #ifdef DEBUG_SOUND |
701 fprintf (stderr, "Using secondary audio buffer\n"); | 700 fprintf(stderr, "Using secondary audio buffer\n"); |
702 #endif | 701 #endif |
703 } | 702 } |
704 #ifdef DEBUG_SOUND | 703 #ifdef DEBUG_SOUND |
705 else | 704 else |
706 fprintf (stderr, "Using primary audio buffer\n"); | 705 fprintf(stderr, "Using primary audio buffer\n"); |
707 #endif | 706 #endif |
708 | 707 |
709 /* The buffer will auto-start playing in DX5_WaitAudio() */ | 708 /* The buffer will auto-start playing in DX5_WaitAudio() */ |
710 playing = 0; | 709 playing = 0; |
711 mixlen = spec->size; | 710 mixlen = spec->size; |
712 | 711 |
713 #ifdef USE_POSITION_NOTIFY | 712 #ifdef USE_POSITION_NOTIFY |
714 /* See if we can use DirectX 6 event notification */ | 713 /* See if we can use DirectX 6 event notification */ |
715 if (CreateAudioEvent (this) == 0) { | 714 if (CreateAudioEvent(this) == 0) { |
716 this->WaitAudio = DX6_WaitAudio_EventWait; | 715 this->WaitAudio = DX6_WaitAudio_EventWait; |
717 } else { | 716 } else { |
718 this->WaitAudio = DX5_WaitAudio_BusyWait; | 717 this->WaitAudio = DX5_WaitAudio_BusyWait; |
719 } | 718 } |
720 #endif | 719 #endif |