You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
827 lines
20 KiB
827 lines
20 KiB
//--------------------------------------------------------------------------;
|
|
//
|
|
// File: dslevel.cpp
|
|
//
|
|
// Copyright (c) 1997 Microsoft Corporation. All rights reserved
|
|
//
|
|
//--------------------------------------------------------------------------;
|
|
|
|
|
|
#include "mmcpl.h"
|
|
|
|
#include <windowsx.h>
|
|
#ifdef DEBUG
|
|
#undef DEBUG
|
|
#include <mmsystem.h>
|
|
#define DEBUG
|
|
#else
|
|
#include <mmsystem.h>
|
|
#endif
|
|
#include <commctrl.h>
|
|
#include <prsht.h>
|
|
#include <regstr.h>
|
|
|
|
#include "utils.h"
|
|
#include "medhelp.h"
|
|
#include "dslevel.h"
|
|
#include "perfpage.h"
|
|
#include "speakers.h"
|
|
|
|
#include <initguid.h>
|
|
#include <dsound.h>
|
|
#include <dsprv.h>
|
|
|
|
#define REG_KEY_SPEAKERTYPE TEXT("Speaker Type")
|
|
|
|
typedef HRESULT (STDAPICALLTYPE *LPFNDLLGETCLASSOBJECT)(REFCLSID, REFIID, LPVOID *);
|
|
typedef HRESULT (STDAPICALLTYPE *LPFNDIRECTSOUNDCREATE)(LPGUID, LPDIRECTSOUND*, IUnknown FAR *);
|
|
typedef HRESULT (STDAPICALLTYPE *LPFNDIRECTSOUNDCAPTURECREATE)(LPGUID, LPDIRECTSOUNDCAPTURE*, IUnknown FAR *);
|
|
|
|
|
|
HRESULT
|
|
DirectSoundPrivateCreate
|
|
(
|
|
OUT LPKSPROPERTYSET * ppKsPropertySet
|
|
)
|
|
{
|
|
HMODULE hLibDsound = NULL;
|
|
LPFNDLLGETCLASSOBJECT pfnDllGetClassObject = NULL;
|
|
LPCLASSFACTORY pClassFactory = NULL;
|
|
LPKSPROPERTYSET pKsPropertySet = NULL;
|
|
HRESULT hr = DS_OK;
|
|
|
|
// Load dsound.dll
|
|
hLibDsound = LoadLibrary(TEXT("dsound.dll"));
|
|
|
|
if(!hLibDsound)
|
|
{
|
|
hr = DSERR_GENERIC;
|
|
}
|
|
|
|
// Find DllGetClassObject
|
|
if(SUCCEEDED(hr))
|
|
{
|
|
pfnDllGetClassObject =
|
|
(LPFNDLLGETCLASSOBJECT)GetProcAddress
|
|
(
|
|
hLibDsound,
|
|
"DllGetClassObject"
|
|
);
|
|
|
|
if(!pfnDllGetClassObject)
|
|
{
|
|
hr = DSERR_GENERIC;
|
|
}
|
|
}
|
|
|
|
// Create a class factory object
|
|
if(SUCCEEDED(hr))
|
|
{
|
|
hr =
|
|
pfnDllGetClassObject
|
|
(
|
|
CLSID_DirectSoundPrivate,
|
|
IID_IClassFactory,
|
|
(LPVOID *)&pClassFactory
|
|
);
|
|
}
|
|
|
|
// Create the DirectSoundPrivate object and query for an IKsPropertySet
|
|
// interface
|
|
if(SUCCEEDED(hr))
|
|
{
|
|
hr =
|
|
pClassFactory->CreateInstance
|
|
(
|
|
NULL,
|
|
IID_IKsPropertySet,
|
|
(LPVOID *)&pKsPropertySet
|
|
);
|
|
}
|
|
|
|
// Release the class factory
|
|
if(pClassFactory)
|
|
{
|
|
pClassFactory->Release();
|
|
}
|
|
|
|
// Handle final success or failure
|
|
if(SUCCEEDED(hr))
|
|
{
|
|
*ppKsPropertySet = pKsPropertySet;
|
|
}
|
|
else if(pKsPropertySet)
|
|
{
|
|
pKsPropertySet->Release();
|
|
}
|
|
|
|
FreeLibrary(hLibDsound);
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
HRESULT
|
|
DSGetGuidFromName
|
|
(
|
|
IN LPTSTR szName,
|
|
IN BOOL fRecord,
|
|
OUT LPGUID pGuid
|
|
)
|
|
{
|
|
LPKSPROPERTYSET pKsPropertySet = NULL;
|
|
HRESULT hr;
|
|
|
|
DSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING_DATA
|
|
WaveDeviceMap;
|
|
|
|
// Create the DirectSoundPrivate object
|
|
hr =
|
|
DirectSoundPrivateCreate
|
|
(
|
|
&pKsPropertySet
|
|
);
|
|
|
|
// Attempt to map the waveIn/waveOut device string to a DirectSound device
|
|
// GUID.
|
|
if(SUCCEEDED(hr))
|
|
{
|
|
WaveDeviceMap.DeviceName = szName;
|
|
WaveDeviceMap.DataFlow = fRecord ? DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE : DIRECTSOUNDDEVICE_DATAFLOW_RENDER;
|
|
|
|
hr =
|
|
pKsPropertySet->Get
|
|
(
|
|
DSPROPSETID_DirectSoundDevice,
|
|
DSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING,
|
|
NULL,
|
|
0,
|
|
&WaveDeviceMap,
|
|
sizeof(WaveDeviceMap),
|
|
NULL
|
|
);
|
|
}
|
|
|
|
// Clean up
|
|
if(pKsPropertySet)
|
|
{
|
|
pKsPropertySet->Release();
|
|
}
|
|
|
|
if(SUCCEEDED(hr))
|
|
{
|
|
*pGuid = WaveDeviceMap.DeviceId;
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
HRESULT
|
|
DSSetupFunctions
|
|
(
|
|
LPFNDIRECTSOUNDCREATE* pfnDSCreate,
|
|
LPFNDIRECTSOUNDCAPTURECREATE* pfnDSCaptureCreate
|
|
)
|
|
{
|
|
HMODULE hLibDsound = NULL;
|
|
HRESULT hr = DS_OK;
|
|
|
|
// Load dsound.dll
|
|
hLibDsound = LoadLibrary(TEXT("dsound.dll"));
|
|
|
|
if(!hLibDsound)
|
|
{
|
|
hr = DSERR_GENERIC;
|
|
}
|
|
|
|
// Find DirectSoundCreate
|
|
if(SUCCEEDED(hr))
|
|
{
|
|
*pfnDSCreate =
|
|
(LPFNDIRECTSOUNDCREATE)GetProcAddress
|
|
(
|
|
hLibDsound,
|
|
"DirectSoundCreate"
|
|
);
|
|
|
|
if(!(*pfnDSCreate))
|
|
{
|
|
hr = DSERR_GENERIC;
|
|
}
|
|
} //end DirectSoundCreate
|
|
|
|
// Find DirectSoundCaptureCreate
|
|
if(SUCCEEDED(hr))
|
|
{
|
|
*pfnDSCaptureCreate =
|
|
(LPFNDIRECTSOUNDCAPTURECREATE)GetProcAddress
|
|
(
|
|
hLibDsound,
|
|
"DirectSoundCaptureCreate"
|
|
);
|
|
|
|
if(!(*pfnDSCaptureCreate))
|
|
{
|
|
hr = DSERR_GENERIC;
|
|
}
|
|
} //end DirectSoundCaptureCreate
|
|
|
|
FreeLibrary(hLibDsound);
|
|
|
|
return (hr);
|
|
}
|
|
|
|
void
|
|
DSCleanup
|
|
(
|
|
IN LPKSPROPERTYSET pKsPropertySet,
|
|
IN LPDIRECTSOUND pDirectSound,
|
|
IN LPDIRECTSOUNDCAPTURE pDirectSoundCapture
|
|
)
|
|
{
|
|
if(pKsPropertySet)
|
|
{
|
|
pKsPropertySet->Release();
|
|
}
|
|
|
|
if(pDirectSound)
|
|
{
|
|
pDirectSound->Release();
|
|
}
|
|
|
|
if(pDirectSoundCapture)
|
|
{
|
|
pDirectSoundCapture->Release();
|
|
}
|
|
}
|
|
|
|
HRESULT
|
|
DSInitialize
|
|
(
|
|
IN GUID guid,
|
|
IN BOOL fRecord,
|
|
OUT LPKSPROPERTYSET* ppKsPropertySet,
|
|
OUT LPLPDIRECTSOUND ppDirectSound,
|
|
OUT LPLPDIRECTSOUNDCAPTURE ppDirectSoundCapture
|
|
)
|
|
{
|
|
HRESULT hr;
|
|
|
|
LPFNDIRECTSOUNDCREATE pfnDirectSoundCreate = NULL;
|
|
LPFNDIRECTSOUNDCAPTURECREATE pfnDirectSoundCaptureCreate = NULL;
|
|
|
|
// Initialize variables to return
|
|
*ppKsPropertySet = NULL;
|
|
*ppDirectSound = NULL;
|
|
*ppDirectSoundCapture = NULL;
|
|
|
|
// Find the necessary DirectSound functions
|
|
hr = DSSetupFunctions(&pfnDirectSoundCreate, &pfnDirectSoundCaptureCreate);
|
|
|
|
if (FAILED(hr))
|
|
{
|
|
return (hr);
|
|
}
|
|
|
|
// Create the DirectSound object
|
|
if(fRecord)
|
|
{
|
|
hr =
|
|
pfnDirectSoundCaptureCreate
|
|
(
|
|
&guid,
|
|
ppDirectSoundCapture,
|
|
NULL
|
|
);
|
|
}
|
|
else
|
|
{
|
|
hr =
|
|
pfnDirectSoundCreate
|
|
(
|
|
&guid,
|
|
ppDirectSound,
|
|
NULL
|
|
);
|
|
}
|
|
|
|
// Create the DirectSoundPrivate object
|
|
if(SUCCEEDED(hr))
|
|
{
|
|
hr =
|
|
DirectSoundPrivateCreate
|
|
(
|
|
ppKsPropertySet
|
|
);
|
|
}
|
|
|
|
// Clean up
|
|
if(FAILED(hr))
|
|
{
|
|
DSCleanup
|
|
(
|
|
*ppKsPropertySet,
|
|
*ppDirectSound,
|
|
*ppDirectSoundCapture
|
|
);
|
|
*ppKsPropertySet = NULL;
|
|
*ppDirectSound = NULL;
|
|
*ppDirectSoundCapture = NULL;
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
HRESULT
|
|
DSGetAcceleration
|
|
(
|
|
IN GUID guid,
|
|
IN BOOL fRecord,
|
|
OUT LPDWORD pdwHWLevel
|
|
)
|
|
{
|
|
LPKSPROPERTYSET pKsPropertySet = NULL;
|
|
LPDIRECTSOUND pDirectSound = NULL;
|
|
LPDIRECTSOUNDCAPTURE pDirectSoundCapture = NULL;
|
|
HRESULT hr;
|
|
|
|
DSPROPERTY_DIRECTSOUNDBASICACCELERATION_ACCELERATION_DATA
|
|
BasicAcceleration;
|
|
|
|
// Find the necessary DirectSound functions
|
|
hr = DSInitialize(guid, fRecord, &pKsPropertySet, &pDirectSound, &pDirectSoundCapture );
|
|
|
|
// Get properties for this device
|
|
if(SUCCEEDED(hr))
|
|
{
|
|
BasicAcceleration.DeviceId = guid;
|
|
|
|
// Get the default acceleration level
|
|
hr =
|
|
pKsPropertySet->Get
|
|
(
|
|
DSPROPSETID_DirectSoundBasicAcceleration,
|
|
DSPROPERTY_DIRECTSOUNDBASICACCELERATION_DEFAULT,
|
|
NULL,
|
|
0,
|
|
&BasicAcceleration,
|
|
sizeof(BasicAcceleration),
|
|
NULL
|
|
);
|
|
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
gAudData.dwDefaultHWLevel = BasicAcceleration.Level;
|
|
}
|
|
|
|
// Get the basic HW acceleration level. This property will return
|
|
// S_FALSE if no error occurred, but the registry value did not exist.
|
|
|
|
|
|
hr =
|
|
pKsPropertySet->Get
|
|
(
|
|
DSPROPSETID_DirectSoundBasicAcceleration,
|
|
DSPROPERTY_DIRECTSOUNDBASICACCELERATION_ACCELERATION,
|
|
NULL,
|
|
0,
|
|
&BasicAcceleration,
|
|
sizeof(BasicAcceleration),
|
|
NULL
|
|
);
|
|
|
|
if(SUCCEEDED(hr))
|
|
{
|
|
*pdwHWLevel = BasicAcceleration.Level;
|
|
}
|
|
else
|
|
{
|
|
*pdwHWLevel = gAudData.dwDefaultHWLevel;
|
|
}
|
|
}
|
|
|
|
// Clean up
|
|
DSCleanup
|
|
(
|
|
pKsPropertySet,
|
|
pDirectSound,
|
|
pDirectSoundCapture
|
|
);
|
|
|
|
return hr;
|
|
}
|
|
|
|
HRESULT
|
|
DSGetSrcQuality
|
|
(
|
|
IN GUID guid,
|
|
IN BOOL fRecord,
|
|
OUT LPDWORD pdwSRCLevel
|
|
)
|
|
{
|
|
LPKSPROPERTYSET pKsPropertySet = NULL;
|
|
LPDIRECTSOUND pDirectSound = NULL;
|
|
LPDIRECTSOUNDCAPTURE pDirectSoundCapture = NULL;
|
|
HRESULT hr;
|
|
|
|
DSPROPERTY_DIRECTSOUNDMIXER_SRCQUALITY_DATA
|
|
SrcQuality;
|
|
|
|
// Find the necessary DirectSound functions
|
|
hr = DSInitialize(guid, fRecord, &pKsPropertySet, &pDirectSound, &pDirectSoundCapture );
|
|
|
|
// Get properties for this device
|
|
if(SUCCEEDED(hr))
|
|
{
|
|
// Get the mixer SRC quality. This property will return S_FALSE
|
|
// if no error occurred, but the registry value did not exist.
|
|
SrcQuality.DeviceId = guid;
|
|
|
|
hr =
|
|
pKsPropertySet->Get
|
|
(
|
|
DSPROPSETID_DirectSoundMixer,
|
|
DSPROPERTY_DIRECTSOUNDMIXER_SRCQUALITY,
|
|
NULL,
|
|
0,
|
|
&SrcQuality,
|
|
sizeof(SrcQuality),
|
|
NULL
|
|
);
|
|
|
|
if(SUCCEEDED(hr))
|
|
{
|
|
// The CPL only uses the 3 highest of 4 possible SRC values
|
|
*pdwSRCLevel = SrcQuality.Quality;
|
|
|
|
if(*pdwSRCLevel > 0)
|
|
{
|
|
(*pdwSRCLevel)--;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
*pdwSRCLevel = DEFAULT_SRC_LEVEL;
|
|
}
|
|
}
|
|
|
|
// Clean up
|
|
DSCleanup
|
|
(
|
|
pKsPropertySet,
|
|
pDirectSound,
|
|
pDirectSoundCapture
|
|
);
|
|
|
|
return hr;
|
|
}
|
|
|
|
HRESULT
|
|
DSGetSpeakerConfigType
|
|
(
|
|
IN GUID guid,
|
|
IN BOOL fRecord,
|
|
OUT LPDWORD pdwSpeakerConfig,
|
|
OUT LPDWORD pdwSpeakerType
|
|
)
|
|
{
|
|
LPKSPROPERTYSET pKsPropertySet = NULL;
|
|
LPDIRECTSOUND pDirectSound = NULL;
|
|
LPDIRECTSOUNDCAPTURE pDirectSoundCapture = NULL;
|
|
HRESULT hr = DS_OK;
|
|
HRESULT hrSpeakerType;
|
|
|
|
DSPROPERTY_DIRECTSOUNDPERSISTENTDATA_PERSISTDATA_DATA
|
|
SpeakerType;
|
|
|
|
// Can't get the speaker type if we're recording
|
|
if(fRecord)
|
|
{
|
|
hr = E_INVALIDARG;
|
|
}
|
|
|
|
// Find the necessary DirectSound functions
|
|
if(SUCCEEDED(hr))
|
|
{
|
|
hr = DSInitialize(guid, fRecord, &pKsPropertySet, &pDirectSound, &pDirectSoundCapture );
|
|
}
|
|
|
|
// Get properties for this device
|
|
if(SUCCEEDED(hr))
|
|
{
|
|
// Get the speaker config
|
|
hr =
|
|
pDirectSound->GetSpeakerConfig
|
|
(
|
|
pdwSpeakerConfig
|
|
);
|
|
|
|
if(FAILED(hr))
|
|
{
|
|
*pdwSpeakerConfig = DSSPEAKER_STEREO;
|
|
}
|
|
|
|
// Get the speaker type. This property will return failure
|
|
// if the registry value doesn't exist.
|
|
SpeakerType.DeviceId = guid;
|
|
SpeakerType.SubKeyName = REG_KEY_SPEAKERTYPE;
|
|
SpeakerType.ValueName = REG_KEY_SPEAKERTYPE;
|
|
SpeakerType.RegistryDataType = REG_DWORD;
|
|
SpeakerType.Data = pdwSpeakerType;
|
|
SpeakerType.DataSize = sizeof(pdwSpeakerType);
|
|
|
|
hrSpeakerType =
|
|
pKsPropertySet->Get
|
|
(
|
|
DSPROPSETID_DirectSoundPersistentData,
|
|
DSPROPERTY_DIRECTSOUNDPERSISTENTDATA_PERSISTDATA,
|
|
NULL,
|
|
0,
|
|
&SpeakerType,
|
|
sizeof(SpeakerType),
|
|
NULL
|
|
);
|
|
|
|
if(FAILED(hrSpeakerType))
|
|
{
|
|
*pdwSpeakerType = SPEAKERS_DEFAULT_TYPE;
|
|
}
|
|
}
|
|
|
|
// Clean up
|
|
DSCleanup
|
|
(
|
|
pKsPropertySet,
|
|
pDirectSound,
|
|
pDirectSoundCapture
|
|
);
|
|
|
|
return hr;
|
|
}
|
|
|
|
HRESULT
|
|
DSGetCplValues
|
|
(
|
|
IN GUID guid,
|
|
IN BOOL fRecord,
|
|
OUT LPCPLDATA pData
|
|
)
|
|
{
|
|
HRESULT hr;
|
|
|
|
// Get the basic HW acceleration level.
|
|
pData->dwHWLevel = gAudData.dwDefaultHWLevel;
|
|
hr = DSGetAcceleration
|
|
(
|
|
guid,
|
|
fRecord,
|
|
&pData->dwHWLevel
|
|
);
|
|
|
|
// Get the mixer SRC quality.
|
|
pData->dwSRCLevel = DEFAULT_SRC_LEVEL;
|
|
hr = DSGetSrcQuality
|
|
(
|
|
guid,
|
|
fRecord,
|
|
&pData->dwSRCLevel
|
|
);
|
|
|
|
// Get playback-specific settings
|
|
if(!fRecord)
|
|
{
|
|
// Get the speaker config
|
|
pData->dwSpeakerConfig = DSSPEAKER_STEREO;
|
|
pData->dwSpeakerType = SPEAKERS_DEFAULT_TYPE;
|
|
hr = DSGetSpeakerConfigType
|
|
(
|
|
guid,
|
|
fRecord,
|
|
&pData->dwSpeakerConfig,
|
|
&pData->dwSpeakerType
|
|
);
|
|
}
|
|
|
|
return DS_OK;
|
|
}
|
|
|
|
|
|
HRESULT
|
|
DSSetAcceleration
|
|
(
|
|
IN GUID guid,
|
|
IN BOOL fRecord,
|
|
IN DWORD dwHWLevel
|
|
)
|
|
{
|
|
LPKSPROPERTYSET pKsPropertySet = NULL;
|
|
LPDIRECTSOUND pDirectSound = NULL;
|
|
LPDIRECTSOUNDCAPTURE pDirectSoundCapture = NULL;
|
|
HRESULT hr;
|
|
|
|
DSPROPERTY_DIRECTSOUNDBASICACCELERATION_ACCELERATION_DATA
|
|
BasicAcceleration;
|
|
|
|
// Find the necessary DirectSound functions
|
|
hr = DSInitialize(guid, fRecord, &pKsPropertySet, &pDirectSound, &pDirectSoundCapture );
|
|
|
|
// Get properties for this device
|
|
if(SUCCEEDED(hr))
|
|
{
|
|
BasicAcceleration.DeviceId = guid;
|
|
BasicAcceleration.Level = (DIRECTSOUNDBASICACCELERATION_LEVEL)dwHWLevel;
|
|
|
|
// Set the basic HW acceleration level
|
|
hr =
|
|
pKsPropertySet->Set
|
|
(
|
|
DSPROPSETID_DirectSoundBasicAcceleration,
|
|
DSPROPERTY_DIRECTSOUNDBASICACCELERATION_ACCELERATION,
|
|
NULL,
|
|
0,
|
|
&BasicAcceleration,
|
|
sizeof(BasicAcceleration)
|
|
);
|
|
}
|
|
|
|
// Clean up
|
|
DSCleanup
|
|
(
|
|
pKsPropertySet,
|
|
pDirectSound,
|
|
pDirectSoundCapture
|
|
);
|
|
|
|
return hr;
|
|
}
|
|
|
|
HRESULT
|
|
DSSetSrcQuality
|
|
(
|
|
IN GUID guid,
|
|
IN BOOL fRecord,
|
|
IN DWORD dwSRCLevel
|
|
)
|
|
{
|
|
LPKSPROPERTYSET pKsPropertySet = NULL;
|
|
LPDIRECTSOUND pDirectSound = NULL;
|
|
LPDIRECTSOUNDCAPTURE pDirectSoundCapture = NULL;
|
|
HRESULT hr;
|
|
|
|
DSPROPERTY_DIRECTSOUNDMIXER_SRCQUALITY_DATA
|
|
SrcQuality;
|
|
|
|
// Find the necessary DirectSound functions
|
|
hr = DSInitialize(guid, fRecord, &pKsPropertySet, &pDirectSound, &pDirectSoundCapture );
|
|
|
|
// Get properties for this device
|
|
if(SUCCEEDED(hr))
|
|
{
|
|
SrcQuality.DeviceId = guid;
|
|
|
|
// The CPL only uses the 3 highest of 4 possible SRC values
|
|
SrcQuality.Quality = (DIRECTSOUNDMIXER_SRCQUALITY)(dwSRCLevel + 1);
|
|
|
|
// Set the mixer SRC quality
|
|
hr =
|
|
pKsPropertySet->Set
|
|
(
|
|
DSPROPSETID_DirectSoundMixer,
|
|
DSPROPERTY_DIRECTSOUNDMIXER_SRCQUALITY,
|
|
NULL,
|
|
0,
|
|
&SrcQuality,
|
|
sizeof(SrcQuality)
|
|
);
|
|
}
|
|
|
|
// Clean up
|
|
DSCleanup
|
|
(
|
|
pKsPropertySet,
|
|
pDirectSound,
|
|
pDirectSoundCapture
|
|
);
|
|
|
|
return hr;
|
|
}
|
|
|
|
HRESULT
|
|
DSSetSpeakerConfigType
|
|
(
|
|
IN GUID guid,
|
|
IN BOOL fRecord,
|
|
IN DWORD dwSpeakerConfig,
|
|
IN DWORD dwSpeakerType
|
|
)
|
|
{
|
|
LPKSPROPERTYSET pKsPropertySet = NULL;
|
|
LPDIRECTSOUND pDirectSound = NULL;
|
|
LPDIRECTSOUNDCAPTURE pDirectSoundCapture = NULL;
|
|
HRESULT hr = DS_OK;
|
|
|
|
DSPROPERTY_DIRECTSOUNDPERSISTENTDATA_PERSISTDATA_DATA
|
|
SpeakerType;
|
|
|
|
// Can't set the speaker type if we're recording
|
|
if(fRecord)
|
|
{
|
|
hr = E_INVALIDARG;
|
|
}
|
|
|
|
// Find the necessary DirectSound functions
|
|
if(SUCCEEDED(hr))
|
|
{
|
|
hr = DSInitialize(guid, fRecord, &pKsPropertySet, &pDirectSound, &pDirectSoundCapture );
|
|
}
|
|
|
|
// Set the speaker config
|
|
if(SUCCEEDED(hr))
|
|
{
|
|
hr =
|
|
pDirectSound->SetSpeakerConfig
|
|
(
|
|
dwSpeakerConfig
|
|
);
|
|
}
|
|
|
|
// Set the speaker type
|
|
if(SUCCEEDED(hr))
|
|
{
|
|
SpeakerType.DeviceId = guid;
|
|
SpeakerType.SubKeyName = REG_KEY_SPEAKERTYPE;
|
|
SpeakerType.ValueName = REG_KEY_SPEAKERTYPE;
|
|
SpeakerType.RegistryDataType = REG_DWORD;
|
|
SpeakerType.Data = &dwSpeakerType;
|
|
SpeakerType.DataSize = sizeof(dwSpeakerType);
|
|
|
|
hr =
|
|
pKsPropertySet->Set
|
|
(
|
|
DSPROPSETID_DirectSoundPersistentData,
|
|
DSPROPERTY_DIRECTSOUNDPERSISTENTDATA_PERSISTDATA,
|
|
NULL,
|
|
0,
|
|
&SpeakerType,
|
|
sizeof(SpeakerType)
|
|
);
|
|
}
|
|
|
|
// Clean up
|
|
DSCleanup
|
|
(
|
|
pKsPropertySet,
|
|
pDirectSound,
|
|
pDirectSoundCapture
|
|
);
|
|
|
|
return hr;
|
|
}
|
|
|
|
HRESULT
|
|
DSSetCplValues
|
|
(
|
|
IN GUID guid,
|
|
IN BOOL fRecord,
|
|
IN const LPCPLDATA pData
|
|
)
|
|
{
|
|
HRESULT hr;
|
|
|
|
// Set the basic HW acceleration level
|
|
hr =
|
|
DSSetAcceleration
|
|
(
|
|
guid,
|
|
fRecord,
|
|
pData->dwHWLevel
|
|
);
|
|
|
|
// Set the mixer SRC quality
|
|
if(SUCCEEDED(hr))
|
|
{
|
|
hr =
|
|
DSSetSrcQuality
|
|
(
|
|
guid,
|
|
fRecord,
|
|
pData->dwSRCLevel // +1 is done in DSSetSrcQuality
|
|
);
|
|
}
|
|
|
|
// Set the speaker config
|
|
if(SUCCEEDED(hr) && !fRecord)
|
|
{
|
|
DSSetSpeakerConfigType
|
|
(
|
|
guid,
|
|
fRecord,
|
|
pData->dwSpeakerConfig,
|
|
pData->dwSpeakerType
|
|
);
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
|