aboutsummaryrefslogtreecommitdiffstats
path: root/Alc/backends/dsound.c
diff options
context:
space:
mode:
Diffstat (limited to 'Alc/backends/dsound.c')
-rw-r--r--Alc/backends/dsound.c511
1 files changed, 291 insertions, 220 deletions
diff --git a/Alc/backends/dsound.c b/Alc/backends/dsound.c
index b09208ae..f487a6cb 100644
--- a/Alc/backends/dsound.c
+++ b/Alc/backends/dsound.c
@@ -38,6 +38,8 @@
#include "compat.h"
#include "alstring.h"
+#include "backends/base.h"
+
#ifndef DSSPEAKER_5POINT1
# define DSSPEAKER_5POINT1 0x00000006
#endif
@@ -68,41 +70,6 @@ static HRESULT (WINAPI *pDirectSoundCaptureEnumerateW)(LPDSENUMCALLBACKW pDSEnum
#define DirectSoundCaptureEnumerateW pDirectSoundCaptureEnumerateW
-typedef struct {
- // DirectSound Playback Device
- IDirectSound *DS;
- IDirectSoundBuffer *PrimaryBuffer;
- IDirectSoundBuffer *Buffer;
- IDirectSoundNotify *Notifies;
- HANDLE NotifyEvent;
-
- volatile int killNow;
- althrd_t thread;
-} DSoundPlaybackData;
-
-typedef struct {
- // DirectSound Capture Device
- IDirectSoundCapture *DSC;
- IDirectSoundCaptureBuffer *DSCbuffer;
- DWORD BufferBytes;
- DWORD Cursor;
- RingBuffer *Ring;
-} DSoundCaptureData;
-
-
-typedef struct {
- al_string name;
- GUID guid;
-} DevMap;
-DECL_VECTOR(DevMap)
-
-vector_DevMap PlaybackDevices;
-vector_DevMap CaptureDevices;
-
-
-#define MAX_UPDATES 128
-
-
static ALCboolean DSoundLoad(void)
{
if(!ds_handle)
@@ -132,6 +99,17 @@ static ALCboolean DSoundLoad(void)
}
+#define MAX_UPDATES 128
+
+typedef struct {
+ al_string name;
+ GUID guid;
+} DevMap;
+DECL_VECTOR(DevMap)
+
+vector_DevMap PlaybackDevices;
+vector_DevMap CaptureDevices;
+
static BOOL CALLBACK DSoundEnumDevices(LPGUID guid, LPCWSTR desc, LPCWSTR UNUSED(drvname), LPVOID data)
{
vector_DevMap *devices = data;
@@ -180,10 +158,49 @@ static BOOL CALLBACK DSoundEnumDevices(LPGUID guid, LPCWSTR desc, LPCWSTR UNUSED
}
-FORCE_ALIGN static int DSoundPlaybackProc(void *ptr)
+typedef struct ALCdsoundPlayback {
+ DERIVE_FROM_TYPE(ALCbackend);
+
+ IDirectSound *DS;
+ IDirectSoundBuffer *PrimaryBuffer;
+ IDirectSoundBuffer *Buffer;
+ IDirectSoundNotify *Notifies;
+ HANDLE NotifyEvent;
+
+ volatile int killNow;
+ althrd_t thread;
+} ALCdsoundPlayback;
+
+static int ALCdsoundPlayback_mixerProc(void *ptr);
+
+static void ALCdsoundPlayback_Construct(ALCdsoundPlayback *self, ALCdevice *device);
+static DECLARE_FORWARD(ALCdsoundPlayback, ALCbackend, void, Destruct)
+static ALCenum ALCdsoundPlayback_open(ALCdsoundPlayback *self, const ALCchar *name);
+static void ALCdsoundPlayback_close(ALCdsoundPlayback *self);
+static ALCboolean ALCdsoundPlayback_reset(ALCdsoundPlayback *self);
+static ALCboolean ALCdsoundPlayback_start(ALCdsoundPlayback *self);
+static void ALCdsoundPlayback_stop(ALCdsoundPlayback *self);
+static DECLARE_FORWARD2(ALCdsoundPlayback, ALCbackend, ALCenum, captureSamples, void*, ALCuint)
+static DECLARE_FORWARD(ALCdsoundPlayback, ALCbackend, ALCuint, availableSamples)
+static DECLARE_FORWARD(ALCdsoundPlayback, ALCbackend, ALint64, getLatency)
+static DECLARE_FORWARD(ALCdsoundPlayback, ALCbackend, void, lock)
+static DECLARE_FORWARD(ALCdsoundPlayback, ALCbackend, void, unlock)
+DECLARE_DEFAULT_ALLOCATORS(ALCdsoundPlayback)
+
+DEFINE_ALCBACKEND_VTABLE(ALCdsoundPlayback);
+
+
+static void ALCdsoundPlayback_Construct(ALCdsoundPlayback *self, ALCdevice *device)
{
- ALCdevice *Device = (ALCdevice*)ptr;
- DSoundPlaybackData *data = (DSoundPlaybackData*)Device->ExtraData;
+ ALCbackend_Construct(STATIC_CAST(ALCbackend, self), device);
+ SET_VTABLE2(ALCdsoundPlayback, ALCbackend, self);
+}
+
+
+FORCE_ALIGN static int ALCdsoundPlayback_mixerProc(void *ptr)
+{
+ ALCdsoundPlayback *self = ptr;
+ ALCdevice *device = STATIC_CAST(ALCbackend, self)->mDevice;
DSBCAPS DSBCaps;
DWORD LastCursor = 0;
DWORD PlayCursor;
@@ -200,43 +217,43 @@ FORCE_ALIGN static int DSoundPlaybackProc(void *ptr)
memset(&DSBCaps, 0, sizeof(DSBCaps));
DSBCaps.dwSize = sizeof(DSBCaps);
- err = IDirectSoundBuffer_GetCaps(data->Buffer, &DSBCaps);
+ err = IDirectSoundBuffer_GetCaps(self->Buffer, &DSBCaps);
if(FAILED(err))
{
ERR("Failed to get buffer caps: 0x%lx\n", err);
- ALCdevice_Lock(Device);
- aluHandleDisconnect(Device);
- ALCdevice_Unlock(Device);
+ ALCdevice_Lock(device);
+ aluHandleDisconnect(device);
+ ALCdevice_Unlock(device);
return 1;
}
- FrameSize = FrameSizeFromDevFmt(Device->FmtChans, Device->FmtType);
- FragSize = Device->UpdateSize * FrameSize;
+ FrameSize = FrameSizeFromDevFmt(device->FmtChans, device->FmtType);
+ FragSize = device->UpdateSize * FrameSize;
- IDirectSoundBuffer_GetCurrentPosition(data->Buffer, &LastCursor, NULL);
- while(!data->killNow)
+ IDirectSoundBuffer_GetCurrentPosition(self->Buffer, &LastCursor, NULL);
+ while(!self->killNow)
{
// Get current play cursor
- IDirectSoundBuffer_GetCurrentPosition(data->Buffer, &PlayCursor, NULL);
+ IDirectSoundBuffer_GetCurrentPosition(self->Buffer, &PlayCursor, NULL);
avail = (PlayCursor-LastCursor+DSBCaps.dwBufferBytes) % DSBCaps.dwBufferBytes;
if(avail < FragSize)
{
if(!Playing)
{
- err = IDirectSoundBuffer_Play(data->Buffer, 0, 0, DSBPLAY_LOOPING);
+ err = IDirectSoundBuffer_Play(self->Buffer, 0, 0, DSBPLAY_LOOPING);
if(FAILED(err))
{
ERR("Failed to play buffer: 0x%lx\n", err);
- ALCdevice_Lock(Device);
- aluHandleDisconnect(Device);
- ALCdevice_Unlock(Device);
+ ALCdevice_Lock(device);
+ aluHandleDisconnect(device);
+ ALCdevice_Unlock(device);
return 1;
}
Playing = TRUE;
}
- avail = WaitForSingleObjectEx(data->NotifyEvent, 2000, FALSE);
+ avail = WaitForSingleObjectEx(self->NotifyEvent, 2000, FALSE);
if(avail != WAIT_OBJECT_0)
ERR("WaitForSingleObjectEx error: 0x%lx\n", avail);
continue;
@@ -246,18 +263,18 @@ FORCE_ALIGN static int DSoundPlaybackProc(void *ptr)
// Lock output buffer
WriteCnt1 = 0;
WriteCnt2 = 0;
- err = IDirectSoundBuffer_Lock(data->Buffer, LastCursor, avail, &WritePtr1, &WriteCnt1, &WritePtr2, &WriteCnt2, 0);
+ err = IDirectSoundBuffer_Lock(self->Buffer, LastCursor, avail, &WritePtr1, &WriteCnt1, &WritePtr2, &WriteCnt2, 0);
// If the buffer is lost, restore it and lock
if(err == DSERR_BUFFERLOST)
{
WARN("Buffer lost, restoring...\n");
- err = IDirectSoundBuffer_Restore(data->Buffer);
+ err = IDirectSoundBuffer_Restore(self->Buffer);
if(SUCCEEDED(err))
{
Playing = FALSE;
LastCursor = 0;
- err = IDirectSoundBuffer_Lock(data->Buffer, 0, DSBCaps.dwBufferBytes, &WritePtr1, &WriteCnt1, &WritePtr2, &WriteCnt2, 0);
+ err = IDirectSoundBuffer_Lock(self->Buffer, 0, DSBCaps.dwBufferBytes, &WritePtr1, &WriteCnt1, &WritePtr2, &WriteCnt2, 0);
}
}
@@ -265,18 +282,18 @@ FORCE_ALIGN static int DSoundPlaybackProc(void *ptr)
if(SUCCEEDED(err))
{
// If we have an active context, mix data directly into output buffer otherwise fill with silence
- aluMixData(Device, WritePtr1, WriteCnt1/FrameSize);
- aluMixData(Device, WritePtr2, WriteCnt2/FrameSize);
+ aluMixData(device, WritePtr1, WriteCnt1/FrameSize);
+ aluMixData(device, WritePtr2, WriteCnt2/FrameSize);
// Unlock output buffer only when successfully locked
- IDirectSoundBuffer_Unlock(data->Buffer, WritePtr1, WriteCnt1, WritePtr2, WriteCnt2);
+ IDirectSoundBuffer_Unlock(self->Buffer, WritePtr1, WriteCnt1, WritePtr2, WriteCnt2);
}
else
{
ERR("Buffer lock error: %#lx\n", err);
- ALCdevice_Lock(Device);
- aluHandleDisconnect(Device);
- ALCdevice_Unlock(Device);
+ ALCdevice_Lock(device);
+ aluHandleDisconnect(device);
+ ALCdevice_Unlock(device);
return 1;
}
@@ -288,9 +305,9 @@ FORCE_ALIGN static int DSoundPlaybackProc(void *ptr)
return 0;
}
-static ALCenum DSoundOpenPlayback(ALCdevice *device, const ALCchar *deviceName)
+static ALCenum ALCdsoundPlayback_open(ALCdsoundPlayback *self, const ALCchar *deviceName)
{
- DSoundPlaybackData *data = NULL;
+ ALCdevice *device = STATIC_CAST(ALCbackend, self)->mDevice;
LPGUID guid = NULL;
HRESULT hr, hrcom;
@@ -328,60 +345,55 @@ static ALCenum DSoundOpenPlayback(ALCdevice *device, const ALCchar *deviceName)
return ALC_INVALID_VALUE;
}
- //Initialise requested device
- data = calloc(1, sizeof(DSoundPlaybackData));
- if(!data)
- return ALC_OUT_OF_MEMORY;
-
hr = DS_OK;
- data->NotifyEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
- if(data->NotifyEvent == NULL)
+ self->NotifyEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
+ if(self->NotifyEvent == NULL)
hr = E_FAIL;
//DirectSound Init code
if(SUCCEEDED(hr))
- hr = DirectSoundCreate(guid, &data->DS, NULL);
+ hr = DirectSoundCreate(guid, &self->DS, NULL);
if(SUCCEEDED(hr))
- hr = IDirectSound_SetCooperativeLevel(data->DS, GetForegroundWindow(), DSSCL_PRIORITY);
+ hr = IDirectSound_SetCooperativeLevel(self->DS, GetForegroundWindow(), DSSCL_PRIORITY);
if(FAILED(hr))
{
- if(data->DS)
- IDirectSound_Release(data->DS);
- if(data->NotifyEvent)
- CloseHandle(data->NotifyEvent);
- free(data);
+ if(self->DS)
+ IDirectSound_Release(self->DS);
+ self->DS = NULL;
+ if(self->NotifyEvent)
+ CloseHandle(self->NotifyEvent);
+ self->NotifyEvent = NULL;
+
ERR("Device init failed: 0x%08lx\n", hr);
return ALC_INVALID_VALUE;
}
al_string_copy_cstr(&device->DeviceName, deviceName);
- device->ExtraData = data;
+
return ALC_NO_ERROR;
}
-static void DSoundClosePlayback(ALCdevice *device)
+static void ALCdsoundPlayback_close(ALCdsoundPlayback *self)
{
- DSoundPlaybackData *data = device->ExtraData;
-
- if(data->Notifies)
- IDirectSoundNotify_Release(data->Notifies);
- data->Notifies = NULL;
- if(data->Buffer)
- IDirectSoundBuffer_Release(data->Buffer);
- data->Buffer = NULL;
- if(data->PrimaryBuffer != NULL)
- IDirectSoundBuffer_Release(data->PrimaryBuffer);
- data->PrimaryBuffer = NULL;
-
- IDirectSound_Release(data->DS);
- CloseHandle(data->NotifyEvent);
- free(data);
- device->ExtraData = NULL;
+ if(self->Notifies)
+ IDirectSoundNotify_Release(self->Notifies);
+ self->Notifies = NULL;
+ if(self->Buffer)
+ IDirectSoundBuffer_Release(self->Buffer);
+ self->Buffer = NULL;
+ if(self->PrimaryBuffer != NULL)
+ IDirectSoundBuffer_Release(self->PrimaryBuffer);
+ self->PrimaryBuffer = NULL;
+
+ IDirectSound_Release(self->DS);
+ self->DS = NULL;
+ CloseHandle(self->NotifyEvent);
+ self->NotifyEvent = NULL;
}
-static ALCboolean DSoundResetPlayback(ALCdevice *device)
+static ALCboolean ALCdsoundPlayback_reset(ALCdsoundPlayback *self)
{
- DSoundPlaybackData *data = (DSoundPlaybackData*)device->ExtraData;
+ ALCdevice *device = STATIC_CAST(ALCbackend, self)->mDevice;
DSBUFFERDESC DSBDescription;
WAVEFORMATEXTENSIBLE OutputType;
DWORD speakers;
@@ -389,15 +401,15 @@ static ALCboolean DSoundResetPlayback(ALCdevice *device)
memset(&OutputType, 0, sizeof(OutputType));
- if(data->Notifies)
- IDirectSoundNotify_Release(data->Notifies);
- data->Notifies = NULL;
- if(data->Buffer)
- IDirectSoundBuffer_Release(data->Buffer);
- data->Buffer = NULL;
- if(data->PrimaryBuffer != NULL)
- IDirectSoundBuffer_Release(data->PrimaryBuffer);
- data->PrimaryBuffer = NULL;
+ if(self->Notifies)
+ IDirectSoundNotify_Release(self->Notifies);
+ self->Notifies = NULL;
+ if(self->Buffer)
+ IDirectSoundBuffer_Release(self->Buffer);
+ self->Buffer = NULL;
+ if(self->PrimaryBuffer != NULL)
+ IDirectSoundBuffer_Release(self->PrimaryBuffer);
+ self->PrimaryBuffer = NULL;
switch(device->FmtType)
{
@@ -420,7 +432,7 @@ static ALCboolean DSoundResetPlayback(ALCdevice *device)
break;
}
- hr = IDirectSound_GetSpeakerConfig(data->DS, &speakers);
+ hr = IDirectSound_GetSpeakerConfig(self->DS, &speakers);
if(SUCCEEDED(hr))
{
if(!(device->Flags&DEVICE_CHANNELS_REQUEST))
@@ -513,21 +525,21 @@ retry_open:
else
OutputType.SubFormat = KSDATAFORMAT_SUBTYPE_PCM;
- if(data->PrimaryBuffer)
- IDirectSoundBuffer_Release(data->PrimaryBuffer);
- data->PrimaryBuffer = NULL;
+ if(self->PrimaryBuffer)
+ IDirectSoundBuffer_Release(self->PrimaryBuffer);
+ self->PrimaryBuffer = NULL;
}
else
{
- if(SUCCEEDED(hr) && !data->PrimaryBuffer)
+ if(SUCCEEDED(hr) && !self->PrimaryBuffer)
{
memset(&DSBDescription,0,sizeof(DSBUFFERDESC));
DSBDescription.dwSize=sizeof(DSBUFFERDESC);
DSBDescription.dwFlags=DSBCAPS_PRIMARYBUFFER;
- hr = IDirectSound_CreateSoundBuffer(data->DS, &DSBDescription, &data->PrimaryBuffer, NULL);
+ hr = IDirectSound_CreateSoundBuffer(self->DS, &DSBDescription, &self->PrimaryBuffer, NULL);
}
if(SUCCEEDED(hr))
- hr = IDirectSoundBuffer_SetFormat(data->PrimaryBuffer,&OutputType.Format);
+ hr = IDirectSoundBuffer_SetFormat(self->PrimaryBuffer,&OutputType.Format);
}
if(SUCCEEDED(hr))
@@ -545,7 +557,7 @@ retry_open:
DSBDescription.dwBufferBytes=device->UpdateSize * device->NumUpdates *
OutputType.Format.nBlockAlign;
DSBDescription.lpwfxFormat=&OutputType.Format;
- hr = IDirectSound_CreateSoundBuffer(data->DS, &DSBDescription, &data->Buffer, NULL);
+ hr = IDirectSound_CreateSoundBuffer(self->DS, &DSBDescription, &self->Buffer, NULL);
if(FAILED(hr) && device->FmtType == DevFmtFloat)
{
device->FmtType = DevFmtShort;
@@ -555,7 +567,7 @@ retry_open:
if(SUCCEEDED(hr))
{
- hr = IDirectSoundBuffer_QueryInterface(data->Buffer, &IID_IDirectSoundNotify, (LPVOID *)&data->Notifies);
+ hr = IDirectSoundBuffer_QueryInterface(self->Buffer, &IID_IDirectSoundNotify, (LPVOID *)&self->Notifies);
if(SUCCEEDED(hr))
{
DSBPOSITIONNOTIFY notifies[MAX_UPDATES];
@@ -565,62 +577,93 @@ retry_open:
{
notifies[i].dwOffset = i * device->UpdateSize *
OutputType.Format.nBlockAlign;
- notifies[i].hEventNotify = data->NotifyEvent;
+ notifies[i].hEventNotify = self->NotifyEvent;
}
- if(IDirectSoundNotify_SetNotificationPositions(data->Notifies, device->NumUpdates, notifies) != DS_OK)
+ if(IDirectSoundNotify_SetNotificationPositions(self->Notifies, device->NumUpdates, notifies) != DS_OK)
hr = E_FAIL;
}
}
if(FAILED(hr))
{
- if(data->Notifies != NULL)
- IDirectSoundNotify_Release(data->Notifies);
- data->Notifies = NULL;
- if(data->Buffer != NULL)
- IDirectSoundBuffer_Release(data->Buffer);
- data->Buffer = NULL;
- if(data->PrimaryBuffer != NULL)
- IDirectSoundBuffer_Release(data->PrimaryBuffer);
- data->PrimaryBuffer = NULL;
+ if(self->Notifies != NULL)
+ IDirectSoundNotify_Release(self->Notifies);
+ self->Notifies = NULL;
+ if(self->Buffer != NULL)
+ IDirectSoundBuffer_Release(self->Buffer);
+ self->Buffer = NULL;
+ if(self->PrimaryBuffer != NULL)
+ IDirectSoundBuffer_Release(self->PrimaryBuffer);
+ self->PrimaryBuffer = NULL;
return ALC_FALSE;
}
- ResetEvent(data->NotifyEvent);
+ ResetEvent(self->NotifyEvent);
SetDefaultWFXChannelOrder(device);
return ALC_TRUE;
}
-static ALCboolean DSoundStartPlayback(ALCdevice *device)
+static ALCboolean ALCdsoundPlayback_start(ALCdsoundPlayback *self)
{
- DSoundPlaybackData *data = (DSoundPlaybackData*)device->ExtraData;
-
- data->killNow = 0;
- if(althrd_create(&data->thread, DSoundPlaybackProc, device) != althrd_success)
+ self->killNow = 0;
+ if(althrd_create(&self->thread, ALCdsoundPlayback_mixerProc, self) != althrd_success)
return ALC_FALSE;
return ALC_TRUE;
}
-static void DSoundStopPlayback(ALCdevice *device)
+static void ALCdsoundPlayback_stop(ALCdsoundPlayback *self)
{
- DSoundPlaybackData *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);
+
+ IDirectSoundBuffer_Stop(self->Buffer);
+}
+
+
+
+typedef struct ALCdsoundCapture {
+ DERIVE_FROM_TYPE(ALCbackend);
- IDirectSoundBuffer_Stop(data->Buffer);
+ IDirectSoundCapture *DSC;
+ IDirectSoundCaptureBuffer *DSCbuffer;
+ DWORD BufferBytes;
+ DWORD Cursor;
+ RingBuffer *Ring;
+} ALCdsoundCapture;
+
+static void ALCdsoundCapture_Construct(ALCdsoundCapture *self, ALCdevice *device);
+static DECLARE_FORWARD(ALCdsoundCapture, ALCbackend, void, Destruct)
+static ALCenum ALCdsoundCapture_open(ALCdsoundCapture *self, const ALCchar *name);
+static void ALCdsoundCapture_close(ALCdsoundCapture *self);
+static DECLARE_FORWARD(ALCdsoundCapture, ALCbackend, ALCboolean, reset)
+static ALCboolean ALCdsoundCapture_start(ALCdsoundCapture *self);
+static void ALCdsoundCapture_stop(ALCdsoundCapture *self);
+static ALCenum ALCdsoundCapture_captureSamples(ALCdsoundCapture *self, ALCvoid *buffer, ALCuint samples);
+static ALCuint ALCdsoundCapture_availableSamples(ALCdsoundCapture *self);
+static DECLARE_FORWARD(ALCdsoundCapture, ALCbackend, ALint64, getLatency)
+static DECLARE_FORWARD(ALCdsoundCapture, ALCbackend, void, lock)
+static DECLARE_FORWARD(ALCdsoundCapture, ALCbackend, void, unlock)
+DECLARE_DEFAULT_ALLOCATORS(ALCdsoundCapture)
+
+DEFINE_ALCBACKEND_VTABLE(ALCdsoundCapture);
+
+static void ALCdsoundCapture_Construct(ALCdsoundCapture *self, ALCdevice *device)
+{
+ ALCbackend_Construct(STATIC_CAST(ALCbackend, self), device);
+ SET_VTABLE2(ALCdsoundCapture, ALCbackend, self);
}
-static ALCenum DSoundOpenCapture(ALCdevice *device, const ALCchar *deviceName)
+static ALCenum ALCdsoundCapture_open(ALCdsoundCapture *self, const ALCchar *deviceName)
{
- DSoundCaptureData *data = NULL;
+ ALCdevice *device = STATIC_CAST(ALCbackend, self)->mDevice;
WAVEFORMATEXTENSIBLE InputType;
DSCBUFFERDESC DSCBDescription;
LPGUID guid = NULL;
@@ -676,16 +719,8 @@ static ALCenum DSoundOpenCapture(ALCdevice *device, const ALCchar *deviceName)
break;
}
- //Initialise requested device
- data = calloc(1, sizeof(DSoundCaptureData));
- if(!data)
- return ALC_OUT_OF_MEMORY;
-
- hr = DS_OK;
-
//DirectSoundCapture Init code
- if(SUCCEEDED(hr))
- hr = DirectSoundCaptureCreate(guid, &data->DSC, NULL);
+ hr = DirectSoundCaptureCreate(guid, &self->DSC, NULL);
if(SUCCEEDED(hr))
{
memset(&InputType, 0, sizeof(InputType));
@@ -770,12 +805,12 @@ static ALCenum DSoundOpenCapture(ALCdevice *device, const ALCchar *deviceName)
DSCBDescription.dwBufferBytes = samples * InputType.Format.nBlockAlign;
DSCBDescription.lpwfxFormat = &InputType.Format;
- hr = IDirectSoundCapture_CreateCaptureBuffer(data->DSC, &DSCBDescription, &data->DSCbuffer, NULL);
+ hr = IDirectSoundCapture_CreateCaptureBuffer(self->DSC, &DSCBDescription, &self->DSCbuffer, NULL);
}
if(SUCCEEDED(hr))
{
- data->Ring = CreateRingBuffer(InputType.Format.nBlockAlign, device->UpdateSize * device->NumUpdates);
- if(data->Ring == NULL)
+ self->Ring = CreateRingBuffer(InputType.Format.nBlockAlign, device->UpdateSize * device->NumUpdates);
+ if(self->Ring == NULL)
hr = DSERR_OUTOFMEMORY;
}
@@ -783,158 +818,156 @@ static ALCenum DSoundOpenCapture(ALCdevice *device, const ALCchar *deviceName)
{
ERR("Device init failed: 0x%08lx\n", hr);
- DestroyRingBuffer(data->Ring);
- data->Ring = NULL;
- if(data->DSCbuffer != NULL)
- IDirectSoundCaptureBuffer_Release(data->DSCbuffer);
- data->DSCbuffer = NULL;
- if(data->DSC)
- IDirectSoundCapture_Release(data->DSC);
- data->DSC = NULL;
+ DestroyRingBuffer(self->Ring);
+ self->Ring = NULL;
+ if(self->DSCbuffer != NULL)
+ IDirectSoundCaptureBuffer_Release(self->DSCbuffer);
+ self->DSCbuffer = NULL;
+ if(self->DSC)
+ IDirectSoundCapture_Release(self->DSC);
+ self->DSC = NULL;
- free(data);
return ALC_INVALID_VALUE;
}
- data->BufferBytes = DSCBDescription.dwBufferBytes;
+ self->BufferBytes = DSCBDescription.dwBufferBytes;
SetDefaultWFXChannelOrder(device);
al_string_copy_cstr(&device->DeviceName, deviceName);
- device->ExtraData = data;
return ALC_NO_ERROR;
}
-static void DSoundCloseCapture(ALCdevice *device)
+static void ALCdsoundCapture_close(ALCdsoundCapture *self)
{
- DSoundCaptureData *data = device->ExtraData;
-
- DestroyRingBuffer(data->Ring);
- data->Ring = NULL;
+ DestroyRingBuffer(self->Ring);
+ self->Ring = NULL;
- if(data->DSCbuffer != NULL)
+ if(self->DSCbuffer != NULL)
{
- IDirectSoundCaptureBuffer_Stop(data->DSCbuffer);
- IDirectSoundCaptureBuffer_Release(data->DSCbuffer);
- data->DSCbuffer = NULL;
+ IDirectSoundCaptureBuffer_Stop(self->DSCbuffer);
+ IDirectSoundCaptureBuffer_Release(self->DSCbuffer);
+ self->DSCbuffer = NULL;
}
- IDirectSoundCapture_Release(data->DSC);
- data->DSC = NULL;
-
- free(data);
- device->ExtraData = NULL;
+ IDirectSoundCapture_Release(self->DSC);
+ self->DSC = NULL;
}
-static void DSoundStartCapture(ALCdevice *device)
+static ALCboolean ALCdsoundCapture_start(ALCdsoundCapture *self)
{
- DSoundCaptureData *data = device->ExtraData;
HRESULT hr;
- hr = IDirectSoundCaptureBuffer_Start(data->DSCbuffer, DSCBSTART_LOOPING);
+ hr = IDirectSoundCaptureBuffer_Start(self->DSCbuffer, DSCBSTART_LOOPING);
if(FAILED(hr))
{
ERR("start failed: 0x%08lx\n", hr);
- aluHandleDisconnect(device);
+ aluHandleDisconnect(STATIC_CAST(ALCbackend, self)->mDevice);
+ return ALC_FALSE;
}
+
+ return ALC_TRUE;
}
-static void DSoundStopCapture(ALCdevice *device)
+static void ALCdsoundCapture_stop(ALCdsoundCapture *self)
{
- DSoundCaptureData *data = device->ExtraData;
HRESULT hr;
- hr = IDirectSoundCaptureBuffer_Stop(data->DSCbuffer);
+ hr = IDirectSoundCaptureBuffer_Stop(self->DSCbuffer);
if(FAILED(hr))
{
ERR("stop failed: 0x%08lx\n", hr);
- aluHandleDisconnect(device);
+ aluHandleDisconnect(STATIC_CAST(ALCbackend, self)->mDevice);
}
}
-static ALCenum DSoundCaptureSamples(ALCdevice *Device, ALCvoid *pBuffer, ALCuint lSamples)
+static ALCenum ALCdsoundCapture_captureSamples(ALCdsoundCapture *self, ALCvoid *buffer, ALCuint samples)
{
- DSoundCaptureData *data = Device->ExtraData;
- ReadRingBuffer(data->Ring, pBuffer, lSamples);
+ ReadRingBuffer(self->Ring, buffer, samples);
return ALC_NO_ERROR;
}
-static ALCuint DSoundAvailableSamples(ALCdevice *Device)
+static ALCuint ALCdsoundCapture_availableSamples(ALCdsoundCapture *self)
{
- DSoundCaptureData *data = Device->ExtraData;
+ ALCdevice *device = STATIC_CAST(ALCbackend, self)->mDevice;
DWORD ReadCursor, LastCursor, BufferBytes, NumBytes;
VOID *ReadPtr1, *ReadPtr2;
DWORD ReadCnt1, ReadCnt2;
DWORD FrameSize;
HRESULT hr;
- if(!Device->Connected)
+ if(!device->Connected)
goto done;
- FrameSize = FrameSizeFromDevFmt(Device->FmtChans, Device->FmtType);
- BufferBytes = data->BufferBytes;
- LastCursor = data->Cursor;
+ FrameSize = FrameSizeFromDevFmt(device->FmtChans, device->FmtType);
+ BufferBytes = self->BufferBytes;
+ LastCursor = self->Cursor;
- hr = IDirectSoundCaptureBuffer_GetCurrentPosition(data->DSCbuffer, NULL, &ReadCursor);
+ hr = IDirectSoundCaptureBuffer_GetCurrentPosition(self->DSCbuffer, NULL, &ReadCursor);
if(SUCCEEDED(hr))
{
NumBytes = (ReadCursor-LastCursor + BufferBytes) % BufferBytes;
if(NumBytes == 0)
goto done;
- hr = IDirectSoundCaptureBuffer_Lock(data->DSCbuffer, LastCursor, NumBytes,
+ hr = IDirectSoundCaptureBuffer_Lock(self->DSCbuffer, LastCursor, NumBytes,
&ReadPtr1, &ReadCnt1,
&ReadPtr2, &ReadCnt2, 0);
}
if(SUCCEEDED(hr))
{
- WriteRingBuffer(data->Ring, ReadPtr1, ReadCnt1/FrameSize);
+ WriteRingBuffer(self->Ring, ReadPtr1, ReadCnt1/FrameSize);
if(ReadPtr2 != NULL)
- WriteRingBuffer(data->Ring, ReadPtr2, ReadCnt2/FrameSize);
- hr = IDirectSoundCaptureBuffer_Unlock(data->DSCbuffer,
+ WriteRingBuffer(self->Ring, ReadPtr2, ReadCnt2/FrameSize);
+ hr = IDirectSoundCaptureBuffer_Unlock(self->DSCbuffer,
ReadPtr1, ReadCnt1,
ReadPtr2, ReadCnt2);
- data->Cursor = (LastCursor+ReadCnt1+ReadCnt2) % BufferBytes;
+ self->Cursor = (LastCursor+ReadCnt1+ReadCnt2) % BufferBytes;
}
if(FAILED(hr))
{
ERR("update failed: 0x%08lx\n", hr);
- aluHandleDisconnect(Device);
+ aluHandleDisconnect(device);
}
done:
- return RingBufferSize(data->Ring);
+ return RingBufferSize(self->Ring);
}
-static const BackendFuncs DSoundFuncs = {
- DSoundOpenPlayback,
- DSoundClosePlayback,
- DSoundResetPlayback,
- DSoundStartPlayback,
- DSoundStopPlayback,
- DSoundOpenCapture,
- DSoundCloseCapture,
- DSoundStartCapture,
- DSoundStopCapture,
- DSoundCaptureSamples,
- DSoundAvailableSamples,
- ALCdevice_GetLatencyDefault
-};
+typedef struct ALCdsoundBackendFactory {
+ DERIVE_FROM_TYPE(ALCbackendFactory);
+} ALCdsoundBackendFactory;
+#define ALCDSOUNDBACKENDFACTORY_INITIALIZER { { GET_VTABLE2(ALCdsoundBackendFactory, ALCbackendFactory) } }
+
+ALCbackendFactory *ALCdsoundBackendFactory_getFactory(void);
+
+static ALCboolean ALCdsoundBackendFactory_init(ALCdsoundBackendFactory *self);
+static void ALCdsoundBackendFactory_deinit(ALCdsoundBackendFactory *self);
+static ALCboolean ALCdsoundBackendFactory_querySupport(ALCdsoundBackendFactory *self, ALCbackend_Type type);
+static void ALCdsoundBackendFactory_probe(ALCdsoundBackendFactory *self, enum DevProbe type);
+static ALCbackend* ALCdsoundBackendFactory_createBackend(ALCdsoundBackendFactory *self, ALCdevice *device, ALCbackend_Type type);
+DEFINE_ALCBACKENDFACTORY_VTABLE(ALCdsoundBackendFactory);
+
+ALCbackendFactory *ALCdsoundBackendFactory_getFactory(void)
+{
+ static ALCdsoundBackendFactory factory = ALCDSOUNDBACKENDFACTORY_INITIALIZER;
+ return STATIC_CAST(ALCbackendFactory, &factory);
+}
-ALCboolean alcDSoundInit(BackendFuncs *FuncList)
+
+static ALCboolean ALCdsoundBackendFactory_init(ALCdsoundBackendFactory* UNUSED(self))
{
VECTOR_INIT(PlaybackDevices);
VECTOR_INIT(CaptureDevices);
if(!DSoundLoad())
return ALC_FALSE;
- *FuncList = DSoundFuncs;
return ALC_TRUE;
}
-void alcDSoundDeinit(void)
+static void ALCdsoundBackendFactory_deinit(ALCdsoundBackendFactory* UNUSED(self))
{
DevMap *iter, *end;
@@ -955,7 +988,14 @@ void alcDSoundDeinit(void)
ds_handle = NULL;
}
-void alcDSoundProbe(enum DevProbe type)
+static ALCboolean ALCdsoundBackendFactory_querySupport(ALCdsoundBackendFactory* UNUSED(self), ALCbackend_Type type)
+{
+ if(type == ALCbackend_Playback || type == ALCbackend_Capture)
+ return ALC_TRUE;
+ return ALC_FALSE;
+}
+
+static void ALCdsoundBackendFactory_probe(ALCdsoundBackendFactory* UNUSED(self), enum DevProbe type)
{
DevMap *iter, *end;
HRESULT hr, hrcom;
@@ -1005,3 +1045,34 @@ void alcDSoundProbe(enum DevProbe type)
if(SUCCEEDED(hrcom))
CoUninitialize();
}
+
+static ALCbackend* ALCdsoundBackendFactory_createBackend(ALCdsoundBackendFactory* UNUSED(self), ALCdevice *device, ALCbackend_Type type)
+{
+ if(type == ALCbackend_Playback)
+ {
+ ALCdsoundPlayback *backend;
+
+ backend = ALCdsoundPlayback_New(sizeof(*backend));
+ if(!backend) return NULL;
+ memset(backend, 0, sizeof(*backend));
+
+ ALCdsoundPlayback_Construct(backend, device);
+
+ return STATIC_CAST(ALCbackend, backend);
+ }
+
+ if(type == ALCbackend_Capture)
+ {
+ ALCdsoundCapture *backend;
+
+ backend = ALCdsoundCapture_New(sizeof(*backend));
+ if(!backend) return NULL;
+ memset(backend, 0, sizeof(*backend));
+
+ ALCdsoundCapture_Construct(backend, device);
+
+ return STATIC_CAST(ALCbackend, backend);
+ }
+
+ return NULL;
+}