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
25 #define NONAMELESSUNION
28 #include "xaudio_private.h"
29 #include "xaudio2fx.h"
32 #include "wine/debug.h"
33 #include "wine/heap.h"
39 WINE_DEFAULT_DEBUG_CHANNEL(xaudio2
);
41 static XA2XAPOFXImpl
*impl_from_IXAPO(IXAPO
*iface
)
43 return CONTAINING_RECORD(iface
, XA2XAPOFXImpl
, IXAPO_iface
);
46 static XA2XAPOFXImpl
*impl_from_IXAPOParameters(IXAPOParameters
*iface
)
48 return CONTAINING_RECORD(iface
, XA2XAPOFXImpl
, IXAPOParameters_iface
);
51 static HRESULT WINAPI
XAPOFX_QueryInterface(IXAPO
*iface
, REFIID riid
, void **ppvObject
)
53 XA2XAPOFXImpl
*This
= impl_from_IXAPO(iface
);
55 TRACE("%p, %s, %p\n", This
, wine_dbgstr_guid(riid
), ppvObject
);
57 if(IsEqualGUID(riid
, &IID_IUnknown
) ||
58 IsEqualGUID(riid
, &IID_IXAPO
) ||
59 IsEqualGUID(riid
, &IID_IXAPO27
))
60 *ppvObject
= &This
->IXAPO_iface
;
61 else if(IsEqualGUID(riid
, &IID_IXAPOParameters
) ||
62 IsEqualGUID(riid
, &IID_IXAPO27Parameters
))
63 *ppvObject
= &This
->IXAPOParameters_iface
;
68 IUnknown_AddRef((IUnknown
*)*ppvObject
);
75 static ULONG WINAPI
XAPOFX_AddRef(IXAPO
*iface
)
77 XA2XAPOFXImpl
*This
= impl_from_IXAPO(iface
);
78 ULONG ref
= This
->fapo
->AddRef(This
->fapo
);
79 TRACE("(%p)->(): Refcount now %u\n", This
, ref
);
83 static ULONG WINAPI
XAPOFX_Release(IXAPO
*iface
)
85 XA2XAPOFXImpl
*This
= impl_from_IXAPO(iface
);
86 ULONG ref
= This
->fapo
->Release(This
->fapo
);
88 TRACE("(%p)->(): Refcount now %u\n", This
, ref
);
91 HeapFree(GetProcessHeap(), 0, This
);
96 static HRESULT WINAPI
XAPOFX_GetRegistrationProperties(IXAPO
*iface
,
97 XAPO_REGISTRATION_PROPERTIES
**props
)
99 XA2XAPOFXImpl
*This
= impl_from_IXAPO(iface
);
101 FAPORegistrationProperties
*fprops
;
103 TRACE("%p, %p\n", This
, props
);
105 hr
= This
->fapo
->GetRegistrationProperties(This
->fapo
, &fprops
);
109 /* TODO: check for version == 20 and use XAPO20_REGISTRATION_PROPERTIES */
110 *props
= (XAPO_REGISTRATION_PROPERTIES
*) fprops
;
114 static HRESULT WINAPI
XAPOFX_IsInputFormatSupported(IXAPO
*iface
,
115 const WAVEFORMATEX
*output_fmt
, const WAVEFORMATEX
*input_fmt
,
116 WAVEFORMATEX
**supported_fmt
)
118 XA2XAPOFXImpl
*This
= impl_from_IXAPO(iface
);
119 TRACE("%p, %p, %p, %p\n", This
, output_fmt
, input_fmt
, supported_fmt
);
120 return This
->fapo
->IsInputFormatSupported(This
->fapo
,
121 (const FAudioWaveFormatEx
*)output_fmt
,
122 (const FAudioWaveFormatEx
*)input_fmt
,
123 (FAudioWaveFormatEx
**)supported_fmt
);
126 static HRESULT WINAPI
XAPOFX_IsOutputFormatSupported(IXAPO
*iface
,
127 const WAVEFORMATEX
*input_fmt
, const WAVEFORMATEX
*output_fmt
,
128 WAVEFORMATEX
**supported_fmt
)
130 XA2XAPOFXImpl
*This
= impl_from_IXAPO(iface
);
131 TRACE("%p, %p, %p, %p\n", This
, input_fmt
, output_fmt
, supported_fmt
);
132 return This
->fapo
->IsOutputFormatSupported(This
->fapo
,
133 (const FAudioWaveFormatEx
*)input_fmt
,
134 (const FAudioWaveFormatEx
*)output_fmt
,
135 (FAudioWaveFormatEx
**)supported_fmt
);
138 static HRESULT WINAPI
XAPOFX_Initialize(IXAPO
*iface
, const void *data
,
141 XA2XAPOFXImpl
*This
= impl_from_IXAPO(iface
);
142 TRACE("%p, %p, %u\n", This
, data
, data_len
);
143 return This
->fapo
->Initialize(This
->fapo
, data
, data_len
);
146 static void WINAPI
XAPOFX_Reset(IXAPO
*iface
)
148 XA2XAPOFXImpl
*This
= impl_from_IXAPO(iface
);
150 This
->fapo
->Reset(This
->fapo
);
153 static HRESULT WINAPI
XAPOFX_LockForProcess(IXAPO
*iface
, UINT32 in_params_count
,
154 const XAPO_LOCKFORPROCESS_BUFFER_PARAMETERS
*in_params
,
155 UINT32 out_params_count
,
156 const XAPO_LOCKFORPROCESS_BUFFER_PARAMETERS
*out_params
)
158 XA2XAPOFXImpl
*This
= impl_from_IXAPO(iface
);
159 TRACE("%p, %u, %p, %u, %p\n", This
, in_params_count
, in_params
,
160 out_params_count
, out_params
);
161 return This
->fapo
->LockForProcess(This
->fapo
,
163 (const FAPOLockForProcessBufferParameters
*)in_params
,
165 (const FAPOLockForProcessBufferParameters
*)out_params
);
168 static void WINAPI
XAPOFX_UnlockForProcess(IXAPO
*iface
)
170 XA2XAPOFXImpl
*This
= impl_from_IXAPO(iface
);
172 This
->fapo
->UnlockForProcess(This
->fapo
);
175 static void WINAPI
XAPOFX_Process(IXAPO
*iface
, UINT32 in_params_count
,
176 const XAPO_PROCESS_BUFFER_PARAMETERS
*in_params
,
177 UINT32 out_params_count
,
178 XAPO_PROCESS_BUFFER_PARAMETERS
*out_params
, BOOL enabled
)
180 XA2XAPOFXImpl
*This
= impl_from_IXAPO(iface
);
181 TRACE("%p, %u, %p, %u, %p, %u\n", This
, in_params_count
, in_params
,
182 out_params_count
, out_params
, enabled
);
183 This
->fapo
->Process(This
->fapo
, in_params_count
,
184 (const FAPOProcessBufferParameters
*)in_params
, out_params_count
,
185 (FAPOProcessBufferParameters
*)out_params
, enabled
);
188 static UINT32 WINAPI
XAPOFX_CalcInputFrames(IXAPO
*iface
, UINT32 output_frames
)
190 XA2XAPOFXImpl
*This
= impl_from_IXAPO(iface
);
191 TRACE("%p, %u\n", This
, output_frames
);
195 static UINT32 WINAPI
XAPOFX_CalcOutputFrames(IXAPO
*iface
, UINT32 input_frames
)
197 XA2XAPOFXImpl
*This
= impl_from_IXAPO(iface
);
198 TRACE("%p, %u\n", This
, input_frames
);
202 static const IXAPOVtbl XAPOFX_Vtbl
= {
203 XAPOFX_QueryInterface
,
206 XAPOFX_GetRegistrationProperties
,
207 XAPOFX_IsInputFormatSupported
,
208 XAPOFX_IsOutputFormatSupported
,
211 XAPOFX_LockForProcess
,
212 XAPOFX_UnlockForProcess
,
214 XAPOFX_CalcInputFrames
,
215 XAPOFX_CalcOutputFrames
218 static HRESULT WINAPI
XAPOFXParams_QueryInterface(IXAPOParameters
*iface
,
219 REFIID riid
, void **ppvObject
)
221 XA2XAPOFXImpl
*This
= impl_from_IXAPOParameters(iface
);
222 return XAPOFX_QueryInterface(&This
->IXAPO_iface
, riid
, ppvObject
);
225 static ULONG WINAPI
XAPOFXParams_AddRef(IXAPOParameters
*iface
)
227 XA2XAPOFXImpl
*This
= impl_from_IXAPOParameters(iface
);
228 return XAPOFX_AddRef(&This
->IXAPO_iface
);
231 static ULONG WINAPI
XAPOFXParams_Release(IXAPOParameters
*iface
)
233 XA2XAPOFXImpl
*This
= impl_from_IXAPOParameters(iface
);
234 return XAPOFX_Release(&This
->IXAPO_iface
);
237 static void WINAPI
XAPOFXParams_SetParameters(IXAPOParameters
*iface
,
238 const void *params
, UINT32 params_len
)
240 XA2XAPOFXImpl
*This
= impl_from_IXAPOParameters(iface
);
241 TRACE("%p, %p, %u\n", This
, params
, params_len
);
242 This
->fapo
->SetParameters(This
->fapo
, params
, params_len
);
245 static void WINAPI
XAPOFXParams_GetParameters(IXAPOParameters
*iface
, void *params
,
248 XA2XAPOFXImpl
*This
= impl_from_IXAPOParameters(iface
);
249 TRACE("%p, %p, %u\n", This
, params
, params_len
);
250 This
->fapo
->GetParameters(This
->fapo
, params
, params_len
);
253 static const IXAPOParametersVtbl XAPOFXParameters_Vtbl
= {
254 XAPOFXParams_QueryInterface
,
256 XAPOFXParams_Release
,
257 XAPOFXParams_SetParameters
,
258 XAPOFXParams_GetParameters
262 IClassFactory IClassFactory_iface
;
267 static struct xapo_cf
*xapo_impl_from_IClassFactory(IClassFactory
*iface
)
269 return CONTAINING_RECORD(iface
, struct xapo_cf
, IClassFactory_iface
);
272 static HRESULT WINAPI
xapocf_QueryInterface(IClassFactory
*iface
, REFIID riid
, void **ppobj
)
274 if(IsEqualGUID(riid
, &IID_IUnknown
)
275 || IsEqualGUID(riid
, &IID_IClassFactory
))
277 IClassFactory_AddRef(iface
);
283 WARN("(%p)->(%s, %p): interface not found\n", iface
, debugstr_guid(riid
), ppobj
);
284 return E_NOINTERFACE
;
287 static ULONG WINAPI
xapocf_AddRef(IClassFactory
*iface
)
289 struct xapo_cf
*This
= xapo_impl_from_IClassFactory(iface
);
290 ULONG ref
= InterlockedIncrement(&This
->ref
);
291 TRACE("(%p)->(): Refcount now %u\n", This
, ref
);
295 static ULONG WINAPI
xapocf_Release(IClassFactory
*iface
)
297 struct xapo_cf
*This
= xapo_impl_from_IClassFactory(iface
);
298 ULONG ref
= InterlockedDecrement(&This
->ref
);
299 TRACE("(%p)->(): Refcount now %u\n", This
, ref
);
301 HeapFree(GetProcessHeap(), 0, This
);
305 static inline HRESULT
get_fapo_from_clsid(REFCLSID clsid
, FAPO
**fapo
)
308 if(IsEqualGUID(clsid
, &CLSID_AudioVolumeMeter27
))
309 return FAudioCreateVolumeMeterWithCustomAllocatorEXT(
312 XAudio_Internal_Malloc
,
313 XAudio_Internal_Free
,
314 XAudio_Internal_Realloc
316 #if XAUDIO2_VER >= 9 && HAVE_FAUDIOCREATEREVERB9WITHCUSTOMALLOCATOREXT
317 if(IsEqualGUID(clsid
, &CLSID_AudioReverb27
))
318 return FAudioCreateReverb9WithCustomAllocatorEXT(
321 XAudio_Internal_Malloc
,
322 XAudio_Internal_Free
,
323 XAudio_Internal_Realloc
326 if(IsEqualGUID(clsid
, &CLSID_AudioReverb27
))
327 return FAudioCreateReverbWithCustomAllocatorEXT(
330 XAudio_Internal_Malloc
,
331 XAudio_Internal_Free
,
332 XAudio_Internal_Realloc
336 #if XAUDIO2_VER >= 8 || defined XAPOFX1_VER
337 if(IsEqualGUID(clsid
, &CLSID_FXReverb
) ||
338 IsEqualGUID(clsid
, &CLSID_FXEQ
) ||
339 IsEqualGUID(clsid
, &CLSID_FXEcho
) ||
340 IsEqualGUID(clsid
, &CLSID_FXMasteringLimiter
))
341 return FAPOFX_CreateFXWithCustomAllocatorEXT(
342 (const FAudioGUID
*) clsid
,
346 XAudio_Internal_Malloc
,
347 XAudio_Internal_Free
,
348 XAudio_Internal_Realloc
351 ERR("Invalid XAPO CLSID!\n");
355 static HRESULT WINAPI
xapocf_CreateInstance(IClassFactory
*iface
, IUnknown
*pOuter
,
356 REFIID riid
, void **ppobj
)
358 struct xapo_cf
*This
= xapo_impl_from_IClassFactory(iface
);
360 XA2XAPOFXImpl
*object
;
362 TRACE("(%p)->(%p,%s,%p)\n", This
, pOuter
, debugstr_guid(riid
), ppobj
);
367 return CLASS_E_NOAGGREGATION
;
369 object
= heap_alloc(sizeof(*object
));
370 object
->IXAPO_iface
.lpVtbl
= &XAPOFX_Vtbl
;
371 object
->IXAPOParameters_iface
.lpVtbl
= &XAPOFXParameters_Vtbl
;
373 hr
= get_fapo_from_clsid(This
->class, &object
->fapo
);
376 HeapFree(GetProcessHeap(), 0, object
);
380 hr
= IXAPO_QueryInterface(&object
->IXAPO_iface
, riid
, ppobj
);
381 IXAPO_Release(&object
->IXAPO_iface
);
386 static HRESULT WINAPI
xapocf_LockServer(IClassFactory
*iface
, BOOL dolock
)
388 struct xapo_cf
*This
= xapo_impl_from_IClassFactory(iface
);
389 FIXME("(%p)->(%d): stub!\n", This
, dolock
);
393 static const IClassFactoryVtbl xapo_Vtbl
=
395 xapocf_QueryInterface
,
398 xapocf_CreateInstance
,
402 HRESULT
make_xapo_factory(REFCLSID clsid
, REFIID riid
, void **ppv
)
405 struct xapo_cf
*ret
= HeapAlloc(GetProcessHeap(), 0, sizeof(struct xapo_cf
));
406 ret
->IClassFactory_iface
.lpVtbl
= &xapo_Vtbl
;
409 hr
= IClassFactory_QueryInterface(&ret
->IClassFactory_iface
, riid
, ppv
);
411 HeapFree(GetProcessHeap(), 0, ret
);