win32: try MMDeviceEnumerator for waveOut device enumeration before

falling back to device caps (#883)
This commit is contained in:
OV2 2023-11-03 19:05:22 +01:00
parent bd918f60fb
commit d30060cdc1
2 changed files with 70 additions and 24 deletions

View File

@ -4,11 +4,16 @@
For further information, consult the LICENSE file in the root directory. For further information, consult the LICENSE file in the root directory.
\*****************************************************************************/ \*****************************************************************************/
#include "CWaveOut.h" #include "CWaveOut.h"
#include <mmdeviceapi.h> // needs to be before snes9x.h, otherwise conflicts with SetFlags macro
#include <Functiondiscoverykeys_devpkey.h>
#include "../snes9x.h" #include "../snes9x.h"
#include "../apu/apu.h" #include "../apu/apu.h"
#include "wsnes9x.h" #include "wsnes9x.h"
CWaveOut::CWaveOut(void) CWaveOut::CWaveOut(void)
{ {
hWaveOut = NULL; hWaveOut = NULL;
@ -237,10 +242,51 @@ std::vector<std::wstring> CWaveOut::GetDeviceList()
{ {
std::vector<std::wstring> device_list; std::vector<std::wstring> device_list;
UINT num_devices = waveOutGetNumDevs();
device_list.push_back(_T("Default")); device_list.push_back(_T("Default"));
// try to enumerate devices via multimedia device enumerator, waveout has a 31 character limit on device names
IMMDeviceEnumerator* deviceEnumerator;
HRESULT hr = CoCreateInstance(__uuidof(MMDeviceEnumerator), NULL, CLSCTX_INPROC_SERVER, __uuidof(IMMDeviceEnumerator), (LPVOID*)&deviceEnumerator);
if (SUCCEEDED(hr))
{
IMMDeviceCollection* renderDevices;
hr = deviceEnumerator->EnumAudioEndpoints(eRender, DEVICE_STATE_ACTIVE, &renderDevices);
if (SUCCEEDED(hr))
{
UINT count;
renderDevices->GetCount(&count);
for (int i = 0; i < count; i++)
{
IMMDevice* renderDevice = NULL;
if (renderDevices->Item(i, &renderDevice) != S_OK)
{
continue;
}
IPropertyStore* propStore;
PROPVARIANT propVar;
PropVariantInit(&propVar);
hr = renderDevice->OpenPropertyStore(STGM_READ, &propStore);
if (SUCCEEDED(hr))
{
hr = propStore->GetValue(PKEY_Device_FriendlyName, &propVar);
}
if (SUCCEEDED(hr) && propVar.vt == VT_LPWSTR)
{
device_list.push_back(propVar.pwszVal);
}
PropVariantClear(&propVar);
renderDevice->Release();
}
renderDevices->Release();
}
deviceEnumerator->Release();
}
// if we still only have "default" in the list, use old waveout enumeration
if (device_list.size() == 1)
{
UINT num_devices = waveOutGetNumDevs();
for (unsigned int i = 0; i < num_devices; i++) for (unsigned int i = 0; i < num_devices; i++)
{ {
WAVEOUTCAPS caps; WAVEOUTCAPS caps;
@ -249,6 +295,7 @@ std::vector<std::wstring> CWaveOut::GetDeviceList()
device_list.push_back(caps.szPname); device_list.push_back(caps.szPname);
} }
} }
}
return device_list; return device_list;
} }

View File

@ -6,7 +6,6 @@
#pragma once #pragma once
#include "../snes9x.h"
#include <windows.h> #include <windows.h>
#include "IS9xSoundOutput.h" #include "IS9xSoundOutput.h"
#include <mmsystem.h> #include <mmsystem.h>