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.

579 lines
16 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. //
  5. // Copyright (C) Microsoft Corporation, 1998 - 1999
  6. //
  7. // File: dsoundbufferobj.cpp
  8. //
  9. //--------------------------------------------------------------------------
  10. // dSoundBufferObj.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 "dSoundBufferObj.h"
  17. #include "dSoundObj.h"
  18. #include "dSound3DListener.h"
  19. #include "dSound3DBuffer.h"
  20. #include "dsoundFXGargleobj.h"
  21. #include "dsoundFXEchoobj.h"
  22. #include "dsoundFXChorusobj.h"
  23. #include "dsoundFXCompressorobj.h"
  24. #include "dsoundFXDistortionobj.h"
  25. #include "dsoundFXFlangerobj.h"
  26. #include "dsoundfxi3dl2reverbobj.h"
  27. #if 0
  28. #include "dsoundfxi3dl2sourceobj.h"
  29. #include "dsoundfxsendobj.h"
  30. #endif
  31. #include "dsoundfxparameqobj.h"
  32. #include "dsoundfxwavesreverbobj.h"
  33. extern void *g_dxj_DirectSoundFXWavesReverb;
  34. extern void *g_dxj_DirectSoundFXCompressor;
  35. extern void *g_dxj_DirectSoundFXChorus;
  36. extern void *g_dxj_DirectSoundFXGargle;
  37. extern void *g_dxj_DirectSoundFXEcho;
  38. extern void *g_dxj_DirectSoundFXSend;
  39. extern void *g_dxj_DirectSoundFXDistortion;
  40. extern void *g_dxj_DirectSoundFXFlanger;
  41. extern void *g_dxj_DirectSoundFXParamEQ;
  42. extern void *g_dxj_DirectSoundFXI3DL2Reverb;
  43. #if 0
  44. extern void *g_dxj_DirectSoundFXI3DL2Source;
  45. #endif
  46. #define SAFE_DELETE(p) { if (p) {free(p); p = NULL;} }
  47. extern HRESULT AudioBSTRtoGUID(LPGUID,BSTR);
  48. extern HRESULT InternalSaveToFile(IDirectSoundBuffer *pBuff,BSTR file);
  49. CONSTRUCTOR(_dxj_DirectSoundBuffer, {});
  50. DESTRUCTOR(_dxj_DirectSoundBuffer, {});
  51. GETSET_OBJECT(_dxj_DirectSoundBuffer);
  52. PASS_THROUGH1_R(_dxj_DirectSoundBuffer, getVolume, GetVolume, long*);
  53. PASS_THROUGH1_R(_dxj_DirectSoundBuffer, getPan, GetPan, long*);
  54. PASS_THROUGH_CAST_1_R(_dxj_DirectSoundBuffer, getFrequency, GetFrequency, long*,(DWORD*));
  55. PASS_THROUGH_CAST_1_R(_dxj_DirectSoundBuffer, getStatus, GetStatus, long*,(DWORD*));
  56. PASS_THROUGH_CAST_1_R(_dxj_DirectSoundBuffer, setCurrentPosition, SetCurrentPosition, long,(DWORD));
  57. PASS_THROUGH1_R(_dxj_DirectSoundBuffer, setPan, SetPan, LONG);
  58. PASS_THROUGH_CAST_1_R(_dxj_DirectSoundBuffer, setFrequency, SetFrequency, long,(DWORD));
  59. PASS_THROUGH_R(_dxj_DirectSoundBuffer, stop, Stop);
  60. PASS_THROUGH_R(_dxj_DirectSoundBuffer, restore, Restore);
  61. STDMETHODIMP C_dxj_DirectSoundBufferObject::setVolume(LONG vol)
  62. {
  63. __try {
  64. return m__dxj_DirectSoundBuffer->SetVolume(vol);
  65. }
  66. __except(EXCEPTION_EXECUTE_HANDLER)
  67. {
  68. return E_FAIL;
  69. }
  70. }
  71. STDMETHODIMP C_dxj_DirectSoundBufferObject::getDirectSound3dBuffer(I_dxj_DirectSound3dBuffer **retval)
  72. {
  73. IDirectSound3DBuffer *lp3db;
  74. HRESULT hr = S_OK;
  75. __try {
  76. if( (hr=m__dxj_DirectSoundBuffer->QueryInterface(IID_IDirectSound3DBuffer, (void**) &lp3db)) != S_OK)
  77. return hr;
  78. INTERNAL_CREATE(_dxj_DirectSound3dBuffer, lp3db, retval);
  79. }
  80. __except(EXCEPTION_EXECUTE_HANDLER)
  81. {
  82. return E_FAIL;
  83. }
  84. return hr;
  85. }
  86. STDMETHODIMP C_dxj_DirectSoundBufferObject::getCaps(DSBCAPS_CDESC* caps)
  87. {
  88. __try {
  89. if(!caps)
  90. return E_POINTER;
  91. caps->lSize = sizeof(DSBCAPS);
  92. return m__dxj_DirectSoundBuffer->GetCaps((LPDSBCAPS)caps);
  93. }
  94. __except(EXCEPTION_EXECUTE_HANDLER)
  95. {
  96. return E_FAIL;
  97. }
  98. }
  99. /////////////////////////////////////////////////////////////////////////////
  100. STDMETHODIMP C_dxj_DirectSoundBufferObject::getCurrentPosition(DSCURSORS_CDESC *desc)
  101. {
  102. __try {
  103. if(!desc) return E_POINTER;
  104. return (m__dxj_DirectSoundBuffer->GetCurrentPosition((DWORD*)&desc->lPlay, (DWORD*)&desc->lWrite) );
  105. }
  106. __except(EXCEPTION_EXECUTE_HANDLER)
  107. {
  108. return E_FAIL;
  109. }
  110. }
  111. /////////////////////////////////////////////////////////////////////////////
  112. //Java has no direct access to system memory, so it allocates it's own buffer
  113. //which is passed into WriteBuffer(). Because the environment is now double
  114. //buffered there is no need to Lock Java memory. WriteBuffer() calls
  115. //both lock and Unlock internally to write the result after the fact.
  116. /////////////////////////////////////////////////////////////////////////////
  117. STDMETHODIMP C_dxj_DirectSoundBufferObject::writeBuffer(long start, long totsz,
  118. void *buf, long flags)
  119. {
  120. #pragma message ("SoundBuffer writeBuffer ")
  121. byte *buffer=(byte*)buf; //(byte*)((SAFEARRAY*)*ppsa)->pvData;
  122. if(!buffer)
  123. return E_POINTER;
  124. LPVOID p1, p2;
  125. DWORD size1=0, size2=0;
  126. HRESULT val = E_FAIL;
  127. __try {
  128. if ((val = m__dxj_DirectSoundBuffer->Lock((DWORD)start, (DWORD)totsz,
  129. &p1, &size1, &p2, &size2,
  130. (DWORD)flags)) != DS_OK)
  131. return val;
  132. // Copy to buffer end, then do a wrapped portion if it exists, then unlock
  133. DPF1(1,"----- DXVB: DSoundBuffer (WriteBuffer) about to copy to buffer (size1 = %d )\n",size1);
  134. if (p1)
  135. {
  136. DPF1(1,"----- DXVB: DSoundBuffer (WriteBuffer) about to copy to buffer (size1 = %d )\n",size1);
  137. memcpy (p1, buffer, size1);
  138. }
  139. if (p2) //There was wrapping
  140. {
  141. DPF1(1,"----- DXVB: DSoundBuffer (WriteBuffer) about to copy to buffer (size2 = %d )\n",size2);
  142. memcpy(p2, &buffer[size1], size2);
  143. }
  144. //docdoc: because Lock and Unlock are tied together within WriteBuffer,
  145. // DSBufferDesc no longer needs to save Lock's system pointers.
  146. DPF(1,"----- DXVB: DSoundBuffer (WriteBuffer) Unlocking buffer.\n");
  147. val=m__dxj_DirectSoundBuffer->Unlock(p1, size1, p2, size2);
  148. }
  149. __except(0,0){
  150. return E_FAIL;
  151. }
  152. return val;
  153. }
  154. /////////////////////////////////////////////////////////////////////////////
  155. //Java has no direct access to system memory, so it allocates it's own buffer
  156. //which is passed into WriteBuffer(). Because the environment is now double
  157. //buffered there is no need to Lock Java memory. WriteBuffer() calls
  158. //both lock and Unlock internally to write the result after the fact.
  159. /////////////////////////////////////////////////////////////////////////////
  160. STDMETHODIMP C_dxj_DirectSoundBufferObject::readBuffer(long start, long totsz,
  161. void *buf, long flags)
  162. {
  163. byte *buffer=(byte*)buf;
  164. if(!buffer)
  165. return E_POINTER;
  166. LPVOID p1, p2;
  167. DWORD size1=0, size2=0;
  168. HRESULT val = E_FAIL;
  169. __try {
  170. if ((val = m__dxj_DirectSoundBuffer->Lock((DWORD)start, (DWORD)totsz, &p1, &size1, &p2, &size2,
  171. (DWORD)flags)) != DS_OK)
  172. return val;
  173. // Copy to buffer end, then do a wrapped portion if it exists, then unlock
  174. if (p1)
  175. {
  176. DPF1(1,"----- DXVB: DSoundBuffer (ReadBuffer) about to copy to buffer (size1 = %d )\n",size1);
  177. memcpy (buffer,p1, size1);
  178. }
  179. if (p2) //There was wrapping
  180. {
  181. DPF1(1,"----- DXVB: DSoundBuffer (ReadBuffer) about to copy to buffer (size2 = %d )\n",size2);
  182. memcpy(&buffer[size1],p2, size2);
  183. }
  184. //docdoc: because Lock and Unlock are tied together within WriteBuffer,
  185. // DSBufferDesc no longer needs to save Lock's system pointers.
  186. DPF(1,"----- DXVB: DSoundBuffer (ReadBuffer) Unlocking buffer.\n");
  187. val= m__dxj_DirectSoundBuffer->Unlock(p1, size1, p2, size2);
  188. }
  189. __except(1,1){
  190. return E_FAIL;
  191. }
  192. return val;
  193. }
  194. /////////////////////////////////////////////////////////////////////////////
  195. STDMETHODIMP C_dxj_DirectSoundBufferObject::getFormat(WAVEFORMATEX_CDESC *format)
  196. {
  197. DWORD *wsize=0; // docdoc: throw away returned written size
  198. HRESULT hr=DS_OK;
  199. __try {
  200. hr=m__dxj_DirectSoundBuffer->GetFormat((LPWAVEFORMATEX)format, (DWORD)sizeof(WAVEFORMATEX_CDESC), wsize);
  201. }
  202. __except(EXCEPTION_EXECUTE_HANDLER)
  203. {
  204. return E_FAIL;
  205. }
  206. return hr;
  207. }
  208. /////////////////////////////////////////////////////////////////////////////
  209. STDMETHODIMP C_dxj_DirectSoundBufferObject::initialize(I_dxj_DirectSound *ds,
  210. DSBUFFERDESC_CDESC *buf, unsigned char *wave)
  211. {
  212. if(! (ds && buf && wave) )
  213. return E_POINTER;
  214. LPDSBUFFERDESC lpds = NULL;
  215. __try {
  216. lpds = (LPDSBUFFERDESC)malloc(sizeof(DSBUFFERDESC));
  217. if (!lpds)
  218. return E_OUTOFMEMORY;
  219. ZeroMemory(lpds, sizeof(DSBUFFERDESC));
  220. lpds->dwSize = sizeof(DSBUFFERDESC);
  221. lpds->dwFlags = buf->lFlags;
  222. lpds->dwBufferBytes = buf->lBufferBytes;
  223. lpds->dwReserved = buf->lReserved;
  224. #ifdef _WIN64
  225. lpds->lpwfxFormat = (WAVEFORMATEX*)wave;
  226. #else
  227. lpds->lpwfxFormat = (WAVEFORMATEX*)PtrToLong(wave);
  228. #endif
  229. AudioBSTRtoGUID(&lpds->guid3DAlgorithm, buf->guid3DAlgorithm);
  230. DO_GETOBJECT_NOTNULL(LPDIRECTSOUND, lpdsound, ds)
  231. m__dxj_DirectSoundBuffer->Initialize(lpdsound, (LPDSBUFFERDESC)lpds);
  232. }
  233. __except(EXCEPTION_EXECUTE_HANDLER)
  234. {
  235. return E_FAIL;
  236. }
  237. return S_OK;
  238. }
  239. /////////////////////////////////////////////////////////////////////////////
  240. STDMETHODIMP C_dxj_DirectSoundBufferObject::play(long flags)
  241. {
  242. HRESULT hr=DS_OK;
  243. __try {
  244. if((hr=m__dxj_DirectSoundBuffer->Play(0, 0, (DWORD)flags)) != DS_OK)
  245. return hr;
  246. }
  247. __except(EXCEPTION_EXECUTE_HANDLER)
  248. {
  249. return E_FAIL;
  250. }
  251. return hr;
  252. }
  253. STDMETHODIMP C_dxj_DirectSoundBufferObject::setNotificationPositions (long nElements,SAFEARRAY **ppsa)
  254. {
  255. if (!ISSAFEARRAY1D(ppsa,(DWORD)nElements))
  256. return E_INVALIDARG;
  257. HRESULT hr;
  258. LPDIRECTSOUNDNOTIFY pDSN=NULL;
  259. __try {
  260. if (nElements == 0)
  261. {
  262. // There is absolutely nothing to do if we want to set 0 notification positions
  263. return S_OK;
  264. }
  265. hr=m__dxj_DirectSoundBuffer->QueryInterface(IID_IDirectSoundNotify,(void**)&pDSN);
  266. if FAILED(hr) return hr;
  267. hr=pDSN->SetNotificationPositions((DWORD)nElements,(LPCDSBPOSITIONNOTIFY)((SAFEARRAY*)*ppsa)->pvData);
  268. pDSN->Release();
  269. }
  270. __except(EXCEPTION_EXECUTE_HANDLER)
  271. {
  272. return E_FAIL;
  273. }
  274. return hr;
  275. }
  276. STDMETHODIMP C_dxj_DirectSoundBufferObject::saveToFile(BSTR file)
  277. {
  278. HRESULT hr= InternalSaveToFile(m__dxj_DirectSoundBuffer,file);
  279. return hr;
  280. }
  281. STDMETHODIMP C_dxj_DirectSoundBufferObject::SetFX(long lEffectsCount, SAFEARRAY **Buffers, SAFEARRAY **lResultIDs)
  282. {
  283. HRESULT hr;
  284. DSEFFECTDESC *dsec = NULL;
  285. DSEFFECTDESC_CDESC *bufTemp = NULL;
  286. DWORD *dwRetStatus = NULL;
  287. __try {
  288. if (lEffectsCount != 0)
  289. {
  290. // Get memory for our effects buffers
  291. dsec = (DSEFFECTDESC*)malloc(sizeof(DSEFFECTDESC) * lEffectsCount);
  292. if (!dsec) return E_OUTOFMEMORY;
  293. //Get memory for our Status
  294. dwRetStatus = (DWORD*)malloc(sizeof(DWORD) * lEffectsCount);
  295. if (!dwRetStatus)
  296. {
  297. SAFE_DELETE(dsec);
  298. return E_OUTOFMEMORY;
  299. }
  300. ZeroMemory(dwRetStatus,sizeof(DWORD) * lEffectsCount);
  301. bufTemp = (DSEFFECTDESC_CDESC*)malloc(sizeof(DSEFFECTDESC_CDESC) * lEffectsCount);
  302. if (!bufTemp) return E_OUTOFMEMORY;
  303. memcpy(bufTemp, (DSEFFECTDESC_CDESC*)((SAFEARRAY*)*Buffers)->pvData, sizeof(DSEFFECTDESC_CDESC) * lEffectsCount);
  304. // Set up our effect
  305. for (int i=0 ; i<=lEffectsCount-1 ; i++)
  306. {
  307. ZeroMemory(&dsec[i], sizeof(DSEFFECTDESC));
  308. dsec[i].dwSize = sizeof(DSEFFECTDESC);
  309. dsec[i].dwFlags = (DWORD) bufTemp[i].lFlags;
  310. #if 0
  311. DO_GETOBJECT_NOTNULL(LPDIRECTSOUNDBUFFER, lpBuf, bufTemp[i].SendBuffer);
  312. dsec[i].lpSendBuffer = lpBuf;
  313. #endif
  314. if (FAILED (hr = AudioBSTRtoGUID(&dsec[i].guidDSFXClass, bufTemp[i].guidDSFXClass ) ) )
  315. {
  316. SAFE_DELETE(dsec);
  317. SAFE_DELETE(bufTemp);
  318. return hr;
  319. }
  320. }
  321. // We no longer need this
  322. SAFE_DELETE(bufTemp);
  323. }
  324. if (FAILED (hr = m__dxj_DirectSoundBuffer->SetFX((DWORD)lEffectsCount, dsec, dwRetStatus) ))
  325. {
  326. SAFE_DELETE(dsec);
  327. return hr;
  328. }
  329. SAFE_DELETE(dsec);
  330. // Now we can return our status's
  331. if (dwRetStatus)
  332. memcpy(((SAFEARRAY*)*lResultIDs)->pvData, dwRetStatus, sizeof(DWORD) * lEffectsCount);
  333. SAFE_DELETE(dwRetStatus);
  334. }
  335. __except(EXCEPTION_EXECUTE_HANDLER)
  336. {
  337. return E_FAIL;
  338. }
  339. return S_OK;
  340. }
  341. STDMETHODIMP C_dxj_DirectSoundBufferObject::AcquireResources(long lFlags, SAFEARRAY **lEffects)
  342. {
  343. HRESULT hr;
  344. DWORD *dwRetStatus = NULL;
  345. DWORD dwEffectsCount = 0;
  346. __try {
  347. dwEffectsCount = (DWORD)((SAFEARRAY*)*lEffects)->rgsabound[0].cElements;
  348. //Get memory for our Status
  349. dwRetStatus = (DWORD*)malloc(sizeof(DWORD) * dwEffectsCount);
  350. if (!dwRetStatus)
  351. return E_OUTOFMEMORY;
  352. ZeroMemory(dwRetStatus,sizeof(DWORD) * dwEffectsCount);
  353. if (FAILED ( hr = m__dxj_DirectSoundBuffer->AcquireResources((DWORD) lFlags, dwEffectsCount, dwRetStatus) ) )
  354. return hr;
  355. // Now we can return our status's
  356. memcpy(((SAFEARRAY*)*lEffects)->pvData, dwRetStatus, sizeof(DWORD) * dwEffectsCount);
  357. SAFE_DELETE(dwRetStatus);
  358. }
  359. __except(EXCEPTION_EXECUTE_HANDLER)
  360. {
  361. return E_FAIL;
  362. }
  363. return S_OK;
  364. }
  365. STDMETHODIMP C_dxj_DirectSoundBufferObject::GetObjectinPath(BSTR guidFX, long lIndex, BSTR iidInterface, IUnknown **ret)
  366. {
  367. HRESULT hr;
  368. GUID guidEffect;
  369. GUID guidIID;
  370. __try {
  371. if (FAILED (hr = AudioBSTRtoGUID(&guidEffect, guidFX ) ) )
  372. return hr;
  373. if (FAILED (hr = AudioBSTRtoGUID(&guidIID, iidInterface ) ) )
  374. return hr;
  375. if( 0==_wcsicmp(guidFX,L"guid_dsfx_standard_gargle")){
  376. IDirectSoundFXGargle *lpRetObj = NULL;
  377. if (FAILED ( hr= m__dxj_DirectSoundBuffer->GetObjectInPath(guidEffect, (DWORD) lIndex, guidIID, (void**) &lpRetObj) ) )
  378. return hr;
  379. INTERNAL_CREATE(_dxj_DirectSoundFXGargle, lpRetObj, ret);
  380. }
  381. #if 0
  382. else if( 0==_wcsicmp(guidFX,L"guid_dsfx_send")){
  383. IDirectSoundFXSend *lpRetObj = NULL;
  384. if (FAILED ( hr= m__dxj_DirectSoundBuffer->GetObjectInPath(guidEffect, (DWORD) lIndex, guidIID, (void**) &lpRetObj) ) )
  385. return hr;
  386. INTERNAL_CREATE(_dxj_DirectSoundFXSend, lpRetObj, ret);
  387. }
  388. #endif
  389. else if( 0==_wcsicmp(guidFX,L"guid_dsfx_standard_echo")){
  390. IDirectSoundFXEcho *lpRetObj = NULL;
  391. if (FAILED ( hr= m__dxj_DirectSoundBuffer->GetObjectInPath(guidEffect, (DWORD) lIndex, guidIID, (void**) &lpRetObj) ) )
  392. return hr;
  393. INTERNAL_CREATE(_dxj_DirectSoundFXEcho, lpRetObj, ret);
  394. }
  395. else if( 0==_wcsicmp(guidFX,L"guid_dsfx_standard_chorus")){
  396. IDirectSoundFXChorus *lpRetObj = NULL;
  397. if (FAILED ( hr= m__dxj_DirectSoundBuffer->GetObjectInPath(guidEffect, (DWORD) lIndex, guidIID, (void**) &lpRetObj) ) )
  398. return hr;
  399. INTERNAL_CREATE(_dxj_DirectSoundFXChorus, lpRetObj, ret);
  400. }
  401. else if( 0==_wcsicmp(guidFX,L"guid_dsfx_standard_compressor")){
  402. IDirectSoundFXCompressor *lpRetObj = NULL;
  403. if (FAILED ( hr= m__dxj_DirectSoundBuffer->GetObjectInPath(guidEffect, (DWORD) lIndex, guidIID, (void**) &lpRetObj) ) )
  404. return hr;
  405. INTERNAL_CREATE(_dxj_DirectSoundFXCompressor, lpRetObj, ret);
  406. }
  407. else if( 0==_wcsicmp(guidFX,L"guid_dsfx_standard_distortion")){
  408. IDirectSoundFXDistortion *lpRetObj = NULL;
  409. if (FAILED ( hr= m__dxj_DirectSoundBuffer->GetObjectInPath(guidEffect, (DWORD) lIndex, guidIID, (void**) &lpRetObj) ) )
  410. return hr;
  411. INTERNAL_CREATE(_dxj_DirectSoundFXDistortion, lpRetObj, ret);
  412. }
  413. else if( 0==_wcsicmp(guidFX,L"guid_dsfx_standard_flanger")){
  414. IDirectSoundFXFlanger *lpRetObj = NULL;
  415. if (FAILED ( hr= m__dxj_DirectSoundBuffer->GetObjectInPath(guidEffect, (DWORD) lIndex, guidIID, (void**) &lpRetObj) ) )
  416. return hr;
  417. INTERNAL_CREATE(_dxj_DirectSoundFXFlanger, lpRetObj, ret);
  418. }
  419. #if 0
  420. else if( 0==_wcsicmp(guidFX,L"guid_dsfx_standard_i3dl2source")){
  421. IDirectSoundFXI3DL2Source *lpRetObj = NULL;
  422. if (FAILED ( hr= m__dxj_DirectSoundBuffer->GetObjectInPath(guidEffect, (DWORD) lIndex, guidIID, (void**) &lpRetObj) ) )
  423. return hr;
  424. INTERNAL_CREATE(_dxj_DirectSoundFXI3DL2Source, lpRetObj, ret);
  425. }
  426. #endif
  427. else if( 0==_wcsicmp(guidFX,L"guid_dsfx_standard_i3dl2reverb")){
  428. IDirectSoundFXI3DL2Reverb *lpRetObj = NULL;
  429. if (FAILED ( hr= m__dxj_DirectSoundBuffer->GetObjectInPath(guidEffect, (DWORD) lIndex, guidIID, (void**) &lpRetObj) ) )
  430. return hr;
  431. INTERNAL_CREATE(_dxj_DirectSoundFXI3DL2Reverb, lpRetObj, ret);
  432. }
  433. else if( 0==_wcsicmp(guidFX,L"guid_dsfx_standard_parameq")){
  434. IDirectSoundFXParamEq *lpRetObj = NULL;
  435. if (FAILED ( hr= m__dxj_DirectSoundBuffer->GetObjectInPath(guidEffect, (DWORD) lIndex, guidIID, (void**) &lpRetObj) ) )
  436. return hr;
  437. INTERNAL_CREATE(_dxj_DirectSoundFXParamEQ, lpRetObj, ret);
  438. }
  439. else if( 0==_wcsicmp(guidFX,L"guid_dsfx_waves_reverb")){
  440. IDirectSoundFXWavesReverb *lpRetObj = NULL;
  441. if (FAILED ( hr= m__dxj_DirectSoundBuffer->GetObjectInPath(guidEffect, (DWORD) lIndex, guidIID, (void**) &lpRetObj) ) )
  442. return hr;
  443. INTERNAL_CREATE(_dxj_DirectSoundFXWavesReverb, lpRetObj, ret);
  444. }
  445. else
  446. return E_INVALIDARG;
  447. }
  448. __except(EXCEPTION_EXECUTE_HANDLER)
  449. {
  450. return E_FAIL;
  451. }
  452. return S_OK;
  453. }
  454. #if 0
  455. STDMETHODIMP C_dxj_DirectSoundBufferObject::SetChannelVolume(long lChannelCount, SAFEARRAY **lChannels, SAFEARRAY **lVolumes)
  456. {
  457. HRESULT hr;
  458. __try {
  459. if (FAILED(hr = m__dxj_DirectSoundBuffer->SetChannelVolume((DWORD) lChannelCount, (DWORD*) ((SAFEARRAY*)*lChannels)->pvData, (long*) ((SAFEARRAY*)*lVolumes)->pvData) ) )
  460. return hr;
  461. }
  462. __except(EXCEPTION_EXECUTE_HANDLER)
  463. {
  464. return E_FAIL;
  465. }
  466. return S_OK;
  467. }
  468. #endif