From 315bd556acdc4b8b67b073f64d472f243a96544d Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Wed, 21 Dec 2016 17:20:11 -0800 Subject: Convert the SndIO backend to the updated API --- Alc/ALc.c | 2 +- Alc/backends/base.h | 1 + Alc/backends/sndio.c | 204 ++++++++++++++++++++++++++++------------------ OpenAL32/Include/alMain.h | 3 - 4 files changed, 128 insertions(+), 82 deletions(-) diff --git a/Alc/ALc.c b/Alc/ALc.c index f1e1ad1f..1690c9fe 100644 --- a/Alc/ALc.c +++ b/Alc/ALc.c @@ -81,7 +81,7 @@ static struct BackendInfo BackendList[] = { { "solaris", ALCsolarisBackendFactory_getFactory, NULL, NULL, NULL, EmptyFuncs }, #endif #ifdef HAVE_SNDIO - { "sndio", NULL, alc_sndio_init, alc_sndio_deinit, alc_sndio_probe, EmptyFuncs }, + { "sndio", ALCsndioBackendFactory_getFactory, NULL, NULL, NULL, EmptyFuncs }, #endif #ifdef HAVE_QSA { "qsa", NULL, alc_qsa_init, alc_qsa_deinit, alc_qsa_probe, EmptyFuncs }, diff --git a/Alc/backends/base.h b/Alc/backends/base.h index 04795b36..94177405 100644 --- a/Alc/backends/base.h +++ b/Alc/backends/base.h @@ -140,6 +140,7 @@ ALCbackendFactory *ALCalsaBackendFactory_getFactory(void); ALCbackendFactory *ALCossBackendFactory_getFactory(void); ALCbackendFactory *ALCjackBackendFactory_getFactory(void); ALCbackendFactory *ALCsolarisBackendFactory_getFactory(void); +ALCbackendFactory *ALCsndioBackendFactory_getFactory(void); ALCbackendFactory *ALCmmdevBackendFactory_getFactory(void); ALCbackendFactory *ALCdsoundBackendFactory_getFactory(void); ALCbackendFactory *ALCwinmmBackendFactory_getFactory(void); diff --git a/Alc/backends/sndio.c b/Alc/backends/sndio.c index 52bff13a..af519794 100644 --- a/Alc/backends/sndio.c +++ b/Alc/backends/sndio.c @@ -28,19 +28,16 @@ #include "alu.h" #include "threads.h" -#include +#include "backends/base.h" +#include -static const ALCchar sndio_device[] = "SndIO Default"; -static ALCboolean sndio_load(void) -{ - return ALC_TRUE; -} +typedef struct ALCsndioBackend { + DERIVE_FROM_TYPE(ALCbackend); -typedef struct { struct sio_hdl *sndHandle; ALvoid *mix_data; @@ -48,13 +45,53 @@ typedef struct { volatile int killNow; althrd_t thread; -} sndio_data; +} ALCsndioBackend; + +static int ALCsndioBackend_mixerProc(void *ptr); + +static void ALCsndioBackend_Construct(ALCsndioBackend *self, ALCdevice *device); +static void ALCsndioBackend_Destruct(ALCsndioBackend *self); +static ALCenum ALCsndioBackend_open(ALCsndioBackend *self, const ALCchar *name); +static void ALCsndioBackend_close(ALCsndioBackend *self); +static ALCboolean ALCsndioBackend_reset(ALCsndioBackend *self); +static ALCboolean ALCsndioBackend_start(ALCsndioBackend *self); +static void ALCsndioBackend_stop(ALCsndioBackend *self); +static DECLARE_FORWARD2(ALCsndioBackend, ALCbackend, ALCenum, captureSamples, void*, ALCuint) +static DECLARE_FORWARD(ALCsndioBackend, ALCbackend, ALCuint, availableSamples) +static DECLARE_FORWARD(ALCsndioBackend, ALCbackend, ClockLatency, getClockLatency) +static DECLARE_FORWARD(ALCsndioBackend, ALCbackend, void, lock) +static DECLARE_FORWARD(ALCsndioBackend, ALCbackend, void, unlock) +DECLARE_DEFAULT_ALLOCATORS(ALCsndioBackend) + +DEFINE_ALCBACKEND_VTABLE(ALCsndioBackend); + + +static const ALCchar sndio_device[] = "SndIO Default"; + + +static void ALCsndioBackend_Construct(ALCsndioBackend *self, ALCdevice *device) +{ + ALCbackend_Construct(STATIC_CAST(ALCbackend, self), device); + SET_VTABLE2(ALCsndioBackend, ALCbackend, self); +} + +static void ALCsndioBackend_Destruct(ALCsndioBackend *self) +{ + if(self->sndHandle) + sio_close(self->sndHandle); + self->sndHandle = NULL; + + al_free(self->mix_data); + self->mix_data = NULL; + + ALCbackend_Destruct(STATIC_CAST(ALCbackend, self)); +} -static int sndio_proc(void *ptr) +static int ALCsndioBackend_mixerProc(void *ptr) { - ALCdevice *device = ptr; - sndio_data *data = device->ExtraData; + ALCsndioBackend *self = (ALCsndioBackend*)ptr; + ALCdevice *device = STATIC_CAST(ALCbackend, self)->mDevice; ALsizei frameSize; size_t wrote; @@ -63,15 +100,15 @@ static int sndio_proc(void *ptr) frameSize = FrameSizeFromDevFmt(device->FmtChans, device->FmtType); - while(!data->killNow && device->Connected) + while(!self->killNow && device->Connected) { - ALsizei len = data->data_size; - ALubyte *WritePtr = data->mix_data; + ALsizei len = self->data_size; + ALubyte *WritePtr = self->mix_data; aluMixData(device, WritePtr, len/frameSize); - while(len > 0 && !data->killNow) + while(len > 0 && !self->killNow) { - wrote = sio_write(data->sndHandle, WritePtr, len); + wrote = sio_write(self->sndHandle, WritePtr, len); if(wrote == 0) { ERR("sio_write failed\n"); @@ -90,45 +127,36 @@ static int sndio_proc(void *ptr) } - -static ALCenum sndio_open_playback(ALCdevice *device, const ALCchar *deviceName) +static ALCenum ALCsndioBackend_open(ALCsndioBackend *self, const ALCchar *name) { - sndio_data *data; + ALCdevice *device = STATIC_CAST(ALCbackend,self)->mDevice; - if(!deviceName) - deviceName = sndio_device; - else if(strcmp(deviceName, sndio_device) != 0) + if(!name) + name = sndio_device; + else if(strcmp(name, sndio_device) != 0) return ALC_INVALID_VALUE; - data = calloc(1, sizeof(*data)); - data->killNow = 0; - - data->sndHandle = sio_open(NULL, SIO_PLAY, 0); - if(data->sndHandle == NULL) + self->sndHandle = sio_open(NULL, SIO_PLAY, 0); + if(self->sndHandle == NULL) { - free(data); ERR("Could not open device\n"); return ALC_INVALID_VALUE; } - al_string_copy_cstr(&device->DeviceName, deviceName); - device->ExtraData = data; + al_string_copy_cstr(&device->DeviceName, name); return ALC_NO_ERROR; } -static void sndio_close_playback(ALCdevice *device) +static void ALCsndioBackend_close(ALCsndioBackend *self) { - sndio_data *data = device->ExtraData; - - sio_close(data->sndHandle); - free(data); - device->ExtraData = NULL; + sio_close(self->sndHandle); + self->sndHandle = NULL; } -static ALCboolean sndio_reset_playback(ALCdevice *device) +static ALCboolean ALCsndioBackend_reset(ALCsndioBackend *self) { - sndio_data *data = device->ExtraData; + ALCdevice *device = STATIC_CAST(ALCbackend,self)->mDevice; struct sio_par par; sio_initpar(&par); @@ -170,7 +198,7 @@ static ALCboolean sndio_reset_playback(ALCdevice *device) par.appbufsz = device->UpdateSize * (device->NumUpdates-1); if(!par.appbufsz) par.appbufsz = device->UpdateSize; - if(!sio_setpar(data->sndHandle, &par) || !sio_getpar(data->sndHandle, &par)) + if(!sio_setpar(self->sndHandle, &par) || !sio_getpar(self->sndHandle, &par)) { ERR("Failed to set device parameters\n"); return ALC_FALSE; @@ -211,77 +239,84 @@ static ALCboolean sndio_reset_playback(ALCdevice *device) return ALC_TRUE; } -static ALCboolean sndio_start_playback(ALCdevice *device) +static ALCboolean ALCsndioBackend_start(ALCsndioBackend *self) { - sndio_data *data = device->ExtraData; + ALCdevice *device = STATIC_CAST(ALCbackend,self)->mDevice; - if(!sio_start(data->sndHandle)) + self->data_size = device->UpdateSize * FrameSizeFromDevFmt(device->FmtChans, device->FmtType); + al_free(self->mix_data); + self->mix_data = al_calloc(16, self->data_size); + + if(!sio_start(self->sndHandle)) { ERR("Error starting playback\n"); return ALC_FALSE; } - data->data_size = device->UpdateSize * FrameSizeFromDevFmt(device->FmtChans, device->FmtType); - data->mix_data = calloc(1, data->data_size); - - data->killNow = 0; - if(althrd_create(&data->thread, sndio_proc, device) != althrd_success) + self->killNow = 0; + if(althrd_create(&self->thread, ALCsndioBackend_mixerProc, self) != althrd_success) { - sio_stop(data->sndHandle); - free(data->mix_data); - data->mix_data = NULL; + sio_stop(self->sndHandle); return ALC_FALSE; } return ALC_TRUE; } -static void sndio_stop_playback(ALCdevice *device) +static void ALCsndioBackend_stop(ALCsndioBackend *self) { - sndio_data *data = device->ExtraData; int res; - if(data->killNow) + if(self->killNow) return; - data->killNow = 1; - althrd_join(data->thread, &res); + self->killNow = 1; + althrd_join(self->thread, &res); - if(!sio_stop(data->sndHandle)) + if(!sio_stop(self->sndHandle)) ERR("Error stopping device\n"); - free(data->mix_data); - data->mix_data = NULL; + al_free(self->mix_data); + self->mix_data = NULL; } -static const BackendFuncs sndio_funcs = { - sndio_open_playback, - sndio_close_playback, - sndio_reset_playback, - sndio_start_playback, - sndio_stop_playback, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL -}; - -ALCboolean alc_sndio_init(BackendFuncs *func_list) +typedef struct ALCsndioBackendFactory { + DERIVE_FROM_TYPE(ALCbackendFactory); +} ALCsndioBackendFactory; +#define ALCSNDIOBACKENDFACTORY_INITIALIZER { { GET_VTABLE2(ALCsndioBackendFactory, ALCbackendFactory) } } + +ALCbackendFactory *ALCsndioBackendFactory_getFactory(void); + +static ALCboolean ALCsndioBackendFactory_init(ALCsndioBackendFactory *self); +static DECLARE_FORWARD(ALCsndioBackendFactory, ALCbackendFactory, void, deinit) +static ALCboolean ALCsndioBackendFactory_querySupport(ALCsndioBackendFactory *self, ALCbackend_Type type); +static void ALCsndioBackendFactory_probe(ALCsndioBackendFactory *self, enum DevProbe type); +static ALCbackend* ALCsndioBackendFactory_createBackend(ALCsndioBackendFactory *self, ALCdevice *device, ALCbackend_Type type); +DEFINE_ALCBACKENDFACTORY_VTABLE(ALCsndioBackendFactory); + + +ALCbackendFactory *ALCsndioBackendFactory_getFactory(void) { - if(!sndio_load()) - return ALC_FALSE; - *func_list = sndio_funcs; + static ALCsndioBackendFactory factory = ALCSNDIOBACKENDFACTORY_INITIALIZER; + return STATIC_CAST(ALCbackendFactory, &factory); +} + + +static ALCboolean ALCsndioBackendFactory_init(ALCsndioBackendFactory* UNUSED(self)) +{ + /* No dynamic loading */ return ALC_TRUE; } -void alc_sndio_deinit(void) +static ALCboolean ALCsndioBackendFactory_querySupport(ALCsndioBackendFactory* UNUSED(self), ALCbackend_Type type) { + if(type == ALCbackend_Playback) + return ALC_TRUE; + return ALC_FALSE; } -void alc_sndio_probe(enum DevProbe type) +static void ALCsndioBackendFactory_probe(ALCsndioBackendFactory* UNUSED(self), enum DevProbe type) { switch(type) { @@ -292,3 +327,16 @@ void alc_sndio_probe(enum DevProbe type) break; } } + +static ALCbackend* ALCsndioBackendFactory_createBackend(ALCsndioBackendFactory* UNUSED(self), ALCdevice *device, ALCbackend_Type type) +{ + if(type == ALCbackend_Playback) + { + ALCsndioBackend *backend; + NEW_OBJ(backend, ALCsndioBackend)(device); + if(!backend) return NULL; + return STATIC_CAST(ALCbackend, backend); + } + + return NULL; +} diff --git a/OpenAL32/Include/alMain.h b/OpenAL32/Include/alMain.h index 837e1082..5a5c3923 100644 --- a/OpenAL32/Include/alMain.h +++ b/OpenAL32/Include/alMain.h @@ -401,9 +401,6 @@ typedef struct { ALCuint (*AvailableSamples)(ALCdevice*); } BackendFuncs; -ALCboolean alc_sndio_init(BackendFuncs *func_list); -void alc_sndio_deinit(void); -void alc_sndio_probe(enum DevProbe type); ALCboolean alc_ca_init(BackendFuncs *func_list); void alc_ca_deinit(void); void alc_ca_probe(enum DevProbe type); -- cgit v1.2.3