2 * Copyright (c) 2015 Mark Harmstone
3 * Copyright (c) 2015 Andrew Eikum for CodeWeavers
4 * Copyright (c) 2018 Ethan Lee for CodeWeavers
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
23 #define NONAMELESSUNION
26 #include "xaudio_private.h"
27 #include "xaudio2fx.h"
30 #include "wine/debug.h"
31 #include "wine/heap.h"
37 WINE_DEFAULT_DEBUG_CHANNEL(xaudio2
);
39 static XA2XAPOFXImpl
*impl_from_IXAPO(IXAPO
*iface
)
41 return CONTAINING_RECORD(iface
, XA2XAPOFXImpl
, IXAPO_iface
);
44 static XA2XAPOFXImpl
*impl_from_IXAPOParameters(IXAPOParameters
*iface
)
46 return CONTAINING_RECORD(iface
, XA2XAPOFXImpl
, IXAPOParameters_iface
);
49 static HRESULT WINAPI
XAPOFX_QueryInterface(IXAPO
*iface
, REFIID riid
, void **ppvObject
)
51 XA2XAPOFXImpl
*This
= impl_from_IXAPO(iface
);
53 TRACE("%p, %s, %p\n", This
, wine_dbgstr_guid(riid
), ppvObject
);
55 if(IsEqualGUID(riid
, &IID_IUnknown
) ||
56 IsEqualGUID(riid
, &IID_IXAPO
) ||
57 IsEqualGUID(riid
, &IID_IXAPO27
))
58 *ppvObject
= &This
->IXAPO_iface
;
59 else if(IsEqualGUID(riid
, &IID_IXAPOParameters
) ||
60 IsEqualGUID(riid
, &IID_IXAPO27Parameters
))
61 *ppvObject
= &This
->IXAPOParameters_iface
;
66 IUnknown_AddRef((IUnknown
*)*ppvObject
);
73 static ULONG WINAPI
XAPOFX_AddRef(IXAPO
*iface
)
75 XA2XAPOFXImpl
*This
= impl_from_IXAPO(iface
);
76 ULONG ref
= This
->fapo
->AddRef(This
->fapo
);
77 TRACE("(%p)->(): Refcount now %u\n", This
, ref
);
81 static ULONG WINAPI
XAPOFX_Release(IXAPO
*iface
)
83 XA2XAPOFXImpl
*This
= impl_from_IXAPO(iface
);
84 ULONG ref
= This
->fapo
->Release(This
->fapo
);
86 TRACE("(%p)->(): Refcount now %u\n", This
, ref
);
89 HeapFree(GetProcessHeap(), 0, This
);
94 static HRESULT WINAPI
XAPOFX_GetRegistrationProperties(IXAPO
*iface
,
95 XAPO_REGISTRATION_PROPERTIES
**props
)
97 XA2XAPOFXImpl
*This
= impl_from_IXAPO(iface
);
99 FAPORegistrationProperties
*fprops
;
101 TRACE("%p, %p\n", This
, props
);
103 hr
= This
->fapo
->GetRegistrationProperties(This
->fapo
, &fprops
);
107 /* TODO: check for version == 20 and use XAPO20_REGISTRATION_PROPERTIES */
108 *props
= (XAPO_REGISTRATION_PROPERTIES
*) fprops
;
112 static HRESULT WINAPI
XAPOFX_IsInputFormatSupported(IXAPO
*iface
,
113 const WAVEFORMATEX
*output_fmt
, const WAVEFORMATEX
*input_fmt
,
114 WAVEFORMATEX
**supported_fmt
)
116 XA2XAPOFXImpl
*This
= impl_from_IXAPO(iface
);
117 TRACE("%p, %p, %p, %p\n", This
, output_fmt
, input_fmt
, supported_fmt
);
118 return This
->fapo
->IsInputFormatSupported(This
->fapo
,
119 (const FAudioWaveFormatEx
*)output_fmt
,
120 (const FAudioWaveFormatEx
*)input_fmt
,
121 (FAudioWaveFormatEx
**)supported_fmt
);
124 static HRESULT WINAPI
XAPOFX_IsOutputFormatSupported(IXAPO
*iface
,
125 const WAVEFORMATEX
*input_fmt
, const WAVEFORMATEX
*output_fmt
,
126 WAVEFORMATEX
**supported_fmt
)
128 XA2XAPOFXImpl
*This
= impl_from_IXAPO(iface
);
129 TRACE("%p, %p, %p, %p\n", This
, input_fmt
, output_fmt
, supported_fmt
);
130 return This
->fapo
->IsOutputFormatSupported(This
->fapo
,
131 (const FAudioWaveFormatEx
*)input_fmt
,
132 (const FAudioWaveFormatEx
*)output_fmt
,
133 (FAudioWaveFormatEx
**)supported_fmt
);
136 static HRESULT WINAPI
XAPOFX_Initialize(IXAPO
*iface
, const void *data
,
139 XA2XAPOFXImpl
*This
= impl_from_IXAPO(iface
);
140 TRACE("%p, %p, %u\n", This
, data
, data_len
);
141 return This
->fapo
->Initialize(This
->fapo
, data
, data_len
);
144 static void WINAPI
XAPOFX_Reset(IXAPO
*iface
)
146 XA2XAPOFXImpl
*This
= impl_from_IXAPO(iface
);
148 This
->fapo
->Reset(This
->fapo
);
151 static HRESULT WINAPI
XAPOFX_LockForProcess(IXAPO
*iface
, UINT32 in_params_count
,
152 const XAPO_LOCKFORPROCESS_BUFFER_PARAMETERS
*in_params
,
153 UINT32 out_params_count
,
154 const XAPO_LOCKFORPROCESS_BUFFER_PARAMETERS
*out_params
)
156 XA2XAPOFXImpl
*This
= impl_from_IXAPO(iface
);
157 TRACE("%p, %u, %p, %u, %p\n", This
, in_params_count
, in_params
,
158 out_params_count
, out_params
);
159 return This
->fapo
->LockForProcess(This
->fapo
,
161 (const FAPOLockForProcessBufferParameters
*)in_params
,
163 (const FAPOLockForProcessBufferParameters
*)out_params
);
166 static void WINAPI
XAPOFX_UnlockForProcess(IXAPO
*iface
)
168 XA2XAPOFXImpl
*This
= impl_from_IXAPO(iface
);
170 This
->fapo
->UnlockForProcess(This
->fapo
);
173 static void WINAPI
XAPOFX_Process(IXAPO
*iface
, UINT32 in_params_count
,
174 const XAPO_PROCESS_BUFFER_PARAMETERS
*in_params
,
175 UINT32 out_params_count
,
176 XAPO_PROCESS_BUFFER_PARAMETERS
*out_params
, BOOL enabled
)
178 XA2XAPOFXImpl
*This
= impl_from_IXAPO(iface
);
179 TRACE("%p, %u, %p, %u, %p, %u\n", This
, in_params_count
, in_params
,
180 out_params_count
, out_params
, enabled
);
181 This
->fapo
->Process(This
->fapo
, in_params_count
,
182 (const FAPOProcessBufferParameters
*)in_params
, out_params_count
,
183 (FAPOProcessBufferParameters
*)out_params
, enabled
);
186 static UINT32 WINAPI
XAPOFX_CalcInputFrames(IXAPO
*iface
, UINT32 output_frames
)
188 XA2XAPOFXImpl
*This
= impl_from_IXAPO(iface
);
189 TRACE("%p, %u\n", This
, output_frames
);
193 static UINT32 WINAPI
XAPOFX_CalcOutputFrames(IXAPO
*iface
, UINT32 input_frames
)
195 XA2XAPOFXImpl
*This
= impl_from_IXAPO(iface
);
196 TRACE("%p, %u\n", This
, input_frames
);
200 static const IXAPOVtbl XAPOFX_Vtbl
= {
201 XAPOFX_QueryInterface
,
204 XAPOFX_GetRegistrationProperties
,
205 XAPOFX_IsInputFormatSupported
,
206 XAPOFX_IsOutputFormatSupported
,
209 XAPOFX_LockForProcess
,
210 XAPOFX_UnlockForProcess
,
212 XAPOFX_CalcInputFrames
,
213 XAPOFX_CalcOutputFrames
216 static HRESULT WINAPI
XAPOFXParams_QueryInterface(IXAPOParameters
*iface
,
217 REFIID riid
, void **ppvObject
)
219 XA2XAPOFXImpl
*This
= impl_from_IXAPOParameters(iface
);
220 return XAPOFX_QueryInterface(&This
->IXAPO_iface
, riid
, ppvObject
);
223 static ULONG WINAPI
XAPOFXParams_AddRef(IXAPOParameters
*iface
)
225 XA2XAPOFXImpl
*This
= impl_from_IXAPOParameters(iface
);
226 return XAPOFX_AddRef(&This
->IXAPO_iface
);
229 static ULONG WINAPI
XAPOFXParams_Release(IXAPOParameters
*iface
)
231 XA2XAPOFXImpl
*This
= impl_from_IXAPOParameters(iface
);
232 return XAPOFX_Release(&This
->IXAPO_iface
);
235 static void WINAPI
XAPOFXParams_SetParameters(IXAPOParameters
*iface
,
236 const void *params
, UINT32 params_len
)
238 XA2XAPOFXImpl
*This
= impl_from_IXAPOParameters(iface
);
239 TRACE("%p, %p, %u\n", This
, params
, params_len
);
240 This
->fapo
->SetParameters(This
->fapo
, params
, params_len
);
243 static void WINAPI
XAPOFXParams_GetParameters(IXAPOParameters
*iface
, void *params
,
246 XA2XAPOFXImpl
*This
= impl_from_IXAPOParameters(iface
);
247 TRACE("%p, %p, %u\n", This
, params
, params_len
);
248 This
->fapo
->GetParameters(This
->fapo
, params
, params_len
);
251 static const IXAPOParametersVtbl XAPOFXParameters_Vtbl
= {
252 XAPOFXParams_QueryInterface
,
254 XAPOFXParams_Release
,
255 XAPOFXParams_SetParameters
,
256 XAPOFXParams_GetParameters
260 IClassFactory IClassFactory_iface
;
265 static struct xapo_cf
*xapo_impl_from_IClassFactory(IClassFactory
*iface
)
267 return CONTAINING_RECORD(iface
, struct xapo_cf
, IClassFactory_iface
);
270 static HRESULT WINAPI
xapocf_QueryInterface(IClassFactory
*iface
, REFIID riid
, void **ppobj
)
272 if(IsEqualGUID(riid
, &IID_IUnknown
)
273 || IsEqualGUID(riid
, &IID_IClassFactory
))
275 IClassFactory_AddRef(iface
);
281 WARN("(%p)->(%s, %p): interface not found\n", iface
, debugstr_guid(riid
), ppobj
);
282 return E_NOINTERFACE
;
285 static ULONG WINAPI
xapocf_AddRef(IClassFactory
*iface
)
287 struct xapo_cf
*This
= xapo_impl_from_IClassFactory(iface
);
288 ULONG ref
= InterlockedIncrement(&This
->ref
);
289 TRACE("(%p)->(): Refcount now %u\n", This
, ref
);
293 static ULONG WINAPI
xapocf_Release(IClassFactory
*iface
)
295 struct xapo_cf
*This
= xapo_impl_from_IClassFactory(iface
);
296 ULONG ref
= InterlockedDecrement(&This
->ref
);
297 TRACE("(%p)->(): Refcount now %u\n", This
, ref
);
299 HeapFree(GetProcessHeap(), 0, This
);
303 static inline HRESULT
get_fapo_from_clsid(REFCLSID clsid
, FAPO
**fapo
)
306 if(IsEqualGUID(clsid
, &CLSID_AudioVolumeMeter27
))
307 return FAudioCreateVolumeMeterWithCustomAllocatorEXT(
310 XAudio_Internal_Malloc
,
311 XAudio_Internal_Free
,
312 XAudio_Internal_Realloc
315 if(IsEqualGUID(clsid
, &CLSID_AudioReverb27
))
316 return FAudioCreateReverb9WithCustomAllocatorEXT(
319 XAudio_Internal_Malloc
,
320 XAudio_Internal_Free
,
321 XAudio_Internal_Realloc
324 if(IsEqualGUID(clsid
, &CLSID_AudioReverb27
))
325 return FAudioCreateReverbWithCustomAllocatorEXT(
328 XAudio_Internal_Malloc
,
329 XAudio_Internal_Free
,
330 XAudio_Internal_Realloc
334 #if XAUDIO2_VER >= 8 || defined XAPOFX1_VER
335 if(IsEqualGUID(clsid
, &CLSID_FXReverb
) ||
336 IsEqualGUID(clsid
, &CLSID_FXEQ
) ||
337 IsEqualGUID(clsid
, &CLSID_FXEcho
) ||
338 IsEqualGUID(clsid
, &CLSID_FXMasteringLimiter
))
339 return FAPOFX_CreateFXWithCustomAllocatorEXT(
340 (const FAudioGUID
*) clsid
,
344 XAudio_Internal_Malloc
,
345 XAudio_Internal_Free
,
346 XAudio_Internal_Realloc
349 ERR("Invalid XAPO CLSID!\n");
353 static HRESULT WINAPI
xapocf_CreateInstance(IClassFactory
*iface
, IUnknown
*pOuter
,
354 REFIID riid
, void **ppobj
)
356 struct xapo_cf
*This
= xapo_impl_from_IClassFactory(iface
);
358 XA2XAPOFXImpl
*object
;
360 TRACE("(%p)->(%p,%s,%p)\n", This
, pOuter
, debugstr_guid(riid
), ppobj
);
365 return CLASS_E_NOAGGREGATION
;
367 object
= heap_alloc(sizeof(*object
));
368 object
->IXAPO_iface
.lpVtbl
= &XAPOFX_Vtbl
;
369 object
->IXAPOParameters_iface
.lpVtbl
= &XAPOFXParameters_Vtbl
;
371 hr
= get_fapo_from_clsid(This
->class, &object
->fapo
);
374 HeapFree(GetProcessHeap(), 0, object
);
378 hr
= IXAPO_QueryInterface(&object
->IXAPO_iface
, riid
, ppobj
);
379 IXAPO_Release(&object
->IXAPO_iface
);
384 static HRESULT WINAPI
xapocf_LockServer(IClassFactory
*iface
, BOOL dolock
)
386 struct xapo_cf
*This
= xapo_impl_from_IClassFactory(iface
);
387 FIXME("(%p)->(%d): stub!\n", This
, dolock
);
391 static const IClassFactoryVtbl xapo_Vtbl
=
393 xapocf_QueryInterface
,
396 xapocf_CreateInstance
,
400 HRESULT
make_xapo_factory(REFCLSID clsid
, REFIID riid
, void **ppv
)
403 struct xapo_cf
*ret
= HeapAlloc(GetProcessHeap(), 0, sizeof(struct xapo_cf
));
404 ret
->IClassFactory_iface
.lpVtbl
= &xapo_Vtbl
;
407 hr
= IClassFactory_QueryInterface(&ret
->IClassFactory_iface
, riid
, ppv
);
409 HeapFree(GetProcessHeap(), 0, ret
);