Start a new backend factory API
Using proper class inheritance. Be aware this breaks all backends except null (and loopback). They will be restored individually in due time.
This commit is contained in:
+16
-25
@@ -57,6 +57,7 @@
|
||||
#include "almalloc.h"
|
||||
|
||||
#include "backends/base.h"
|
||||
#include "backends/null.h"
|
||||
|
||||
|
||||
namespace {
|
||||
@@ -66,10 +67,11 @@ namespace {
|
||||
************************************************/
|
||||
struct BackendInfo {
|
||||
const char *name;
|
||||
ALCbackendFactory* (*getFactory)(void);
|
||||
BackendFactory& (*getFactory)(void);
|
||||
};
|
||||
|
||||
struct BackendInfo BackendList[] = {
|
||||
#if 0
|
||||
#ifdef HAVE_JACK
|
||||
{ "jack", ALCjackBackendFactory_getFactory },
|
||||
#endif
|
||||
@@ -117,6 +119,8 @@ struct BackendInfo BackendList[] = {
|
||||
#ifdef HAVE_WAVE
|
||||
{ "wave", ALCwaveBackendFactory_getFactory },
|
||||
#endif
|
||||
#endif /* 0 */
|
||||
{ "null", NullBackendFactory::getFactory },
|
||||
};
|
||||
ALsizei BackendListSize = COUNTOF(BackendList);
|
||||
#undef EmptyFuncs
|
||||
@@ -1099,23 +1103,22 @@ static void alc_initconfig(void)
|
||||
|
||||
for(n = i = 0;i < BackendListSize && (!PlaybackBackend.name || !CaptureBackend.name);i++)
|
||||
{
|
||||
ALCbackendFactory *factory;
|
||||
BackendList[n] = BackendList[i];
|
||||
|
||||
factory = BackendList[n].getFactory();
|
||||
if(!V0(factory,init)())
|
||||
BackendFactory &factory = BackendList[n].getFactory();
|
||||
if(!factory.init())
|
||||
{
|
||||
WARN("Failed to initialize backend \"%s\"\n", BackendList[n].name);
|
||||
continue;
|
||||
}
|
||||
|
||||
TRACE("Initialized backend \"%s\"\n", BackendList[n].name);
|
||||
if(!PlaybackBackend.name && V(factory,querySupport)(ALCbackend_Playback))
|
||||
if(!PlaybackBackend.name && factory.querySupport(ALCbackend_Playback))
|
||||
{
|
||||
PlaybackBackend = BackendList[n];
|
||||
TRACE("Added \"%s\" for playback\n", PlaybackBackend.name);
|
||||
}
|
||||
if(!CaptureBackend.name && V(factory,querySupport)(ALCbackend_Capture))
|
||||
if(!CaptureBackend.name && factory.querySupport(ALCbackend_Capture))
|
||||
{
|
||||
CaptureBackend = BackendList[n];
|
||||
TRACE("Added \"%s\" for capture\n", CaptureBackend.name);
|
||||
@@ -1212,10 +1215,8 @@ static void alc_deinit(void)
|
||||
memset(&CaptureBackend, 0, sizeof(CaptureBackend));
|
||||
|
||||
for(i = 0;i < BackendListSize;i++)
|
||||
{
|
||||
ALCbackendFactory *factory = BackendList[i].getFactory();
|
||||
V0(factory,deinit)();
|
||||
}
|
||||
BackendList[i].getFactory().deinit();
|
||||
|
||||
{
|
||||
ALCbackendFactory *factory = ALCloopbackFactory_getFactory();
|
||||
V0(factory,deinit)();
|
||||
@@ -1235,10 +1236,7 @@ static void ProbeDevices(std::string *list, struct BackendInfo *backendinfo, enu
|
||||
std::lock_guard<std::recursive_mutex> _{ListLock};
|
||||
list->clear();
|
||||
if(backendinfo->getFactory)
|
||||
{
|
||||
ALCbackendFactory *factory = backendinfo->getFactory();
|
||||
V(factory,probe)(type, list);
|
||||
}
|
||||
backendinfo->getFactory().probe(type, list);
|
||||
}
|
||||
static void ProbeAllDevicesList(void)
|
||||
{ ProbeDevices(&alcAllDevicesList, &PlaybackBackend, ALL_DEVICE_PROBE); }
|
||||
@@ -3971,7 +3969,6 @@ ALC_API ALCdevice* ALC_APIENTRY alcGetContextsDevice(ALCcontext *Context)
|
||||
*/
|
||||
ALC_API ALCdevice* ALC_APIENTRY alcOpenDevice(const ALCchar *deviceName)
|
||||
{
|
||||
ALCbackendFactory *factory;
|
||||
const ALCchar *fmt;
|
||||
ALCdevice *device;
|
||||
ALCenum err;
|
||||
@@ -4114,8 +4111,7 @@ ALC_API ALCdevice* ALC_APIENTRY alcOpenDevice(const ALCchar *deviceName)
|
||||
device->NumStereoSources = 1;
|
||||
device->NumMonoSources = device->SourcesMax - device->NumStereoSources;
|
||||
|
||||
factory = PlaybackBackend.getFactory();
|
||||
device->Backend = V(factory,createBackend)(device, ALCbackend_Playback);
|
||||
device->Backend = PlaybackBackend.getFactory().createBackend(device, ALCbackend_Playback);
|
||||
if(!device->Backend)
|
||||
{
|
||||
FreeDevice(device);
|
||||
@@ -4219,7 +4215,6 @@ ALC_API ALCboolean ALC_APIENTRY alcCloseDevice(ALCdevice *device)
|
||||
************************************************/
|
||||
ALC_API ALCdevice* ALC_APIENTRY alcCaptureOpenDevice(const ALCchar *deviceName, ALCuint frequency, ALCenum format, ALCsizei samples)
|
||||
{
|
||||
ALCbackendFactory *factory;
|
||||
ALCdevice *device = nullptr;
|
||||
ALCenum err;
|
||||
|
||||
@@ -4268,8 +4263,7 @@ ALC_API ALCdevice* ALC_APIENTRY alcCaptureOpenDevice(const ALCchar *deviceName,
|
||||
device->UpdateSize = samples;
|
||||
device->NumUpdates = 1;
|
||||
|
||||
factory = CaptureBackend.getFactory();
|
||||
device->Backend = V(factory,createBackend)(device, ALCbackend_Capture);
|
||||
device->Backend = CaptureBackend.getFactory().createBackend(device, ALCbackend_Capture);
|
||||
if(!device->Backend)
|
||||
{
|
||||
FreeDevice(device);
|
||||
@@ -4409,9 +4403,6 @@ ALC_API void ALC_APIENTRY alcCaptureSamples(ALCdevice *device, ALCvoid *buffer,
|
||||
*/
|
||||
ALC_API ALCdevice* ALC_APIENTRY alcLoopbackOpenDeviceSOFT(const ALCchar *deviceName)
|
||||
{
|
||||
ALCbackendFactory *factory;
|
||||
ALCdevice *device;
|
||||
|
||||
DO_INITCONFIG();
|
||||
|
||||
/* Make sure the device name, if specified, is us. */
|
||||
@@ -4421,7 +4412,7 @@ ALC_API ALCdevice* ALC_APIENTRY alcLoopbackOpenDeviceSOFT(const ALCchar *deviceN
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
device = static_cast<ALCdevice*>(al_calloc(16, sizeof(ALCdevice)));
|
||||
ALCdevice *device{static_cast<ALCdevice*>(al_calloc(16, sizeof(ALCdevice)))};
|
||||
if(!device)
|
||||
{
|
||||
alcSetError(nullptr, ALC_OUT_OF_MEMORY);
|
||||
@@ -4461,7 +4452,7 @@ ALC_API ALCdevice* ALC_APIENTRY alcLoopbackOpenDeviceSOFT(const ALCchar *deviceN
|
||||
device->NumStereoSources = 1;
|
||||
device->NumMonoSources = device->SourcesMax - device->NumStereoSources;
|
||||
|
||||
factory = ALCloopbackFactory_getFactory();
|
||||
ALCbackendFactory *factory = ALCloopbackFactory_getFactory();
|
||||
device->Backend = V(factory,createBackend)(device, ALCbackend_Loopback);
|
||||
if(!device->Backend)
|
||||
{
|
||||
|
||||
+13
-1
@@ -153,10 +153,22 @@ ALCbackendFactory *ALCdsoundBackendFactory_getFactory(void);
|
||||
ALCbackendFactory *ALCwinmmBackendFactory_getFactory(void);
|
||||
ALCbackendFactory *ALCportBackendFactory_getFactory(void);
|
||||
ALCbackendFactory *ALCopenslBackendFactory_getFactory(void);
|
||||
ALCbackendFactory *ALCnullBackendFactory_getFactory(void);
|
||||
ALCbackendFactory *ALCwaveBackendFactory_getFactory(void);
|
||||
ALCbackendFactory *ALCsdl2BackendFactory_getFactory(void);
|
||||
ALCbackendFactory *ALCloopbackFactory_getFactory(void);
|
||||
|
||||
|
||||
struct BackendFactory {
|
||||
virtual bool init() = 0;
|
||||
virtual void deinit() { }
|
||||
|
||||
virtual bool querySupport(ALCbackend_Type type) = 0;
|
||||
|
||||
virtual void probe(enum DevProbe type, std::string *outnames) = 0;
|
||||
|
||||
virtual ALCbackend *createBackend(ALCdevice *device, ALCbackend_Type type) = 0;
|
||||
};
|
||||
|
||||
|
||||
#endif /* __cplusplus */
|
||||
#endif /* AL_BACKENDS_BASE_H */
|
||||
|
||||
+35
-54
@@ -20,6 +20,8 @@
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "backends/null.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#ifdef HAVE_WINDOWS_H
|
||||
#include <windows.h>
|
||||
@@ -32,8 +34,6 @@
|
||||
#include "alu.h"
|
||||
#include "compat.h"
|
||||
|
||||
#include "backends/base.h"
|
||||
|
||||
|
||||
namespace {
|
||||
|
||||
@@ -43,32 +43,31 @@ using std::chrono::nanoseconds;
|
||||
|
||||
constexpr ALCchar nullDevice[] = "No Output";
|
||||
|
||||
} // namespace
|
||||
|
||||
struct ALCnullBackend final : public ALCbackend {
|
||||
ATOMIC(int) killNow;
|
||||
std::thread thread;
|
||||
};
|
||||
|
||||
static int ALCnullBackend_mixerProc(ALCnullBackend *self);
|
||||
int ALCnullBackend_mixerProc(ALCnullBackend *self);
|
||||
|
||||
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)
|
||||
void ALCnullBackend_Construct(ALCnullBackend *self, ALCdevice *device);
|
||||
void ALCnullBackend_Destruct(ALCnullBackend *self);
|
||||
ALCenum ALCnullBackend_open(ALCnullBackend *self, const ALCchar *name);
|
||||
ALCboolean ALCnullBackend_reset(ALCnullBackend *self);
|
||||
ALCboolean ALCnullBackend_start(ALCnullBackend *self);
|
||||
void ALCnullBackend_stop(ALCnullBackend *self);
|
||||
DECLARE_FORWARD2(ALCnullBackend, ALCbackend, ALCenum, captureSamples, void*, ALCuint)
|
||||
DECLARE_FORWARD(ALCnullBackend, ALCbackend, ALCuint, availableSamples)
|
||||
DECLARE_FORWARD(ALCnullBackend, ALCbackend, ClockLatency, getClockLatency)
|
||||
DECLARE_FORWARD(ALCnullBackend, ALCbackend, void, lock)
|
||||
DECLARE_FORWARD(ALCnullBackend, ALCbackend, void, unlock)
|
||||
DECLARE_DEFAULT_ALLOCATORS(ALCnullBackend)
|
||||
|
||||
DEFINE_ALCBACKEND_VTABLE(ALCnullBackend);
|
||||
|
||||
|
||||
static void ALCnullBackend_Construct(ALCnullBackend *self, ALCdevice *device)
|
||||
void ALCnullBackend_Construct(ALCnullBackend *self, ALCdevice *device)
|
||||
{
|
||||
new (self) ALCnullBackend{};
|
||||
ALCbackend_Construct(STATIC_CAST(ALCbackend, self), device);
|
||||
@@ -77,14 +76,14 @@ static void ALCnullBackend_Construct(ALCnullBackend *self, ALCdevice *device)
|
||||
ATOMIC_INIT(&self->killNow, AL_TRUE);
|
||||
}
|
||||
|
||||
static void ALCnullBackend_Destruct(ALCnullBackend *self)
|
||||
void ALCnullBackend_Destruct(ALCnullBackend *self)
|
||||
{
|
||||
ALCbackend_Destruct(STATIC_CAST(ALCbackend, self));
|
||||
self->~ALCnullBackend();
|
||||
}
|
||||
|
||||
|
||||
static int ALCnullBackend_mixerProc(ALCnullBackend *self)
|
||||
int ALCnullBackend_mixerProc(ALCnullBackend *self)
|
||||
{
|
||||
ALCdevice *device = STATIC_CAST(ALCbackend, self)->mDevice;
|
||||
const milliseconds restTime{device->UpdateSize*1000/device->Frequency / 2};
|
||||
@@ -131,7 +130,7 @@ static int ALCnullBackend_mixerProc(ALCnullBackend *self)
|
||||
}
|
||||
|
||||
|
||||
static ALCenum ALCnullBackend_open(ALCnullBackend *self, const ALCchar *name)
|
||||
ALCenum ALCnullBackend_open(ALCnullBackend *self, const ALCchar *name)
|
||||
{
|
||||
ALCdevice *device;
|
||||
|
||||
@@ -147,13 +146,13 @@ static ALCenum ALCnullBackend_open(ALCnullBackend *self, const ALCchar *name)
|
||||
return ALC_NO_ERROR;
|
||||
}
|
||||
|
||||
static ALCboolean ALCnullBackend_reset(ALCnullBackend *self)
|
||||
ALCboolean ALCnullBackend_reset(ALCnullBackend *self)
|
||||
{
|
||||
SetDefaultWFXChannelOrder(STATIC_CAST(ALCbackend, self)->mDevice);
|
||||
return ALC_TRUE;
|
||||
}
|
||||
|
||||
static ALCboolean ALCnullBackend_start(ALCnullBackend *self)
|
||||
ALCboolean ALCnullBackend_start(ALCnullBackend *self)
|
||||
{
|
||||
try {
|
||||
ATOMIC_STORE(&self->killNow, AL_FALSE, almemory_order_release);
|
||||
@@ -168,7 +167,7 @@ static ALCboolean ALCnullBackend_start(ALCnullBackend *self)
|
||||
return ALC_FALSE;
|
||||
}
|
||||
|
||||
static void ALCnullBackend_stop(ALCnullBackend *self)
|
||||
void ALCnullBackend_stop(ALCnullBackend *self)
|
||||
{
|
||||
if(ATOMIC_EXCHANGE(&self->killNow, AL_TRUE, almemory_order_acq_rel) ||
|
||||
!self->thread.joinable())
|
||||
@@ -176,46 +175,22 @@ static void ALCnullBackend_stop(ALCnullBackend *self)
|
||||
self->thread.join();
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
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, std::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)}
|
||||
bool NullBackendFactory::init()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
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)
|
||||
bool NullBackendFactory::querySupport(ALCbackend_Type type)
|
||||
{
|
||||
if(type == ALCbackend_Playback)
|
||||
return ALC_TRUE;
|
||||
return ALC_FALSE;
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
static void ALCnullBackendFactory_probe(ALCnullBackendFactory* UNUSED(self), enum DevProbe type, std::string *outnames)
|
||||
void NullBackendFactory::probe(enum DevProbe type, std::string *outnames)
|
||||
{
|
||||
switch(type)
|
||||
{
|
||||
@@ -228,7 +203,7 @@ static void ALCnullBackendFactory_probe(ALCnullBackendFactory* UNUSED(self), enu
|
||||
}
|
||||
}
|
||||
|
||||
static ALCbackend* ALCnullBackendFactory_createBackend(ALCnullBackendFactory* UNUSED(self), ALCdevice *device, ALCbackend_Type type)
|
||||
ALCbackend *NullBackendFactory::createBackend(ALCdevice *device, ALCbackend_Type type)
|
||||
{
|
||||
if(type == ALCbackend_Playback)
|
||||
{
|
||||
@@ -240,3 +215,9 @@ static ALCbackend* ALCnullBackendFactory_createBackend(ALCnullBackendFactory* UN
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
BackendFactory &NullBackendFactory::getFactory()
|
||||
{
|
||||
static NullBackendFactory factory{};
|
||||
return factory;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
#ifndef BACKENDS_NULL_H
|
||||
#define BACKENDS_NULL_H
|
||||
|
||||
#include "backends/base.h"
|
||||
|
||||
struct NullBackendFactory final : public BackendFactory {
|
||||
public:
|
||||
bool init() override;
|
||||
/*void deinit() override;*/
|
||||
|
||||
bool querySupport(ALCbackend_Type type) override;
|
||||
|
||||
void probe(enum DevProbe type, std::string *outnames) override;
|
||||
|
||||
ALCbackend *createBackend(ALCdevice *device, ALCbackend_Type type) override;
|
||||
|
||||
static BackendFactory &getFactory();
|
||||
};
|
||||
|
||||
#endif /* BACKENDS_NULL_H */
|
||||
@@ -992,6 +992,7 @@ SET(ALC_OBJS ${ALC_OBJS}
|
||||
# Default backends, always available
|
||||
Alc/backends/loopback.cpp
|
||||
Alc/backends/null.cpp
|
||||
Alc/backends/null.h
|
||||
)
|
||||
|
||||
# Check ALSA backend
|
||||
|
||||
Reference in New Issue
Block a user