Skip to content

Commit

Permalink
Add a IDirectSoundCapture stub
Browse files Browse the repository at this point in the history
  • Loading branch information
kcat committed Apr 18, 2023
1 parent 72903fb commit 54f440f
Show file tree
Hide file tree
Showing 4 changed files with 225 additions and 2 deletions.
2 changes: 2 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@ add_library(dsound SHARED
src/AL/efx.h
src/buffer.cpp
src/buffer.h
src/capture.cpp
src/capture.h
src/comhelpers.h
src/comptr.h
src/dsoal_global.h
Expand Down
107 changes: 107 additions & 0 deletions src/capture.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
#include "capture.h"

#include "guidprinter.h"
#include "logging.h"


namespace {

using voidp = void*;
using cvoidp = const void*;

} // namespace

#define PREFIX "DSCapture::"
ComPtr<DSCapture> DSCapture::Create(bool is8)
{
return ComPtr<DSCapture>{new DSCapture{is8}};
}

DSCapture::DSCapture(bool is8) : mIs8{is8} { }
DSCapture::~DSCapture() = default;


HRESULT STDMETHODCALLTYPE DSCapture::QueryInterface(REFIID riid, void **ppvObject) noexcept
{
DEBUG(PREFIX "QueryInterface (%p)->(%s, %p)\n", voidp{this}, GuidPrinter{riid}.c_str(),
voidp{ppvObject});

*ppvObject = NULL;
if(riid == IID_IUnknown)
{
mUnknownIface.AddRef();
*ppvObject = mUnknownIface.as<IUnknown*>();
return S_OK;
}
if(riid == IID_IDirectSoundCapture)
{
AddRef();
*ppvObject = as<IDirectSoundCapture*>();
return S_OK;
}

FIXME(PREFIX "QueryInterface Unhandled GUID: %s\n", GuidPrinter{riid}.c_str());
return E_NOINTERFACE;
}

ULONG STDMETHODCALLTYPE DSCapture::AddRef() noexcept
{
mTotalRef.fetch_add(1u, std::memory_order_relaxed);
const auto ret = mDsRef.fetch_add(1u, std::memory_order_relaxed) + 1;
DEBUG(PREFIX "AddRef (%p) ref %lu\n", voidp{this}, ret);
return ret;
}

ULONG STDMETHODCALLTYPE DSCapture::Release() noexcept
{
const auto ret = mDsRef.fetch_sub(1u, std::memory_order_relaxed) - 1;
DEBUG(PREFIX "Release (%p) ref %lu\n", voidp{this}, ret);
if(mTotalRef.fetch_sub(1u, std::memory_order_relaxed) == 1u) UNLIKELY
delete this;
return ret;
}

HRESULT STDMETHODCALLTYPE DSCapture::CreateCaptureBuffer(const DSCBUFFERDESC *dscBufferDesc,
IDirectSoundCaptureBuffer **dsCaptureBuffer, IUnknown *unk) noexcept
{
FIXME(PREFIX "CreateCaptureBuffer (%p)->(%p, %p, %p)\n", voidp{this}, cvoidp{dscBufferDesc},
voidp{dsCaptureBuffer}, voidp{unk});
return E_NOTIMPL;
}

HRESULT STDMETHODCALLTYPE DSCapture::GetCaps(DSCCAPS *dscCaps) noexcept
{
FIXME(PREFIX "GetCaps (%p)->(%p)\n", voidp{this}, voidp{dscCaps});
return E_NOTIMPL;
}

HRESULT STDMETHODCALLTYPE DSCapture::Initialize(const GUID *guid) noexcept
{
FIXME(PREFIX "Initialize (%p)->(%s)\n", voidp{this}, GuidPrinter{guid}.c_str());
return E_NOTIMPL;
}
#undef PREFIX

#define PREFIX "DSCapture::UnknownIface::"
HRESULT STDMETHODCALLTYPE DSCapture::UnknownIface::QueryInterface(REFIID riid, void **ppvObject) noexcept
{ return impl_from_base()->QueryInterface(riid, ppvObject); }

ULONG STDMETHODCALLTYPE DSCapture::UnknownIface::AddRef() noexcept
{
auto self = impl_from_base();
self->mTotalRef.fetch_add(1u, std::memory_order_relaxed);
const auto ret = self->mUnkRef.fetch_add(1u, std::memory_order_relaxed) + 1;
DEBUG(PREFIX "AddRef (%p) ref %lu\n", voidp{this}, ret);
return ret;
}

ULONG STDMETHODCALLTYPE DSCapture::UnknownIface::Release() noexcept
{
auto self = impl_from_base();
const auto ret = self->mUnkRef.fetch_sub(1u, std::memory_order_relaxed) - 1;
DEBUG(PREFIX "Release (%p) ref %lu\n", voidp{this}, ret);
if(self->mTotalRef.fetch_sub(1u, std::memory_order_relaxed) == 1u) UNLIKELY
delete self;
return ret;
}
#undef PREFIX
55 changes: 55 additions & 0 deletions src/capture.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
#ifndef CAPTURE_H
#define CAPTURE_H

#include <atomic>

#include <dsound.h>

#include "comptr.h"


class DSCapture final : IDirectSoundCapture {
DSCapture(bool is8);
~DSCapture();

class UnknownIface final : IUnknown {
DSCapture *impl_from_base() noexcept
{
#ifdef __GNUC__
_Pragma("GCC diagnostic push") _Pragma("GCC diagnostic ignored \"-Wcast-align\"")
#endif
return CONTAINING_RECORD(this, DSCapture, mUnknownIface);
#ifdef __GNUC__
_Pragma("GCC diagnostic pop")
#endif
}

public:
HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void** ppvObject) noexcept override;
ULONG STDMETHODCALLTYPE AddRef() noexcept override;
ULONG STDMETHODCALLTYPE Release() noexcept override;

template<typename T>
T as() noexcept { return static_cast<T>(this); }
};
UnknownIface mUnknownIface;

std::atomic<ULONG> mTotalRef{1u}, mDsRef{1u}, mUnkRef{0u};

bool mIs8{};

public:
HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObject) noexcept override;
ULONG STDMETHODCALLTYPE AddRef() noexcept override;
ULONG STDMETHODCALLTYPE Release() noexcept override;
HRESULT STDMETHODCALLTYPE CreateCaptureBuffer(const DSCBUFFERDESC *dscBufferDesc, IDirectSoundCaptureBuffer **dsCaptureBuffer, IUnknown *unk) noexcept override;
HRESULT STDMETHODCALLTYPE GetCaps(DSCCAPS *dscCaps) noexcept override;
HRESULT STDMETHODCALLTYPE Initialize(const GUID *guid) noexcept override;

