aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Alc/ALc.c18
-rw-r--r--Alc/backends/base.h6
-rw-r--r--Alc/backends/loopback.c120
-rw-r--r--OpenAL32/Include/alMain.h3
4 files changed, 109 insertions, 38 deletions
diff --git a/Alc/ALc.c b/Alc/ALc.c
index efbc4be5..266134c9 100644
--- a/Alc/ALc.c
+++ b/Alc/ALc.c
@@ -99,9 +99,6 @@ static struct BackendInfo BackendList[] = {
{ NULL, NULL, NULL, NULL, NULL, EmptyFuncs }
};
-static struct BackendInfo BackendLoopback = {
- "loopback", NULL, alc_loopback_init, alc_loopback_deinit, alc_loopback_probe, EmptyFuncs
-};
#undef EmptyFuncs
static struct BackendInfo PlaybackBackend;
@@ -1063,7 +1060,10 @@ static void alc_initconfig(void)
TRACE("Added \"%s\" for capture\n", CaptureBackend.name);
}
}
- BackendLoopback.Init(&BackendLoopback.Funcs);
+ {
+ ALCbackendFactory *factory = ALCloopbackFactory_getFactory();
+ VCALL0(factory,init)();
+ }
if(ConfigValueStr(NULL, "excludefx", &str))
{
@@ -1161,7 +1161,10 @@ static void alc_deinit(void)
VCALL0(factory,deinit)();
}
}
- BackendLoopback.Deinit();
+ {
+ ALCbackendFactory *factory = ALCloopbackFactory_getFactory();
+ VCALL0(factory,deinit)();
+ }
alc_deinit_safe();
}
@@ -3284,6 +3287,7 @@ 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();
@@ -3303,7 +3307,6 @@ ALC_API ALCdevice* ALC_APIENTRY alcLoopbackOpenDeviceSOFT(const ALCchar *deviceN
}
//Validate device
- device->Funcs = &BackendLoopback.Funcs;
device->ref = 1;
device->Connected = ALC_TRUE;
device->Type = Loopback;
@@ -3324,7 +3327,8 @@ ALC_API ALCdevice* ALC_APIENTRY alcLoopbackOpenDeviceSOFT(const ALCchar *deviceN
InitUIntMap(&device->EffectMap, ~0);
InitUIntMap(&device->FilterMap, ~0);
- device->Backend = create_backend_wrapper(device, ALCbackend_Playback);
+ factory = ALCloopbackFactory_getFactory();
+ device->Backend = VCALL(factory,createBackend)(device, ALCbackend_Playback);
if(!device->Backend)
{
al_free(device);
diff --git a/Alc/backends/base.h b/Alc/backends/base.h
index 90c4d30f..a8917bec 100644
--- a/Alc/backends/base.h
+++ b/Alc/backends/base.h
@@ -42,6 +42,9 @@ struct ALCbackendVtable {
void (*const Delete)(ALCbackend*);
};
+#define DECLARE_ALCBACKEND_VTABLE(T) \
+static const struct ALCbackendVtable T##_ALCbackend_vtable
+
#define DEFINE_ALCBACKEND_VTABLE(T) \
static void T##_ALCbackend_Destruct(ALCbackend *obj) \
{ T##_Destruct(STATIC_UPCAST(T, ALCbackend, obj)); } \
@@ -68,7 +71,7 @@ static void T##_ALCbackend_unlock(ALCbackend *obj) \
static void T##_ALCbackend_Delete(ALCbackend *obj) \
{ T##_Delete(STATIC_UPCAST(T, ALCbackend, obj)); } \
\
-static const struct ALCbackendVtable T##_ALCbackend_vtable = { \
+DECLARE_ALCBACKEND_VTABLE(T) = { \
T##_ALCbackend_Destruct, \
\
T##_ALCbackend_open, \
@@ -132,6 +135,7 @@ static const struct ALCbackendFactoryVtable T##_ALCbackendFactory_vtable = { \
ALCbackendFactory *ALCalsaBackendFactory_getFactory(void);
ALCbackendFactory *ALCnullBackendFactory_getFactory(void);
+ALCbackendFactory *ALCloopbackFactory_getFactory(void);
ALCbackend *create_backend_wrapper(ALCdevice *device, ALCbackend_Type type);
diff --git a/Alc/backends/loopback.c b/Alc/backends/loopback.c
index 067e23d1..bb5dd503 100644
--- a/Alc/backends/loopback.c
+++ b/Alc/backends/loopback.c
@@ -25,60 +25,126 @@
#include "alMain.h"
#include "alu.h"
+#include "backends/base.h"
-static ALCenum loopback_open_playback(ALCdevice *device, const ALCchar *deviceName)
+
+typedef struct ALCloopback {
+ DERIVE_FROM_TYPE(ALCbackend);
+} ALCloopback;
+DECLARE_ALCBACKEND_VTABLE(ALCloopback);
+
+#define ALCNULLBACKEND_INITIALIZER { { GET_VTABLE2(ALCbackend, ALCloopback) } }
+
+
+static void ALCloopback_Construct(ALCloopback *self, ALCdevice *device)
+{
+ ALCbackend_Construct(STATIC_CAST(ALCbackend, self), device);
+ SET_VTABLE2(ALCloopback, ALCbackend, self);
+}
+
+static void ALCloopback_Destruct(ALCloopback *self)
+{
+ ALCbackend_Destruct(STATIC_CAST(ALCbackend, self));
+}
+
+static ALCenum ALCloopback_open(ALCloopback *self, const ALCchar *name)
{
- device->DeviceName = strdup(deviceName);
+ ALCdevice *device = STATIC_CAST(ALCbackend, self)->mDevice;
+
+ device->DeviceName = strdup(name);
return ALC_NO_ERROR;
}
-static void loopback_close_playback(ALCdevice *UNUSED(device))
+static void ALCloopback_close(ALCloopback* UNUSED(self))
{
}
-static ALCboolean loopback_reset_playback(ALCdevice *device)
+static ALCboolean ALCloopback_reset(ALCloopback *self)
{
- SetDefaultWFXChannelOrder(device);
+ SetDefaultWFXChannelOrder(STATIC_CAST(ALCbackend, self)->mDevice);
return ALC_TRUE;
}
-static ALCboolean loopback_start_playback(ALCdevice *UNUSED(device))
+static ALCboolean ALCloopback_start(ALCloopback* UNUSED(self))
{
return ALC_TRUE;
}
-static void loopback_stop_playback(ALCdevice *UNUSED(device))
+static void ALCloopback_stop(ALCloopback* UNUSED(self))
+{
+}
+
+ALCenum ALCloopback_captureSamples(ALCloopback* UNUSED(self), void* UNUSED(buffer), ALCuint UNUSED(samples))
+{
+ return ALC_INVALID_VALUE;
+}
+
+ALCuint ALCloopback_availableSamples(ALCloopback* UNUSED(self))
{
+ return 0;
}
+static ALint64 ALCloopback_getLatency(ALCloopback *self)
+{ return ALCbackend_getLatency(STATIC_CAST(ALCbackend, self)); }
+
+static void ALCloopback_lock(ALCloopback *self)
+{ ALCbackend_lock(STATIC_CAST(ALCbackend, self)); }
-static const BackendFuncs loopback_funcs = {
- loopback_open_playback,
- loopback_close_playback,
- loopback_reset_playback,
- loopback_start_playback,
- loopback_stop_playback,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- ALCdevice_LockDefault,
- ALCdevice_UnlockDefault,
- ALCdevice_GetLatencyDefault
-};
+static void ALCloopback_unlock(ALCloopback *self)
+{ ALCbackend_unlock(STATIC_CAST(ALCbackend, self)); }
-ALCboolean alc_loopback_init(BackendFuncs *func_list)
+static void ALCloopback_Delete(ALCloopback *self)
+{
+ free(self);
+}
+
+DEFINE_ALCBACKEND_VTABLE(ALCloopback);
+
+
+typedef struct ALCloopbackFactory {
+ DERIVE_FROM_TYPE(ALCbackendFactory);
+} ALCloopbackFactory;
+#define ALCNULLBACKENDFACTORY_INITIALIZER { { GET_VTABLE2(ALCloopbackFactory, ALCbackendFactory) } }
+
+ALCboolean ALCloopbackFactory_init(ALCloopbackFactory* UNUSED(self))
{
- *func_list = loopback_funcs;
return ALC_TRUE;
}
-void alc_loopback_deinit(void)
+void ALCloopbackFactory_deinit(ALCloopbackFactory* UNUSED(self))
+{
+}
+
+ALCboolean ALCloopbackFactory_querySupport(ALCloopbackFactory* UNUSED(self), ALCbackend_Type type)
+{
+ if(type == ALCbackend_Playback)
+ return ALC_TRUE;
+ return ALC_FALSE;
+}
+
+void ALCloopbackFactory_probe(ALCloopbackFactory* UNUSED(self), enum DevProbe UNUSED(type))
{
}
-void alc_loopback_probe(enum DevProbe UNUSED(type))
+ALCbackend* ALCloopbackFactory_createBackend(ALCloopbackFactory* UNUSED(self), ALCdevice *device, ALCbackend_Type type)
+{
+ ALCloopback *backend;
+
+ assert(type == ALCbackend_Playback);
+
+ backend = calloc(1, sizeof(*backend));
+ if(!backend) return NULL;
+
+ ALCloopback_Construct(backend, device);
+
+ return STATIC_CAST(ALCbackend, backend);
+}
+
+DEFINE_ALCBACKENDFACTORY_VTABLE(ALCloopbackFactory);
+
+
+ALCbackendFactory *ALCloopbackFactory_getFactory(void)
{
+ static ALCloopbackFactory factory = ALCNULLBACKENDFACTORY_INITIALIZER;
+ return STATIC_CAST(ALCbackendFactory, &factory);
}
diff --git a/OpenAL32/Include/alMain.h b/OpenAL32/Include/alMain.h
index 685536b5..a8175ce7 100644
--- a/OpenAL32/Include/alMain.h
+++ b/OpenAL32/Include/alMain.h
@@ -232,9 +232,6 @@ void alc_opensl_probe(enum DevProbe type);
ALCboolean alc_qsa_init(BackendFuncs *func_list);
void alc_qsa_deinit(void);
void alc_qsa_probe(enum DevProbe type);
-ALCboolean alc_loopback_init(BackendFuncs *func_list);
-void alc_loopback_deinit(void);
-void alc_loopback_probe(enum DevProbe type);
struct ALCbackend;