From f706c435798dc9e60bc101f430422273e9752b7c Mon Sep 17 00:00:00 2001 From: josh turpen Date: Mon, 28 Aug 2023 08:28:56 -0700 Subject: [PATCH] fix voice capture and receive for UT2004 --- al/buffer.cpp | 11 +++++++++++ al/buffer.h | 3 +++ al/source.cpp | 46 ++++++++++++++++++++++++++++++++++++++++++++++ alc/alc.cpp | 5 ++++- include/AL/al.h | 3 +++ 5 files changed, 67 insertions(+), 1 deletion(-) diff --git a/al/buffer.cpp b/al/buffer.cpp index 28afc7c0a4..1e4168a70e 100644 --- a/al/buffer.cpp +++ b/al/buffer.cpp @@ -65,6 +65,9 @@ #include "eax/x_ram.h" #endif // ALSOFT_EAX +//snarf +#include +#include "debugapi.h" namespace { @@ -286,9 +289,12 @@ void LoadData(ALCcontext *context, ALbuffer *ALBuf, ALsizei freq, ALuint size, const FmtChannels DstChannels, const FmtType DstType, const std::byte *SrcData, ALbitfieldSOFT access) { + /* + snarf if(ReadRef(ALBuf->ref) != 0 || ALBuf->MappedAccess != 0) UNLIKELY return context->setError(AL_INVALID_OPERATION, "Modifying storage for in-use buffer %u", ALBuf->id); + */ const ALuint unpackalign{ALBuf->UnpackAlign}; const ALuint align{SanitizeAlignment(DstType, unpackalign)}; @@ -1247,6 +1253,11 @@ FORCE_ALIGN void AL_APIENTRY alGetBufferiDirect(ALCcontext *context, ALuint buff *value = static_cast(albuf->UnpackAmbiOrder); break; + case AL_BUFFER_SOURCE_ID: + *value = static_cast(albuf->sourceId); + break; + + default: context->setError(AL_INVALID_ENUM, "Invalid buffer integer property 0x%04x", param); } diff --git a/al/buffer.h b/al/buffer.h index f936cf9849..42fbd83271 100644 --- a/al/buffer.h +++ b/al/buffer.h @@ -48,6 +48,9 @@ struct ALbuffer : public BufferStorage { /* Self ID */ ALuint id{0}; + // snarf + ALuint sourceId{0}; + static void SetName(ALCcontext *context, ALuint id, std::string_view name); DISABLE_ALLOC() diff --git a/al/source.cpp b/al/source.cpp index 6bcb73186a..e138b384ea 100644 --- a/al/source.cpp +++ b/al/source.cpp @@ -3006,6 +3006,42 @@ FORCE_ALIGN void AL_APIENTRY alGetSourceiDirect(ALCcontext *context, ALuint sour if(!value) UNLIKELY return context->setError(AL_INVALID_VALUE, "NULL pointer"); + //snarf + ALenum oldParam = param; + if (param == AL_BUFFERS_QUEUED) + { + param = AL_SOURCE_STATE; + std::ignore = GetProperty(Source, context, static_cast(param), + al::span{ value, 1u }); + param = oldParam; + + if (*value != AL_PLAYING) + *value = 9; + else + { + *value = Source->mQueue.size(); + } + return; + } + else if (param == AL_BUFFERS_PROCESSED) + { + int played{ 0 }; + //if (Source->state != AL_INITIAL) + //{ + const VoiceBufferItem* Current{ nullptr }; + if (Voice * voice{ GetSourceVoice(Source, context) }) + Current = voice->mCurrentBuffer.load(std::memory_order_relaxed); + for (auto& item : Source->mQueue) + { + if (&item == Current) + break; + ++played; + } + //} + *value = played; + return; + } + std::ignore = GetProperty(Source, context, static_cast(param), al::span{value, 1u}); } @@ -3422,6 +3458,12 @@ FORCE_ALIGN void AL_APIENTRY alSourceQueueBuffersDirect(ALCcontext *context, ALu } if(buffer) { + //snarf + if (buffer->sourceId == 0) + { + buffer->sourceId = src; + } + if(buffer->mSampleRate < 1) { context->setError(AL_INVALID_OPERATION, "Queueing buffer %u with no format", @@ -3456,6 +3498,9 @@ FORCE_ALIGN void AL_APIENTRY alSourceQueueBuffersDirect(ALCcontext *context, ALu BufferList->mLoopEnd = buffer->mSampleLen; BufferList->mSamples = buffer->mData.data(); BufferList->mBuffer = buffer; + + //snarf + buffer->sourceId = src; IncrementRef(buffer->ref); if(BufferFmt == nullptr) @@ -3548,6 +3593,7 @@ FORCE_ALIGN void AL_APIENTRY alSourceUnqueueBuffersDirect(ALCcontext *context, A auto &head = source->mQueue.front(); if(ALbuffer *buffer{head.mBuffer}) { + buffer->sourceId = src; *(buffers++) = buffer->id; DecrementRef(buffer->ref); } diff --git a/alc/alc.cpp b/alc/alc.cpp index 0c42edbc9f..52c3d498f2 100644 --- a/alc/alc.cpp +++ b/alc/alc.cpp @@ -2728,7 +2728,7 @@ ALC_API ALCcontext* ALC_APIENTRY alcCreateContext(ALCdevice *device, const ALCin if(ALeffectslot *slot{context->mDefaultSlot.get()}) { - ALenum sloterr{slot->initEffect(0, ALCcontext::sDefaultEffect.type, + ALenum sloterr{slot->initEffect(ALCcontext::sDefaultEffect.type, ALCcontext::sDefaultEffect.Props, context.get())}; if(sloterr == AL_NO_ERROR) slot->updateProps(context.get()); @@ -2998,6 +2998,9 @@ ALC_API ALCboolean ALC_APIENTRY alcCloseDevice(ALCdevice *device) noexcept ************************************************/ ALC_API ALCdevice* ALC_APIENTRY alcCaptureOpenDevice(const ALCchar *deviceName, ALCuint frequency, ALCenum format, ALCsizei samples) noexcept { + //snarf + samples = samples / 4; + InitConfig(); if(!CaptureFactory) diff --git a/include/AL/al.h b/include/AL/al.h index 87274184b2..09cd8fc172 100644 --- a/include/AL/al.h +++ b/include/AL/al.h @@ -472,6 +472,9 @@ typedef void ALvoid; #define AL_EXPONENT_DISTANCE 0xD005 #define AL_EXPONENT_DISTANCE_CLAMPED 0xD006 +//snarf +#define AL_BUFFER_SOURCE_ID 0xE001 + #ifndef AL_NO_PROTOTYPES /* Renderer State management. */ AL_API void AL_APIENTRY alEnable(ALenum capability) AL_API_NOEXCEPT;