winedbg: Don't dereference possibly NULL thread pointer.
[wine/zf.git] / dlls / dsdmo / main.c
blobc6fc30dc2c46000751669c12f47a23dbed4675a1
1 /*
2 * Copyright 2019 Alistair Leslie-Hughes
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19 #define COBJMACROS
20 #include "dmo.h"
21 #include "mmreg.h"
22 #include "mmsystem.h"
23 #include "uuids.h"
24 #include "initguid.h"
25 #include "dsound.h"
26 #include "rpcproxy.h"
28 #include "wine/debug.h"
30 WINE_DEFAULT_DEBUG_CHANNEL(dsdmo);
32 static HINSTANCE dsdmo_instance;
34 struct effect
36 IMediaObject IMediaObject_iface;
37 IMediaObjectInPlace IMediaObjectInPlace_iface;
38 IUnknown IUnknown_inner;
39 IUnknown *outer_unk;
40 LONG refcount;
42 CRITICAL_SECTION cs;
43 WAVEFORMATEX format;
45 const struct effect_ops *ops;
48 struct effect_ops
50 void *(*query_interface)(struct effect *effect, REFIID iid);
51 void (*destroy)(struct effect *effect);
54 static struct effect *impl_from_IUnknown(IUnknown *iface)
56 return CONTAINING_RECORD(iface, struct effect, IUnknown_inner);
59 static HRESULT WINAPI effect_inner_QueryInterface(IUnknown *iface, REFIID iid, void **out)
61 struct effect *effect = impl_from_IUnknown(iface);
63 TRACE("effect %p, iid %s, out %p.\n", effect, debugstr_guid(iid), out);
65 if (IsEqualGUID(iid, &IID_IUnknown))
66 *out = iface;
67 else if (IsEqualGUID(iid, &IID_IMediaObject))
68 *out = &effect->IMediaObject_iface;
69 else if (IsEqualGUID(iid, &IID_IMediaObjectInPlace))
70 *out = &effect->IMediaObjectInPlace_iface;
71 else if (!(*out = effect->ops->query_interface(effect, iid)))
73 WARN("%s not implemented; returning E_NOINTERFACE.\n", debugstr_guid(iid));
74 return E_NOINTERFACE;
77 IUnknown_AddRef((IUnknown *)*out);
78 return S_OK;
81 static ULONG WINAPI effect_inner_AddRef(IUnknown *iface)
83 struct effect *effect = impl_from_IUnknown(iface);
84 ULONG refcount = InterlockedIncrement(&effect->refcount);
86 TRACE("%p increasing refcount to %u.\n", effect, refcount);
87 return refcount;
90 static ULONG WINAPI effect_inner_Release(IUnknown *iface)
92 struct effect *effect = impl_from_IUnknown(iface);
93 ULONG refcount = InterlockedDecrement(&effect->refcount);
95 TRACE("%p decreasing refcount to %u.\n", effect, refcount);
97 if (!refcount)
99 effect->cs.DebugInfo->Spare[0] = 0;
100 DeleteCriticalSection(&effect->cs);
101 effect->ops->destroy(effect);
103 return refcount;
106 static const IUnknownVtbl effect_inner_vtbl =
108 effect_inner_QueryInterface,
109 effect_inner_AddRef,
110 effect_inner_Release,
113 static struct effect *impl_from_IMediaObject(IMediaObject *iface)
115 return CONTAINING_RECORD(iface, struct effect, IMediaObject_iface);
118 static HRESULT WINAPI effect_QueryInterface(IMediaObject *iface, REFIID iid, void **out)
120 struct effect *effect = impl_from_IMediaObject(iface);
121 return IUnknown_QueryInterface(effect->outer_unk, iid, out);
124 static ULONG WINAPI effect_AddRef(IMediaObject *iface)
126 struct effect *effect = impl_from_IMediaObject(iface);
127 return IUnknown_AddRef(effect->outer_unk);
130 static ULONG WINAPI effect_Release(IMediaObject *iface)
132 struct effect *effect = impl_from_IMediaObject(iface);
133 return IUnknown_Release(effect->outer_unk);
136 static HRESULT WINAPI effect_GetStreamCount(IMediaObject *iface, DWORD *input, DWORD *output)
138 FIXME("iface %p, input %p, output %p, stub!\n", iface, input, output);
139 return E_NOTIMPL;
142 static HRESULT WINAPI effect_GetInputStreamInfo(IMediaObject *iface, DWORD index, DWORD *flags)
144 FIXME("iface %p, index %u, flags %p, stub!\n", iface, index, flags);
145 return E_NOTIMPL;
148 static HRESULT WINAPI effect_GetOutputStreamInfo(IMediaObject *iface, DWORD index, DWORD *flags)
150 FIXME("iface %p, index %u, flags %p, stub!\n", iface, index, flags);
151 return E_NOTIMPL;
154 static HRESULT WINAPI effect_GetInputType(IMediaObject *iface, DWORD index, DWORD type_index, DMO_MEDIA_TYPE *type)
156 FIXME("iface %p, index %u, type_index %u, type %p, stub!\n", iface, index, type_index, type);
157 return E_NOTIMPL;
160 static HRESULT WINAPI effect_GetOutputType(IMediaObject *iface, DWORD index, DWORD type_index, DMO_MEDIA_TYPE *type)
162 FIXME("iface %p, index %u, type_index %u, type %p, stub!\n", iface, index, type_index, type);
163 return E_NOTIMPL;
166 static HRESULT WINAPI effect_SetInputType(IMediaObject *iface, DWORD index, const DMO_MEDIA_TYPE *type, DWORD flags)
168 struct effect *effect = impl_from_IMediaObject(iface);
169 const WAVEFORMATEX *format;
171 TRACE("iface %p, index %u, type %p, flags %#x.\n", iface, index, type, flags);
173 if (flags & DMO_SET_TYPEF_CLEAR)
175 EnterCriticalSection(&effect->cs);
176 memset(&effect->format, 0, sizeof(effect->format));
177 LeaveCriticalSection(&effect->cs);
178 return S_OK;
181 if (!IsEqualGUID(&type->majortype, &MEDIATYPE_Audio))
182 return DMO_E_TYPE_NOT_ACCEPTED;
184 if (!IsEqualGUID(&type->subtype, &MEDIASUBTYPE_PCM)
185 && !IsEqualGUID(&type->subtype, &MEDIASUBTYPE_IEEE_FLOAT))
186 return DMO_E_TYPE_NOT_ACCEPTED;
188 if (!IsEqualGUID(&type->formattype, &FORMAT_WaveFormatEx))
189 return DMO_E_TYPE_NOT_ACCEPTED;
191 format = (const WAVEFORMATEX *)type->pbFormat;
192 if (format->wFormatTag == WAVE_FORMAT_PCM)
194 if (format->wBitsPerSample != 8 && format->wBitsPerSample != 16)
196 WARN("Rejecting %u-bit integer PCM.\n", format->wBitsPerSample);
197 return DMO_E_TYPE_NOT_ACCEPTED;
200 else if (format->wFormatTag == WAVE_FORMAT_IEEE_FLOAT)
202 if (format->wBitsPerSample != 32)
204 WARN("Rejecting %u-bit float PCM.\n", format->wBitsPerSample);
205 return DMO_E_TYPE_NOT_ACCEPTED;
208 else
210 WARN("Rejecting tag %#x.\n", format->wFormatTag);
211 return DMO_E_TYPE_NOT_ACCEPTED;
214 if (format->nChannels != 1 && format->nChannels != 2)
216 WARN("Rejecting %u channels.\n", format->nChannels);
217 return DMO_E_TYPE_NOT_ACCEPTED;
220 EnterCriticalSection(&effect->cs);
221 effect->format = *format;
222 LeaveCriticalSection(&effect->cs);
224 return S_OK;
227 static HRESULT WINAPI effect_SetOutputType(IMediaObject *iface, DWORD index, const DMO_MEDIA_TYPE *type, DWORD flags)
229 struct effect *effect = impl_from_IMediaObject(iface);
230 HRESULT hr;
232 TRACE("iface %p, index %u, type %p, flags %#x.\n", iface, index, type, flags);
234 if (flags & DMO_SET_TYPEF_CLEAR)
235 return S_OK;
237 if (!IsEqualGUID(&type->majortype, &MEDIATYPE_Audio))
238 return DMO_E_TYPE_NOT_ACCEPTED;
240 if (!IsEqualGUID(&type->subtype, &MEDIASUBTYPE_PCM)
241 && !IsEqualGUID(&type->subtype, &MEDIASUBTYPE_IEEE_FLOAT))
242 return DMO_E_TYPE_NOT_ACCEPTED;
244 if (!IsEqualGUID(&type->formattype, &FORMAT_WaveFormatEx))
245 return DMO_E_TYPE_NOT_ACCEPTED;
247 EnterCriticalSection(&effect->cs);
248 hr = memcmp(type->pbFormat, &effect->format, sizeof(WAVEFORMATEX)) ? DMO_E_TYPE_NOT_ACCEPTED : S_OK;
249 LeaveCriticalSection(&effect->cs);
251 return hr;
254 static HRESULT WINAPI effect_GetInputCurrentType(IMediaObject *iface, DWORD index, DMO_MEDIA_TYPE *type)
256 FIXME("iface %p, index %u, type %p, stub!\n", iface, index, type);
257 return E_NOTIMPL;
260 static HRESULT WINAPI effect_GetOutputCurrentType(IMediaObject *iface, DWORD index, DMO_MEDIA_TYPE *type)
262 FIXME("iface %p, index %u, type %p, stub!\n", iface, index, type);
263 return E_NOTIMPL;
266 static HRESULT WINAPI effect_GetInputSizeInfo(IMediaObject *iface, DWORD index,
267 DWORD *size, DWORD *lookahead, DWORD *alignment)
269 FIXME("iface %p, index %u, size %p, lookahead %p, alignment %p, stub!\n", iface, index, size, lookahead, alignment);
270 return E_NOTIMPL;
273 static HRESULT WINAPI effect_GetOutputSizeInfo(IMediaObject *iface, DWORD index, DWORD *size, DWORD *alignment)
275 FIXME("iface %p, index %u, size %p, alignment %p, stub!\n", iface, index, size, alignment);
276 return E_NOTIMPL;
279 static HRESULT WINAPI effect_GetInputMaxLatency(IMediaObject *iface, DWORD index, REFERENCE_TIME *latency)
281 FIXME("iface %p, index %u, latency %p, stub!\n", iface, index, latency);
282 return E_NOTIMPL;
285 static HRESULT WINAPI effect_SetInputMaxLatency(IMediaObject *iface, DWORD index, REFERENCE_TIME latency)
287 FIXME("iface %p, index %u, latency %s, stub!\n", iface, index, wine_dbgstr_longlong(latency));
288 return E_NOTIMPL;
291 static HRESULT WINAPI effect_Flush(IMediaObject *iface)
293 FIXME("iface %p, stub!\n", iface);
294 return E_NOTIMPL;
297 static HRESULT WINAPI effect_Discontinuity(IMediaObject *iface, DWORD index)
299 FIXME("iface %p, index %u, stub!\n", iface, index);
300 return E_NOTIMPL;
303 static HRESULT WINAPI effect_AllocateStreamingResources(IMediaObject *iface)
305 FIXME("iface %p, stub!\n", iface);
306 return E_NOTIMPL;
309 static HRESULT WINAPI effect_FreeStreamingResources(IMediaObject *iface)
311 FIXME("iface %p, stub!\n", iface);
312 return E_NOTIMPL;
315 static HRESULT WINAPI effect_GetInputStatus(IMediaObject *iface, DWORD index, DWORD *flags)
317 FIXME("iface %p, index %u, flags %p, stub!\n", iface, index, flags);
318 return E_NOTIMPL;
321 static HRESULT WINAPI effect_ProcessInput(IMediaObject *iface, DWORD index,
322 IMediaBuffer *buffer, DWORD flags, REFERENCE_TIME timestamp, REFERENCE_TIME timelength)
324 FIXME("iface %p, index %u, buffer %p, flags %#x, timestamp %s, timelength %s, stub!\n",
325 iface, index, buffer, flags, wine_dbgstr_longlong(timestamp), wine_dbgstr_longlong(timelength));
326 return E_NOTIMPL;
329 static HRESULT WINAPI effect_ProcessOutput(IMediaObject *iface, DWORD flags,
330 DWORD count, DMO_OUTPUT_DATA_BUFFER *buffers, DWORD *status)
332 FIXME("iface %p, flags %#x, count %u, buffers %p, status %p, stub!\n", iface, flags, count, buffers, status);
333 return E_NOTIMPL;
336 static HRESULT WINAPI effect_Lock(IMediaObject *iface, LONG lock)
338 FIXME("iface %p, lock %d, stub!\n", iface, lock);
339 return E_NOTIMPL;
342 static const IMediaObjectVtbl effect_vtbl =
344 effect_QueryInterface,
345 effect_AddRef,
346 effect_Release,
347 effect_GetStreamCount,
348 effect_GetInputStreamInfo,
349 effect_GetOutputStreamInfo,
350 effect_GetInputType,
351 effect_GetOutputType,
352 effect_SetInputType,
353 effect_SetOutputType,
354 effect_GetInputCurrentType,
355 effect_GetOutputCurrentType,
356 effect_GetInputSizeInfo,
357 effect_GetOutputSizeInfo,
358 effect_GetInputMaxLatency,
359 effect_SetInputMaxLatency,
360 effect_Flush,
361 effect_Discontinuity,
362 effect_AllocateStreamingResources,
363 effect_FreeStreamingResources,
364 effect_GetInputStatus,
365 effect_ProcessInput,
366 effect_ProcessOutput,
367 effect_Lock,
370 static struct effect *impl_from_IMediaObjectInPlace(IMediaObjectInPlace *iface)
372 return CONTAINING_RECORD(iface, struct effect, IMediaObjectInPlace_iface);
375 static HRESULT WINAPI effect_inplace_QueryInterface(IMediaObjectInPlace *iface, REFIID iid, void **out)
377 struct effect *effect = impl_from_IMediaObjectInPlace(iface);
378 return IUnknown_QueryInterface(effect->outer_unk, iid, out);
381 static ULONG WINAPI effect_inplace_AddRef(IMediaObjectInPlace *iface)
383 struct effect *effect = impl_from_IMediaObjectInPlace(iface);
384 return IUnknown_AddRef(effect->outer_unk);
387 static ULONG WINAPI effect_inplace_Release(IMediaObjectInPlace *iface)
389 struct effect *effect = impl_from_IMediaObjectInPlace(iface);
390 return IUnknown_Release(effect->outer_unk);
393 static HRESULT WINAPI effect_inplace_Process(IMediaObjectInPlace *iface, ULONG size,
394 BYTE *data, REFERENCE_TIME start, DWORD flags)
396 FIXME("iface %p, size %u, data %p, start %s, flags %#x, stub!\n",
397 iface, size, data, wine_dbgstr_longlong(start), flags);
398 return E_NOTIMPL;
401 static HRESULT WINAPI effect_inplace_Clone(IMediaObjectInPlace *iface, IMediaObjectInPlace **out)
403 FIXME("iface %p, out %p, stub!\n", iface, out);
404 return E_NOTIMPL;
407 static HRESULT WINAPI effect_inplace_GetLatency(IMediaObjectInPlace *iface, REFERENCE_TIME *latency)
409 FIXME("iface %p, latency %p, stub!\n", iface, latency);
410 return E_NOTIMPL;
413 static const IMediaObjectInPlaceVtbl effect_inplace_vtbl =
415 effect_inplace_QueryInterface,
416 effect_inplace_AddRef,
417 effect_inplace_Release,
418 effect_inplace_Process,
419 effect_inplace_Clone,
420 effect_inplace_GetLatency,
423 static void effect_init(struct effect *effect, IUnknown *outer, const struct effect_ops *ops)
425 effect->outer_unk = outer ? outer : &effect->IUnknown_inner;
426 effect->refcount = 1;
427 effect->IUnknown_inner.lpVtbl = &effect_inner_vtbl;
428 effect->IMediaObject_iface.lpVtbl = &effect_vtbl;
429 effect->IMediaObjectInPlace_iface.lpVtbl = &effect_inplace_vtbl;
431 InitializeCriticalSection(&effect->cs);
432 effect->cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": effect.cs");
434 effect->ops = ops;
437 struct eq
439 struct effect effect;
440 IDirectSoundFXParamEq IDirectSoundFXParamEq_iface;
441 DSFXParamEq params;
444 static struct eq *impl_from_IDirectSoundFXParamEq(IDirectSoundFXParamEq *iface)
446 return CONTAINING_RECORD(iface, struct eq, IDirectSoundFXParamEq_iface);
449 static HRESULT WINAPI eq_params_QueryInterface(IDirectSoundFXParamEq *iface, REFIID iid, void **out)
451 struct eq *effect = impl_from_IDirectSoundFXParamEq(iface);
452 return IUnknown_QueryInterface(effect->effect.outer_unk, iid, out);
455 static ULONG WINAPI eq_params_AddRef(IDirectSoundFXParamEq *iface)
457 struct eq *effect = impl_from_IDirectSoundFXParamEq(iface);
458 return IUnknown_AddRef(effect->effect.outer_unk);
461 static ULONG WINAPI eq_params_Release(IDirectSoundFXParamEq *iface)
463 struct eq *effect = impl_from_IDirectSoundFXParamEq(iface);
464 return IUnknown_Release(effect->effect.outer_unk);
467 static HRESULT WINAPI eq_params_SetAllParameters(IDirectSoundFXParamEq *iface, const DSFXParamEq *params)
469 struct eq *effect = impl_from_IDirectSoundFXParamEq(iface);
471 TRACE("effect %p, params %p.\n", effect, params);
473 EnterCriticalSection(&effect->effect.cs);
474 effect->params = *params;
475 LeaveCriticalSection(&effect->effect.cs);
476 return S_OK;
479 static HRESULT WINAPI eq_params_GetAllParameters(IDirectSoundFXParamEq *iface, DSFXParamEq *params)
481 struct eq *effect = impl_from_IDirectSoundFXParamEq(iface);
483 TRACE("effect %p, params %p.\n", effect, params);
485 EnterCriticalSection(&effect->effect.cs);
486 *params = effect->params;
487 LeaveCriticalSection(&effect->effect.cs);
488 return S_OK;
491 static const IDirectSoundFXParamEqVtbl eq_params_vtbl =
493 eq_params_QueryInterface,
494 eq_params_AddRef,
495 eq_params_Release,
496 eq_params_SetAllParameters,
497 eq_params_GetAllParameters,
500 static struct eq *impl_eq_from_effect(struct effect *iface)
502 return CONTAINING_RECORD(iface, struct eq, effect);
505 static void *eq_query_interface(struct effect *iface, REFIID iid)
507 struct eq *effect = impl_eq_from_effect(iface);
509 if (IsEqualGUID(iid, &IID_IDirectSoundFXParamEq))
510 return &effect->IDirectSoundFXParamEq_iface;
511 return NULL;
514 static void eq_destroy(struct effect *iface)
516 struct eq *effect = impl_eq_from_effect(iface);
518 free(effect);
521 static const struct effect_ops eq_ops =
523 .destroy = eq_destroy,
524 .query_interface = eq_query_interface,
527 static HRESULT eq_create(IUnknown *outer, IUnknown **out)
529 struct eq *object;
531 if (!(object = calloc(1, sizeof(*object))))
532 return E_OUTOFMEMORY;
534 effect_init(&object->effect, outer, &eq_ops);
535 object->IDirectSoundFXParamEq_iface.lpVtbl = &eq_params_vtbl;
537 object->params.fCenter = 8000.0f;
538 object->params.fBandwidth = 12.0f;
539 object->params.fGain = 0.0f;
541 TRACE("Created equalizer effect %p.\n", object);
542 *out = &object->effect.IUnknown_inner;
543 return S_OK;
546 struct reverb
548 struct effect effect;
549 IDirectSoundFXI3DL2Reverb IDirectSoundFXI3DL2Reverb_iface;
550 DSFXI3DL2Reverb params;
553 static struct reverb *impl_from_IDirectSoundFXI3DL2Reverb(IDirectSoundFXI3DL2Reverb *iface)
555 return CONTAINING_RECORD(iface, struct reverb, IDirectSoundFXI3DL2Reverb_iface);
558 static HRESULT WINAPI reverb_params_QueryInterface(IDirectSoundFXI3DL2Reverb *iface, REFIID iid, void **out)
560 struct reverb *effect = impl_from_IDirectSoundFXI3DL2Reverb(iface);
561 return IUnknown_QueryInterface(effect->effect.outer_unk, iid, out);
564 static ULONG WINAPI reverb_params_AddRef(IDirectSoundFXI3DL2Reverb *iface)
566 struct reverb *effect = impl_from_IDirectSoundFXI3DL2Reverb(iface);
567 return IUnknown_AddRef(effect->effect.outer_unk);
570 static ULONG WINAPI reverb_params_Release(IDirectSoundFXI3DL2Reverb *iface)
572 struct reverb *effect = impl_from_IDirectSoundFXI3DL2Reverb(iface);
573 return IUnknown_Release(effect->effect.outer_unk);
576 static HRESULT WINAPI reverb_params_SetAllParameters(IDirectSoundFXI3DL2Reverb *iface, const DSFXI3DL2Reverb *params)
578 struct reverb *effect = impl_from_IDirectSoundFXI3DL2Reverb(iface);
580 TRACE("effect %p, params %p.\n", effect, params);
582 EnterCriticalSection(&effect->effect.cs);
583 effect->params = *params;
584 LeaveCriticalSection(&effect->effect.cs);
585 return S_OK;
588 static HRESULT WINAPI reverb_params_GetAllParameters(IDirectSoundFXI3DL2Reverb *iface, DSFXI3DL2Reverb *params)
590 struct reverb *effect = impl_from_IDirectSoundFXI3DL2Reverb(iface);
592 TRACE("effect %p, params %p.\n", effect, params);
594 EnterCriticalSection(&effect->effect.cs);
595 *params = effect->params;
596 LeaveCriticalSection(&effect->effect.cs);
597 return S_OK;
600 static HRESULT WINAPI reverb_params_SetPreset(IDirectSoundFXI3DL2Reverb *iface, DWORD preset)
602 struct reverb *effect = impl_from_IDirectSoundFXI3DL2Reverb(iface);
604 FIXME("effect %p, preset %u, stub!\n", effect, preset);
606 return E_NOTIMPL;
609 static HRESULT WINAPI reverb_params_GetPreset(IDirectSoundFXI3DL2Reverb *iface, DWORD *preset)
611 struct reverb *effect = impl_from_IDirectSoundFXI3DL2Reverb(iface);
613 FIXME("effect %p, preset %p, stub!\n", effect, preset);
615 return E_NOTIMPL;
618 static HRESULT WINAPI reverb_params_SetQuality(IDirectSoundFXI3DL2Reverb *iface, LONG quality)
620 struct reverb *effect = impl_from_IDirectSoundFXI3DL2Reverb(iface);
622 FIXME("effect %p, quality %u, stub!\n", effect, quality);
624 return E_NOTIMPL;
627 static HRESULT WINAPI reverb_params_GetQuality(IDirectSoundFXI3DL2Reverb *iface, LONG *quality)
629 struct reverb *effect = impl_from_IDirectSoundFXI3DL2Reverb(iface);
631 FIXME("effect %p, quality %p, stub!\n", effect, quality);
633 return E_NOTIMPL;
636 static const IDirectSoundFXI3DL2ReverbVtbl reverb_params_vtbl =
638 reverb_params_QueryInterface,
639 reverb_params_AddRef,
640 reverb_params_Release,
641 reverb_params_SetAllParameters,
642 reverb_params_GetAllParameters,
643 reverb_params_SetPreset,
644 reverb_params_GetPreset,
645 reverb_params_SetQuality,
646 reverb_params_GetQuality,
649 static struct reverb *impl_reverb_from_effect(struct effect *iface)
651 return CONTAINING_RECORD(iface, struct reverb, effect);
654 static void *reverb_query_interface(struct effect *iface, REFIID iid)
656 struct reverb *effect = impl_reverb_from_effect(iface);
658 if (IsEqualGUID(iid, &IID_IDirectSoundFXI3DL2Reverb))
659 return &effect->IDirectSoundFXI3DL2Reverb_iface;
660 return NULL;
663 static void reverb_destroy(struct effect *iface)
665 struct reverb *effect = impl_reverb_from_effect(iface);
667 free(effect);
670 static const struct effect_ops reverb_ops =
672 .destroy = reverb_destroy,
673 .query_interface = reverb_query_interface,
676 static HRESULT reverb_create(IUnknown *outer, IUnknown **out)
678 struct reverb *object;
680 if (!(object = calloc(1, sizeof(*object))))
681 return E_OUTOFMEMORY;
683 effect_init(&object->effect, outer, &reverb_ops);
684 object->IDirectSoundFXI3DL2Reverb_iface.lpVtbl = &reverb_params_vtbl;
686 object->params.lRoom = DSFX_I3DL2REVERB_ROOM_DEFAULT;
687 object->params.lRoomHF = DSFX_I3DL2REVERB_ROOMHF_DEFAULT;
688 object->params.flRoomRolloffFactor = DSFX_I3DL2REVERB_ROOMROLLOFFFACTOR_DEFAULT;
689 object->params.flDecayTime = DSFX_I3DL2REVERB_DECAYTIME_DEFAULT;
690 object->params.flDecayHFRatio = DSFX_I3DL2REVERB_DECAYHFRATIO_DEFAULT;
691 object->params.lReflections = DSFX_I3DL2REVERB_REFLECTIONS_DEFAULT;
692 object->params.flReflectionsDelay = DSFX_I3DL2REVERB_REFLECTIONSDELAY_DEFAULT;
693 object->params.lReverb = DSFX_I3DL2REVERB_REVERB_DEFAULT;
694 object->params.flReverbDelay = DSFX_I3DL2REVERB_REVERBDELAY_DEFAULT;
695 object->params.flDiffusion = DSFX_I3DL2REVERB_DIFFUSION_DEFAULT;
696 object->params.flDensity = DSFX_I3DL2REVERB_DENSITY_DEFAULT;
697 object->params.flHFReference = DSFX_I3DL2REVERB_HFREFERENCE_DEFAULT;
699 TRACE("Created I3DL2 reverb effect %p.\n", object);
700 *out = &object->effect.IUnknown_inner;
701 return S_OK;
704 struct waves_reverb
706 struct effect effect;
707 IDirectSoundFXWavesReverb IDirectSoundFXWavesReverb_iface;
710 static struct waves_reverb *impl_from_IDirectSoundFXWavesReverb(IDirectSoundFXWavesReverb *iface)
712 return CONTAINING_RECORD(iface, struct waves_reverb, IDirectSoundFXWavesReverb_iface);
715 static HRESULT WINAPI waves_reverb_params_QueryInterface(IDirectSoundFXWavesReverb *iface, REFIID iid, void **out)
717 struct waves_reverb *effect = impl_from_IDirectSoundFXWavesReverb(iface);
718 return IUnknown_QueryInterface(effect->effect.outer_unk, iid, out);
721 static ULONG WINAPI waves_reverb_params_AddRef(IDirectSoundFXWavesReverb *iface)
723 struct waves_reverb *effect = impl_from_IDirectSoundFXWavesReverb(iface);
724 return IUnknown_AddRef(effect->effect.outer_unk);
727 static ULONG WINAPI waves_reverb_params_Release(IDirectSoundFXWavesReverb *iface)
729 struct waves_reverb *effect = impl_from_IDirectSoundFXWavesReverb(iface);
730 return IUnknown_Release(effect->effect.outer_unk);
733 static HRESULT WINAPI waves_reverb_params_SetAllParameters(IDirectSoundFXWavesReverb *iface, const DSFXWavesReverb *params)
735 struct waves_reverb *effect = impl_from_IDirectSoundFXWavesReverb(iface);
737 FIXME("effect %p, params %p, stub!\n", effect, params);
739 return E_NOTIMPL;
742 static HRESULT WINAPI waves_reverb_params_GetAllParameters(IDirectSoundFXWavesReverb *iface, DSFXWavesReverb *params)
744 struct waves_reverb *effect = impl_from_IDirectSoundFXWavesReverb(iface);
746 FIXME("effect %p, params %p, stub!\n", effect, params);
748 return E_NOTIMPL;
751 static const IDirectSoundFXWavesReverbVtbl waves_reverb_params_vtbl =
753 waves_reverb_params_QueryInterface,
754 waves_reverb_params_AddRef,
755 waves_reverb_params_Release,
756 waves_reverb_params_SetAllParameters,
757 waves_reverb_params_GetAllParameters,
760 static struct waves_reverb *impl_waves_reverb_from_effect(struct effect *iface)
762 return CONTAINING_RECORD(iface, struct waves_reverb, effect);
765 static void *waves_reverb_query_interface(struct effect *iface, REFIID iid)
767 struct waves_reverb *effect = impl_waves_reverb_from_effect(iface);
769 if (IsEqualGUID(iid, &IID_IDirectSoundFXWavesReverb))
770 return &effect->IDirectSoundFXWavesReverb_iface;
771 return NULL;
774 static void waves_reverb_destroy(struct effect *iface)
776 struct waves_reverb *effect = impl_waves_reverb_from_effect(iface);
778 free(effect);
781 static const struct effect_ops waves_reverb_ops =
783 .destroy = waves_reverb_destroy,
784 .query_interface = waves_reverb_query_interface,
787 static HRESULT waves_reverb_create(IUnknown *outer, IUnknown **out)
789 struct waves_reverb *object;
791 if (!(object = calloc(1, sizeof(*object))))
792 return E_OUTOFMEMORY;
794 effect_init(&object->effect, outer, &waves_reverb_ops);
795 object->IDirectSoundFXWavesReverb_iface.lpVtbl = &waves_reverb_params_vtbl;
797 TRACE("Created waves reverb effect %p.\n", object);
798 *out = &object->effect.IUnknown_inner;
799 return S_OK;
802 BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, void *reserved)
804 switch(reason)
806 case DLL_PROCESS_ATTACH:
807 dsdmo_instance = instance;
808 DisableThreadLibraryCalls(dsdmo_instance);
809 break;
812 return TRUE;
815 struct class_factory
817 IClassFactory IClassFactory_iface;
818 HRESULT (*create_instance)(IUnknown *outer, IUnknown **out);
821 static struct class_factory *impl_from_IClassFactory(IClassFactory *iface)
823 return CONTAINING_RECORD(iface, struct class_factory, IClassFactory_iface);
826 static HRESULT WINAPI class_factory_QueryInterface(IClassFactory *iface, REFIID iid, void **out)
828 TRACE("iface %p, iid %s, out %p.\n", iface, debugstr_guid(iid), out);
830 if (IsEqualGUID(iid, &IID_IUnknown) || IsEqualGUID(iid, &IID_IClassFactory))
832 IClassFactory_AddRef(iface);
833 *out = iface;
834 return S_OK;
837 *out = NULL;
838 WARN("%s not implemented, returning E_NOINTERFACE\n", debugstr_guid(iid));
839 return E_NOINTERFACE;
842 static ULONG WINAPI class_factory_AddRef(IClassFactory *iface)
844 return 2;
847 static ULONG WINAPI class_factory_Release(IClassFactory *iface)
849 return 1;
852 static HRESULT WINAPI class_factory_CreateInstance(IClassFactory *iface,
853 IUnknown *outer, REFIID iid, void **out)
855 struct class_factory *factory = impl_from_IClassFactory(iface);
856 IUnknown *unk;
857 HRESULT hr;
859 TRACE("iface %p, outer %p, iid %s, out %p.\n", iface, outer, debugstr_guid(iid), out);
861 *out = NULL;
863 if (outer && !IsEqualGUID(iid, &IID_IUnknown))
864 return E_NOINTERFACE;
866 if (SUCCEEDED(hr = factory->create_instance(outer, &unk)))
868 hr = IUnknown_QueryInterface(unk, iid, out);
869 IUnknown_Release(unk);
871 return hr;
874 static HRESULT WINAPI class_factory_LockServer(IClassFactory *iface, BOOL lock)
876 FIXME("lock %d, stub!\n", lock);
877 return S_OK;
880 static const IClassFactoryVtbl class_factory_vtbl =
882 class_factory_QueryInterface,
883 class_factory_AddRef,
884 class_factory_Release,
885 class_factory_CreateInstance,
886 class_factory_LockServer,
889 static struct
891 const GUID *clsid;
892 struct class_factory factory;
894 class_factories[] =
896 {&GUID_DSFX_STANDARD_I3DL2REVERB, {{&class_factory_vtbl}, reverb_create}},
897 {&GUID_DSFX_STANDARD_PARAMEQ, {{&class_factory_vtbl}, eq_create}},
898 {&GUID_DSFX_WAVES_REVERB, {{&class_factory_vtbl}, waves_reverb_create}},
901 HRESULT WINAPI DllGetClassObject(REFCLSID clsid, REFIID iid, void **out)
903 unsigned int i;
905 TRACE("clsid %s, iid %s, out %p.\n", debugstr_guid(clsid), debugstr_guid(iid), out);
907 for (i = 0; i < ARRAY_SIZE(class_factories); ++i)
909 if (IsEqualGUID(clsid, class_factories[i].clsid))
910 return IClassFactory_QueryInterface(&class_factories[i].factory.IClassFactory_iface, iid, out);
913 FIXME("%s not available, returning CLASS_E_CLASSNOTAVAILABLE.\n", debugstr_guid(clsid));
914 return CLASS_E_CLASSNOTAVAILABLE;
917 HRESULT WINAPI DllCanUnloadNow(void)
919 return S_FALSE;
922 HRESULT WINAPI DllRegisterServer(void)
924 TRACE("()\n");
925 return __wine_register_resources(dsdmo_instance);
928 HRESULT WINAPI DllUnregisterServer(void)
930 TRACE("()\n");
931 return __wine_unregister_resources(dsdmo_instance);