mirror of https://github.com/snes9xgit/snes9x.git
win32: map waveOut devices to mmdevices via endpoint id
This commit is contained in:
parent
d30060cdc1
commit
5c65edbbca
|
@ -11,8 +11,10 @@
|
||||||
#include "../snes9x.h"
|
#include "../snes9x.h"
|
||||||
#include "../apu/apu.h"
|
#include "../apu/apu.h"
|
||||||
#include "wsnes9x.h"
|
#include "wsnes9x.h"
|
||||||
|
#include <map>
|
||||||
|
|
||||||
|
#define DRV_QUERYFUNCTIONINSTANCEID (DRV_RESERVED + 17)
|
||||||
|
#define DRV_QUERYFUNCTIONINSTANCEIDSIZE (DRV_RESERVED + 18)
|
||||||
|
|
||||||
CWaveOut::CWaveOut(void)
|
CWaveOut::CWaveOut(void)
|
||||||
{
|
{
|
||||||
|
@ -244,13 +246,16 @@ std::vector<std::wstring> CWaveOut::GetDeviceList()
|
||||||
|
|
||||||
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
|
std::map<std::wstring, std::wstring> endpointId_deviceName_map;
|
||||||
|
|
||||||
|
// try to get device names via multimedia device enumerator, waveOut has a 31 character limit on device names
|
||||||
|
// save them in a map with their endpoint id to later match to waveOut devices
|
||||||
IMMDeviceEnumerator* deviceEnumerator;
|
IMMDeviceEnumerator* deviceEnumerator;
|
||||||
HRESULT hr = CoCreateInstance(__uuidof(MMDeviceEnumerator), NULL, CLSCTX_INPROC_SERVER, __uuidof(IMMDeviceEnumerator), (LPVOID*)&deviceEnumerator);
|
HRESULT hr = CoCreateInstance(__uuidof(MMDeviceEnumerator), NULL, CLSCTX_INPROC_SERVER, __uuidof(IMMDeviceEnumerator), (LPVOID*)&deviceEnumerator);
|
||||||
if (SUCCEEDED(hr))
|
if (SUCCEEDED(hr))
|
||||||
{
|
{
|
||||||
IMMDeviceCollection* renderDevices;
|
IMMDeviceCollection* renderDevices;
|
||||||
hr = deviceEnumerator->EnumAudioEndpoints(eRender, DEVICE_STATE_ACTIVE, &renderDevices);
|
hr = deviceEnumerator->EnumAudioEndpoints(eRender, DEVICE_STATEMASK_ALL, &renderDevices);
|
||||||
if (SUCCEEDED(hr))
|
if (SUCCEEDED(hr))
|
||||||
{
|
{
|
||||||
UINT count;
|
UINT count;
|
||||||
|
@ -262,6 +267,12 @@ std::vector<std::wstring> CWaveOut::GetDeviceList()
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
WCHAR* pstrEndpointId = NULL;
|
||||||
|
hr = renderDevice->GetId(&pstrEndpointId);
|
||||||
|
if (SUCCEEDED(hr))
|
||||||
|
{
|
||||||
|
std::wstring strEndpoint = pstrEndpointId;
|
||||||
|
CoTaskMemFree(pstrEndpointId);
|
||||||
IPropertyStore* propStore;
|
IPropertyStore* propStore;
|
||||||
PROPVARIANT propVar;
|
PROPVARIANT propVar;
|
||||||
PropVariantInit(&propVar);
|
PropVariantInit(&propVar);
|
||||||
|
@ -272,9 +283,11 @@ std::vector<std::wstring> CWaveOut::GetDeviceList()
|
||||||
}
|
}
|
||||||
if (SUCCEEDED(hr) && propVar.vt == VT_LPWSTR)
|
if (SUCCEEDED(hr) && propVar.vt == VT_LPWSTR)
|
||||||
{
|
{
|
||||||
device_list.push_back(propVar.pwszVal);
|
endpointId_deviceName_map[strEndpoint] = propVar.pwszVal;
|
||||||
}
|
}
|
||||||
PropVariantClear(&propVar);
|
PropVariantClear(&propVar);
|
||||||
|
}
|
||||||
|
|
||||||
renderDevice->Release();
|
renderDevice->Release();
|
||||||
}
|
}
|
||||||
renderDevices->Release();
|
renderDevices->Release();
|
||||||
|
@ -282,19 +295,41 @@ std::vector<std::wstring> CWaveOut::GetDeviceList()
|
||||||
deviceEnumerator->Release();
|
deviceEnumerator->Release();
|
||||||
}
|
}
|
||||||
|
|
||||||
// if we still only have "default" in the list, use old waveout enumeration
|
// enum waveOut devices, using mapped names if available
|
||||||
if (device_list.size() == 1)
|
|
||||||
{
|
|
||||||
UINT num_devices = waveOutGetNumDevs();
|
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;
|
||||||
if (waveOutGetDevCaps(i, &caps, sizeof(WAVEOUTCAPS)) == MMSYSERR_NOERROR)
|
MMRESULT mmr;
|
||||||
|
mmr = waveOutGetDevCaps(i, &caps, sizeof(WAVEOUTCAPS));
|
||||||
|
if (mmr != MMSYSERR_NOERROR)
|
||||||
{
|
{
|
||||||
device_list.push_back(caps.szPname);
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// get endpoint id, called function instance id in waveOutMessage
|
||||||
|
size_t endpointIdSize = 0;
|
||||||
|
mmr = waveOutMessage((HWAVEOUT)IntToPtr(i), DRV_QUERYFUNCTIONINSTANCEIDSIZE, (DWORD_PTR)&endpointIdSize, NULL);
|
||||||
|
if (mmr != MMSYSERR_NOERROR)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
std::vector<wchar_t> endpointIdBuffer(endpointIdSize);
|
||||||
|
mmr = waveOutMessage((HWAVEOUT)IntToPtr(i), DRV_QUERYFUNCTIONINSTANCEID, (DWORD_PTR)endpointIdBuffer.data(), endpointIdSize);
|
||||||
|
if (mmr != MMSYSERR_NOERROR)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
std::wstring strEndpoint(endpointIdBuffer.data());
|
||||||
|
|
||||||
|
// use name retrieved from mmdevice above if available
|
||||||
|
std::wstring devName = caps.szPname;
|
||||||
|
if (endpointId_deviceName_map.count(strEndpoint))
|
||||||
|
{
|
||||||
|
devName = endpointId_deviceName_map[strEndpoint];
|
||||||
|
}
|
||||||
|
|
||||||
|
device_list.push_back(devName);
|
||||||
}
|
}
|
||||||
|
|
||||||
return device_list;
|
return device_list;
|
||||||
|
|
Loading…
Reference in New Issue