dmusic: Create the list of available system ports at the beginning and use it to enumerate ports.
This commit is contained in:
parent
649a177007
commit
66a817f067
|
@ -74,6 +74,7 @@ static ULONG WINAPI IDirectMusic8Impl_Release(LPDIRECTMUSIC8 iface)
|
||||||
TRACE("(%p)->(): new ref = %u\n", This, ref);
|
TRACE("(%p)->(): new ref = %u\n", This, ref);
|
||||||
|
|
||||||
if (!ref) {
|
if (!ref) {
|
||||||
|
HeapFree(GetProcessHeap(), 0, This->system_ports);
|
||||||
HeapFree(GetProcessHeap(), 0, This->ppPorts);
|
HeapFree(GetProcessHeap(), 0, This->ppPorts);
|
||||||
HeapFree(GetProcessHeap(), 0, This);
|
HeapFree(GetProcessHeap(), 0, This);
|
||||||
}
|
}
|
||||||
|
@ -87,85 +88,18 @@ static ULONG WINAPI IDirectMusic8Impl_Release(LPDIRECTMUSIC8 iface)
|
||||||
static HRESULT WINAPI IDirectMusic8Impl_EnumPort(LPDIRECTMUSIC8 iface, DWORD index, LPDMUS_PORTCAPS port_caps)
|
static HRESULT WINAPI IDirectMusic8Impl_EnumPort(LPDIRECTMUSIC8 iface, DWORD index, LPDMUS_PORTCAPS port_caps)
|
||||||
{
|
{
|
||||||
IDirectMusic8Impl *This = impl_from_IDirectMusic8(iface);
|
IDirectMusic8Impl *This = impl_from_IDirectMusic8(iface);
|
||||||
ULONG nb_midi_out;
|
|
||||||
ULONG nb_midi_in;
|
|
||||||
const WCHAR emulated[] = {' ','[','E','m','u','l','a','t','e','d',']',0};
|
|
||||||
|
|
||||||
TRACE("(%p, %d, %p)\n", This, index, port_caps);
|
TRACE("(%p, %d, %p)\n", This, index, port_caps);
|
||||||
|
|
||||||
if (!port_caps)
|
if (!port_caps)
|
||||||
return E_POINTER;
|
return E_POINTER;
|
||||||
|
|
||||||
/* NOTE: It seems some native versions get the rest of devices through dmusic32.EnumLegacyDevices...*sigh*...which is undocumented */
|
if (index >= This->nb_system_ports)
|
||||||
|
return S_FALSE;
|
||||||
|
|
||||||
/* NOTE: Should we enum wave devices ? Native does not seem to */
|
*port_caps = This->system_ports[index].caps;
|
||||||
|
|
||||||
/* Fill common port caps for winmm ports */
|
return S_OK;
|
||||||
port_caps->dwType = DMUS_PORT_WINMM_DRIVER;
|
|
||||||
port_caps->dwMemorySize = 0;
|
|
||||||
port_caps->dwMaxChannelGroups = 1;
|
|
||||||
port_caps->dwMaxVoices = 0;
|
|
||||||
port_caps->dwMaxAudioChannels = 0;
|
|
||||||
port_caps->dwEffectFlags = DMUS_EFFECT_NONE;
|
|
||||||
/* Fake port GUID */
|
|
||||||
port_caps->guidPort = IID_IUnknown;
|
|
||||||
port_caps->guidPort.Data1 = index + 1;
|
|
||||||
|
|
||||||
nb_midi_out = midiOutGetNumDevs();
|
|
||||||
|
|
||||||
if (index == 0)
|
|
||||||
{
|
|
||||||
MIDIOUTCAPSW caps;
|
|
||||||
midiOutGetDevCapsW(MIDI_MAPPER, &caps, sizeof(caps));
|
|
||||||
strcpyW(port_caps->wszDescription, caps.szPname);
|
|
||||||
strcatW(port_caps->wszDescription, emulated);
|
|
||||||
port_caps->dwFlags = DMUS_PC_SHAREABLE;
|
|
||||||
port_caps->dwClass = DMUS_PC_OUTPUTCLASS;
|
|
||||||
TRACE("Enumerating port: %s\n", debugstr_w(port_caps->wszDescription));
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (index < (nb_midi_out + 1))
|
|
||||||
{
|
|
||||||
MIDIOUTCAPSW caps;
|
|
||||||
midiOutGetDevCapsW(index - 1, &caps, sizeof(caps));
|
|
||||||
strcpyW(port_caps->wszDescription, caps.szPname);
|
|
||||||
strcatW(port_caps->wszDescription, emulated);
|
|
||||||
port_caps->dwFlags = DMUS_PC_SHAREABLE | DMUS_PC_EXTERNAL;
|
|
||||||
port_caps->dwClass = DMUS_PC_OUTPUTCLASS;
|
|
||||||
TRACE("Enumerating port: %s\n", debugstr_w(port_caps->wszDescription));
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
nb_midi_in = midiInGetNumDevs();
|
|
||||||
|
|
||||||
if (index < (nb_midi_in + nb_midi_out + 1))
|
|
||||||
{
|
|
||||||
MIDIINCAPSW caps;
|
|
||||||
midiInGetDevCapsW(index - nb_midi_out - 1, &caps, sizeof(caps));
|
|
||||||
strcpyW(port_caps->wszDescription, caps.szPname);
|
|
||||||
strcatW(port_caps->wszDescription, emulated);
|
|
||||||
port_caps->dwFlags = DMUS_PC_EXTERNAL;
|
|
||||||
port_caps->dwClass = DMUS_PC_INPUTCLASS;
|
|
||||||
TRACE("Enumerating port: %s\n", debugstr_w(port_caps->wszDescription));
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (index == (nb_midi_in + nb_midi_out + 1))
|
|
||||||
{
|
|
||||||
IDirectMusicSynth8* synth = NULL;
|
|
||||||
HRESULT hr;
|
|
||||||
hr = CoCreateInstance(&CLSID_DirectMusicSynth, NULL, CLSCTX_INPROC_SERVER, &IID_IDirectMusicSynth8, (void**)&synth);
|
|
||||||
if (SUCCEEDED(hr))
|
|
||||||
hr = IDirectMusicSynth8_GetPortCaps(synth, port_caps);
|
|
||||||
if (SUCCEEDED(hr))
|
|
||||||
TRACE("Enumerating port: %s\n", debugstr_w(port_caps->wszDescription));
|
|
||||||
if (synth)
|
|
||||||
IDirectMusicSynth8_Release(synth);
|
|
||||||
return hr;
|
|
||||||
}
|
|
||||||
|
|
||||||
return S_FALSE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static HRESULT WINAPI IDirectMusic8Impl_CreateMusicBuffer(LPDIRECTMUSIC8 iface, LPDMUS_BUFFERDESC buffer_desc, LPDIRECTMUSICBUFFER* buffer, LPUNKNOWN unkouter)
|
static HRESULT WINAPI IDirectMusic8Impl_CreateMusicBuffer(LPDIRECTMUSIC8 iface, LPDMUS_BUFFERDESC buffer_desc, LPDIRECTMUSICBUFFER* buffer, LPUNKNOWN unkouter)
|
||||||
|
@ -222,7 +156,7 @@ static HRESULT WINAPI IDirectMusic8Impl_CreatePort(LPDIRECTMUSIC8 iface, REFCLSI
|
||||||
|
|
||||||
for (i = 0; S_FALSE != IDirectMusic8Impl_EnumPort(iface, i, &PortCaps); i++) {
|
for (i = 0; S_FALSE != IDirectMusic8Impl_EnumPort(iface, i, &PortCaps); i++) {
|
||||||
if (IsEqualCLSID (request_port, &PortCaps.guidPort)) {
|
if (IsEqualCLSID (request_port, &PortCaps.guidPort)) {
|
||||||
hr = DMUSIC_CreateDirectMusicPortImpl(&IID_IDirectMusicPort, (LPVOID*) &pNewPort, (LPUNKNOWN) This, pPortParams, &PortCaps);
|
hr = DMUSIC_CreateDirectMusicPortImpl(&IID_IDirectMusicPort, (LPVOID*) &pNewPort, (LPUNKNOWN) This, pPortParams, &PortCaps, 0);
|
||||||
if (FAILED(hr)) {
|
if (FAILED(hr)) {
|
||||||
*ppPort = NULL;
|
*ppPort = NULL;
|
||||||
return hr;
|
return hr;
|
||||||
|
@ -370,6 +304,101 @@ static const IDirectMusic8Vtbl DirectMusic8_Vtbl = {
|
||||||
IDirectMusic8Impl_SetExternalMasterClock
|
IDirectMusic8Impl_SetExternalMasterClock
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static void create_system_ports_list(IDirectMusic8Impl* object)
|
||||||
|
{
|
||||||
|
port_info * port;
|
||||||
|
const WCHAR emulated[] = {' ','[','E','m','u','l','a','t','e','d',']',0};
|
||||||
|
ULONG nb_ports;
|
||||||
|
ULONG nb_midi_out;
|
||||||
|
ULONG nb_midi_in;
|
||||||
|
MIDIOUTCAPSW caps_out;
|
||||||
|
MIDIINCAPSW caps_in;
|
||||||
|
IDirectMusicSynth8* synth;
|
||||||
|
HRESULT hr;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
TRACE("(%p)\n", object);
|
||||||
|
|
||||||
|
/* NOTE:
|
||||||
|
- it seems some native versions get the rest of devices through dmusic32.EnumLegacyDevices...*sigh*...which is undocumented
|
||||||
|
- should we enum wave devices ? Native does not seem to
|
||||||
|
*/
|
||||||
|
|
||||||
|
nb_midi_out = midiOutGetNumDevs();
|
||||||
|
nb_midi_in = midiInGetNumDevs();
|
||||||
|
nb_ports = 1 /* midi mapper */ + nb_midi_out + nb_midi_in + 1 /* synth port */;
|
||||||
|
|
||||||
|
port = object->system_ports = HeapAlloc(GetProcessHeap(), 0, nb_ports * sizeof(port_info));
|
||||||
|
if (!object->system_ports)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* Fill common port caps for all winmm ports */
|
||||||
|
for (i = 0; i < (nb_ports - 1 /* synth port*/); i++)
|
||||||
|
{
|
||||||
|
object->system_ports[i].caps.dwSize = sizeof(DMUS_PORTCAPS);
|
||||||
|
object->system_ports[i].caps.dwType = DMUS_PORT_WINMM_DRIVER;
|
||||||
|
object->system_ports[i].caps.dwMemorySize = 0;
|
||||||
|
object->system_ports[i].caps.dwMaxChannelGroups = 1;
|
||||||
|
object->system_ports[i].caps.dwMaxVoices = 0;
|
||||||
|
object->system_ports[i].caps.dwMaxAudioChannels = 0;
|
||||||
|
object->system_ports[i].caps.dwEffectFlags = DMUS_EFFECT_NONE;
|
||||||
|
/* Fake port GUID */
|
||||||
|
object->system_ports[i].caps.guidPort = IID_IUnknown;
|
||||||
|
object->system_ports[i].caps.guidPort.Data1 = i + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Fill midi mapper port info */
|
||||||
|
port->device = MIDI_MAPPER;
|
||||||
|
port->create = DMUSIC_CreateDirectMusicPortImpl; /* FIXME: The same for all ports for now */
|
||||||
|
midiOutGetDevCapsW(MIDI_MAPPER, &caps_out, sizeof(caps_out));
|
||||||
|
strcpyW(port->caps.wszDescription, caps_out.szPname);
|
||||||
|
strcatW(port->caps.wszDescription, emulated);
|
||||||
|
port->caps.dwFlags = DMUS_PC_SHAREABLE;
|
||||||
|
port->caps.dwClass = DMUS_PC_OUTPUTCLASS;
|
||||||
|
port++;
|
||||||
|
|
||||||
|
/* Fill midi out port info */
|
||||||
|
for (i = 0; i < nb_midi_out; i++)
|
||||||
|
{
|
||||||
|
port->device = i;
|
||||||
|
port->create = DMUSIC_CreateDirectMusicPortImpl; /* FIXME: The same for all ports for now */
|
||||||
|
midiOutGetDevCapsW(i, &caps_out, sizeof(caps_out));
|
||||||
|
strcpyW(port->caps.wszDescription, caps_in.szPname);
|
||||||
|
strcatW(port->caps.wszDescription, emulated);
|
||||||
|
port->caps.dwFlags = DMUS_PC_SHAREABLE | DMUS_PC_EXTERNAL;
|
||||||
|
port->caps.dwClass = DMUS_PC_OUTPUTCLASS;
|
||||||
|
port++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Fill midi in port info */
|
||||||
|
for (i = 0; i < nb_midi_in; i++)
|
||||||
|
{
|
||||||
|
port->device = i;
|
||||||
|
port->create = DMUSIC_CreateDirectMusicPortImpl; /* FIXME: The same for all ports for now */
|
||||||
|
midiInGetDevCapsW(i, &caps_in, sizeof(caps_in));
|
||||||
|
strcpyW(port->caps.wszDescription, caps_in.szPname);
|
||||||
|
strcatW(port->caps.wszDescription, emulated);
|
||||||
|
port->caps.dwFlags = DMUS_PC_EXTERNAL;
|
||||||
|
port->caps.dwClass = DMUS_PC_INPUTCLASS;
|
||||||
|
port++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Fill synth port info */
|
||||||
|
port->create = DMUSIC_CreateDirectMusicPortImpl; /* FIXME: The same for all ports for now */
|
||||||
|
hr = CoCreateInstance(&CLSID_DirectMusicSynth, NULL, CLSCTX_INPROC_SERVER, &IID_IDirectMusicSynth8, (void**)&synth);
|
||||||
|
if (SUCCEEDED(hr))
|
||||||
|
{
|
||||||
|
hr = IDirectMusicSynth8_GetPortCaps(synth, &port->caps);
|
||||||
|
IDirectMusicSynth8_Release(synth);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
nb_ports--;
|
||||||
|
}
|
||||||
|
|
||||||
|
object->nb_system_ports = nb_ports;
|
||||||
|
}
|
||||||
|
|
||||||
/* For ClassFactory */
|
/* For ClassFactory */
|
||||||
HRESULT WINAPI DMUSIC_CreateDirectMusicImpl(LPCGUID riid, LPVOID* ret_iface, LPUNKNOWN unkouter)
|
HRESULT WINAPI DMUSIC_CreateDirectMusicImpl(LPCGUID riid, LPVOID* ret_iface, LPUNKNOWN unkouter)
|
||||||
{
|
{
|
||||||
|
@ -402,5 +431,7 @@ HRESULT WINAPI DMUSIC_CreateDirectMusicImpl(LPCGUID riid, LPVOID* ret_iface, LPU
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
create_system_ports_list(dmusic);
|
||||||
|
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
|
@ -72,6 +72,12 @@ typedef struct DMUSIC_PRIVATE_CHANNEL_GROUP_ {
|
||||||
DMUSIC_PRIVATE_MCHANNEL channel[16]; /* 16 channels in a group */
|
DMUSIC_PRIVATE_MCHANNEL channel[16]; /* 16 channels in a group */
|
||||||
} DMUSIC_PRIVATE_CHANNEL_GROUP, *LPDMUSIC_PRIVATE_CHANNEL_GROUP;
|
} DMUSIC_PRIVATE_CHANNEL_GROUP, *LPDMUSIC_PRIVATE_CHANNEL_GROUP;
|
||||||
|
|
||||||
|
typedef struct port_info {
|
||||||
|
DMUS_PORTCAPS caps;
|
||||||
|
HRESULT (*create)(LPCGUID guid, LPVOID *object, LPUNKNOWN unkouter, LPDMUS_PORTPARAMS port_params, LPDMUS_PORTCAPS port_caps, DWORD device);
|
||||||
|
ULONG device;
|
||||||
|
} port_info;
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
* ClassFactory
|
* ClassFactory
|
||||||
|
@ -100,6 +106,8 @@ struct IDirectMusic8Impl {
|
||||||
IReferenceClockImpl* pMasterClock;
|
IReferenceClockImpl* pMasterClock;
|
||||||
IDirectMusicPort** ppPorts;
|
IDirectMusicPort** ppPorts;
|
||||||
int nrofports;
|
int nrofports;
|
||||||
|
port_info* system_ports;
|
||||||
|
int nb_system_ports;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
|
@ -161,7 +169,7 @@ struct IDirectMusicPortImpl {
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Internal factory */
|
/** Internal factory */
|
||||||
extern HRESULT DMUSIC_CreateDirectMusicPortImpl (LPCGUID lpcGUID, LPVOID *ppobj, LPUNKNOWN pUnkOuter, LPDMUS_PORTPARAMS pPortParams, LPDMUS_PORTCAPS pPortCaps) DECLSPEC_HIDDEN;
|
extern HRESULT DMUSIC_CreateDirectMusicPortImpl(LPCGUID lpcGUID, LPVOID *ppobj, LPUNKNOWN pUnkOuter, LPDMUS_PORTPARAMS pPortParams, LPDMUS_PORTCAPS pPortCaps, DWORD device) DECLSPEC_HIDDEN;
|
||||||
|
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
* IReferenceClockImpl implementation structure
|
* IReferenceClockImpl implementation structure
|
||||||
|
|
|
@ -473,12 +473,13 @@ static const IDirectMusicThruVtbl DirectMusicThru_Vtbl = {
|
||||||
IDirectMusicThruImpl_ThruChannel
|
IDirectMusicThruImpl_ThruChannel
|
||||||
};
|
};
|
||||||
|
|
||||||
HRESULT DMUSIC_CreateDirectMusicPortImpl (LPCGUID lpcGUID, LPVOID *ppobj, LPUNKNOWN pUnkOuter, LPDMUS_PORTPARAMS pPortParams, LPDMUS_PORTCAPS pPortCaps) {
|
HRESULT DMUSIC_CreateDirectMusicPortImpl(LPCGUID lpcGUID, LPVOID *ppobj, LPUNKNOWN pUnkOuter, LPDMUS_PORTPARAMS pPortParams, LPDMUS_PORTCAPS pPortCaps, DWORD device)
|
||||||
|
{
|
||||||
IDirectMusicPortImpl *obj;
|
IDirectMusicPortImpl *obj;
|
||||||
HRESULT hr = E_FAIL;
|
HRESULT hr = E_FAIL;
|
||||||
UINT j;
|
UINT j;
|
||||||
|
|
||||||
TRACE("(%p,%p,%p)\n", lpcGUID, ppobj, pUnkOuter);
|
TRACE("(%p,%p,%p,%d)\n", lpcGUID, ppobj, pUnkOuter, device);
|
||||||
|
|
||||||
obj = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirectMusicPortImpl));
|
obj = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirectMusicPortImpl));
|
||||||
if (NULL == obj) {
|
if (NULL == obj) {
|
||||||
|
|
Loading…
Reference in New Issue