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 #include "xaudio_private.h"
28 #include "wine/debug.h"
34 WINE_DEFAULT_DEBUG_CHANNEL(xaudio2
);
36 static XA2XAPOFXImpl
*impl_from_IXAPO(IXAPO
*iface
)
38 return CONTAINING_RECORD(iface
, XA2XAPOFXImpl
, IXAPO_iface
);
41 static XA2XAPOFXImpl
*impl_from_IXAPOParameters(IXAPOParameters
*iface
)
43 return CONTAINING_RECORD(iface
, XA2XAPOFXImpl
, IXAPOParameters_iface
);
46 static HRESULT WINAPI
XAPOFX_QueryInterface(IXAPO
*iface
, REFIID riid
, void **ppvObject
)
48 XA2XAPOFXImpl
*This
= impl_from_IXAPO(iface
);
50 TRACE("%p, %s, %p\n", This
, wine_dbgstr_guid(riid
), ppvObject
);
52 if(IsEqualGUID(riid
, &IID_IUnknown
) ||
53 IsEqualGUID(riid
, &IID_IXAPO
) ||
54 IsEqualGUID(riid
, &IID_IXAPO27
))
55 *ppvObject
= &This
->IXAPO_iface
;
56 else if(IsEqualGUID(riid
, &IID_IXAPOParameters
) ||
57 IsEqualGUID(riid
, &IID_IXAPO27Parameters
))
58 *ppvObject
= &This
->IXAPOParameters_iface
;
63 IUnknown_AddRef((IUnknown
*)*ppvObject
);
70 static ULONG WINAPI
XAPOFX_AddRef(IXAPO
*iface
)
72 XA2XAPOFXImpl
*This
= impl_from_IXAPO(iface
);
73 ULONG ref
= This
->fapo
->AddRef(This
->fapo
);
74 TRACE("(%p)->(): Refcount now %lu\n", This
, ref
);
78 static ULONG WINAPI
XAPOFX_Release(IXAPO
*iface
)
80 XA2XAPOFXImpl
*This
= impl_from_IXAPO(iface
);
81 ULONG ref
= This
->fapo
->Release(This
->fapo
);
83 TRACE("(%p)->(): Refcount now %lu\n", This
, ref
);
91 static HRESULT WINAPI
XAPOFX_GetRegistrationProperties(IXAPO
*iface
,
92 XAPO_REGISTRATION_PROPERTIES
**props
)
94 XA2XAPOFXImpl
*This
= impl_from_IXAPO(iface
);
96 FAPORegistrationProperties
*fprops
;
98 TRACE("%p, %p\n", This
, props
);
100 hr
= This
->fapo
->GetRegistrationProperties(This
->fapo
, &fprops
);
104 /* TODO: check for version == 20 and use XAPO20_REGISTRATION_PROPERTIES */
105 *props
= (XAPO_REGISTRATION_PROPERTIES
*) fprops
;
109 static HRESULT WINAPI
XAPOFX_IsInputFormatSupported(IXAPO
*iface
,
110 const WAVEFORMATEX
*output_fmt
, const WAVEFORMATEX
*input_fmt
,
111 WAVEFORMATEX
**supported_fmt
)
113 XA2XAPOFXImpl
*This
= impl_from_IXAPO(iface
);
114 TRACE("%p, %p, %p, %p\n", This
, output_fmt
, input_fmt
, supported_fmt
);
115 return This
->fapo
->IsInputFormatSupported(This
->fapo
,
116 (const FAudioWaveFormatEx
*)output_fmt
,
117 (const FAudioWaveFormatEx
*)input_fmt
,
118 (FAudioWaveFormatEx
**)supported_fmt
);
121 static HRESULT WINAPI
XAPOFX_IsOutputFormatSupported(IXAPO
*iface
,
122 const WAVEFORMATEX
*input_fmt
, const WAVEFORMATEX
*output_fmt
,
123 WAVEFORMATEX
**supported_fmt
)
125 XA2XAPOFXImpl
*This
= impl_from_IXAPO(iface
);
126 TRACE("%p, %p, %p, %p\n", This
, input_fmt
, output_fmt
, supported_fmt
);
127 return This
->fapo
->IsOutputFormatSupported(This
->fapo
,
128 (const FAudioWaveFormatEx
*)input_fmt
,
129 (const FAudioWaveFormatEx
*)output_fmt
,
130 (FAudioWaveFormatEx
**)supported_fmt
);
133 static HRESULT WINAPI
XAPOFX_Initialize(IXAPO
*iface
, const void *data
,
136 XA2XAPOFXImpl
*This
= impl_from_IXAPO(iface
);
137 TRACE("%p, %p, %u\n", This
, data
, data_len
);
138 return This
->fapo
->Initialize(This
->fapo
, data
, data_len
);
141 static void WINAPI
XAPOFX_Reset(IXAPO
*iface
)
143 XA2XAPOFXImpl
*This
= impl_from_IXAPO(iface
);
145 This
->fapo
->Reset(This
->fapo
);
148 static HRESULT WINAPI
XAPOFX_LockForProcess(IXAPO
*iface
, UINT32 in_params_count
,
149 const XAPO_LOCKFORPROCESS_BUFFER_PARAMETERS
*in_params
,
150 UINT32 out_params_count
,
151 const XAPO_LOCKFORPROCESS_BUFFER_PARAMETERS
*out_params
)
153 XA2XAPOFXImpl
*This
= impl_from_IXAPO(iface
);
154 TRACE("%p, %u, %p, %u, %p\n", This
, in_params_count
, in_params
,
155 out_params_count
, out_params
);
156 return This
->fapo
->LockForProcess(This
->fapo
,
158 (const FAPOLockForProcessBufferParameters
*)in_params
,
160 (const FAPOLockForProcessBufferParameters
*)out_params
);
163 static void WINAPI
XAPOFX_UnlockForProcess(IXAPO
*iface
)
165 XA2XAPOFXImpl
*This
= impl_from_IXAPO(iface
);
167 This
->fapo
->UnlockForProcess(This
->fapo
);
170 static void WINAPI
XAPOFX_Process(IXAPO
*iface
, UINT32 in_params_count
,
171 const XAPO_PROCESS_BUFFER_PARAMETERS
*in_params
,
172 UINT32 out_params_count
,
173 XAPO_PROCESS_BUFFER_PARAMETERS
*out_params
, BOOL enabled
)
175 XA2XAPOFXImpl
*This
= impl_from_IXAPO(iface
);
176 TRACE("%p, %u, %p, %u, %p, %u\n", This
, in_params_count
, in_params
,
177 out_params_count
, out_params
, enabled
);
178 This
->fapo
->Process(This
->fapo
, in_params_count
,
179 (const FAPOProcessBufferParameters
*)in_params
, out_params_count
,
180 (FAPOProcessBufferParameters
*)out_params
, enabled
);
183 static UINT32 WINAPI
XAPOFX_CalcInputFrames(IXAPO
*iface
, UINT32 output_frames
)
185 XA2XAPOFXImpl
*This
= impl_from_IXAPO(iface
);
186 TRACE("%p, %u\n", This
, output_frames
);
190 static UINT32 WINAPI
XAPOFX_CalcOutputFrames(IXAPO
*iface
, UINT32 input_frames
)
192 XA2XAPOFXImpl
*This
= impl_from_IXAPO(iface
);
193 TRACE("%p, %u\n", This
, input_frames
);
197 static const IXAPOVtbl XAPOFX_Vtbl
= {
198 XAPOFX_QueryInterface
,
201 XAPOFX_GetRegistrationProperties
,
202 XAPOFX_IsInputFormatSupported
,
203 XAPOFX_IsOutputFormatSupported
,
206 XAPOFX_LockForProcess
,
207 XAPOFX_UnlockForProcess
,
209 XAPOFX_CalcInputFrames
,
210 XAPOFX_CalcOutputFrames
213 static HRESULT WINAPI
XAPOFXParams_QueryInterface(IXAPOParameters
*iface
,
214 REFIID riid
, void **ppvObject
)
216 XA2XAPOFXImpl
*This
= impl_from_IXAPOParameters(iface
);
217 return XAPOFX_QueryInterface(&This
->IXAPO_iface
, riid
, ppvObject
);
220 static ULONG WINAPI
XAPOFXParams_AddRef(IXAPOParameters
*iface
)
222 XA2XAPOFXImpl
*This
= impl_from_IXAPOParameters(iface
);
223 return XAPOFX_AddRef(&This
->IXAPO_iface
);
226 static ULONG WINAPI
XAPOFXParams_Release(IXAPOParameters
*iface
)
228 XA2XAPOFXImpl
*This
= impl_from_IXAPOParameters(iface
);
229 return XAPOFX_Release(&This
->IXAPO_iface
);
232 static void WINAPI
XAPOFXParams_SetParameters(IXAPOParameters
*iface
,
233 const void *params
, UINT32 params_len
)
235 XA2XAPOFXImpl
*This
= impl_from_IXAPOParameters(iface
);
236 TRACE("%p, %p, %u\n", This
, params
, params_len
);
237 This
->fapo
->SetParameters(This
->fapo
, params
, params_len
);
240 static void WINAPI
XAPOFXParams_GetParameters(IXAPOParameters
*iface
, void *params
,
243 XA2XAPOFXImpl
*This
= impl_from_IXAPOParameters(iface
);
244 TRACE("%p, %p, %u\n", This
, params
, params_len
);
245 This
->fapo
->GetParameters(This
->fapo
, params
, params_len
);
248 static const IXAPOParametersVtbl XAPOFXParameters_Vtbl
= {
249 XAPOFXParams_QueryInterface
,
251 XAPOFXParams_Release
,
252 XAPOFXParams_SetParameters
,
253 XAPOFXParams_GetParameters
256 static HRESULT
xapo_create(FAPO
*fapo
, XA2XAPOFXImpl
**out
)
258 XA2XAPOFXImpl
*object
;
260 if (!(object
= malloc(sizeof(*object
))))
261 return E_OUTOFMEMORY
;
263 object
->IXAPO_iface
.lpVtbl
= &XAPOFX_Vtbl
;
264 object
->IXAPOParameters_iface
.lpVtbl
= &XAPOFXParameters_Vtbl
;
272 static HRESULT
reverb_create(XA2XAPOFXImpl
**out
)
278 hr
= FAudioCreateReverb9WithCustomAllocatorEXT(&fapo
, 0,
279 XAudio_Internal_Malloc
, XAudio_Internal_Free
, XAudio_Internal_Realloc
);
281 hr
= FAudioCreateReverbWithCustomAllocatorEXT(&fapo
, 0,
282 XAudio_Internal_Malloc
, XAudio_Internal_Free
, XAudio_Internal_Realloc
);
287 if (FAILED(hr
= xapo_create(fapo
, out
)))
292 static HRESULT
volume_meter_create(XA2XAPOFXImpl
**out
)
297 if (FAILED(hr
= FAudioCreateVolumeMeterWithCustomAllocatorEXT(&fapo
, 0,
298 XAudio_Internal_Malloc
, XAudio_Internal_Free
, XAudio_Internal_Realloc
)))
301 if (FAILED(hr
= xapo_create(fapo
, out
)))
305 #endif /* XAPOFX1_VER */
308 IClassFactory IClassFactory_iface
;
313 static struct xapo_cf
*xapo_impl_from_IClassFactory(IClassFactory
*iface
)
315 return CONTAINING_RECORD(iface
, struct xapo_cf
, IClassFactory_iface
);
318 static HRESULT WINAPI
xapocf_QueryInterface(IClassFactory
*iface
, REFIID riid
, void **ppobj
)
320 if(IsEqualGUID(riid
, &IID_IUnknown
)
321 || IsEqualGUID(riid
, &IID_IClassFactory
))
323 IClassFactory_AddRef(iface
);
329 WARN("(%p)->(%s, %p): interface not found\n", iface
, debugstr_guid(riid
), ppobj
);
330 return E_NOINTERFACE
;
333 static ULONG WINAPI
xapocf_AddRef(IClassFactory
*iface
)
335 struct xapo_cf
*This
= xapo_impl_from_IClassFactory(iface
);
336 ULONG ref
= InterlockedIncrement(&This
->ref
);
337 TRACE("(%p)->(): Refcount now %lu\n", This
, ref
);
341 static ULONG WINAPI
xapocf_Release(IClassFactory
*iface
)
343 struct xapo_cf
*This
= xapo_impl_from_IClassFactory(iface
);
344 ULONG ref
= InterlockedDecrement(&This
->ref
);
345 TRACE("(%p)->(): Refcount now %lu\n", This
, ref
);
351 static HRESULT WINAPI
xapocf_CreateInstance(IClassFactory
*iface
, IUnknown
*pOuter
,
352 REFIID riid
, void **ppobj
)
354 struct xapo_cf
*This
= xapo_impl_from_IClassFactory(iface
);
356 XA2XAPOFXImpl
*object
;
358 TRACE("(%p)->(%p,%s,%p)\n", This
, pOuter
, debugstr_guid(riid
), ppobj
);
363 return CLASS_E_NOAGGREGATION
;
365 #if XAUDIO2_VER < 8 && !defined(XAPOFX1_VER)
366 if (IsEqualGUID(This
->class, &CLSID_AudioVolumeMeter
))
368 hr
= volume_meter_create(&object
);
370 else if (IsEqualGUID(This
->class, &CLSID_AudioReverb
))
372 hr
= reverb_create(&object
);
375 if (IsEqualGUID(This
->class, &CLSID_FXReverb
)
376 || IsEqualGUID(This
->class, &CLSID_FXEQ
)
377 || IsEqualGUID(This
->class, &CLSID_FXEcho
)
378 || IsEqualGUID(This
->class, &CLSID_FXMasteringLimiter
))
382 if (FAILED(hr
= FAPOFX_CreateFXWithCustomAllocatorEXT((const FAudioGUID
*)This
->class, &fapo
, NULL
,
383 0, XAudio_Internal_Malloc
, XAudio_Internal_Free
, XAudio_Internal_Realloc
)))
386 if (FAILED(hr
= xapo_create(fapo
, &object
)))
395 FIXME("Unknown CLSID %s.\n", debugstr_guid(This
->class));
402 hr
= IXAPO_QueryInterface(&object
->IXAPO_iface
, riid
, ppobj
);
403 IXAPO_Release(&object
->IXAPO_iface
);
408 static HRESULT WINAPI
xapocf_LockServer(IClassFactory
*iface
, BOOL dolock
)
410 struct xapo_cf
*This
= xapo_impl_from_IClassFactory(iface
);
411 FIXME("(%p)->(%d): stub!\n", This
, dolock
);
415 static const IClassFactoryVtbl xapo_Vtbl
=
417 xapocf_QueryInterface
,
420 xapocf_CreateInstance
,
424 HRESULT
make_xapo_factory(REFCLSID clsid
, REFIID riid
, void **ppv
)
427 struct xapo_cf
*ret
= malloc(sizeof(struct xapo_cf
));
428 ret
->IClassFactory_iface
.lpVtbl
= &xapo_Vtbl
;
431 hr
= IClassFactory_QueryInterface(&ret
->IClassFactory_iface
, riid
, ppv
);
438 HRESULT WINAPI
CreateAudioVolumeMeter(IUnknown
**out
)
440 XA2XAPOFXImpl
*object
;
445 if (SUCCEEDED(hr
= volume_meter_create(&object
)))
446 *out
= (IUnknown
*)&object
->IXAPO_iface
;
450 HRESULT WINAPI
CreateAudioReverb(IUnknown
**out
)
452 XA2XAPOFXImpl
*object
;
457 if (SUCCEEDED(hr
= reverb_create(&object
)))
458 *out
= (IUnknown
*)&object
->IXAPO_iface
;