Leaked source code of windows server 2003
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.

457 lines
11 KiB

  1. /***************************************************************************
  2. *
  3. * Copyright (C) 1999-2002 Microsoft Corporation. All Rights Reserved.
  4. *
  5. * File: aec.cpp
  6. * Content: Acoustic Echo Cancellation DMO implementation.
  7. *
  8. ***************************************************************************/
  9. #include <windows.h>
  10. #include "aecp.h"
  11. #include "kshlp.h"
  12. #include "clone.h"
  13. #include "ksdbgprop.h"
  14. STD_CAPTURE_CREATE(Aec)
  15. //////////////////////////////////////////////////////////////////////////////
  16. //
  17. // CDirectSoundCaptureAecDMO::NDQueryInterface
  18. //
  19. STDMETHODIMP CDirectSoundCaptureAecDMO::NDQueryInterface
  20. (
  21. REFIID riid,
  22. LPVOID *ppv
  23. )
  24. {
  25. IMP_DSDMO_QI(riid, ppv);
  26. if (riid == IID_IPersist)
  27. {
  28. return GetInterface((IPersist*)this, ppv);
  29. }
  30. else if (riid == IID_IMediaObject)
  31. {
  32. return GetInterface((IMediaObject*)this, ppv);
  33. }
  34. else if (riid == IID_IDirectSoundCaptureFXAec)
  35. {
  36. return GetInterface((IDirectSoundCaptureFXAec*)this, ppv);
  37. }
  38. #ifdef AEC_DEBUG_SUPPORT
  39. else if (riid == IID_IDirectSoundCaptureFXMsAecPrivate)
  40. {
  41. return GetInterface((IDirectSoundCaptureFXMsAecPrivate*)this, ppv);
  42. }
  43. #endif // AEC_DEBUG_SUPPORT
  44. else if (riid == IID_IMediaParams)
  45. {
  46. return GetInterface((IMediaParams*)this, ppv);
  47. }
  48. else if (riid == IID_IMediaParamInfo)
  49. {
  50. return GetInterface((IMediaParamInfo*)this, ppv);
  51. }
  52. else
  53. {
  54. return CComBase::NDQueryInterface(riid, ppv);
  55. }
  56. }
  57. //////////////////////////////////////////////////////////////////////////////
  58. //
  59. // CDirectSoundCaptureAecDMO constructor
  60. //
  61. CDirectSoundCaptureAecDMO::CDirectSoundCaptureAecDMO(IUnknown *pUnk, HRESULT *phr) :
  62. CComBase(pUnk, phr),
  63. m_bInitialized(FALSE),
  64. m_fEnable(TRUE),
  65. m_fNfEnable(FALSE),
  66. m_dwMode(DSCFX_AEC_MODE_FULL_DUPLEX),
  67. m_fDirty(FALSE)
  68. {
  69. }
  70. //////////////////////////////////////////////////////////////////////////////
  71. //
  72. // CDirectSoundCaptureAecDMO destructor
  73. //
  74. CDirectSoundCaptureAecDMO::~CDirectSoundCaptureAecDMO()
  75. {
  76. }
  77. const MP_CAPS g_AecCapsAll = 0;
  78. static ParamInfo g_params[] =
  79. {
  80. // index type caps min, max, neutral, unit text, label, pwchText??
  81. AECP_Enable, MPT_BOOL, g_AecCapsAll, 0, 1, 1, L"", L"", L"",
  82. AECP_NoiseFill, MPT_BOOL, g_AecCapsAll, 0, 1, 0, L"", L"", L"",
  83. AECP_Mode, MPT_INT, g_AecCapsAll, 0, 1, 0, L"", L"", L"",
  84. };
  85. //////////////////////////////////////////////////////////////////////////////
  86. //
  87. // CDirectSoundCaptureAecDMO::InitOnCreation
  88. //
  89. HRESULT CDirectSoundCaptureAecDMO::InitOnCreation()
  90. {
  91. HRESULT hr = InitParams(1, &GUID_TIME_REFERENCE, 0, 0, sizeof g_params / sizeof *g_params, g_params);
  92. return hr;
  93. }
  94. //////////////////////////////////////////////////////////////////////////////
  95. //
  96. // CDirectSoundCaptureAecDMO::Init
  97. //
  98. HRESULT CDirectSoundCaptureAecDMO::Init()
  99. {
  100. m_bInitialized = TRUE;
  101. return S_OK;
  102. }
  103. //////////////////////////////////////////////////////////////////////////////
  104. //
  105. // CDirectSoundCaptureAecDMO::Clone
  106. //
  107. STDMETHODIMP CDirectSoundCaptureAecDMO::Clone(IMediaObjectInPlace **pp)
  108. {
  109. return StandardDMOClone<CDirectSoundCaptureAecDMO, DSCFXAec>(this, pp);
  110. }
  111. //////////////////////////////////////////////////////////////////////////////
  112. //
  113. // CDirectSoundCaptureAecDMO::Discontinuity
  114. //
  115. HRESULT CDirectSoundCaptureAecDMO::Discontinuity()
  116. {
  117. return NOERROR;
  118. }
  119. //////////////////////////////////////////////////////////////////////////////
  120. //
  121. // CDirectSoundCaptureAecDMO::FBRProcess
  122. //
  123. HRESULT CDirectSoundCaptureAecDMO::FBRProcess
  124. (
  125. DWORD cSamples,
  126. BYTE *pIn,
  127. BYTE *pOut
  128. )
  129. {
  130. if (!m_bInitialized)
  131. return DMO_E_TYPE_NOT_SET;
  132. return NOERROR;
  133. }
  134. // ==============Implementation of the private IAec interface ==========
  135. // ==================== needed to support the property page ===============
  136. //////////////////////////////////////////////////////////////////////////////
  137. //
  138. // CDirectSoundCaptureAecDMO::SetAllParameters
  139. //
  140. STDMETHODIMP CDirectSoundCaptureAecDMO::SetAllParameters(LPCDSCFXAec pParm)
  141. {
  142. if (pParm == NULL)
  143. {
  144. Trace(1, "ERROR: pParm is NULL\n");
  145. return E_POINTER;
  146. }
  147. HRESULT hr = SetParam(AECP_Enable, static_cast<MP_DATA>(pParm->fEnable));
  148. if (SUCCEEDED(hr))
  149. {
  150. m_fDirty = true;
  151. hr = SetParam(AECP_NoiseFill, static_cast<MP_DATA>(pParm->fNoiseFill));
  152. }
  153. if (SUCCEEDED(hr))
  154. {
  155. hr = SetParam(AECP_Mode, static_cast<MP_DATA>(pParm->dwMode));
  156. }
  157. return hr;
  158. }
  159. //////////////////////////////////////////////////////////////////////////////
  160. //
  161. // CDirectSoundCaptureAecDMO::GetAllParameters
  162. //
  163. STDMETHODIMP CDirectSoundCaptureAecDMO::GetAllParameters(LPDSCFXAec pParm)
  164. {
  165. if (pParm == NULL)
  166. {
  167. return E_POINTER;
  168. }
  169. MP_DATA var;
  170. HRESULT hr = GetParam(AECP_Enable, &var);
  171. if (SUCCEEDED(hr))
  172. {
  173. pParm->fEnable = (BOOL)var;
  174. hr = GetParam(AECP_NoiseFill, &var);
  175. }
  176. if (SUCCEEDED(hr))
  177. {
  178. pParm->fNoiseFill = (BOOL)var;
  179. hr = GetParam(AECP_Mode, &var);
  180. }
  181. if (SUCCEEDED(hr))
  182. {
  183. pParm->dwMode = (DWORD)var;
  184. }
  185. return hr;
  186. }
  187. //////////////////////////////////////////////////////////////////////////////
  188. //
  189. // CDirectSoundCaptureAecDMO::GetStatus
  190. //
  191. STDMETHODIMP CDirectSoundCaptureAecDMO::GetStatus(PDWORD pdwStatus)
  192. {
  193. DWORD dwStatus;
  194. ULONG cBytes;
  195. HRESULT hr;
  196. if (pdwStatus == NULL)
  197. {
  198. return E_POINTER;
  199. }
  200. hr = KsGetNodeProperty
  201. (
  202. m_hPin,
  203. KSPROPSETID_Acoustic_Echo_Cancel,
  204. KSPROPERTY_AEC_STATUS,
  205. m_ulNodeId,
  206. &dwStatus,
  207. sizeof dwStatus,
  208. &cBytes
  209. );
  210. if (SUCCEEDED(hr))
  211. {
  212. *pdwStatus = dwStatus;
  213. }
  214. return hr;
  215. }
  216. //////////////////////////////////////////////////////////////////////////////
  217. //
  218. // CDirectSoundCaptureAecDMO::Reset
  219. //
  220. STDMETHODIMP CDirectSoundCaptureAecDMO::Reset()
  221. {
  222. return KsTopologyNodeReset(m_hPin, m_ulNodeId, true);
  223. }
  224. //////////////////////////////////////////////////////////////////////////////
  225. //
  226. // CDirectSoundCaptureAecDMO::SetParam
  227. //
  228. STDMETHODIMP CDirectSoundCaptureAecDMO::SetParam
  229. (
  230. DWORD dwParamIndex,
  231. MP_DATA value,
  232. bool fSkipPasssingToParamManager
  233. )
  234. {
  235. HRESULT hr = S_OK;
  236. switch (dwParamIndex)
  237. {
  238. case AECP_Enable:
  239. if ((BOOL)value != m_fEnable)
  240. {
  241. hr = KsSetTopologyNodeEnable(m_hPin, m_ulNodeId, (BOOL)value);
  242. if (SUCCEEDED(hr)) m_fEnable = (BOOL)value;
  243. }
  244. break;
  245. case AECP_NoiseFill:
  246. if ((BOOL)value != m_fNfEnable)
  247. {
  248. hr = KsSetNodeProperty(m_hPin, KSPROPSETID_Acoustic_Echo_Cancel, KSPROPERTY_AEC_NOISE_FILL_ENABLE, m_ulNodeId, &value, sizeof value);
  249. if (SUCCEEDED(hr)) m_fNfEnable = (BOOL)value;
  250. }
  251. break;
  252. case AECP_Mode:
  253. if ((DWORD)value != m_dwMode)
  254. {
  255. hr = KsSetNodeProperty(m_hPin, KSPROPSETID_Acoustic_Echo_Cancel, KSPROPERTY_AEC_MODE, m_ulNodeId, &value, sizeof value);
  256. if (SUCCEEDED(hr)) m_dwMode = (DWORD)value;
  257. }
  258. break;
  259. }
  260. if (SUCCEEDED(hr))
  261. {
  262. Init(); // FIXME - temp hack (sets m_bInitialized flag)
  263. }
  264. // Let the base class set this so it can handle all the rest of the param calls.
  265. // Skip the base class if fSkipPasssingToParamManager. This indicates that we're
  266. // calling the function internally using values that came from the base class --
  267. // thus there's no need to tell it values it already knows.
  268. return (FAILED(hr) || fSkipPasssingToParamManager) ? hr : CParamsManager::SetParam(dwParamIndex, value);
  269. }
  270. //////////////////////////////////////////////////////////////////////////////
  271. //
  272. // CDirectSoundCaptureAecDMO::GetParam
  273. //
  274. STDMETHODIMP CDirectSoundCaptureAecDMO::GetParam
  275. (
  276. DWORD dwParamIndex,
  277. MP_DATA* value
  278. )
  279. {
  280. HRESULT hr = S_OK;
  281. BOOL fTemp;
  282. DWORD dwTemp;
  283. ULONG cBytes;
  284. switch (dwParamIndex)
  285. {
  286. case AECP_Enable:
  287. hr = KsGetTopologyNodeEnable(m_hPin, m_ulNodeId, &fTemp);
  288. if (SUCCEEDED(hr))
  289. {
  290. m_fEnable = fTemp;
  291. *value = (MP_DATA)fTemp;
  292. }
  293. break;
  294. case AECP_NoiseFill:
  295. hr = KsGetNodeProperty(m_hPin, KSPROPSETID_Acoustic_Echo_Cancel, KSPROPERTY_AEC_NOISE_FILL_ENABLE, m_ulNodeId, &fTemp, sizeof fTemp, &cBytes);
  296. if (SUCCEEDED(hr))
  297. {
  298. m_fNfEnable = fTemp;
  299. *value = (MP_DATA)fTemp;
  300. }
  301. break;
  302. case AECP_Mode:
  303. hr = KsGetNodeProperty(m_hPin, KSPROPSETID_Acoustic_Echo_Cancel, KSPROPERTY_AEC_MODE, m_ulNodeId, &dwTemp, sizeof dwTemp, &cBytes);
  304. if (SUCCEEDED(hr))
  305. {
  306. m_dwMode = dwTemp;
  307. *value = (MP_DATA)dwTemp;
  308. }
  309. break;
  310. }
  311. return hr;
  312. }
  313. //////////////////////////////////////////////////////////////////////////////
  314. //
  315. // CDirectSoundCaptureAecDMO::ProcessInPlace
  316. //
  317. HRESULT CDirectSoundCaptureAecDMO::ProcessInPlace
  318. (
  319. ULONG ulQuanta,
  320. LPBYTE pcbData,
  321. REFERENCE_TIME rtStart,
  322. DWORD dwFlags
  323. )
  324. {
  325. // Update parameter values from any curves that may be in effect.
  326. // Do this in the same order as SetAllParameters in case there are any interdependencies.
  327. return FBRProcess(ulQuanta, pcbData, pcbData);
  328. }
  329. #ifdef AEC_DEBUG_SUPPORT
  330. //////////////////////////////////////////////////////////////////////////////
  331. //
  332. // CDirectSoundCaptureAecDMO::GetSynchStreamFlag
  333. //
  334. STDMETHODIMP
  335. CDirectSoundCaptureAecDMO::GetSynchStreamFlag
  336. (
  337. PBOOL pfSynchStreamFlag
  338. )
  339. {
  340. HRESULT hr = DS_OK;
  341. ULONG cbDataReturned = 0;
  342. if (!pfSynchStreamFlag)
  343. return E_INVALIDARG;
  344. *pfSynchStreamFlag = 0;
  345. hr = KsGetNodeProperty
  346. (
  347. m_hPin,
  348. KSPROPSETID_DebugAecValue,
  349. KSPROPERTY_DEBUGAECVALUE_SYNCHSTREAM,
  350. m_ulNodeId,
  351. pfSynchStreamFlag,
  352. sizeof BOOL,
  353. &cbDataReturned
  354. );
  355. return hr;
  356. }
  357. //////////////////////////////////////////////////////////////////////////////
  358. //
  359. // CDirectSoundCaptureAecDMO::GetNoiseMagnitude
  360. //
  361. STDMETHODIMP
  362. CDirectSoundCaptureAecDMO::GetNoiseMagnitude
  363. (
  364. PVOID pvData,
  365. ULONG cbData,
  366. PULONG pcbDataReturned
  367. )
  368. {
  369. HRESULT hr = DS_OK;
  370. if ((cbData && !pvData) || !pcbDataReturned || (cbData % sizeof FLOAT))
  371. return E_INVALIDARG;
  372. *pcbDataReturned = 0;
  373. hr = KsGetNodeProperty
  374. (
  375. m_hPin,
  376. KSPROPSETID_DebugAecValue,
  377. KSPROPERTY_DEBUGAECARRAY_NOISEMAGNITUDE,
  378. m_ulNodeId,
  379. pvData,
  380. cbData,
  381. pcbDataReturned
  382. );
  383. return hr;
  384. }
  385. #endif // AEC_DEBUG_SUPPORT