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
28 #include "wine/debug.h"
30 WINE_DEFAULT_DEBUG_CHANNEL(dsdmo
);
34 IMediaObject IMediaObject_iface
;
35 IMediaObjectInPlace IMediaObjectInPlace_iface
;
36 IUnknown IUnknown_inner
;
43 const struct effect_ops
*ops
;
48 void *(*query_interface
)(struct effect
*effect
, REFIID iid
);
49 void (*destroy
)(struct effect
*effect
);
52 static struct effect
*impl_from_IUnknown(IUnknown
*iface
)
54 return CONTAINING_RECORD(iface
, struct effect
, IUnknown_inner
);
57 static HRESULT WINAPI
effect_inner_QueryInterface(IUnknown
*iface
, REFIID iid
, void **out
)
59 struct effect
*effect
= impl_from_IUnknown(iface
);
61 TRACE("effect %p, iid %s, out %p.\n", effect
, debugstr_guid(iid
), out
);
63 if (IsEqualGUID(iid
, &IID_IUnknown
))
65 else if (IsEqualGUID(iid
, &IID_IMediaObject
))
66 *out
= &effect
->IMediaObject_iface
;
67 else if (IsEqualGUID(iid
, &IID_IMediaObjectInPlace
))
68 *out
= &effect
->IMediaObjectInPlace_iface
;
69 else if (!(*out
= effect
->ops
->query_interface(effect
, iid
)))
71 WARN("%s not implemented; returning E_NOINTERFACE.\n", debugstr_guid(iid
));
75 IUnknown_AddRef((IUnknown
*)*out
);
79 static ULONG WINAPI
effect_inner_AddRef(IUnknown
*iface
)
81 struct effect
*effect
= impl_from_IUnknown(iface
);
82 ULONG refcount
= InterlockedIncrement(&effect
->refcount
);
84 TRACE("%p increasing refcount to %lu.\n", effect
, refcount
);
88 static ULONG WINAPI
effect_inner_Release(IUnknown
*iface
)
90 struct effect
*effect
= impl_from_IUnknown(iface
);
91 ULONG refcount
= InterlockedDecrement(&effect
->refcount
);
93 TRACE("%p decreasing refcount to %lu.\n", effect
, refcount
);
97 effect
->cs
.DebugInfo
->Spare
[0] = 0;
98 DeleteCriticalSection(&effect
->cs
);
99 effect
->ops
->destroy(effect
);
104 static const IUnknownVtbl effect_inner_vtbl
=
106 effect_inner_QueryInterface
,
108 effect_inner_Release
,
111 static struct effect
*impl_from_IMediaObject(IMediaObject
*iface
)
113 return CONTAINING_RECORD(iface
, struct effect
, IMediaObject_iface
);
116 static HRESULT WINAPI
effect_QueryInterface(IMediaObject
*iface
, REFIID iid
, void **out
)
118 struct effect
*effect
= impl_from_IMediaObject(iface
);
119 return IUnknown_QueryInterface(effect
->outer_unk
, iid
, out
);
122 static ULONG WINAPI
effect_AddRef(IMediaObject
*iface
)
124 struct effect
*effect
= impl_from_IMediaObject(iface
);
125 return IUnknown_AddRef(effect
->outer_unk
);
128 static ULONG WINAPI
effect_Release(IMediaObject
*iface
)
130 struct effect
*effect
= impl_from_IMediaObject(iface
);
131 return IUnknown_Release(effect
->outer_unk
);
134 static HRESULT WINAPI
effect_GetStreamCount(IMediaObject
*iface
, DWORD
*input
, DWORD
*output
)
136 FIXME("iface %p, input %p, output %p, stub!\n", iface
, input
, output
);
140 static HRESULT WINAPI
effect_GetInputStreamInfo(IMediaObject
*iface
, DWORD index
, DWORD
*flags
)
142 FIXME("iface %p, index %lu, flags %p, stub!\n", iface
, index
, flags
);
146 static HRESULT WINAPI
effect_GetOutputStreamInfo(IMediaObject
*iface
, DWORD index
, DWORD
*flags
)
148 FIXME("iface %p, index %lu, flags %p, stub!\n", iface
, index
, flags
);
152 static HRESULT WINAPI
effect_GetInputType(IMediaObject
*iface
, DWORD index
, DWORD type_index
, DMO_MEDIA_TYPE
*type
)
154 FIXME("iface %p, index %lu, type_index %lu, type %p, stub!\n", iface
, index
, type_index
, type
);
158 static HRESULT WINAPI
effect_GetOutputType(IMediaObject
*iface
, DWORD index
, DWORD type_index
, DMO_MEDIA_TYPE
*type
)
160 FIXME("iface %p, index %lu, type_index %lu, type %p, stub!\n", iface
, index
, type_index
, type
);
164 static HRESULT WINAPI
effect_SetInputType(IMediaObject
*iface
, DWORD index
, const DMO_MEDIA_TYPE
*type
, DWORD flags
)
166 struct effect
*effect
= impl_from_IMediaObject(iface
);
167 const WAVEFORMATEX
*format
;
169 TRACE("iface %p, index %lu, type %p, flags %#lx.\n", iface
, index
, type
, flags
);
171 if (flags
& DMO_SET_TYPEF_CLEAR
)
173 EnterCriticalSection(&effect
->cs
);
174 memset(&effect
->format
, 0, sizeof(effect
->format
));
175 LeaveCriticalSection(&effect
->cs
);
179 if (!IsEqualGUID(&type
->majortype
, &MEDIATYPE_Audio
))
180 return DMO_E_TYPE_NOT_ACCEPTED
;
182 if (!IsEqualGUID(&type
->subtype
, &MEDIASUBTYPE_PCM
)
183 && !IsEqualGUID(&type
->subtype
, &MEDIASUBTYPE_IEEE_FLOAT
))
184 return DMO_E_TYPE_NOT_ACCEPTED
;
186 if (!IsEqualGUID(&type
->formattype
, &FORMAT_WaveFormatEx
))
187 return DMO_E_TYPE_NOT_ACCEPTED
;
189 format
= (const WAVEFORMATEX
*)type
->pbFormat
;
190 if (format
->wFormatTag
== WAVE_FORMAT_PCM
)
192 if (format
->wBitsPerSample
!= 8 && format
->wBitsPerSample
!= 16)
194 WARN("Rejecting %u-bit integer PCM.\n", format
->wBitsPerSample
);
195 return DMO_E_TYPE_NOT_ACCEPTED
;
198 else if (format
->wFormatTag
== WAVE_FORMAT_IEEE_FLOAT
)
200 if (format
->wBitsPerSample
!= 32)
202 WARN("Rejecting %u-bit float PCM.\n", format
->wBitsPerSample
);
203 return DMO_E_TYPE_NOT_ACCEPTED
;
208 WARN("Rejecting tag %#x.\n", format
->wFormatTag
);
209 return DMO_E_TYPE_NOT_ACCEPTED
;
212 if (format
->nChannels
!= 1 && format
->nChannels
!= 2)
214 WARN("Rejecting %u channels.\n", format
->nChannels
);
215 return DMO_E_TYPE_NOT_ACCEPTED
;
218 EnterCriticalSection(&effect
->cs
);
219 effect
->format
= *format
;
220 LeaveCriticalSection(&effect
->cs
);
225 static HRESULT WINAPI
effect_SetOutputType(IMediaObject
*iface
, DWORD index
, const DMO_MEDIA_TYPE
*type
, DWORD flags
)
227 struct effect
*effect
= impl_from_IMediaObject(iface
);
230 TRACE("iface %p, index %lu, type %p, flags %#lx.\n", iface
, index
, type
, flags
);
232 if (flags
& DMO_SET_TYPEF_CLEAR
)
235 if (!IsEqualGUID(&type
->majortype
, &MEDIATYPE_Audio
))
236 return DMO_E_TYPE_NOT_ACCEPTED
;
238 if (!IsEqualGUID(&type
->subtype
, &MEDIASUBTYPE_PCM
)
239 && !IsEqualGUID(&type
->subtype
, &MEDIASUBTYPE_IEEE_FLOAT
))
240 return DMO_E_TYPE_NOT_ACCEPTED
;
242 if (!IsEqualGUID(&type
->formattype
, &FORMAT_WaveFormatEx
))
243 return DMO_E_TYPE_NOT_ACCEPTED
;
245 EnterCriticalSection(&effect
->cs
);
246 hr
= memcmp(type
->pbFormat
, &effect
->format
, sizeof(WAVEFORMATEX
)) ? DMO_E_TYPE_NOT_ACCEPTED
: S_OK
;
247 LeaveCriticalSection(&effect
->cs
);
252 static HRESULT WINAPI
effect_GetInputCurrentType(IMediaObject
*iface
, DWORD index
, DMO_MEDIA_TYPE
*type
)
254 FIXME("iface %p, index %lu, type %p, stub!\n", iface
, index
, type
);
258 static HRESULT WINAPI
effect_GetOutputCurrentType(IMediaObject
*iface
, DWORD index
, DMO_MEDIA_TYPE
*type
)
260 FIXME("iface %p, index %lu, type %p, stub!\n", iface
, index
, type
);
264 static HRESULT WINAPI
effect_GetInputSizeInfo(IMediaObject
*iface
, DWORD index
,
265 DWORD
*size
, DWORD
*lookahead
, DWORD
*alignment
)
267 FIXME("iface %p, index %lu, size %p, lookahead %p, alignment %p, stub!\n", iface
, index
, size
, lookahead
, alignment
);
271 static HRESULT WINAPI
effect_GetOutputSizeInfo(IMediaObject
*iface
, DWORD index
, DWORD
*size
, DWORD
*alignment
)
273 FIXME("iface %p, index %lu, size %p, alignment %p, stub!\n", iface
, index
, size
, alignment
);
277 static HRESULT WINAPI
effect_GetInputMaxLatency(IMediaObject
*iface
, DWORD index
, REFERENCE_TIME
*latency
)
279 FIXME("iface %p, index %lu, latency %p, stub!\n", iface
, index
, latency
);
283 static HRESULT WINAPI
effect_SetInputMaxLatency(IMediaObject
*iface
, DWORD index
, REFERENCE_TIME latency
)
285 FIXME("iface %p, index %lu, latency %s, stub!\n", iface
, index
, wine_dbgstr_longlong(latency
));
289 static HRESULT WINAPI
effect_Flush(IMediaObject
*iface
)
291 FIXME("iface %p, stub!\n", iface
);
295 static HRESULT WINAPI
effect_Discontinuity(IMediaObject
*iface
, DWORD index
)
297 FIXME("iface %p, index %lu, stub!\n", iface
, index
);
301 static HRESULT WINAPI
effect_AllocateStreamingResources(IMediaObject
*iface
)
303 FIXME("iface %p, stub!\n", iface
);
307 static HRESULT WINAPI
effect_FreeStreamingResources(IMediaObject
*iface
)
309 FIXME("iface %p, stub!\n", iface
);
313 static HRESULT WINAPI
effect_GetInputStatus(IMediaObject
*iface
, DWORD index
, DWORD
*flags
)
315 FIXME("iface %p, index %lu, flags %p, stub!\n", iface
, index
, flags
);
319 static HRESULT WINAPI
effect_ProcessInput(IMediaObject
*iface
, DWORD index
,
320 IMediaBuffer
*buffer
, DWORD flags
, REFERENCE_TIME timestamp
, REFERENCE_TIME timelength
)
322 FIXME("iface %p, index %lu, buffer %p, flags %#lx, timestamp %s, timelength %s, stub!\n",
323 iface
, index
, buffer
, flags
, wine_dbgstr_longlong(timestamp
), wine_dbgstr_longlong(timelength
));
327 static HRESULT WINAPI
effect_ProcessOutput(IMediaObject
*iface
, DWORD flags
,
328 DWORD count
, DMO_OUTPUT_DATA_BUFFER
*buffers
, DWORD
*status
)
330 FIXME("iface %p, flags %#lx, count %lu, buffers %p, status %p, stub!\n", iface
, flags
, count
, buffers
, status
);
334 static HRESULT WINAPI
effect_Lock(IMediaObject
*iface
, LONG lock
)
336 FIXME("iface %p, lock %ld, stub!\n", iface
, lock
);
340 static const IMediaObjectVtbl effect_vtbl
=
342 effect_QueryInterface
,
345 effect_GetStreamCount
,
346 effect_GetInputStreamInfo
,
347 effect_GetOutputStreamInfo
,
349 effect_GetOutputType
,
351 effect_SetOutputType
,
352 effect_GetInputCurrentType
,
353 effect_GetOutputCurrentType
,
354 effect_GetInputSizeInfo
,
355 effect_GetOutputSizeInfo
,
356 effect_GetInputMaxLatency
,
357 effect_SetInputMaxLatency
,
359 effect_Discontinuity
,
360 effect_AllocateStreamingResources
,
361 effect_FreeStreamingResources
,
362 effect_GetInputStatus
,
364 effect_ProcessOutput
,
368 static struct effect
*impl_from_IMediaObjectInPlace(IMediaObjectInPlace
*iface
)
370 return CONTAINING_RECORD(iface
, struct effect
, IMediaObjectInPlace_iface
);
373 static HRESULT WINAPI
effect_inplace_QueryInterface(IMediaObjectInPlace
*iface
, REFIID iid
, void **out
)
375 struct effect
*effect
= impl_from_IMediaObjectInPlace(iface
);
376 return IUnknown_QueryInterface(effect
->outer_unk
, iid
, out
);
379 static ULONG WINAPI
effect_inplace_AddRef(IMediaObjectInPlace
*iface
)
381 struct effect
*effect
= impl_from_IMediaObjectInPlace(iface
);
382 return IUnknown_AddRef(effect
->outer_unk
);
385 static ULONG WINAPI
effect_inplace_Release(IMediaObjectInPlace
*iface
)
387 struct effect
*effect
= impl_from_IMediaObjectInPlace(iface
);
388 return IUnknown_Release(effect
->outer_unk
);
391 static HRESULT WINAPI
effect_inplace_Process(IMediaObjectInPlace
*iface
, ULONG size
,
392 BYTE
*data
, REFERENCE_TIME start
, DWORD flags
)
394 FIXME("iface %p, size %lu, data %p, start %s, flags %#lx, stub!\n",
395 iface
, size
, data
, wine_dbgstr_longlong(start
), flags
);
399 static HRESULT WINAPI
effect_inplace_Clone(IMediaObjectInPlace
*iface
, IMediaObjectInPlace
**out
)
401 FIXME("iface %p, out %p, stub!\n", iface
, out
);
405 static HRESULT WINAPI
effect_inplace_GetLatency(IMediaObjectInPlace
*iface
, REFERENCE_TIME
*latency
)
407 FIXME("iface %p, latency %p, stub!\n", iface
, latency
);
411 static const IMediaObjectInPlaceVtbl effect_inplace_vtbl
=
413 effect_inplace_QueryInterface
,
414 effect_inplace_AddRef
,
415 effect_inplace_Release
,
416 effect_inplace_Process
,
417 effect_inplace_Clone
,
418 effect_inplace_GetLatency
,
421 static void effect_init(struct effect
*effect
, IUnknown
*outer
, const struct effect_ops
*ops
)
423 effect
->outer_unk
= outer
? outer
: &effect
->IUnknown_inner
;
424 effect
->refcount
= 1;
425 effect
->IUnknown_inner
.lpVtbl
= &effect_inner_vtbl
;
426 effect
->IMediaObject_iface
.lpVtbl
= &effect_vtbl
;
427 effect
->IMediaObjectInPlace_iface
.lpVtbl
= &effect_inplace_vtbl
;
429 InitializeCriticalSection(&effect
->cs
);
430 effect
->cs
.DebugInfo
->Spare
[0] = (DWORD_PTR
)(__FILE__
": effect.cs");
437 struct effect effect
;
438 IDirectSoundFXParamEq IDirectSoundFXParamEq_iface
;
442 static struct eq
*impl_from_IDirectSoundFXParamEq(IDirectSoundFXParamEq
*iface
)
444 return CONTAINING_RECORD(iface
, struct eq
, IDirectSoundFXParamEq_iface
);
447 static HRESULT WINAPI
eq_params_QueryInterface(IDirectSoundFXParamEq
*iface
, REFIID iid
, void **out
)
449 struct eq
*effect
= impl_from_IDirectSoundFXParamEq(iface
);
450 return IUnknown_QueryInterface(effect
->effect
.outer_unk
, iid
, out
);
453 static ULONG WINAPI
eq_params_AddRef(IDirectSoundFXParamEq
*iface
)
455 struct eq
*effect
= impl_from_IDirectSoundFXParamEq(iface
);
456 return IUnknown_AddRef(effect
->effect
.outer_unk
);
459 static ULONG WINAPI
eq_params_Release(IDirectSoundFXParamEq
*iface
)
461 struct eq
*effect
= impl_from_IDirectSoundFXParamEq(iface
);
462 return IUnknown_Release(effect
->effect
.outer_unk
);
465 static HRESULT WINAPI
eq_params_SetAllParameters(IDirectSoundFXParamEq
*iface
, const DSFXParamEq
*params
)
467 struct eq
*effect
= impl_from_IDirectSoundFXParamEq(iface
);
469 TRACE("effect %p, params %p.\n", effect
, params
);
471 EnterCriticalSection(&effect
->effect
.cs
);
472 effect
->params
= *params
;
473 LeaveCriticalSection(&effect
->effect
.cs
);
477 static HRESULT WINAPI
eq_params_GetAllParameters(IDirectSoundFXParamEq
*iface
, DSFXParamEq
*params
)
479 struct eq
*effect
= impl_from_IDirectSoundFXParamEq(iface
);
481 TRACE("effect %p, params %p.\n", effect
, params
);
483 EnterCriticalSection(&effect
->effect
.cs
);
484 *params
= effect
->params
;
485 LeaveCriticalSection(&effect
->effect
.cs
);
489 static const IDirectSoundFXParamEqVtbl eq_params_vtbl
=
491 eq_params_QueryInterface
,
494 eq_params_SetAllParameters
,
495 eq_params_GetAllParameters
,
498 static struct eq
*impl_eq_from_effect(struct effect
*iface
)
500 return CONTAINING_RECORD(iface
, struct eq
, effect
);
503 static void *eq_query_interface(struct effect
*iface
, REFIID iid
)
505 struct eq
*effect
= impl_eq_from_effect(iface
);
507 if (IsEqualGUID(iid
, &IID_IDirectSoundFXParamEq
))
508 return &effect
->IDirectSoundFXParamEq_iface
;
512 static void eq_destroy(struct effect
*iface
)
514 struct eq
*effect
= impl_eq_from_effect(iface
);
519 static const struct effect_ops eq_ops
=
521 .destroy
= eq_destroy
,
522 .query_interface
= eq_query_interface
,
525 static HRESULT
eq_create(IUnknown
*outer
, IUnknown
**out
)
529 if (!(object
= calloc(1, sizeof(*object
))))
530 return E_OUTOFMEMORY
;
532 effect_init(&object
->effect
, outer
, &eq_ops
);
533 object
->IDirectSoundFXParamEq_iface
.lpVtbl
= &eq_params_vtbl
;
535 object
->params
.fCenter
= 8000.0f
;
536 object
->params
.fBandwidth
= 12.0f
;
537 object
->params
.fGain
= 0.0f
;
539 TRACE("Created equalizer effect %p.\n", object
);
540 *out
= &object
->effect
.IUnknown_inner
;
546 struct effect effect
;
547 IDirectSoundFXI3DL2Reverb IDirectSoundFXI3DL2Reverb_iface
;
548 DSFXI3DL2Reverb params
;
551 static struct reverb
*impl_from_IDirectSoundFXI3DL2Reverb(IDirectSoundFXI3DL2Reverb
*iface
)
553 return CONTAINING_RECORD(iface
, struct reverb
, IDirectSoundFXI3DL2Reverb_iface
);
556 static HRESULT WINAPI
reverb_params_QueryInterface(IDirectSoundFXI3DL2Reverb
*iface
, REFIID iid
, void **out
)
558 struct reverb
*effect
= impl_from_IDirectSoundFXI3DL2Reverb(iface
);
559 return IUnknown_QueryInterface(effect
->effect
.outer_unk
, iid
, out
);
562 static ULONG WINAPI
reverb_params_AddRef(IDirectSoundFXI3DL2Reverb
*iface
)
564 struct reverb
*effect
= impl_from_IDirectSoundFXI3DL2Reverb(iface
);
565 return IUnknown_AddRef(effect
->effect
.outer_unk
);
568 static ULONG WINAPI
reverb_params_Release(IDirectSoundFXI3DL2Reverb
*iface
)
570 struct reverb
*effect
= impl_from_IDirectSoundFXI3DL2Reverb(iface
);
571 return IUnknown_Release(effect
->effect
.outer_unk
);
574 static HRESULT WINAPI
reverb_params_SetAllParameters(IDirectSoundFXI3DL2Reverb
*iface
, const DSFXI3DL2Reverb
*params
)
576 struct reverb
*effect
= impl_from_IDirectSoundFXI3DL2Reverb(iface
);
578 TRACE("effect %p, params %p.\n", effect
, params
);
580 EnterCriticalSection(&effect
->effect
.cs
);
581 effect
->params
= *params
;
582 LeaveCriticalSection(&effect
->effect
.cs
);
586 static HRESULT WINAPI
reverb_params_GetAllParameters(IDirectSoundFXI3DL2Reverb
*iface
, DSFXI3DL2Reverb
*params
)
588 struct reverb
*effect
= impl_from_IDirectSoundFXI3DL2Reverb(iface
);
590 TRACE("effect %p, params %p.\n", effect
, params
);
592 EnterCriticalSection(&effect
->effect
.cs
);
593 *params
= effect
->params
;
594 LeaveCriticalSection(&effect
->effect
.cs
);
598 static HRESULT WINAPI
reverb_params_SetPreset(IDirectSoundFXI3DL2Reverb
*iface
, DWORD preset
)
600 struct reverb
*effect
= impl_from_IDirectSoundFXI3DL2Reverb(iface
);
602 FIXME("effect %p, preset %lu, stub!\n", effect
, preset
);
607 static HRESULT WINAPI
reverb_params_GetPreset(IDirectSoundFXI3DL2Reverb
*iface
, DWORD
*preset
)
609 struct reverb
*effect
= impl_from_IDirectSoundFXI3DL2Reverb(iface
);
611 FIXME("effect %p, preset %p, stub!\n", effect
, preset
);
616 static HRESULT WINAPI
reverb_params_SetQuality(IDirectSoundFXI3DL2Reverb
*iface
, LONG quality
)
618 struct reverb
*effect
= impl_from_IDirectSoundFXI3DL2Reverb(iface
);
620 FIXME("effect %p, quality %lu, stub!\n", effect
, quality
);
625 static HRESULT WINAPI
reverb_params_GetQuality(IDirectSoundFXI3DL2Reverb
*iface
, LONG
*quality
)
627 struct reverb
*effect
= impl_from_IDirectSoundFXI3DL2Reverb(iface
);
629 FIXME("effect %p, quality %p, stub!\n", effect
, quality
);
634 static const IDirectSoundFXI3DL2ReverbVtbl reverb_params_vtbl
=
636 reverb_params_QueryInterface
,
637 reverb_params_AddRef
,
638 reverb_params_Release
,
639 reverb_params_SetAllParameters
,
640 reverb_params_GetAllParameters
,
641 reverb_params_SetPreset
,
642 reverb_params_GetPreset
,
643 reverb_params_SetQuality
,
644 reverb_params_GetQuality
,
647 static struct reverb
*impl_reverb_from_effect(struct effect
*iface
)
649 return CONTAINING_RECORD(iface
, struct reverb
, effect
);
652 static void *reverb_query_interface(struct effect
*iface
, REFIID iid
)
654 struct reverb
*effect
= impl_reverb_from_effect(iface
);
656 if (IsEqualGUID(iid
, &IID_IDirectSoundFXI3DL2Reverb
))
657 return &effect
->IDirectSoundFXI3DL2Reverb_iface
;
661 static void reverb_destroy(struct effect
*iface
)
663 struct reverb
*effect
= impl_reverb_from_effect(iface
);
668 static const struct effect_ops reverb_ops
=
670 .destroy
= reverb_destroy
,
671 .query_interface
= reverb_query_interface
,
674 static HRESULT
reverb_create(IUnknown
*outer
, IUnknown
**out
)
676 struct reverb
*object
;
678 if (!(object
= calloc(1, sizeof(*object
))))
679 return E_OUTOFMEMORY
;
681 effect_init(&object
->effect
, outer
, &reverb_ops
);
682 object
->IDirectSoundFXI3DL2Reverb_iface
.lpVtbl
= &reverb_params_vtbl
;
684 object
->params
.lRoom
= DSFX_I3DL2REVERB_ROOM_DEFAULT
;
685 object
->params
.lRoomHF
= DSFX_I3DL2REVERB_ROOMHF_DEFAULT
;
686 object
->params
.flRoomRolloffFactor
= DSFX_I3DL2REVERB_ROOMROLLOFFFACTOR_DEFAULT
;
687 object
->params
.flDecayTime
= DSFX_I3DL2REVERB_DECAYTIME_DEFAULT
;
688 object
->params
.flDecayHFRatio
= DSFX_I3DL2REVERB_DECAYHFRATIO_DEFAULT
;
689 object
->params
.lReflections
= DSFX_I3DL2REVERB_REFLECTIONS_DEFAULT
;
690 object
->params
.flReflectionsDelay
= DSFX_I3DL2REVERB_REFLECTIONSDELAY_DEFAULT
;
691 object
->params
.lReverb
= DSFX_I3DL2REVERB_REVERB_DEFAULT
;
692 object
->params
.flReverbDelay
= DSFX_I3DL2REVERB_REVERBDELAY_DEFAULT
;
693 object
->params
.flDiffusion
= DSFX_I3DL2REVERB_DIFFUSION_DEFAULT
;
694 object
->params
.flDensity
= DSFX_I3DL2REVERB_DENSITY_DEFAULT
;
695 object
->params
.flHFReference
= DSFX_I3DL2REVERB_HFREFERENCE_DEFAULT
;
697 TRACE("Created I3DL2 reverb effect %p.\n", object
);
698 *out
= &object
->effect
.IUnknown_inner
;
704 struct effect effect
;
705 IDirectSoundFXWavesReverb IDirectSoundFXWavesReverb_iface
;
708 static struct waves_reverb
*impl_from_IDirectSoundFXWavesReverb(IDirectSoundFXWavesReverb
*iface
)
710 return CONTAINING_RECORD(iface
, struct waves_reverb
, IDirectSoundFXWavesReverb_iface
);
713 static HRESULT WINAPI
waves_reverb_params_QueryInterface(IDirectSoundFXWavesReverb
*iface
, REFIID iid
, void **out
)
715 struct waves_reverb
*effect
= impl_from_IDirectSoundFXWavesReverb(iface
);
716 return IUnknown_QueryInterface(effect
->effect
.outer_unk
, iid
, out
);
719 static ULONG WINAPI
waves_reverb_params_AddRef(IDirectSoundFXWavesReverb
*iface
)
721 struct waves_reverb
*effect
= impl_from_IDirectSoundFXWavesReverb(iface
);
722 return IUnknown_AddRef(effect
->effect
.outer_unk
);
725 static ULONG WINAPI
waves_reverb_params_Release(IDirectSoundFXWavesReverb
*iface
)
727 struct waves_reverb
*effect
= impl_from_IDirectSoundFXWavesReverb(iface
);
728 return IUnknown_Release(effect
->effect
.outer_unk
);
731 static HRESULT WINAPI
waves_reverb_params_SetAllParameters(IDirectSoundFXWavesReverb
*iface
, const DSFXWavesReverb
*params
)
733 struct waves_reverb
*effect
= impl_from_IDirectSoundFXWavesReverb(iface
);
735 FIXME("effect %p, params %p, stub!\n", effect
, params
);
740 static HRESULT WINAPI
waves_reverb_params_GetAllParameters(IDirectSoundFXWavesReverb
*iface
, DSFXWavesReverb
*params
)
742 struct waves_reverb
*effect
= impl_from_IDirectSoundFXWavesReverb(iface
);
744 FIXME("effect %p, params %p, stub!\n", effect
, params
);
749 static const IDirectSoundFXWavesReverbVtbl waves_reverb_params_vtbl
=
751 waves_reverb_params_QueryInterface
,
752 waves_reverb_params_AddRef
,
753 waves_reverb_params_Release
,
754 waves_reverb_params_SetAllParameters
,
755 waves_reverb_params_GetAllParameters
,
758 static struct waves_reverb
*impl_waves_reverb_from_effect(struct effect
*iface
)
760 return CONTAINING_RECORD(iface
, struct waves_reverb
, effect
);
763 static void *waves_reverb_query_interface(struct effect
*iface
, REFIID iid
)
765 struct waves_reverb
*effect
= impl_waves_reverb_from_effect(iface
);
767 if (IsEqualGUID(iid
, &IID_IDirectSoundFXWavesReverb
))
768 return &effect
->IDirectSoundFXWavesReverb_iface
;
772 static void waves_reverb_destroy(struct effect
*iface
)
774 struct waves_reverb
*effect
= impl_waves_reverb_from_effect(iface
);
779 static const struct effect_ops waves_reverb_ops
=
781 .destroy
= waves_reverb_destroy
,
782 .query_interface
= waves_reverb_query_interface
,
785 static HRESULT
waves_reverb_create(IUnknown
*outer
, IUnknown
**out
)
787 struct waves_reverb
*object
;
789 if (!(object
= calloc(1, sizeof(*object
))))
790 return E_OUTOFMEMORY
;
792 effect_init(&object
->effect
, outer
, &waves_reverb_ops
);
793 object
->IDirectSoundFXWavesReverb_iface
.lpVtbl
= &waves_reverb_params_vtbl
;
795 TRACE("Created waves reverb effect %p.\n", object
);
796 *out
= &object
->effect
.IUnknown_inner
;
802 IClassFactory IClassFactory_iface
;
803 HRESULT (*create_instance
)(IUnknown
*outer
, IUnknown
**out
);
806 static struct class_factory
*impl_from_IClassFactory(IClassFactory
*iface
)
808 return CONTAINING_RECORD(iface
, struct class_factory
, IClassFactory_iface
);
811 static HRESULT WINAPI
class_factory_QueryInterface(IClassFactory
*iface
, REFIID iid
, void **out
)
813 TRACE("iface %p, iid %s, out %p.\n", iface
, debugstr_guid(iid
), out
);
815 if (IsEqualGUID(iid
, &IID_IUnknown
) || IsEqualGUID(iid
, &IID_IClassFactory
))
817 IClassFactory_AddRef(iface
);
823 WARN("%s not implemented, returning E_NOINTERFACE\n", debugstr_guid(iid
));
824 return E_NOINTERFACE
;
827 static ULONG WINAPI
class_factory_AddRef(IClassFactory
*iface
)
832 static ULONG WINAPI
class_factory_Release(IClassFactory
*iface
)
837 static HRESULT WINAPI
class_factory_CreateInstance(IClassFactory
*iface
,
838 IUnknown
*outer
, REFIID iid
, void **out
)
840 struct class_factory
*factory
= impl_from_IClassFactory(iface
);
844 TRACE("iface %p, outer %p, iid %s, out %p.\n", iface
, outer
, debugstr_guid(iid
), out
);
848 if (outer
&& !IsEqualGUID(iid
, &IID_IUnknown
))
849 return E_NOINTERFACE
;
851 if (SUCCEEDED(hr
= factory
->create_instance(outer
, &unk
)))
853 hr
= IUnknown_QueryInterface(unk
, iid
, out
);
854 IUnknown_Release(unk
);
859 static HRESULT WINAPI
class_factory_LockServer(IClassFactory
*iface
, BOOL lock
)
861 FIXME("lock %d, stub!\n", lock
);
865 static const IClassFactoryVtbl class_factory_vtbl
=
867 class_factory_QueryInterface
,
868 class_factory_AddRef
,
869 class_factory_Release
,
870 class_factory_CreateInstance
,
871 class_factory_LockServer
,
877 struct class_factory factory
;
881 {&GUID_DSFX_STANDARD_I3DL2REVERB
, {{&class_factory_vtbl
}, reverb_create
}},
882 {&GUID_DSFX_STANDARD_PARAMEQ
, {{&class_factory_vtbl
}, eq_create
}},
883 {&GUID_DSFX_WAVES_REVERB
, {{&class_factory_vtbl
}, waves_reverb_create
}},
886 HRESULT WINAPI
DllGetClassObject(REFCLSID clsid
, REFIID iid
, void **out
)
890 TRACE("clsid %s, iid %s, out %p.\n", debugstr_guid(clsid
), debugstr_guid(iid
), out
);
892 for (i
= 0; i
< ARRAY_SIZE(class_factories
); ++i
)
894 if (IsEqualGUID(clsid
, class_factories
[i
].clsid
))
895 return IClassFactory_QueryInterface(&class_factories
[i
].factory
.IClassFactory_iface
, iid
, out
);
898 FIXME("%s not available, returning CLASS_E_CLASSNOTAVAILABLE.\n", debugstr_guid(clsid
));
899 return CLASS_E_CLASSNOTAVAILABLE
;