From e8679e72140438b7fb9d2fe672914b056d1a3171 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Fri, 9 Nov 2018 03:46:30 -0800 Subject: Convert the null backend to C++ --- Alc/backends/null.c | 220 ----------------------------------------------- Alc/backends/null.cpp | 232 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 232 insertions(+), 220 deletions(-) delete mode 100644 Alc/backends/null.c create mode 100644 Alc/backends/null.cpp (limited to 'Alc') diff --git a/Alc/backends/null.c b/Alc/backends/null.c deleted file mode 100644 index d1c110e8..00000000 --- a/Alc/backends/null.c +++ /dev/null @@ -1,220 +0,0 @@ -/** - * OpenAL cross platform audio library - * Copyright (C) 2010 by Chris Robinson - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * Or go to http://www.gnu.org/copyleft/lgpl.html - */ - -#include "config.h" - -#include -#ifdef HAVE_WINDOWS_H -#include -#endif - -#include "alMain.h" -#include "alu.h" -#include "threads.h" -#include "compat.h" - -#include "backends/base.h" - - -typedef struct ALCnullBackend { - DERIVE_FROM_TYPE(ALCbackend); - - ATOMIC(int) killNow; - althrd_t thread; -} ALCnullBackend; - -static int ALCnullBackend_mixerProc(void *ptr); - -static void ALCnullBackend_Construct(ALCnullBackend *self, ALCdevice *device); -static DECLARE_FORWARD(ALCnullBackend, ALCbackend, void, Destruct) -static ALCenum ALCnullBackend_open(ALCnullBackend *self, const ALCchar *name); -static ALCboolean ALCnullBackend_reset(ALCnullBackend *self); -static ALCboolean ALCnullBackend_start(ALCnullBackend *self); -static void ALCnullBackend_stop(ALCnullBackend *self); -static DECLARE_FORWARD2(ALCnullBackend, ALCbackend, ALCenum, captureSamples, void*, ALCuint) -static DECLARE_FORWARD(ALCnullBackend, ALCbackend, ALCuint, availableSamples) -static DECLARE_FORWARD(ALCnullBackend, ALCbackend, ClockLatency, getClockLatency) -static DECLARE_FORWARD(ALCnullBackend, ALCbackend, void, lock) -static DECLARE_FORWARD(ALCnullBackend, ALCbackend, void, unlock) -DECLARE_DEFAULT_ALLOCATORS(ALCnullBackend) - -DEFINE_ALCBACKEND_VTABLE(ALCnullBackend); - - -static const ALCchar nullDevice[] = "No Output"; - - -static void ALCnullBackend_Construct(ALCnullBackend *self, ALCdevice *device) -{ - ALCbackend_Construct(STATIC_CAST(ALCbackend, self), device); - SET_VTABLE2(ALCnullBackend, ALCbackend, self); - - ATOMIC_INIT(&self->killNow, AL_TRUE); -} - - -static int ALCnullBackend_mixerProc(void *ptr) -{ - ALCnullBackend *self = (ALCnullBackend*)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) - { - ALCnullBackend_lock(self); - aluMixData(device, NULL, device->UpdateSize); - ALCnullBackend_unlock(self); - done += device->UpdateSize; - } - } - - return 0; -} - - -static ALCenum ALCnullBackend_open(ALCnullBackend *self, const ALCchar *name) -{ - ALCdevice *device; - - if(!name) - name = nullDevice; - else if(strcmp(name, nullDevice) != 0) - return ALC_INVALID_VALUE; - - device = STATIC_CAST(ALCbackend, self)->mDevice; - alstr_copy_cstr(&device->DeviceName, name); - - return ALC_NO_ERROR; -} - -static ALCboolean ALCnullBackend_reset(ALCnullBackend *self) -{ - SetDefaultWFXChannelOrder(STATIC_CAST(ALCbackend, self)->mDevice); - return ALC_TRUE; -} - -static ALCboolean ALCnullBackend_start(ALCnullBackend *self) -{ - ATOMIC_STORE(&self->killNow, AL_FALSE, almemory_order_release); - if(althrd_create(&self->thread, ALCnullBackend_mixerProc, self) != althrd_success) - return ALC_FALSE; - return ALC_TRUE; -} - -static void ALCnullBackend_stop(ALCnullBackend *self) -{ - int res; - - if(ATOMIC_EXCHANGE(&self->killNow, AL_TRUE, almemory_order_acq_rel)) - return; - althrd_join(self->thread, &res); -} - - -typedef struct ALCnullBackendFactory { - DERIVE_FROM_TYPE(ALCbackendFactory); -} ALCnullBackendFactory; -#define ALCNULLBACKENDFACTORY_INITIALIZER { { GET_VTABLE2(ALCnullBackendFactory, ALCbackendFactory) } } - -ALCbackendFactory *ALCnullBackendFactory_getFactory(void); - -static ALCboolean ALCnullBackendFactory_init(ALCnullBackendFactory *self); -static DECLARE_FORWARD(ALCnullBackendFactory, ALCbackendFactory, void, deinit) -static ALCboolean ALCnullBackendFactory_querySupport(ALCnullBackendFactory *self, ALCbackend_Type type); -static void ALCnullBackendFactory_probe(ALCnullBackendFactory *self, enum DevProbe type, al_string *outnames); -static ALCbackend* ALCnullBackendFactory_createBackend(ALCnullBackendFactory *self, ALCdevice *device, ALCbackend_Type type); -DEFINE_ALCBACKENDFACTORY_VTABLE(ALCnullBackendFactory); - - -ALCbackendFactory *ALCnullBackendFactory_getFactory(void) -{ - static ALCnullBackendFactory factory = ALCNULLBACKENDFACTORY_INITIALIZER; - return STATIC_CAST(ALCbackendFactory, &factory); -} - - -static ALCboolean ALCnullBackendFactory_init(ALCnullBackendFactory* UNUSED(self)) -{ - return ALC_TRUE; -} - -static ALCboolean ALCnullBackendFactory_querySupport(ALCnullBackendFactory* UNUSED(self), ALCbackend_Type type) -{ - if(type == ALCbackend_Playback) - return ALC_TRUE; - return ALC_FALSE; -} - -static void ALCnullBackendFactory_probe(ALCnullBackendFactory* UNUSED(self), enum DevProbe type, al_string *outnames) -{ - switch(type) - { - case ALL_DEVICE_PROBE: - case CAPTURE_DEVICE_PROBE: - alstr_append_range(outnames, nullDevice, nullDevice+sizeof(nullDevice)); - break; - } -} - -static ALCbackend* ALCnullBackendFactory_createBackend(ALCnullBackendFactory* UNUSED(self), ALCdevice *device, ALCbackend_Type type) -{ - if(type == ALCbackend_Playback) - { - ALCnullBackend *backend; - NEW_OBJ(backend, ALCnullBackend)(device); - if(!backend) return NULL; - return STATIC_CAST(ALCbackend, backend); - } - - return NULL; -} diff --git a/Alc/backends/null.cpp b/Alc/backends/null.cpp new file mode 100644 index 00000000..2e1c6ac9 --- /dev/null +++ b/Alc/backends/null.cpp @@ -0,0 +1,232 @@ +/** + * OpenAL cross platform audio library + * Copyright (C) 2010 by Chris Robinson + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * Or go to http://www.gnu.org/copyleft/lgpl.html + */ + +#include "config.h" + +#include +#ifdef HAVE_WINDOWS_H +#include +#endif + +#include "alMain.h" +#include "alu.h" +#include "threads.h" +#include "compat.h" + +#include "backends/base.h" + + +namespace { + +constexpr ALCchar nullDevice[] = "No Output"; + +} // namespace + +struct ALCnullBackend final : public ALCbackend { + ATOMIC(int) killNow; + althrd_t thread; +}; + +static int ALCnullBackend_mixerProc(void *ptr); + +static void ALCnullBackend_Construct(ALCnullBackend *self, ALCdevice *device); +static void ALCnullBackend_Destruct(ALCnullBackend *self); +static ALCenum ALCnullBackend_open(ALCnullBackend *self, const ALCchar *name); +static ALCboolean ALCnullBackend_reset(ALCnullBackend *self); +static ALCboolean ALCnullBackend_start(ALCnullBackend *self); +static void ALCnullBackend_stop(ALCnullBackend *self); +static DECLARE_FORWARD2(ALCnullBackend, ALCbackend, ALCenum, captureSamples, void*, ALCuint) +static DECLARE_FORWARD(ALCnullBackend, ALCbackend, ALCuint, availableSamples) +static DECLARE_FORWARD(ALCnullBackend, ALCbackend, ClockLatency, getClockLatency) +static DECLARE_FORWARD(ALCnullBackend, ALCbackend, void, lock) +static DECLARE_FORWARD(ALCnullBackend, ALCbackend, void, unlock) +DECLARE_DEFAULT_ALLOCATORS(ALCnullBackend) + +DEFINE_ALCBACKEND_VTABLE(ALCnullBackend); + + +static void ALCnullBackend_Construct(ALCnullBackend *self, ALCdevice *device) +{ + new (self) ALCnullBackend{}; + ALCbackend_Construct(STATIC_CAST(ALCbackend, self), device); + SET_VTABLE2(ALCnullBackend, ALCbackend, self); + + ATOMIC_INIT(&self->killNow, AL_TRUE); +} + +static void ALCnullBackend_Destruct(ALCnullBackend *self) +{ + ALCbackend_Destruct(STATIC_CAST(ALCbackend, self)); + self->~ALCnullBackend(); +} + + +static int ALCnullBackend_mixerProc(void *ptr) +{ + ALCnullBackend *self = (ALCnullBackend*)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) + { + ALCnullBackend_lock(self); + aluMixData(device, NULL, device->UpdateSize); + ALCnullBackend_unlock(self); + done += device->UpdateSize; + } + } + + return 0; +} + + +static ALCenum ALCnullBackend_open(ALCnullBackend *self, const ALCchar *name) +{ + ALCdevice *device; + + if(!name) + name = nullDevice; + else if(strcmp(name, nullDevice) != 0) + return ALC_INVALID_VALUE; + + device = STATIC_CAST(ALCbackend, self)->mDevice; + alstr_copy_cstr(&device->DeviceName, name); + + return ALC_NO_ERROR; +} + +static ALCboolean ALCnullBackend_reset(ALCnullBackend *self) +{ + SetDefaultWFXChannelOrder(STATIC_CAST(ALCbackend, self)->mDevice); + return ALC_TRUE; +} + +static ALCboolean ALCnullBackend_start(ALCnullBackend *self) +{ + ATOMIC_STORE(&self->killNow, AL_FALSE, almemory_order_release); + if(althrd_create(&self->thread, ALCnullBackend_mixerProc, self) != althrd_success) + return ALC_FALSE; + return ALC_TRUE; +} + +static void ALCnullBackend_stop(ALCnullBackend *self) +{ + int res; + + if(ATOMIC_EXCHANGE(&self->killNow, AL_TRUE, almemory_order_acq_rel)) + return; + althrd_join(self->thread, &res); +} + + +struct ALCnullBackendFactory final : public ALCbackendFactory { + ALCnullBackendFactory() noexcept; +}; + +ALCbackendFactory *ALCnullBackendFactory_getFactory(void); + +static ALCboolean ALCnullBackendFactory_init(ALCnullBackendFactory *self); +static DECLARE_FORWARD(ALCnullBackendFactory, ALCbackendFactory, void, deinit) +static ALCboolean ALCnullBackendFactory_querySupport(ALCnullBackendFactory *self, ALCbackend_Type type); +static void ALCnullBackendFactory_probe(ALCnullBackendFactory *self, enum DevProbe type, al_string *outnames); +static ALCbackend* ALCnullBackendFactory_createBackend(ALCnullBackendFactory *self, ALCdevice *device, ALCbackend_Type type); +DEFINE_ALCBACKENDFACTORY_VTABLE(ALCnullBackendFactory); + +ALCnullBackendFactory::ALCnullBackendFactory() noexcept + : ALCbackendFactory{GET_VTABLE2(ALCnullBackendFactory, ALCbackendFactory)} +{ +} + + +ALCbackendFactory *ALCnullBackendFactory_getFactory(void) +{ + static ALCnullBackendFactory factory{}; + return STATIC_CAST(ALCbackendFactory, &factory); +} + + +static ALCboolean ALCnullBackendFactory_init(ALCnullBackendFactory* UNUSED(self)) +{ + return ALC_TRUE; +} + +static ALCboolean ALCnullBackendFactory_querySupport(ALCnullBackendFactory* UNUSED(self), ALCbackend_Type type) +{ + if(type == ALCbackend_Playback) + return ALC_TRUE; + return ALC_FALSE; +} + +static void ALCnullBackendFactory_probe(ALCnullBackendFactory* UNUSED(self), enum DevProbe type, al_string *outnames) +{ + switch(type) + { + case ALL_DEVICE_PROBE: + case CAPTURE_DEVICE_PROBE: + alstr_append_range(outnames, nullDevice, nullDevice+sizeof(nullDevice)); + break; + } +} + +static ALCbackend* ALCnullBackendFactory_createBackend(ALCnullBackendFactory* UNUSED(self), ALCdevice *device, ALCbackend_Type type) +{ + if(type == ALCbackend_Playback) + { + ALCnullBackend *backend; + NEW_OBJ(backend, ALCnullBackend)(device); + if(!backend) return NULL; + return STATIC_CAST(ALCbackend, backend); + } + + return NULL; +} -- cgit v1.2.3