mirror of
https://github.com/love2d/megasource.git
synced 2026-08-19 04:05:09 +02:00
Update SDL to 2.0.7
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2016 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
@@ -20,8 +20,8 @@
|
||||
*/
|
||||
#include "../../SDL_internal.h"
|
||||
|
||||
#ifndef _SDL_coreaudio_h
|
||||
#define _SDL_coreaudio_h
|
||||
#ifndef SDL_coreaudio_h_
|
||||
#define SDL_coreaudio_h_
|
||||
|
||||
#include "../SDL_sysaudio.h"
|
||||
|
||||
@@ -47,7 +47,7 @@ struct SDL_PrivateAudioData
|
||||
{
|
||||
SDL_Thread *thread;
|
||||
AudioQueueRef audioQueue;
|
||||
AudioQueueBufferRef audioBuffer[2];
|
||||
AudioQueueBufferRef *audioBuffer;
|
||||
void *buffer;
|
||||
UInt32 bufferOffset;
|
||||
UInt32 bufferSize;
|
||||
@@ -63,5 +63,6 @@ struct SDL_PrivateAudioData
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif /* _SDL_coreaudio_h */
|
||||
#endif /* SDL_coreaudio_h_ */
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2016 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
@@ -25,6 +25,7 @@
|
||||
/* !!! FIXME: clean out some of the macro salsa in here. */
|
||||
|
||||
#include "SDL_audio.h"
|
||||
#include "SDL_hints.h"
|
||||
#include "../SDL_audio_c.h"
|
||||
#include "../SDL_sysaudio.h"
|
||||
#include "SDL_coreaudio.h"
|
||||
@@ -285,9 +286,9 @@ static void interruption_begin(_THIS)
|
||||
static void interruption_end(_THIS)
|
||||
{
|
||||
if (this != NULL && this->hidden != NULL && this->hidden->audioQueue != NULL
|
||||
&& this->hidden->interrupted) {
|
||||
&& this->hidden->interrupted
|
||||
&& AudioQueueStart(this->hidden->audioQueue, NULL) == AVAudioSessionErrorCodeNone) {
|
||||
this->hidden->interrupted = SDL_FALSE;
|
||||
AudioQueueStart(this->hidden->audioQueue, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -325,7 +326,8 @@ static BOOL update_audio_session(_THIS, SDL_bool open)
|
||||
@autoreleasepool {
|
||||
AVAudioSession *session = [AVAudioSession sharedInstance];
|
||||
NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
|
||||
NSString *category;
|
||||
/* Set category to ambient by default so that other music continues playing. */
|
||||
NSString *category = AVAudioSessionCategoryAmbient;
|
||||
NSError *err = nil;
|
||||
|
||||
if (open_playback_devices && open_capture_devices) {
|
||||
@@ -333,10 +335,17 @@ static BOOL update_audio_session(_THIS, SDL_bool open)
|
||||
} else if (open_capture_devices) {
|
||||
category = AVAudioSessionCategoryRecord;
|
||||
} else {
|
||||
/* Set category to ambient so that other music continues playing.
|
||||
You can change this at runtime in your own code if you need different
|
||||
behavior. If this is common, we can add an SDL hint for this. */
|
||||
category = AVAudioSessionCategoryAmbient;
|
||||
const char *hint = SDL_GetHint(SDL_HINT_AUDIO_CATEGORY);
|
||||
if (hint) {
|
||||
if (SDL_strcasecmp(hint, "AVAudioSessionCategoryAmbient") == 0) {
|
||||
category = AVAudioSessionCategoryAmbient;
|
||||
} else if (SDL_strcasecmp(hint, "AVAudioSessionCategorySoloAmbient") == 0) {
|
||||
category = AVAudioSessionCategorySoloAmbient;
|
||||
} else if (SDL_strcasecmp(hint, "AVAudioSessionCategoryPlayback") == 0 ||
|
||||
SDL_strcasecmp(hint, "playback") == 0) {
|
||||
category = AVAudioSessionCategoryPlayback;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (![session setCategory:category error:&err]) {
|
||||
@@ -400,8 +409,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;
|
||||
@@ -412,7 +425,7 @@ outputCallback(void *inUserData, AudioQueueRef inAQ, AudioQueueBufferRef inBuffe
|
||||
if (this->hidden->bufferOffset >= this->hidden->bufferSize) {
|
||||
/* Generate the data */
|
||||
SDL_LockMutex(this->mixer_lock);
|
||||
(*this->spec.callback)(this->spec.userdata,
|
||||
(*this->callbackspec.callback)(this->callbackspec.userdata,
|
||||
this->hidden->buffer, this->hidden->bufferSize);
|
||||
SDL_UnlockMutex(this->mixer_lock);
|
||||
this->hidden->bufferOffset = 0;
|
||||
@@ -430,9 +443,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 +454,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) {
|
||||
@@ -459,16 +476,14 @@ inputCallback(void *inUserData, AudioQueueRef inAQ, AudioQueueBufferRef inBuffer
|
||||
|
||||
if (this->hidden->bufferOffset >= this->hidden->bufferSize) {
|
||||
SDL_LockMutex(this->mixer_lock);
|
||||
(*this->spec.callback)(this->spec.userdata, this->hidden->buffer, this->hidden->bufferSize);
|
||||
(*this->callbackspec.callback)(this->callbackspec.userdata, this->hidden->buffer, this->hidden->bufferSize);
|
||||
SDL_UnlockMutex(this->mixer_lock);
|
||||
this->hidden->bufferOffset = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!SDL_AtomicGet(&this->hidden->shutdown)) {
|
||||
AudioQueueEnqueueBuffer(this->hidden->audioQueue, inBuffer, 0, NULL);
|
||||
}
|
||||
AudioQueueEnqueueBuffer(this->hidden->audioQueue, inBuffer, 0, NULL);
|
||||
}
|
||||
|
||||
|
||||
@@ -514,7 +529,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?) */
|
||||
@@ -527,24 +541,24 @@ COREAUDIO_CloseDevice(_THIS)
|
||||
update_audio_session(this, SDL_FALSE);
|
||||
#endif
|
||||
|
||||
/* if callback fires again, feed silence; don't call into the app. */
|
||||
SDL_AtomicSet(&this->paused, 1);
|
||||
|
||||
if (this->hidden->audioQueue) {
|
||||
AudioQueueDispose(this->hidden->audioQueue, 1);
|
||||
}
|
||||
|
||||
if (this->hidden->thread) {
|
||||
SDL_AtomicSet(&this->hidden->shutdown, 1);
|
||||
SDL_WaitThread(this->hidden->thread, NULL);
|
||||
}
|
||||
|
||||
if (this->hidden->audioQueue) {
|
||||
for (i = 0; i < SDL_arraysize(this->hidden->audioBuffer); i++) {
|
||||
if (this->hidden->audioBuffer[i]) {
|
||||
AudioQueueFreeBuffer(this->hidden->audioQueue, this->hidden->audioBuffer[i]);
|
||||
}
|
||||
}
|
||||
AudioQueueDispose(this->hidden->audioQueue, 1);
|
||||
}
|
||||
|
||||
if (this->hidden->ready_semaphore) {
|
||||
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);
|
||||
@@ -663,7 +677,31 @@ prepare_audioqueue(_THIS)
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (i = 0; i < SDL_arraysize(this->hidden->audioBuffer); i++) {
|
||||
/* Make sure we can feed the device a minimum amount of time */
|
||||
double MINIMUM_AUDIO_BUFFER_TIME_MS = 15.0;
|
||||
#if defined(__IPHONEOS__)
|
||||
if (floor(NSFoundationVersionNumber) <= NSFoundationVersionNumber_iOS_7_1) {
|
||||
/* Older iOS hardware, use 40 ms as a minimum time */
|
||||
MINIMUM_AUDIO_BUFFER_TIME_MS = 40.0;
|
||||
}
|
||||
#endif
|
||||
const double msecs = (this->spec.samples / ((double) this->spec.freq)) * 1000.0;
|
||||
int numAudioBuffers = 2;
|
||||
if (msecs < MINIMUM_AUDIO_BUFFER_TIME_MS) { /* use more buffers if we have a VERY small sample set. */
|
||||
numAudioBuffers = ((int)SDL_ceil(MINIMUM_AUDIO_BUFFER_TIME_MS / msecs) * 2);
|
||||
}
|
||||
|
||||
this->hidden->audioBuffer = SDL_calloc(1, sizeof (AudioQueueBufferRef) * numAudioBuffers);
|
||||
if (this->hidden->audioBuffer == NULL) {
|
||||
SDL_OutOfMemory();
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if DEBUG_COREAUDIO
|
||||
printf("COREAUDIO: numAudioBuffers == %d\n", numAudioBuffers);
|
||||
#endif
|
||||
|
||||
for (i = 0; i < 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);
|
||||
@@ -696,10 +734,7 @@ audioqueue_thread(void *arg)
|
||||
CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0.10, 1);
|
||||
}
|
||||
|
||||
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);
|
||||
if (!this->iscapture) { /* Drain off any pending playback. */
|
||||
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);
|
||||
}
|
||||
@@ -734,6 +769,13 @@ COREAUDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
|
||||
if (!update_audio_session(this, SDL_TRUE)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Stop CoreAudio from doing expensive audio rate conversion */
|
||||
@autoreleasepool {
|
||||
AVAudioSession* session = [AVAudioSession sharedInstance];
|
||||
[session setPreferredSampleRate:this->spec.freq error:nil];
|
||||
this->spec.freq = (int)session.sampleRate;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Setup a AudioStreamBasicDescription with the requested format */
|
||||
|
||||
Reference in New Issue
Block a user