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);
|
||||
|
||||
if (!ref) {
|
||||
HeapFree(GetProcessHeap(), 0, This->system_ports);
|
||||
HeapFree(GetProcessHeap(), 0, This->ppPorts);
|
||||
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)
|
||||
{
|
||||
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);
|
||||
|
||||
if (!port_caps)
|
||||
return E_POINTER;
|
||||
|
||||
/* NOTE: It seems some native versions get the rest of devices through dmusic32.EnumLegacyDevices...*sigh*...which is undocumented */
|
||||
|
||||
/* NOTE: Should we enum wave devices ? Native does not seem to */
|
||||
|
||||
/* Fill common port caps for winmm ports */
|
||||
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;
|
||||
}
|
||||
|
||||
if (index >= This->nb_system_ports)
|
||||
return S_FALSE;
|
||||
|
||||
*port_caps = This->system_ports[index].caps;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
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++) {
|
||||
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)) {
|
||||
*ppPort = NULL;
|
||||
return hr;
|
||||
|
@ -370,6 +304,101 @@ static const IDirectMusic8Vtbl DirectMusic8_Vtbl = {
|
|||
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 */
|
||||
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;
|
||||
}
|
||||
|
||||
create_system_ports_list(dmusic);
|
||||
|
||||
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_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
|
||||
|
@ -100,6 +106,8 @@ struct IDirectMusic8Impl {
|
|||
IReferenceClockImpl* pMasterClock;
|
||||
IDirectMusicPort** ppPorts;
|
||||
int nrofports;
|
||||
port_info* system_ports;
|
||||
int nb_system_ports;
|
||||
};
|
||||
|
||||
/*****************************************************************************
|
||||
|
@ -161,7 +169,7 @@ struct IDirectMusicPortImpl {
|
|||
};
|
||||
|
||||
/** 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
|
||||
|
|
|
@ -473,12 +473,13 @@ static const IDirectMusicThruVtbl DirectMusicThru_Vtbl = {
|
|||
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;
|
||||
HRESULT hr = E_FAIL;
|
||||
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));
|
||||
if (NULL == obj) {
|
||||
|
|
Loading…
Reference in New Issue