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.

279 lines
7.5 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. //
  5. // Copyright (C) Microsoft Corporation, 1998 - 1999
  6. //
  7. // File: dsoundobj.cpp
  8. //
  9. //--------------------------------------------------------------------------
  10. // dSoundObj.cpp : Implementation of CDirectApp and DLL registration.
  11. // DHF_DS entire file
  12. #include "stdafx.h"
  13. #include "Direct.h"
  14. #include "dSound.h"
  15. #include "dms.h"
  16. #include "dSoundObj.h"
  17. #include "dSoundBufferObj.h"
  18. #include "dsoundprimarybufferobj.h"
  19. extern BOOL IsAllZeros(void *pStruct,DWORD size);
  20. extern HRESULT AudioBSTRtoGUID(LPGUID,BSTR);
  21. extern HRESULT InternalCreateSoundBufferFromFile(LPDIRECTSOUND8 lpDirectSound,LPDSBUFFERDESC pDesc,WCHAR *file,LPDIRECTSOUNDBUFFER8 *lplpDirectSoundBuffer) ;
  22. extern HRESULT InternalCreateSoundBufferFromResource(LPDIRECTSOUND8 lpDirectSound,LPDSBUFFERDESC pDesc,HANDLE resHandle,WCHAR *resName,LPDIRECTSOUNDBUFFER8 *lplpDirectSoundBuffer);
  23. extern void *g_dxj_DirectSoundPrimaryBuffer;
  24. CONSTRUCTOR(_dxj_DirectSound, {m__dxj_DirectSound=NULL;m_pDriverGuid=NULL;});
  25. DESTRUCTOR(_dxj_DirectSound, {if (m_pDriverGuid) delete m_pDriverGuid;});
  26. GETSET_OBJECT(_dxj_DirectSound);
  27. //
  28. /*** IDirectSound methods ***/
  29. //
  30. PASS_THROUGH_CAST_1_R(_dxj_DirectSound, getSpeakerConfig, GetSpeakerConfig, long*,(DWORD*));
  31. PASS_THROUGH_CAST_1_R(_dxj_DirectSound, setSpeakerConfig, SetSpeakerConfig, long,(DWORD));
  32. STDMETHODIMP C_dxj_DirectSoundObject::getCaps(DSCAPS_CDESC* caps)
  33. {
  34. caps->lSize = sizeof(DSCAPS);
  35. return m__dxj_DirectSound->GetCaps((LPDSCAPS)caps);
  36. }
  37. /////////////////////////////////////////////////////////////////////////////
  38. /////////////////////////////////////////////////////////////////////////////
  39. #ifdef _WIN64
  40. STDMETHODIMP C_dxj_DirectSoundObject::setCooperativeLevel(HWND h, long d)
  41. #else
  42. STDMETHODIMP C_dxj_DirectSoundObject::setCooperativeLevel(LONG h, long d)
  43. #endif
  44. {
  45. if( m__dxj_DirectSound == NULL )
  46. return E_FAIL;
  47. return m__dxj_DirectSound->SetCooperativeLevel((HWND)h, (DWORD)d);
  48. }
  49. /////////////////////////////////////////////////////////////////////////////
  50. STDMETHODIMP C_dxj_DirectSoundObject::duplicateSoundBuffer(I_dxj_DirectSoundBuffer *src,
  51. I_dxj_DirectSoundBuffer **val)
  52. {
  53. if(! (src && val) )
  54. return E_POINTER;
  55. DO_GETOBJECT_NOTNULL(LPDIRECTSOUNDBUFFER, lpdsb, src);
  56. //Need to create a second one
  57. LPDIRECTSOUNDBUFFER dsb=0;
  58. HRESULT hr=S_OK;
  59. hr=m__dxj_DirectSound->DuplicateSoundBuffer((LPDIRECTSOUNDBUFFER)lpdsb, &dsb);
  60. if SUCCEEDED(hr)
  61. {
  62. INTERNAL_CREATE(_dxj_DirectSoundBuffer, dsb, val);
  63. }
  64. return hr;
  65. }
  66. /////////////////////////////////////////////////////////////////////////////
  67. STDMETHODIMP C_dxj_DirectSoundObject::CreatePrimarySoundBuffer(DSBUFFERDESC_CDESC *desc,
  68. I_dxj_DirectSoundPrimaryBuffer **val)
  69. {
  70. LPDIRECTSOUNDBUFFER dsb = NULL; // Need to get the buffer first
  71. DSBUFFERDESC lpds;
  72. HRESULT hr;
  73. if ((desc->lFlags & DSBCAPS_PRIMARYBUFFER) == 0)
  74. return E_INVALIDARG;
  75. lpds.dwSize = sizeof(DSBUFFERDESC);
  76. lpds.dwFlags = desc->lFlags;
  77. lpds.dwBufferBytes = desc->lBufferBytes;
  78. lpds.dwReserved = desc->lReserved;
  79. lpds.lpwfxFormat = NULL;
  80. AudioBSTRtoGUID(&lpds.guid3DAlgorithm, desc->guid3DAlgorithm);
  81. if (FAILED(hr = m__dxj_DirectSound->CreateSoundBuffer(&lpds, &dsb, NULL) ) )
  82. return hr;
  83. INTERNAL_CREATE(_dxj_DirectSoundPrimaryBuffer, dsb, val);
  84. return S_OK;
  85. }
  86. STDMETHODIMP C_dxj_DirectSoundObject::createSoundBuffer(DSBUFFERDESC_CDESC *desc,
  87. I_dxj_DirectSoundBuffer **val)
  88. {
  89. LPDIRECTSOUNDBUFFER dsb = NULL; // Need to get the buffer first
  90. DSBUFFERDESC lpds;
  91. LPDIRECTSOUNDBUFFER8 dsbReal = NULL;
  92. HRESULT hr;
  93. WAVEFORMATEX fxWave;
  94. if (desc->lFlags & DSBCAPS_PRIMARYBUFFER)
  95. return E_INVALIDARG;
  96. ZeroMemory(&lpds, sizeof(DSBUFFERDESC));
  97. ZeroMemory(&fxWave, sizeof(WAVEFORMATEX));
  98. lpds.dwSize = sizeof(DSBUFFERDESC);
  99. lpds.dwFlags = desc->lFlags;
  100. lpds.dwBufferBytes = desc->lBufferBytes;
  101. lpds.dwReserved = desc->lReserved;
  102. if (!IsAllZeros(&desc->fxFormat, sizeof(WAVEFORMATEX)))
  103. {
  104. memcpy(&fxWave, &desc->fxFormat, sizeof(WAVEFORMATEX));
  105. }
  106. else
  107. {
  108. // Do a default one
  109. fxWave.cbSize = sizeof(WAVEFORMATEX);
  110. fxWave.wFormatTag = WAVE_FORMAT_PCM;
  111. fxWave.nChannels = 2;
  112. fxWave.nSamplesPerSec = 22050;
  113. fxWave.wBitsPerSample = 16;
  114. fxWave.nBlockAlign = fxWave.wBitsPerSample / 8 * fxWave.nChannels;
  115. fxWave.nAvgBytesPerSec = fxWave.nSamplesPerSec * fxWave.nBlockAlign;
  116. #if 0
  117. if ((desc->lFlags & DSBCAPS_MIXIN) == 0)
  118. lpds.dwBufferBytes = fxWave.nSamplesPerSec;
  119. #endif
  120. }
  121. lpds.lpwfxFormat = &fxWave;
  122. AudioBSTRtoGUID(&lpds.guid3DAlgorithm, desc->guid3DAlgorithm);
  123. if (FAILED(hr = m__dxj_DirectSound->CreateSoundBuffer(&lpds, &dsb, NULL) ) )
  124. return hr;
  125. hr = dsb->QueryInterface(IID_IDirectSoundBuffer8, (void**) &dsbReal);
  126. dsb->Release();
  127. if (FAILED(hr)) return hr;
  128. INTERNAL_CREATE(_dxj_DirectSoundBuffer, dsbReal, val);
  129. return S_OK;
  130. }
  131. STDMETHODIMP C_dxj_DirectSoundObject::createSoundBufferFromFile(BSTR fileName, DSBUFFERDESC_CDESC *desc,
  132. I_dxj_DirectSoundBuffer **val)
  133. {
  134. LPDIRECTSOUNDBUFFER8 dsb; // Need to get the buffer first
  135. LPDSBUFFERDESC lpds = NULL;
  136. HRESULT hr=S_OK;
  137. *val=NULL;
  138. lpds = (LPDSBUFFERDESC)malloc(sizeof(DSBUFFERDESC));
  139. if (!lpds)
  140. return E_OUTOFMEMORY;
  141. ZeroMemory(lpds, sizeof(DSBUFFERDESC));
  142. lpds->dwSize = sizeof(DSBUFFERDESC);
  143. lpds->dwFlags = desc->lFlags;
  144. lpds->dwBufferBytes = desc->lBufferBytes;
  145. lpds->dwReserved = desc->lReserved;
  146. lpds->lpwfxFormat = (WAVEFORMATEX*)&desc->fxFormat;
  147. AudioBSTRtoGUID(&lpds->guid3DAlgorithm, desc->guid3DAlgorithm);
  148. if (FAILED( hr=InternalCreateSoundBufferFromFile(m__dxj_DirectSound,(LPDSBUFFERDESC)lpds,
  149. (WCHAR*)fileName,&dsb) ) )
  150. return hr;
  151. // Return our information now
  152. desc->lFlags = lpds->dwFlags;
  153. desc->lBufferBytes = lpds->dwBufferBytes;
  154. INTERNAL_CREATE(_dxj_DirectSoundBuffer, dsb, val);
  155. DWORD *wsize=0;
  156. hr = dsb->GetFormat((LPWAVEFORMATEX)&desc->fxFormat, (DWORD)sizeof(WAVEFORMATEX_CDESC), wsize);
  157. return S_OK;
  158. }
  159. STDMETHODIMP C_dxj_DirectSoundObject::createSoundBufferFromResource(BSTR resFile, BSTR resName,
  160. DSBUFFERDESC_CDESC *desc,
  161. I_dxj_DirectSoundBuffer **val)
  162. {
  163. LPDIRECTSOUNDBUFFER8 dsb; // Need to get the buffer first
  164. LPDSBUFFERDESC lpds = NULL ;
  165. HRESULT hr=S_OK;
  166. HMODULE hMod=NULL;
  167. USES_CONVERSION;
  168. if ((resFile) &&(resFile[0]!=0)){
  169. // BUG BUG: -
  170. // seems that GetModuleHandleW is
  171. // always returning 0 on w98??
  172. // hMod= GetModuleHandleW(moduleName);
  173. LPCTSTR pszName = W2T(resFile);
  174. hMod= GetModuleHandle(pszName);
  175. }
  176. *val=NULL;
  177. lpds = (LPDSBUFFERDESC)malloc(sizeof(DSBUFFERDESC));
  178. if (!lpds)
  179. return E_OUTOFMEMORY;
  180. ZeroMemory(lpds, sizeof(DSBUFFERDESC));
  181. lpds->dwSize = sizeof(DSBUFFERDESC);
  182. lpds->dwFlags = desc->lFlags;
  183. lpds->dwBufferBytes = desc->lBufferBytes;
  184. lpds->dwReserved = desc->lReserved;
  185. lpds->lpwfxFormat = (WAVEFORMATEX*)&desc->fxFormat;
  186. AudioBSTRtoGUID(&lpds->guid3DAlgorithm, desc->guid3DAlgorithm);
  187. hr=InternalCreateSoundBufferFromResource(m__dxj_DirectSound,(LPDSBUFFERDESC)lpds,
  188. (HANDLE)hMod,(WCHAR*)resName,&dsb);
  189. if SUCCEEDED(hr)
  190. {
  191. INTERNAL_CREATE(_dxj_DirectSoundBuffer, dsb, val);
  192. }
  193. return hr;
  194. }
  195. #if 0
  196. //DEAD CODE
  197. STDMETHODIMP C_dxj_DirectSoundObject::AllocSink(
  198. long lBusCount, WAVEFORMATEX_CDESC *format,
  199. I_dxj_DirectSoundSink **ret)
  200. {
  201. HRESULT hr;
  202. LPDIRECTSOUNDSINK8 lpdsink = NULL;
  203. hr = m__dxj_DirectSound->AllocSink((DWORD) lBusCount, sizeof(lBusCount), (WAVEFORMATEX*)format, &lpdsink);
  204. if (FAILED(hr))
  205. return hr;
  206. INTERNAL_CREATE(_dxj_DirectSoundSink, lpdsink , ret);
  207. return S_OK;
  208. }
  209. #endif