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.

357 lines
10 KiB

  1. /*==========================================================================
  2. *
  3. * Copyright (C) 1999 Microsoft Corporation. All Rights Reserved.
  4. *
  5. * File: dsplayd.cpp
  6. * Content:
  7. * This module contains the implementation of the
  8. * CDirectSoundPlaybackDevice.
  9. *
  10. * History:
  11. * Date By Reason
  12. * ==== == ======
  13. * 07/16/99 rodtoll Created
  14. * 07/30/99 rodtoll Updated to allow creation of object using a pre-created
  15. * DirectSound Object.
  16. * 10/05/99 rodtoll Added DPF_MODNAMEs
  17. * 10/14/99 rodtoll Added 3d caps to primary buffer created
  18. * 10/27/99 rodtoll Bug #115431: Must release primary buffer
  19. * 11/12/99 rodtoll Modified abstraction for new waveOut support.
  20. * Now abstracted types look almost like dsound objects
  21. * 12/01/99 rodtoll Bug #121815 - Static in playback/record
  22. * Added implementations of Set/GetMixerQuality
  23. * (For Win2k/Millenium/Systems w/DX7)
  24. * 01/27/2000 rodtoll Updated sound classes to accept playback flags,
  25. * buffer structures and DSBUFFERDESC instead of DSBUFFERDESC1
  26. * 02/16/2000 rodtoll Fixed so primary buffer is not released
  27. * 02/17/2000 rodtoll Updated so primary buffer is held instead of released immediately
  28. * 04/21/2000 rodtoll Bug #32952 - Does not run on Win95 GOLD w/o IE4 -- modified
  29. * to allow reads of REG_BINARY when expecting REG_DWORD
  30. * 04/24/2000 rodtoll Bug #33203 - Removed workaround for aureal vortex 1 problem -- had
  31. * problems on Vortex 2.
  32. * 06/09/00 rmt Updates to split CLSID and allow whistler compat and support external create funcs
  33. * 07/12/2000 rodtoll Bug #31468 - Add diagnostic spew to logfile to show what is failing the HW Wizard
  34. * 08/03/2000 rodtoll Bug #41457 - DPVOICE: need way to discover which specific dsound call failed when returning DVERR_SOUNDINITFAILURE
  35. * 08/28/2000 masonb Voice Merge: Changed ccomutil.h to comutil.h
  36. * 04/04/2001 rodtoll WINBUG #343428 - DPVOICE: Voice wizard's playback is very choppy.
  37. *
  38. ***************************************************************************/
  39. #include "dxvutilspch.h"
  40. #undef DPF_SUBCOMP
  41. #define DPF_SUBCOMP DN_SUBCOMP_VOICE
  42. #undef DPF_MODNAME
  43. #define DPF_MODNAME "CDirectSoundPlaybackDevice::CDirectSoundPlaybackDevice"
  44. CDirectSoundPlaybackDevice::CDirectSoundPlaybackDevice(
  45. ): CAudioPlaybackDevice(), m_hwndOwner(NULL), m_lpdsDirectSound(NULL), m_guidDevice(GUID_NULL), m_lpdsPrimaryBuffer(NULL), m_fEmulated(FALSE)
  46. {
  47. }
  48. #undef DPF_MODNAME
  49. #define DPF_MODNAME "CDirectSoundPlaybackDevice::~CDirectSoundPlaybackDevice"
  50. CDirectSoundPlaybackDevice::~CDirectSoundPlaybackDevice()
  51. {
  52. if( m_lpdsPrimaryBuffer != NULL )
  53. {
  54. m_lpdsPrimaryBuffer->Release();
  55. m_lpdsPrimaryBuffer = NULL;
  56. }
  57. if( m_lpdsDirectSound != NULL )
  58. {
  59. m_lpdsDirectSound->Release();
  60. m_lpdsDirectSound = NULL;
  61. }
  62. }
  63. #undef DPF_MODNAME
  64. #define DPF_MODNAME "CDirectSoundPlaybackDevice::CheckAndSetEmulated"
  65. HRESULT CDirectSoundPlaybackDevice::CheckAndSetEmulated( )
  66. {
  67. HRESULT hr;
  68. DSCAPS dsCaps;
  69. ZeroMemory( &dsCaps, sizeof( DSCAPS ) );
  70. dsCaps.dwSize = sizeof( DSCAPS );
  71. hr = m_lpdsDirectSound->GetCaps( &dsCaps );
  72. if( FAILED( hr ) )
  73. {
  74. m_fEmulated = FALSE;
  75. Diagnostics_Write(DVF_ERRORLEVEL, "Querying for playback caps failed hr=0x%x", hr );
  76. return hr;
  77. }
  78. m_fEmulated = (dsCaps.dwFlags & DSCAPS_EMULDRIVER);
  79. return hr;
  80. }
  81. #undef DPF_MODNAME
  82. #define DPF_MODNAME "CDirectSoundPlaybackDevice::Initialize"
  83. HRESULT CDirectSoundPlaybackDevice::Initialize( LPDIRECTSOUND lpdsDirectSound, const GUID &guidDevice )
  84. {
  85. HRESULT hr;
  86. m_guidDevice = guidDevice;
  87. hr = lpdsDirectSound->QueryInterface( IID_IDirectSound, (void **) &m_lpdsDirectSound );
  88. if( FAILED( hr ) )
  89. {
  90. Diagnostics_Write(DVF_ERRORLEVEL, "DirectSound Object passed failed. 0x%x Creating internal", hr );
  91. m_lpdsDirectSound = NULL;
  92. return hr;
  93. }
  94. hr = CheckAndSetEmulated();
  95. if( FAILED( hr ) )
  96. {
  97. m_lpdsDirectSound->Release();
  98. m_lpdsDirectSound = NULL;
  99. return hr;
  100. }
  101. return DV_OK;
  102. }
  103. #undef DPF_MODNAME
  104. #define DPF_MODNAME "CDirectSoundPlaybackDevice::Initialize"
  105. HRESULT CDirectSoundPlaybackDevice::Initialize( const GUID &guidDevice, HWND hwndOwner, WAVEFORMATEX *lpwfxFormat, BOOL fPriorityMode )
  106. {
  107. HRESULT hr;
  108. DSBUFFERDESC dsbdesc;
  109. DWORD dwPriority;
  110. m_guidDevice = guidDevice;
  111. if( m_lpdsDirectSound != NULL )
  112. {
  113. Diagnostics_Write(DVF_ERRORLEVEL, "Already initialized" );
  114. return DVERR_INITIALIZED;
  115. }
  116. hr = COM_CoCreateInstance( CLSID_DirectSound, NULL, CLSCTX_INPROC_SERVER , IID_IDirectSound, (void **) &m_lpdsDirectSound, FALSE );
  117. DSERTRACK_Update( "DSD::CoCreateInstance()", hr );
  118. if( FAILED( hr ) )
  119. {
  120. Diagnostics_Write(DVF_ERRORLEVEL, "Unable to load directsound hr=0x%x", hr );
  121. goto INITIALIZE_ERROR;
  122. }
  123. hr = m_lpdsDirectSound->Initialize( &guidDevice );
  124. DSERTRACK_Update( "DSD::Initialize()", hr );
  125. if( FAILED( hr ) )
  126. {
  127. Diagnostics_Write(DVF_ERRORLEVEL, "Unable to initialize directsound hr=0x%x", hr );
  128. goto INITIALIZE_ERROR;
  129. }
  130. if( fPriorityMode )
  131. {
  132. dwPriority = DSSCL_PRIORITY;
  133. }
  134. else
  135. {
  136. dwPriority = DSSCL_NORMAL;
  137. }
  138. hr = m_lpdsDirectSound->SetCooperativeLevel( hwndOwner, dwPriority );
  139. DSERTRACK_Update( "DSD::SetCooperativeLevel()", hr );
  140. if( FAILED( hr ) )
  141. {
  142. Diagnostics_Write(DVF_ERRORLEVEL, "Unable to set cooperative level hr=0x%x", hr );
  143. goto INITIALIZE_ERROR;
  144. }
  145. if( fPriorityMode && lpwfxFormat != NULL )
  146. {
  147. memset(&dsbdesc, 0, sizeof(DSBUFFERDESC));
  148. dsbdesc.dwSize = sizeof(DSBUFFERDESC);
  149. dsbdesc.dwFlags = DSBCAPS_PRIMARYBUFFER | DSBCAPS_CTRL3D;
  150. dsbdesc.dwBufferBytes = 0;
  151. dsbdesc.lpwfxFormat = NULL;
  152. hr = m_lpdsDirectSound->CreateSoundBuffer( (DSBUFFERDESC *) &dsbdesc, &m_lpdsPrimaryBuffer, NULL );
  153. DSERTRACK_Update( "DSD::CreateSoundBuffer() (Primary)", hr );
  154. if( FAILED( hr ) )
  155. {
  156. Diagnostics_Write(DVF_ERRORLEVEL, "Create of primary buffer failed. Trying DX5 dsound hr=0x%x", hr );
  157. dsbdesc.dwSize = sizeof( DSBUFFERDESC1 );
  158. hr = m_lpdsDirectSound->CreateSoundBuffer( (DSBUFFERDESC *) &dsbdesc, &m_lpdsPrimaryBuffer, NULL );
  159. }
  160. if( FAILED( hr ) )
  161. {
  162. Diagnostics_Write(DVF_ERRORLEVEL, "Could not create primary sound buffer" );
  163. goto INITIALIZE_ERROR;
  164. }
  165. hr = m_lpdsPrimaryBuffer->SetFormat( lpwfxFormat );
  166. DSERTRACK_Update( "DSD::SetFormat() (Primary)", hr );
  167. if( FAILED( hr ) )
  168. {
  169. Diagnostics_Write(DVF_ERRORLEVEL, "Could not set the format" );
  170. goto INITIALIZE_ERROR;
  171. }
  172. }
  173. m_hwndOwner = hwndOwner;
  174. hr = CheckAndSetEmulated();
  175. if( FAILED( hr ) )
  176. {
  177. Diagnostics_Write(DVF_ERRORLEVEL, "Could not get emulated state hr=0x%x", hr );
  178. goto INITIALIZE_ERROR;
  179. }
  180. return DV_OK;
  181. INITIALIZE_ERROR:
  182. if( m_lpdsPrimaryBuffer )
  183. {
  184. m_lpdsPrimaryBuffer->Release();
  185. m_lpdsPrimaryBuffer = NULL;
  186. }
  187. if( m_lpdsDirectSound != NULL )
  188. {
  189. m_lpdsDirectSound->Release();
  190. m_lpdsDirectSound = NULL;
  191. }
  192. return hr;
  193. }
  194. #undef DPF_MODNAME
  195. #define DPF_MODNAME "CDirectSoundPlaybackDevice::CreateBuffer"
  196. HRESULT CDirectSoundPlaybackDevice::CreateBuffer( LPDSBUFFERDESC lpdsBufferDesc, DWORD dwFrameSize, CAudioPlaybackBuffer **lplpapBuffer )
  197. {
  198. HRESULT hr;
  199. LPDIRECTSOUNDBUFFER lpdsBuffer;
  200. hr = m_lpdsDirectSound->CreateSoundBuffer( (DSBUFFERDESC *) lpdsBufferDesc, &lpdsBuffer, NULL );
  201. DSERTRACK_Update( "DSD::CreateSoundBuffer() ", hr );
  202. if( FAILED( hr ) )
  203. {
  204. lpdsBufferDesc->dwSize = sizeof( DSBUFFERDESC1 );
  205. Diagnostics_Write(DVF_ERRORLEVEL, "Unable to create sound buffer under DX7. Attempting DX5 create hr=0x%x", hr );
  206. hr = m_lpdsDirectSound->CreateSoundBuffer( (DSBUFFERDESC *) lpdsBufferDesc, &lpdsBuffer, NULL );
  207. }
  208. if( FAILED( hr ) )
  209. {
  210. Diagnostics_Write(DVF_ERRORLEVEL, "Failed to create the sound buffer hr=0x%x", hr );
  211. return hr;
  212. }
  213. /*
  214. // Freee wave format
  215. delete dsBufferDesc.lpwfxFormat;
  216. hr = lpdsBuffer->SetFrequency( 8000 );
  217. if( FAILED( hr ) )
  218. {
  219. DPFX(DPFPREP, 0, "Could not set frequency hr=0x%x", hr );
  220. return hr;
  221. }*/
  222. *lplpapBuffer = new CDirectSoundPlaybackBuffer( lpdsBuffer );
  223. lpdsBuffer->Release();
  224. if( *lplpapBuffer == NULL )
  225. {
  226. Diagnostics_Write(DVF_ERRORLEVEL, "Out of memory" );
  227. return DVERR_OUTOFMEMORY;
  228. }
  229. return DV_OK;
  230. }
  231. #undef DPF_MODNAME
  232. #define DPF_MODNAME "CDirectSoundPlaybackDevice::GetPlaybackDevice"
  233. LPDIRECTSOUND CDirectSoundPlaybackDevice::GetPlaybackDevice( )
  234. {
  235. return m_lpdsDirectSound;
  236. }
  237. #undef DPF_MODNAME
  238. #define DPF_MODNAME "CDirectSoundPlaybackDevice::GetMixerQuality"
  239. HRESULT CDirectSoundPlaybackDevice::GetMixerQuality( DIRECTSOUNDMIXER_SRCQUALITY *psrcQuality )
  240. {
  241. HRESULT hr;
  242. LPKSPROPERTYSET pPropertySet = NULL;
  243. hr = DirectSoundPrivateCreate( &pPropertySet );
  244. if( FAILED( hr ) )
  245. {
  246. DPFX(DPFPREP, DVF_WARNINGLEVEL, "Unable to get int to get mixer quality hr=0x%x", hr );
  247. return hr;
  248. }
  249. hr = PrvGetMixerSrcQuality( pPropertySet, m_guidDevice, psrcQuality );
  250. if( FAILED( hr ) )
  251. {
  252. DPFX(DPFPREP, DVF_WARNINGLEVEL, "Unable to retrieve mixer quality hr=0x%x", hr );
  253. }
  254. pPropertySet->Release();
  255. return hr;
  256. }
  257. #undef DPF_MODNAME
  258. #define DPF_MODNAME "CDirectSoundPlaybackDevice::SetMixerQuality"
  259. HRESULT CDirectSoundPlaybackDevice::SetMixerQuality( const DIRECTSOUNDMIXER_SRCQUALITY srcQuality )
  260. {
  261. HRESULT hr;
  262. LPKSPROPERTYSET pPropertySet = NULL;
  263. hr = DirectSoundPrivateCreate( &pPropertySet );
  264. if( FAILED( hr ) )
  265. {
  266. DPFX(DPFPREP, DVF_WARNINGLEVEL, "Unable to get int to set mixer quality hr=0x%x", hr );
  267. return hr;
  268. }
  269. hr = PrvSetMixerSrcQuality( pPropertySet, m_guidDevice, srcQuality );
  270. if( FAILED( hr ) )
  271. {
  272. DPFX(DPFPREP, DVF_WARNINGLEVEL, "Unable to set mixer quality hr=0x%x", hr );
  273. }
  274. pPropertySet->Release();
  275. return hr;
  276. }