explorerframe: Remove DECLSPEC_HIDDEN usage.
[wine.git] / dlls / xaudio2_7 / xaudio_dll.c
blob5b9513b3ab05d3234376b83d31330768b47597bd
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 <stdarg.h>
23 #define NONAMELESSUNION
24 #define COBJMACROS
26 #include "windows.h"
27 #include "objbase.h"
28 #include "mmdeviceapi.h"
30 #include "initguid.h"
31 #include "xaudio_private.h"
32 #if XAUDIO2_VER >= 8
33 #include "xapofx.h"
34 #endif
36 #include "wine/asm.h"
37 #include "wine/debug.h"
38 #include "wine/heap.h"
40 WINE_DEFAULT_DEBUG_CHANNEL(xaudio2);
42 #if XAUDIO2_VER != 0 && defined(__i386__)
43 /* EVE Online uses an OnVoiceProcessingPassStart callback which corrupts %esi;
44 * League of Legends uses a callback which corrupts %ebx. */
45 #define IXAudio2VoiceCallback_OnVoiceProcessingPassStart(a, b) call_on_voice_processing_pass_start(a, b)
46 extern void call_on_voice_processing_pass_start(IXAudio2VoiceCallback *This, UINT32 BytesRequired);
47 __ASM_GLOBAL_FUNC( call_on_voice_processing_pass_start,
48 "pushl %ebp\n\t"
49 __ASM_CFI(".cfi_adjust_cfa_offset 4\n\t")
50 __ASM_CFI(".cfi_rel_offset %ebp,0\n\t")
51 "movl %esp,%ebp\n\t"
52 __ASM_CFI(".cfi_def_cfa_register %ebp\n\t")
53 "pushl %esi\n\t"
54 __ASM_CFI(".cfi_rel_offset %esi,-4\n\t")
55 "pushl %edi\n\t"
56 __ASM_CFI(".cfi_rel_offset %edi,-8\n\t")
57 "pushl %ebx\n\t"
58 __ASM_CFI(".cfi_rel_offset %ebx,-12\n\t")
59 "subl $4,%esp\n\t"
60 "pushl 12(%ebp)\n\t" /* BytesRequired */
61 "pushl 8(%ebp)\n\t" /* This */
62 "movl 8(%ebp),%eax\n\t"
63 "movl 0(%eax),%eax\n\t"
64 "call *0(%eax)\n\t" /* This->lpVtbl->OnVoiceProcessingPassStart */
65 "leal -12(%ebp),%esp\n\t"
66 "popl %ebx\n\t"
67 __ASM_CFI(".cfi_same_value %ebx\n\t")
68 "popl %edi\n\t"
69 __ASM_CFI(".cfi_same_value %edi\n\t")
70 "popl %esi\n\t"
71 __ASM_CFI(".cfi_same_value %esi\n\t")
72 "popl %ebp\n\t"
73 __ASM_CFI(".cfi_def_cfa %esp,4\n\t")
74 __ASM_CFI(".cfi_same_value %ebp\n\t")
75 "ret" )
76 #endif
78 static XA2VoiceImpl *impl_from_IXAudio2Voice(IXAudio2Voice *iface);
80 BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD reason, void *pReserved)
82 TRACE("(%p, %ld, %p)\n", hinstDLL, reason, pReserved);
84 switch (reason)
86 case DLL_PROCESS_ATTACH:
87 DisableThreadLibraryCalls( hinstDLL );
88 TRACE("Using FAudio version %d\n", FAudioLinkedVersion() );
89 break;
91 return TRUE;
94 /* Effect Wrapping */
96 static inline XA2XAPOImpl *impl_from_FAPO(FAPO *iface)
98 return CONTAINING_RECORD(iface, XA2XAPOImpl, FAPO_vtbl);
101 static int32_t FAPOCALL XAPO_AddRef(void *iface)
103 XA2XAPOImpl *This = impl_from_FAPO(iface);
104 TRACE("%p\n", This);
105 return InterlockedIncrement(&This->ref);
108 static int32_t FAPOCALL XAPO_Release(void *iface)
110 int32_t r;
111 XA2XAPOImpl *This = impl_from_FAPO(iface);
112 TRACE("%p\n", This);
113 r = InterlockedDecrement(&This->ref);
114 if(r == 0){
115 IXAPO_Release(This->xapo);
116 if(This->xapo_params)
117 IXAPOParameters_Release(This->xapo_params);
118 heap_free(This);
120 return r;
123 static uint32_t FAPOCALL XAPO_GetRegistrationProperties(void *iface,
124 FAPORegistrationProperties **ppRegistrationProperties)
126 XA2XAPOImpl *This = impl_from_FAPO(iface);
127 XAPO_REGISTRATION_PROPERTIES *xprops;
128 HRESULT hr;
130 TRACE("%p\n", This);
132 hr = IXAPO_GetRegistrationProperties(This->xapo, &xprops);
133 if(FAILED(hr))
134 return hr;
136 /* TODO: check for version == 20 and use XAPO20_REGISTRATION_PROPERTIES */
137 *ppRegistrationProperties = (FAPORegistrationProperties*) xprops;
138 return 0;
141 static uint32_t FAPOCALL XAPO_IsInputFormatSupported(void *iface,
142 const FAudioWaveFormatEx *pOutputFormat, const FAudioWaveFormatEx *pRequestedInputFormat,
143 FAudioWaveFormatEx **ppSupportedInputFormat)
145 XA2XAPOImpl *This = impl_from_FAPO(iface);
146 TRACE("%p\n", This);
147 return IXAPO_IsInputFormatSupported(This->xapo, (const WAVEFORMATEX*)pOutputFormat,
148 (const WAVEFORMATEX*)pRequestedInputFormat, (WAVEFORMATEX**)ppSupportedInputFormat);
151 static uint32_t FAPOCALL XAPO_IsOutputFormatSupported(void *iface,
152 const FAudioWaveFormatEx *pInputFormat, const FAudioWaveFormatEx *pRequestedOutputFormat,
153 FAudioWaveFormatEx **ppSupportedOutputFormat)
155 XA2XAPOImpl *This = impl_from_FAPO(iface);
156 TRACE("%p\n", This);
157 return IXAPO_IsOutputFormatSupported(This->xapo, (const WAVEFORMATEX *)pInputFormat,
158 (const WAVEFORMATEX *)pRequestedOutputFormat, (WAVEFORMATEX**)ppSupportedOutputFormat);
161 static uint32_t FAPOCALL XAPO_Initialize(void *iface, const void *pData,
162 uint32_t DataByteSize)
164 XA2XAPOImpl *This = impl_from_FAPO(iface);
165 TRACE("%p\n", This);
166 return IXAPO_Initialize(This->xapo, pData, DataByteSize);
169 static void FAPOCALL XAPO_Reset(void *iface)
171 XA2XAPOImpl *This = impl_from_FAPO(iface);
172 TRACE("%p\n", This);
173 IXAPO_Reset(This->xapo);
176 static uint32_t FAPOCALL XAPO_LockForProcess(void *iface,
177 uint32_t InputLockedParameterCount,
178 const FAPOLockForProcessBufferParameters *pInputLockedParameters,
179 uint32_t OutputLockedParameterCount,
180 const FAPOLockForProcessBufferParameters *pOutputLockedParameters)
182 XA2XAPOImpl *This = impl_from_FAPO(iface);
183 TRACE("%p\n", This);
184 return IXAPO_LockForProcess(This->xapo,
185 InputLockedParameterCount,
186 (const XAPO_LOCKFORPROCESS_BUFFER_PARAMETERS *)pInputLockedParameters,
187 OutputLockedParameterCount,
188 (const XAPO_LOCKFORPROCESS_BUFFER_PARAMETERS *)pOutputLockedParameters);
191 static void FAPOCALL XAPO_UnlockForProcess(void *iface)
193 XA2XAPOImpl *This = impl_from_FAPO(iface);
194 TRACE("%p\n", This);
195 IXAPO_UnlockForProcess(This->xapo);
198 static void FAPOCALL XAPO_Process(void *iface,
199 uint32_t InputProcessParameterCount,
200 const FAPOProcessBufferParameters* pInputProcessParameters,
201 uint32_t OutputProcessParameterCount,
202 FAPOProcessBufferParameters* pOutputProcessParameters,
203 int32_t IsEnabled)
205 XA2XAPOImpl *This = impl_from_FAPO(iface);
206 TRACE("%p\n", This);
207 IXAPO_Process(This->xapo, InputProcessParameterCount,
208 (const XAPO_PROCESS_BUFFER_PARAMETERS *)pInputProcessParameters,
209 OutputProcessParameterCount,
210 (XAPO_PROCESS_BUFFER_PARAMETERS *)pOutputProcessParameters,
211 IsEnabled);
214 static uint32_t FAPOCALL XAPO_CalcInputFrames(void *iface,
215 uint32_t OutputFrameCount)
217 XA2XAPOImpl *This = impl_from_FAPO(iface);
218 TRACE("%p\n", This);
219 return IXAPO_CalcInputFrames(This->xapo, OutputFrameCount);
222 static uint32_t FAPOCALL XAPO_CalcOutputFrames(void *iface,
223 uint32_t InputFrameCount)
225 XA2XAPOImpl *This = impl_from_FAPO(iface);
226 TRACE("%p\n", This);
227 return IXAPO_CalcOutputFrames(This->xapo, InputFrameCount);
230 static void FAPOCALL XAPO_SetParameters(void *iface,
231 const void *pParameters, uint32_t ParametersByteSize)
233 XA2XAPOImpl *This = impl_from_FAPO(iface);
234 TRACE("%p\n", This);
235 if(This->xapo_params)
236 IXAPOParameters_SetParameters(This->xapo_params, pParameters, ParametersByteSize);
239 static void FAPOCALL XAPO_GetParameters(void *iface,
240 void *pParameters, uint32_t ParametersByteSize)
242 XA2XAPOImpl *This = impl_from_FAPO(iface);
243 TRACE("%p\n", This);
244 if(This->xapo_params)
245 IXAPOParameters_GetParameters(This->xapo_params, pParameters, ParametersByteSize);
246 else
247 memset(pParameters, 0, ParametersByteSize);
250 static const FAPO FAPO_Vtbl = {
251 XAPO_AddRef,
252 XAPO_Release,
253 XAPO_GetRegistrationProperties,
254 XAPO_IsInputFormatSupported,
255 XAPO_IsOutputFormatSupported,
256 XAPO_Initialize,
257 XAPO_Reset,
258 XAPO_LockForProcess,
259 XAPO_UnlockForProcess,
260 XAPO_Process,
261 XAPO_CalcInputFrames,
262 XAPO_CalcOutputFrames,
263 XAPO_SetParameters,
264 XAPO_GetParameters,
267 static XA2XAPOImpl *wrap_xapo(IUnknown *unk)
269 XA2XAPOImpl *ret;
270 IXAPO *xapo;
271 IXAPOParameters *xapo_params;
272 HRESULT hr;
274 #if XAUDIO2_VER <= 7
275 hr = IUnknown_QueryInterface(unk, &IID_IXAPO27, (void**)&xapo);
276 #else
277 hr = IUnknown_QueryInterface(unk, &IID_IXAPO, (void**)&xapo);
278 #endif
279 if(FAILED(hr)){
280 WARN("XAPO doesn't support IXAPO? %p\n", unk);
281 return NULL;
284 #if XAUDIO2_VER <= 7
285 hr = IUnknown_QueryInterface(unk, &IID_IXAPO27Parameters, (void**)&xapo_params);
286 #else
287 hr = IUnknown_QueryInterface(unk, &IID_IXAPOParameters, (void**)&xapo_params);
288 #endif
289 if(FAILED(hr)){
290 TRACE("XAPO doesn't support IXAPOParameters %p\n", unk);
291 xapo_params = NULL;
294 ret = heap_alloc(sizeof(*ret));
296 ret->xapo = xapo;
297 ret->xapo_params = xapo_params;
298 ret->FAPO_vtbl = FAPO_Vtbl;
299 ret->ref = 1;
301 TRACE("wrapped IXAPO %p with %p\n", xapo, ret);
303 return ret;
306 FAudioEffectChain *wrap_effect_chain(const XAUDIO2_EFFECT_CHAIN *pEffectChain)
308 FAudioEffectChain *ret;
309 int i;
311 if(!pEffectChain)
312 return NULL;
314 ret = heap_alloc(sizeof(*ret) + sizeof(FAudioEffectDescriptor) * pEffectChain->EffectCount);
316 ret->EffectCount = pEffectChain->EffectCount;
317 ret->pEffectDescriptors = (void*)(ret + 1);
319 for(i = 0; i < ret->EffectCount; ++i){
320 ret->pEffectDescriptors[i].pEffect = &wrap_xapo(pEffectChain->pEffectDescriptors[i].pEffect)->FAPO_vtbl;
321 ret->pEffectDescriptors[i].InitialState = pEffectChain->pEffectDescriptors[i].InitialState;
322 ret->pEffectDescriptors[i].OutputChannels = pEffectChain->pEffectDescriptors[i].OutputChannels;
325 return ret;
328 static void free_effect_chain(FAudioEffectChain *chain)
330 int i;
331 if(!chain)
332 return;
333 for(i = 0; i < chain->EffectCount; ++i)
334 XAPO_Release(chain->pEffectDescriptors[i].pEffect);
335 heap_free(chain);
338 /* Send Wrapping */
340 static FAudioVoiceSends *wrap_voice_sends(const XAUDIO2_VOICE_SENDS *sends)
342 FAudioVoiceSends *ret;
343 int i;
345 if(!sends)
346 return NULL;
348 #if XAUDIO2_VER <= 3
349 ret = heap_alloc(sizeof(*ret) + sends->OutputCount * sizeof(FAudioSendDescriptor));
350 ret->SendCount = sends->OutputCount;
351 ret->pSends = (FAudioSendDescriptor*)(ret + 1);
352 for(i = 0; i < sends->OutputCount; ++i){
353 XA2VoiceImpl *voice = impl_from_IXAudio2Voice(sends->pOutputVoices[i]);
354 ret->pSends[i].pOutputVoice = voice->faudio_voice;
355 ret->pSends[i].Flags = 0;
357 #else
358 ret = heap_alloc(sizeof(*ret) + sends->SendCount * sizeof(FAudioSendDescriptor));
359 ret->SendCount = sends->SendCount;
360 ret->pSends = (FAudioSendDescriptor*)(ret + 1);
361 for(i = 0; i < sends->SendCount; ++i){
362 XA2VoiceImpl *voice = impl_from_IXAudio2Voice(sends->pSends[i].pOutputVoice);
363 ret->pSends[i].pOutputVoice = voice->faudio_voice;
364 ret->pSends[i].Flags = sends->pSends[i].Flags;
366 #endif
367 return ret;
370 static void free_voice_sends(FAudioVoiceSends *sends)
372 if(!sends)
373 return;
374 heap_free(sends);
377 /* Voice Callbacks */
379 static inline XA2VoiceImpl *impl_from_FAudioVoiceCallback(FAudioVoiceCallback *iface)
381 return CONTAINING_RECORD(iface, XA2VoiceImpl, FAudioVoiceCallback_vtbl);
384 static void FAUDIOCALL XA2VCB_OnVoiceProcessingPassStart(FAudioVoiceCallback *iface,
385 UINT32 BytesRequired)
387 XA2VoiceImpl *This = impl_from_FAudioVoiceCallback(iface);
388 TRACE("%p\n", This);
389 if(This->cb)
390 IXAudio2VoiceCallback_OnVoiceProcessingPassStart(This->cb
391 #if XAUDIO2_VER > 0
392 , BytesRequired
393 #endif
397 static void FAUDIOCALL XA2VCB_OnVoiceProcessingPassEnd(FAudioVoiceCallback *iface)
399 XA2VoiceImpl *This = impl_from_FAudioVoiceCallback(iface);
400 TRACE("%p\n", This);
401 if(This->cb)
402 IXAudio2VoiceCallback_OnVoiceProcessingPassEnd(This->cb);
405 static void FAUDIOCALL XA2VCB_OnStreamEnd(FAudioVoiceCallback *iface)
407 XA2VoiceImpl *This = impl_from_FAudioVoiceCallback(iface);
408 TRACE("%p\n", This);
409 if(This->cb)
410 IXAudio2VoiceCallback_OnStreamEnd(This->cb);
413 static void FAUDIOCALL XA2VCB_OnBufferStart(FAudioVoiceCallback *iface,
414 void *pBufferContext)
416 XA2VoiceImpl *This = impl_from_FAudioVoiceCallback(iface);
417 TRACE("%p\n", This);
418 if(This->cb)
419 IXAudio2VoiceCallback_OnBufferStart(This->cb, pBufferContext);
422 static void FAUDIOCALL XA2VCB_OnBufferEnd(FAudioVoiceCallback *iface,
423 void *pBufferContext)
425 XA2VoiceImpl *This = impl_from_FAudioVoiceCallback(iface);
426 TRACE("%p\n", This);
427 if(This->cb)
428 IXAudio2VoiceCallback_OnBufferEnd(This->cb, pBufferContext);
431 static void FAUDIOCALL XA2VCB_OnLoopEnd(FAudioVoiceCallback *iface,
432 void *pBufferContext)
434 XA2VoiceImpl *This = impl_from_FAudioVoiceCallback(iface);
435 TRACE("%p\n", This);
436 if(This->cb)
437 IXAudio2VoiceCallback_OnLoopEnd(This->cb, pBufferContext);
440 static void FAUDIOCALL XA2VCB_OnVoiceError(FAudioVoiceCallback *iface,
441 void *pBufferContext, unsigned int Error)
443 XA2VoiceImpl *This = impl_from_FAudioVoiceCallback(iface);
444 TRACE("%p\n", This);
445 if(This->cb)
446 IXAudio2VoiceCallback_OnVoiceError(This->cb, pBufferContext, (HRESULT)Error);
449 static const FAudioVoiceCallback FAudioVoiceCallback_Vtbl = {
450 XA2VCB_OnBufferEnd,
451 XA2VCB_OnBufferStart,
452 XA2VCB_OnLoopEnd,
453 XA2VCB_OnStreamEnd,
454 XA2VCB_OnVoiceError,
455 XA2VCB_OnVoiceProcessingPassEnd,
456 XA2VCB_OnVoiceProcessingPassStart
459 /* Engine Callbacks */
461 static inline IXAudio2Impl *impl_from_FAudioEngineCallback(FAudioEngineCallback *iface)
463 return CONTAINING_RECORD(iface, IXAudio2Impl, FAudioEngineCallback_vtbl);
466 static void FAUDIOCALL XA2ECB_OnProcessingPassStart(FAudioEngineCallback *iface)
468 IXAudio2Impl *This = impl_from_FAudioEngineCallback(iface);
469 int i;
470 TRACE("%p\n", This);
471 for(i = 0; i < This->ncbs && This->cbs[i]; ++i)
472 IXAudio2EngineCallback_OnProcessingPassStart(This->cbs[i]);
475 static void FAUDIOCALL XA2ECB_OnProcessingPassEnd(FAudioEngineCallback *iface)
477 IXAudio2Impl *This = impl_from_FAudioEngineCallback(iface);
478 int i;
479 TRACE("%p\n", This);
480 for(i = 0; i < This->ncbs && This->cbs[i]; ++i)
481 IXAudio2EngineCallback_OnProcessingPassEnd(This->cbs[i]);
484 static void FAUDIOCALL XA2ECB_OnCriticalError(FAudioEngineCallback *iface,
485 uint32_t error)
487 IXAudio2Impl *This = impl_from_FAudioEngineCallback(iface);
488 int i;
489 TRACE("%p\n", This);
490 for(i = 0; i < This->ncbs && This->cbs[i]; ++i)
491 IXAudio2EngineCallback_OnCriticalError(This->cbs[i], error);
494 static const FAudioEngineCallback FAudioEngineCallback_Vtbl = {
495 XA2ECB_OnCriticalError,
496 XA2ECB_OnProcessingPassEnd,
497 XA2ECB_OnProcessingPassStart
500 /* Common Voice Functions */
502 static inline void destroy_voice(XA2VoiceImpl *This)
504 FAudioVoice_DestroyVoice(This->faudio_voice);
505 free_effect_chain(This->effect_chain);
506 This->effect_chain = NULL;
507 This->in_use = FALSE;
510 static void get_voice_details(XA2VoiceImpl *voice, XAUDIO2_VOICE_DETAILS *details)
512 FAudioVoiceDetails faudio_details;
514 TRACE("%p, %p\n", voice, details);
516 FAudioVoice_GetVoiceDetails(voice->faudio_voice, &faudio_details);
517 details->CreationFlags = faudio_details.CreationFlags;
518 #if XAUDIO2_VER >= 8
519 details->ActiveFlags = faudio_details.ActiveFlags;
520 #endif
521 details->InputChannels = faudio_details.InputChannels;
522 details->InputSampleRate = faudio_details.InputSampleRate;
525 /* Source Voices */
527 static inline XA2VoiceImpl *impl_from_IXAudio2SourceVoice(IXAudio2SourceVoice *iface)
529 return CONTAINING_RECORD(iface, XA2VoiceImpl, IXAudio2SourceVoice_iface);
532 static void WINAPI XA2SRC_GetVoiceDetails(IXAudio2SourceVoice *iface, XAUDIO2_VOICE_DETAILS *details)
534 XA2VoiceImpl *voice = impl_from_IXAudio2SourceVoice(iface);
536 get_voice_details(voice, details);
539 static HRESULT WINAPI XA2SRC_SetOutputVoices(IXAudio2SourceVoice *iface,
540 const XAUDIO2_VOICE_SENDS *pSendList)
542 XA2VoiceImpl *This = impl_from_IXAudio2SourceVoice(iface);
543 FAudioVoiceSends *faudio_sends;
544 HRESULT hr;
546 TRACE("%p, %p\n", This, pSendList);
548 faudio_sends = wrap_voice_sends(pSendList);
550 hr = FAudioVoice_SetOutputVoices(This->faudio_voice, faudio_sends);
552 free_voice_sends(faudio_sends);
554 return hr;
557 static HRESULT WINAPI XA2SRC_SetEffectChain(IXAudio2SourceVoice *iface,
558 const XAUDIO2_EFFECT_CHAIN *pEffectChain)
560 XA2VoiceImpl *This = impl_from_IXAudio2SourceVoice(iface);
561 HRESULT hr;
563 TRACE("%p, %p\n", This, pEffectChain);
565 free_effect_chain(This->effect_chain);
566 This->effect_chain = wrap_effect_chain(pEffectChain);
568 hr = FAudioVoice_SetEffectChain(This->faudio_voice, This->effect_chain);
570 return hr;
573 static HRESULT WINAPI XA2SRC_EnableEffect(IXAudio2SourceVoice *iface, UINT32 EffectIndex,
574 UINT32 OperationSet)
576 XA2VoiceImpl *This = impl_from_IXAudio2SourceVoice(iface);
577 TRACE("%p, %u, 0x%x\n", This, EffectIndex, OperationSet);
578 return FAudioVoice_EnableEffect(This->faudio_voice, EffectIndex, OperationSet);
581 static HRESULT WINAPI XA2SRC_DisableEffect(IXAudio2SourceVoice *iface, UINT32 EffectIndex,
582 UINT32 OperationSet)
584 XA2VoiceImpl *This = impl_from_IXAudio2SourceVoice(iface);
585 TRACE("%p, %u, 0x%x\n", This, EffectIndex, OperationSet);
586 return FAudioVoice_DisableEffect(This->faudio_voice, EffectIndex, OperationSet);
589 static void WINAPI XA2SRC_GetEffectState(IXAudio2SourceVoice *iface, UINT32 EffectIndex,
590 BOOL *pEnabled)
592 XA2VoiceImpl *This = impl_from_IXAudio2SourceVoice(iface);
593 TRACE("%p, %u, %p\n", This, EffectIndex, pEnabled);
594 FAudioVoice_GetEffectState(This->faudio_voice, EffectIndex, (int32_t*)pEnabled);
597 static HRESULT WINAPI XA2SRC_SetEffectParameters(IXAudio2SourceVoice *iface,
598 UINT32 EffectIndex, const void *pParameters, UINT32 ParametersByteSize,
599 UINT32 OperationSet)
601 XA2VoiceImpl *This = impl_from_IXAudio2SourceVoice(iface);
602 TRACE("%p, %u, %p, 0x%x, 0x%x\n", This, EffectIndex, pParameters,
603 ParametersByteSize, OperationSet);
604 return FAudioVoice_SetEffectParameters(This->faudio_voice, EffectIndex,
605 pParameters, ParametersByteSize, OperationSet);
608 static HRESULT WINAPI XA2SRC_GetEffectParameters(IXAudio2SourceVoice *iface,
609 UINT32 EffectIndex, void *pParameters, UINT32 ParametersByteSize)
611 XA2VoiceImpl *This = impl_from_IXAudio2SourceVoice(iface);
612 TRACE("%p, %u, %p, 0x%x\n", This, EffectIndex, pParameters,
613 ParametersByteSize);
614 return FAudioVoice_GetEffectParameters(This->faudio_voice, EffectIndex,
615 pParameters, ParametersByteSize);
618 static HRESULT WINAPI XA2SRC_SetFilterParameters(IXAudio2SourceVoice *iface,
619 const XAUDIO2_FILTER_PARAMETERS *pParameters, UINT32 OperationSet)
621 XA2VoiceImpl *This = impl_from_IXAudio2SourceVoice(iface);
622 TRACE("%p, %p, 0x%x\n", This, pParameters, OperationSet);
623 return FAudioVoice_SetFilterParameters(This->faudio_voice,
624 (const FAudioFilterParameters *)pParameters, OperationSet);
627 static void WINAPI XA2SRC_GetFilterParameters(IXAudio2SourceVoice *iface,
628 XAUDIO2_FILTER_PARAMETERS *pParameters)
630 XA2VoiceImpl *This = impl_from_IXAudio2SourceVoice(iface);
631 TRACE("%p, %p\n", This, pParameters);
632 FAudioVoice_GetFilterParameters(This->faudio_voice, (FAudioFilterParameters *)pParameters);
635 #if XAUDIO2_VER >= 4
636 static HRESULT WINAPI XA2SRC_SetOutputFilterParameters(IXAudio2SourceVoice *iface,
637 IXAudio2Voice *pDestinationVoice,
638 const XAUDIO2_FILTER_PARAMETERS *pParameters, UINT32 OperationSet)
640 XA2VoiceImpl *This = impl_from_IXAudio2SourceVoice(iface);
641 XA2VoiceImpl *dst = pDestinationVoice ? impl_from_IXAudio2Voice(pDestinationVoice) : NULL;
643 TRACE("%p, %p, %p, 0x%x\n", This, pDestinationVoice, pParameters, OperationSet);
645 return FAudioVoice_SetOutputFilterParameters(This->faudio_voice,
646 dst ? dst->faudio_voice : NULL, (const FAudioFilterParameters *)pParameters, OperationSet);
649 static void WINAPI XA2SRC_GetOutputFilterParameters(IXAudio2SourceVoice *iface,
650 IXAudio2Voice *pDestinationVoice,
651 XAUDIO2_FILTER_PARAMETERS *pParameters)
653 XA2VoiceImpl *This = impl_from_IXAudio2SourceVoice(iface);
654 XA2VoiceImpl *dst = pDestinationVoice ? impl_from_IXAudio2Voice(pDestinationVoice) : NULL;
656 TRACE("%p, %p, %p\n", This, pDestinationVoice, pParameters);
658 FAudioVoice_GetOutputFilterParameters(This->faudio_voice,
659 dst ? dst->faudio_voice : NULL, (FAudioFilterParameters *)pParameters);
661 #endif
663 static HRESULT WINAPI XA2SRC_SetVolume(IXAudio2SourceVoice *iface, float Volume,
664 UINT32 OperationSet)
666 XA2VoiceImpl *This = impl_from_IXAudio2SourceVoice(iface);
667 TRACE("%p, %f, 0x%x\n", This, Volume, OperationSet);
668 return FAudioVoice_SetVolume(This->faudio_voice, Volume, OperationSet);
671 static void WINAPI XA2SRC_GetVolume(IXAudio2SourceVoice *iface, float *pVolume)
673 XA2VoiceImpl *This = impl_from_IXAudio2SourceVoice(iface);
674 TRACE("%p, %p\n", This, pVolume);
675 return FAudioVoice_GetVolume(This->faudio_voice, pVolume);
678 static HRESULT WINAPI XA2SRC_SetChannelVolumes(IXAudio2SourceVoice *iface, UINT32 Channels,
679 const float *pVolumes, UINT32 OperationSet)
681 XA2VoiceImpl *This = impl_from_IXAudio2SourceVoice(iface);
682 TRACE("%p, %u, %p, 0x%x\n", This, Channels, pVolumes, OperationSet);
683 return FAudioVoice_SetChannelVolumes(This->faudio_voice, Channels,
684 pVolumes, OperationSet);
687 static void WINAPI XA2SRC_GetChannelVolumes(IXAudio2SourceVoice *iface, UINT32 Channels,
688 float *pVolumes)
690 XA2VoiceImpl *This = impl_from_IXAudio2SourceVoice(iface);
691 TRACE("%p, %u, %p\n", This, Channels, pVolumes);
692 return FAudioVoice_GetChannelVolumes(This->faudio_voice, Channels,
693 pVolumes);
696 static HRESULT WINAPI XA2SRC_SetOutputMatrix(IXAudio2SourceVoice *iface,
697 IXAudio2Voice *pDestinationVoice, UINT32 SourceChannels,
698 UINT32 DestinationChannels, const float *pLevelMatrix,
699 UINT32 OperationSet)
701 XA2VoiceImpl *This = impl_from_IXAudio2SourceVoice(iface);
702 XA2VoiceImpl *dst = pDestinationVoice ? impl_from_IXAudio2Voice(pDestinationVoice) : NULL;
704 TRACE("%p, %p, %u, %u, %p, 0x%x\n", This, pDestinationVoice,
705 SourceChannels, DestinationChannels, pLevelMatrix, OperationSet);
707 return FAudioVoice_SetOutputMatrix(This->faudio_voice, dst ? dst->faudio_voice : NULL,
708 SourceChannels, DestinationChannels, pLevelMatrix, OperationSet);
711 #if XAUDIO2_VER == 0
712 static HRESULT
713 #else
714 static void
715 #endif
716 WINAPI XA2SRC_GetOutputMatrix(IXAudio2SourceVoice *iface,
717 IXAudio2Voice *pDestinationVoice, UINT32 SourceChannels,
718 UINT32 DestinationChannels, float *pLevelMatrix)
720 XA2VoiceImpl *This = impl_from_IXAudio2SourceVoice(iface);
721 XA2VoiceImpl *dst = pDestinationVoice ? impl_from_IXAudio2Voice(pDestinationVoice) : NULL;
723 TRACE("%p, %p, %u, %u, %p\n", This, pDestinationVoice,
724 SourceChannels, DestinationChannels, pLevelMatrix);
726 FAudioVoice_GetOutputMatrix(This->faudio_voice, dst ? dst->faudio_voice : NULL,
727 SourceChannels, DestinationChannels, pLevelMatrix);
728 #if XAUDIO2_VER == 0
729 return S_OK;
730 #endif
733 static void WINAPI XA2SRC_DestroyVoice(IXAudio2SourceVoice *iface)
735 XA2VoiceImpl *This = impl_from_IXAudio2SourceVoice(iface);
737 TRACE("%p\n", This);
739 EnterCriticalSection(&This->lock);
741 destroy_voice(This);
743 LeaveCriticalSection(&This->lock);
746 static HRESULT WINAPI XA2SRC_Start(IXAudio2SourceVoice *iface, UINT32 Flags,
747 UINT32 OperationSet)
749 XA2VoiceImpl *This = impl_from_IXAudio2SourceVoice(iface);
751 TRACE("%p, 0x%x, 0x%x\n", This, Flags, OperationSet);
753 return FAudioSourceVoice_Start(This->faudio_voice, Flags, OperationSet);
756 static HRESULT WINAPI XA2SRC_Stop(IXAudio2SourceVoice *iface, UINT32 Flags,
757 UINT32 OperationSet)
759 XA2VoiceImpl *This = impl_from_IXAudio2SourceVoice(iface);
761 TRACE("%p, 0x%x, 0x%x\n", This, Flags, OperationSet);
763 return FAudioSourceVoice_Stop(This->faudio_voice, Flags, OperationSet);
766 static HRESULT WINAPI XA2SRC_SubmitSourceBuffer(IXAudio2SourceVoice *iface,
767 const XAUDIO2_BUFFER *pBuffer, const XAUDIO2_BUFFER_WMA *pBufferWMA)
769 XA2VoiceImpl *This = impl_from_IXAudio2SourceVoice(iface);
771 TRACE("%p, %p, %p\n", This, pBuffer, pBufferWMA);
773 return FAudioSourceVoice_SubmitSourceBuffer(This->faudio_voice, (FAudioBuffer*)pBuffer, (FAudioBufferWMA*)pBufferWMA);
776 static HRESULT WINAPI XA2SRC_FlushSourceBuffers(IXAudio2SourceVoice *iface)
778 XA2VoiceImpl *This = impl_from_IXAudio2SourceVoice(iface);
780 TRACE("%p\n", This);
782 return FAudioSourceVoice_FlushSourceBuffers(This->faudio_voice);
785 static HRESULT WINAPI XA2SRC_Discontinuity(IXAudio2SourceVoice *iface)
787 XA2VoiceImpl *This = impl_from_IXAudio2SourceVoice(iface);
789 TRACE("%p\n", This);
791 return FAudioSourceVoice_Discontinuity(This->faudio_voice);
794 static HRESULT WINAPI XA2SRC_ExitLoop(IXAudio2SourceVoice *iface, UINT32 OperationSet)
796 XA2VoiceImpl *This = impl_from_IXAudio2SourceVoice(iface);
798 TRACE("%p, 0x%x\n", This, OperationSet);
800 return FAudioSourceVoice_ExitLoop(This->faudio_voice, OperationSet);
803 #if XAUDIO2_VER >= 8
804 static void WINAPI XA2SRC_GetState(IXAudio2SourceVoice *iface, XAUDIO2_VOICE_STATE *pVoiceState, UINT32 Flags)
805 #else
806 static void WINAPI XA2SRC_GetState(IXAudio2SourceVoice *iface, XAUDIO2_VOICE_STATE *pVoiceState)
807 #endif
809 XA2VoiceImpl *This = impl_from_IXAudio2SourceVoice(iface);
810 #if XAUDIO2_VER < 8
811 UINT32 Flags = 0;
812 #endif
814 TRACE("%p, %p, 0x%x\n", This, pVoiceState, Flags);
816 return FAudioSourceVoice_GetState(This->faudio_voice, (FAudioVoiceState*)pVoiceState, Flags);
819 static HRESULT WINAPI XA2SRC_SetFrequencyRatio(IXAudio2SourceVoice *iface,
820 float Ratio, UINT32 OperationSet)
822 XA2VoiceImpl *This = impl_from_IXAudio2SourceVoice(iface);
824 TRACE("%p, %f, 0x%x\n", This, Ratio, OperationSet);
826 return FAudioSourceVoice_SetFrequencyRatio(This->faudio_voice, Ratio, OperationSet);
829 static void WINAPI XA2SRC_GetFrequencyRatio(IXAudio2SourceVoice *iface, float *pRatio)
831 XA2VoiceImpl *This = impl_from_IXAudio2SourceVoice(iface);
833 TRACE("%p, %p\n", This, pRatio);
835 return FAudioSourceVoice_GetFrequencyRatio(This->faudio_voice, pRatio);
838 #if XAUDIO2_VER >= 4
839 static HRESULT WINAPI XA2SRC_SetSourceSampleRate(
840 IXAudio2SourceVoice *iface,
841 UINT32 NewSourceSampleRate)
843 XA2VoiceImpl *This = impl_from_IXAudio2SourceVoice(iface);
845 TRACE("%p, %u\n", This, NewSourceSampleRate);
847 return FAudioSourceVoice_SetSourceSampleRate(This->faudio_voice, NewSourceSampleRate);
849 #endif
851 static const IXAudio2SourceVoiceVtbl XAudio2SourceVoice_Vtbl = {
852 XA2SRC_GetVoiceDetails,
853 XA2SRC_SetOutputVoices,
854 XA2SRC_SetEffectChain,
855 XA2SRC_EnableEffect,
856 XA2SRC_DisableEffect,
857 XA2SRC_GetEffectState,
858 XA2SRC_SetEffectParameters,
859 XA2SRC_GetEffectParameters,
860 XA2SRC_SetFilterParameters,
861 XA2SRC_GetFilterParameters,
862 #if XAUDIO2_VER >= 4
863 XA2SRC_SetOutputFilterParameters,
864 XA2SRC_GetOutputFilterParameters,
865 #endif
866 XA2SRC_SetVolume,
867 XA2SRC_GetVolume,
868 XA2SRC_SetChannelVolumes,
869 XA2SRC_GetChannelVolumes,
870 XA2SRC_SetOutputMatrix,
871 XA2SRC_GetOutputMatrix,
872 XA2SRC_DestroyVoice,
873 XA2SRC_Start,
874 XA2SRC_Stop,
875 XA2SRC_SubmitSourceBuffer,
876 XA2SRC_FlushSourceBuffers,
877 XA2SRC_Discontinuity,
878 XA2SRC_ExitLoop,
879 XA2SRC_GetState,
880 XA2SRC_SetFrequencyRatio,
881 XA2SRC_GetFrequencyRatio,
882 #if XAUDIO2_VER >= 4
883 XA2SRC_SetSourceSampleRate
884 #endif
887 /* Submix Voices */
889 static inline XA2VoiceImpl *impl_from_IXAudio2SubmixVoice(IXAudio2SubmixVoice *iface)
891 return CONTAINING_RECORD(iface, XA2VoiceImpl, IXAudio2SubmixVoice_iface);
894 static void WINAPI XA2SUB_GetVoiceDetails(IXAudio2SubmixVoice *iface, XAUDIO2_VOICE_DETAILS *details)
896 XA2VoiceImpl *voice = impl_from_IXAudio2SubmixVoice(iface);
898 get_voice_details(voice, details);
901 static HRESULT WINAPI XA2SUB_SetOutputVoices(IXAudio2SubmixVoice *iface,
902 const XAUDIO2_VOICE_SENDS *pSendList)
904 XA2VoiceImpl *This = impl_from_IXAudio2SubmixVoice(iface);
905 FAudioVoiceSends *faudio_sends;
906 HRESULT hr;
908 TRACE("%p, %p\n", This, pSendList);
910 faudio_sends = wrap_voice_sends(pSendList);
912 hr = FAudioVoice_SetOutputVoices(This->faudio_voice, faudio_sends);
914 free_voice_sends(faudio_sends);
916 return hr;
919 static HRESULT WINAPI XA2SUB_SetEffectChain(IXAudio2SubmixVoice *iface,
920 const XAUDIO2_EFFECT_CHAIN *pEffectChain)
922 XA2VoiceImpl *This = impl_from_IXAudio2SubmixVoice(iface);
923 HRESULT hr;
925 TRACE("%p, %p\n", This, pEffectChain);
927 free_effect_chain(This->effect_chain);
928 This->effect_chain = wrap_effect_chain(pEffectChain);
930 hr = FAudioVoice_SetEffectChain(This->faudio_voice, This->effect_chain);
932 return hr;
935 static HRESULT WINAPI XA2SUB_EnableEffect(IXAudio2SubmixVoice *iface, UINT32 EffectIndex,
936 UINT32 OperationSet)
938 XA2VoiceImpl *This = impl_from_IXAudio2SubmixVoice(iface);
939 TRACE("%p, %u, 0x%x\n", This, EffectIndex, OperationSet);
940 return FAudioVoice_EnableEffect(This->faudio_voice, EffectIndex, OperationSet);
943 static HRESULT WINAPI XA2SUB_DisableEffect(IXAudio2SubmixVoice *iface, UINT32 EffectIndex,
944 UINT32 OperationSet)
946 XA2VoiceImpl *This = impl_from_IXAudio2SubmixVoice(iface);
947 TRACE("%p, %u, 0x%x\n", This, EffectIndex, OperationSet);
948 return FAudioVoice_DisableEffect(This->faudio_voice, EffectIndex, OperationSet);
951 static void WINAPI XA2SUB_GetEffectState(IXAudio2SubmixVoice *iface, UINT32 EffectIndex,
952 BOOL *pEnabled)
954 XA2VoiceImpl *This = impl_from_IXAudio2SubmixVoice(iface);
955 TRACE("%p, %u, %p\n", This, EffectIndex, pEnabled);
956 FAudioVoice_GetEffectState(This->faudio_voice, EffectIndex, (int32_t*)pEnabled);
959 static HRESULT WINAPI XA2SUB_SetEffectParameters(IXAudio2SubmixVoice *iface,
960 UINT32 EffectIndex, const void *pParameters, UINT32 ParametersByteSize,
961 UINT32 OperationSet)
963 XA2VoiceImpl *This = impl_from_IXAudio2SubmixVoice(iface);
964 TRACE("%p, %u, %p, 0x%x, 0x%x\n", This, EffectIndex, pParameters,
965 ParametersByteSize, OperationSet);
966 return FAudioVoice_SetEffectParameters(This->faudio_voice, EffectIndex,
967 pParameters, ParametersByteSize, OperationSet);
970 static HRESULT WINAPI XA2SUB_GetEffectParameters(IXAudio2SubmixVoice *iface,
971 UINT32 EffectIndex, void *pParameters, UINT32 ParametersByteSize)
973 XA2VoiceImpl *This = impl_from_IXAudio2SubmixVoice(iface);
974 TRACE("%p, %u, %p, 0x%x\n", This, EffectIndex, pParameters,
975 ParametersByteSize);
976 return FAudioVoice_GetEffectParameters(This->faudio_voice, EffectIndex,
977 pParameters, ParametersByteSize);
980 static HRESULT WINAPI XA2SUB_SetFilterParameters(IXAudio2SubmixVoice *iface,
981 const XAUDIO2_FILTER_PARAMETERS *pParameters, UINT32 OperationSet)
983 XA2VoiceImpl *This = impl_from_IXAudio2SubmixVoice(iface);
984 TRACE("%p, %p, 0x%x\n", This, pParameters, OperationSet);
985 return FAudioVoice_SetFilterParameters(This->faudio_voice, (const FAudioFilterParameters *)pParameters,
986 OperationSet);
989 static void WINAPI XA2SUB_GetFilterParameters(IXAudio2SubmixVoice *iface,
990 XAUDIO2_FILTER_PARAMETERS *pParameters)
992 XA2VoiceImpl *This = impl_from_IXAudio2SubmixVoice(iface);
993 TRACE("%p, %p\n", This, pParameters);
994 FAudioVoice_GetFilterParameters(This->faudio_voice, (FAudioFilterParameters *)pParameters);
997 #if XAUDIO2_VER >= 4
998 static HRESULT WINAPI XA2SUB_SetOutputFilterParameters(IXAudio2SubmixVoice *iface,
999 IXAudio2Voice *pDestinationVoice,
1000 const XAUDIO2_FILTER_PARAMETERS *pParameters, UINT32 OperationSet)
1002 XA2VoiceImpl *This = impl_from_IXAudio2SubmixVoice(iface);
1003 XA2VoiceImpl *dst = pDestinationVoice ? impl_from_IXAudio2Voice(pDestinationVoice) : NULL;
1005 TRACE("%p, %p, %p, 0x%x\n", This, pDestinationVoice, pParameters, OperationSet);
1007 return FAudioVoice_SetOutputFilterParameters(This->faudio_voice,
1008 dst ? dst->faudio_voice : NULL, (const FAudioFilterParameters *)pParameters, OperationSet);
1011 static void WINAPI XA2SUB_GetOutputFilterParameters(IXAudio2SubmixVoice *iface,
1012 IXAudio2Voice *pDestinationVoice,
1013 XAUDIO2_FILTER_PARAMETERS *pParameters)
1015 XA2VoiceImpl *This = impl_from_IXAudio2SubmixVoice(iface);
1016 XA2VoiceImpl *dst = pDestinationVoice ? impl_from_IXAudio2Voice(pDestinationVoice) : NULL;
1018 TRACE("%p, %p, %p\n", This, pDestinationVoice, pParameters);
1020 FAudioVoice_GetOutputFilterParameters(This->faudio_voice,
1021 dst ? dst->faudio_voice : NULL, (FAudioFilterParameters *)pParameters);
1023 #endif
1025 static HRESULT WINAPI XA2SUB_SetVolume(IXAudio2SubmixVoice *iface, float Volume,
1026 UINT32 OperationSet)
1028 XA2VoiceImpl *This = impl_from_IXAudio2SubmixVoice(iface);
1029 TRACE("%p, %f, 0x%x\n", This, Volume, OperationSet);
1030 return FAudioVoice_SetVolume(This->faudio_voice, Volume, OperationSet);
1033 static void WINAPI XA2SUB_GetVolume(IXAudio2SubmixVoice *iface, float *pVolume)
1035 XA2VoiceImpl *This = impl_from_IXAudio2SubmixVoice(iface);
1036 TRACE("%p, %p\n", This, pVolume);
1037 return FAudioVoice_GetVolume(This->faudio_voice, pVolume);
1040 static HRESULT WINAPI XA2SUB_SetChannelVolumes(IXAudio2SubmixVoice *iface, UINT32 Channels,
1041 const float *pVolumes, UINT32 OperationSet)
1043 XA2VoiceImpl *This = impl_from_IXAudio2SubmixVoice(iface);
1044 TRACE("%p, %u, %p, 0x%x\n", This, Channels, pVolumes, OperationSet);
1045 return FAudioVoice_SetChannelVolumes(This->faudio_voice, Channels,
1046 pVolumes, OperationSet);
1049 static void WINAPI XA2SUB_GetChannelVolumes(IXAudio2SubmixVoice *iface, UINT32 Channels,
1050 float *pVolumes)
1052 XA2VoiceImpl *This = impl_from_IXAudio2SubmixVoice(iface);
1053 TRACE("%p, %u, %p\n", This, Channels, pVolumes);
1054 return FAudioVoice_GetChannelVolumes(This->faudio_voice, Channels,
1055 pVolumes);
1058 static HRESULT WINAPI XA2SUB_SetOutputMatrix(IXAudio2SubmixVoice *iface,
1059 IXAudio2Voice *pDestinationVoice, UINT32 SourceChannels,
1060 UINT32 DestinationChannels, const float *pLevelMatrix,
1061 UINT32 OperationSet)
1063 XA2VoiceImpl *This = impl_from_IXAudio2SubmixVoice(iface);
1064 XA2VoiceImpl *dst = pDestinationVoice ? impl_from_IXAudio2Voice(pDestinationVoice) : NULL;
1066 TRACE("%p, %p, %u, %u, %p, 0x%x\n", This, pDestinationVoice,
1067 SourceChannels, DestinationChannels, pLevelMatrix, OperationSet);
1069 return FAudioVoice_SetOutputMatrix(This->faudio_voice, dst ? dst->faudio_voice : NULL,
1070 SourceChannels, DestinationChannels, pLevelMatrix, OperationSet);
1073 #if XAUDIO2_VER == 0
1074 static HRESULT
1075 #else
1076 static void
1077 #endif
1078 WINAPI XA2SUB_GetOutputMatrix(IXAudio2SubmixVoice *iface,
1079 IXAudio2Voice *pDestinationVoice, UINT32 SourceChannels,
1080 UINT32 DestinationChannels, float *pLevelMatrix)
1082 XA2VoiceImpl *This = impl_from_IXAudio2SubmixVoice(iface);
1083 XA2VoiceImpl *dst = pDestinationVoice ? impl_from_IXAudio2Voice(pDestinationVoice) : NULL;
1085 TRACE("%p, %p, %u, %u, %p\n", This, pDestinationVoice,
1086 SourceChannels, DestinationChannels, pLevelMatrix);
1088 FAudioVoice_GetOutputMatrix(This->faudio_voice, dst ? dst->faudio_voice : NULL,
1089 SourceChannels, DestinationChannels, pLevelMatrix);
1090 #if XAUDIO2_VER == 0
1091 return S_OK;
1092 #endif
1095 static void WINAPI XA2SUB_DestroyVoice(IXAudio2SubmixVoice *iface)
1097 XA2VoiceImpl *This = impl_from_IXAudio2SubmixVoice(iface);
1099 TRACE("%p\n", This);
1101 EnterCriticalSection(&This->lock);
1103 destroy_voice(This);
1105 LeaveCriticalSection(&This->lock);
1108 static const struct IXAudio2SubmixVoiceVtbl XAudio2SubmixVoice_Vtbl = {
1109 XA2SUB_GetVoiceDetails,
1110 XA2SUB_SetOutputVoices,
1111 XA2SUB_SetEffectChain,
1112 XA2SUB_EnableEffect,
1113 XA2SUB_DisableEffect,
1114 XA2SUB_GetEffectState,
1115 XA2SUB_SetEffectParameters,
1116 XA2SUB_GetEffectParameters,
1117 XA2SUB_SetFilterParameters,
1118 XA2SUB_GetFilterParameters,
1119 #if XAUDIO2_VER >= 4
1120 XA2SUB_SetOutputFilterParameters,
1121 XA2SUB_GetOutputFilterParameters,
1122 #endif
1123 XA2SUB_SetVolume,
1124 XA2SUB_GetVolume,
1125 XA2SUB_SetChannelVolumes,
1126 XA2SUB_GetChannelVolumes,
1127 XA2SUB_SetOutputMatrix,
1128 XA2SUB_GetOutputMatrix,
1129 XA2SUB_DestroyVoice
1132 /* Mastering Voices */
1134 static inline XA2VoiceImpl *impl_from_IXAudio2MasteringVoice(IXAudio2MasteringVoice *iface)
1136 return CONTAINING_RECORD(iface, XA2VoiceImpl, IXAudio2MasteringVoice_iface);
1139 static void WINAPI XA2M_GetVoiceDetails(IXAudio2MasteringVoice *iface, XAUDIO2_VOICE_DETAILS *details)
1141 XA2VoiceImpl *voice = impl_from_IXAudio2MasteringVoice(iface);
1143 get_voice_details(voice, details);
1146 static HRESULT WINAPI XA2M_SetOutputVoices(IXAudio2MasteringVoice *iface,
1147 const XAUDIO2_VOICE_SENDS *pSendList)
1149 XA2VoiceImpl *This = impl_from_IXAudio2MasteringVoice(iface);
1150 FAudioVoiceSends *faudio_sends;
1151 HRESULT hr;
1153 TRACE("%p, %p\n", This, pSendList);
1155 faudio_sends = wrap_voice_sends(pSendList);
1157 hr = FAudioVoice_SetOutputVoices(This->faudio_voice, faudio_sends);
1159 free_voice_sends(faudio_sends);
1161 return hr;
1164 static HRESULT WINAPI XA2M_SetEffectChain(IXAudio2MasteringVoice *iface,
1165 const XAUDIO2_EFFECT_CHAIN *pEffectChain)
1167 XA2VoiceImpl *This = impl_from_IXAudio2MasteringVoice(iface);
1168 HRESULT hr;
1170 TRACE("%p, %p\n", This, pEffectChain);
1172 free_effect_chain(This->effect_chain);
1173 This->effect_chain = wrap_effect_chain(pEffectChain);
1175 hr = FAudioVoice_SetEffectChain(This->faudio_voice, This->effect_chain);
1177 return hr;
1180 static HRESULT WINAPI XA2M_EnableEffect(IXAudio2MasteringVoice *iface, UINT32 EffectIndex,
1181 UINT32 OperationSet)
1183 XA2VoiceImpl *This = impl_from_IXAudio2MasteringVoice(iface);
1184 TRACE("%p, %u, 0x%x\n", This, EffectIndex, OperationSet);
1185 return FAudioVoice_EnableEffect(This->faudio_voice, EffectIndex, OperationSet);
1188 static HRESULT WINAPI XA2M_DisableEffect(IXAudio2MasteringVoice *iface, UINT32 EffectIndex,
1189 UINT32 OperationSet)
1191 XA2VoiceImpl *This = impl_from_IXAudio2MasteringVoice(iface);
1192 TRACE("%p, %u, 0x%x\n", This, EffectIndex, OperationSet);
1193 return FAudioVoice_DisableEffect(This->faudio_voice, EffectIndex, OperationSet);
1196 static void WINAPI XA2M_GetEffectState(IXAudio2MasteringVoice *iface, UINT32 EffectIndex,
1197 BOOL *pEnabled)
1199 XA2VoiceImpl *This = impl_from_IXAudio2MasteringVoice(iface);
1200 TRACE("%p, %u, %p\n", This, EffectIndex, pEnabled);
1201 FAudioVoice_GetEffectState(This->faudio_voice, EffectIndex, (int32_t*)pEnabled);
1204 static HRESULT WINAPI XA2M_SetEffectParameters(IXAudio2MasteringVoice *iface,
1205 UINT32 EffectIndex, const void *pParameters, UINT32 ParametersByteSize,
1206 UINT32 OperationSet)
1208 XA2VoiceImpl *This = impl_from_IXAudio2MasteringVoice(iface);
1209 TRACE("%p, %u, %p, 0x%x, 0x%x\n", This, EffectIndex, pParameters,
1210 ParametersByteSize, OperationSet);
1211 return FAudioVoice_SetEffectParameters(This->faudio_voice, EffectIndex,
1212 pParameters, ParametersByteSize, OperationSet);
1215 static HRESULT WINAPI XA2M_GetEffectParameters(IXAudio2MasteringVoice *iface,
1216 UINT32 EffectIndex, void *pParameters, UINT32 ParametersByteSize)
1218 XA2VoiceImpl *This = impl_from_IXAudio2MasteringVoice(iface);
1219 TRACE("%p, %u, %p, 0x%x\n", This, EffectIndex, pParameters,
1220 ParametersByteSize);
1221 return FAudioVoice_GetEffectParameters(This->faudio_voice, EffectIndex,
1222 pParameters, ParametersByteSize);
1225 static HRESULT WINAPI XA2M_SetFilterParameters(IXAudio2MasteringVoice *iface,
1226 const XAUDIO2_FILTER_PARAMETERS *pParameters, UINT32 OperationSet)
1228 XA2VoiceImpl *This = impl_from_IXAudio2MasteringVoice(iface);
1229 TRACE("%p, %p, 0x%x\n", This, pParameters, OperationSet);
1230 return FAudioVoice_SetFilterParameters(This->faudio_voice, (const FAudioFilterParameters *)pParameters,
1231 OperationSet);
1234 static void WINAPI XA2M_GetFilterParameters(IXAudio2MasteringVoice *iface,
1235 XAUDIO2_FILTER_PARAMETERS *pParameters)
1237 XA2VoiceImpl *This = impl_from_IXAudio2MasteringVoice(iface);
1238 TRACE("%p, %p\n", This, pParameters);
1239 FAudioVoice_GetFilterParameters(This->faudio_voice, (FAudioFilterParameters *)pParameters);
1242 #if XAUDIO2_VER >= 4
1243 static HRESULT WINAPI XA2M_SetOutputFilterParameters(IXAudio2MasteringVoice *iface,
1244 IXAudio2Voice *pDestinationVoice,
1245 const XAUDIO2_FILTER_PARAMETERS *pParameters, UINT32 OperationSet)
1247 XA2VoiceImpl *This = impl_from_IXAudio2MasteringVoice(iface);
1248 XA2VoiceImpl *dst = pDestinationVoice ? impl_from_IXAudio2Voice(pDestinationVoice) : NULL;
1250 TRACE("%p, %p, %p, 0x%x\n", This, pDestinationVoice, pParameters, OperationSet);
1252 return FAudioVoice_SetOutputFilterParameters(This->faudio_voice,
1253 dst ? dst->faudio_voice : NULL, (const FAudioFilterParameters *)pParameters, OperationSet);
1256 static void WINAPI XA2M_GetOutputFilterParameters(IXAudio2MasteringVoice *iface,
1257 IXAudio2Voice *pDestinationVoice,
1258 XAUDIO2_FILTER_PARAMETERS *pParameters)
1260 XA2VoiceImpl *This = impl_from_IXAudio2MasteringVoice(iface);
1261 XA2VoiceImpl *dst = pDestinationVoice ? impl_from_IXAudio2Voice(pDestinationVoice) : NULL;
1263 TRACE("%p, %p, %p\n", This, pDestinationVoice, pParameters);
1265 FAudioVoice_GetOutputFilterParameters(This->faudio_voice,
1266 dst ? dst->faudio_voice : NULL, (FAudioFilterParameters *)pParameters);
1268 #endif
1270 static HRESULT WINAPI XA2M_SetVolume(IXAudio2MasteringVoice *iface, float Volume,
1271 UINT32 OperationSet)
1273 XA2VoiceImpl *This = impl_from_IXAudio2MasteringVoice(iface);
1274 TRACE("%p, %f, 0x%x\n", This, Volume, OperationSet);
1275 return FAudioVoice_SetVolume(This->faudio_voice, Volume, OperationSet);
1278 static void WINAPI XA2M_GetVolume(IXAudio2MasteringVoice *iface, float *pVolume)
1280 XA2VoiceImpl *This = impl_from_IXAudio2MasteringVoice(iface);
1281 TRACE("%p, %p\n", This, pVolume);
1282 return FAudioVoice_GetVolume(This->faudio_voice, pVolume);
1285 static HRESULT WINAPI XA2M_SetChannelVolumes(IXAudio2MasteringVoice *iface, UINT32 Channels,
1286 const float *pVolumes, UINT32 OperationSet)
1288 XA2VoiceImpl *This = impl_from_IXAudio2MasteringVoice(iface);
1289 TRACE("%p, %u, %p, 0x%x\n", This, Channels, pVolumes, OperationSet);
1290 return FAudioVoice_SetChannelVolumes(This->faudio_voice, Channels,
1291 pVolumes, OperationSet);
1294 static void WINAPI XA2M_GetChannelVolumes(IXAudio2MasteringVoice *iface, UINT32 Channels,
1295 float *pVolumes)
1297 XA2VoiceImpl *This = impl_from_IXAudio2MasteringVoice(iface);
1298 TRACE("%p, %u, %p\n", This, Channels, pVolumes);
1299 return FAudioVoice_GetChannelVolumes(This->faudio_voice, Channels,
1300 pVolumes);
1303 static HRESULT WINAPI XA2M_SetOutputMatrix(IXAudio2MasteringVoice *iface,
1304 IXAudio2Voice *pDestinationVoice, UINT32 SourceChannels,
1305 UINT32 DestinationChannels, const float *pLevelMatrix,
1306 UINT32 OperationSet)
1308 XA2VoiceImpl *This = impl_from_IXAudio2MasteringVoice(iface);
1309 XA2VoiceImpl *dst = pDestinationVoice ? impl_from_IXAudio2Voice(pDestinationVoice) : NULL;
1311 TRACE("%p, %p, %u, %u, %p, 0x%x\n", This, pDestinationVoice,
1312 SourceChannels, DestinationChannels, pLevelMatrix, OperationSet);
1314 return FAudioVoice_SetOutputMatrix(This->faudio_voice, dst ? dst->faudio_voice : NULL,
1315 SourceChannels, DestinationChannels, pLevelMatrix, OperationSet);
1318 #if XAUDIO2_VER == 0
1319 static HRESULT
1320 #else
1321 static void
1322 #endif
1323 WINAPI XA2M_GetOutputMatrix(IXAudio2MasteringVoice *iface,
1324 IXAudio2Voice *pDestinationVoice, UINT32 SourceChannels,
1325 UINT32 DestinationChannels, float *pLevelMatrix)
1327 XA2VoiceImpl *This = impl_from_IXAudio2MasteringVoice(iface);
1328 XA2VoiceImpl *dst = pDestinationVoice ? impl_from_IXAudio2Voice(pDestinationVoice) : NULL;
1330 TRACE("%p, %p, %u, %u, %p\n", This, pDestinationVoice,
1331 SourceChannels, DestinationChannels, pLevelMatrix);
1333 FAudioVoice_GetOutputMatrix(This->faudio_voice, dst ? dst->faudio_voice : NULL,
1334 SourceChannels, DestinationChannels, pLevelMatrix);
1335 #if XAUDIO2_VER == 0
1336 return S_OK;
1337 #endif
1340 static void WINAPI XA2M_DestroyVoice(IXAudio2MasteringVoice *iface)
1342 XA2VoiceImpl *This = impl_from_IXAudio2MasteringVoice(iface);
1344 TRACE("%p\n", This);
1346 EnterCriticalSection(&This->lock);
1348 destroy_voice(This);
1350 LeaveCriticalSection(&This->lock);
1353 #if XAUDIO2_VER >= 8
1354 static void WINAPI XA2M_GetChannelMask(IXAudio2MasteringVoice *iface,
1355 DWORD *pChannelMask)
1357 XA2VoiceImpl *This = impl_from_IXAudio2MasteringVoice(iface);
1359 TRACE("%p, %p\n", This, pChannelMask);
1361 FAudioMasteringVoice_GetChannelMask(This->faudio_voice, (uint32_t *)pChannelMask);
1363 #endif
1365 static const struct IXAudio2MasteringVoiceVtbl XAudio2MasteringVoice_Vtbl = {
1366 XA2M_GetVoiceDetails,
1367 XA2M_SetOutputVoices,
1368 XA2M_SetEffectChain,
1369 XA2M_EnableEffect,
1370 XA2M_DisableEffect,
1371 XA2M_GetEffectState,
1372 XA2M_SetEffectParameters,
1373 XA2M_GetEffectParameters,
1374 XA2M_SetFilterParameters,
1375 XA2M_GetFilterParameters,
1376 #if XAUDIO2_VER >= 4
1377 XA2M_SetOutputFilterParameters,
1378 XA2M_GetOutputFilterParameters,
1379 #endif
1380 XA2M_SetVolume,
1381 XA2M_GetVolume,
1382 XA2M_SetChannelVolumes,
1383 XA2M_GetChannelVolumes,
1384 XA2M_SetOutputMatrix,
1385 XA2M_GetOutputMatrix,
1386 XA2M_DestroyVoice,
1387 #if XAUDIO2_VER >= 8
1388 XA2M_GetChannelMask
1389 #endif
1392 /* More Common Voice Functions */
1394 static XA2VoiceImpl *impl_from_IXAudio2Voice(IXAudio2Voice *iface)
1396 if(iface->lpVtbl == (void*)&XAudio2SourceVoice_Vtbl)
1397 return impl_from_IXAudio2SourceVoice((IXAudio2SourceVoice*)iface);
1398 if(iface->lpVtbl == (void*)&XAudio2MasteringVoice_Vtbl)
1399 return impl_from_IXAudio2MasteringVoice((IXAudio2MasteringVoice*)iface);
1400 if(iface->lpVtbl == (void*)&XAudio2SubmixVoice_Vtbl)
1401 return impl_from_IXAudio2SubmixVoice((IXAudio2SubmixVoice*)iface);
1402 ERR("invalid IXAudio2Voice pointer: %p\n", iface);
1403 return NULL;
1406 /* XAudio2 Engine Implementation */
1408 static inline IXAudio2Impl *impl_from_IXAudio2(IXAudio2 *iface)
1410 return CONTAINING_RECORD(iface, IXAudio2Impl, IXAudio2_iface);
1413 static HRESULT WINAPI IXAudio2Impl_QueryInterface(IXAudio2 *iface, REFIID riid,
1414 void **ppvObject)
1416 IXAudio2Impl *This = impl_from_IXAudio2(iface);
1418 TRACE("(%p)->(%s, %p)\n", This, debugstr_guid(riid), ppvObject);
1420 if(IsEqualGUID(riid, &IID_IUnknown) ||
1421 IsEqualGUID(riid, &IID_IXAudio2))
1422 *ppvObject = &This->IXAudio2_iface;
1423 else
1424 *ppvObject = NULL;
1426 if(*ppvObject){
1427 IUnknown_AddRef((IUnknown*)*ppvObject);
1428 return S_OK;
1431 FIXME("(%p)->(%s,%p), not found\n", This,debugstr_guid(riid), ppvObject);
1433 return E_NOINTERFACE;
1436 static ULONG WINAPI IXAudio2Impl_AddRef(IXAudio2 *iface)
1438 IXAudio2Impl *This = impl_from_IXAudio2(iface);
1439 ULONG ref = FAudio_AddRef(This->faudio);
1440 TRACE("(%p)->(): Refcount now %lu\n", This, ref);
1441 return ref;
1444 static ULONG WINAPI IXAudio2Impl_Release(IXAudio2 *iface)
1446 IXAudio2Impl *This = impl_from_IXAudio2(iface);
1447 ULONG ref = FAudio_Release(This->faudio);
1449 TRACE("(%p)->(): Refcount now %lu\n", This, ref);
1451 if (!ref) {
1452 XA2VoiceImpl *v, *v2;
1454 LIST_FOR_EACH_ENTRY_SAFE(v, v2, &This->voices, XA2VoiceImpl, entry){
1455 v->lock.DebugInfo->Spare[0] = 0;
1456 DeleteCriticalSection(&v->lock);
1457 HeapFree(GetProcessHeap(), 0, v);
1460 HeapFree(GetProcessHeap(), 0, This->cbs);
1462 This->lock.DebugInfo->Spare[0] = 0;
1463 DeleteCriticalSection(&This->lock);
1465 HeapFree(GetProcessHeap(), 0, This);
1467 return ref;
1470 #if XAUDIO2_VER <= 7
1471 static HRESULT WINAPI IXAudio2Impl_GetDeviceCount(IXAudio2 *iface, UINT32 *count)
1473 IXAudio2Impl *audio = impl_from_IXAudio2(iface);
1475 TRACE("%p, %p\n", audio, count);
1477 return FAudio_GetDeviceCount(audio->faudio, count);
1480 static HRESULT WINAPI IXAudio2Impl_GetDeviceDetails(IXAudio2 *iface, UINT32 index,
1481 XAUDIO2_DEVICE_DETAILS *details)
1483 IXAudio2Impl *audio = impl_from_IXAudio2(iface);
1485 TRACE("%p, %u, %p\n", audio, index, details);
1487 return FAudio_GetDeviceDetails(audio->faudio, index, (FAudioDeviceDetails *)details);
1490 static HRESULT WINAPI IXAudio2Impl_Initialize(IXAudio2 *iface, UINT32 flags, XAUDIO2_PROCESSOR processor)
1492 IXAudio2Impl *audio = impl_from_IXAudio2(iface);
1494 TRACE("%p, %#x, %#x\n", audio, flags, processor);
1496 return xaudio2_initialize(audio, flags, processor);
1498 #endif
1500 static HRESULT WINAPI IXAudio2Impl_RegisterForCallbacks(IXAudio2 *iface,
1501 IXAudio2EngineCallback *pCallback)
1503 IXAudio2Impl *This = impl_from_IXAudio2(iface);
1504 int i;
1506 TRACE("(%p)->(%p)\n", This, pCallback);
1508 EnterCriticalSection(&This->lock);
1510 for(i = 0; i < This->ncbs; ++i){
1511 if(!This->cbs[i] || This->cbs[i] == pCallback){
1512 This->cbs[i] = pCallback;
1513 LeaveCriticalSection(&This->lock);
1514 return S_OK;
1518 This->ncbs++;
1519 This->cbs = heap_realloc(This->cbs, This->ncbs * sizeof(*This->cbs));
1521 This->cbs[i] = pCallback;
1523 LeaveCriticalSection(&This->lock);
1525 return S_OK;
1528 static void WINAPI IXAudio2Impl_UnregisterForCallbacks(IXAudio2 *iface,
1529 IXAudio2EngineCallback *pCallback)
1531 IXAudio2Impl *This = impl_from_IXAudio2(iface);
1532 int i;
1534 TRACE("(%p)->(%p)\n", This, pCallback);
1536 EnterCriticalSection(&This->lock);
1538 if(This->ncbs == 0){
1539 LeaveCriticalSection(&This->lock);
1540 return;
1543 for(i = 0; i < This->ncbs; ++i){
1544 if(This->cbs[i] == pCallback)
1545 break;
1548 for(; i < This->ncbs - 1 && This->cbs[i + 1]; ++i)
1549 This->cbs[i] = This->cbs[i + 1];
1551 if(i < This->ncbs)
1552 This->cbs[i] = NULL;
1554 LeaveCriticalSection(&This->lock);
1557 static inline XA2VoiceImpl *create_voice(IXAudio2Impl *This)
1559 XA2VoiceImpl *voice;
1561 voice = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*voice));
1562 if(!voice)
1563 return NULL;
1565 list_add_head(&This->voices, &voice->entry);
1567 voice->IXAudio2SourceVoice_iface.lpVtbl = &XAudio2SourceVoice_Vtbl;
1568 voice->IXAudio2SubmixVoice_iface.lpVtbl = &XAudio2SubmixVoice_Vtbl;
1569 voice->FAudioVoiceCallback_vtbl = FAudioVoiceCallback_Vtbl;
1571 InitializeCriticalSection(&voice->lock);
1572 voice->lock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": XA2VoiceImpl.lock");
1574 return voice;
1577 static HRESULT WINAPI IXAudio2Impl_CreateSourceVoice(IXAudio2 *iface,
1578 IXAudio2SourceVoice **ppSourceVoice, const WAVEFORMATEX *pSourceFormat,
1579 UINT32 flags, float maxFrequencyRatio,
1580 IXAudio2VoiceCallback *pCallback, const XAUDIO2_VOICE_SENDS *pSendList,
1581 const XAUDIO2_EFFECT_CHAIN *pEffectChain)
1583 IXAudio2Impl *This = impl_from_IXAudio2(iface);
1584 XA2VoiceImpl *src;
1585 HRESULT hr;
1586 FAudioVoiceSends *faudio_sends;
1588 TRACE("(%p)->(%p, %p, 0x%x, %f, %p, %p, %p)\n", This, ppSourceVoice,
1589 pSourceFormat, flags, maxFrequencyRatio, pCallback, pSendList,
1590 pEffectChain);
1592 EnterCriticalSection(&This->lock);
1594 LIST_FOR_EACH_ENTRY(src, &This->voices, XA2VoiceImpl, entry){
1595 EnterCriticalSection(&src->lock);
1596 if(!src->in_use)
1597 break;
1598 LeaveCriticalSection(&src->lock);
1601 if(&src->entry == &This->voices){
1602 src = create_voice(This);
1603 EnterCriticalSection(&src->lock);
1606 LeaveCriticalSection(&This->lock);
1608 src->effect_chain = wrap_effect_chain(pEffectChain);
1609 faudio_sends = wrap_voice_sends(pSendList);
1611 hr = FAudio_CreateSourceVoice(This->faudio, &src->faudio_voice,
1612 (FAudioWaveFormatEx*)pSourceFormat, flags, maxFrequencyRatio,
1613 &src->FAudioVoiceCallback_vtbl, faudio_sends,
1614 src->effect_chain);
1615 free_voice_sends(faudio_sends);
1616 if(FAILED(hr)){
1617 LeaveCriticalSection(&This->lock);
1618 return hr;
1620 src->in_use = TRUE;
1621 src->cb = pCallback;
1623 LeaveCriticalSection(&src->lock);
1625 *ppSourceVoice = &src->IXAudio2SourceVoice_iface;
1627 TRACE("Created source voice: %p\n", src);
1629 return S_OK;
1632 static HRESULT WINAPI IXAudio2Impl_CreateSubmixVoice(IXAudio2 *iface,
1633 IXAudio2SubmixVoice **ppSubmixVoice, UINT32 inputChannels,
1634 UINT32 inputSampleRate, UINT32 flags, UINT32 processingStage,
1635 const XAUDIO2_VOICE_SENDS *pSendList,
1636 const XAUDIO2_EFFECT_CHAIN *pEffectChain)
1638 HRESULT hr;
1639 IXAudio2Impl *This = impl_from_IXAudio2(iface);
1640 XA2VoiceImpl *sub;
1641 FAudioVoiceSends *faudio_sends;
1643 TRACE("(%p)->(%p, %u, %u, 0x%x, %u, %p, %p)\n", This, ppSubmixVoice,
1644 inputChannels, inputSampleRate, flags, processingStage, pSendList,
1645 pEffectChain);
1647 EnterCriticalSection(&This->lock);
1649 LIST_FOR_EACH_ENTRY(sub, &This->voices, XA2VoiceImpl, entry){
1650 EnterCriticalSection(&sub->lock);
1651 if(!sub->in_use)
1652 break;
1653 LeaveCriticalSection(&sub->lock);
1656 if(&sub->entry == &This->voices){
1657 sub = create_voice(This);
1658 EnterCriticalSection(&sub->lock);
1661 LeaveCriticalSection(&This->lock);
1663 sub->effect_chain = wrap_effect_chain(pEffectChain);
1664 faudio_sends = wrap_voice_sends(pSendList);
1666 hr = FAudio_CreateSubmixVoice(This->faudio, &sub->faudio_voice, inputChannels,
1667 inputSampleRate, flags, processingStage, faudio_sends,
1668 sub->effect_chain);
1669 free_voice_sends(faudio_sends);
1670 if(FAILED(hr)){
1671 LeaveCriticalSection(&sub->lock);
1672 return hr;
1674 sub->in_use = TRUE;
1676 LeaveCriticalSection(&sub->lock);
1678 *ppSubmixVoice = &sub->IXAudio2SubmixVoice_iface;
1680 TRACE("Created submix voice: %p\n", sub);
1682 return S_OK;
1685 static HRESULT WINAPI IXAudio2Impl_CreateMasteringVoice(IXAudio2 *iface,
1686 IXAudio2MasteringVoice **ppMasteringVoice, UINT32 inputChannels,
1687 UINT32 inputSampleRate, UINT32 flags,
1688 #if XAUDIO2_VER >= 8
1689 const WCHAR *deviceId,
1690 #else
1691 UINT32 index,
1692 #endif
1693 const XAUDIO2_EFFECT_CHAIN *pEffectChain
1694 #if XAUDIO2_VER >= 8
1695 , AUDIO_STREAM_CATEGORY streamCategory
1696 #endif
1699 IXAudio2Impl *This = impl_from_IXAudio2(iface);
1701 TRACE("(%p)->(%p, %u, %u, 0x%x, %p)\n", This,
1702 ppMasteringVoice, inputChannels, inputSampleRate, flags, pEffectChain);
1704 EnterCriticalSection(&This->lock);
1706 *ppMasteringVoice = &This->mst.IXAudio2MasteringVoice_iface;
1708 EnterCriticalSection(&This->mst.lock);
1710 if(This->mst.in_use){
1711 LeaveCriticalSection(&This->mst.lock);
1712 LeaveCriticalSection(&This->lock);
1713 return COMPAT_E_INVALID_CALL;
1716 LeaveCriticalSection(&This->lock);
1718 This->mst.effect_chain = wrap_effect_chain(pEffectChain);
1720 #if XAUDIO2_VER >= 8
1721 TRACE("device id %s, category %#x\n", debugstr_w(deviceId), streamCategory);
1723 FAudio_CreateMasteringVoice8(This->faudio, &This->mst.faudio_voice, inputChannels,
1724 inputSampleRate, flags, NULL /* TODO: (uint16_t*)deviceId */,
1725 This->mst.effect_chain, (FAudioStreamCategory)streamCategory);
1726 #else
1727 TRACE("device index %u\n", index);
1729 FAudio_CreateMasteringVoice(This->faudio, &This->mst.faudio_voice, inputChannels,
1730 inputSampleRate, flags, index, This->mst.effect_chain);
1731 #endif
1733 This->mst.in_use = TRUE;
1735 LeaveCriticalSection(&This->mst.lock);
1737 return S_OK;
1740 static HRESULT WINAPI IXAudio2Impl_StartEngine(IXAudio2 *iface)
1742 IXAudio2Impl *This = impl_from_IXAudio2(iface);
1744 TRACE("(%p)->()\n", This);
1746 return FAudio_StartEngine(This->faudio);
1749 static void WINAPI IXAudio2Impl_StopEngine(IXAudio2 *iface)
1751 IXAudio2Impl *This = impl_from_IXAudio2(iface);
1753 TRACE("(%p)->()\n", This);
1755 FAudio_StopEngine(This->faudio);
1758 static HRESULT WINAPI IXAudio2Impl_CommitChanges(IXAudio2 *iface,
1759 UINT32 operationSet)
1761 IXAudio2Impl *This = impl_from_IXAudio2(iface);
1763 TRACE("(%p)->(0x%x)\n", This, operationSet);
1765 return FAudio_CommitOperationSet(This->faudio, operationSet);
1768 static void WINAPI IXAudio2Impl_GetPerformanceData(IXAudio2 *iface, XAUDIO2_PERFORMANCE_DATA *data)
1770 IXAudio2Impl *audio = impl_from_IXAudio2(iface);
1771 FAudioPerformanceData faudio_data;
1773 TRACE("(%p)->(%p)\n", audio, data);
1775 FAudio_GetPerformanceData(audio->faudio, &faudio_data);
1777 data->AudioCyclesSinceLastQuery = faudio_data.AudioCyclesSinceLastQuery;
1778 data->TotalCyclesSinceLastQuery = faudio_data.TotalCyclesSinceLastQuery;
1779 data->MinimumCyclesPerQuantum = faudio_data.MinimumCyclesPerQuantum;
1780 data->MaximumCyclesPerQuantum = faudio_data.MaximumCyclesPerQuantum;
1781 data->MemoryUsageInBytes = faudio_data.MemoryUsageInBytes;
1782 data->CurrentLatencyInSamples = faudio_data.CurrentLatencyInSamples;
1783 #if XAUDIO2_VER == 0
1784 data->GlitchesSinceLastQuery = faudio_data.GlitchesSinceEngineStarted - audio->last_query_glitches;
1785 audio->last_query_glitches = faudio_data.GlitchesSinceEngineStarted;
1786 #else
1787 data->GlitchesSinceEngineStarted = faudio_data.GlitchesSinceEngineStarted;
1788 #endif
1789 data->ActiveSourceVoiceCount = faudio_data.ActiveSourceVoiceCount;
1790 data->TotalSourceVoiceCount = faudio_data.TotalSourceVoiceCount;
1791 data->ActiveSubmixVoiceCount = faudio_data.ActiveSubmixVoiceCount;
1792 #if XAUDIO2_VER <= 2
1793 data->TotalSubmixVoiceCount = faudio_data.ActiveSubmixVoiceCount;
1794 #else
1795 data->ActiveResamplerCount = faudio_data.ActiveResamplerCount;
1796 data->ActiveMatrixMixCount = faudio_data.ActiveMatrixMixCount;
1797 #endif
1798 data->ActiveXmaSourceVoices = faudio_data.ActiveXmaSourceVoices;
1799 data->ActiveXmaStreams = faudio_data.ActiveXmaStreams;
1802 static void WINAPI IXAudio2Impl_SetDebugConfiguration(IXAudio2 *iface,
1803 const XAUDIO2_DEBUG_CONFIGURATION *pDebugConfiguration,
1804 void *pReserved)
1806 IXAudio2Impl *This = impl_from_IXAudio2(iface);
1808 TRACE("(%p)->(%p, %p)\n", This, pDebugConfiguration, pReserved);
1810 FAudio_SetDebugConfiguration(This->faudio, (FAudioDebugConfiguration *)pDebugConfiguration, pReserved);
1813 static const IXAudio2Vtbl XAudio2_Vtbl =
1815 IXAudio2Impl_QueryInterface,
1816 IXAudio2Impl_AddRef,
1817 IXAudio2Impl_Release,
1818 #if XAUDIO2_VER <= 7
1819 IXAudio2Impl_GetDeviceCount,
1820 IXAudio2Impl_GetDeviceDetails,
1821 IXAudio2Impl_Initialize,
1822 #endif
1823 IXAudio2Impl_RegisterForCallbacks,
1824 IXAudio2Impl_UnregisterForCallbacks,
1825 IXAudio2Impl_CreateSourceVoice,
1826 IXAudio2Impl_CreateSubmixVoice,
1827 IXAudio2Impl_CreateMasteringVoice,
1828 IXAudio2Impl_StartEngine,
1829 IXAudio2Impl_StopEngine,
1830 IXAudio2Impl_CommitChanges,
1831 IXAudio2Impl_GetPerformanceData,
1832 IXAudio2Impl_SetDebugConfiguration
1835 /* XAudio2 ClassFactory */
1837 struct xaudio2_cf {
1838 IClassFactory IClassFactory_iface;
1839 LONG ref;
1842 static struct xaudio2_cf *impl_from_IClassFactory(IClassFactory *iface)
1844 return CONTAINING_RECORD(iface, struct xaudio2_cf, IClassFactory_iface);
1847 static HRESULT WINAPI XAudio2CF_QueryInterface(IClassFactory *iface, REFIID riid, void **ppobj)
1849 if(IsEqualGUID(riid, &IID_IUnknown)
1850 || IsEqualGUID(riid, &IID_IClassFactory))
1852 IClassFactory_AddRef(iface);
1853 *ppobj = iface;
1854 return S_OK;
1857 *ppobj = NULL;
1858 WARN("(%p)->(%s, %p): interface not found\n", iface, debugstr_guid(riid), ppobj);
1859 return E_NOINTERFACE;
1862 static ULONG WINAPI XAudio2CF_AddRef(IClassFactory *iface)
1864 struct xaudio2_cf *This = impl_from_IClassFactory(iface);
1865 ULONG ref = InterlockedIncrement(&This->ref);
1866 TRACE("(%p)->(): Refcount now %lu\n", This, ref);
1867 return ref;
1870 static ULONG WINAPI XAudio2CF_Release(IClassFactory *iface)
1872 struct xaudio2_cf *This = impl_from_IClassFactory(iface);
1873 ULONG ref = InterlockedDecrement(&This->ref);
1874 TRACE("(%p)->(): Refcount now %lu\n", This, ref);
1875 if (!ref)
1876 HeapFree(GetProcessHeap(), 0, This);
1877 return ref;
1880 static HRESULT WINAPI XAudio2CF_CreateInstance(IClassFactory *iface, IUnknown *pOuter,
1881 REFIID riid, void **ppobj)
1883 struct xaudio2_cf *This = impl_from_IClassFactory(iface);
1884 HRESULT hr;
1885 IXAudio2Impl *object;
1887 TRACE("(%p)->(%p,%s,%p)\n", This, pOuter, debugstr_guid(riid), ppobj);
1889 *ppobj = NULL;
1891 if(pOuter)
1892 return CLASS_E_NOAGGREGATION;
1894 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
1895 if(!object)
1896 return E_OUTOFMEMORY;
1898 object->IXAudio2_iface.lpVtbl = &XAudio2_Vtbl;
1899 object->mst.IXAudio2MasteringVoice_iface.lpVtbl = &XAudio2MasteringVoice_Vtbl;
1901 object->FAudioEngineCallback_vtbl = FAudioEngineCallback_Vtbl;
1903 list_init(&object->voices);
1905 InitializeCriticalSection(&object->lock);
1906 object->lock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": IXAudio2Impl.lock");
1908 InitializeCriticalSection(&object->mst.lock);
1909 object->mst.lock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": XA2MasteringVoice.lock");
1911 FAudioCOMConstructWithCustomAllocatorEXT(
1912 &object->faudio,
1913 XAUDIO2_VER,
1914 XAudio_Internal_Malloc,
1915 XAudio_Internal_Free,
1916 XAudio_Internal_Realloc
1919 FAudio_RegisterForCallbacks(object->faudio, &object->FAudioEngineCallback_vtbl);
1921 hr = IXAudio2_QueryInterface(&object->IXAudio2_iface, riid, ppobj);
1922 IXAudio2_Release(&object->IXAudio2_iface);
1923 if(FAILED(hr)){
1924 return hr;
1927 TRACE("Created XAudio version %u: %p\n", 20 + XAUDIO2_VER, object);
1929 return hr;
1932 static HRESULT WINAPI XAudio2CF_LockServer(IClassFactory *iface, BOOL dolock)
1934 struct xaudio2_cf *This = impl_from_IClassFactory(iface);
1935 FIXME("(%p)->(%d): stub!\n", This, dolock);
1936 return S_OK;
1939 static const IClassFactoryVtbl XAudio2CF_Vtbl =
1941 XAudio2CF_QueryInterface,
1942 XAudio2CF_AddRef,
1943 XAudio2CF_Release,
1944 XAudio2CF_CreateInstance,
1945 XAudio2CF_LockServer
1948 /* Engine Generators */
1950 static inline HRESULT make_xaudio2_factory(REFIID riid, void **ppv)
1952 HRESULT hr;
1953 struct xaudio2_cf *ret = HeapAlloc(GetProcessHeap(), 0, sizeof(struct xaudio2_cf));
1954 ret->IClassFactory_iface.lpVtbl = &XAudio2CF_Vtbl;
1955 ret->ref = 0;
1956 hr = IClassFactory_QueryInterface(&ret->IClassFactory_iface, riid, ppv);
1957 if(FAILED(hr))
1958 HeapFree(GetProcessHeap(), 0, ret);
1959 return hr;
1962 HRESULT xaudio2_initialize(IXAudio2Impl *This, UINT32 flags, XAUDIO2_PROCESSOR proc)
1964 if(proc != XAUDIO2_ANY_PROCESSOR)
1965 WARN("Processor affinity not implemented in FAudio\n");
1966 return FAudio_Initialize(This->faudio, flags, FAUDIO_DEFAULT_PROCESSOR);
1969 #if XAUDIO2_VER <= 7
1970 HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, void **ppv)
1972 TRACE("(%s, %s, %p)\n", debugstr_guid(rclsid), debugstr_guid(riid), ppv);
1974 if (IsEqualGUID(rclsid, &CLSID_XAudio2))
1975 return make_xaudio2_factory(riid, ppv);
1977 if (IsEqualGUID(rclsid, &CLSID_AudioVolumeMeter))
1978 return make_xapo_factory(&CLSID_AudioVolumeMeter, riid, ppv);
1980 if (IsEqualGUID(rclsid, &CLSID_AudioReverb))
1981 return make_xapo_factory(&CLSID_AudioReverb, riid, ppv);
1983 return CLASS_E_CLASSNOTAVAILABLE;
1985 #else
1986 HRESULT WINAPI XAudio2Create(IXAudio2 **ppxa2, UINT32 flags, XAUDIO2_PROCESSOR proc)
1988 HRESULT hr;
1989 IXAudio2 *xa2;
1990 IClassFactory *cf;
1992 TRACE("%p 0x%x 0x%x\n", ppxa2, flags, proc);
1994 hr = make_xaudio2_factory(&IID_IClassFactory, (void**)&cf);
1995 if(FAILED(hr))
1996 return hr;
1998 hr = IClassFactory_CreateInstance(cf, NULL, &IID_IXAudio2, (void**)&xa2);
1999 IClassFactory_Release(cf);
2000 if(FAILED(hr))
2001 return hr;
2003 hr = xaudio2_initialize(impl_from_IXAudio2(xa2), flags, proc);
2004 if(FAILED(hr)){
2005 IXAudio2_Release(xa2);
2006 return hr;
2009 *ppxa2 = xa2;
2011 return S_OK;
2013 #endif /* XAUDIO2_VER >= 8 */