aboutsummaryrefslogtreecommitdiffstats
path: root/Alc
diff options
context:
space:
mode:
Diffstat (limited to 'Alc')
-rw-r--r--Alc/ALc.c2
-rw-r--r--Alc/backends/base.c6
-rw-r--r--Alc/backends/base.h5
-rw-r--r--Alc/backends/oss.c454
4 files changed, 287 insertions, 180 deletions
diff --git a/Alc/ALc.c b/Alc/ALc.c
index f86d1d5d..67127cec 100644
--- a/Alc/ALc.c
+++ b/Alc/ALc.c
@@ -65,7 +65,7 @@ static struct BackendInfo BackendList[] = {
{ "core", NULL, alc_ca_init, alc_ca_deinit, alc_ca_probe, EmptyFuncs },
#endif
#ifdef HAVE_OSS
- { "oss", NULL, alc_oss_init, alc_oss_deinit, alc_oss_probe, EmptyFuncs },
+ { "oss", ALCossBackendFactory_getFactory, NULL, NULL, NULL, EmptyFuncs },
#endif
#ifdef HAVE_SOLARIS
{ "solaris", NULL, alc_solaris_init, alc_solaris_deinit, alc_solaris_probe, EmptyFuncs },
diff --git a/Alc/backends/base.c b/Alc/backends/base.c
index 0c285993..d32cf417 100644
--- a/Alc/backends/base.c
+++ b/Alc/backends/base.c
@@ -51,6 +51,12 @@ void ALCbackend_unlock(ALCbackend *self)
}
+/* Base ALCbackendFactory method implementations. */
+void ALCbackendFactory_deinit(ALCbackendFactory* UNUSED(self))
+{
+}
+
+
/* Wrappers to use an old-style backend with the new interface. */
typedef struct PlaybackWrapper {
DERIVE_FROM_TYPE(ALCbackend);
diff --git a/Alc/backends/base.h b/Alc/backends/base.h
index 59e01304..636e79e5 100644
--- a/Alc/backends/base.h
+++ b/Alc/backends/base.h
@@ -92,6 +92,8 @@ typedef struct ALCbackendFactory {
const struct ALCbackendFactoryVtable *vtbl;
} ALCbackendFactory;
+void ALCbackendFactory_deinit(ALCbackendFactory *self);
+
struct ALCbackendFactoryVtable {
ALCboolean (*const init)(ALCbackendFactory *self);
void (*const deinit)(ALCbackendFactory *self);
@@ -119,8 +121,9 @@ static const struct ALCbackendFactoryVtable T##_ALCbackendFactory_vtable = { \
}
-ALCbackendFactory *ALCalsaBackendFactory_getFactory(void);
ALCbackendFactory *ALCpulseBackendFactory_getFactory(void);
+ALCbackendFactory *ALCalsaBackendFactory_getFactory(void);
+ALCbackendFactory *ALCossBackendFactory_getFactory(void);
ALCbackendFactory *ALCnullBackendFactory_getFactory(void);
ALCbackendFactory *ALCloopbackFactory_getFactory(void);
diff --git a/Alc/backends/oss.c b/Alc/backends/oss.c
index a9510a35..3d7de113 100644
--- a/Alc/backends/oss.c
+++ b/Alc/backends/oss.c
@@ -36,6 +36,8 @@
#include "threads.h"
#include "compat.h"
+#include "backends/base.h"
+
#include <sys/soundcard.h>
/*
@@ -49,25 +51,12 @@
#define SOUND_MIXER_WRITE MIXER_WRITE
#endif
+
static const ALCchar oss_device[] = "OSS Default";
static const char *oss_driver = "/dev/dsp";
static const char *oss_capture = "/dev/dsp";
-typedef struct {
- int fd;
-
- ALubyte *mix_data;
- int data_size;
-
- RingBuffer *ring;
- int doCapture;
-
- volatile int killNow;
- althread_t thread;
-} oss_data;
-
-
static int log2i(ALCuint x)
{
int y = 0;
@@ -80,35 +69,65 @@ static int log2i(ALCuint x)
}
-static ALuint OSSProc(ALvoid *ptr)
+typedef struct ALCplaybackOSS {
+ DERIVE_FROM_TYPE(ALCbackend);
+
+ int fd;
+
+ ALubyte *mix_data;
+ int data_size;
+
+ volatile int killNow;
+ althread_t thread;
+} ALCplaybackOSS;
+
+static ALuint ALCplaybackOSS_mixerProc(ALvoid *ptr);
+
+static void ALCplaybackOSS_Construct(ALCplaybackOSS *self, ALCdevice *device);
+static DECLARE_FORWARD(ALCplaybackOSS, ALCbackend, void, Destruct)
+static ALCenum ALCplaybackOSS_open(ALCplaybackOSS *self, const ALCchar *name);
+static void ALCplaybackOSS_close(ALCplaybackOSS *self);
+static ALCboolean ALCplaybackOSS_reset(ALCplaybackOSS *self);
+static ALCboolean ALCplaybackOSS_start(ALCplaybackOSS *self);
+static void ALCplaybackOSS_stop(ALCplaybackOSS *self);
+static DECLARE_FORWARD2(ALCplaybackOSS, ALCbackend, ALCenum, captureSamples, ALCvoid*, ALCuint)
+static DECLARE_FORWARD(ALCplaybackOSS, ALCbackend, ALCuint, availableSamples)
+static DECLARE_FORWARD(ALCplaybackOSS, ALCbackend, ALint64, getLatency)
+static DECLARE_FORWARD(ALCplaybackOSS, ALCbackend, void, lock)
+static DECLARE_FORWARD(ALCplaybackOSS, ALCbackend, void, unlock)
+static void ALCplaybackOSS_Delete(ALCplaybackOSS *self);
+DEFINE_ALCBACKEND_VTABLE(ALCplaybackOSS);
+
+
+static ALuint ALCplaybackOSS_mixerProc(ALvoid *ptr)
{
- ALCdevice *Device = (ALCdevice*)ptr;
- oss_data *data = (oss_data*)Device->ExtraData;
+ ALCplaybackOSS *self = (ALCplaybackOSS*)ptr;
+ ALCdevice *device = STATIC_CAST(ALCbackend, self)->mDevice;
ALint frameSize;
ssize_t wrote;
SetRTPriority();
SetThreadName(MIXER_THREAD_NAME);
- frameSize = FrameSizeFromDevFmt(Device->FmtChans, Device->FmtType);
+ frameSize = FrameSizeFromDevFmt(device->FmtChans, device->FmtType);
- while(!data->killNow && Device->Connected)
+ while(!self->killNow && device->Connected)
{
- ALint len = data->data_size;
- ALubyte *WritePtr = data->mix_data;
+ ALint len = self->data_size;
+ ALubyte *WritePtr = self->mix_data;
- aluMixData(Device, WritePtr, len/frameSize);
- while(len > 0 && !data->killNow)
+ aluMixData(device, WritePtr, len/frameSize);
+ while(len > 0 && !self->killNow)
{
- wrote = write(data->fd, WritePtr, len);
+ wrote = write(self->fd, WritePtr, len);
if(wrote < 0)
{
if(errno != EAGAIN && errno != EWOULDBLOCK && errno != EINTR)
{
ERR("write failed: %s\n", strerror(errno));
- ALCdevice_Lock(Device);
- aluHandleDisconnect(Device);
- ALCdevice_Unlock(Device);
+ ALCplaybackOSS_lock(self);
+ aluHandleDisconnect(device);
+ ALCplaybackOSS_unlock(self);
break;
}
@@ -124,78 +143,45 @@ static ALuint OSSProc(ALvoid *ptr)
return 0;
}
-static ALuint OSSCaptureProc(ALvoid *ptr)
-{
- ALCdevice *Device = (ALCdevice*)ptr;
- oss_data *data = (oss_data*)Device->ExtraData;
- int frameSize;
- int amt;
- SetRTPriority();
- SetThreadName("alsoft-record");
-
- frameSize = FrameSizeFromDevFmt(Device->FmtChans, Device->FmtType);
-
- while(!data->killNow)
- {
- amt = read(data->fd, data->mix_data, data->data_size);
- if(amt < 0)
- {
- ERR("read failed: %s\n", strerror(errno));
- ALCdevice_Lock(Device);
- aluHandleDisconnect(Device);
- ALCdevice_Unlock(Device);
- break;
- }
- if(amt == 0)
- {
- Sleep(1);
- continue;
- }
- if(data->doCapture)
- WriteRingBuffer(data->ring, data->mix_data, amt/frameSize);
- }
-
- return 0;
+static void ALCplaybackOSS_Construct(ALCplaybackOSS *self, ALCdevice *device)
+{
+ ALCbackend_Construct(STATIC_CAST(ALCbackend, self), device);
+ SET_VTABLE2(ALCplaybackOSS, ALCbackend, self);
}
-static ALCenum oss_open_playback(ALCdevice *device, const ALCchar *deviceName)
+static ALCenum ALCplaybackOSS_open(ALCplaybackOSS *self, const ALCchar *name)
{
- oss_data *data;
+ ALCdevice *device = STATIC_CAST(ALCbackend, self)->mDevice;
- if(!deviceName)
- deviceName = oss_device;
- else if(strcmp(deviceName, oss_device) != 0)
+ if(!name)
+ name = oss_device;
+ else if(strcmp(name, oss_device) != 0)
return ALC_INVALID_VALUE;
- data = (oss_data*)calloc(1, sizeof(oss_data));
- data->killNow = 0;
+ self->killNow = 0;
- data->fd = open(oss_driver, O_WRONLY);
- if(data->fd == -1)
+ self->fd = open(oss_driver, O_WRONLY);
+ if(self->fd == -1)
{
- free(data);
ERR("Could not open %s: %s\n", oss_driver, strerror(errno));
return ALC_INVALID_VALUE;
}
- device->DeviceName = strdup(deviceName);
- device->ExtraData = data;
+ device->DeviceName = strdup(name);
+
return ALC_NO_ERROR;
}
-static void oss_close_playback(ALCdevice *device)
+static void ALCplaybackOSS_close(ALCplaybackOSS *self)
{
- oss_data *data = (oss_data*)device->ExtraData;
-
- close(data->fd);
- free(data);
- device->ExtraData = NULL;
+ close(self->fd);
+ self->fd = -1;
}
-static ALCboolean oss_reset_playback(ALCdevice *device)
+static ALCboolean ALCplaybackOSS_reset(ALCplaybackOSS *self)
{
- oss_data *data = (oss_data*)device->ExtraData;
+ ALCdevice *device = STATIC_CAST(ALCbackend, self)->mDevice;
int numFragmentsLogSize;
int log2FragmentSize;
unsigned int periods;
@@ -246,11 +232,11 @@ static ALCboolean oss_reset_playback(ALCdevice *device)
}
/* Don't fail if SETFRAGMENT fails. We can handle just about anything
* that's reported back via GETOSPACE */
- ioctl(data->fd, SNDCTL_DSP_SETFRAGMENT, &numFragmentsLogSize);
- CHECKERR(ioctl(data->fd, SNDCTL_DSP_SETFMT, &ossFormat));
- CHECKERR(ioctl(data->fd, SNDCTL_DSP_CHANNELS, &numChannels));
- CHECKERR(ioctl(data->fd, SNDCTL_DSP_SPEED, &ossSpeed));
- CHECKERR(ioctl(data->fd, SNDCTL_DSP_GETOSPACE, &info));
+ ioctl(self->fd, SNDCTL_DSP_SETFRAGMENT, &numFragmentsLogSize);
+ CHECKERR(ioctl(self->fd, SNDCTL_DSP_SETFMT, &ossFormat));
+ CHECKERR(ioctl(self->fd, SNDCTL_DSP_CHANNELS, &numChannels));
+ CHECKERR(ioctl(self->fd, SNDCTL_DSP_SPEED, &ossSpeed));
+ CHECKERR(ioctl(self->fd, SNDCTL_DSP_GETOSPACE, &info));
if(0)
{
err:
@@ -282,68 +268,142 @@ static ALCboolean oss_reset_playback(ALCdevice *device)
return ALC_TRUE;
}
-static ALCboolean oss_start_playback(ALCdevice *device)
+static ALCboolean ALCplaybackOSS_start(ALCplaybackOSS *self)
{
- oss_data *data = (oss_data*)device->ExtraData;
+ ALCdevice *device = STATIC_CAST(ALCbackend, self)->mDevice;
- data->data_size = device->UpdateSize * FrameSizeFromDevFmt(device->FmtChans, device->FmtType);
- data->mix_data = calloc(1, data->data_size);
+ self->data_size = device->UpdateSize * FrameSizeFromDevFmt(device->FmtChans, device->FmtType);
+ self->mix_data = calloc(1, self->data_size);
- if(!StartThread(&data->thread, OSSProc, device))
+ if(!StartThread(&self->thread, ALCplaybackOSS_mixerProc, self))
{
- free(data->mix_data);
- data->mix_data = NULL;
+ free(self->mix_data);
+ self->mix_data = NULL;
return ALC_FALSE;
}
return ALC_TRUE;
}
-static void oss_stop_playback(ALCdevice *device)
+static void ALCplaybackOSS_stop(ALCplaybackOSS *self)
{
- oss_data *data = (oss_data*)device->ExtraData;
-
- if(!data->thread)
+ if(!self->thread)
return;
- data->killNow = 1;
- StopThread(data->thread);
- data->thread = NULL;
+ self->killNow = 1;
+ StopThread(self->thread);
+ self->thread = NULL;
- data->killNow = 0;
- if(ioctl(data->fd, SNDCTL_DSP_RESET) != 0)
+ self->killNow = 0;
+ if(ioctl(self->fd, SNDCTL_DSP_RESET) != 0)
ERR("Error resetting device: %s\n", strerror(errno));
- free(data->mix_data);
- data->mix_data = NULL;
+ free(self->mix_data);
+ self->mix_data = NULL;
}
+static void ALCplaybackOSS_Delete(ALCplaybackOSS *self)
+{
+ free(self);
+}
+
+
+typedef struct ALCcaptureOSS {
+ DERIVE_FROM_TYPE(ALCbackend);
+
+ int fd;
+
+ ALubyte *read_data;
+ int data_size;
-static ALCenum oss_open_capture(ALCdevice *device, const ALCchar *deviceName)
+ RingBuffer *ring;
+ int doCapture;
+
+ volatile int killNow;
+ althread_t thread;
+} ALCcaptureOSS;
+
+static ALuint ALCcaptureOSS_recordProc(ALvoid *ptr);
+
+static void ALCcaptureOSS_Construct(ALCcaptureOSS *self, ALCdevice *device);
+static DECLARE_FORWARD(ALCcaptureOSS, ALCbackend, void, Destruct)
+static ALCenum ALCcaptureOSS_open(ALCcaptureOSS *self, const ALCchar *name);
+static void ALCcaptureOSS_close(ALCcaptureOSS *self);
+static DECLARE_FORWARD(ALCcaptureOSS, ALCbackend, ALCboolean, reset)
+static ALCboolean ALCcaptureOSS_start(ALCcaptureOSS *self);
+static void ALCcaptureOSS_stop(ALCcaptureOSS *self);
+static ALCenum ALCcaptureOSS_captureSamples(ALCcaptureOSS *self, ALCvoid *buffer, ALCuint samples);
+static ALCuint ALCcaptureOSS_availableSamples(ALCcaptureOSS *self);
+static DECLARE_FORWARD(ALCcaptureOSS, ALCbackend, ALint64, getLatency)
+static DECLARE_FORWARD(ALCcaptureOSS, ALCbackend, void, lock)
+static DECLARE_FORWARD(ALCcaptureOSS, ALCbackend, void, unlock)
+static void ALCcaptureOSS_Delete(ALCcaptureOSS *self);
+DEFINE_ALCBACKEND_VTABLE(ALCcaptureOSS);
+
+
+static ALuint ALCcaptureOSS_recordProc(ALvoid *ptr)
+{
+ ALCcaptureOSS *self = (ALCcaptureOSS*)ptr;
+ ALCdevice *device = STATIC_CAST(ALCbackend, self)->mDevice;
+ int frameSize;
+ int amt;
+
+ SetRTPriority();
+ SetThreadName("alsoft-record");
+
+ frameSize = FrameSizeFromDevFmt(device->FmtChans, device->FmtType);
+
+ while(!self->killNow)
+ {
+ amt = read(self->fd, self->read_data, self->data_size);
+ if(amt < 0)
+ {
+ ERR("read failed: %s\n", strerror(errno));
+ ALCcaptureOSS_lock(self);
+ aluHandleDisconnect(device);
+ ALCcaptureOSS_unlock(self);
+ break;
+ }
+ if(amt == 0)
+ {
+ Sleep(1);
+ continue;
+ }
+ if(self->doCapture)
+ WriteRingBuffer(self->ring, self->read_data, amt/frameSize);
+ }
+
+ return 0;
+}
+
+
+static void ALCcaptureOSS_Construct(ALCcaptureOSS *self, ALCdevice *device)
+{
+ ALCbackend_Construct(STATIC_CAST(ALCbackend, self), device);
+ SET_VTABLE2(ALCcaptureOSS, ALCbackend, self);
+}
+
+static ALCenum ALCcaptureOSS_open(ALCcaptureOSS *self, const ALCchar *name)
{
+ ALCdevice *device = STATIC_CAST(ALCbackend, self)->mDevice;
int numFragmentsLogSize;
int log2FragmentSize;
unsigned int periods;
audio_buf_info info;
ALuint frameSize;
int numChannels;
- oss_data *data;
int ossFormat;
int ossSpeed;
char *err;
- if(!deviceName)
- deviceName = oss_device;
- else if(strcmp(deviceName, oss_device) != 0)
+ if(!name)
+ name = oss_device;
+ else if(strcmp(name, oss_device) != 0)
return ALC_INVALID_VALUE;
- data = (oss_data*)calloc(1, sizeof(oss_data));
- data->killNow = 0;
-
- data->fd = open(oss_capture, O_RDONLY);
- if(data->fd == -1)
+ self->fd = open(oss_capture, O_RDONLY);
+ if(self->fd == -1)
{
- free(data);
ERR("Could not open %s: %s\n", oss_capture, strerror(errno));
return ALC_INVALID_VALUE;
}
@@ -363,7 +423,6 @@ static ALCenum oss_open_capture(ALCdevice *device, const ALCchar *deviceName)
case DevFmtInt:
case DevFmtUInt:
case DevFmtFloat:
- free(data);
ERR("%s capture samples not supported\n", DevFmtTypeString(device->FmtType));
return ALC_INVALID_VALUE;
}
@@ -384,17 +443,17 @@ static ALCenum oss_open_capture(ALCdevice *device, const ALCchar *deviceName)
err = #func; \
goto err; \
}
- CHECKERR(ioctl(data->fd, SNDCTL_DSP_SETFRAGMENT, &numFragmentsLogSize));
- CHECKERR(ioctl(data->fd, SNDCTL_DSP_SETFMT, &ossFormat));
- CHECKERR(ioctl(data->fd, SNDCTL_DSP_CHANNELS, &numChannels));
- CHECKERR(ioctl(data->fd, SNDCTL_DSP_SPEED, &ossSpeed));
- CHECKERR(ioctl(data->fd, SNDCTL_DSP_GETISPACE, &info));
+ CHECKERR(ioctl(self->fd, SNDCTL_DSP_SETFRAGMENT, &numFragmentsLogSize));
+ CHECKERR(ioctl(self->fd, SNDCTL_DSP_SETFMT, &ossFormat));
+ CHECKERR(ioctl(self->fd, SNDCTL_DSP_CHANNELS, &numChannels));
+ CHECKERR(ioctl(self->fd, SNDCTL_DSP_SPEED, &ossSpeed));
+ CHECKERR(ioctl(self->fd, SNDCTL_DSP_GETISPACE, &info));
if(0)
{
err:
ERR("%s failed: %s\n", err, strerror(errno));
- close(data->fd);
- free(data);
+ close(self->fd);
+ self->fd = -1;
return ALC_INVALID_VALUE;
}
#undef CHECKERR
@@ -402,8 +461,8 @@ static ALCenum oss_open_capture(ALCdevice *device, const ALCchar *deviceName)
if((int)ChannelsFromDevFmt(device->FmtChans) != numChannels)
{
ERR("Failed to set %s, got %d channels instead\n", DevFmtChannelsString(device->FmtChans), numChannels);
- close(data->fd);
- free(data);
+ close(self->fd);
+ self->fd = -1;
return ALC_INVALID_VALUE;
}
@@ -412,108 +471,119 @@ static ALCenum oss_open_capture(ALCdevice *device, const ALCchar *deviceName)
(ossFormat == AFMT_S16_NE && device->FmtType == DevFmtShort)))
{
ERR("Failed to set %s samples, got OSS format %#x\n", DevFmtTypeString(device->FmtType), ossFormat);
- close(data->fd);
- free(data);
+ close(self->fd);
+ self->fd = -1;
return ALC_INVALID_VALUE;
}
- data->ring = CreateRingBuffer(frameSize, device->UpdateSize * device->NumUpdates);
- if(!data->ring)
+ self->ring = CreateRingBuffer(frameSize, device->UpdateSize * device->NumUpdates);
+ if(!self->ring)
{
ERR("Ring buffer create failed\n");
- close(data->fd);
- free(data);
+ close(self->fd);
+ self->fd = -1;
return ALC_OUT_OF_MEMORY;
}
- data->data_size = info.fragsize;
- data->mix_data = calloc(1, data->data_size);
+ self->data_size = info.fragsize;
+ self->read_data = calloc(1, self->data_size);
- device->ExtraData = data;
- if(!StartThread(&data->thread, OSSCaptureProc, device))
+ if(!StartThread(&self->thread, ALCcaptureOSS_recordProc, self))
{
device->ExtraData = NULL;
- free(data->mix_data);
- free(data);
+ close(self->fd);
+ self->fd = -1;
return ALC_OUT_OF_MEMORY;
}
- device->DeviceName = strdup(deviceName);
+ device->DeviceName = strdup(name);
+
return ALC_NO_ERROR;
}
-static void oss_close_capture(ALCdevice *device)
+static void ALCcaptureOSS_close(ALCcaptureOSS *self)
{
- oss_data *data = (oss_data*)device->ExtraData;
- data->killNow = 1;
- StopThread(data->thread);
+ self->killNow = 1;
+ StopThread(self->thread);
+ self->killNow = 0;
- close(data->fd);
+ close(self->fd);
+ self->fd = -1;
- DestroyRingBuffer(data->ring);
+ DestroyRingBuffer(self->ring);
+ self->ring = NULL;
- free(data->mix_data);
- free(data);
- device->ExtraData = NULL;
+ free(self->read_data);
+ self->read_data = NULL;
}
-static void oss_start_capture(ALCdevice *Device)
+static ALCboolean ALCcaptureOSS_start(ALCcaptureOSS *self)
{
- oss_data *data = (oss_data*)Device->ExtraData;
- data->doCapture = 1;
+ self->doCapture = 1;
+ return ALC_TRUE;
}
-static void oss_stop_capture(ALCdevice *Device)
+static void ALCcaptureOSS_stop(ALCcaptureOSS *self)
{
- oss_data *data = (oss_data*)Device->ExtraData;
- data->doCapture = 0;
+ self->doCapture = 0;
}
-static ALCenum oss_capture_samples(ALCdevice *Device, ALCvoid *pBuffer, ALCuint lSamples)
+static ALCenum ALCcaptureOSS_captureSamples(ALCcaptureOSS *self, ALCvoid *buffer, ALCuint samples)
{
- oss_data *data = (oss_data*)Device->ExtraData;
- ReadRingBuffer(data->ring, pBuffer, lSamples);
+ ReadRingBuffer(self->ring, buffer, samples);
return ALC_NO_ERROR;
}
-static ALCuint oss_available_samples(ALCdevice *Device)
+static ALCuint ALCcaptureOSS_availableSamples(ALCcaptureOSS *self)
+{
+ return RingBufferSize(self->ring);
+}
+
+void ALCcaptureOSS_Delete(ALCcaptureOSS *self)
+{
+ free(self);
+}
+
+
+
+typedef struct ALCossBackendFactory {
+ DERIVE_FROM_TYPE(ALCbackendFactory);
+} ALCossBackendFactory;
+#define ALCOSSBACKENDFACTORY_INITIALIZER { { GET_VTABLE2(ALCossBackendFactory, ALCbackendFactory) } }
+
+ALCbackendFactory *ALCossBackendFactory_getFactory(void);
+
+ALCboolean ALCossBackendFactory_init(ALCossBackendFactory *self);
+DECLARE_FORWARD(ALCossBackendFactory, ALCbackendFactory, void, deinit)
+ALCboolean ALCossBackendFactory_querySupport(ALCossBackendFactory *self, ALCbackend_Type type);
+void ALCossBackendFactory_probe(ALCossBackendFactory *self, enum DevProbe type);
+ALCbackend* ALCossBackendFactory_createBackend(ALCossBackendFactory *self, ALCdevice *device, ALCbackend_Type type);
+DEFINE_ALCBACKENDFACTORY_VTABLE(ALCossBackendFactory);
+
+
+ALCbackendFactory *ALCossBackendFactory_getFactory(void)
{
- oss_data *data = (oss_data*)Device->ExtraData;
- return RingBufferSize(data->ring);
+ static ALCossBackendFactory factory = ALCOSSBACKENDFACTORY_INITIALIZER;
+ return STATIC_CAST(ALCbackendFactory, &factory);
}
-static const BackendFuncs oss_funcs = {
- oss_open_playback,
- oss_close_playback,
- oss_reset_playback,
- oss_start_playback,
- oss_stop_playback,
- oss_open_capture,
- oss_close_capture,
- oss_start_capture,
- oss_stop_capture,
- oss_capture_samples,
- oss_available_samples,
- ALCdevice_LockDefault,
- ALCdevice_UnlockDefault,
- ALCdevice_GetLatencyDefault
-};
-
-ALCboolean alc_oss_init(BackendFuncs *func_list)
+ALCboolean ALCossBackendFactory_init(ALCossBackendFactory* UNUSED(self))
{
ConfigValueStr("oss", "device", &oss_driver);
ConfigValueStr("oss", "capture", &oss_capture);
- *func_list = oss_funcs;
return ALC_TRUE;
}
-void alc_oss_deinit(void)
+ALCboolean ALCossBackendFactory_querySupport(ALCossBackendFactory* UNUSED(self), ALCbackend_Type type)
{
+ if(type == ALCbackend_Playback || type == ALCbackend_Capture)
+ return ALC_TRUE;
+ return ALC_FALSE;
}
-void alc_oss_probe(enum DevProbe type)
+void ALCossBackendFactory_probe(ALCossBackendFactory* UNUSED(self), enum DevProbe type)
{
switch(type)
{
@@ -538,3 +608,31 @@ void alc_oss_probe(enum DevProbe type)
break;
}
}
+
+ALCbackend* ALCossBackendFactory_createBackend(ALCossBackendFactory* UNUSED(self), ALCdevice *device, ALCbackend_Type type)
+{
+ if(type == ALCbackend_Playback)
+ {
+ ALCplaybackOSS *backend;
+
+ backend = calloc(1, sizeof(*backend));
+ if(!backend) return NULL;
+
+ ALCplaybackOSS_Construct(backend, device);
+
+ return STATIC_CAST(ALCbackend, backend);
+ }
+ if(type == ALCbackend_Capture)
+ {
+ ALCcaptureOSS *backend;
+
+ backend = calloc(1, sizeof(*backend));
+ if(!backend) return NULL;
+
+ ALCcaptureOSS_Construct(backend, device);
+
+ return STATIC_CAST(ALCbackend, backend);
+ }
+
+ return NULL;
+}