dsound: Implement SetFX.
This commit is contained in:
parent
e6ae73359f
commit
17056b9f30
|
@ -21,6 +21,8 @@
|
|||
|
||||
#include <stdarg.h>
|
||||
|
||||
#define COBJMACROS
|
||||
|
||||
#define NONAMELESSSTRUCT
|
||||
#define NONAMELESSUNION
|
||||
#include "windef.h"
|
||||
|
@ -697,14 +699,129 @@ static HRESULT WINAPI IDirectSoundBufferImpl_SetFX(IDirectSoundBuffer8 *iface, D
|
|||
{
|
||||
IDirectSoundBufferImpl *This = impl_from_IDirectSoundBuffer8(iface);
|
||||
DWORD u;
|
||||
DSFilter *filters;
|
||||
HRESULT hr, hr2;
|
||||
DMO_MEDIA_TYPE dmt;
|
||||
WAVEFORMATEX wfx;
|
||||
|
||||
FIXME("(%p,%u,%p,%p): stub\n",This,dwEffectsCount,pDSFXDesc,pdwResultCodes);
|
||||
TRACE("(%p,%u,%p,%p)\n", This, dwEffectsCount, pDSFXDesc, pdwResultCodes);
|
||||
|
||||
if (pdwResultCodes)
|
||||
for (u=0; u<dwEffectsCount; u++) pdwResultCodes[u] = DSFXR_UNKNOWN;
|
||||
|
||||
WARN("control unavailable\n");
|
||||
return DSERR_CONTROLUNAVAIL;
|
||||
if ((dwEffectsCount > 0 && !pDSFXDesc) ||
|
||||
(dwEffectsCount == 0 && (pDSFXDesc || pdwResultCodes))
|
||||
)
|
||||
return E_INVALIDARG;
|
||||
|
||||
if (!(This->dsbd.dwFlags & DSBCAPS_CTRLFX)) {
|
||||
WARN("attempted to call SetFX on buffer without DSBCAPS_CTRLFX\n");
|
||||
return DSERR_CONTROLUNAVAIL;
|
||||
}
|
||||
|
||||
if (This->state != STATE_STOPPED)
|
||||
return DSERR_INVALIDCALL;
|
||||
|
||||
if (This->buffer->lockedbytes > 0)
|
||||
return DSERR_INVALIDCALL;
|
||||
|
||||
if (dwEffectsCount == 0) {
|
||||
if (This->num_filters > 0) {
|
||||
for (u = 0; u < This->num_filters; u++) {
|
||||
IMediaObject_Release(This->filters[u].obj);
|
||||
}
|
||||
HeapFree(GetProcessHeap(), 0, This->filters);
|
||||
|
||||
This->filters = NULL;
|
||||
This->num_filters = 0;
|
||||
}
|
||||
|
||||
return DS_OK;
|
||||
}
|
||||
|
||||
filters = HeapAlloc(GetProcessHeap(), 0, dwEffectsCount * sizeof(DSFilter));
|
||||
if (!filters) {
|
||||
WARN("out of memory\n");
|
||||
return DSERR_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
hr = DS_OK;
|
||||
|
||||
wfx.wFormatTag = WAVE_FORMAT_IEEE_FLOAT;
|
||||
wfx.nChannels = This->pwfx->nChannels;
|
||||
wfx.nSamplesPerSec = This->pwfx->nSamplesPerSec;
|
||||
wfx.wBitsPerSample = sizeof(float) * 8;
|
||||
wfx.nBlockAlign = (wfx.nChannels * wfx.wBitsPerSample)/8;
|
||||
wfx.nAvgBytesPerSec = wfx.nSamplesPerSec * wfx.nBlockAlign;
|
||||
wfx.cbSize = sizeof(wfx);
|
||||
|
||||
dmt.majortype = KSDATAFORMAT_TYPE_AUDIO;
|
||||
dmt.subtype = KSDATAFORMAT_SUBTYPE_IEEE_FLOAT;
|
||||
dmt.bFixedSizeSamples = TRUE;
|
||||
dmt.bTemporalCompression = FALSE;
|
||||
dmt.lSampleSize = sizeof(float) * This->pwfx->nChannels / 8;
|
||||
dmt.formattype = FORMAT_WaveFormatEx;
|
||||
dmt.pUnk = NULL;
|
||||
dmt.cbFormat = sizeof(WAVEFORMATEX);
|
||||
dmt.pbFormat = (BYTE*)&wfx;
|
||||
|
||||
for (u = 0; u < dwEffectsCount; u++) {
|
||||
hr2 = CoCreateInstance(&pDSFXDesc[u].guidDSFXClass, NULL, CLSCTX_INPROC_SERVER, &IID_IMediaObject, (LPVOID*)&filters[u].obj);
|
||||
|
||||
if (SUCCEEDED(hr2)) {
|
||||
hr2 = IMediaObject_SetInputType(filters[u].obj, 0, &dmt, 0);
|
||||
if (FAILED(hr2))
|
||||
WARN("Could not set DMO input type\n");
|
||||
}
|
||||
|
||||
if (SUCCEEDED(hr2)) {
|
||||
hr2 = IMediaObject_SetOutputType(filters[u].obj, 0, &dmt, 0);
|
||||
if (FAILED(hr2))
|
||||
WARN("Could not set DMO output type\n");
|
||||
}
|
||||
|
||||
if (FAILED(hr2)) {
|
||||
if (hr == DS_OK)
|
||||
hr = hr2;
|
||||
|
||||
if (pdwResultCodes)
|
||||
pdwResultCodes[u] = (hr2 == REGDB_E_CLASSNOTREG) ? DSFXR_UNKNOWN : DSFXR_FAILED;
|
||||
} else {
|
||||
if (pdwResultCodes)
|
||||
pdwResultCodes[u] = DSFXR_LOCSOFTWARE;
|
||||
}
|
||||
}
|
||||
|
||||
if (FAILED(hr)) {
|
||||
for (u = 0; u < dwEffectsCount; u++) {
|
||||
if (pdwResultCodes)
|
||||
pdwResultCodes[u] = (pdwResultCodes[u] != DSFXR_UNKNOWN) ? DSFXR_PRESENT : DSFXR_UNKNOWN;
|
||||
|
||||
if (filters[u].obj)
|
||||
IMediaObject_Release(filters[u].obj);
|
||||
}
|
||||
|
||||
HeapFree(GetProcessHeap(), 0, filters);
|
||||
} else {
|
||||
if (This->num_filters > 0) {
|
||||
for (u = 0; u < This->num_filters; u++) {
|
||||
IMediaObject_Release(This->filters[u].obj);
|
||||
if (This->filters[u].inplace) IMediaObjectInPlace_Release(This->filters[u].inplace);
|
||||
}
|
||||
HeapFree(GetProcessHeap(), 0, This->filters);
|
||||
}
|
||||
|
||||
for (u = 0; u < dwEffectsCount; u++) {
|
||||
memcpy(&filters[u].guid, &pDSFXDesc[u].guidDSFXClass, sizeof(GUID));
|
||||
if (FAILED(IMediaObject_QueryInterface(filters[u].obj, &IID_IMediaObjectInPlace, (void*)&filters[u].inplace)))
|
||||
filters[u].inplace = NULL;
|
||||
}
|
||||
|
||||
This->filters = filters;
|
||||
This->num_filters = dwEffectsCount;
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IDirectSoundBufferImpl_AcquireResources(IDirectSoundBuffer8 *iface,
|
||||
|
@ -1024,6 +1141,16 @@ void secondarybuffer_destroy(IDirectSoundBufferImpl *This)
|
|||
|
||||
HeapFree(GetProcessHeap(), 0, This->notifies);
|
||||
HeapFree(GetProcessHeap(), 0, This->pwfx);
|
||||
|
||||
if (This->filters) {
|
||||
int i;
|
||||
for (i = 0; i < This->num_filters; i++) {
|
||||
IMediaObject_Release(This->filters[i].obj);
|
||||
if (This->filters[i].inplace) IMediaObjectInPlace_Release(This->filters[i].inplace);
|
||||
}
|
||||
HeapFree(GetProcessHeap(), 0, This->filters);
|
||||
}
|
||||
|
||||
HeapFree(GetProcessHeap(), 0, This);
|
||||
|
||||
TRACE("(%p) released\n", This);
|
||||
|
|
|
@ -55,6 +55,7 @@
|
|||
#include "unknwn.h"
|
||||
#include "oleidl.h"
|
||||
#include "shobjidl.h"
|
||||
#include "strmif.h"
|
||||
|
||||
#include "initguid.h"
|
||||
#include "ksmedia.h"
|
||||
|
|
|
@ -26,7 +26,9 @@
|
|||
#include "wingdi.h"
|
||||
#include "mmdeviceapi.h"
|
||||
#include "audioclient.h"
|
||||
#include "mediaobj.h"
|
||||
#include "mmsystem.h"
|
||||
#include "uuids.h"
|
||||
|
||||
#include "wine/list.h"
|
||||
|
||||
|
@ -57,6 +59,12 @@ typedef struct _DSVOLUMEPAN
|
|||
LONG lPan;
|
||||
} DSVOLUMEPAN,*PDSVOLUMEPAN;
|
||||
|
||||
typedef struct DSFilter {
|
||||
GUID guid;
|
||||
IMediaObject* obj;
|
||||
IMediaObjectInPlace* inplace;
|
||||
} DSFilter;
|
||||
|
||||
/*****************************************************************************
|
||||
* IDirectSoundDevice implementation structure
|
||||
*/
|
||||
|
@ -160,6 +168,8 @@ struct IDirectSoundBufferImpl
|
|||
int mix_channels;
|
||||
bitsgetfunc get, get_aux;
|
||||
bitsputfunc put, put_aux;
|
||||
int num_filters;
|
||||
DSFilter* filters;
|
||||
|
||||
struct list entry;
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue