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.

443 lines
11 KiB

  1. /*==========================================================================
  2. *
  3. * Copyright (C) 1999 Microsoft Corporation. All Rights Reserved.
  4. *
  5. * File: dscrecb.cpp
  6. * Content:
  7. * This module contains the implementation of the
  8. * CDirectSoundCaptureRecordBuffer.
  9. *
  10. * History:
  11. * Date By Reason
  12. * ==== == ======
  13. * 11/04/99 rodtoll Created
  14. * 11/22/99 rodtoll Added code to allow specification of wave device ID
  15. * 11/23/99 rodtoll Updated to use waveIn device ID or DSound 7.1 when they are avail
  16. * rodtoll Updated with new Microphone select member
  17. * 12/08/99 rodtoll Bug #115783 - Will always adjust volume of default device
  18. * Now uses new CMixerLine class for adjusting volumes/selecting mic
  19. * 12/08/99 rodtoll Bug #121054 - DirectX 7.1 support.
  20. * - Added hwndOwner param for capture focus support
  21. * - Added lpfLostFocus param to GetCurrentPosition so upper
  22. * layers can detect lost focus.
  23. * 01/28/2000 rodtoll Bug #130465: Record Mute/Unmute must call YieldFocus() / ClaimFocus()
  24. * 02/10/2000 rodtoll Removed more capture focus code
  25. * 04/19/2000 rodtoll Re-enabled capture focus behaviour
  26. * 08/03/2000 rodtoll Bug #41457 - DPVOICE: need way to discover which specific dsound call failed when returning DVERR_SOUNDINITFAILURE
  27. * 04/22/2001 rodtoll Fixed bug in lockup simulation code (TESTING PURPOSES ONLY)
  28. *
  29. ***************************************************************************/
  30. #include "dxvutilspch.h"
  31. #undef DPF_SUBCOMP
  32. #define DPF_SUBCOMP DN_SUBCOMP_VOICE
  33. #define DSC_STARTUP_LATENCY 1
  34. #undef DPF_MODNAME
  35. #define DPF_MODNAME "CDirectSoundCaptureRecordBuffer::CDirectSoundCaptureRecordBuffer"
  36. CDirectSoundCaptureRecordBuffer::CDirectSoundCaptureRecordBuffer(
  37. LPDIRECTSOUNDCAPTUREBUFFER lpdscBuffer, HWND hwndOwner, const GUID &guidDevice, UINT uiWaveDeviceID, const DSCBUFFERDESC * lpdsBufferDesc
  38. ): CAudioRecordBuffer(), m_lpwfxRecordFormat(NULL), m_lpdscBuffer7(NULL),
  39. m_guidDevice(guidDevice), m_uiWaveDeviceID(uiWaveDeviceID),
  40. #ifdef LOCKUP_SIMULATION
  41. m_dwNumSinceLastLockup(0), m_dwLastPosition(0),
  42. #endif
  43. m_hwndOwner(hwndOwner), m_fUseCaptureFocus( FALSE )
  44. {
  45. HRESULT hr;
  46. DWORD dwSize;
  47. if( lpdsBufferDesc->dwFlags & DSCBCAPS_FOCUSAWARE )
  48. {
  49. DPFX(DPFPREP, 1, "Enabling focus" );
  50. m_fUseCaptureFocus = TRUE;
  51. }
  52. else
  53. {
  54. DPFX(DPFPREP, 1, "Disabling focus" );
  55. m_fUseCaptureFocus = FALSE;
  56. }
  57. hr = lpdscBuffer->QueryInterface( IID_IDirectSoundCaptureBuffer, (void **) &m_lpdscBuffer );
  58. if( FAILED( hr ) )
  59. {
  60. DPFX(DPFPREP, DVF_ERRORLEVEL, "Unable to get dsound buffer interface" );
  61. m_lpdscBuffer = NULL;
  62. return;
  63. }
  64. hr = lpdscBuffer->QueryInterface( IID_IDirectSoundCaptureBuffer7_1, (void **) &m_lpdscBuffer7 );
  65. if( FAILED( hr ) )
  66. {
  67. DPFX(DPFPREP, DVF_WARNINGLEVEL, "Could not retrieve new interface hr=0x%x.", hr );
  68. hr = m_mixerLine.Initialize( m_uiWaveDeviceID );
  69. if( FAILED( hr ) )
  70. {
  71. DPFX(DPFPREP, DVF_ERRORLEVEL, "Unable to acquire volume controls hr=0x%x", hr );
  72. DNASSERT( FALSE );
  73. }
  74. }
  75. else
  76. {
  77. if( m_fUseCaptureFocus )
  78. {
  79. hr = m_lpdscBuffer7->SetFocusHWND( hwndOwner );
  80. if( FAILED( hr ) )
  81. {
  82. DPFX(DPFPREP, DVF_ERRORLEVEL, "Unable to set the focus window hr = 0x%x", hr );
  83. DNASSERT( FALSE );
  84. }
  85. }
  86. }
  87. hr = lpdscBuffer->GetFormat( NULL, 0, &dwSize );
  88. m_lpwfxRecordFormat = (LPWAVEFORMATEX) new BYTE[dwSize];
  89. if( m_lpwfxRecordFormat == NULL )
  90. {
  91. DPFX(DPFPREP, DVF_ERRORLEVEL, "Unable to allocate space for record format" );
  92. DNASSERT( FALSE );
  93. }
  94. hr = lpdscBuffer->GetFormat( m_lpwfxRecordFormat, dwSize, NULL );
  95. if( FAILED( hr ) )
  96. {
  97. delete [] ((LPBYTE) m_lpwfxRecordFormat);
  98. m_lpwfxRecordFormat = NULL;
  99. }
  100. }
  101. #undef DPF_MODNAME
  102. #define DPF_MODNAME "CDirectSoundCaptureRecordBuffer::~CDirectSoundCaptureRecordBuffer"
  103. CDirectSoundCaptureRecordBuffer::~CDirectSoundCaptureRecordBuffer()
  104. {
  105. if( m_lpdscBuffer7 != NULL )
  106. {
  107. m_lpdscBuffer7->Release();
  108. }
  109. if( m_lpdscBuffer != NULL )
  110. {
  111. m_lpdscBuffer->Release();
  112. }
  113. if( m_lpwfxRecordFormat != NULL )
  114. {
  115. delete [] ((LPBYTE) m_lpwfxRecordFormat);
  116. }
  117. }
  118. #undef DPF_MODNAME
  119. #define DPF_MODNAME "CDirectSoundCaptureRecordBuffer::Lock"
  120. HRESULT CDirectSoundCaptureRecordBuffer::Lock( DWORD dwWriteCursor, DWORD dwWriteBytes, LPVOID *lplpvBuffer1, LPDWORD lpdwSize1, LPVOID *lplpvBuffer2, LPDWORD lpdwSize2, DWORD dwFlags )
  121. {
  122. HRESULT hr;
  123. if( m_lpdscBuffer == NULL )
  124. {
  125. DPFX(DPFPREP, DVF_ERRORLEVEL, "No DirectSoundCapture Buffer Available" );
  126. return DVERR_NOTINITIALIZED;
  127. }
  128. hr = m_lpdscBuffer->Lock( dwWriteCursor, dwWriteBytes, lplpvBuffer1, lpdwSize1, lplpvBuffer2, lpdwSize2, dwFlags );
  129. DSERTRACK_Update( "DSCB::Lock()", hr );
  130. return hr;
  131. }
  132. #undef DPF_MODNAME
  133. #define DPF_MODNAME "CDirectSoundCaptureRecordBuffer::UnLock"
  134. HRESULT CDirectSoundCaptureRecordBuffer::UnLock( LPVOID lpvBuffer1, DWORD dwSize1, LPVOID lpvBuffer2, DWORD dwSize2 )
  135. {
  136. HRESULT hr;
  137. if( m_lpdscBuffer == NULL )
  138. {
  139. DPFX(DPFPREP, DVF_ERRORLEVEL, "No DirectSoundCapture Buffer Available" );
  140. return DVERR_NOTINITIALIZED;
  141. }
  142. hr = m_lpdscBuffer->Unlock( lpvBuffer1, dwSize1, lpvBuffer2, dwSize2 );
  143. return hr;
  144. }
  145. #undef DPF_MODNAME
  146. #define DPF_MODNAME "CDirectSoundCaptureRecordBuffer::SetVolume"
  147. HRESULT CDirectSoundCaptureRecordBuffer::SetVolume( LONG lVolume )
  148. {
  149. if( m_lpdscBuffer == NULL )
  150. {
  151. DPFX(DPFPREP, DVF_ERRORLEVEL, "No DirectSoundCapture Buffer Available" );
  152. return DVERR_NOTINITIALIZED;
  153. }
  154. HRESULT hr;
  155. if( m_lpdscBuffer7 != NULL )
  156. {
  157. hr = m_lpdscBuffer7->SetVolume( lVolume );
  158. }
  159. else
  160. {
  161. hr = m_mixerLine.SetMasterRecordVolume( lVolume );
  162. }
  163. // This is only a warning condition
  164. if( FAILED( hr ) )
  165. {
  166. DPFX(DPFPREP, DVF_INFOLEVEL, "Could not set master volume hr=0x%x", hr );
  167. }
  168. if( m_lpdscBuffer7 != NULL )
  169. {
  170. hr = m_lpdscBuffer7->SetMicVolume( lVolume );
  171. }
  172. else
  173. {
  174. hr = m_mixerLine.SetMicrophoneVolume( lVolume );
  175. }
  176. if( FAILED( hr ) )
  177. {
  178. DPFX(DPFPREP, DVF_INFOLEVEL, "Unable to set Microphone volume hr=0x%x", hr );
  179. return hr;
  180. }
  181. return DV_OK;
  182. }
  183. #undef DPF_MODNAME
  184. #define DPF_MODNAME "CDirectSoundCaptureRecordBuffer::GetVolume"
  185. HRESULT CDirectSoundCaptureRecordBuffer::GetVolume( LPLONG lplVolume )
  186. {
  187. if( m_lpdscBuffer == NULL )
  188. {
  189. DPFX(DPFPREP, DVF_ERRORLEVEL, "No DirectSoundCapture Buffer Available" );
  190. return DVERR_NOTINITIALIZED;
  191. }
  192. HRESULT hr;
  193. if( m_lpdscBuffer7 != NULL )
  194. {
  195. hr = m_lpdscBuffer7->GetMicVolume( lplVolume );
  196. }
  197. else
  198. {
  199. hr = m_mixerLine.GetMicrophoneVolume( lplVolume );
  200. }
  201. if( FAILED( hr ) )
  202. {
  203. DPFX(DPFPREP, DVF_WARNINGLEVEL, "Unable to get Microphone volume hr=0x%x", hr );
  204. if( m_lpdscBuffer7 != NULL )
  205. {
  206. hr = m_lpdscBuffer7->GetVolume( lplVolume );
  207. }
  208. else
  209. {
  210. hr = m_mixerLine.GetMasterRecordVolume( lplVolume );
  211. }
  212. // This is only a warning condition
  213. if( FAILED( hr ) )
  214. {
  215. DPFX(DPFPREP, DVF_WARNINGLEVEL, "Could not get master record volume hr=0x%x", hr );
  216. return hr;
  217. }
  218. return hr;
  219. }
  220. return hr;
  221. }
  222. #undef DPF_MODNAME
  223. #define DPF_MODNAME "CDirectSoundCaptureRecordBuffer::GetCurrentPosition"
  224. HRESULT CDirectSoundCaptureRecordBuffer::GetCurrentPosition( LPDWORD lpdwPosition, LPBOOL lpfLostFocus )
  225. {
  226. if( m_lpdscBuffer == NULL )
  227. {
  228. DPFX(DPFPREP, DVF_ERRORLEVEL, "No DirectSoundCapture Buffer Available" );
  229. return DVERR_NOTINITIALIZED;
  230. }
  231. #ifdef LOCKUP_SIMULATION
  232. m_dwNumSinceLastLockup++;
  233. if( m_dwNumSinceLastLockup > LOCKUP_NUM_CALLS_BEFORE_LOCKUP )
  234. {
  235. *lpdwPosition = m_dwLastPosition;
  236. *lpfLostFocus = FALSE;
  237. return DV_OK;
  238. }
  239. #endif
  240. HRESULT hr;
  241. if( m_lpdscBuffer7 != NULL && m_fUseCaptureFocus )
  242. {
  243. DWORD dwStatus;
  244. hr = m_lpdscBuffer7->GetStatus( &dwStatus );
  245. if( FAILED( hr ) )
  246. {
  247. DPFX(DPFPREP, DVF_ERRORLEVEL, "Error getting status hr=0x%x", hr );
  248. *lpfLostFocus = FALSE;
  249. }
  250. else
  251. {
  252. *lpfLostFocus = (dwStatus & DSCBSTATUS_LOSTFOCUS) ? TRUE : FALSE;
  253. }
  254. }
  255. else
  256. {
  257. *lpfLostFocus = FALSE;
  258. }
  259. hr = m_lpdscBuffer->GetCurrentPosition( NULL, lpdwPosition );
  260. #ifdef LOCKUP_SIMULATION
  261. m_dwLastPosition = *lpdwPosition;
  262. #endif
  263. DSERTRACK_Update( "DSCB::GetCurrentPosition()", hr );
  264. return hr;
  265. }
  266. #undef DPF_MODNAME
  267. #define DPF_MODNAME "CDirectSoundCaptureRecordBuffer::Play"
  268. HRESULT CDirectSoundCaptureRecordBuffer::Record( BOOL fLooping )
  269. {
  270. if( m_lpdscBuffer == NULL )
  271. {
  272. DPFX(DPFPREP, DVF_ERRORLEVEL, "No DirectSound Buffer Available" );
  273. return DVERR_NOTINITIALIZED;
  274. }
  275. HRESULT hr;
  276. hr = m_lpdscBuffer->Start( (fLooping) ? DSCBSTART_LOOPING : 0 );
  277. #ifdef LOCKUP_SIMULATION
  278. #ifdef LOCKUP_STOPFAIL
  279. if( m_dwNumSinceLastLockup > LOCKUP_NUM_CALLS_BEFORE_LOCKUP )
  280. {
  281. hr = DSERR_GENERIC;
  282. }
  283. #else
  284. m_dwNumSinceLastLockup = 0;
  285. #endif
  286. #endif
  287. DSERTRACK_Update( "DSCB::Start()", hr );
  288. return hr;
  289. }
  290. #undef DPF_MODNAME
  291. #define DPF_MODNAME "CDirectSoundCaptureRecordBuffer::Stop"
  292. HRESULT CDirectSoundCaptureRecordBuffer::Stop()
  293. {
  294. if( m_lpdscBuffer == NULL )
  295. {
  296. DPFX(DPFPREP, DVF_ERRORLEVEL, "No DirectSound Buffer Available" );
  297. return DVERR_NOTINITIALIZED;
  298. }
  299. HRESULT hr;
  300. hr = m_lpdscBuffer->Stop( );
  301. #ifdef LOCKUP_SIMULATION
  302. #ifdef LOCKUP_STOPFAIL
  303. if( m_dwNumSinceLastLockup > LOCKUP_NUM_CALLS_BEFORE_LOCKUP )
  304. {
  305. hr = DSERR_GENERIC;
  306. }
  307. #endif
  308. #endif
  309. DSERTRACK_Update( "DSCB::Stop()", hr );
  310. return hr;
  311. }
  312. #undef DPF_MODNAME
  313. #define DPF_MODNAME "CDirectSoundCaptureRecordBuffer::GetStartupLatency"
  314. DWORD CDirectSoundCaptureRecordBuffer::GetStartupLatency()
  315. {
  316. return DSC_STARTUP_LATENCY;
  317. }
  318. #undef DPF_MODNAME
  319. #define DPF_MODNAME "CDirectSoundCaptureRecordBuffer::GetRecordFormat"
  320. LPWAVEFORMATEX CDirectSoundCaptureRecordBuffer::GetRecordFormat()
  321. {
  322. return m_lpwfxRecordFormat;
  323. }
  324. #undef DPF_MODNAME
  325. #define DPF_MODNAME "CDirectSoundCaptureRecordBuffer::SelectMicrophone"
  326. HRESULT CDirectSoundCaptureRecordBuffer::SelectMicrophone( BOOL fSelect )
  327. {
  328. if( m_lpdscBuffer7 != NULL )
  329. {
  330. return m_lpdscBuffer7->EnableMic( fSelect );
  331. }
  332. else
  333. {
  334. return m_mixerLine.EnableMicrophone( fSelect );
  335. }
  336. }
  337. #undef DPF_MODNAME
  338. #define DPF_MODNAME "CDirectSoundCaptureRecordBuffer::ClaimFocus"
  339. HRESULT CDirectSoundCaptureRecordBuffer::ClaimFocus( )
  340. {
  341. if( m_lpdscBuffer7 != NULL && m_fUseCaptureFocus)
  342. {
  343. return m_lpdscBuffer7->ClaimFocus();
  344. }
  345. else
  346. {
  347. return DVERR_NOTSUPPORTED;
  348. }
  349. }
  350. #undef DPF_MODNAME
  351. #define DPF_MODNAME "CDirectSoundCaptureRecordBuffer::YieldFocus"
  352. HRESULT CDirectSoundCaptureRecordBuffer::YieldFocus( )
  353. {
  354. if( m_lpdscBuffer7 != NULL && m_fUseCaptureFocus )
  355. {
  356. return m_lpdscBuffer7->YieldFocus();
  357. }
  358. else
  359. {
  360. return DVERR_NOTSUPPORTED;
  361. }
  362. }