dmusic: Create the list of available system ports at the beginning and use it to enumerate ports.

This commit is contained in:
Christian Costa 2012-09-16 20:24:10 +02:00 committed by Alexandre Julliard
parent 649a177007
commit 66a817f067
3 changed files with 115 additions and 75 deletions

View File

@ -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;
}

View File

@ -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

View File

@ -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) {