wineps: Handle EMR_INVERTRGN record in spool files.
[wine.git] / dlls / dsdmo / main.c
blobbb19b7b7e2ea418eeb4bb6f9755905d8f457a360
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 "medparam.h"
26 #include "dsound.h"
27 #include "rpcproxy.h"
29 #include "wine/debug.h"
31 WINE_DEFAULT_DEBUG_CHANNEL(dsdmo);
33 struct effect
35 IMediaObject IMediaObject_iface;
36 IMediaObjectInPlace IMediaObjectInPlace_iface;
37 IMediaParams IMediaParams_iface;
38 IMediaParamInfo IMediaParamInfo_iface;
39 IUnknown IUnknown_inner;
40 IUnknown *outer_unk;
41 LONG refcount;
43 CRITICAL_SECTION cs;
44 WAVEFORMATEX format;
46 const struct effect_ops *ops;
49 struct effect_ops
51 void *(*query_interface)(struct effect *effect, REFIID iid);
52 void (*destroy)(struct effect *effect);
55 static struct effect *impl_from_IUnknown(IUnknown *iface)
57 return CONTAINING_RECORD(iface, struct effect, IUnknown_inner);
60 static HRESULT WINAPI effect_inner_QueryInterface(IUnknown *iface, REFIID iid, void **out)
62 struct effect *effect = impl_from_IUnknown(iface);
64 TRACE("effect %p, iid %s, out %p.\n", effect, debugstr_guid(iid), out);
66 if (IsEqualGUID(iid, &IID_IUnknown))
67 *out = iface;
68 else if (IsEqualGUID(iid, &IID_IMediaObject))
69 *out = &effect->IMediaObject_iface;
70 else if (IsEqualGUID(iid, &IID_IMediaObjectInPlace))
71 *out = &effect->IMediaObjectInPlace_iface;
72 else if (IsEqualGUID(iid, &IID_IMediaParams))
73 *out = &effect->IMediaParams_iface;
74 else if (IsEqualGUID(iid, &IID_IMediaParamInfo))
75 *out = &effect->IMediaParamInfo_iface;
76 else if (!(*out = effect->ops->query_interface(effect, iid)))
78 WARN("%s not implemented; returning E_NOINTERFACE.\n", debugstr_guid(iid));
79 return E_NOINTERFACE;
82 IUnknown_AddRef((IUnknown *)*out);
83 return S_OK;
86 static ULONG WINAPI effect_inner_AddRef(IUnknown *iface)
88 struct effect *effect = impl_from_IUnknown(iface);
89 ULONG refcount = InterlockedIncrement(&effect->refcount);
91 TRACE("%p increasing refcount to %lu.\n", effect, refcount);
92 return refcount;
95 static ULONG WINAPI effect_inner_Release(IUnknown *iface)
97 struct effect *effect = impl_from_IUnknown(iface);
98 ULONG refcount = InterlockedDecrement(&effect->refcount);
100 TRACE("%p decreasing refcount to %lu.\n", effect, refcount);
102 if (!refcount)
104 effect->cs.DebugInfo->Spare[0] = 0;
105 DeleteCriticalSection(&effect->cs);
106 effect->ops->destroy(effect);
108 return refcount;
111 static const IUnknownVtbl effect_inner_vtbl =
113 effect_inner_QueryInterface,
114 effect_inner_AddRef,
115 effect_inner_Release,
118 static struct effect *impl_from_IMediaObject(IMediaObject *iface)
120 return CONTAINING_RECORD(iface, struct effect, IMediaObject_iface);
123 static HRESULT WINAPI effect_QueryInterface(IMediaObject *iface, REFIID iid, void **out)
125 struct effect *effect = impl_from_IMediaObject(iface);
126 return IUnknown_QueryInterface(effect->outer_unk, iid, out);
129 static ULONG WINAPI effect_AddRef(IMediaObject *iface)
131 struct effect *effect = impl_from_IMediaObject(iface);
132 return IUnknown_AddRef(effect->outer_unk);
135 static ULONG WINAPI effect_Release(IMediaObject *iface)
137 struct effect *effect = impl_from_IMediaObject(iface);
138 return IUnknown_Release(effect->outer_unk);
141 static HRESULT WINAPI effect_GetStreamCount(IMediaObject *iface, DWORD *input, DWORD *output)
143 FIXME("iface %p, input %p, output %p, stub!\n", iface, input, output);
144 return E_NOTIMPL;
147 static HRESULT WINAPI effect_GetInputStreamInfo(IMediaObject *iface, DWORD index, DWORD *flags)
149 FIXME("iface %p, index %lu, flags %p, stub!\n", iface, index, flags);
150 return E_NOTIMPL;
153 static HRESULT WINAPI effect_GetOutputStreamInfo(IMediaObject *iface, DWORD index, DWORD *flags)
155 FIXME("iface %p, index %lu, flags %p, stub!\n", iface, index, flags);
156 return E_NOTIMPL;
159 static HRESULT WINAPI effect_GetInputType(IMediaObject *iface, DWORD index, DWORD type_index, DMO_MEDIA_TYPE *type)
161 FIXME("iface %p, index %lu, type_index %lu, type %p, stub!\n", iface, index, type_index, type);
162 return E_NOTIMPL;
165 static HRESULT WINAPI effect_GetOutputType(IMediaObject *iface, DWORD index, DWORD type_index, DMO_MEDIA_TYPE *type)
167 FIXME("iface %p, index %lu, type_index %lu, type %p, stub!\n", iface, index, type_index, type);
168 return E_NOTIMPL;
171 static HRESULT WINAPI effect_SetInputType(IMediaObject *iface, DWORD index, const DMO_MEDIA_TYPE *type, DWORD flags)
173 struct effect *effect = impl_from_IMediaObject(iface);
174 const WAVEFORMATEX *format;
176 TRACE("iface %p, index %lu, type %p, flags %#lx.\n", iface, index, type, flags);
178 if (flags & DMO_SET_TYPEF_CLEAR)
180 EnterCriticalSection(&effect->cs);
181 memset(&effect->format, 0, sizeof(effect->format));
182 LeaveCriticalSection(&effect->cs);
183 return S_OK;
186 if (!IsEqualGUID(&type->majortype, &MEDIATYPE_Audio))
187 return DMO_E_TYPE_NOT_ACCEPTED;
189 if (!IsEqualGUID(&type->subtype, &MEDIASUBTYPE_PCM)
190 && !IsEqualGUID(&type->subtype, &MEDIASUBTYPE_IEEE_FLOAT))
191 return DMO_E_TYPE_NOT_ACCEPTED;
193 if (!IsEqualGUID(&type->formattype, &FORMAT_WaveFormatEx))
194 return DMO_E_TYPE_NOT_ACCEPTED;
196 format = (const WAVEFORMATEX *)type->pbFormat;
197 if (format->wFormatTag == WAVE_FORMAT_PCM)
199 if (format->wBitsPerSample != 8 && format->wBitsPerSample != 16)
201 WARN("Rejecting %u-bit integer PCM.\n", format->wBitsPerSample);
202 return DMO_E_TYPE_NOT_ACCEPTED;
205 else if (format->wFormatTag == WAVE_FORMAT_IEEE_FLOAT)
207 if (format->wBitsPerSample != 32)
209 WARN("Rejecting %u-bit float PCM.\n", format->wBitsPerSample);
210 return DMO_E_TYPE_NOT_ACCEPTED;
213 else
215 WARN("Rejecting tag %#x.\n", format->wFormatTag);
216 return DMO_E_TYPE_NOT_ACCEPTED;
219 if (format->nChannels != 1 && format->nChannels != 2)
221 WARN("Rejecting %u channels.\n", format->nChannels);
222 return DMO_E_TYPE_NOT_ACCEPTED;
225 EnterCriticalSection(&effect->cs);
226 effect->format = *format;
227 LeaveCriticalSection(&effect->cs);
229 return S_OK;
232 static HRESULT WINAPI effect_SetOutputType(IMediaObject *iface, DWORD index, const DMO_MEDIA_TYPE *type, DWORD flags)
234 struct effect *effect = impl_from_IMediaObject(iface);
235 HRESULT hr;
237 TRACE("iface %p, index %lu, type %p, flags %#lx.\n", iface, index, type, flags);
239 if (flags & DMO_SET_TYPEF_CLEAR)
240 return S_OK;
242 if (!IsEqualGUID(&type->majortype, &MEDIATYPE_Audio))
243 return DMO_E_TYPE_NOT_ACCEPTED;
245 if (!IsEqualGUID(&type->subtype, &MEDIASUBTYPE_PCM)
246 && !IsEqualGUID(&type->subtype, &MEDIASUBTYPE_IEEE_FLOAT))
247 return DMO_E_TYPE_NOT_ACCEPTED;
249 if (!IsEqualGUID(&type->formattype, &FORMAT_WaveFormatEx))
250 return DMO_E_TYPE_NOT_ACCEPTED;
252 EnterCriticalSection(&effect->cs);
253 hr = memcmp(type->pbFormat, &effect->format, sizeof(WAVEFORMATEX)) ? DMO_E_TYPE_NOT_ACCEPTED : S_OK;
254 LeaveCriticalSection(&effect->cs);
256 return hr;
259 static HRESULT WINAPI effect_GetInputCurrentType(IMediaObject *iface, DWORD index, DMO_MEDIA_TYPE *type)
261 FIXME("iface %p, index %lu, type %p, stub!\n", iface, index, type);
262 return E_NOTIMPL;
265 static HRESULT WINAPI effect_GetOutputCurrentType(IMediaObject *iface, DWORD index, DMO_MEDIA_TYPE *type)
267 FIXME("iface %p, index %lu, type %p, stub!\n", iface, index, type);
268 return E_NOTIMPL;
271 static HRESULT WINAPI effect_GetInputSizeInfo(IMediaObject *iface, DWORD index,
272 DWORD *size, DWORD *lookahead, DWORD *alignment)
274 FIXME("iface %p, index %lu, size %p, lookahead %p, alignment %p, stub!\n", iface, index, size, lookahead, alignment);
275 return E_NOTIMPL;
278 static HRESULT WINAPI effect_GetOutputSizeInfo(IMediaObject *iface, DWORD index, DWORD *size, DWORD *alignment)
280 FIXME("iface %p, index %lu, size %p, alignment %p, stub!\n", iface, index, size, alignment);
281 return E_NOTIMPL;
284 static HRESULT WINAPI effect_GetInputMaxLatency(IMediaObject *iface, DWORD index, REFERENCE_TIME *latency)
286 FIXME("iface %p, index %lu, latency %p, stub!\n", iface, index, latency);
287 return E_NOTIMPL;
290 static HRESULT WINAPI effect_SetInputMaxLatency(IMediaObject *iface, DWORD index, REFERENCE_TIME latency)
292 FIXME("iface %p, index %lu, latency %s, stub!\n", iface, index, wine_dbgstr_longlong(latency));
293 return E_NOTIMPL;
296 static HRESULT WINAPI effect_Flush(IMediaObject *iface)
298 FIXME("iface %p, stub!\n", iface);
299 return E_NOTIMPL;
302 static HRESULT WINAPI effect_Discontinuity(IMediaObject *iface, DWORD index)
304 FIXME("iface %p, index %lu, stub!\n", iface, index);
305 return E_NOTIMPL;
308 static HRESULT WINAPI effect_AllocateStreamingResources(IMediaObject *iface)
310 FIXME("iface %p, stub!\n", iface);
311 return E_NOTIMPL;
314 static HRESULT WINAPI effect_FreeStreamingResources(IMediaObject *iface)
316 FIXME("iface %p, stub!\n", iface);
317 return E_NOTIMPL;
320 static HRESULT WINAPI effect_GetInputStatus(IMediaObject *iface, DWORD index, DWORD *flags)
322 FIXME("iface %p, index %lu, flags %p, stub!\n", iface, index, flags);
323 return E_NOTIMPL;
326 static HRESULT WINAPI effect_ProcessInput(IMediaObject *iface, DWORD index,
327 IMediaBuffer *buffer, DWORD flags, REFERENCE_TIME timestamp, REFERENCE_TIME timelength)
329 FIXME("iface %p, index %lu, buffer %p, flags %#lx, timestamp %s, timelength %s, stub!\n",
330 iface, index, buffer, flags, wine_dbgstr_longlong(timestamp), wine_dbgstr_longlong(timelength));
331 return E_NOTIMPL;
334 static HRESULT WINAPI effect_ProcessOutput(IMediaObject *iface, DWORD flags,
335 DWORD count, DMO_OUTPUT_DATA_BUFFER *buffers, DWORD *status)
337 FIXME("iface %p, flags %#lx, count %lu, buffers %p, status %p, stub!\n", iface, flags, count, buffers, status);
338 return E_NOTIMPL;
341 static HRESULT WINAPI effect_Lock(IMediaObject *iface, LONG lock)
343 FIXME("iface %p, lock %ld, stub!\n", iface, lock);
344 return E_NOTIMPL;
347 static const IMediaObjectVtbl effect_vtbl =
349 effect_QueryInterface,
350 effect_AddRef,
351 effect_Release,
352 effect_GetStreamCount,
353 effect_GetInputStreamInfo,
354 effect_GetOutputStreamInfo,
355 effect_GetInputType,
356 effect_GetOutputType,
357 effect_SetInputType,
358 effect_SetOutputType,
359 effect_GetInputCurrentType,
360 effect_GetOutputCurrentType,
361 effect_GetInputSizeInfo,
362 effect_GetOutputSizeInfo,
363 effect_GetInputMaxLatency,
364 effect_SetInputMaxLatency,
365 effect_Flush,
366 effect_Discontinuity,
367 effect_AllocateStreamingResources,
368 effect_FreeStreamingResources,
369 effect_GetInputStatus,
370 effect_ProcessInput,
371 effect_ProcessOutput,
372 effect_Lock,
375 static struct effect *impl_from_IMediaObjectInPlace(IMediaObjectInPlace *iface)
377 return CONTAINING_RECORD(iface, struct effect, IMediaObjectInPlace_iface);
380 static HRESULT WINAPI effect_inplace_QueryInterface(IMediaObjectInPlace *iface, REFIID iid, void **out)
382 struct effect *effect = impl_from_IMediaObjectInPlace(iface);
383 return IUnknown_QueryInterface(effect->outer_unk, iid, out);
386 static ULONG WINAPI effect_inplace_AddRef(IMediaObjectInPlace *iface)
388 struct effect *effect = impl_from_IMediaObjectInPlace(iface);
389 return IUnknown_AddRef(effect->outer_unk);
392 static ULONG WINAPI effect_inplace_Release(IMediaObjectInPlace *iface)
394 struct effect *effect = impl_from_IMediaObjectInPlace(iface);
395 return IUnknown_Release(effect->outer_unk);
398 static HRESULT WINAPI effect_inplace_Process(IMediaObjectInPlace *iface, ULONG size,
399 BYTE *data, REFERENCE_TIME start, DWORD flags)
401 FIXME("iface %p, size %lu, data %p, start %s, flags %#lx, stub!\n",
402 iface, size, data, wine_dbgstr_longlong(start), flags);
403 return E_NOTIMPL;
406 static HRESULT WINAPI effect_inplace_Clone(IMediaObjectInPlace *iface, IMediaObjectInPlace **out)
408 FIXME("iface %p, out %p, stub!\n", iface, out);
409 return E_NOTIMPL;
412 static HRESULT WINAPI effect_inplace_GetLatency(IMediaObjectInPlace *iface, REFERENCE_TIME *latency)
414 FIXME("iface %p, latency %p, stub!\n", iface, latency);
415 return E_NOTIMPL;
418 static const IMediaObjectInPlaceVtbl effect_inplace_vtbl =
420 effect_inplace_QueryInterface,
421 effect_inplace_AddRef,
422 effect_inplace_Release,
423 effect_inplace_Process,
424 effect_inplace_Clone,
425 effect_inplace_GetLatency,
428 static struct effect *impl_from_IMediaParams(IMediaParams *iface)
430 return CONTAINING_RECORD(iface, struct effect, IMediaParams_iface);
433 static HRESULT WINAPI effect_media_params_QueryInterface(IMediaParams *iface, REFIID iid, void **out)
435 struct effect *effect = impl_from_IMediaParams(iface);
436 return IUnknown_QueryInterface(effect->outer_unk, iid, out);
439 static ULONG WINAPI effect_media_params_AddRef(IMediaParams *iface)
441 struct effect *effect = impl_from_IMediaParams(iface);
442 return IUnknown_AddRef(effect->outer_unk);
445 static ULONG WINAPI effect_media_params_Release(IMediaParams *iface)
447 struct effect *effect = impl_from_IMediaParams(iface);
448 return IUnknown_Release(effect->outer_unk);
451 static HRESULT WINAPI effect_media_params_GetParam(IMediaParams *iface, DWORD index, MP_DATA *data)
453 FIXME("iface %p, index %lu, data %p, stub!\n", iface, index, data);
454 return E_NOTIMPL;
457 static HRESULT WINAPI effect_media_params_SetParam(IMediaParams *iface, DWORD index, MP_DATA data)
459 FIXME("iface %p, index %lu, data %f, stub!\n", iface, index, data);
460 return E_NOTIMPL;
463 static HRESULT WINAPI effect_media_params_AddEnvelope(IMediaParams *iface, DWORD index, DWORD count,
464 MP_ENVELOPE_SEGMENT *segments)
466 FIXME("iface %p, index %lu, count %lu, segments %p, stub!\n", iface, index, count, segments);
467 return E_NOTIMPL;
470 static HRESULT WINAPI effect_media_params_FlushEnvelope(IMediaParams *iface, DWORD index,
471 REFERENCE_TIME start, REFERENCE_TIME end)
473 FIXME("iface %p, index %lu, start %s, end %s, stub!\n", iface, index,
474 wine_dbgstr_longlong(start), wine_dbgstr_longlong(end));
475 return E_NOTIMPL;
478 static HRESULT WINAPI effect_media_params_SetTimeFormat(IMediaParams *iface, GUID guid,
479 MP_TIMEDATA time_data)
481 FIXME("iface %p, guid %s, time_data %lx, stub!\n", iface, wine_dbgstr_guid(&guid), time_data);
482 return E_NOTIMPL;
485 static const IMediaParamsVtbl effect_media_params_vtbl =
487 effect_media_params_QueryInterface,
488 effect_media_params_AddRef,
489 effect_media_params_Release,
490 effect_media_params_GetParam,
491 effect_media_params_SetParam,
492 effect_media_params_AddEnvelope,
493 effect_media_params_FlushEnvelope,
494 effect_media_params_SetTimeFormat,
497 static struct effect *impl_from_IMediaParamInfo(IMediaParamInfo *iface)
499 return CONTAINING_RECORD(iface, struct effect, IMediaParamInfo_iface);
502 static HRESULT WINAPI effect_media_param_info_QueryInterface(IMediaParamInfo *iface, REFIID iid, void **out)
504 struct effect *effect = impl_from_IMediaParamInfo(iface);
505 return IUnknown_QueryInterface(effect->outer_unk, iid, out);
508 static ULONG WINAPI effect_media_param_info_AddRef(IMediaParamInfo *iface)
510 struct effect *effect = impl_from_IMediaParamInfo(iface);
511 return IUnknown_AddRef(effect->outer_unk);
514 static ULONG WINAPI effect_media_param_info_Release(IMediaParamInfo *iface)
516 struct effect *effect = impl_from_IMediaParamInfo(iface);
517 return IUnknown_Release(effect->outer_unk);
520 static HRESULT WINAPI effect_media_param_info_GetParamCount(IMediaParamInfo *iface, DWORD *count)
522 FIXME("iface %p, count %p, stub!\n", iface, count);
523 return E_NOTIMPL;
526 static HRESULT WINAPI effect_media_param_info_GetParamInfo(IMediaParamInfo *iface, DWORD index, MP_PARAMINFO *info)
528 FIXME("iface %p, index %lu, info %p, stub!\n", iface, index, info);
529 return E_NOTIMPL;
532 static HRESULT WINAPI effect_media_param_info_GetParamText(IMediaParamInfo *iface, DWORD index, WCHAR **text)
534 FIXME("iface %p, index %lu, text %p, stub!\n", iface, index, text);
535 return E_NOTIMPL;
538 static HRESULT WINAPI effect_media_param_info_GetNumTimeFormats(IMediaParamInfo *iface, DWORD *count)
540 FIXME("iface %p, count %p, stub!\n", iface, count);
541 return E_NOTIMPL;
544 static HRESULT WINAPI effect_media_param_info_GetSupportedTimeFormat(IMediaParamInfo *iface, DWORD index, GUID *guid)
546 FIXME("iface %p, index %lu, guid %p, stub!\n", iface, index, guid);
547 return E_NOTIMPL;
550 static HRESULT WINAPI effect_media_param_info_GetCurrentTimeFormat(IMediaParamInfo *iface, GUID *guid, MP_TIMEDATA *time_data)
552 FIXME("iface %p, guid %p, time_data %p, stub!\n", iface, guid, time_data);
553 return E_NOTIMPL;
556 static const IMediaParamInfoVtbl effect_media_param_info_vtbl =
558 effect_media_param_info_QueryInterface,
559 effect_media_param_info_AddRef,
560 effect_media_param_info_Release,
561 effect_media_param_info_GetParamCount,
562 effect_media_param_info_GetParamInfo,
563 effect_media_param_info_GetParamText,
564 effect_media_param_info_GetNumTimeFormats,
565 effect_media_param_info_GetSupportedTimeFormat,
566 effect_media_param_info_GetCurrentTimeFormat,
569 static void effect_init(struct effect *effect, IUnknown *outer, const struct effect_ops *ops)
571 effect->outer_unk = outer ? outer : &effect->IUnknown_inner;
572 effect->refcount = 1;
573 effect->IUnknown_inner.lpVtbl = &effect_inner_vtbl;
574 effect->IMediaObject_iface.lpVtbl = &effect_vtbl;
575 effect->IMediaObjectInPlace_iface.lpVtbl = &effect_inplace_vtbl;
576 effect->IMediaParams_iface.lpVtbl = &effect_media_params_vtbl;
577 effect->IMediaParamInfo_iface.lpVtbl = &effect_media_param_info_vtbl;
579 InitializeCriticalSection(&effect->cs);
580 effect->cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": effect.cs");
582 effect->ops = ops;
585 struct eq
587 struct effect effect;
588 IDirectSoundFXParamEq IDirectSoundFXParamEq_iface;
589 DSFXParamEq params;
592 static struct eq *impl_from_IDirectSoundFXParamEq(IDirectSoundFXParamEq *iface)
594 return CONTAINING_RECORD(iface, struct eq, IDirectSoundFXParamEq_iface);
597 static HRESULT WINAPI eq_params_QueryInterface(IDirectSoundFXParamEq *iface, REFIID iid, void **out)
599 struct eq *effect = impl_from_IDirectSoundFXParamEq(iface);
600 return IUnknown_QueryInterface(effect->effect.outer_unk, iid, out);
603 static ULONG WINAPI eq_params_AddRef(IDirectSoundFXParamEq *iface)
605 struct eq *effect = impl_from_IDirectSoundFXParamEq(iface);
606 return IUnknown_AddRef(effect->effect.outer_unk);
609 static ULONG WINAPI eq_params_Release(IDirectSoundFXParamEq *iface)
611 struct eq *effect = impl_from_IDirectSoundFXParamEq(iface);
612 return IUnknown_Release(effect->effect.outer_unk);
615 static HRESULT WINAPI eq_params_SetAllParameters(IDirectSoundFXParamEq *iface, const DSFXParamEq *params)
617 struct eq *effect = impl_from_IDirectSoundFXParamEq(iface);
619 TRACE("effect %p, params %p.\n", effect, params);
621 EnterCriticalSection(&effect->effect.cs);
622 effect->params = *params;
623 LeaveCriticalSection(&effect->effect.cs);
624 return S_OK;
627 static HRESULT WINAPI eq_params_GetAllParameters(IDirectSoundFXParamEq *iface, DSFXParamEq *params)
629 struct eq *effect = impl_from_IDirectSoundFXParamEq(iface);
631 TRACE("effect %p, params %p.\n", effect, params);
633 EnterCriticalSection(&effect->effect.cs);
634 *params = effect->params;
635 LeaveCriticalSection(&effect->effect.cs);
636 return S_OK;
639 static const IDirectSoundFXParamEqVtbl eq_params_vtbl =
641 eq_params_QueryInterface,
642 eq_params_AddRef,
643 eq_params_Release,
644 eq_params_SetAllParameters,
645 eq_params_GetAllParameters,
648 static struct eq *impl_eq_from_effect(struct effect *iface)
650 return CONTAINING_RECORD(iface, struct eq, effect);
653 static void *eq_query_interface(struct effect *iface, REFIID iid)
655 struct eq *effect = impl_eq_from_effect(iface);
657 if (IsEqualGUID(iid, &IID_IDirectSoundFXParamEq))
658 return &effect->IDirectSoundFXParamEq_iface;
659 return NULL;
662 static void eq_destroy(struct effect *iface)
664 struct eq *effect = impl_eq_from_effect(iface);
666 free(effect);
669 static const struct effect_ops eq_ops =
671 .destroy = eq_destroy,
672 .query_interface = eq_query_interface,
675 static HRESULT eq_create(IUnknown *outer, IUnknown **out)
677 struct eq *object;
679 if (!(object = calloc(1, sizeof(*object))))
680 return E_OUTOFMEMORY;
682 effect_init(&object->effect, outer, &eq_ops);
683 object->IDirectSoundFXParamEq_iface.lpVtbl = &eq_params_vtbl;
685 object->params.fCenter = 8000.0f;
686 object->params.fBandwidth = 12.0f;
687 object->params.fGain = 0.0f;
689 TRACE("Created equalizer effect %p.\n", object);
690 *out = &object->effect.IUnknown_inner;
691 return S_OK;
694 struct reverb
696 struct effect effect;
697 IDirectSoundFXI3DL2Reverb IDirectSoundFXI3DL2Reverb_iface;
698 DSFXI3DL2Reverb params;
701 static struct reverb *impl_from_IDirectSoundFXI3DL2Reverb(IDirectSoundFXI3DL2Reverb *iface)
703 return CONTAINING_RECORD(iface, struct reverb, IDirectSoundFXI3DL2Reverb_iface);
706 static HRESULT WINAPI reverb_params_QueryInterface(IDirectSoundFXI3DL2Reverb *iface, REFIID iid, void **out)
708 struct reverb *effect = impl_from_IDirectSoundFXI3DL2Reverb(iface);
709 return IUnknown_QueryInterface(effect->effect.outer_unk, iid, out);
712 static ULONG WINAPI reverb_params_AddRef(IDirectSoundFXI3DL2Reverb *iface)
714 struct reverb *effect = impl_from_IDirectSoundFXI3DL2Reverb(iface);
715 return IUnknown_AddRef(effect->effect.outer_unk);
718 static ULONG WINAPI reverb_params_Release(IDirectSoundFXI3DL2Reverb *iface)
720 struct reverb *effect = impl_from_IDirectSoundFXI3DL2Reverb(iface);
721 return IUnknown_Release(effect->effect.outer_unk);
724 static HRESULT WINAPI reverb_params_SetAllParameters(IDirectSoundFXI3DL2Reverb *iface, const DSFXI3DL2Reverb *params)
726 struct reverb *effect = impl_from_IDirectSoundFXI3DL2Reverb(iface);
728 TRACE("effect %p, params %p.\n", effect, params);
730 EnterCriticalSection(&effect->effect.cs);
731 effect->params = *params;
732 LeaveCriticalSection(&effect->effect.cs);
733 return S_OK;
736 static HRESULT WINAPI reverb_params_GetAllParameters(IDirectSoundFXI3DL2Reverb *iface, DSFXI3DL2Reverb *params)
738 struct reverb *effect = impl_from_IDirectSoundFXI3DL2Reverb(iface);
740 TRACE("effect %p, params %p.\n", effect, params);
742 EnterCriticalSection(&effect->effect.cs);
743 *params = effect->params;
744 LeaveCriticalSection(&effect->effect.cs);
745 return S_OK;
748 static HRESULT WINAPI reverb_params_SetPreset(IDirectSoundFXI3DL2Reverb *iface, DWORD preset)
750 struct reverb *effect = impl_from_IDirectSoundFXI3DL2Reverb(iface);
752 FIXME("effect %p, preset %lu, stub!\n", effect, preset);
754 return E_NOTIMPL;
757 static HRESULT WINAPI reverb_params_GetPreset(IDirectSoundFXI3DL2Reverb *iface, DWORD *preset)
759 struct reverb *effect = impl_from_IDirectSoundFXI3DL2Reverb(iface);
761 FIXME("effect %p, preset %p, stub!\n", effect, preset);
763 return E_NOTIMPL;
766 static HRESULT WINAPI reverb_params_SetQuality(IDirectSoundFXI3DL2Reverb *iface, LONG quality)
768 struct reverb *effect = impl_from_IDirectSoundFXI3DL2Reverb(iface);
770 FIXME("effect %p, quality %lu, stub!\n", effect, quality);
772 return E_NOTIMPL;
775 static HRESULT WINAPI reverb_params_GetQuality(IDirectSoundFXI3DL2Reverb *iface, LONG *quality)
777 struct reverb *effect = impl_from_IDirectSoundFXI3DL2Reverb(iface);
779 FIXME("effect %p, quality %p, stub!\n", effect, quality);
781 return E_NOTIMPL;
784 static const IDirectSoundFXI3DL2ReverbVtbl reverb_params_vtbl =
786 reverb_params_QueryInterface,
787 reverb_params_AddRef,
788 reverb_params_Release,
789 reverb_params_SetAllParameters,
790 reverb_params_GetAllParameters,
791 reverb_params_SetPreset,
792 reverb_params_GetPreset,
793 reverb_params_SetQuality,
794 reverb_params_GetQuality,
797 static struct reverb *impl_reverb_from_effect(struct effect *iface)
799 return CONTAINING_RECORD(iface, struct reverb, effect);
802 static void *reverb_query_interface(struct effect *iface, REFIID iid)
804 struct reverb *effect = impl_reverb_from_effect(iface);
806 if (IsEqualGUID(iid, &IID_IDirectSoundFXI3DL2Reverb))
807 return &effect->IDirectSoundFXI3DL2Reverb_iface;
808 return NULL;
811 static void reverb_destroy(struct effect *iface)
813 struct reverb *effect = impl_reverb_from_effect(iface);
815 free(effect);
818 static const struct effect_ops reverb_ops =
820 .destroy = reverb_destroy,
821 .query_interface = reverb_query_interface,
824 static HRESULT reverb_create(IUnknown *outer, IUnknown **out)
826 struct reverb *object;
828 if (!(object = calloc(1, sizeof(*object))))
829 return E_OUTOFMEMORY;
831 effect_init(&object->effect, outer, &reverb_ops);
832 object->IDirectSoundFXI3DL2Reverb_iface.lpVtbl = &reverb_params_vtbl;
834 object->params.lRoom = DSFX_I3DL2REVERB_ROOM_DEFAULT;
835 object->params.lRoomHF = DSFX_I3DL2REVERB_ROOMHF_DEFAULT;
836 object->params.flRoomRolloffFactor = DSFX_I3DL2REVERB_ROOMROLLOFFFACTOR_DEFAULT;
837 object->params.flDecayTime = DSFX_I3DL2REVERB_DECAYTIME_DEFAULT;
838 object->params.flDecayHFRatio = DSFX_I3DL2REVERB_DECAYHFRATIO_DEFAULT;
839 object->params.lReflections = DSFX_I3DL2REVERB_REFLECTIONS_DEFAULT;
840 object->params.flReflectionsDelay = DSFX_I3DL2REVERB_REFLECTIONSDELAY_DEFAULT;
841 object->params.lReverb = DSFX_I3DL2REVERB_REVERB_DEFAULT;
842 object->params.flReverbDelay = DSFX_I3DL2REVERB_REVERBDELAY_DEFAULT;
843 object->params.flDiffusion = DSFX_I3DL2REVERB_DIFFUSION_DEFAULT;
844 object->params.flDensity = DSFX_I3DL2REVERB_DENSITY_DEFAULT;
845 object->params.flHFReference = DSFX_I3DL2REVERB_HFREFERENCE_DEFAULT;
847 TRACE("Created I3DL2 reverb effect %p.\n", object);
848 *out = &object->effect.IUnknown_inner;
849 return S_OK;
852 struct waves_reverb
854 struct effect effect;
855 IDirectSoundFXWavesReverb IDirectSoundFXWavesReverb_iface;
858 static struct waves_reverb *impl_from_IDirectSoundFXWavesReverb(IDirectSoundFXWavesReverb *iface)
860 return CONTAINING_RECORD(iface, struct waves_reverb, IDirectSoundFXWavesReverb_iface);
863 static HRESULT WINAPI waves_reverb_params_QueryInterface(IDirectSoundFXWavesReverb *iface, REFIID iid, void **out)
865 struct waves_reverb *effect = impl_from_IDirectSoundFXWavesReverb(iface);
866 return IUnknown_QueryInterface(effect->effect.outer_unk, iid, out);
869 static ULONG WINAPI waves_reverb_params_AddRef(IDirectSoundFXWavesReverb *iface)
871 struct waves_reverb *effect = impl_from_IDirectSoundFXWavesReverb(iface);
872 return IUnknown_AddRef(effect->effect.outer_unk);
875 static ULONG WINAPI waves_reverb_params_Release(IDirectSoundFXWavesReverb *iface)
877 struct waves_reverb *effect = impl_from_IDirectSoundFXWavesReverb(iface);
878 return IUnknown_Release(effect->effect.outer_unk);
881 static HRESULT WINAPI waves_reverb_params_SetAllParameters(IDirectSoundFXWavesReverb *iface, const DSFXWavesReverb *params)
883 struct waves_reverb *effect = impl_from_IDirectSoundFXWavesReverb(iface);
885 FIXME("effect %p, params %p, stub!\n", effect, params);
887 return E_NOTIMPL;
890 static HRESULT WINAPI waves_reverb_params_GetAllParameters(IDirectSoundFXWavesReverb *iface, DSFXWavesReverb *params)
892 struct waves_reverb *effect = impl_from_IDirectSoundFXWavesReverb(iface);
894 FIXME("effect %p, params %p, stub!\n", effect, params);
896 return E_NOTIMPL;
899 static const IDirectSoundFXWavesReverbVtbl waves_reverb_params_vtbl =
901 waves_reverb_params_QueryInterface,
902 waves_reverb_params_AddRef,
903 waves_reverb_params_Release,
904 waves_reverb_params_SetAllParameters,
905 waves_reverb_params_GetAllParameters,
908 static struct waves_reverb *impl_waves_reverb_from_effect(struct effect *iface)
910 return CONTAINING_RECORD(iface, struct waves_reverb, effect);
913 static void *waves_reverb_query_interface(struct effect *iface, REFIID iid)
915 struct waves_reverb *effect = impl_waves_reverb_from_effect(iface);
917 if (IsEqualGUID(iid, &IID_IDirectSoundFXWavesReverb))
918 return &effect->IDirectSoundFXWavesReverb_iface;
919 return NULL;
922 static void waves_reverb_destroy(struct effect *iface)
924 struct waves_reverb *effect = impl_waves_reverb_from_effect(iface);
926 free(effect);
929 static const struct effect_ops waves_reverb_ops =
931 .destroy = waves_reverb_destroy,
932 .query_interface = waves_reverb_query_interface,
935 static HRESULT waves_reverb_create(IUnknown *outer, IUnknown **out)
937 struct waves_reverb *object;
939 if (!(object = calloc(1, sizeof(*object))))
940 return E_OUTOFMEMORY;
942 effect_init(&object->effect, outer, &waves_reverb_ops);
943 object->IDirectSoundFXWavesReverb_iface.lpVtbl = &waves_reverb_params_vtbl;
945 TRACE("Created waves reverb effect %p.\n", object);
946 *out = &object->effect.IUnknown_inner;
947 return S_OK;
950 struct dmo_echofx
952 struct effect effect;
953 IDirectSoundFXEcho IDirectSoundFXEcho_iface;
956 static inline struct dmo_echofx *impl_from_IDirectSoundFXEcho(IDirectSoundFXEcho *iface)
958 return CONTAINING_RECORD(iface, struct dmo_echofx, IDirectSoundFXEcho_iface);
961 static HRESULT WINAPI echofx_QueryInterface(IDirectSoundFXEcho *iface, REFIID iid, void **out)
963 struct dmo_echofx *effect = impl_from_IDirectSoundFXEcho(iface);
964 return IUnknown_QueryInterface(effect->effect.outer_unk, iid, out);
967 static ULONG WINAPI echofx_AddRef(IDirectSoundFXEcho *iface)
969 struct dmo_echofx *effect = impl_from_IDirectSoundFXEcho(iface);
970 return IUnknown_AddRef(effect->effect.outer_unk);
973 static ULONG WINAPI echofx_Release(IDirectSoundFXEcho *iface)
975 struct dmo_echofx *effect = impl_from_IDirectSoundFXEcho(iface);
976 return IUnknown_Release(effect->effect.outer_unk);
979 static HRESULT WINAPI echofx_SetAllParameters(IDirectSoundFXEcho *iface, const DSFXEcho *echo)
981 struct dmo_echofx *effect = impl_from_IDirectSoundFXEcho(iface);
982 FIXME("(%p) %p\n", effect, echo);
984 return E_NOTIMPL;
987 static HRESULT WINAPI echofx_GetAllParameters(IDirectSoundFXEcho *iface, DSFXEcho *echo)
989 struct dmo_echofx *effect = impl_from_IDirectSoundFXEcho(iface);
990 FIXME("(%p) %p\n", effect, echo);
992 return E_NOTIMPL;
995 static const struct IDirectSoundFXEchoVtbl echofx_vtbl =
997 echofx_QueryInterface,
998 echofx_AddRef,
999 echofx_Release,
1000 echofx_SetAllParameters,
1001 echofx_GetAllParameters
1004 static struct dmo_echofx *impl_echo_from_effect(struct effect *iface)
1006 return CONTAINING_RECORD(iface, struct dmo_echofx, effect);
1009 static void *echo_query_interface(struct effect *iface, REFIID iid)
1011 struct dmo_echofx *effect = impl_echo_from_effect(iface);
1013 if (IsEqualGUID(iid, &IID_IDirectSoundFXEcho))
1014 return &effect->IDirectSoundFXEcho_iface;
1015 return NULL;
1018 static void echo_destroy(struct effect *iface)
1020 struct dmo_echofx *effect = impl_echo_from_effect(iface);
1022 free(effect);
1025 static const struct effect_ops echo_ops =
1027 .destroy = echo_destroy,
1028 .query_interface = echo_query_interface,
1031 static HRESULT echo_create(IUnknown *outer, IUnknown **out)
1033 struct dmo_echofx *object;
1035 if (!(object = calloc(1, sizeof(*object))))
1036 return E_OUTOFMEMORY;
1038 effect_init(&object->effect, outer, &echo_ops);
1039 object->IDirectSoundFXEcho_iface.lpVtbl = &echofx_vtbl;
1041 TRACE("Created echo effect %p.\n", object);
1042 *out = &object->effect.IUnknown_inner;
1043 return S_OK;
1046 struct dmo_compressorfx
1048 struct effect effect;
1049 IDirectSoundFXCompressor IDirectSoundFXCompressor_iface;
1052 static inline struct dmo_compressorfx *impl_from_IDirectSoundFXCompressor(IDirectSoundFXCompressor *iface)
1054 return CONTAINING_RECORD(iface, struct dmo_compressorfx, IDirectSoundFXCompressor_iface);
1057 static HRESULT WINAPI compressorfx_QueryInterface(IDirectSoundFXCompressor *iface, REFIID iid, void **out)
1059 struct dmo_compressorfx *effect = impl_from_IDirectSoundFXCompressor(iface);
1060 return IUnknown_QueryInterface(effect->effect.outer_unk, iid, out);
1063 static ULONG WINAPI compressorfx_AddRef(IDirectSoundFXCompressor *iface)
1065 struct dmo_compressorfx *effect = impl_from_IDirectSoundFXCompressor(iface);
1066 return IUnknown_AddRef(effect->effect.outer_unk);
1069 static ULONG WINAPI compressorfx_Release(IDirectSoundFXCompressor *iface)
1071 struct dmo_compressorfx *effect = impl_from_IDirectSoundFXCompressor(iface);
1072 return IUnknown_Release(effect->effect.outer_unk);
1075 static HRESULT WINAPI compressorfx_SetAllParameters(IDirectSoundFXCompressor *iface, const DSFXCompressor *compressor)
1077 struct dmo_compressorfx *This = impl_from_IDirectSoundFXCompressor(iface);
1078 FIXME("(%p) %p\n", This, compressor);
1080 return E_NOTIMPL;
1083 static HRESULT WINAPI compressorfx_GetAllParameters(IDirectSoundFXCompressor *iface, DSFXCompressor *compressor)
1085 struct dmo_compressorfx *This = impl_from_IDirectSoundFXCompressor(iface);
1086 FIXME("(%p) %p\n", This, compressor);
1088 return E_NOTIMPL;
1091 static const struct IDirectSoundFXCompressorVtbl compressor_vtbl =
1093 compressorfx_QueryInterface,
1094 compressorfx_AddRef,
1095 compressorfx_Release,
1096 compressorfx_SetAllParameters,
1097 compressorfx_GetAllParameters
1100 static struct dmo_compressorfx *impl_compressor_from_effect(struct effect *iface)
1102 return CONTAINING_RECORD(iface, struct dmo_compressorfx, effect);
1105 static void *compressor_query_interface(struct effect *iface, REFIID iid)
1107 struct dmo_compressorfx *effect = impl_compressor_from_effect(iface);
1109 if (IsEqualGUID(iid, &IID_IDirectSoundFXCompressor))
1110 return &effect->IDirectSoundFXCompressor_iface;
1111 return NULL;
1114 static void compressor_destroy(struct effect *iface)
1116 struct dmo_compressorfx *effect = impl_compressor_from_effect(iface);
1118 free(effect);
1121 static const struct effect_ops compressor_ops =
1123 .destroy = compressor_destroy,
1124 .query_interface = compressor_query_interface,
1127 static HRESULT compressor_create(IUnknown *outer, IUnknown **out)
1129 struct dmo_compressorfx *object;
1131 if (!(object = calloc(1, sizeof(*object))))
1132 return E_OUTOFMEMORY;
1134 effect_init(&object->effect, outer, &compressor_ops);
1135 object->IDirectSoundFXCompressor_iface.lpVtbl = &compressor_vtbl;
1137 TRACE("Created compressor effect %p.\n", object);
1138 *out = &object->effect.IUnknown_inner;
1139 return S_OK;
1142 struct class_factory
1144 IClassFactory IClassFactory_iface;
1145 HRESULT (*create_instance)(IUnknown *outer, IUnknown **out);
1148 static struct class_factory *impl_from_IClassFactory(IClassFactory *iface)
1150 return CONTAINING_RECORD(iface, struct class_factory, IClassFactory_iface);
1153 static HRESULT WINAPI class_factory_QueryInterface(IClassFactory *iface, REFIID iid, void **out)
1155 TRACE("iface %p, iid %s, out %p.\n", iface, debugstr_guid(iid), out);
1157 if (IsEqualGUID(iid, &IID_IUnknown) || IsEqualGUID(iid, &IID_IClassFactory))
1159 IClassFactory_AddRef(iface);
1160 *out = iface;
1161 return S_OK;
1164 *out = NULL;
1165 WARN("%s not implemented, returning E_NOINTERFACE\n", debugstr_guid(iid));
1166 return E_NOINTERFACE;
1169 static ULONG WINAPI class_factory_AddRef(IClassFactory *iface)
1171 return 2;
1174 static ULONG WINAPI class_factory_Release(IClassFactory *iface)
1176 return 1;
1179 static HRESULT WINAPI class_factory_CreateInstance(IClassFactory *iface,
1180 IUnknown *outer, REFIID iid, void **out)
1182 struct class_factory *factory = impl_from_IClassFactory(iface);
1183 IUnknown *unk;
1184 HRESULT hr;
1186 TRACE("iface %p, outer %p, iid %s, out %p.\n", iface, outer, debugstr_guid(iid), out);
1188 *out = NULL;
1190 if (outer && !IsEqualGUID(iid, &IID_IUnknown))
1191 return E_NOINTERFACE;
1193 if (SUCCEEDED(hr = factory->create_instance(outer, &unk)))
1195 hr = IUnknown_QueryInterface(unk, iid, out);
1196 IUnknown_Release(unk);
1198 return hr;
1201 static HRESULT WINAPI class_factory_LockServer(IClassFactory *iface, BOOL lock)
1203 FIXME("lock %d, stub!\n", lock);
1204 return S_OK;
1207 static const IClassFactoryVtbl class_factory_vtbl =
1209 class_factory_QueryInterface,
1210 class_factory_AddRef,
1211 class_factory_Release,
1212 class_factory_CreateInstance,
1213 class_factory_LockServer,
1216 static struct
1218 const GUID *clsid;
1219 struct class_factory factory;
1221 class_factories[] =
1223 {&GUID_DSFX_STANDARD_I3DL2REVERB, {{&class_factory_vtbl}, reverb_create}},
1224 {&GUID_DSFX_STANDARD_PARAMEQ, {{&class_factory_vtbl}, eq_create}},
1225 {&GUID_DSFX_WAVES_REVERB, {{&class_factory_vtbl}, waves_reverb_create}},
1226 {&GUID_DSFX_STANDARD_ECHO, {{&class_factory_vtbl}, echo_create}},
1227 {&GUID_DSFX_STANDARD_COMPRESSOR, {{&class_factory_vtbl}, compressor_create}},
1230 HRESULT WINAPI DllGetClassObject(REFCLSID clsid, REFIID iid, void **out)
1232 unsigned int i;
1234 TRACE("clsid %s, iid %s, out %p.\n", debugstr_guid(clsid), debugstr_guid(iid), out);
1236 for (i = 0; i < ARRAY_SIZE(class_factories); ++i)
1238 if (IsEqualGUID(clsid, class_factories[i].clsid))
1239 return IClassFactory_QueryInterface(&class_factories[i].factory.IClassFactory_iface, iid, out);
1242 FIXME("%s not available, returning CLASS_E_CLASSNOTAVAILABLE.\n", debugstr_guid(clsid));
1243 return CLASS_E_CLASSNOTAVAILABLE;