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.

283 lines
8.2 KiB

  1. /*==========================================================================
  2. *
  3. * Copyright (C) 1999 Microsoft Corporation. All Rights Reserved.
  4. *
  5. * File: dscrecd.cpp
  6. * Content:
  7. * This file contains the DirectSoundCapture implementation of the
  8. * CAudioRecordDevice abstraction.
  9. *
  10. * History:
  11. * Date By Reason
  12. * ==== == ======
  13. * 11/04/99 rodtoll Created
  14. * 11/12/99 rodtoll Modified abstraction for new waveIN support.
  15. * Now abstracted types look almost like dsoundcap objects
  16. * 11/22/99 rodtoll Added code to map from GUID to waveIN device
  17. * ID for non-millenium systems.
  18. * 11/23/99 rodtoll Updated to use waveIn device ID or DSound 7.1 when they are avail
  19. * 12/01/99 rodtoll Bug #115783 - Will always adjust volume of default device
  20. * Now uses new CMixerLine class for adjusting volumes/selecting mic
  21. * rodtoll New algorithm to map from GUIDs to device IDs if DSound 7.1 is not
  22. * available. Will map device correctly on DX7, will guess for other
  23. * DX versions < 7. However, default device is assumed to be waveIN ID #0.
  24. * 12/08/99 rodtoll Bug #121054 - DirectX 7.1 support.
  25. * - Added hwndOwner param for capture focus support
  26. * 04/21/2000 rodtoll Bug #32952 - Does not run on Win95 GOLD w/o IE4 -- modified
  27. * to allow reads of REG_BINARY when expecting REG_DWORD
  28. * 06/09/00 rmt Updates to split CLSID and allow whistler compat and support external create funcs
  29. * 06/28/2000 rodtoll Prefix Bug #38022
  30. * 08/03/2000 rodtoll Bug #41457 - DPVOICE: need way to discover which specific dsound call failed when returning DVERR_SOUNDINITFAILURE
  31. * 08/28/2000 masonb Voice Merge: Changed ccomutil.h to comutil.h
  32. * 09/13/2000 rodtoll Bug #44806 - When volume control not avail, dropping to DX7 levels instead of disabling volume control
  33. *
  34. ***************************************************************************/
  35. #include "dxvutilspch.h"
  36. #undef DPF_SUBCOMP
  37. #define DPF_SUBCOMP DN_SUBCOMP_VOICE
  38. // This function is responsible for mapping from the Device's GUID to the
  39. // waveIN ID.
  40. //
  41. #undef DPF_MODNAME
  42. #define DPF_MODNAME "CDirectSoundCaptureRecordDevice::FindDeviceID"
  43. HRESULT CDirectSoundCaptureRecordDevice::FindDeviceID()
  44. {
  45. HRESULT hr;
  46. DWORD dwDeviceID = 0;
  47. hr = DV_MapGUIDToWaveID( TRUE, m_guidDevice, &dwDeviceID );
  48. // If we were going to use the hack for enum of devices
  49. if( FAILED( hr ) )
  50. {
  51. DPFX(DPFPREP, DVF_ERRORLEVEL, "Unable to find waveIN ID, mapping to ID 0 hr=0x%x", hr );
  52. m_uiWaveDeviceID = 0;
  53. }
  54. else
  55. {
  56. m_uiWaveDeviceID = dwDeviceID;
  57. }
  58. return hr;
  59. }
  60. #undef DPF_MODNAME
  61. #define DPF_MODNAME "CDirectSoundCaptureRecordDevice::CDirectSoundCaptureRecordDevice"
  62. CDirectSoundCaptureRecordDevice::CDirectSoundCaptureRecordDevice(
  63. ): CAudioRecordDevice(), m_lpdscDirectSound(NULL), m_uiWaveDeviceID(0), m_guidDevice(GUID_NULL)
  64. {
  65. }
  66. #undef DPF_MODNAME
  67. #define DPF_MODNAME "CDirectSoundCaptureRecordDevice::CDirectSoundCaptureRecordDevice"
  68. CDirectSoundCaptureRecordDevice::~CDirectSoundCaptureRecordDevice()
  69. {
  70. if( m_lpdscDirectSound != NULL )
  71. {
  72. m_lpdscDirectSound->Release();
  73. }
  74. }
  75. #undef DPF_MODNAME
  76. #define DPF_MODNAME "CDirectSoundCaptureRecordDevice::Initialize"
  77. HRESULT CDirectSoundCaptureRecordDevice::Initialize( LPDIRECTSOUNDCAPTURE lpdscDirectSound, const GUID &guidDevice )
  78. {
  79. HRESULT hr;
  80. if( m_lpdscDirectSound != NULL )
  81. {
  82. DPFX(DPFPREP, DVF_ERRORLEVEL, "Already initialized" );
  83. return DVERR_INITIALIZED;
  84. }
  85. hr = lpdscDirectSound->QueryInterface( IID_IDirectSoundCapture, (void **) &m_lpdscDirectSound );
  86. if( FAILED( hr ) )
  87. {
  88. DPFX(DPFPREP, DVF_ERRORLEVEL, "DirectSoundCapture Object passed failed. 0x%x Creating internal", hr );
  89. m_lpdscDirectSound = NULL;
  90. return hr;
  91. }
  92. m_guidDevice = guidDevice;
  93. hr = FindDeviceID();
  94. if( FAILED( hr ) )
  95. {
  96. DPFX(DPFPREP, DVF_ERRORLEVEL, "Unable to find waveIn ID for device hr=0x%x", hr );
  97. m_lpdscDirectSound->Release();
  98. return hr;
  99. }
  100. return hr;
  101. }
  102. #undef DPF_MODNAME
  103. #define DPF_MODNAME "CDirectSoundCaptureRecordDevice::Initialize"
  104. HRESULT CDirectSoundCaptureRecordDevice::Initialize( const GUID &guidDevice )
  105. {
  106. HRESULT hr;
  107. if( m_lpdscDirectSound != NULL )
  108. {
  109. DPFX(DPFPREP, DVF_ERRORLEVEL, "Already initialized" );
  110. return DVERR_INITIALIZED;
  111. }
  112. hr = COM_CoCreateInstance( CLSID_DirectSoundCapture, NULL, CLSCTX_INPROC_SERVER , IID_IDirectSoundCapture, (void **) &m_lpdscDirectSound, FALSE );
  113. DSERTRACK_Update( "DSCD:CoCreateInstance()", hr );
  114. if( FAILED( hr ) )
  115. {
  116. DPFX(DPFPREP, DVF_ERRORLEVEL, "Unable to load directsoundcapture hr=0x%x", hr );
  117. goto INITIALIZE_ERROR;
  118. }
  119. hr = m_lpdscDirectSound->Initialize( &guidDevice );
  120. DSERTRACK_Update( "DSCD:Initialize()", hr );
  121. if( FAILED( hr ) )
  122. {
  123. DPFX(DPFPREP, DVF_ERRORLEVEL, "Unable to initialize directsoundcapture hr=0x%x", hr );
  124. goto INITIALIZE_ERROR;
  125. }
  126. m_guidDevice = guidDevice;
  127. hr = FindDeviceID();
  128. if( FAILED( hr ) )
  129. {
  130. DPFX(DPFPREP, DVF_ERRORLEVEL, "Unable to find waveIn ID for device hr=0x%x", hr );
  131. return hr;
  132. }
  133. return DV_OK;
  134. INITIALIZE_ERROR:
  135. if( m_lpdscDirectSound != NULL )
  136. {
  137. m_lpdscDirectSound->Release();
  138. m_lpdscDirectSound = NULL;
  139. }
  140. return hr;
  141. }
  142. #undef DPF_MODNAME
  143. #define DPF_MODNAME "CDirectSoundCaptureRecordDevice::CreateBuffer"
  144. HRESULT CDirectSoundCaptureRecordDevice::CreateBuffer( LPDSCBUFFERDESC lpdsBufferDesc, HWND hwndOwner, DWORD dwFrameSize, CAudioRecordBuffer **lplpacBuffer )
  145. {
  146. HRESULT hr;
  147. LPDIRECTSOUNDCAPTUREBUFFER lpdscBuffer;
  148. lpdsBufferDesc->dwFlags |= DSCBCAPS_CTRLVOLUME;
  149. hr = m_lpdscDirectSound->CreateCaptureBuffer( lpdsBufferDesc, &lpdscBuffer, NULL );
  150. DSERTRACK_Update( "DSCD::CreateCaptureBuffer()", hr );
  151. // Ask for volume control, if we can't get it, do the old create
  152. if( hr == DSERR_INVALIDPARAM || hr == DSERR_CONTROLUNAVAIL )
  153. {
  154. DPFX(DPFPREP, DVF_ERRORLEVEL, "New caps are not available, attempting old create hr=0x%x", hr );
  155. // Turn off the new caps -- (for non-Millenium systems).
  156. lpdsBufferDesc->dwFlags &= ~(DSCBCAPS_CTRLVOLUME);
  157. hr = m_lpdscDirectSound->CreateCaptureBuffer( lpdsBufferDesc, &lpdscBuffer, NULL );
  158. }
  159. if( FAILED( hr ) )
  160. {
  161. DPFX(DPFPREP, DVF_ERRORLEVEL, "Failed to create the capture buffer hr=0x%x", hr );
  162. return hr;
  163. }
  164. *lplpacBuffer = new CDirectSoundCaptureRecordBuffer( lpdscBuffer, hwndOwner, m_guidDevice, m_uiWaveDeviceID, lpdsBufferDesc );
  165. lpdscBuffer->Release();
  166. if( *lplpacBuffer == NULL )
  167. {
  168. DPFX(DPFPREP, DVF_ERRORLEVEL, "Out of memory" );
  169. return DVERR_OUTOFMEMORY;
  170. }
  171. return DV_OK;
  172. }
  173. #undef DPF_MODNAME
  174. #define DPF_MODNAME "CDirectSoundCaptureRecordDevice::GetCaptureDevice"
  175. LPDIRECTSOUNDCAPTURE CDirectSoundCaptureRecordDevice::GetCaptureDevice()
  176. {
  177. return m_lpdscDirectSound;
  178. }
  179. #undef DPF_MODNAME
  180. #define DPF_MODNAME "CDirectSoundCaptureRecordDevice::GetMixerQuality"
  181. HRESULT CDirectSoundCaptureRecordDevice::GetMixerQuality( DIRECTSOUNDMIXER_SRCQUALITY *psrcQuality )
  182. {
  183. HRESULT hr;
  184. LPKSPROPERTYSET pPropertySet = NULL;
  185. hr = DirectSoundPrivateCreate( &pPropertySet );
  186. if( FAILED( hr ) )
  187. {
  188. DPFX(DPFPREP, DVF_WARNINGLEVEL, "Unable to get int to get mixer quality hr=0x%x", hr );
  189. return hr;
  190. }
  191. hr = PrvGetMixerSrcQuality( pPropertySet, m_guidDevice, psrcQuality );
  192. if( FAILED( hr ) )
  193. {
  194. DPFX(DPFPREP, DVF_WARNINGLEVEL, "Unable to retrieve mixer quality hr=0x%x", hr );
  195. }
  196. pPropertySet->Release();
  197. return hr;
  198. }
  199. #undef DPF_MODNAME
  200. #define DPF_MODNAME "CDirectSoundCaptureRecordDevice::SetMixerQuality"
  201. HRESULT CDirectSoundCaptureRecordDevice::SetMixerQuality( const DIRECTSOUNDMIXER_SRCQUALITY srcQuality )
  202. {
  203. HRESULT hr;
  204. LPKSPROPERTYSET pPropertySet = NULL;
  205. hr = DirectSoundPrivateCreate( &pPropertySet );
  206. if( FAILED( hr ) )
  207. {
  208. DPFX(DPFPREP, DVF_WARNINGLEVEL, "Unable to get int to set mixer quality hr=0x%x", hr );
  209. return hr;
  210. }
  211. hr = PrvSetMixerSrcQuality( pPropertySet, m_guidDevice, srcQuality );
  212. if( FAILED( hr ) )
  213. {
  214. DPFX(DPFPREP, DVF_WARNINGLEVEL, "Unable to set mixer quality hr=0x%x", hr );
  215. }
  216. pPropertySet->Release();
  217. return hr;
  218. }