comparison src/audio/windx5/SDL_dx5audio.c @ 1701:442248d4e738 SDL-1.3

Merged DirectSound dropout fix from SDL 1.2
author Sam Lantinga <slouken@libsdl.org>
date Fri, 23 Jun 2006 08:48:24 +0000
parents 4da1ee79c9af
children
comparison
equal deleted inserted replaced
1700:21184e1d04c3 1701:442248d4e738
261 HRESULT result; 261 HRESULT result;
262 262
263 /* 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
264 on a primary mixing buffer located in hardware (DirectX 5.0) 264 on a primary mixing buffer located in hardware (DirectX 5.0)
265 */ 265 */
266 result = IDirectSoundBuffer_GetCurrentPosition(mixbuf, &cursor, &junk); 266 result = IDirectSoundBuffer_GetCurrentPosition(mixbuf, &junk, &cursor);
267 if (result != DS_OK) { 267 if (result != DS_OK) {
268 if (result == DSERR_BUFFERLOST) { 268 if (result == DSERR_BUFFERLOST) {
269 IDirectSoundBuffer_Restore(mixbuf); 269 IDirectSoundBuffer_Restore(mixbuf);
270 } 270 }
271 #ifdef DEBUG_SOUND 271 #ifdef DEBUG_SOUND
272 SetDSerror("DirectSound GetCurrentPosition", result); 272 SetDSerror("DirectSound GetCurrentPosition", result);
273 #endif 273 #endif
274 return; 274 return;
275 } 275 }
276 cursor /= mixlen; 276
277 277 while ((cursor / mixlen) == lastchunk) {
278 while (cursor == playing) {
279 /* FIXME: find out how much time is left and sleep that long */ 278 /* FIXME: find out how much time is left and sleep that long */
280 SDL_Delay(10); 279 SDL_Delay(1);
281 280
282 /* Try to restore a lost sound buffer */ 281 /* Try to restore a lost sound buffer */
283 IDirectSoundBuffer_GetStatus(mixbuf, &status); 282 IDirectSoundBuffer_GetStatus(mixbuf, &status);
284 if ((status & DSBSTATUS_BUFFERLOST)) { 283 if ((status & DSBSTATUS_BUFFERLOST)) {
285 IDirectSoundBuffer_Restore(mixbuf); 284 IDirectSoundBuffer_Restore(mixbuf);
299 return; 298 return;
300 } 299 }
301 300
302 /* Find out where we are playing */ 301 /* Find out where we are playing */
303 result = IDirectSoundBuffer_GetCurrentPosition(mixbuf, 302 result = IDirectSoundBuffer_GetCurrentPosition(mixbuf,
304 &cursor, &junk); 303 &junk, &cursor);
305 if (result != DS_OK) { 304 if (result != DS_OK) {
306 SetDSerror("DirectSound GetCurrentPosition", result); 305 SetDSerror("DirectSound GetCurrentPosition", result);
307 return; 306 return;
308 } 307 }
309 cursor /= mixlen;
310 } 308 }
311 } 309 }
312 310
313 #ifdef USE_POSITION_NOTIFY 311 #ifdef USE_POSITION_NOTIFY
314 static void 312 static void
356 HRESULT result; 354 HRESULT result;
357 DWORD rawlen; 355 DWORD rawlen;
358 356
359 /* Figure out which blocks to fill next */ 357 /* Figure out which blocks to fill next */
360 locked_buf = NULL; 358 locked_buf = NULL;
361 result = IDirectSoundBuffer_GetCurrentPosition(mixbuf, &cursor, &junk); 359 result = IDirectSoundBuffer_GetCurrentPosition(mixbuf, &junk, &cursor);
362 if (result == DSERR_BUFFERLOST) { 360 if (result == DSERR_BUFFERLOST) {
363 IDirectSoundBuffer_Restore(mixbuf); 361 IDirectSoundBuffer_Restore(mixbuf);
364 result = IDirectSoundBuffer_GetCurrentPosition(mixbuf, 362 result = IDirectSoundBuffer_GetCurrentPosition(mixbuf,
365 &cursor, &junk); 363 &junk, &cursor);
366 } 364 }
367 if (result != DS_OK) { 365 if (result != DS_OK) {
368 SetDSerror("DirectSound GetCurrentPosition", result); 366 SetDSerror("DirectSound GetCurrentPosition", result);
369 return (NULL); 367 return (NULL);
370 } 368 }
371 cursor /= mixlen; 369 cursor /= mixlen;
372 playing = cursor; 370 #ifdef DEBUG_SOUND
371 /* Detect audio dropouts */
372 {
373 DWORD spot = cursor;
374 if (spot < lastchunk) {
375 spot += NUM_BUFFERS;
376 }
377 if (spot > lastchunk + 1) {
378 fprintf(stderr, "Audio dropout, missed %d fragments\n",
379 (spot - (lastchunk + 1)));
380 }
381 }
382 #endif
383 lastchunk = cursor;
373 cursor = (cursor + 1) % NUM_BUFFERS; 384 cursor = (cursor + 1) % NUM_BUFFERS;
374 cursor *= mixlen; 385 cursor *= mixlen;
375 386
376 /* Lock the audio buffer */ 387 /* Lock the audio buffer */
377 result = IDirectSoundBuffer_Lock(mixbuf, cursor, mixlen, 388 result = IDirectSoundBuffer_Lock(mixbuf, cursor, mixlen,
509 static int 520 static int
510 CreateSecondary(LPDIRECTSOUND sndObj, HWND focus, 521 CreateSecondary(LPDIRECTSOUND sndObj, HWND focus,
511 LPDIRECTSOUNDBUFFER * sndbuf, WAVEFORMATEX * wavefmt, 522 LPDIRECTSOUNDBUFFER * sndbuf, WAVEFORMATEX * wavefmt,
512 Uint32 chunksize) 523 Uint32 chunksize)
513 { 524 {
514 const int numchunks = 2; 525 const int numchunks = 8;
515 HRESULT result; 526 HRESULT result;
516 DSBUFFERDESC format; 527 DSBUFFERDESC format;
517 LPVOID pvAudioPtr1, pvAudioPtr2; 528 LPVOID pvAudioPtr1, pvAudioPtr2;
518 DWORD dwAudioBytes1, dwAudioBytes2; 529 DWORD dwAudioBytes1, dwAudioBytes2;
519 530
561 } 572 }
562 IDirectSoundBuffer_SetFormat(*sndbuf, wavefmt); 573 IDirectSoundBuffer_SetFormat(*sndbuf, wavefmt);
563 574
564 /* Silence the initial audio buffer */ 575 /* Silence the initial audio buffer */
565 result = IDirectSoundBuffer_Lock(*sndbuf, 0, format.dwBufferBytes, 576 result = IDirectSoundBuffer_Lock(*sndbuf, 0, format.dwBufferBytes,
566 (LPVOID *) & pvAudioPtr1, 577 (LPVOID *) & pvAudioPtr1, &dwAudioBytes1,
567 &dwAudioBytes1, 578 (LPVOID *) & pvAudioPtr2, &dwAudioBytes2,
568 (LPVOID *) & pvAudioPtr2, 579 DSBLOCK_ENTIREBUFFER);
569 &dwAudioBytes2, DSBLOCK_ENTIREBUFFER);
570 if (result == DS_OK) { 580 if (result == DS_OK) {
571 if (wavefmt->wBitsPerSample == 8) { 581 if (wavefmt->wBitsPerSample == 8) {
572 SDL_memset(pvAudioPtr1, 0x80, dwAudioBytes1); 582 SDL_memset(pvAudioPtr1, 0x80, dwAudioBytes1);
573 } else { 583 } else {
574 SDL_memset(pvAudioPtr1, 0x00, dwAudioBytes1); 584 SDL_memset(pvAudioPtr1, 0x00, dwAudioBytes1);
704 else 714 else
705 fprintf(stderr, "Using primary audio buffer\n"); 715 fprintf(stderr, "Using primary audio buffer\n");
706 #endif 716 #endif
707 717
708 /* The buffer will auto-start playing in DX5_WaitAudio() */ 718 /* The buffer will auto-start playing in DX5_WaitAudio() */
709 playing = 0; 719 lastchunk = 0;
710 mixlen = spec->size; 720 mixlen = spec->size;
711 721
712 #ifdef USE_POSITION_NOTIFY 722 #ifdef USE_POSITION_NOTIFY
713 /* See if we can use DirectX 6 event notification */ 723 /* See if we can use DirectX 6 event notification */
714 if (CreateAudioEvent(this) == 0) { 724 if (CreateAudioEvent(this) == 0) {