On 7/23/20 10:16 AM, Andrew Eikum wrote:
On Tue, Jul 21, 2020 at 06:16:51PM -0500, Zebediah Figura wrote:
@@ -1219,206 +1222,598 @@ static void test_primary_flags(void) IDirectSound8_Release(dso); }
-static void test_effects(void) +static IMediaObject testdmo; +static IMediaObjectInPlace testdmo_inplace; +static LONG testdmo_refcount; +static WAVEFORMATEX testdmo_input_type; +static BOOL testdmo_input_type_set, testdmo_output_type_set;
+static unsigned int got_Discontinuity; +static HANDLE got_Process;
+static HRESULT WINAPI dmo_QueryInterface(IMediaObject *iface, REFIID iid, void **out) {
- HRESULT rc;
- LPDIRECTSOUND8 dso;
- LPDIRECTSOUNDBUFFER primary, secondary;
- LPDIRECTSOUNDBUFFER8 secondary8;
- DSBUFFERDESC bufdesc;
- WAVEFORMATEX wfx;
- DSEFFECTDESC effects[2];
- DWORD resultcodes[2];
- if (winetest_debug > 1) trace("QueryInterface(%s)\n", wine_dbgstr_guid(iid));
- /* Create a DirectSound8 object */
- rc = DirectSoundCreate8(NULL, &dso, NULL);
- ok(rc==DS_OK||rc==DSERR_NODRIVER,"DirectSoundCreate8() failed: %08x\n",rc);
- if (IsEqualGUID(iid, &IID_IMediaObject))
*out = iface;
- else if (IsEqualGUID(iid, &IID_IMediaObjectInPlace))
*out = &testdmo_inplace;
- else
return E_NOINTERFACE;
- if (rc!=DS_OK)
return;
- IUnknown_AddRef((IUnknown *)*out);
- return S_OK;
+}
- rc=IDirectSound8_SetCooperativeLevel(dso,get_hwnd(),DSSCL_PRIORITY);
- ok(rc==DS_OK,"IDirectSound8_SetCooperativeLevel() failed: %08x\n", rc);
- if (rc!=DS_OK) {
IDirectSound8_Release(dso);
return;
- }
+static ULONG WINAPI dmo_AddRef(IMediaObject *iface) +{
- return InterlockedIncrement(&testdmo_refcount);
+}
- primary=NULL;
- ZeroMemory(&bufdesc, sizeof(bufdesc));
- bufdesc.dwSize=sizeof(bufdesc);
- bufdesc.dwFlags=DSBCAPS_PRIMARYBUFFER;
- rc=IDirectSound8_CreateSoundBuffer(dso,&bufdesc,&primary,NULL);
- ok((rc==DS_OK && primary!=NULL),
"IDirectSound8_CreateSoundBuffer() failed to create a primary buffer: "
"%08x\n",rc);
- if (rc==DS_OK) {
init_format(&wfx,WAVE_FORMAT_PCM,11025,8,1);
ZeroMemory(&bufdesc, sizeof(bufdesc));
bufdesc.dwSize=sizeof(bufdesc);
bufdesc.dwFlags=0;
bufdesc.dwBufferBytes=align(wfx.nAvgBytesPerSec*BUFFER_LEN/1000,
wfx.nBlockAlign);
bufdesc.lpwfxFormat=&wfx;
+static ULONG WINAPI dmo_Release(IMediaObject *iface) +{
- return InterlockedDecrement(&testdmo_refcount);
+}
ZeroMemory(effects, sizeof(effects));
effects[0].dwSize=sizeof(effects[0]);
effects[0].guidDSFXClass=GUID_DSFX_STANDARD_ECHO;
effects[1].dwSize=sizeof(effects[1]);
effects[1].guidDSFXClass=GUID_NULL;
+static HRESULT WINAPI dmo_GetStreamCount(IMediaObject *iface, DWORD *input, DWORD *output) +{
- ok(0, "Unexpected call.\n");
- return E_NOTIMPL;
+}
secondary=NULL;
rc=IDirectSound8_CreateSoundBuffer(dso,&bufdesc,&secondary,NULL);
ok(rc==DS_OK && secondary!=NULL,
"IDirectSound8_CreateSoundBuffer() failed to create a secondary "
"buffer: %08x\n",rc);
+static HRESULT WINAPI dmo_GetInputStreamInfo(IMediaObject *iface, DWORD index, DWORD *flags) +{
- ok(0, "Unexpected call.\n");
- return E_NOTIMPL;
+}
/* Call SetFX on buffer without DSBCAPS_CTRLFX */
if (rc==DS_OK && secondary!=NULL) {
secondary8=NULL;
rc=IDirectSoundBuffer_QueryInterface(secondary,&IID_IDirectSoundBuffer8,(LPVOID*)&secondary8);
ok(rc==DS_OK,"IDirectSoundBuffer_QueryInterface(IID_IDirectSoundBuffer8) failed: %08x\n", rc);
+static HRESULT WINAPI dmo_GetOutputStreamInfo(IMediaObject *iface, DWORD index, DWORD *flags) +{
- ok(0, "Unexpected call.\n");
- return E_NOTIMPL;
+}
if (rc==DS_OK && secondary8) {
rc=IDirectSoundBuffer8_SetFX(secondary8,1,effects,resultcodes);
ok(rc==DSERR_CONTROLUNAVAIL,"IDirectSoundBuffer8_SetFX() "
"should have returned DSERR_CONTROLUNAVAIL, returned: %08x\n", rc);
+static HRESULT WINAPI dmo_GetInputType(IMediaObject *iface, DWORD index, DWORD type_index, DMO_MEDIA_TYPE *type) +{
- ok(0, "Unexpected call.\n");
- return E_NOTIMPL;
+}
IDirectSoundBuffer8_Release(secondary8);
}
IDirectSoundBuffer_Release(secondary);
}
+static HRESULT WINAPI dmo_GetOutputType(IMediaObject *iface, DWORD index, DWORD type_index, DMO_MEDIA_TYPE *type) +{
- ok(0, "Unexpected call.\n");
- return E_NOTIMPL;
+}
secondary=NULL;
bufdesc.dwFlags=DSBCAPS_CTRLFX;
rc=IDirectSound8_CreateSoundBuffer(dso,&bufdesc,&secondary,NULL);
ok(rc==DS_OK && secondary!=NULL,
"IDirectSound8_CreateSoundBuffer() failed to create a secondary "
"buffer: %08x\n",rc);
+static HRESULT WINAPI dmo_SetInputType(IMediaObject *iface, DWORD index, const DMO_MEDIA_TYPE *type, DWORD flags) +{
- const WAVEFORMATEX *wfx;
if (rc==DS_OK) {
secondary8=NULL;
rc=IDirectSoundBuffer_QueryInterface(secondary,&IID_IDirectSoundBuffer8,(LPVOID*)&secondary8);
ok(rc==DS_OK,"IDirectSoundBuffer_QueryInterface(IID_IDirectSoundBuffer8) failed: %08x\n", rc);
if (rc==DS_OK && secondary8) {
LPVOID ptr1,ptr2;
DWORD bytes1,bytes2;
IUnknown* obj = NULL;
HRESULT rc2;
/* Call SetFX with dwEffectsCount > 0 and pDSFXDesc == NULL */
rc=IDirectSoundBuffer8_SetFX(secondary8,1,NULL,NULL);
ok(rc==E_INVALIDARG||rc==DSERR_CONTROLUNAVAIL,"IDirectSoundBuffer8_SetFX() "
"should have returned E_INVALIDARG, returned: %08x\n", rc);
/* Call SetFX with dwEffectsCount == 0 and pDSFXDesc != NULL */
rc=IDirectSoundBuffer8_SetFX(secondary8,0,effects,NULL);
ok(rc==E_INVALIDARG||rc==DSERR_CONTROLUNAVAIL,"IDirectSoundBuffer8_SetFX() "
"should have returned E_INVALIDARG, returned: %08x\n", rc);
/* Call SetFX with dwEffectsCount == 0 and pdwResultCodes != NULL */
rc=IDirectSoundBuffer8_SetFX(secondary8,0,NULL,resultcodes);
ok(rc==E_INVALIDARG||rc==DSERR_CONTROLUNAVAIL,"IDirectSoundBuffer8_SetFX() "
"should have returned E_INVALIDARG, returned: %08x\n", rc);
rc=IDirectSoundBuffer8_Lock(secondary8,0,0,&ptr1,&bytes1,&ptr2,&bytes2,DSBLOCK_ENTIREBUFFER);
ok(rc==DS_OK,"IDirectSoundBuffer8_Lock() failed: %08x\n",rc);
if (rc==DS_OK) {
/* Call SetFX when buffer is locked */
rc=IDirectSoundBuffer8_SetFX(secondary8,1,effects,resultcodes);
ok(rc==DSERR_INVALIDCALL||rc==DSERR_CONTROLUNAVAIL,"IDirectSoundBuffer8_SetFX() "
"should have returned DSERR_INVALIDCALL, returned: %08x\n", rc);
rc=IDirectSoundBuffer8_Unlock(secondary8,ptr1,bytes1,ptr2,bytes2);
ok(rc==DS_OK,"IDirectSoundBuffer8_Unlock() failed: %08x\n",rc);
}
- if (winetest_debug > 1) trace("SetInputType()\n");
rc=IDirectSoundBuffer8_Play(secondary8,0,0,DSBPLAY_LOOPING);
ok(rc==DS_OK,"IDirectSoundBuffer8_Play() failed: %08x\n",rc);
- ok(!index, "Got unexpected index %u.\n", index);
- ok(!flags, "Got unexpected flags %#x.\n", flags);
if (rc==DS_OK) {
/* Call SetFX when buffer is playing */
rc=IDirectSoundBuffer8_SetFX(secondary8,1,effects,resultcodes);
ok(rc==DSERR_INVALIDCALL||rc==DSERR_CONTROLUNAVAIL,"IDirectSoundBuffer8_SetFX() "
"should have returned DSERR_INVALIDCALL, returned: %08x\n", rc);
- ok(IsEqualGUID(&type->majortype, &MEDIATYPE_Audio), "Got major type %s.\n", debugstr_guid(&type->majortype));
- todo_wine ok(IsEqualGUID(&type->subtype, &MEDIASUBTYPE_PCM), "Got subtype %s.\n", debugstr_guid(&type->subtype));
- ok(type->bFixedSizeSamples == TRUE, "Got fixed size %d.\n", type->bFixedSizeSamples);
- ok(!type->bTemporalCompression, "Got temporal compression %d.\n", type->bTemporalCompression);
- ok(IsEqualGUID(&type->formattype, &FORMAT_WaveFormatEx), "Got format type %s.\n", debugstr_guid(&type->formattype));
- ok(!type->pUnk, "Got pUnk %p.\n", type->pUnk);
- ok(type->cbFormat == sizeof(WAVEFORMATEX), "Got format size %u.\n", type->cbFormat);
rc=IDirectSoundBuffer8_Stop(secondary8);
ok(rc==DS_OK,"IDirectSoundBuffer8_Stop() failed: %08x\n",rc);
}
- wfx = (WAVEFORMATEX *)type->pbFormat;
- todo_wine ok(type->lSampleSize == wfx->nBlockAlign, "Got sample size %u.\n", type->lSampleSize);
/* Call SetFX with non-existent filter */
rc=IDirectSoundBuffer8_SetFX(secondary8,1,&effects[1],resultcodes);
ok(rc==REGDB_E_CLASSNOTREG||rc==DSERR_CONTROLUNAVAIL,"IDirectSoundBuffer8_SetFX(GUID_NULL) "
"should have returned REGDB_E_CLASSNOTREG, returned: %08x\n",rc);
if (rc!=DSERR_CONTROLUNAVAIL) {
ok(resultcodes[0]==DSFXR_UNKNOWN,"result code == %08x, expected DSFXR_UNKNOWN\n",resultcodes[0]);
}
- if (wfx->wBitsPerSample != 8)
return DMO_E_TYPE_NOT_ACCEPTED;
/* Call SetFX with standard echo */
rc2=IDirectSoundBuffer8_SetFX(secondary8,1,&effects[0],resultcodes);
ok(rc2==DS_OK||rc2==REGDB_E_CLASSNOTREG||rc2==DSERR_CONTROLUNAVAIL,
"IDirectSoundBuffer8_SetFX(GUID_DSFX_STANDARD_ECHO) failed: %08x\n",rc);
if (rc2!=DSERR_CONTROLUNAVAIL) {
ok(resultcodes[0]==DSFXR_UNKNOWN||resultcodes[0]==DSFXR_LOCHARDWARE||resultcodes[0]==DSFXR_LOCSOFTWARE,
"resultcode == %08x, expected DSFXR_UNKNOWN, DSFXR_LOCHARDWARE, or DSFXR_LOCSOFTWARE\n",resultcodes[0]);
}
- testdmo_input_type = *wfx;
- testdmo_input_type_set = TRUE;
- return S_OK;
+}
/* Call GetObjectInPath for out-of-bounds DMO */
rc=IDirectSoundBuffer8_GetObjectInPath(secondary8,&GUID_All_Objects,2,&IID_IMediaObject,(void**)&obj);
ok(rc==DSERR_OBJECTNOTFOUND||rc==DSERR_CONTROLUNAVAIL,"IDirectSoundBuffer8_GetObjectInPath() "
"should have returned DSERR_OBJECTNOTFOUND, returned: %08x\n",rc);
/* Call GetObjectInPath with NULL ppObject */
rc=IDirectSoundBuffer8_GetObjectInPath(secondary8,&GUID_All_Objects,0,&IID_IMediaObject,NULL);
ok(rc==E_INVALIDARG||rc==DSERR_CONTROLUNAVAIL,"IDirectSoundBuffer8_GetObjectInPath() "
"should have returned E_INVALIDARG, returned: %08x\n",rc);
/* Call GetObjectInPath for unsupported interface */
rc=IDirectSoundBuffer8_GetObjectInPath(secondary8,&GUID_All_Objects,0,&GUID_NULL,(void**)&obj);
ok(rc==E_NOINTERFACE||rc==DSERR_CONTROLUNAVAIL,"IDirectSoundBuffer8_GetObjectInPath() "
"should have returned E_NOINTERFACE, returned: %08x\n",rc);
/* Call GetObjectInPath for unloaded DMO */
rc=IDirectSoundBuffer8_GetObjectInPath(secondary8,&GUID_NULL,0,&IID_IMediaObject,(void**)&obj);
ok(rc==DSERR_OBJECTNOTFOUND||rc==DSERR_CONTROLUNAVAIL,"IDirectSoundBuffer8_GetObjectInPath() "
"should have returned DSERR_OBJECTNOTFOUND, returned: %08x\n",rc);
/* Call GetObjectInPath for first DMO */
obj=NULL;
rc=IDirectSoundBuffer8_GetObjectInPath(secondary8,&GUID_All_Objects,0,&IID_IMediaObject,(void**)&obj);
if (rc2==DS_OK) {
ok(rc==DS_OK||rc==DSERR_CONTROLUNAVAIL,"IDirectSoundBuffer8_GetObjectInPath() "
"should have returned DS_OK, returned: %08x\n",rc);
if (obj) IUnknown_Release(obj);
} else {
ok(rc==DSERR_OBJECTNOTFOUND||rc==DSERR_CONTROLUNAVAIL,"IDirectSoundBuffer8_GetObjectInPath() "
"should have returned DSERR_OBJECTNOTFOUND, returned: %08x\n",rc);
}
+static HRESULT WINAPI dmo_SetOutputType(IMediaObject *iface, DWORD index, const DMO_MEDIA_TYPE *type, DWORD flags) +{
- if (winetest_debug > 1) trace("SetOutputType()\n");
/* Call SetFX with one real filter and one fake one */
rc=IDirectSoundBuffer8_SetFX(secondary8,2,effects,resultcodes);
ok(rc==REGDB_E_CLASSNOTREG||rc==DSERR_CONTROLUNAVAIL,
"IDirectSoundBuffer8_SetFX(GUID_DSFX_STANDARD_ECHO, GUID_NULL) "
"should have returned REGDB_E_CLASSNOTREG, returned: %08x\n",rc);
if (rc!=DSERR_CONTROLUNAVAIL) {
ok(resultcodes[0]==DSFXR_PRESENT||resultcodes[0]==DSFXR_UNKNOWN,
"resultcodes[0] == %08x, expected DSFXR_PRESENT or DSFXR_UNKNOWN\n",resultcodes[0]);
ok(resultcodes[1]==DSFXR_UNKNOWN,
"resultcodes[1] == %08x, expected DSFXR_UNKNOWN\n",resultcodes[1]);
}
- ok(!index, "Got unexpected index %u.\n", index);
- ok(!flags, "Got unexpected flags %#x.\n", flags);
IDirectSoundBuffer8_Release(secondary8);
}
- ok(testdmo_input_type_set, "Expected the input type to be set.\n");
IDirectSoundBuffer_Release(secondary);
}
- ok(IsEqualGUID(&type->majortype, &MEDIATYPE_Audio), "Got major type %s.\n", debugstr_guid(&type->majortype));
- ok(IsEqualGUID(&type->subtype, &MEDIASUBTYPE_PCM), "Got subtype %s.\n", debugstr_guid(&type->subtype));
- ok(type->bFixedSizeSamples == TRUE, "Got fixed size %d.\n", type->bFixedSizeSamples);
- ok(!type->bTemporalCompression, "Got temporal compression %d.\n", type->bTemporalCompression);
- ok(type->lSampleSize == 1, "Got sample size %u.\n", type->lSampleSize);
- ok(IsEqualGUID(&type->formattype, &FORMAT_WaveFormatEx), "Got format type %s.\n", debugstr_guid(&type->formattype));
- ok(!type->pUnk, "Got pUnk %p.\n", type->pUnk);
- ok(type->cbFormat == sizeof(WAVEFORMATEX), "Got format size %u.\n", type->cbFormat);
IDirectSoundBuffer_Release(primary);
- ok(!memcmp(type->pbFormat, &testdmo_input_type, sizeof(WAVEFORMATEX)), "Format blocks didn't match.\n");
- testdmo_output_type_set = TRUE;
- return S_OK;
+}
+static HRESULT WINAPI dmo_GetInputCurrentType(IMediaObject *iface, DWORD index, DMO_MEDIA_TYPE *type) +{
- ok(0, "Unexpected call.\n");
- return E_NOTIMPL;
+}
+static HRESULT WINAPI dmo_GetOutputCurrentType(IMediaObject *iface, DWORD index, DMO_MEDIA_TYPE *type) +{
- ok(0, "Unexpected call.\n");
- return E_NOTIMPL;
+}
+static HRESULT WINAPI dmo_GetInputSizeInfo(IMediaObject *iface, DWORD index,
DWORD *size, DWORD *lookahead, DWORD *alignment)
+{
- ok(0, "Unexpected call.\n");
- return E_NOTIMPL;
+}
+static HRESULT WINAPI dmo_GetOutputSizeInfo(IMediaObject *iface, DWORD index, DWORD *size, DWORD *alignment) +{
- ok(0, "Unexpected call.\n");
- return E_NOTIMPL;
+}
+static HRESULT WINAPI dmo_GetInputMaxLatency(IMediaObject *iface, DWORD index, REFERENCE_TIME *latency) +{
- ok(0, "Unexpected call.\n");
- return E_NOTIMPL;
+}
+static HRESULT WINAPI dmo_SetInputMaxLatency(IMediaObject *iface, DWORD index, REFERENCE_TIME latency) +{
- ok(0, "Unexpected call.\n");
- return E_NOTIMPL;
+}
+static HRESULT WINAPI dmo_Flush(IMediaObject *iface) +{
- ok(0, "Unexpected call.\n");
- return E_NOTIMPL;
+}
+static HRESULT WINAPI dmo_Discontinuity(IMediaObject *iface, DWORD index) +{
- if (winetest_debug > 1) trace("Discontinuity()\n");
- ++got_Discontinuity;
- return S_OK;
+}
+static HRESULT WINAPI dmo_AllocateStreamingResources(IMediaObject *iface) +{
- ok(0, "Unexpected call.\n");
- return E_NOTIMPL;
+}
+static HRESULT WINAPI dmo_FreeStreamingResources(IMediaObject *iface) +{
- ok(0, "Unexpected call.\n");
- return E_NOTIMPL;
+}
+static HRESULT WINAPI dmo_GetInputStatus(IMediaObject *iface, DWORD index, DWORD *flags) +{
- ok(0, "Unexpected call.\n");
- return E_NOTIMPL;
+}
+static HRESULT WINAPI dmo_ProcessInput(IMediaObject *iface, DWORD index,
- IMediaBuffer *buffer, DWORD flags, REFERENCE_TIME timestamp, REFERENCE_TIME timelength)
+{
- ok(0, "Unexpected call.\n");
- return E_NOTIMPL;
+}
+static HRESULT WINAPI dmo_ProcessOutput(IMediaObject *iface, DWORD flags,
DWORD count, DMO_OUTPUT_DATA_BUFFER *buffers, DWORD *status)
+{
- ok(0, "Unexpected call.\n");
- return E_NOTIMPL;
+}
+static HRESULT WINAPI dmo_Lock(IMediaObject *iface, LONG lock) +{
- ok(0, "Unexpected call.\n");
- return E_NOTIMPL;
+}
+static const IMediaObjectVtbl dmo_vtbl = +{
- dmo_QueryInterface,
- dmo_AddRef,
- dmo_Release,
- dmo_GetStreamCount,
- dmo_GetInputStreamInfo,
- dmo_GetOutputStreamInfo,
- dmo_GetInputType,
- dmo_GetOutputType,
- dmo_SetInputType,
- dmo_SetOutputType,
- dmo_GetInputCurrentType,
- dmo_GetOutputCurrentType,
- dmo_GetInputSizeInfo,
- dmo_GetOutputSizeInfo,
- dmo_GetInputMaxLatency,
- dmo_SetInputMaxLatency,
- dmo_Flush,
- dmo_Discontinuity,
- dmo_AllocateStreamingResources,
- dmo_FreeStreamingResources,
- dmo_GetInputStatus,
- dmo_ProcessInput,
- dmo_ProcessOutput,
- dmo_Lock,
+};
+static HRESULT WINAPI dmo_inplace_QueryInterface(IMediaObjectInPlace *iface, REFIID iid, void **out) +{
- return IMediaObject_QueryInterface(&testdmo, iid, out);
+}
+static ULONG WINAPI dmo_inplace_AddRef(IMediaObjectInPlace *iface) +{
- return IMediaObject_AddRef(&testdmo);
+}
+static ULONG WINAPI dmo_inplace_Release(IMediaObjectInPlace *iface) +{
- return IMediaObject_Release(&testdmo);
+}
+static HRESULT WINAPI dmo_inplace_Process(IMediaObjectInPlace *iface, ULONG size,
BYTE *data, REFERENCE_TIME start, DWORD flags)
+{
- if (winetest_debug > 1) trace("Process(size %u)\n", size);
- ok(!start, "Got start time %s.\n", wine_dbgstr_longlong(start));
- ok(!flags, "Got flags %#x.\n", flags);
- SetEvent(got_Process);
- return S_FALSE;
+}
+static HRESULT WINAPI dmo_inplace_Clone(IMediaObjectInPlace *iface, IMediaObjectInPlace **ret_dmo) +{
- ok(0, "Unexpected call.\n");
- return E_NOTIMPL;
+}
+static HRESULT WINAPI dmo_inplace_GetLatency(IMediaObjectInPlace *iface, REFERENCE_TIME *latency) +{
- ok(0, "Unexpected call.\n");
- return E_NOTIMPL;
+}
+static const IMediaObjectInPlaceVtbl dmo_inplace_vtbl = +{
- dmo_inplace_QueryInterface,
- dmo_inplace_AddRef,
- dmo_inplace_Release,
- dmo_inplace_Process,
- dmo_inplace_Clone,
- dmo_inplace_GetLatency,
+};
+static IMediaObject testdmo = {&dmo_vtbl}; +static IMediaObjectInPlace testdmo_inplace = {&dmo_inplace_vtbl};
+static HRESULT WINAPI dmo_cf_QueryInterface(IClassFactory *iface, REFIID iid, void **out) +{
- if (IsEqualGUID(iid, &IID_IUnknown) || IsEqualGUID(iid, &IID_IClassFactory))
- {
*out = iface;
return S_OK;
- }
- return E_NOINTERFACE;
+}
+static ULONG WINAPI dmo_cf_AddRef(IClassFactory *iface) +{
- return 2;
+}
+static ULONG WINAPI dmo_cf_Release(IClassFactory *iface) +{
- return 1;
+}
+static HRESULT WINAPI dmo_cf_CreateInstance(IClassFactory *iface, IUnknown *outer, REFIID iid, void **out) +{
- ok(!outer, "Unexpected outer parameter.\n");
- ok(IsEqualGUID(iid, &IID_IMediaObject), "Got unexpected iid %s.\n", wine_dbgstr_guid(iid));
- *out = &testdmo;
- IMediaObject_AddRef(&testdmo);
- return S_OK;
+}
+static HRESULT WINAPI dmo_cf_LockServer(IClassFactory *iface, BOOL lock) +{
- ok(0, "Unexpected call.\n");
- return S_OK;
+}
+static const IClassFactoryVtbl dmo_cf_vtbl = +{
- dmo_cf_QueryInterface,
- dmo_cf_AddRef,
- dmo_cf_Release,
- dmo_cf_CreateInstance,
- dmo_cf_LockServer,
+};
+static IClassFactory testdmo_cf = {&dmo_cf_vtbl};
+static void test_effects(void) +{
- DSBUFFERDESC buffer_desc = {.dwSize = sizeof(buffer_desc)};
- IMediaObject *echo = NULL, *reverb = NULL;
- IDirectSoundBuffer8 *buffer8;
- DSEFFECTDESC effects[2] = {};
- IDirectSoundBuffer *buffer;
- IDirectSound8 *dsound;
- DWORD size1, size2;
- IMediaObject *dmo;
- void *ptr1, *ptr2;
- WAVEFORMATEX wfx;
- DWORD results[2];
- IUnknown *unk;
- HRESULT hr;
- ULONG ref;
- hr = DirectSoundCreate8(NULL, &dsound, NULL);
- ok(hr == DS_OK || hr == DSERR_NODRIVER, "Got hr %#x.\n", hr);
- if (FAILED(hr))
return;
- hr = IDirectSound8_SetCooperativeLevel(dsound, get_hwnd(), DSSCL_PRIORITY);
- ok(hr == DS_OK, "Got hr %#x.\n", hr);
- effects[0].dwSize = effects[1].dwSize = sizeof(effects[0]);
- effects[0].guidDSFXClass = GUID_DSFX_STANDARD_PARAMEQ;
- init_format(&wfx, WAVE_FORMAT_PCM, 11025, 8, 1);
- buffer_desc.dwBufferBytes = align(wfx.nAvgBytesPerSec * BUFFER_LEN / 1000, wfx.nBlockAlign);
- buffer_desc.lpwfxFormat = &wfx;
- hr = IDirectSound8_CreateSoundBuffer(dsound, &buffer_desc, &buffer, NULL);
- ok(hr == DS_OK, "Got hr %#x.\n", hr);
- hr = IDirectSoundBuffer_QueryInterface(buffer, &IID_IDirectSoundBuffer8, (void **)&buffer8);
- ok(hr == DS_OK, "Got hr %#x.\n", hr);
- hr = IDirectSoundBuffer8_SetFX(buffer8, 1, effects, results);
- ok(hr == DSERR_CONTROLUNAVAIL, "Got hr %#x.\n", hr);
- IDirectSoundBuffer8_Release(buffer8);
- IDirectSoundBuffer_Release(buffer);
- buffer_desc.dwFlags = DSBCAPS_CTRLFX;
- hr = IDirectSound8_CreateSoundBuffer(dsound, &buffer_desc, &buffer, NULL);
- ok(hr == DS_OK, "Got hr %#x.\n", hr);
- hr = IDirectSoundBuffer_QueryInterface(buffer, &IID_IDirectSoundBuffer8, (void **)&buffer8);
- ok(hr == DS_OK, "Got hr %#x.\n", hr);
- hr = IDirectSoundBuffer8_SetFX(buffer8, 1, NULL, NULL);
- ok(hr == DSERR_INVALIDPARAM, "Got hr %#x.\n", hr);
- hr = IDirectSoundBuffer8_SetFX(buffer8, 0, effects, NULL);
- ok(hr == DSERR_INVALIDPARAM, "Got hr %#x.\n", hr);
- hr = IDirectSoundBuffer8_SetFX(buffer8, 0, NULL, results);
- ok(hr == DSERR_INVALIDPARAM, "Got hr %#x.\n", hr);
- results[0] = 0xdeadbeef;
- hr = IDirectSoundBuffer8_SetFX(buffer8, 1, effects, results);
- todo_wine ok(hr == DS_OK, "Got hr %#x.\n", hr);
- todo_wine ok(results[0] == DSFXR_LOCSOFTWARE, "Got result %#x.\n", results[0]);
- hr = IDirectSoundBuffer8_Lock(buffer8, 0, 0, &ptr1, &size1, &ptr2, &size2, DSBLOCK_ENTIREBUFFER);
- ok(hr == DS_OK, "Got hr %#x.\n", hr);
- results[0] = 0xdeadbeef;
- hr = IDirectSoundBuffer8_SetFX(buffer8, 1, effects, results);
- ok(hr == DSERR_INVALIDCALL, "Got hr %#x.\n", hr);
- todo_wine ok(results[0] == 0xdeadbeef, "Got result %#x.\n", results[0]);
- hr = IDirectSoundBuffer8_Unlock(buffer8, ptr1, size1, ptr2, size2);
- ok(hr == DS_OK, "Got hr %#x.\n", hr);
- hr = IDirectSoundBuffer8_Play(buffer8, 0, 0, DSBPLAY_LOOPING);
- ok(hr == DS_OK, "Got hr %#x.\n", hr);
- results[0] = 0xdeadbeef;
- hr = IDirectSoundBuffer8_SetFX(buffer8, 1, effects, results);
- ok(hr == DSERR_INVALIDCALL, "Got hr %#x.\n", hr);
- todo_wine ok(results[0] == 0xdeadbeef, "Got result %#x.\n", results[0]);
- hr = IDirectSoundBuffer8_Stop(buffer8);
- ok(hr == DS_OK, "Got hr %#x.\n", hr);
- effects[0].guidDSFXClass = GUID_NULL;
- results[0] = 0xdeadbeef;
- hr = IDirectSoundBuffer8_SetFX(buffer8, 1, effects, results);
- ok(hr == REGDB_E_CLASSNOTREG, "Got hr %#x.\n", hr);
- ok(results[0] == DSFXR_UNKNOWN, "Got result %#x.\n", results[0]);
- effects[0].guidDSFXClass = GUID_DSFX_STANDARD_PARAMEQ;
- results[0] = 0xdeadbeef;
- hr = IDirectSoundBuffer8_SetFX(buffer8, 1, effects, results);
- todo_wine ok(hr == DS_OK, "Got hr %#x.\n", hr);
- todo_wine ok(results[0] == DSFXR_LOCSOFTWARE, "Got result %#x.\n", results[0]);
- hr = IDirectSoundBuffer8_GetObjectInPath(buffer8, &GUID_All_Objects, 0, &IID_IMediaObject, NULL);
- todo_wine ok(hr == DSERR_INVALIDPARAM, "Got hr %#x.\n", hr);
- dmo = (IMediaObject *)0xdeadbeef;
- hr = IDirectSoundBuffer8_GetObjectInPath(buffer8, &GUID_All_Objects, 0, &GUID_NULL, (void **)&dmo);
- todo_wine ok(hr == E_NOINTERFACE, "Got hr %#x.\n", hr);
- todo_wine ok(!dmo, "Got object %p.\n", dmo);
- dmo = (IMediaObject *)0xdeadbeef;
- hr = IDirectSoundBuffer8_GetObjectInPath(buffer8, &GUID_NULL, 0, &IID_IMediaObject, (void **)&dmo);
- todo_wine ok(hr == DSERR_OBJECTNOTFOUND, "Got hr %#x.\n", hr);
- ok(dmo == (IMediaObject *)0xdeadbeef, "Got object %p.\n", dmo);
- dmo = NULL;
- hr = IDirectSoundBuffer8_GetObjectInPath(buffer8, &GUID_All_Objects, 0, &IID_IMediaObject, (void **)&dmo);
- todo_wine ok(hr == DS_OK, "Got hr %#x.\n", hr);
- if (hr == DS_OK)
- {
ok(!!dmo, "Expected a non-NULL object.\n");
IMediaObject_Release(dmo);
- }
- dmo = NULL;
- hr = IDirectSoundBuffer8_GetObjectInPath(buffer8, &GUID_DSFX_STANDARD_PARAMEQ, 0, &IID_IMediaObject, (void **)&dmo);
- if (hr == DS_OK)
- {
ok(!!dmo, "Expected a non-NULL object.\n");
}IMediaObject_Release(dmo);
- while (IDirectSound8_Release(dso));
- dmo = (IMediaObject *)0xdeadbeef;
- hr = IDirectSoundBuffer8_GetObjectInPath(buffer8, &GUID_All_Objects, 1, &IID_IMediaObject, (void **)&dmo);
- todo_wine ok(hr == DSERR_OBJECTNOTFOUND, "Got hr %#x.\n", hr);
- ok(dmo == (IMediaObject *)0xdeadbeef, "Got object %p.\n", dmo);
- effects[0].guidDSFXClass = GUID_DSFX_STANDARD_PARAMEQ;
- effects[1].guidDSFXClass = GUID_NULL;
- results[0] = results[1] = 0xdeadbeef;
- hr = IDirectSoundBuffer8_SetFX(buffer8, 2, effects, results);
- ok(hr == REGDB_E_CLASSNOTREG, "Got hr %#x.\n", hr);
- todo_wine ok(results[0] == DSFXR_PRESENT, "Got result %#x.\n", results[0]);
- ok(results[1] == DSFXR_UNKNOWN, "Got result %#x.\n", results[1]);
- hr = IDirectSoundBuffer8_GetObjectInPath(buffer8, &GUID_All_Objects, 0, &IID_IMediaObject, (void **)&dmo);
- todo_wine ok(hr == DSERR_OBJECTNOTFOUND, "Got hr %#x.\n", hr);
- effects[0].guidDSFXClass = GUID_DSFX_STANDARD_PARAMEQ;
- effects[1].guidDSFXClass = GUID_DSFX_STANDARD_I3DL2REVERB;
- results[0] = results[1] = 0xdeadbeef;
- hr = IDirectSoundBuffer8_SetFX(buffer8, 2, effects, results);
- todo_wine ok(hr == DS_OK, "Got hr %#x.\n", hr);
- todo_wine ok(results[0] == DSFXR_LOCSOFTWARE, "Got result %#x.\n", results[0]);
- todo_wine ok(results[1] == DSFXR_LOCSOFTWARE, "Got result %#x.\n", results[1]);
- hr = IDirectSoundBuffer8_GetObjectInPath(buffer8, &GUID_DSFX_STANDARD_PARAMEQ, 0, &IID_IMediaObject, (void **)&dmo);
- todo_wine ok(hr == DS_OK, "Got hr %#x.\n", hr);
- if (hr == DS_OK)
echo = dmo;
- hr = IDirectSoundBuffer8_GetObjectInPath(buffer8,
&GUID_DSFX_STANDARD_I3DL2REVERB, 0, &IID_IMediaObject, (void **)&dmo);
- todo_wine ok(hr == DS_OK, "Got hr %#x.\n", hr);
- if (hr == DS_OK)
reverb = dmo;
- hr = IDirectSoundBuffer8_GetObjectInPath(buffer8, &GUID_All_Objects, 0, &IID_IMediaObject, (void **)&dmo);
- todo_wine ok(hr == DS_OK, "Got hr %#x.\n", hr);
- if (hr == DS_OK)
- {
ok(dmo == echo, "Expected %p, got %p.\n", echo, dmo);
IMediaObject_Release(dmo);
- }
- hr = IDirectSoundBuffer8_GetObjectInPath(buffer8, &GUID_All_Objects, 1, &IID_IMediaObject, (void **)&dmo);
- todo_wine ok(hr == DS_OK, "Got hr %#x.\n", hr);
- if (hr == DS_OK)
- {
ok(dmo == reverb, "Expected %p, got %p.\n", reverb, dmo);
IMediaObject_Release(dmo);
- }
- hr = IDirectSoundBuffer8_GetObjectInPath(buffer8,
&GUID_DSFX_STANDARD_I3DL2REVERB, 1, &IID_IMediaObject, (void **)&dmo);
- todo_wine ok(hr == DSERR_OBJECTNOTFOUND, "Got hr %#x.\n", hr);
- hr = IDirectSoundBuffer8_GetObjectInPath(buffer8, &GUID_All_Objects, 0, &IID_IDirectSoundFXParamEq, (void **)&unk);
- todo_wine ok(hr == DS_OK, "Got hr %#x.\n", hr);
- if (hr == DS_OK)
IUnknown_Release(unk);
- hr = IDirectSoundBuffer8_GetObjectInPath(buffer8, &GUID_All_Objects, 0,
&IID_IDirectSoundFXParamEq, (void **)&unk);
- todo_wine ok(hr == DS_OK, "Got hr %#x.\n", hr);
- if (hr == DS_OK)
IUnknown_Release(unk);
- hr = IDirectSoundBuffer8_GetObjectInPath(buffer8, &GUID_All_Objects, 0,
&IID_IDirectSoundFXI3DL2Reverb, (void **)&unk);
- todo_wine ok(hr == E_NOINTERFACE, "Got hr %#x.\n", hr);
- hr = IDirectSoundBuffer8_GetObjectInPath(buffer8, &GUID_All_Objects, 1,
&IID_IDirectSoundFXI3DL2Reverb, (void **)&unk);
- todo_wine ok(hr == DS_OK, "Got hr %#x.\n", hr);
- if (hr == DS_OK)
IUnknown_Release(unk);
- hr = IDirectSoundBuffer8_GetObjectInPath(buffer8,
&GUID_DSFX_STANDARD_I3DL2REVERB, 0, &IID_IDirectSoundFXI3DL2Reverb, (void **)&dmo);
- todo_wine ok(hr == DS_OK, "Got hr %#x.\n", hr);
- if (hr == DS_OK)
IUnknown_Release(unk);
I think this Release should be dmo, not unk.
I guess I rather meant to use "unk" in the call to GetObjectInPath(). Either way, thanks for the catch.
Also note the testbot failed on one of its Linux boxes, although it doesn't fail for me.
https://testbot.winehq.org/JobDetails.pl?Key=75900#k401
Possibly it's sometimes still running when the SetFX call is made, so we hit the "state != STATE_STOPPED" path.
Thanks, I didn't anticipate stops would be asynchronous. I've added use of IDirectSoundNotify to ensure synchronization.