Skip to content
Permalink
Browse files

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.
  • Loading branch information
icculus committed May 24, 2017
1 parent 088f57a commit 793c788b1c97b2837ea382bcdd20b822705b0c80
Showing with 23 additions and 3 deletions.
  1. +2 −1 src/audio/coreaudio/SDL_coreaudio.h
  2. +21 −2 src/audio/coreaudio/SDL_coreaudio.m
@@ -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;
@@ -533,11 +533,12 @@ static BOOL update_audio_session(_THIS, SDL_bool open)
}

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 @@ static BOOL update_audio_session(_THIS, SDL_bool open)
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);

0 comments on commit 793c788

Please sign in to comment.