winepulse: Set pulse master volume to 0 when session is muted.
[wine.git] / dlls / xaudio2_7 / xapo.c
blobe47442959d35929f027e2e43a8ac3ba9fd32ea68
1 /*
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
21 #include "config.h"
23 #include <stdarg.h>
25 #define NONAMELESSUNION
26 #define COBJMACROS
28 #include "xaudio_private.h"
29 #include "xaudio2fx.h"
30 #include "xapofx.h"
32 #include "wine/debug.h"
33 #include "wine/heap.h"
35 #include <FAPO.h>
36 #include <FAPOFX.h>
37 #include <FAudioFX.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;
64 else
65 *ppvObject = NULL;
67 if(*ppvObject){
68 IUnknown_AddRef((IUnknown*)*ppvObject);
69 return S_OK;
72 return E_NOINTERFACE;
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);
80 return 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);
90 if(!ref)
91 HeapFree(GetProcessHeap(), 0, This);
93 return ref;
96 static HRESULT WINAPI XAPOFX_GetRegistrationProperties(IXAPO *iface,
97 XAPO_REGISTRATION_PROPERTIES **props)
99 XA2XAPOFXImpl *This = impl_from_IXAPO(iface);
100 HRESULT hr;
101 FAPORegistrationProperties *fprops;
103 TRACE("%p, %p\n", This, props);
105 hr = This->fapo->GetRegistrationProperties(This->fapo, &fprops);
106 if(FAILED(hr))
107 return hr;
109 /* TODO: check for version == 20 and use XAPO20_REGISTRATION_PROPERTIES */
110 *props = (XAPO_REGISTRATION_PROPERTIES*) fprops;
111 return hr;
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,
139 UINT32 data_len)
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);
149 TRACE("%p\n", This);
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,
162 in_params_count,
163 (const FAPOLockForProcessBufferParameters *)in_params,
164 out_params_count,
165 (const FAPOLockForProcessBufferParameters *)out_params);
168 static void WINAPI XAPOFX_UnlockForProcess(IXAPO *iface)
170 XA2XAPOFXImpl *This = impl_from_IXAPO(iface);
171 TRACE("%p\n", This);
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);
192 return 0;
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);
199 return 0;
202 static const IXAPOVtbl XAPOFX_Vtbl = {
203 XAPOFX_QueryInterface,
204 XAPOFX_AddRef,
205 XAPOFX_Release,
206 XAPOFX_GetRegistrationProperties,
207 XAPOFX_IsInputFormatSupported,
208 XAPOFX_IsOutputFormatSupported,
209 XAPOFX_Initialize,
210 XAPOFX_Reset,
211 XAPOFX_LockForProcess,
212 XAPOFX_UnlockForProcess,
213 XAPOFX_Process,
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,
246 UINT32 params_len)
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,
255 XAPOFXParams_AddRef,
256 XAPOFXParams_Release,
257 XAPOFXParams_SetParameters,
258 XAPOFXParams_GetParameters
261 struct xapo_cf {
262 IClassFactory IClassFactory_iface;
263 LONG ref;
264 const CLSID *class;
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);
278 *ppobj = iface;
279 return S_OK;
282 *ppobj = NULL;
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);
292 return 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);
300 if (!ref)
301 HeapFree(GetProcessHeap(), 0, This);
302 return ref;
305 static inline HRESULT get_fapo_from_clsid(REFCLSID clsid, FAPO **fapo)
307 #ifndef XAPOFX1_VER
308 if(IsEqualGUID(clsid, &CLSID_AudioVolumeMeter27))
309 return FAudioCreateVolumeMeterWithCustomAllocatorEXT(
310 fapo,
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(
319 fapo,
321 XAudio_Internal_Malloc,
322 XAudio_Internal_Free,
323 XAudio_Internal_Realloc
325 #else
326 if(IsEqualGUID(clsid, &CLSID_AudioReverb27))
327 return FAudioCreateReverbWithCustomAllocatorEXT(
328 fapo,
330 XAudio_Internal_Malloc,
331 XAudio_Internal_Free,
332 XAudio_Internal_Realloc
334 #endif
335 #endif
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,
343 fapo,
344 NULL,
346 XAudio_Internal_Malloc,
347 XAudio_Internal_Free,
348 XAudio_Internal_Realloc
350 #endif
351 ERR("Invalid XAPO CLSID!\n");
352 return E_INVALIDARG;
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);
359 HRESULT hr;
360 XA2XAPOFXImpl *object;
362 TRACE("(%p)->(%p,%s,%p)\n", This, pOuter, debugstr_guid(riid), ppobj);
364 *ppobj = NULL;
366 if(pOuter)
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);
375 if(FAILED(hr)){
376 HeapFree(GetProcessHeap(), 0, object);
377 return hr;
380 hr = IXAPO_QueryInterface(&object->IXAPO_iface, riid, ppobj);
381 IXAPO_Release(&object->IXAPO_iface);
383 return hr;
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);
390 return S_OK;
393 static const IClassFactoryVtbl xapo_Vtbl =
395 xapocf_QueryInterface,
396 xapocf_AddRef,
397 xapocf_Release,
398 xapocf_CreateInstance,
399 xapocf_LockServer
402 HRESULT make_xapo_factory(REFCLSID clsid, REFIID riid, void **ppv)
404 HRESULT hr;
405 struct xapo_cf *ret = HeapAlloc(GetProcessHeap(), 0, sizeof(struct xapo_cf));
406 ret->IClassFactory_iface.lpVtbl = &xapo_Vtbl;
407 ret->class = clsid;
408 ret->ref = 0;
409 hr = IClassFactory_QueryInterface(&ret->IClassFactory_iface, riid, ppv);
410 if(FAILED(hr))
411 HeapFree(GetProcessHeap(), 0, ret);
412 return hr;