comparison src/audio/windx5/SDL_dx5audio.c @ 1877:9b02a5b97f79

Fixed bug #69 Hopefully this takes care of most of the audio dropouts in Windows
author Sam Lantinga <slouken@libsdl.org>
date Fri, 23 Jun 2006 08:15:47 +0000
parents d910939febfa
children c121d94672cb a1b03ba2fcd0
comparison
equal deleted inserted replaced
1876:406b8325ee34 1877:9b02a5b97f79
252 HRESULT result; 252 HRESULT result;
253 253
254 /* Semi-busy wait, since we have no way of getting play notification 254 /* Semi-busy wait, since we have no way of getting play notification
255 on a primary mixing buffer located in hardware (DirectX 5.0) 255 on a primary mixing buffer located in hardware (DirectX 5.0)
256 */ 256 */
257 result = IDirectSoundBuffer_GetCurrentPosition(mixbuf, &cursor, &junk); 257 result = IDirectSoundBuffer_GetCurrentPosition(mixbuf, &junk, &cursor);
258 if ( result != DS_OK ) { 258 if ( result != DS_OK ) {
259 if ( result == DSERR_BUFFERLOST ) { 259 if ( result == DSERR_BUFFERLOST ) {
260 IDirectSoundBuffer_Restore(mixbuf); 260 IDirectSoundBuffer_Restore(mixbuf);
261 } 261 }
262 #ifdef DEBUG_SOUND 262 #ifdef DEBUG_SOUND
263 SetDSerror("DirectSound GetCurrentPosition", result); 263 SetDSerror("DirectSound GetCurrentPosition", result);
264 #endif 264 #endif
265 return; 265 return;
266 } 266 }
267 cursor /= mixlen; 267
268 268 while ( (cursor/mixlen) == lastchunk ) {
269 while ( cursor == playing ) {
270 /* FIXME: find out how much time is left and sleep that long */ 269 /* FIXME: find out how much time is left and sleep that long */
271 SDL_Delay(10); 270 SDL_Delay(1);
272 271
273 /* Try to restore a lost sound buffer */ 272 /* Try to restore a lost sound buffer */
274 IDirectSoundBuffer_GetStatus(mixbuf, &status); 273 IDirectSoundBuffer_GetStatus(mixbuf, &status);
275 if ( (status&DSBSTATUS_BUFFERLOST) ) { 274 if ( (status&DSBSTATUS_BUFFERLOST) ) {
276 IDirectSoundBuffer_Restore(mixbuf); 275 IDirectSoundBuffer_Restore(mixbuf);
290 return; 289 return;
291 } 290 }
292 291
293 /* Find out where we are playing */ 292 /* Find out where we are playing */
294 result = IDirectSoundBuffer_GetCurrentPosition(mixbuf, 293 result = IDirectSoundBuffer_GetCurrentPosition(mixbuf,
295 &cursor, &junk); 294 &junk, &cursor);
296 if ( result != DS_OK ) { 295 if ( result != DS_OK ) {
297 SetDSerror("DirectSound GetCurrentPosition", result); 296 SetDSerror("DirectSound GetCurrentPosition", result);
298 return; 297 return;
299 } 298 }
300 cursor /= mixlen;
301 } 299 }
302 } 300 }
303 301
304 #ifdef USE_POSITION_NOTIFY 302 #ifdef USE_POSITION_NOTIFY
305 static void DX6_WaitAudio_EventWait(_THIS) 303 static void DX6_WaitAudio_EventWait(_THIS)
344 HRESULT result; 342 HRESULT result;
345 DWORD rawlen; 343 DWORD rawlen;
346 344
347 /* Figure out which blocks to fill next */ 345 /* Figure out which blocks to fill next */
348 locked_buf = NULL; 346 locked_buf = NULL;
349 result = IDirectSoundBuffer_GetCurrentPosition(mixbuf, &cursor, &junk); 347 result = IDirectSoundBuffer_GetCurrentPosition(mixbuf, &junk, &cursor);
350 if ( result == DSERR_BUFFERLOST ) { 348 if ( result == DSERR_BUFFERLOST ) {
351 IDirectSoundBuffer_Restore(mixbuf); 349 IDirectSoundBuffer_Restore(mixbuf);
352 result = IDirectSoundBuffer_GetCurrentPosition(mixbuf, 350 result = IDirectSoundBuffer_GetCurrentPosition(mixbuf,
353 &cursor, &junk); 351 &junk, &cursor);
354 } 352 }
355 if ( result != DS_OK ) { 353 if ( result != DS_OK ) {
356 SetDSerror("DirectSound GetCurrentPosition", result); 354 SetDSerror("DirectSound GetCurrentPosition", result);
357 return(NULL); 355 return(NULL);
358 } 356 }
359 cursor /= mixlen; 357 cursor /= mixlen;
360 playing = cursor; 358 #ifdef DEBUG_SOUND
359 /* Detect audio dropouts */
360 { DWORD spot = cursor;
361 if ( spot < lastchunk ) {
362 spot += NUM_BUFFERS;
363 }
364 if ( spot > lastchunk+1 ) {
365 fprintf(stderr, "Audio dropout, missed %d fragments\n",
366 (spot - (lastchunk+1)));
367 }
368 }
369 #endif
370 lastchunk = cursor;
361 cursor = (cursor+1)%NUM_BUFFERS; 371 cursor = (cursor+1)%NUM_BUFFERS;
362 cursor *= mixlen; 372 cursor *= mixlen;
363 373
364 /* Lock the audio buffer */ 374 /* Lock the audio buffer */
365 result = IDirectSoundBuffer_Lock(mixbuf, cursor, mixlen, 375 result = IDirectSoundBuffer_Lock(mixbuf, cursor, mixlen,
489 number of audio chunks available in the created buffer. 499 number of audio chunks available in the created buffer.
490 */ 500 */
491 static int CreateSecondary(LPDIRECTSOUND sndObj, HWND focus, 501 static int CreateSecondary(LPDIRECTSOUND sndObj, HWND focus,
492 LPDIRECTSOUNDBUFFER *sndbuf, WAVEFORMATEX *wavefmt, Uint32 chunksize) 502 LPDIRECTSOUNDBUFFER *sndbuf, WAVEFORMATEX *wavefmt, Uint32 chunksize)
493 { 503 {
494 const int numchunks = 2; 504 const int numchunks = 8;
495 HRESULT result; 505 HRESULT result;
496 DSBUFFERDESC format; 506 DSBUFFERDESC format;
497 LPVOID pvAudioPtr1, pvAudioPtr2; 507 LPVOID pvAudioPtr1, pvAudioPtr2;
498 DWORD dwAudioBytes1, dwAudioBytes2; 508 DWORD dwAudioBytes1, dwAudioBytes2;
499 509
677 else 687 else
678 fprintf(stderr, "Using primary audio buffer\n"); 688 fprintf(stderr, "Using primary audio buffer\n");
679 #endif 689 #endif
680 690
681 /* The buffer will auto-start playing in DX5_WaitAudio() */ 691 /* The buffer will auto-start playing in DX5_WaitAudio() */
682 playing = 0; 692 lastchunk = 0;
683 mixlen = spec->size; 693 mixlen = spec->size;
684 694
685 #ifdef USE_POSITION_NOTIFY 695 #ifdef USE_POSITION_NOTIFY
686 /* See if we can use DirectX 6 event notification */ 696 /* See if we can use DirectX 6 event notification */
687 if ( CreateAudioEvent(this) == 0 ) { 697 if ( CreateAudioEvent(this) == 0 ) {