Files
spice2x.github.io/src/spice2x/hooks/audio/backends/mmdevice/device_collection.cpp
T
bicarus 2dae86a6f2 gitadora: (arena model) simulate Realtek device, fix asio redirect hooks (#732)
## Link to GitHub Issue or related Pull Request, if one exists
#730, #718

## Description of change

Part 1)

When ASIO is in use, the game also looks for a Realtek device so that it
can open a WASAPI Exclusive mode stream for headphones.

Add an option to fake that, in case the user doesn't have a Realtek
device.

Part 2)

`-gdaasio` wasn't workign properly - fix the logic.

## Testing
Seems to work with FlexASIO, and Xonar with no real Realtek device.
2026-06-05 00:08:52 -07:00

76 lines
2.2 KiB
C++

#include "device_collection.h"
#include "device.h"
#include "null_device.h"
#include "util/utils.h"
#include "util/logging.h"
HRESULT STDMETHODCALLTYPE WrappedIMMDeviceCollection::QueryInterface(REFIID riid, void **ppvObj) {
if (ppvObj == nullptr) {
return E_POINTER;
}
if (riid == __uuidof(IMMDeviceCollection)) {
this->AddRef();
*ppvObj = this;
return S_OK;
}
return pReal->QueryInterface(riid, ppvObj);
}
ULONG STDMETHODCALLTYPE WrappedIMMDeviceCollection::AddRef() {
return pReal->AddRef();
}
ULONG STDMETHODCALLTYPE WrappedIMMDeviceCollection::Release() {
// get reference count of underlying interface
ULONG refs = pReal != nullptr ? pReal->Release() : 0;
if (refs == 0) {
delete this;
}
return refs;
}
bool WrappedIMMDeviceCollection::should_inject_fake_realtek() const {
return null_render_device_enabled()
&& (data_flow == eRender || data_flow == eAll);
}
HRESULT STDMETHODCALLTYPE WrappedIMMDeviceCollection::GetCount(UINT *pcDevices) {
// when active, hide all real devices and present only the synthetic one
if (should_inject_fake_realtek()) {
if (pcDevices == nullptr) {
return E_POINTER;
}
*pcDevices = 1;
return S_OK;
}
return pReal->GetCount(pcDevices);
}
HRESULT STDMETHODCALLTYPE WrappedIMMDeviceCollection::Item(UINT nDevice, IMMDevice **ppDevice) {
if (ppDevice == nullptr) {
return E_POINTER;
}
// when active, the only device in the collection is the synthetic fake Realtek
// render device; all real devices are hidden
if (should_inject_fake_realtek()) {
if (nDevice != 0) {
return E_INVALIDARG;
}
log_info("audio", "WrappedIMMDeviceCollection::Item[{}] -> synthetic fake Realtek render device", nDevice);
*ppDevice = new NullMMDevice();
return S_OK;
}
log_info("audio", "WrappedIMMDeviceCollection::Item[{}]", nDevice);
// call original
const auto hr = pReal->Item(nDevice, ppDevice);
// wrap interface
if (SUCCEEDED(hr) && *ppDevice != nullptr) {
*ppDevice = new WrappedIMMDevice(*ppDevice);
}
return hr;
}