Mercurial > sdl-ios-xcode
comparison src/audio/SDL_audio.c @ 3336:00fab0ebfe54
Fixed a bug where when the audio starts paused all the DirectSound buffers
will end up getting locked and never unlocked and sound will never play.
Added a FIXME for Ryan to look at, too. :)
author | Sam Lantinga <slouken@libsdl.org> |
---|---|
date | Sun, 04 Oct 2009 09:18:48 +0000 |
parents | 1ed5d432e468 |
children | e897a4a9f578 |
comparison
equal
deleted
inserted
replaced
3335:b8d313de8a65 | 3336:00fab0ebfe54 |
---|---|
324 Uint8 *stream; | 324 Uint8 *stream; |
325 int stream_len; | 325 int stream_len; |
326 void *udata; | 326 void *udata; |
327 void (SDLCALL * fill) (void *userdata, Uint8 * stream, int len); | 327 void (SDLCALL * fill) (void *userdata, Uint8 * stream, int len); |
328 int silence; | 328 int silence; |
329 Uint32 delay; | |
329 | 330 |
330 /* For streaming when the buffer sizes don't match up */ | 331 /* For streaming when the buffer sizes don't match up */ |
331 Uint8 *istream; | 332 Uint8 *istream; |
332 int istream_len; | 333 int istream_len; |
333 | 334 |
377 } else { | 378 } else { |
378 silence = device->spec.silence; | 379 silence = device->spec.silence; |
379 stream_len = device->spec.size; | 380 stream_len = device->spec.size; |
380 } | 381 } |
381 | 382 |
383 /* Calculate the delay while paused */ | |
384 delay = ((device->spec.samples * 1000) / device->spec.freq); | |
385 | |
382 /* Determine if the streamer is necessary here */ | 386 /* Determine if the streamer is necessary here */ |
383 if (device->use_streamer == 1) { | 387 if (device->use_streamer == 1) { |
384 /* This code is almost the same as the old code. The difference is, instead of reding | 388 /* This code is almost the same as the old code. The difference is, instead of reading |
385 directly from the callback into "stream", then converting and sending the audio off, | 389 directly from the callback into "stream", then converting and sending the audio off, |
386 we go: callback -> "istream" -> (conversion) -> streamer -> stream -> device. | 390 we go: callback -> "istream" -> (conversion) -> streamer -> stream -> device. |
387 However, reading and writing with streamer are done separately: | 391 However, reading and writing with streamer are done separately: |
388 - We only call the callback and write to the streamer when the streamer does not | 392 - We only call the callback and write to the streamer when the streamer does not |
389 contain enough samples to output to the device. | 393 contain enough samples to output to the device. |
392 This allows us to perform resampling in the conversion step, where the output of the | 396 This allows us to perform resampling in the conversion step, where the output of the |
393 resampling process can be any number. We will have to see what a good size for the | 397 resampling process can be any number. We will have to see what a good size for the |
394 stream's maximum length is, but I suspect 2*max(len_cvt, stream_len) is a good figure. | 398 stream's maximum length is, but I suspect 2*max(len_cvt, stream_len) is a good figure. |
395 */ | 399 */ |
396 while (device->enabled) { | 400 while (device->enabled) { |
401 | |
402 if (device->paused) { | |
403 SDL_Delay(delay); | |
404 continue; | |
405 } | |
406 | |
397 /* Only read in audio if the streamer doesn't have enough already (if it does not have enough samples to output) */ | 407 /* Only read in audio if the streamer doesn't have enough already (if it does not have enough samples to output) */ |
398 if (SDL_StreamLength(&device->streamer) < stream_len) { | 408 if (SDL_StreamLength(&device->streamer) < stream_len) { |
399 /* Set up istream */ | 409 /* Set up istream */ |
400 if (device->convert.needed) { | 410 if (device->convert.needed) { |
401 if (device->convert.buf) { | 411 if (device->convert.buf) { |
402 istream = device->convert.buf; | 412 istream = device->convert.buf; |
403 } else { | 413 } else { |
404 continue; | 414 continue; |
405 } | 415 } |
406 } else { | 416 } else { |
417 /* FIXME: Ryan, this is probably wrong. I imagine we don't want to get | |
418 * a device buffer both here and below in the stream output. | |
419 */ | |
407 istream = current_audio.impl.GetDeviceBuf(device); | 420 istream = current_audio.impl.GetDeviceBuf(device); |
408 if (istream == NULL) { | 421 if (istream == NULL) { |
409 istream = device->fake_stream; | 422 istream = device->fake_stream; |
410 } | 423 } |
411 } | 424 } |
412 | 425 |
413 /* Read from the callback into the _input_ stream */ | 426 /* Read from the callback into the _input_ stream */ |
414 if (!device->paused) { | 427 SDL_mutexP(device->mixer_lock); |
415 SDL_mutexP(device->mixer_lock); | 428 (*fill) (udata, istream, istream_len); |
416 (*fill) (udata, istream, istream_len); | 429 SDL_mutexV(device->mixer_lock); |
417 SDL_mutexV(device->mixer_lock); | |
418 } | |
419 | 430 |
420 /* Convert the audio if necessary and write to the streamer */ | 431 /* Convert the audio if necessary and write to the streamer */ |
421 if (device->convert.needed) { | 432 if (device->convert.needed) { |
422 SDL_ConvertAudio(&device->convert); | 433 SDL_ConvertAudio(&device->convert); |
423 if (istream == NULL) { | 434 if (istream == NULL) { |
449 | 460 |
450 /* Now read from the streamer */ | 461 /* Now read from the streamer */ |
451 SDL_StreamRead(&device->streamer, stream, stream_len); | 462 SDL_StreamRead(&device->streamer, stream, stream_len); |
452 | 463 |
453 /* Ready current buffer for play and change current buffer */ | 464 /* Ready current buffer for play and change current buffer */ |
454 if (stream != device->fake_stream && !device->paused) { | 465 if (stream != device->fake_stream) { |
455 current_audio.impl.PlayDevice(device); | 466 current_audio.impl.PlayDevice(device); |
456 /* Wait for an audio buffer to become available */ | 467 /* Wait for an audio buffer to become available */ |
457 current_audio.impl.WaitDevice(device); | 468 current_audio.impl.WaitDevice(device); |
458 } else { | 469 } else { |
459 SDL_Delay((device->spec.samples * 1000) / | 470 SDL_Delay(delay); |
460 device->spec.freq); | |
461 } | 471 } |
462 } | 472 } |
463 | 473 |
464 } | 474 } |
465 } else { | 475 } else { |
466 /* Otherwise, do not use the streamer. This is the old code. */ | 476 /* Otherwise, do not use the streamer. This is the old code. */ |
467 | 477 |
468 /* Loop, filling the audio buffers */ | 478 /* Loop, filling the audio buffers */ |
469 while (device->enabled) { | 479 while (device->enabled) { |
480 | |
481 if (device->paused) { | |
482 SDL_Delay(delay); | |
483 continue; | |
484 } | |
470 | 485 |
471 /* Fill the current buffer with sound */ | 486 /* Fill the current buffer with sound */ |
472 if (device->convert.needed) { | 487 if (device->convert.needed) { |
473 if (device->convert.buf) { | 488 if (device->convert.buf) { |
474 stream = device->convert.buf; | 489 stream = device->convert.buf; |
480 if (stream == NULL) { | 495 if (stream == NULL) { |
481 stream = device->fake_stream; | 496 stream = device->fake_stream; |
482 } | 497 } |
483 } | 498 } |
484 | 499 |
485 if (!device->paused) { | 500 SDL_mutexP(device->mixer_lock); |
486 SDL_mutexP(device->mixer_lock); | 501 (*fill) (udata, stream, stream_len); |
487 (*fill) (udata, stream, stream_len); | 502 SDL_mutexV(device->mixer_lock); |
488 SDL_mutexV(device->mixer_lock); | |
489 } | |
490 | 503 |
491 /* Convert the audio if necessary */ | 504 /* Convert the audio if necessary */ |
492 if (device->convert.needed) { | 505 if (device->convert.needed) { |
493 SDL_ConvertAudio(&device->convert); | 506 SDL_ConvertAudio(&device->convert); |
494 stream = current_audio.impl.GetDeviceBuf(device); | 507 stream = current_audio.impl.GetDeviceBuf(device); |
498 SDL_memcpy(stream, device->convert.buf, | 511 SDL_memcpy(stream, device->convert.buf, |
499 device->convert.len_cvt); | 512 device->convert.len_cvt); |
500 } | 513 } |
501 | 514 |
502 /* Ready current buffer for play and change current buffer */ | 515 /* Ready current buffer for play and change current buffer */ |
503 if (stream != device->fake_stream && !device->paused) { | 516 if (stream != device->fake_stream) { |
504 current_audio.impl.PlayDevice(device); | 517 current_audio.impl.PlayDevice(device); |
505 /* Wait for an audio buffer to become available */ | 518 /* Wait for an audio buffer to become available */ |
506 current_audio.impl.WaitDevice(device); | 519 current_audio.impl.WaitDevice(device); |
507 } else { | 520 } else { |
508 SDL_Delay((device->spec.samples * 1000) / device->spec.freq); | 521 SDL_Delay(delay); |
509 } | 522 } |
510 } | 523 } |
511 } | 524 } |
512 | 525 |
513 /* Wait for the audio to drain.. */ | 526 /* Wait for the audio to drain.. */ |