Source code of Windows XP (NT5)
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.

451 lines
11 KiB

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