mirror of
https://github.com/spice2x/spice2x.github.io.git
synced 2026-08-02 14:50:41 -07:00
2dae86a6f2
## 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.
76 lines
2.2 KiB
C++
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;
|
|
} |