diff --git a/src/audio/coreaudio/SDL_coreaudio.m b/src/audio/coreaudio/SDL_coreaudio.m index 3cafe3a18..efcaffa16 100644 --- a/src/audio/coreaudio/SDL_coreaudio.m +++ b/src/audio/coreaudio/SDL_coreaudio.m @@ -400,8 +400,12 @@ static void outputCallback(void *inUserData, AudioQueueRef inAQ, AudioQueueBufferRef inBuffer) { SDL_AudioDevice *this = (SDL_AudioDevice *) inUserData; + if (SDL_AtomicGet(&this->hidden->shutdown)) { + return; /* don't do anything. */ + } + if (!SDL_AtomicGet(&this->enabled) || SDL_AtomicGet(&this->paused)) { - /* Supply silence if audio is enabled and not paused */ + /* Supply silence if audio is not enabled or paused */ SDL_memset(inBuffer->mAudioData, this->spec.silence, inBuffer->mAudioDataBytesCapacity); } else { UInt32 remaining = inBuffer->mAudioDataBytesCapacity; @@ -430,9 +434,7 @@ outputCallback(void *inUserData, AudioQueueRef inAQ, AudioQueueBufferRef inBuffe } } - if (!SDL_AtomicGet(&this->hidden->shutdown)) { - AudioQueueEnqueueBuffer(this->hidden->audioQueue, inBuffer, 0, NULL); - } + AudioQueueEnqueueBuffer(this->hidden->audioQueue, inBuffer, 0, NULL); inBuffer->mAudioDataByteSize = inBuffer->mAudioDataBytesCapacity; } @@ -443,7 +445,13 @@ inputCallback(void *inUserData, AudioQueueRef inAQ, AudioQueueBufferRef inBuffer const AudioStreamPacketDescription *inPacketDescs ) { SDL_AudioDevice *this = (SDL_AudioDevice *) inUserData; - if (SDL_AtomicGet(&this->enabled) && !SDL_AtomicGet(&this->paused)) { /* ignore unless we're active. */ + + if (SDL_AtomicGet(&this->shutdown)) { + return; /* don't do anything. */ + } + + /* ignore unless we're active. */ + if (!SDL_AtomicGet(&this->paused) && SDL_AtomicGet(&this->enabled) && !SDL_AtomicGet(&this->paused)) { const Uint8 *ptr = (const Uint8 *) inBuffer->mAudioData; UInt32 remaining = inBuffer->mAudioDataByteSize; while (remaining > 0) { @@ -466,9 +474,7 @@ inputCallback(void *inUserData, AudioQueueRef inAQ, AudioQueueBufferRef inBuffer } } - if (!SDL_AtomicGet(&this->hidden->shutdown)) { - AudioQueueEnqueueBuffer(this->hidden->audioQueue, inBuffer, 0, NULL); - } + AudioQueueEnqueueBuffer(this->hidden->audioQueue, inBuffer, 0, NULL); } @@ -514,7 +520,6 @@ static void COREAUDIO_CloseDevice(_THIS) { const SDL_bool iscapture = this->iscapture; - int i; /* !!! FIXME: what does iOS do when a bluetooth audio device vanishes? Headphones unplugged? */ /* !!! FIXME: (we only do a "default" device on iOS right now...can we do more?) */ @@ -533,12 +538,6 @@ COREAUDIO_CloseDevice(_THIS) } if (this->hidden->audioQueue) { - 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); } @@ -546,6 +545,8 @@ COREAUDIO_CloseDevice(_THIS) SDL_DestroySemaphore(this->hidden->ready_semaphore); } + /* AudioQueueDispose() frees the actual buffer objects. */ + SDL_free(this->hidden->audioBuffer); SDL_free(this->hidden->thread_error); SDL_free(this->hidden->buffer); SDL_free(this->hidden); @@ -718,9 +719,9 @@ audioqueue_thread(void *arg) if (this->iscapture) { /* just stop immediately for capture devices. */ AudioQueueStop(this->hidden->audioQueue, 1); } else { /* Drain off any pending playback. */ - AudioQueueStop(this->hidden->audioQueue, 0); const CFTimeInterval secs = (((this->spec.size / (SDL_AUDIO_BITSIZE(this->spec.format) / 8)) / this->spec.channels) / ((CFTimeInterval) this->spec.freq)) * 2.0; CFRunLoopRunInMode(kCFRunLoopDefaultMode, secs, 0); + AudioQueueStop(this->hidden->audioQueue, 0); } return 0;