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 *) &notify); 602 (void *) &notify);
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