// // dllmain.cpp // // Copyright (c) 1997-2001 Microsoft Corporation // #pragma warning(disable:4530) #include #include "debug.h" #include "oledll.h" #include "dsdmo.h" #include "chorusp.h" #include "compressp.h" #include "distortp.h" #include "echop.h" #include "flangerp.h" #include "parameqp.h" #include "garglep.h" #include "sverbp.h" #include "map.h" #include "aecp.h" #include "nsp.h" #include "agcp.h" #include "reghlp.h" // These are linked in class CDirectSoundI3DL2ReverbDMO; EXT_STD_CREATE(I3DL2Reverb); //class CDirectSoundI3DL2SourceDMO; //EXT_STD_CREATE(I3DL2Source); DWORD g_amPlatform; int g_cActiveObjects = 0; // // this is a temporary place holder only! the dmocom.cpp base class requires this global to be defined // so we're putting something in it for now. Class factory templates aren't used currently, but eventually // we should use the template structure to create all dmo objects. // struct CComClassTemplate g_ComClassTemplates[] = { {&GUID_DSFX_STANDARD_GARGLE, CreateCDirectSoundGargleDMO} }; int g_cComClassTemplates = 0; #define DefineClassFactory(x) \ class x ## Factory : public IClassFactory \ { \ public: \ virtual STDMETHODIMP QueryInterface(const IID &iid, void **ppv); \ virtual STDMETHODIMP_(ULONG) AddRef(); \ virtual STDMETHODIMP_(ULONG) Release(); \ \ virtual STDMETHODIMP CreateInstance(IUnknown* pUnknownOuter, \ const IID& iid, void** ppv); \ virtual STDMETHODIMP LockServer(BOOL bLock); \ \ x ## Factory() : m_cRef(1) {} \ \ ~ x ## Factory() {} \ \ private: \ long m_cRef; \ }; \ STDMETHODIMP x ## Factory::QueryInterface( \ const IID &iid, void **ppv) \ { \ if(iid == IID_IUnknown || iid == IID_IClassFactory) \ { \ *ppv = static_cast(this); \ } \ else \ { \ *ppv = NULL; \ return E_NOINTERFACE; \ } \ \ reinterpret_cast(*ppv)->AddRef(); \ \ return S_OK; \ } \ STDMETHODIMP_(ULONG) x ## Factory::AddRef() \ { \ return InterlockedIncrement(&m_cRef); \ } \ \ STDMETHODIMP_(ULONG) x ## Factory::Release() \ { \ if(!InterlockedDecrement(&m_cRef)) \ { \ delete this; \ return 0; \ } \ \ return m_cRef; \ } \ \ STDMETHODIMP x ## Factory::CreateInstance( \ IUnknown* pUnknownOuter, const IID& riid, void** ppv) \ { \ Trace(DM_DEBUG_STATUS, "Create " #x "\n"); \ if (ppv == NULL) \ { \ return E_POINTER; \ } \ \ if (pUnknownOuter != NULL) { \ if (IsEqualIID(riid,IID_IUnknown) == FALSE) { \ return ResultFromScode(E_NOINTERFACE); \ } \ } \ \ HRESULT hr = S_OK; \ CComBase *p = Create ## x(pUnknownOuter, &hr); \ if (SUCCEEDED(hr)) \ { \ p->NDAddRef(); \ hr = p->NDQueryInterface(riid, ppv); \ p->NDRelease(); \ } \ \ return hr; \ } \ STDMETHODIMP x ## Factory::LockServer(BOOL bLock) \ { \ if(bLock) \ { \ InterlockedIncrement(&g_cLock); \ } \ else \ { \ InterlockedDecrement(&g_cLock); \ } \ \ return S_OK; \ } #define DefineDMOClassFactory(x) DefineClassFactory(CDirectSound ## x ## DMO) #define DefineDMOCaptureClassFactory(x) DefineClassFactory(CDirectSoundCapture ## x ## DMO) ////////////////////////////////////////////////////////////////////// // Globals // // Registry Info // #define DefineNames(x) \ TCHAR g_sz## x ##FriendlyName[] = TEXT("DirectSound" #x "DMO"); \ TCHAR g_sz## x ##VerIndProgID[] = TEXT("Microsoft.DirectSound" #x "DMO"); \ TCHAR g_sz## x ##ProgID[] = TEXT("Microsoft.DirectSound" #x "DMO.1"); \ #define DefineCaptureNames(x) \ TCHAR g_sz## x ##FriendlyName[] = TEXT("DirectSoundCapture" #x "DMO"); \ TCHAR g_sz## x ##VerIndProgID[] = TEXT("Microsoft.DirectSoundCapture" #x "DMO"); \ TCHAR g_sz## x ##ProgID[] = TEXT("Microsoft.DirectSoundCapture" #x "DMO.1"); \ DefineNames(Chorus) DefineNames(Compressor) DefineNames(Distortion) DefineNames(Echo) DefineNames(Flanger) DefineNames(ParamEq) DefineNames(Gargle) DefineNames(WavesReverb) DefineNames(I3DL2Reverb) //DefineNames(I3DL2Source) //DefineCaptureNames(MicArray) DefineCaptureNames(Aec) DefineCaptureNames(NoiseSuppress) DefineCaptureNames(Agc) // Dll's hModule HMODULE g_hModule = NULL; // Count of class factory server locks long g_cLock = 0; DefineDMOClassFactory(Chorus) DefineDMOClassFactory(Compressor) DefineDMOClassFactory(Distortion) DefineDMOClassFactory(Echo) DefineDMOClassFactory(Flanger) DefineDMOClassFactory(ParamEq) DefineDMOClassFactory(I3DL2Reverb) //DefineDMOClassFactory(I3DL2Source) DefineDMOClassFactory(Gargle) DefineDMOClassFactory(WavesReverb) // Capture FXs //DefineDMOCaptureClassFactory(MicArray) DefineDMOCaptureClassFactory(Aec) DefineDMOCaptureClassFactory(NoiseSuppress) DefineDMOCaptureClassFactory(Agc) ////////////////////////////////////////////////////////////////////// // Standard calls needed to be an inproc server ////////////////////////////////////////////////////////////////////// // DllCanUnloadNow STDAPI DllCanUnloadNow() { if (g_cActiveObjects || g_cLock) { return S_FALSE; } return S_OK; } // Hack to make these macros continue to work: #define GUID_DSFX_STANDARD_Chorus GUID_DSFX_STANDARD_CHORUS #define GUID_DSFX_STANDARD_Compressor GUID_DSFX_STANDARD_COMPRESSOR #define GUID_DSFX_STANDARD_Distortion GUID_DSFX_STANDARD_DISTORTION #define GUID_DSFX_STANDARD_Echo GUID_DSFX_STANDARD_ECHO #define GUID_DSFX_STANDARD_Flanger GUID_DSFX_STANDARD_FLANGER #define GUID_DSFX_STANDARD_ParamEq GUID_DSFX_STANDARD_PARAMEQ #define GUID_DSFX_STANDARD_Gargle GUID_DSFX_STANDARD_GARGLE #define GUID_DSFX_STANDARD_WavesReverb GUID_DSFX_WAVES_REVERB #define GUID_DSFX_STANDARD_I3DL2Reverb GUID_DSFX_STANDARD_I3DL2REVERB #define GUID_DSFX_STANDARD_I3DL2Source GUID_DSFX_STANDARD_I3DL2SOURCE // Capture #define GUID_DSCFX_MS_Aec GUID_DSCFX_MS_AEC #define GUID_DSCFX_MS_NoiseSuppress GUID_DSCFX_MS_NS #define GUID_DSCFX_MS_Agc GUID_DSCFX_MS_AGC #define GUID_DSCFX_SYSTEM_MicArray GUID_DSCFX_SYSTEM_MA #define GUID_DSCFX_SYSTEM_Aec GUID_DSCFX_SYSTEM_AEC #define GUID_DSCFX_SYSTEM_NoiseSuppress GUID_DSCFX_SYSTEM_NS #define GUID_DSCFX_SYSTEM_Agc GUID_DSCFX_SYSTEM_AGC #define GetClassObjectCase(x,t) \ if (clsid == x) { \ p = static_cast ((IClassFactory*) (new t)); \ } else #define GetClassObjectCaseEnd \ { return CLASS_E_CLASSNOTAVAILABLE; } #define GetClassObjectCaseFX(x) \ GetClassObjectCase(GUID_DSFX_STANDARD_ ## x, CDirectSound ## x ## DMOFactory) #define GetClassObjectCaseCaptureFX(w,x) \ GetClassObjectCase(GUID_DSCFX_## w ##_ ## x, CDirectSoundCapture ## x ## DMOFactory) ////////////////////////////////////////////////////////////////////// // DllGetClassObject STDAPI DllGetClassObject(const CLSID& clsid, const IID& iid, void** ppv) { if (ppv == NULL) { return E_POINTER; } IUnknown* p = NULL; // Render FX GetClassObjectCaseFX(Chorus) GetClassObjectCaseFX(Compressor) GetClassObjectCaseFX(Distortion) GetClassObjectCaseFX(Echo) GetClassObjectCaseFX(Flanger) GetClassObjectCaseFX(ParamEq) GetClassObjectCaseFX(I3DL2Reverb) // GetClassObjectCaseFX(I3DL2Source) GetClassObjectCaseFX(Gargle) GetClassObjectCaseFX(WavesReverb) // Capture FX GetClassObjectCaseCaptureFX(MS, Aec) GetClassObjectCaseCaptureFX(MS, NoiseSuppress) GetClassObjectCaseCaptureFX(MS, Agc) // GetClassObjectCaseCaptureFX(SYSTEM, MicArray) GetClassObjectCaseCaptureFX(SYSTEM, Aec) GetClassObjectCaseCaptureFX(SYSTEM, NoiseSuppress) GetClassObjectCaseCaptureFX(SYSTEM, Agc) GetClassObjectCaseEnd if(!p) { return E_OUTOFMEMORY; } HRESULT hr = p->QueryInterface(iid, ppv); p->Release(); return hr; } #define DoUnregister(x) \ UnregisterServer(GUID_DSFX_STANDARD_ ## x, \ g_sz ## x ## FriendlyName, \ g_sz ## x ## VerIndProgID, \ g_sz ## x ## ProgID) #define DoRegister(x) \ RegisterServer(g_hModule, \ GUID_DSFX_STANDARD_ ## x, \ g_sz ## x ## FriendlyName, \ g_sz ## x ## VerIndProgID, \ g_sz ## x ## ProgID) #define DoDMORegister(x) \ DMORegister(L#x, \ GUID_DSFX_STANDARD_ ## x, \ DMOCATEGORY_AUDIO_EFFECT, \ 0, 1, &mt, 1, &mt) #define DoDMOUnregister(x) \ DMOUnregister(GUID_DSFX_STANDARD_ ## x, \ DMOCATEGORY_AUDIO_EFFECT) #define Unregister(x) \ if (SUCCEEDED(hr)) hr = DoDMOUnregister(x); \ if (SUCCEEDED(hr)) hr = DoUnregister(x); #define Register(x) \ if (SUCCEEDED(hr)) hr = DoRegister(x); \ if (SUCCEEDED(hr)) hr = DoDMORegister(x); // Capture Defines #define DoCaptureUnregister(w,x) \ UnregisterServer(GUID_DSCFX_## w ##_ ## x, \ g_sz ## x ## FriendlyName, \ g_sz ## x ## VerIndProgID, \ g_sz ## x ## ProgID) #define DoCaptureRegister(w,x) \ RegisterServer(g_hModule, \ GUID_DSCFX_## w ##_ ## x, \ g_sz ## x ## FriendlyName, \ g_sz ## x ## VerIndProgID, \ g_sz ## x ## ProgID) #define DoDMOCaptureRegister(t,w,x,y) \ DMORegister(L#t, \ GUID_DSCFX_## w ##_ ## x, \ y, \ 0, 1, &mt, 1, &mt) #define DoDMOCaptureRegisterCpuResources(w,x,z) \ DMORegisterCpuResources( \ GUID_DSCFX_## w ##_ ## x, \ z) #define DoDMOCaptureUnregister(w,x,y) \ DMOUnregister(GUID_DSCFX_## w ##_ ## x, \ y) #define CaptureUnregister(w,x,y) \ if (SUCCEEDED(hr)) hr = DoDMOCaptureUnregister(w,x,y); \ if (SUCCEEDED(hr)) hr = DoCaptureUnregister(w,x); #define CaptureRegister(t,w,x,y,z) \ if (SUCCEEDED(hr)) hr = DoCaptureRegister(w,x); \ if (SUCCEEDED(hr)) hr = DoDMOCaptureRegister(t,w,x,y); \ if (SUCCEEDED(hr)) hr = DoDMOCaptureRegisterCpuResources(w,x,z); ////////////////////////////////////////////////////////////////////// // DllUnregisterServer STDAPI DllUnregisterServer() { HRESULT hr = S_OK; Unregister(Chorus); Unregister(Compressor); Unregister(Distortion); Unregister(Echo); Unregister(Flanger); Unregister(ParamEq); Unregister(I3DL2Reverb); // Unregister(I3DL2Source); Unregister(Gargle); Unregister(WavesReverb); // Capture FXs CaptureUnregister(MS,Aec,DMOCATEGORY_ACOUSTIC_ECHO_CANCEL); CaptureUnregister(MS,NoiseSuppress,DMOCATEGORY_AUDIO_NOISE_SUPPRESS); CaptureUnregister(MS,Agc,DMOCATEGORY_AGC); // CaptureUnregister(SYSTEM,MicArray,DMOCATEGORY_MICROPHONE_ARRAY_PROCESSOR); CaptureUnregister(SYSTEM,Aec,DMOCATEGORY_ACOUSTIC_ECHO_CANCEL); CaptureUnregister(SYSTEM,NoiseSuppress,DMOCATEGORY_AUDIO_NOISE_SUPPRESS); CaptureUnregister(SYSTEM,Agc,DMOCATEGORY_AGC); return hr; } ////////////////////////////////////////////////////////////////////// // DllRegisterServer STDAPI DllRegisterServer() { HRESULT hr = S_OK; DMO_PARTIAL_MEDIATYPE mt; mt.type = MEDIATYPE_Audio; mt.subtype = MEDIASUBTYPE_PCM; Register(Chorus); Register(Compressor); Register(Distortion); Register(Echo); Register(Flanger); Register(ParamEq); Register(I3DL2Reverb); // Register(I3DL2Source); Register(Gargle); Register(WavesReverb); // Capture FXs CaptureRegister(Microsoft AEC,MS,Aec,DMOCATEGORY_ACOUSTIC_ECHO_CANCEL,DS_SYSTEM_RESOURCES_ALL_HOST_RESOURCES); CaptureRegister(Microsoft Noise Suppression,MS,NoiseSuppress,DMOCATEGORY_AUDIO_NOISE_SUPPRESS,DS_SYSTEM_RESOURCES_ALL_HOST_RESOURCES); CaptureRegister(Microsoft AGC,MS,Agc,DMOCATEGORY_AGC,DS_SYSTEM_RESOURCES_ALL_HOST_RESOURCES); // CaptureRegister(System Microphone Array,SYSTEM,MicArray,DMOCATEGORY_MICROPHONE_ARRAY_PROCESSOR,DS_SYSTEM_RESOURCES_UNDEFINED); CaptureRegister(System AEC,SYSTEM,Aec,DMOCATEGORY_ACOUSTIC_ECHO_CANCEL,DS_SYSTEM_RESOURCES_UNDEFINED); CaptureRegister(System Noise Suppression,SYSTEM,NoiseSuppress,DMOCATEGORY_AUDIO_NOISE_SUPPRESS,DS_SYSTEM_RESOURCES_UNDEFINED); CaptureRegister(System AGC,SYSTEM,Agc,DMOCATEGORY_AGC,DS_SYSTEM_RESOURCES_UNDEFINED); return hr; } ////////////////////////////////////////////////////////////////////// // Standard Win32 DllMain ////////////////////////////////////////////////////////////////////// // DllMain #ifdef DBG static char* aszReasons[] = { "DLL_PROCESS_DETACH", "DLL_PROCESS_ATTACH", "DLL_THREAD_ATTACH", "DLL_THREAD_DETACH" }; const DWORD nReasons = (sizeof(aszReasons) / sizeof(char*)); #endif BOOL APIENTRY DllMain(HINSTANCE hModule, DWORD dwReason, void *lpReserved) { #ifdef DBG if(dwReason < nReasons) { Trace(DM_DEBUG_STATUS, "DllMain: %s\n", (LPSTR)aszReasons[dwReason]); } else { Trace(DM_DEBUG_STATUS, "DllMain: Unknown dwReason <%u>\n", dwReason); } #endif switch(dwReason) { case DLL_PROCESS_ATTACH: if(++g_cActiveObjects == 1) { #ifdef DBG DebugInit(); #endif if(!DisableThreadLibraryCalls(hModule)) { Trace(DM_DEBUG_STATUS, "DisableThreadLibraryCalls failed.\n"); } g_hModule = hModule; g_amPlatform = VER_PLATFORM_WIN32_WINDOWS; // win95 assumed in case GetVersionEx fails OSVERSIONINFO osInfo; osInfo.dwOSVersionInfoSize = sizeof(osInfo); if (GetVersionEx(&osInfo)) { g_amPlatform = osInfo.dwPlatformId; } } break; case DLL_PROCESS_DETACH: if(--g_cActiveObjects == 0) { Trace(DM_DEBUG_STATUS, "Unloading\n"); } break; } return TRUE; }