forked from kcat/dsoal
-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
4 changed files
with
225 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters