From 793c788b1c97b2837ea382bcdd20b822705b0c80 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Wed, 24 May 2017 00:12:22 -0400 Subject: [PATCH] coreaudio: dynamically allocate AudioQueueBuffers. We need more than two buffers to flip between if they are small, or CoreAudio won't make any sound; apparently it needs X milliseconds of audio queued when it needs to play more or it drops any queued buffers. We are currently guessing 50 milliseconds as a minimum, but there's probably a more proper way to get the minimum time period from the system. Fixes Bugzilla #3656. --- src/audio/coreaudio/SDL_coreaudio.h | 3 ++- src/audio/coreaudio/SDL_coreaudio.m | 23 +++++++++++++++++++++-- 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/src/audio/coreaudio/SDL_coreaudio.h b/src/audio/coreaudio/SDL_coreaudio.h index 2227d4443..85f19d459 100644 --- a/src/audio/coreaudio/SDL_coreaudio.h +++ b/src/audio/coreaudio/SDL_coreaudio.h @@ -47,7 +47,8 @@ struct SDL_PrivateAudioData { SDL_Thread *thread; AudioQueueRef audioQueue; - AudioQueueBufferRef audioBuffer[2]; + int numAudioBuffers; + AudioQueueBufferRef *audioBuffer; void *buffer; UInt32 bufferOffset; UInt32 bufferSize; diff --git a/src/audio/coreaudio/SDL_coreaudio.m b/src/audio/coreaudio/SDL_coreaudio.m index a1c3736cb..2b9d6de66 100644 --- a/src/audio/coreaudio/SDL_coreaudio.m +++ b/src/audio/coreaudio/SDL_coreaudio.m @@ -533,11 +533,12 @@ COREAUDIO_CloseDevice(_THIS) } if (this->hidden->audioQueue) { - for (i = 0; i < SDL_arraysize(this->hidden->audioBuffer); i++) { + for (i = 0; i < this->hidden->numAudioBuffers; i++) { if (this->hidden->audioBuffer[i]) { AudioQueueFreeBuffer(this->hidden->audioQueue, this->hidden->audioBuffer[i]); } } + SDL_free(this->hidden->audioBuffer); AudioQueueDispose(this->hidden->audioQueue, 1); } @@ -663,7 +664,25 @@ prepare_audioqueue(_THIS) return 0; } - for (i = 0; i < SDL_arraysize(this->hidden->audioBuffer); i++) { + /* Make sure we can feed the device at least 50 milliseconds at a time. */ + const double msecs = (this->spec.size / ((double) this->spec.freq)) * 1000.0; + if (msecs >= 50.0) { + this->hidden->numAudioBuffers = 2; + } else { + this->hidden->numAudioBuffers = (int) (SDL_ceil(50.0 / msecs) * 2); + } + + this->hidden->audioBuffer = SDL_calloc(1, sizeof (AudioQueueBufferRef) * this->hidden->numAudioBuffers); + if (this->hidden->audioBuffer == NULL) { + SDL_OutOfMemory(); + return 0; + } + +#if DEBUG_COREAUDIO + printf("COREAUDIO: numAudioBuffers == %d\n", this->hidden->numAudioBuffers); +#endif + + for (i = 0; i < this->hidden->numAudioBuffers; i++) { result = AudioQueueAllocateBuffer(this->hidden->audioQueue, this->spec.size, &this->hidden->audioBuffer[i]); CHECK_RESULT("AudioQueueAllocateBuffer"); SDL_memset(this->hidden->audioBuffer[i]->mAudioData, this->spec.silence, this->hidden->audioBuffer[i]->mAudioDataBytesCapacity);