Skip to content

Commit

Permalink
coreaudio: dynamically allocate AudioQueueBuffers.
Browse files Browse the repository at this point in the history
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 793c788
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 3 deletions.
3 changes: 2 additions & 1 deletion src/audio/coreaudio/SDL_coreaudio.h
Expand Up @@ -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;
Expand Down
23 changes: 21 additions & 2 deletions src/audio/coreaudio/SDL_coreaudio.m
Expand Up @@ -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);
}

Expand Down Expand Up @@ -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);
Expand Down

0 comments on commit 793c788

Please sign in to comment.