This is a solution from graph edit plus.
CComPtr<ibasefilter> CreateFilterByName(const WCHAR* filterName, const GUID& category)
{
HRESULT hr = S_OK;
CComPtr<icreatedevenum> pSysDevEnum;
hr = pSysDevEnum.CoCreateInstance(CLSID_SystemDeviceEnum);
if (hrcheck(hr, "Can't create System Device Enumerator"))
{
return NULL;
}
CComPtr<ienummoniker> pEnumCat;
hr = pSysDevEnum->CreateClassEnumerator(category, &pEnumCat, 0);
if (hr == S_OK)
{
CComPtr<imoniker> pMoniker;
ULONG cFetched;
while(pEnumCat->Next(1, &pMoniker, &cFetched) == S_OK)
{
CComPtr<ipropertybag> pPropBag;
hr = pMoniker->BindToStorage(0, 0, IID_IPropertyBag, (void * *)&pPropBag);
if (SUCCEEDED(hr))
{
VARIANT varName;
VariantInit(&varName);
hr = pPropBag->Read(L"FriendlyName", &varName, 0);
if (SUCCEEDED(hr))
{
if (wcscmp(filterName, varName.bstrVal)==0)
{
CComPtr<ibasefilter> pFilter;
hr = pMoniker->BindToObject(NULL, NULL, IID_IBaseFilter, (void**)&pFilter);
if (hrcheck(hr, "Can't bind moniker to filter object"))
return NULL;
return pFilter;
}
}
VariantClear(&varName);
}
pMoniker.Release();
}
}
return NULL;
}
And using:
DEFINE_GUID(CLSID_AudioRenderers,
0xE0F158E1, 0xCB04, 0x11D0, 0xBD, 0x4E, 0x00, 0xA0, 0xC9, 0x11, 0xCE, 0x86);
CComPtr<IBaseFilter> pDefaultDirectSoundDevice = CreateFilterByName(L"Default DirectSound Device", CLSID_AudioRenderers);
hr = pGraph->AddFilter(pDefaultDirectSoundDevice, L"Default DirectSound Device");
CHECK_HR(hr, "Can't add Default DirectSound Device to graph");