Through the IKsPropertySet interface, DirectSound is able to support extended services offered by sound cards and their associated drivers.
Properties are arranged in sets. A GUID identifies a set, and a ULONG identifies a particular property within the set. For example, a hardware vendor might design a card capable of reverberation effects and define a property set DSPROPSETID_ReverbProperties containing properties such as DSPROPERTY_REVERBPROPERTIES_HALL and DSPROPERTY_REVERBPROPERTIES_STADIUM.
Typically, the property identifiers are defined using a C language enumeration starting at ordinal 0.
Individual properties may also have associated parameters. The IKsPropertySet interface specification intentionally leaves these parameters undefined, allowing the designer of the property set to use them in a way most beneficial to the properties within the set being designed. The precise meaning of the parameters is defined with the definition of the properties.
To make use of extended properties on sound cards, you must first determine whether the driver supports the IKsPropertySet interface, and obtain a pointer to the interface if it is supported. You can do this by calling the QueryInterface method of an existing interface on a DirectSound3DBuffer object.
HRESULT hr = lpDirectSound3DBuffer->QueryInterface(
IID_IKsPropertySet,
(void**)&lpKsPropertySet))
In the example, lpDirectSound3DBuffer is a pointer to the buffer's interface and lpKsPropertySet receives the address of the IKsPropertySet interface if one is found. IID_IKsPropertySet is a GUID defined in Dsound.h.
The call will succeed only if the buffer is hardware-accelerated and the underlying driver supports property sets. If it does succeed, you can now look for a particular property using the IKsPropertySet::QuerySupport method. The value of the PropertySetId parameter is a GUID defined by the hardware vendor.
Once you've determined that support for a particular property exists, you can change the state of the property by using the IKsPropertySet::Set method and determine its present state by using the IKsPropertySet::Get method. The state of the property is set or returned in the pPropertyData parameter.
Additional property parameters may also be passed to the object in a structure pointed to by the pPropertyParams parameter to the IKsPropertySet::Set method. The exact way in which this parameter is to be used is defined in the hardware vendor's specifications for the property set, but typically it would be used to define the instance of the property set. In practice, the pPropertyParams parameter is rarely used.
Let's take a somewhat whimsical example. Suppose a sound card has the ability to play famous arias in the voices of several tenors. The driver developer creates a property set, DSPROPSETID_Aria, containing properties like DSPROPERTY_ARIA_VESTI_LA_GIUBBA and DSPROPERTY_ARIA_CHE_GELIDA_MANINA. The property set applies to all of the tenors, and the driver developer has specified that pPropertyParams defines the tenor instance. Now you, the application developer, want to make Caruso sing the great aria from Pagliacci.
DWORD WhichTenor = CARUSO;
BOOL StartOrStop = START;
HRESULT hr = lpKsPropertySet->Set(
DSPROPSETID_Aria,
KSPROPERTY_ARIA_VESTI_LA_GIUBBA,
&WhichTenor,
sizeof(WhichTenor),
&StartOrStop),
sizeof(StartOrStop));