aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJan Niklas Hasse <[email protected]>2018-03-08 09:50:16 +0100
committerJan Niklas Hasse <[email protected]>2018-03-08 09:51:44 +0100
commit767807cd2273eb9e760b25d792820b1c8f1946e1 (patch)
treed44dd3ba5b9ccf6cfbbb9bd5dfdc591a0c4673ef
parent86319127e3e377312f815d55693f7b46569cde62 (diff)
SDL2 backend: Use callback instead of a timing loop
The system clock and audio clock aren't necessarily synchronized.
-rw-r--r--Alc/backends/sdl2.c94
1 files changed, 11 insertions, 83 deletions
diff --git a/Alc/backends/sdl2.c b/Alc/backends/sdl2.c
index 4b2d3acd..c191a528 100644
--- a/Alc/backends/sdl2.c
+++ b/Alc/backends/sdl2.c
@@ -35,15 +35,10 @@ typedef struct ALCsdl2Backend {
DERIVE_FROM_TYPE(ALCbackend);
SDL_AudioDeviceID deviceID;
- ALvoid *mBuffer;
- ALuint mSize;
ALCboolean quit;
- ATOMIC(int) killNow;
althrd_t thread;
} ALCsdl2Backend;
-static int ALCsdl2Backend_mixerProc(void *ptr);
-
static void ALCsdl2Backend_Construct(ALCsdl2Backend *self, ALCdevice *device);
static DECLARE_FORWARD(ALCsdl2Backend, ALCbackend, void, Destruct)
static ALCenum ALCsdl2Backend_open(ALCsdl2Backend *self, const ALCchar *name);
@@ -64,8 +59,6 @@ static void ALCsdl2Backend_Construct(ALCsdl2Backend *self, ALCdevice *device)
ALCbackend_Construct(STATIC_CAST(ALCbackend, self), device);
SET_VTABLE2(ALCsdl2Backend, ALCbackend, self);
- self->mBuffer = NULL;
- self->mSize = 0;
self->quit = ALC_FALSE;
if(SDL_WasInit(0) == 0) // Is SDL2 initialized at all?
{
@@ -74,61 +67,20 @@ static void ALCsdl2Backend_Construct(ALCsdl2Backend *self, ALCdevice *device)
}
else if(!SDL_WasInit(SDL_INIT_AUDIO))
SDL_InitSubSystem(SDL_INIT_AUDIO);
-
- ATOMIC_INIT(&self->killNow, AL_TRUE);
}
-static int ALCsdl2Backend_mixerProc(void *ptr)
+static void ALCsdl2Backend_audioCallback(void *ptr, Uint8* stream, int len)
{
ALCsdl2Backend *self = (ALCsdl2Backend*)ptr;
ALCdevice *device = STATIC_CAST(ALCbackend, self)->mDevice;
- struct timespec now, start;
- ALuint64 avail, done;
- const long restTime = (long)((ALuint64)device->UpdateSize * 1000000000 /
- device->Frequency / 2);
-
- SetRTPriority();
- althrd_setname(althrd_current(), MIXER_THREAD_NAME);
-
- done = 0;
- if(altimespec_get(&start, AL_TIME_UTC) != AL_TIME_UTC)
- {
- ERR("Failed to get starting time\n");
- return 1;
- }
- while(!ATOMIC_LOAD(&self->killNow, almemory_order_acquire) &&
- ATOMIC_LOAD(&device->Connected, almemory_order_acquire))
- {
- if(altimespec_get(&now, AL_TIME_UTC) != AL_TIME_UTC)
- {
- ERR("Failed to get current time\n");
- return 1;
- }
-
- avail = (now.tv_sec - start.tv_sec) * device->Frequency;
- avail += (ALint64)(now.tv_nsec - start.tv_nsec) * device->Frequency / 1000000000;
- if(avail < done)
- {
- /* Oops, time skipped backwards. Reset the number of samples done
- * with one update available since we (likely) just came back from
- * sleeping. */
- done = avail - device->UpdateSize;
- }
-
- if(avail-done < device->UpdateSize)
- al_nssleep(restTime);
- else while(avail-done >= device->UpdateSize)
- {
- ALCsdl2Backend_lock(self);
- aluMixData(device, self->mBuffer, device->UpdateSize);
- SDL_QueueAudio(self->deviceID, self->mBuffer, self->mSize);
- ALCsdl2Backend_unlock(self);
- done += device->UpdateSize;
- }
- }
-
- return 0;
+ ALsizei frameSize = FrameSizeFromDevFmt(
+ device->FmtChans, device->FmtType, device->AmbiOrder
+ );
+ assert(len % frameSize == 0);
+ ALCsdl2Backend_lock(self);
+ aluMixData(device, stream, len / frameSize);
+ ALCsdl2Backend_unlock(self);
}
static ALCenum ALCsdl2Backend_open(ALCsdl2Backend *self, const ALCchar *name)
@@ -140,6 +92,8 @@ static ALCenum ALCsdl2Backend_open(ALCsdl2Backend *self, const ALCchar *name)
want.format = AUDIO_F32;
want.channels = 2;
want.samples = device->UpdateSize;
+ want.callback = ALCsdl2Backend_audioCallback;
+ want.userdata = self;
if(!name)
name = SDL_GetAudioDeviceName(0, 0);
@@ -161,39 +115,13 @@ static ALCboolean ALCsdl2Backend_reset(ALCsdl2Backend *self)
static ALCboolean ALCsdl2Backend_start(ALCsdl2Backend *self)
{
- ALCdevice *device = STATIC_CAST(ALCbackend, self)->mDevice;
- self->mSize = device->UpdateSize * FrameSizeFromDevFmt(
- device->FmtChans, device->FmtType, device->AmbiOrder
- );
- self->mBuffer = malloc(self->mSize);
- if(!self->mBuffer)
- {
- ERR("Buffer malloc failed\n");
- return ALC_FALSE;
- }
-
- ATOMIC_STORE(&self->killNow, AL_FALSE, almemory_order_release);
- if(althrd_create(&self->thread, ALCsdl2Backend_mixerProc, self) != althrd_success)
- {
- free(self->mBuffer);
- self->mBuffer = NULL;
- self->mSize = 0;
- return ALC_FALSE;
- }
SDL_PauseAudioDevice(self->deviceID, 0);
return ALC_TRUE;
}
static void ALCsdl2Backend_stop(ALCsdl2Backend *self)
{
- int res;
-
- if(ATOMIC_EXCHANGE(&self->killNow, AL_TRUE, almemory_order_acq_rel))
- return;
- althrd_join(self->thread, &res);
-
- free(self->mBuffer);
- self->mBuffer = NULL;
+ SDL_PauseAudioDevice(self->deviceID, 1);
if(self->quit)
SDL_Quit();
}