diff options
Diffstat (limited to 'Alc/backends/dsound.c')
-rw-r--r-- | Alc/backends/dsound.c | 372 |
1 files changed, 196 insertions, 176 deletions
diff --git a/Alc/backends/dsound.c b/Alc/backends/dsound.c index 4db4b557..c368cffb 100644 --- a/Alc/backends/dsound.c +++ b/Alc/backends/dsound.c @@ -34,6 +34,7 @@ #include "alMain.h" #include "alu.h" +#include "ringbuffer.h" #include "threads.h" #include "compat.h" #include "alstring.h" @@ -60,7 +61,7 @@ DEFINE_GUID(KSDATAFORMAT_SUBTYPE_PCM, 0x00000001, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71); DEFINE_GUID(KSDATAFORMAT_SUBTYPE_IEEE_FLOAT, 0x00000003, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71); -#define DEVNAME_TAIL " on OpenAL Soft" +#define DEVNAME_HEAD "OpenAL Soft on " #ifdef HAVE_DYNLOAD @@ -123,7 +124,7 @@ static void clear_devlist(vector_DevMap *list) { #define DEINIT_STR(i) AL_STRING_DEINIT((i)->name) VECTOR_FOR_EACH(DevMap, *list, DEINIT_STR); - VECTOR_RESIZE(*list, 0); + VECTOR_RESIZE(*list, 0, 0); #undef DEINIT_STR } @@ -145,19 +146,18 @@ static BOOL CALLBACK DSoundEnumDevices(GUID *guid, const WCHAR *desc, const WCHA { const DevMap *iter; - al_string_copy_wcstr(&entry.name, desc); - if(count == 0) - al_string_append_cstr(&entry.name, DEVNAME_TAIL); - else + alstr_copy_cstr(&entry.name, DEVNAME_HEAD); + alstr_append_wcstr(&entry.name, desc); + if(count != 0) { char str[64]; - snprintf(str, sizeof(str), " #%d"DEVNAME_TAIL, count+1); - al_string_append_cstr(&entry.name, str); + snprintf(str, sizeof(str), " #%d", count+1); + alstr_append_cstr(&entry.name, str); } -#define MATCH_ENTRY(i) (al_string_cmp(entry.name, (i)->name) == 0) +#define MATCH_ENTRY(i) (alstr_cmp(entry.name, (i)->name) == 0) VECTOR_FIND_IF(iter, const DevMap, *devices, MATCH_ENTRY); - if(iter == VECTOR_ITER_END(*devices)) break; + if(iter == VECTOR_END(*devices)) break; #undef MATCH_ENTRY count++; } @@ -166,7 +166,7 @@ static BOOL CALLBACK DSoundEnumDevices(GUID *guid, const WCHAR *desc, const WCHA hr = StringFromCLSID(guid, &guidstr); if(SUCCEEDED(hr)) { - TRACE("Got device \"%s\", GUID \"%ls\"\n", al_string_get_cstr(entry.name), guidstr); + TRACE("Got device \"%s\", GUID \"%ls\"\n", alstr_get_cstr(entry.name), guidstr); CoTaskMemFree(guidstr); } @@ -185,22 +185,21 @@ typedef struct ALCdsoundPlayback { IDirectSoundNotify *Notifies; HANDLE NotifyEvent; - volatile int killNow; + ATOMIC(ALenum) 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 void ALCdsoundPlayback_Destruct(ALCdsoundPlayback *self); 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, ClockLatency, getClockLatency) static DECLARE_FORWARD(ALCdsoundPlayback, ALCbackend, void, lock) static DECLARE_FORWARD(ALCdsoundPlayback, ALCbackend, void, unlock) DECLARE_DEFAULT_ALLOCATORS(ALCdsoundPlayback) @@ -212,6 +211,35 @@ static void ALCdsoundPlayback_Construct(ALCdsoundPlayback *self, ALCdevice *devi { ALCbackend_Construct(STATIC_CAST(ALCbackend, self), device); SET_VTABLE2(ALCdsoundPlayback, ALCbackend, self); + + self->DS = NULL; + self->PrimaryBuffer = NULL; + self->Buffer = NULL; + self->Notifies = NULL; + self->NotifyEvent = NULL; + ATOMIC_INIT(&self->killNow, AL_TRUE); +} + +static void ALCdsoundPlayback_Destruct(ALCdsoundPlayback *self) +{ + 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; + + if(self->DS) + IDirectSound_Release(self->DS); + self->DS = NULL; + if(self->NotifyEvent) + CloseHandle(self->NotifyEvent); + self->NotifyEvent = NULL; + + ALCbackend_Destruct(STATIC_CAST(ALCbackend, self)); } @@ -240,16 +268,17 @@ FORCE_ALIGN static int ALCdsoundPlayback_mixerProc(void *ptr) { ERR("Failed to get buffer caps: 0x%lx\n", err); ALCdevice_Lock(device); - aluHandleDisconnect(device); + aluHandleDisconnect(device, "Failure retrieving playback buffer info: 0x%lx", err); ALCdevice_Unlock(device); return 1; } - FrameSize = FrameSizeFromDevFmt(device->FmtChans, device->FmtType); + FrameSize = FrameSizeFromDevFmt(device->FmtChans, device->FmtType, device->AmbiOrder); FragSize = device->UpdateSize * FrameSize; IDirectSoundBuffer_GetCurrentPosition(self->Buffer, &LastCursor, NULL); - while(!self->killNow) + while(!ATOMIC_LOAD(&self->killNow, almemory_order_acquire) && + ATOMIC_LOAD(&device->Connected, almemory_order_acquire)) { // Get current play cursor IDirectSoundBuffer_GetCurrentPosition(self->Buffer, &PlayCursor, NULL); @@ -264,7 +293,7 @@ FORCE_ALIGN static int ALCdsoundPlayback_mixerProc(void *ptr) { ERR("Failed to play buffer: 0x%lx\n", err); ALCdevice_Lock(device); - aluHandleDisconnect(device); + aluHandleDisconnect(device, "Failure starting playback: 0x%lx", err); ALCdevice_Unlock(device); return 1; } @@ -300,8 +329,10 @@ FORCE_ALIGN static int ALCdsoundPlayback_mixerProc(void *ptr) if(SUCCEEDED(err)) { // If we have an active context, mix data directly into output buffer otherwise fill with silence + ALCdevice_Lock(device); aluMixData(device, WritePtr1, WriteCnt1/FrameSize); aluMixData(device, WritePtr2, WriteCnt2/FrameSize); + ALCdevice_Unlock(device); // Unlock output buffer only when successfully locked IDirectSoundBuffer_Unlock(self->Buffer, WritePtr1, WriteCnt1, WritePtr2, WriteCnt2); @@ -310,7 +341,7 @@ FORCE_ALIGN static int ALCdsoundPlayback_mixerProc(void *ptr) { ERR("Buffer lock error: %#lx\n", err); ALCdevice_Lock(device); - aluHandleDisconnect(device); + aluHandleDisconnect(device, "Failed to lock output buffer: 0x%lx", err); ALCdevice_Unlock(device); return 1; } @@ -342,23 +373,23 @@ static ALCenum ALCdsoundPlayback_open(ALCdsoundPlayback *self, const ALCchar *de if(!deviceName && VECTOR_SIZE(PlaybackDevices) > 0) { - deviceName = al_string_get_cstr(VECTOR_FRONT(PlaybackDevices).name); + deviceName = alstr_get_cstr(VECTOR_FRONT(PlaybackDevices).name); guid = &VECTOR_FRONT(PlaybackDevices).guid; } else { const DevMap *iter; -#define MATCH_NAME(i) (al_string_cmp_cstr((i)->name, deviceName) == 0) +#define MATCH_NAME(i) (alstr_cmp_cstr((i)->name, deviceName) == 0) VECTOR_FIND_IF(iter, const DevMap, PlaybackDevices, MATCH_NAME); #undef MATCH_NAME - if(iter == VECTOR_ITER_END(PlaybackDevices)) + if(iter == VECTOR_END(PlaybackDevices)) return ALC_INVALID_VALUE; guid = &iter->guid; } hr = DS_OK; - self->NotifyEvent = CreateEvent(NULL, FALSE, FALSE, NULL); + self->NotifyEvent = CreateEventW(NULL, FALSE, FALSE, NULL); if(self->NotifyEvent == NULL) hr = E_FAIL; @@ -380,29 +411,11 @@ static ALCenum ALCdsoundPlayback_open(ALCdsoundPlayback *self, const ALCchar *de return ALC_INVALID_VALUE; } - al_string_copy_cstr(&device->DeviceName, deviceName); + alstr_copy_cstr(&device->DeviceName, deviceName); return ALC_NO_ERROR; } -static void ALCdsoundPlayback_close(ALCdsoundPlayback *self) -{ - 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 ALCdsoundPlayback_reset(ALCdsoundPlayback *self) { ALCdevice *device = STATIC_CAST(ALCbackend, self)->mDevice; @@ -473,7 +486,7 @@ static ALCboolean ALCdsoundPlayback_reset(ALCdsoundPlayback *self) case DevFmtMono: OutputType.dwChannelMask = SPEAKER_FRONT_CENTER; break; - case DevFmtBFormat3D: + case DevFmtAmbi3D: device->FmtChans = DevFmtStereo; /*fall-through*/ case DevFmtStereo: @@ -526,7 +539,7 @@ static ALCboolean ALCdsoundPlayback_reset(ALCdsoundPlayback *self) retry_open: hr = S_OK; OutputType.Format.wFormatTag = WAVE_FORMAT_PCM; - OutputType.Format.nChannels = ChannelsFromDevFmt(device->FmtChans); + OutputType.Format.nChannels = ChannelsFromDevFmt(device->FmtChans, device->AmbiOrder); OutputType.Format.wBitsPerSample = BytesFromDevFmt(device->FmtType) * 8; OutputType.Format.nBlockAlign = OutputType.Format.nChannels*OutputType.Format.wBitsPerSample/8; OutputType.Format.nSamplesPerSec = device->Frequency; @@ -625,7 +638,7 @@ retry_open: static ALCboolean ALCdsoundPlayback_start(ALCdsoundPlayback *self) { - self->killNow = 0; + ATOMIC_STORE(&self->killNow, AL_FALSE, almemory_order_release); if(althrd_create(&self->thread, ALCdsoundPlayback_mixerProc, self) != althrd_success) return ALC_FALSE; @@ -636,10 +649,8 @@ static void ALCdsoundPlayback_stop(ALCdsoundPlayback *self) { int res; - if(self->killNow) + if(ATOMIC_EXCHANGE(&self->killNow, AL_TRUE, almemory_order_acq_rel)) return; - - self->killNow = 1; althrd_join(self->thread, &res); IDirectSoundBuffer_Stop(self->Buffer); @@ -654,19 +665,19 @@ typedef struct ALCdsoundCapture { IDirectSoundCaptureBuffer *DSCbuffer; DWORD BufferBytes; DWORD Cursor; - RingBuffer *Ring; + + ll_ringbuffer_t *Ring; } ALCdsoundCapture; static void ALCdsoundCapture_Construct(ALCdsoundCapture *self, ALCdevice *device); -static DECLARE_FORWARD(ALCdsoundCapture, ALCbackend, void, Destruct) +static void ALCdsoundCapture_Destruct(ALCdsoundCapture *self); 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, ClockLatency, getClockLatency) static DECLARE_FORWARD(ALCdsoundCapture, ALCbackend, void, lock) static DECLARE_FORWARD(ALCdsoundCapture, ALCbackend, void, unlock) DECLARE_DEFAULT_ALLOCATORS(ALCdsoundCapture) @@ -677,6 +688,29 @@ static void ALCdsoundCapture_Construct(ALCdsoundCapture *self, ALCdevice *device { ALCbackend_Construct(STATIC_CAST(ALCbackend, self), device); SET_VTABLE2(ALCdsoundCapture, ALCbackend, self); + + self->DSC = NULL; + self->DSCbuffer = NULL; + self->Ring = NULL; +} + +static void ALCdsoundCapture_Destruct(ALCdsoundCapture *self) +{ + ll_ringbuffer_free(self->Ring); + self->Ring = NULL; + + if(self->DSCbuffer != NULL) + { + IDirectSoundCaptureBuffer_Stop(self->DSCbuffer); + IDirectSoundCaptureBuffer_Release(self->DSCbuffer); + self->DSCbuffer = NULL; + } + + if(self->DSC) + IDirectSoundCapture_Release(self->DSC); + self->DSC = NULL; + + ALCbackend_Destruct(STATIC_CAST(ALCbackend, self)); } @@ -702,17 +736,17 @@ static ALCenum ALCdsoundCapture_open(ALCdsoundCapture *self, const ALCchar *devi if(!deviceName && VECTOR_SIZE(CaptureDevices) > 0) { - deviceName = al_string_get_cstr(VECTOR_FRONT(CaptureDevices).name); + deviceName = alstr_get_cstr(VECTOR_FRONT(CaptureDevices).name); guid = &VECTOR_FRONT(CaptureDevices).guid; } else { const DevMap *iter; -#define MATCH_NAME(i) (al_string_cmp_cstr((i)->name, deviceName) == 0) +#define MATCH_NAME(i) (alstr_cmp_cstr((i)->name, deviceName) == 0) VECTOR_FIND_IF(iter, const DevMap, CaptureDevices, MATCH_NAME); #undef MATCH_NAME - if(iter == VECTOR_ITER_END(CaptureDevices)) + if(iter == VECTOR_END(CaptureDevices)) return ALC_INVALID_VALUE; guid = &iter->guid; } @@ -732,99 +766,98 @@ static ALCenum ALCdsoundCapture_open(ALCdsoundCapture *self, const ALCchar *devi break; } - //DirectSoundCapture Init code - hr = DirectSoundCaptureCreate(guid, &self->DSC, NULL); - if(SUCCEEDED(hr)) + memset(&InputType, 0, sizeof(InputType)); + switch(device->FmtChans) { - memset(&InputType, 0, sizeof(InputType)); - - switch(device->FmtChans) - { - case DevFmtMono: - InputType.dwChannelMask = SPEAKER_FRONT_CENTER; - break; - case DevFmtStereo: - InputType.dwChannelMask = SPEAKER_FRONT_LEFT | - SPEAKER_FRONT_RIGHT; - break; - case DevFmtQuad: - InputType.dwChannelMask = SPEAKER_FRONT_LEFT | - SPEAKER_FRONT_RIGHT | - SPEAKER_BACK_LEFT | - SPEAKER_BACK_RIGHT; - break; - case DevFmtX51: - InputType.dwChannelMask = SPEAKER_FRONT_LEFT | - SPEAKER_FRONT_RIGHT | - SPEAKER_FRONT_CENTER | - SPEAKER_LOW_FREQUENCY | - SPEAKER_SIDE_LEFT | - SPEAKER_SIDE_RIGHT; - break; - case DevFmtX51Rear: - InputType.dwChannelMask = SPEAKER_FRONT_LEFT | - SPEAKER_FRONT_RIGHT | - SPEAKER_FRONT_CENTER | - SPEAKER_LOW_FREQUENCY | - SPEAKER_BACK_LEFT | - SPEAKER_BACK_RIGHT; - break; - case DevFmtX61: - InputType.dwChannelMask = SPEAKER_FRONT_LEFT | - SPEAKER_FRONT_RIGHT | - SPEAKER_FRONT_CENTER | - SPEAKER_LOW_FREQUENCY | - SPEAKER_BACK_CENTER | - SPEAKER_SIDE_LEFT | - SPEAKER_SIDE_RIGHT; - break; - case DevFmtX71: - InputType.dwChannelMask = SPEAKER_FRONT_LEFT | - SPEAKER_FRONT_RIGHT | - SPEAKER_FRONT_CENTER | - SPEAKER_LOW_FREQUENCY | - SPEAKER_BACK_LEFT | - SPEAKER_BACK_RIGHT | - SPEAKER_SIDE_LEFT | - SPEAKER_SIDE_RIGHT; - break; - case DevFmtBFormat3D: - break; - } + case DevFmtMono: + InputType.dwChannelMask = SPEAKER_FRONT_CENTER; + break; + case DevFmtStereo: + InputType.dwChannelMask = SPEAKER_FRONT_LEFT | + SPEAKER_FRONT_RIGHT; + break; + case DevFmtQuad: + InputType.dwChannelMask = SPEAKER_FRONT_LEFT | + SPEAKER_FRONT_RIGHT | + SPEAKER_BACK_LEFT | + SPEAKER_BACK_RIGHT; + break; + case DevFmtX51: + InputType.dwChannelMask = SPEAKER_FRONT_LEFT | + SPEAKER_FRONT_RIGHT | + SPEAKER_FRONT_CENTER | + SPEAKER_LOW_FREQUENCY | + SPEAKER_SIDE_LEFT | + SPEAKER_SIDE_RIGHT; + break; + case DevFmtX51Rear: + InputType.dwChannelMask = SPEAKER_FRONT_LEFT | + SPEAKER_FRONT_RIGHT | + SPEAKER_FRONT_CENTER | + SPEAKER_LOW_FREQUENCY | + SPEAKER_BACK_LEFT | + SPEAKER_BACK_RIGHT; + break; + case DevFmtX61: + InputType.dwChannelMask = SPEAKER_FRONT_LEFT | + SPEAKER_FRONT_RIGHT | + SPEAKER_FRONT_CENTER | + SPEAKER_LOW_FREQUENCY | + SPEAKER_BACK_CENTER | + SPEAKER_SIDE_LEFT | + SPEAKER_SIDE_RIGHT; + break; + case DevFmtX71: + InputType.dwChannelMask = SPEAKER_FRONT_LEFT | + SPEAKER_FRONT_RIGHT | + SPEAKER_FRONT_CENTER | + SPEAKER_LOW_FREQUENCY | + SPEAKER_BACK_LEFT | + SPEAKER_BACK_RIGHT | + SPEAKER_SIDE_LEFT | + SPEAKER_SIDE_RIGHT; + break; + case DevFmtAmbi3D: + WARN("%s capture not supported\n", DevFmtChannelsString(device->FmtChans)); + return ALC_INVALID_ENUM; + } - InputType.Format.wFormatTag = WAVE_FORMAT_PCM; - InputType.Format.nChannels = ChannelsFromDevFmt(device->FmtChans); - InputType.Format.wBitsPerSample = BytesFromDevFmt(device->FmtType) * 8; - InputType.Format.nBlockAlign = InputType.Format.nChannels*InputType.Format.wBitsPerSample/8; - InputType.Format.nSamplesPerSec = device->Frequency; - InputType.Format.nAvgBytesPerSec = InputType.Format.nSamplesPerSec*InputType.Format.nBlockAlign; - InputType.Format.cbSize = 0; + InputType.Format.wFormatTag = WAVE_FORMAT_PCM; + InputType.Format.nChannels = ChannelsFromDevFmt(device->FmtChans, device->AmbiOrder); + InputType.Format.wBitsPerSample = BytesFromDevFmt(device->FmtType) * 8; + InputType.Format.nBlockAlign = InputType.Format.nChannels*InputType.Format.wBitsPerSample/8; + InputType.Format.nSamplesPerSec = device->Frequency; + InputType.Format.nAvgBytesPerSec = InputType.Format.nSamplesPerSec*InputType.Format.nBlockAlign; + InputType.Format.cbSize = 0; + InputType.Samples.wValidBitsPerSample = InputType.Format.wBitsPerSample; + if(device->FmtType == DevFmtFloat) + InputType.SubFormat = KSDATAFORMAT_SUBTYPE_IEEE_FLOAT; + else + InputType.SubFormat = KSDATAFORMAT_SUBTYPE_PCM; - if(InputType.Format.nChannels > 2 || device->FmtType == DevFmtFloat) - { - InputType.Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE; - InputType.Format.cbSize = sizeof(WAVEFORMATEXTENSIBLE) - sizeof(WAVEFORMATEX); - InputType.Samples.wValidBitsPerSample = InputType.Format.wBitsPerSample; - if(device->FmtType == DevFmtFloat) - InputType.SubFormat = KSDATAFORMAT_SUBTYPE_IEEE_FLOAT; - else - InputType.SubFormat = KSDATAFORMAT_SUBTYPE_PCM; - } + if(InputType.Format.nChannels > 2 || device->FmtType == DevFmtFloat) + { + InputType.Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE; + InputType.Format.cbSize = sizeof(WAVEFORMATEXTENSIBLE) - sizeof(WAVEFORMATEX); + } - samples = device->UpdateSize * device->NumUpdates; - samples = maxu(samples, 100 * device->Frequency / 1000); + samples = device->UpdateSize * device->NumUpdates; + samples = maxu(samples, 100 * device->Frequency / 1000); - memset(&DSCBDescription, 0, sizeof(DSCBUFFERDESC)); - DSCBDescription.dwSize = sizeof(DSCBUFFERDESC); - DSCBDescription.dwFlags = 0; - DSCBDescription.dwBufferBytes = samples * InputType.Format.nBlockAlign; - DSCBDescription.lpwfxFormat = &InputType.Format; + memset(&DSCBDescription, 0, sizeof(DSCBUFFERDESC)); + DSCBDescription.dwSize = sizeof(DSCBUFFERDESC); + DSCBDescription.dwFlags = 0; + DSCBDescription.dwBufferBytes = samples * InputType.Format.nBlockAlign; + DSCBDescription.lpwfxFormat = &InputType.Format; + //DirectSoundCapture Init code + hr = DirectSoundCaptureCreate(guid, &self->DSC, NULL); + if(SUCCEEDED(hr)) hr = IDirectSoundCapture_CreateCaptureBuffer(self->DSC, &DSCBDescription, &self->DSCbuffer, NULL); - } if(SUCCEEDED(hr)) { - self->Ring = CreateRingBuffer(InputType.Format.nBlockAlign, device->UpdateSize * device->NumUpdates); + self->Ring = ll_ringbuffer_create(device->UpdateSize*device->NumUpdates, + InputType.Format.nBlockAlign, false); if(self->Ring == NULL) hr = DSERR_OUTOFMEMORY; } @@ -833,7 +866,7 @@ static ALCenum ALCdsoundCapture_open(ALCdsoundCapture *self, const ALCchar *devi { ERR("Device init failed: 0x%08lx\n", hr); - DestroyRingBuffer(self->Ring); + ll_ringbuffer_free(self->Ring); self->Ring = NULL; if(self->DSCbuffer != NULL) IDirectSoundCaptureBuffer_Release(self->DSCbuffer); @@ -848,27 +881,11 @@ static ALCenum ALCdsoundCapture_open(ALCdsoundCapture *self, const ALCchar *devi self->BufferBytes = DSCBDescription.dwBufferBytes; SetDefaultWFXChannelOrder(device); - al_string_copy_cstr(&device->DeviceName, deviceName); + alstr_copy_cstr(&device->DeviceName, deviceName); return ALC_NO_ERROR; } -static void ALCdsoundCapture_close(ALCdsoundCapture *self) -{ - DestroyRingBuffer(self->Ring); - self->Ring = NULL; - - if(self->DSCbuffer != NULL) - { - IDirectSoundCaptureBuffer_Stop(self->DSCbuffer); - IDirectSoundCaptureBuffer_Release(self->DSCbuffer); - self->DSCbuffer = NULL; - } - - IDirectSoundCapture_Release(self->DSC); - self->DSC = NULL; -} - static ALCboolean ALCdsoundCapture_start(ALCdsoundCapture *self) { HRESULT hr; @@ -877,7 +894,8 @@ static ALCboolean ALCdsoundCapture_start(ALCdsoundCapture *self) if(FAILED(hr)) { ERR("start failed: 0x%08lx\n", hr); - aluHandleDisconnect(STATIC_CAST(ALCbackend, self)->mDevice); + aluHandleDisconnect(STATIC_CAST(ALCbackend, self)->mDevice, + "Failure starting capture: 0x%lx", hr); return ALC_FALSE; } @@ -892,13 +910,14 @@ static void ALCdsoundCapture_stop(ALCdsoundCapture *self) if(FAILED(hr)) { ERR("stop failed: 0x%08lx\n", hr); - aluHandleDisconnect(STATIC_CAST(ALCbackend, self)->mDevice); + aluHandleDisconnect(STATIC_CAST(ALCbackend, self)->mDevice, + "Failure stopping capture: 0x%lx", hr); } } static ALCenum ALCdsoundCapture_captureSamples(ALCdsoundCapture *self, ALCvoid *buffer, ALCuint samples) { - ReadRingBuffer(self->Ring, buffer, samples); + ll_ringbuffer_read(self->Ring, buffer, samples); return ALC_NO_ERROR; } @@ -911,10 +930,10 @@ static ALCuint ALCdsoundCapture_availableSamples(ALCdsoundCapture *self) DWORD FrameSize; HRESULT hr; - if(!device->Connected) + if(!ATOMIC_LOAD(&device->Connected, almemory_order_acquire)) goto done; - FrameSize = FrameSizeFromDevFmt(device->FmtChans, device->FmtType); + FrameSize = FrameSizeFromDevFmt(device->FmtChans, device->FmtType, device->AmbiOrder); BufferBytes = self->BufferBytes; LastCursor = self->Cursor; @@ -930,9 +949,9 @@ static ALCuint ALCdsoundCapture_availableSamples(ALCdsoundCapture *self) } if(SUCCEEDED(hr)) { - WriteRingBuffer(self->Ring, ReadPtr1, ReadCnt1/FrameSize); + ll_ringbuffer_write(self->Ring, ReadPtr1, ReadCnt1/FrameSize); if(ReadPtr2 != NULL) - WriteRingBuffer(self->Ring, ReadPtr2, ReadCnt2/FrameSize); + ll_ringbuffer_write(self->Ring, ReadPtr2, ReadCnt2/FrameSize); hr = IDirectSoundCaptureBuffer_Unlock(self->DSCbuffer, ReadPtr1, ReadCnt1, ReadPtr2, ReadCnt2); @@ -942,19 +961,14 @@ static ALCuint ALCdsoundCapture_availableSamples(ALCdsoundCapture *self) if(FAILED(hr)) { ERR("update failed: 0x%08lx\n", hr); - aluHandleDisconnect(device); + aluHandleDisconnect(device, "Failure retrieving capture data: 0x%lx", hr); } done: - return RingBufferSize(self->Ring); + return (ALCuint)ll_ringbuffer_read_space(self->Ring); } -static inline void AppendAllDevicesList2(const DevMap *entry) -{ AppendAllDevicesList(al_string_get_cstr(entry->name)); } -static inline void AppendCaptureDeviceList2(const DevMap *entry) -{ AppendCaptureDeviceList(al_string_get_cstr(entry->name)); } - typedef struct ALCdsoundBackendFactory { DERIVE_FROM_TYPE(ALCbackendFactory); } ALCdsoundBackendFactory; @@ -965,7 +979,7 @@ 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 void ALCdsoundBackendFactory_probe(ALCdsoundBackendFactory *self, enum DevProbe type, al_string *outnames); static ALCbackend* ALCdsoundBackendFactory_createBackend(ALCdsoundBackendFactory *self, ALCdevice *device, ALCbackend_Type type); DEFINE_ALCBACKENDFACTORY_VTABLE(ALCdsoundBackendFactory); @@ -1009,7 +1023,7 @@ static ALCboolean ALCdsoundBackendFactory_querySupport(ALCdsoundBackendFactory* return ALC_FALSE; } -static void ALCdsoundBackendFactory_probe(ALCdsoundBackendFactory* UNUSED(self), enum DevProbe type) +static void ALCdsoundBackendFactory_probe(ALCdsoundBackendFactory* UNUSED(self), enum DevProbe type, al_string *outnames) { HRESULT hr, hrcom; @@ -1017,12 +1031,17 @@ static void ALCdsoundBackendFactory_probe(ALCdsoundBackendFactory* UNUSED(self), hrcom = CoInitialize(NULL); switch(type) { +#define APPEND_OUTNAME(e) do { \ + if(!alstr_empty((e)->name)) \ + alstr_append_range(outnames, VECTOR_BEGIN((e)->name), \ + VECTOR_END((e)->name)+1); \ +} while(0) case ALL_DEVICE_PROBE: clear_devlist(&PlaybackDevices); hr = DirectSoundEnumerateW(DSoundEnumDevices, &PlaybackDevices); if(FAILED(hr)) ERR("Error enumerating DirectSound playback devices (0x%lx)!\n", hr); - VECTOR_FOR_EACH(const DevMap, PlaybackDevices, AppendAllDevicesList2); + VECTOR_FOR_EACH(const DevMap, PlaybackDevices, APPEND_OUTNAME); break; case CAPTURE_DEVICE_PROBE: @@ -1030,8 +1049,9 @@ static void ALCdsoundBackendFactory_probe(ALCdsoundBackendFactory* UNUSED(self), hr = DirectSoundCaptureEnumerateW(DSoundEnumDevices, &CaptureDevices); if(FAILED(hr)) ERR("Error enumerating DirectSound capture devices (0x%lx)!\n", hr); - VECTOR_FOR_EACH(const DevMap, CaptureDevices, AppendCaptureDeviceList2); + VECTOR_FOR_EACH(const DevMap, CaptureDevices, APPEND_OUTNAME); break; +#undef APPEND_OUTNAME } if(SUCCEEDED(hrcom)) CoUninitialize(); |