Through property sets, DirectMusic is able to provide unlimited support for new features in hardware and drivers. A property set is associated with a particular port.
Hardware vendors define new capabilities as properties and publish the specification for these properties, including GUIDs. You, the application developer, can then use the IKsControl::KsProperty method to find out whether a property is available and then to set and retrieve values for that property. You obtain the IKsControl interface for a port by calling the IDirectMusicPort::QueryInterface method, passing IID_IKsControl as the interface identifier.
A property set is represented by a GUID, and each item within the set is represented by a zero-based index. The meaning of the indexed items for a GUID never changes. For a list of the property sets supported by DirectMusic, see KSPROPERTY.
All property sets predefined by DirectMusic have only one item, usually at index 0. However, the full definition of kernel streaming (KS) properties is supported, and vendors are free to create property sets with any number of items and instances and data of any size.
Routing of the property item request to the port varies depending on the port implementation. No properties are supported by ports which represent DirectMusic emulation on top of the Win32 handle-based multimedia calls (midiOut and midiIn functions).
The following code uses the IKsControl::KsProperty method to determine if the port supports General MIDI in hardware:
BOOL IsGMSupported(IDirectMusicPort *pPort)
{
HRESULT hr;
IKsControl *pControl;
KSPROPERTY ksp;
DWORD dwFlags;
ULONG cb;
BOOL fIsSupported;
// Query for IKsControl interface
hr = pPort->QueryInterface(IID_IKsControl, (void**)&pControl);
if (FAILED(hr))
{
// Port does not support properties, assume no GM support
return FALSE;
}
// Ask about GM
ksp.Set = GUID_DMUS_PROP_GM_Hardware;
ksp.Id = 0;
ksp.Flags = KSPROPERTY_TYPE_BASICSUPPORT;
hr = pControl->KsProperty(&ksp, sizeof(ksp),
&dwFlags, sizeof(dwFlags), &cb);
fIsSupported = FALSE;
if (SUCCEEDED(hr) || (cb >= sizeof(dwFlags))
{
// Set is supported
fIsSupported = (BOOL)(dwFlags & KSPROPERTY_TYPE_GET);
}
pControl->Release();
return fIsSupported;
}
The following sample code shows how a property can be changed. In this case, the reverberation properties of the software synthesizer are set to those contained in a DMUS_WAVES_REVERB_PARAMS structure.
/* Assume that m_* variables have been initialized to valid values.
m_pPort is a pointer to IDirectMusicPort. */
DMUS_WAVES_REVERB_PARAMS Params;
Params.fInGain = m_fReverbIn;
Params.fHighFreqRTRatio = m_fReverbHigh;
Params.fReverbMix = m_fReverbMix;
Params.fReverbTime = m_fReverbTime;
IKsControl *pControl;
if (m_pPort)
{
// Query for IKsControl interface
HRESULT hr = m_pPort->QueryInterface(IID_IKsControl,
(void**)&pControl);
if (SUCCEEDED(hr))
{
KSPROPERTY ksp;
ULONG cb;
ZeroMemory(&ksp, sizeof(ksp));
ksp.Set = GUID_DMUS_PROP_WavesReverb;
ksp.Id = 0;
ksp.Flags = KSPROPERTY_TYPE_SET;
pControl->KsProperty(&ksp,
sizeof(ksp),
(LPVOID)&Params,
sizeof(Params),
&cb);
pControl->Release();
}
}
The following code actually turns on the reverb effect for the port represented by m_pPort:
DWORD dwEffects = 0;
IKsControl *pControl;
HRESULT hr = m_pPort->QueryInterface(IID_IKsControl,
(void**)&pControl);
if (SUCCEEDED(hr))
{
KSPROPERTY ksp;
ULONG cb;
ZeroMemory(&ksp, sizeof(ksp));
dwEffects = DMUS_EFFECT_REVERB;
ksp.Set = GUID_DMUS_PROP_Effects;
ksp.Id = 0;
ksp.Flags = KSPROPERTY_TYPE_SET;
pControl->KsProperty(&ksp,
sizeof(ksp),
(LPVOID)&dwEffects,
sizeof(dwEffects),
&cb);
pControl->Release();
}
The final example shows how you might turn off reverb while leaving any other effects intact:
DWORD dwEffects = 0;
IKsControl *pControl;
HRESULT hr = m_pPort->QueryInterface(IID_IKsControl,
(void**)&pControl);
if (SUCCEEDED(hr))
{
KSPROPERTY ksp;
ULONG cb;
ZeroMemory(&ksp, sizeof(ksp));
ksp.Set = GUID_DMUS_PROP_Effects;
ksp.Id = 0;
ksp.Flags = KSPROPERTY_TYPE_GET;
pControl->KsProperty(&ksp,
sizeof(ksp),
(LPVOID)&dwEffects,
sizeof(dwEffects),
&cb);
ZeroMemory(&ksp, sizeof(ksp));
dwEffects = dwEffects & ~DMUS_EFFECT_REVERB;
ksp.Set = GUID_DMUS_PROP_Effects;
ksp.Id = 0;
ksp.Flags = KSPROPERTY_TYPE_SET;
pControl->KsProperty(&ksp,
sizeof(ksp),
(LPVOID)&dwEffects,
sizeof(dwEffects),
&cb);
pControl->Release();
}