|
|
//+-------------------------------------------------------------------------
//
// Microsoft Windows
//
// Copyright (C) Microsoft Corporation, 1998 - 1999
//
// File: dsoundbufferobj.cpp
//
//--------------------------------------------------------------------------
// dSoundBufferObj.cpp : Implementation of CDirectApp and DLL registration.
// DHF_DS entire file
#include "stdafx.h"
#include "Direct.h"
#include "dSound.h"
#include "dms.h"
#include "dSoundBufferObj.h"
#include "dSoundObj.h"
#include "dSound3DListener.h"
#include "dSound3DBuffer.h"
#include "dsoundFXGargleobj.h"
#include "dsoundFXEchoobj.h"
#include "dsoundFXChorusobj.h"
#include "dsoundFXCompressorobj.h"
#include "dsoundFXDistortionobj.h"
#include "dsoundFXFlangerobj.h"
#include "dsoundfxi3dl2reverbobj.h"
#if 0
#include "dsoundfxi3dl2sourceobj.h"
#include "dsoundfxsendobj.h"
#endif
#include "dsoundfxparameqobj.h"
#include "dsoundfxwavesreverbobj.h"
extern void *g_dxj_DirectSoundFXWavesReverb; extern void *g_dxj_DirectSoundFXCompressor; extern void *g_dxj_DirectSoundFXChorus; extern void *g_dxj_DirectSoundFXGargle; extern void *g_dxj_DirectSoundFXEcho; extern void *g_dxj_DirectSoundFXSend; extern void *g_dxj_DirectSoundFXDistortion; extern void *g_dxj_DirectSoundFXFlanger; extern void *g_dxj_DirectSoundFXParamEQ; extern void *g_dxj_DirectSoundFXI3DL2Reverb; #if 0
extern void *g_dxj_DirectSoundFXI3DL2Source; #endif
#define SAFE_DELETE(p) { if (p) {free(p); p = NULL;} }
extern HRESULT AudioBSTRtoGUID(LPGUID,BSTR); extern HRESULT InternalSaveToFile(IDirectSoundBuffer *pBuff,BSTR file);
CONSTRUCTOR(_dxj_DirectSoundBuffer, {}); DESTRUCTOR(_dxj_DirectSoundBuffer, {}); GETSET_OBJECT(_dxj_DirectSoundBuffer);
PASS_THROUGH1_R(_dxj_DirectSoundBuffer, getVolume, GetVolume, long*); PASS_THROUGH1_R(_dxj_DirectSoundBuffer, getPan, GetPan, long*); PASS_THROUGH_CAST_1_R(_dxj_DirectSoundBuffer, getFrequency, GetFrequency, long*,(DWORD*)); PASS_THROUGH_CAST_1_R(_dxj_DirectSoundBuffer, getStatus, GetStatus, long*,(DWORD*));
PASS_THROUGH_CAST_1_R(_dxj_DirectSoundBuffer, setCurrentPosition, SetCurrentPosition, long,(DWORD)); PASS_THROUGH1_R(_dxj_DirectSoundBuffer, setPan, SetPan, LONG); PASS_THROUGH_CAST_1_R(_dxj_DirectSoundBuffer, setFrequency, SetFrequency, long,(DWORD)); PASS_THROUGH_R(_dxj_DirectSoundBuffer, stop, Stop); PASS_THROUGH_R(_dxj_DirectSoundBuffer, restore, Restore);
STDMETHODIMP C_dxj_DirectSoundBufferObject::setVolume(LONG vol) { __try { return m__dxj_DirectSoundBuffer->SetVolume(vol); } __except(EXCEPTION_EXECUTE_HANDLER) { return E_FAIL; } }
STDMETHODIMP C_dxj_DirectSoundBufferObject::getDirectSound3dBuffer(I_dxj_DirectSound3dBuffer **retval) { IDirectSound3DBuffer *lp3db; HRESULT hr = S_OK;
__try { if( (hr=m__dxj_DirectSoundBuffer->QueryInterface(IID_IDirectSound3DBuffer, (void**) &lp3db)) != S_OK) return hr;
INTERNAL_CREATE(_dxj_DirectSound3dBuffer, lp3db, retval);
} __except(EXCEPTION_EXECUTE_HANDLER) { return E_FAIL; } return hr; }
STDMETHODIMP C_dxj_DirectSoundBufferObject::getCaps(DSBCAPS_CDESC* caps) { __try { if(!caps) return E_POINTER;
caps->lSize = sizeof(DSBCAPS); return m__dxj_DirectSoundBuffer->GetCaps((LPDSBCAPS)caps); } __except(EXCEPTION_EXECUTE_HANDLER) { return E_FAIL; }
}
/////////////////////////////////////////////////////////////////////////////
STDMETHODIMP C_dxj_DirectSoundBufferObject::getCurrentPosition(DSCURSORS_CDESC *desc) { __try { if(!desc) return E_POINTER; return (m__dxj_DirectSoundBuffer->GetCurrentPosition((DWORD*)&desc->lPlay, (DWORD*)&desc->lWrite) ); } __except(EXCEPTION_EXECUTE_HANDLER) { return E_FAIL; }
}
/////////////////////////////////////////////////////////////////////////////
//Java has no direct access to system memory, so it allocates it's own buffer
//which is passed into WriteBuffer(). Because the environment is now double
//buffered there is no need to Lock Java memory. WriteBuffer() calls
//both lock and Unlock internally to write the result after the fact.
/////////////////////////////////////////////////////////////////////////////
STDMETHODIMP C_dxj_DirectSoundBufferObject::writeBuffer(long start, long totsz, void *buf, long flags) { #pragma message ("SoundBuffer writeBuffer ")
byte *buffer=(byte*)buf; //(byte*)((SAFEARRAY*)*ppsa)->pvData;
if(!buffer) return E_POINTER;
LPVOID p1, p2; DWORD size1=0, size2=0; HRESULT val = E_FAIL;
__try { if ((val = m__dxj_DirectSoundBuffer->Lock((DWORD)start, (DWORD)totsz, &p1, &size1, &p2, &size2, (DWORD)flags)) != DS_OK) return val;
// Copy to buffer end, then do a wrapped portion if it exists, then unlock
DPF1(1,"----- DXVB: DSoundBuffer (WriteBuffer) about to copy to buffer (size1 = %d )\n",size1); if (p1) { DPF1(1,"----- DXVB: DSoundBuffer (WriteBuffer) about to copy to buffer (size1 = %d )\n",size1); memcpy (p1, buffer, size1); }
if (p2) //There was wrapping
{ DPF1(1,"----- DXVB: DSoundBuffer (WriteBuffer) about to copy to buffer (size2 = %d )\n",size2); memcpy(p2, &buffer[size1], size2); }
//docdoc: because Lock and Unlock are tied together within WriteBuffer,
// DSBufferDesc no longer needs to save Lock's system pointers.
DPF(1,"----- DXVB: DSoundBuffer (WriteBuffer) Unlocking buffer.\n"); val=m__dxj_DirectSoundBuffer->Unlock(p1, size1, p2, size2); } __except(0,0){ return E_FAIL; } return val; }
/////////////////////////////////////////////////////////////////////////////
//Java has no direct access to system memory, so it allocates it's own buffer
//which is passed into WriteBuffer(). Because the environment is now double
//buffered there is no need to Lock Java memory. WriteBuffer() calls
//both lock and Unlock internally to write the result after the fact.
/////////////////////////////////////////////////////////////////////////////
STDMETHODIMP C_dxj_DirectSoundBufferObject::readBuffer(long start, long totsz, void *buf, long flags) {
byte *buffer=(byte*)buf;
if(!buffer) return E_POINTER; LPVOID p1, p2; DWORD size1=0, size2=0; HRESULT val = E_FAIL; __try { if ((val = m__dxj_DirectSoundBuffer->Lock((DWORD)start, (DWORD)totsz, &p1, &size1, &p2, &size2, (DWORD)flags)) != DS_OK) return val;
// Copy to buffer end, then do a wrapped portion if it exists, then unlock
if (p1) { DPF1(1,"----- DXVB: DSoundBuffer (ReadBuffer) about to copy to buffer (size1 = %d )\n",size1); memcpy (buffer,p1, size1); }
if (p2) //There was wrapping
{ DPF1(1,"----- DXVB: DSoundBuffer (ReadBuffer) about to copy to buffer (size2 = %d )\n",size2); memcpy(&buffer[size1],p2, size2); }
//docdoc: because Lock and Unlock are tied together within WriteBuffer,
// DSBufferDesc no longer needs to save Lock's system pointers.
DPF(1,"----- DXVB: DSoundBuffer (ReadBuffer) Unlocking buffer.\n"); val= m__dxj_DirectSoundBuffer->Unlock(p1, size1, p2, size2); } __except(1,1){ return E_FAIL; } return val; }
/////////////////////////////////////////////////////////////////////////////
STDMETHODIMP C_dxj_DirectSoundBufferObject::getFormat(WAVEFORMATEX_CDESC *format) { DWORD *wsize=0; // docdoc: throw away returned written size
HRESULT hr=DS_OK; __try { hr=m__dxj_DirectSoundBuffer->GetFormat((LPWAVEFORMATEX)format, (DWORD)sizeof(WAVEFORMATEX_CDESC), wsize); } __except(EXCEPTION_EXECUTE_HANDLER) { return E_FAIL; } return hr; }
/////////////////////////////////////////////////////////////////////////////
STDMETHODIMP C_dxj_DirectSoundBufferObject::initialize(I_dxj_DirectSound *ds, DSBUFFERDESC_CDESC *buf, unsigned char *wave) { if(! (ds && buf && wave) ) return E_POINTER;
LPDSBUFFERDESC lpds = NULL;
__try { lpds = (LPDSBUFFERDESC)malloc(sizeof(DSBUFFERDESC)); if (!lpds) return E_OUTOFMEMORY;
ZeroMemory(lpds, sizeof(DSBUFFERDESC));
lpds->dwSize = sizeof(DSBUFFERDESC); lpds->dwFlags = buf->lFlags; lpds->dwBufferBytes = buf->lBufferBytes; lpds->dwReserved = buf->lReserved; #ifdef _WIN64
lpds->lpwfxFormat = (WAVEFORMATEX*)wave; #else
lpds->lpwfxFormat = (WAVEFORMATEX*)PtrToLong(wave); #endif
AudioBSTRtoGUID(&lpds->guid3DAlgorithm, buf->guid3DAlgorithm);
DO_GETOBJECT_NOTNULL(LPDIRECTSOUND, lpdsound, ds)
m__dxj_DirectSoundBuffer->Initialize(lpdsound, (LPDSBUFFERDESC)lpds);
} __except(EXCEPTION_EXECUTE_HANDLER) { return E_FAIL; } return S_OK; }
/////////////////////////////////////////////////////////////////////////////
STDMETHODIMP C_dxj_DirectSoundBufferObject::play(long flags) { HRESULT hr=DS_OK; __try { if((hr=m__dxj_DirectSoundBuffer->Play(0, 0, (DWORD)flags)) != DS_OK) return hr; } __except(EXCEPTION_EXECUTE_HANDLER) { return E_FAIL; }
return hr; }
STDMETHODIMP C_dxj_DirectSoundBufferObject::setNotificationPositions (long nElements,SAFEARRAY **ppsa) { if (!ISSAFEARRAY1D(ppsa,(DWORD)nElements)) return E_INVALIDARG; HRESULT hr; LPDIRECTSOUNDNOTIFY pDSN=NULL;
__try { if (nElements == 0) { // There is absolutely nothing to do if we want to set 0 notification positions
return S_OK; }
hr=m__dxj_DirectSoundBuffer->QueryInterface(IID_IDirectSoundNotify,(void**)&pDSN); if FAILED(hr) return hr;
hr=pDSN->SetNotificationPositions((DWORD)nElements,(LPCDSBPOSITIONNOTIFY)((SAFEARRAY*)*ppsa)->pvData); pDSN->Release();
} __except(EXCEPTION_EXECUTE_HANDLER) { return E_FAIL; } return hr; }
STDMETHODIMP C_dxj_DirectSoundBufferObject::saveToFile(BSTR file) {
HRESULT hr= InternalSaveToFile(m__dxj_DirectSoundBuffer,file); return hr; }
STDMETHODIMP C_dxj_DirectSoundBufferObject::SetFX(long lEffectsCount, SAFEARRAY **Buffers, SAFEARRAY **lResultIDs) { HRESULT hr;
DSEFFECTDESC *dsec = NULL; DSEFFECTDESC_CDESC *bufTemp = NULL; DWORD *dwRetStatus = NULL;
__try { if (lEffectsCount != 0) { // Get memory for our effects buffers
dsec = (DSEFFECTDESC*)malloc(sizeof(DSEFFECTDESC) * lEffectsCount); if (!dsec) return E_OUTOFMEMORY;
//Get memory for our Status
dwRetStatus = (DWORD*)malloc(sizeof(DWORD) * lEffectsCount); if (!dwRetStatus) { SAFE_DELETE(dsec); return E_OUTOFMEMORY; } ZeroMemory(dwRetStatus,sizeof(DWORD) * lEffectsCount);
bufTemp = (DSEFFECTDESC_CDESC*)malloc(sizeof(DSEFFECTDESC_CDESC) * lEffectsCount); if (!bufTemp) return E_OUTOFMEMORY;
memcpy(bufTemp, (DSEFFECTDESC_CDESC*)((SAFEARRAY*)*Buffers)->pvData, sizeof(DSEFFECTDESC_CDESC) * lEffectsCount);
// Set up our effect
for (int i=0 ; i<=lEffectsCount-1 ; i++) { ZeroMemory(&dsec[i], sizeof(DSEFFECTDESC)); dsec[i].dwSize = sizeof(DSEFFECTDESC); dsec[i].dwFlags = (DWORD) bufTemp[i].lFlags; #if 0
DO_GETOBJECT_NOTNULL(LPDIRECTSOUNDBUFFER, lpBuf, bufTemp[i].SendBuffer); dsec[i].lpSendBuffer = lpBuf; #endif
if (FAILED (hr = AudioBSTRtoGUID(&dsec[i].guidDSFXClass, bufTemp[i].guidDSFXClass ) ) ) { SAFE_DELETE(dsec); SAFE_DELETE(bufTemp); return hr; } } // We no longer need this
SAFE_DELETE(bufTemp); }
if (FAILED (hr = m__dxj_DirectSoundBuffer->SetFX((DWORD)lEffectsCount, dsec, dwRetStatus) )) { SAFE_DELETE(dsec); return hr; }
SAFE_DELETE(dsec); // Now we can return our status's
if (dwRetStatus) memcpy(((SAFEARRAY*)*lResultIDs)->pvData, dwRetStatus, sizeof(DWORD) * lEffectsCount);
SAFE_DELETE(dwRetStatus);
} __except(EXCEPTION_EXECUTE_HANDLER) { return E_FAIL; }
return S_OK; } STDMETHODIMP C_dxj_DirectSoundBufferObject::AcquireResources(long lFlags, SAFEARRAY **lEffects) { HRESULT hr; DWORD *dwRetStatus = NULL; DWORD dwEffectsCount = 0;
__try { dwEffectsCount = (DWORD)((SAFEARRAY*)*lEffects)->rgsabound[0].cElements; //Get memory for our Status
dwRetStatus = (DWORD*)malloc(sizeof(DWORD) * dwEffectsCount); if (!dwRetStatus) return E_OUTOFMEMORY;
ZeroMemory(dwRetStatus,sizeof(DWORD) * dwEffectsCount);
if (FAILED ( hr = m__dxj_DirectSoundBuffer->AcquireResources((DWORD) lFlags, dwEffectsCount, dwRetStatus) ) ) return hr; // Now we can return our status's
memcpy(((SAFEARRAY*)*lEffects)->pvData, dwRetStatus, sizeof(DWORD) * dwEffectsCount); SAFE_DELETE(dwRetStatus);
} __except(EXCEPTION_EXECUTE_HANDLER) { return E_FAIL; } return S_OK; }
STDMETHODIMP C_dxj_DirectSoundBufferObject::GetObjectinPath(BSTR guidFX, long lIndex, BSTR iidInterface, IUnknown **ret) { HRESULT hr; GUID guidEffect; GUID guidIID;
__try { if (FAILED (hr = AudioBSTRtoGUID(&guidEffect, guidFX ) ) ) return hr;
if (FAILED (hr = AudioBSTRtoGUID(&guidIID, iidInterface ) ) ) return hr;
if( 0==_wcsicmp(guidFX,L"guid_dsfx_standard_gargle")){ IDirectSoundFXGargle *lpRetObj = NULL;
if (FAILED ( hr= m__dxj_DirectSoundBuffer->GetObjectInPath(guidEffect, (DWORD) lIndex, guidIID, (void**) &lpRetObj) ) ) return hr; INTERNAL_CREATE(_dxj_DirectSoundFXGargle, lpRetObj, ret); } #if 0
else if( 0==_wcsicmp(guidFX,L"guid_dsfx_send")){ IDirectSoundFXSend *lpRetObj = NULL;
if (FAILED ( hr= m__dxj_DirectSoundBuffer->GetObjectInPath(guidEffect, (DWORD) lIndex, guidIID, (void**) &lpRetObj) ) ) return hr; INTERNAL_CREATE(_dxj_DirectSoundFXSend, lpRetObj, ret); } #endif
else if( 0==_wcsicmp(guidFX,L"guid_dsfx_standard_echo")){ IDirectSoundFXEcho *lpRetObj = NULL;
if (FAILED ( hr= m__dxj_DirectSoundBuffer->GetObjectInPath(guidEffect, (DWORD) lIndex, guidIID, (void**) &lpRetObj) ) ) return hr; INTERNAL_CREATE(_dxj_DirectSoundFXEcho, lpRetObj, ret); } else if( 0==_wcsicmp(guidFX,L"guid_dsfx_standard_chorus")){ IDirectSoundFXChorus *lpRetObj = NULL;
if (FAILED ( hr= m__dxj_DirectSoundBuffer->GetObjectInPath(guidEffect, (DWORD) lIndex, guidIID, (void**) &lpRetObj) ) ) return hr; INTERNAL_CREATE(_dxj_DirectSoundFXChorus, lpRetObj, ret); } else if( 0==_wcsicmp(guidFX,L"guid_dsfx_standard_compressor")){ IDirectSoundFXCompressor *lpRetObj = NULL;
if (FAILED ( hr= m__dxj_DirectSoundBuffer->GetObjectInPath(guidEffect, (DWORD) lIndex, guidIID, (void**) &lpRetObj) ) ) return hr; INTERNAL_CREATE(_dxj_DirectSoundFXCompressor, lpRetObj, ret); } else if( 0==_wcsicmp(guidFX,L"guid_dsfx_standard_distortion")){ IDirectSoundFXDistortion *lpRetObj = NULL;
if (FAILED ( hr= m__dxj_DirectSoundBuffer->GetObjectInPath(guidEffect, (DWORD) lIndex, guidIID, (void**) &lpRetObj) ) ) return hr; INTERNAL_CREATE(_dxj_DirectSoundFXDistortion, lpRetObj, ret); } else if( 0==_wcsicmp(guidFX,L"guid_dsfx_standard_flanger")){ IDirectSoundFXFlanger *lpRetObj = NULL;
if (FAILED ( hr= m__dxj_DirectSoundBuffer->GetObjectInPath(guidEffect, (DWORD) lIndex, guidIID, (void**) &lpRetObj) ) ) return hr; INTERNAL_CREATE(_dxj_DirectSoundFXFlanger, lpRetObj, ret); } #if 0
else if( 0==_wcsicmp(guidFX,L"guid_dsfx_standard_i3dl2source")){ IDirectSoundFXI3DL2Source *lpRetObj = NULL;
if (FAILED ( hr= m__dxj_DirectSoundBuffer->GetObjectInPath(guidEffect, (DWORD) lIndex, guidIID, (void**) &lpRetObj) ) ) return hr; INTERNAL_CREATE(_dxj_DirectSoundFXI3DL2Source, lpRetObj, ret); } #endif
else if( 0==_wcsicmp(guidFX,L"guid_dsfx_standard_i3dl2reverb")){ IDirectSoundFXI3DL2Reverb *lpRetObj = NULL;
if (FAILED ( hr= m__dxj_DirectSoundBuffer->GetObjectInPath(guidEffect, (DWORD) lIndex, guidIID, (void**) &lpRetObj) ) ) return hr; INTERNAL_CREATE(_dxj_DirectSoundFXI3DL2Reverb, lpRetObj, ret); } else if( 0==_wcsicmp(guidFX,L"guid_dsfx_standard_parameq")){ IDirectSoundFXParamEq *lpRetObj = NULL;
if (FAILED ( hr= m__dxj_DirectSoundBuffer->GetObjectInPath(guidEffect, (DWORD) lIndex, guidIID, (void**) &lpRetObj) ) ) return hr; INTERNAL_CREATE(_dxj_DirectSoundFXParamEQ, lpRetObj, ret); } else if( 0==_wcsicmp(guidFX,L"guid_dsfx_waves_reverb")){ IDirectSoundFXWavesReverb *lpRetObj = NULL;
if (FAILED ( hr= m__dxj_DirectSoundBuffer->GetObjectInPath(guidEffect, (DWORD) lIndex, guidIID, (void**) &lpRetObj) ) ) return hr; INTERNAL_CREATE(_dxj_DirectSoundFXWavesReverb, lpRetObj, ret); } else return E_INVALIDARG;
} __except(EXCEPTION_EXECUTE_HANDLER) { return E_FAIL; } return S_OK; }
#if 0
STDMETHODIMP C_dxj_DirectSoundBufferObject::SetChannelVolume(long lChannelCount, SAFEARRAY **lChannels, SAFEARRAY **lVolumes) { HRESULT hr;
__try { if (FAILED(hr = m__dxj_DirectSoundBuffer->SetChannelVolume((DWORD) lChannelCount, (DWORD*) ((SAFEARRAY*)*lChannels)->pvData, (long*) ((SAFEARRAY*)*lVolumes)->pvData) ) ) return hr; } __except(EXCEPTION_EXECUTE_HANDLER) { return E_FAIL; } return S_OK; } #endif
|