template<typename T> [[nodiscard]]
T as() noexcept { return static_cast<T>(this); }

static ComPtr<DSCapture> Create(bool is8);
};

#endif // CAPTURE_H
63 changes: 61 additions & 2 deletions src/dsoal.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#include "AL/al.h"
#include "AL/alc.h"
#include "AL/alext.h"
#include "capture.h"
#include "comhelpers.h"
#include "comptr.h"
#include "dsoal_global.h"
Expand Down Expand Up @@ -425,15 +426,73 @@ HRESULT WINAPI DSOAL_DirectSoundCaptureCreate(const GUID *deviceId, IDirectSound
{
TRACE("DirectSoundCaptureCreate (%s, %p, %p)\n", GuidPrinter{deviceId}.c_str(), voidp{ds},
voidp{outer});
return E_NOTIMPL;

if(!ds)
{
WARN("DirectSoundCaptureCreate invalid parameter: ppDS == NULL\n");
return DSERR_INVALIDPARAM;
}
*ds = NULL;

if(outer)
{
WARN("DirectSoundCaptureCreate invalid parameter: pUnkOuter != NULL\n");
return DSERR_INVALIDPARAM;
}

HRESULT hr{};
try {
auto dsobj = DSCapture::Create(false);
hr = dsobj->Initialize(deviceId);
if(SUCCEEDED(hr))
{
*ds = dsobj.release()->as<IDirectSoundCapture*>();
return DS_OK;
}
}
catch(std::bad_alloc &e) {
ERR("DirectSoundCaptureCreate Caught exception: %s\n", e.what());
hr = DSERR_OUTOFMEMORY;
}

return hr;
}

HRESULT WINAPI DSOAL_DirectSoundCaptureCreate8(const GUID *deviceId, IDirectSoundCapture8 **ds,
IUnknown *outer) noexcept
{
TRACE("DirectSoundCaptureCreate8 (%s, %p, %p)\n", GuidPrinter{deviceId}.c_str(), voidp{ds},
voidp{outer});
return E_NOTIMPL;

if(!ds)
{
WARN("DirectSoundCaptureCreate8 invalid parameter: ppDS == NULL\n");
return DSERR_INVALIDPARAM;
}
*ds = NULL;

if(outer)
{
WARN("DirectSoundCaptureCreate8 invalid parameter: pUnkOuter != NULL\n");
return DSERR_INVALIDPARAM;
}

HRESULT hr{};
try {
auto dsobj = DSCapture::Create(true);
hr = dsobj->Initialize(deviceId);
if(SUCCEEDED(hr))
{
*ds = dsobj.release()->as<IDirectSoundCapture8*>();
return DS_OK;
}
}
catch(std::bad_alloc &e) {
ERR("DirectSoundCaptureCreate8 Caught exception: %s\n", e.what());
hr = DSERR_OUTOFMEMORY;
}

return hr;
}

HRESULT WINAPI DSOAL_DirectSoundFullDuplexCreate(const GUID *captureDevice,
Expand Down

0 comments on commit 54f440f

Please sign in to comment.