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
29 #include "xaudio_private.h"
30 #include "xaudio2fx.h"
39 #include "wine/debug.h"
40 #include "wine/heap.h"
42 WINE_DEFAULT_DEBUG_CHANNEL(xaudio2
);
44 #if XAUDIO2_VER != 0 && defined(__i386__)
45 /* EVE Online uses an OnVoiceProcessingPassStart callback which corrupts %esi;
46 * League of Legends uses a callback which corrupts %ebx. */
47 #define IXAudio2VoiceCallback_OnVoiceProcessingPassStart(a, b) call_on_voice_processing_pass_start(a, b)
48 extern void call_on_voice_processing_pass_start(IXAudio2VoiceCallback
*This
, UINT32 BytesRequired
);
49 __ASM_GLOBAL_FUNC( call_on_voice_processing_pass_start
,
51 __ASM_CFI(".cfi_adjust_cfa_offset 4\n\t")
52 __ASM_CFI(".cfi_rel_offset %ebp,0\n\t")
54 __ASM_CFI(".cfi_def_cfa_register %ebp\n\t")
56 __ASM_CFI(".cfi_rel_offset %esi,-4\n\t")
58 __ASM_CFI(".cfi_rel_offset %edi,-8\n\t")
60 __ASM_CFI(".cfi_rel_offset %ebx,-12\n\t")
62 "pushl 12(%ebp)\n\t" /* BytesRequired */
63 "pushl 8(%ebp)\n\t" /* This */
64 "movl 8(%ebp),%eax\n\t"
65 "movl 0(%eax),%eax\n\t"
66 "call *0(%eax)\n\t" /* This->lpVtbl->OnVoiceProcessingPassStart */
67 "leal -12(%ebp),%esp\n\t"
69 __ASM_CFI(".cfi_same_value %ebx\n\t")
71 __ASM_CFI(".cfi_same_value %edi\n\t")
73 __ASM_CFI(".cfi_same_value %esi\n\t")
75 __ASM_CFI(".cfi_def_cfa %esp,4\n\t")
76 __ASM_CFI(".cfi_same_value %ebp\n\t")
80 static HINSTANCE instance
;
82 static XA2VoiceImpl
*impl_from_IXAudio2Voice(IXAudio2Voice
*iface
);
84 BOOL WINAPI
DllMain(HINSTANCE hinstDLL
, DWORD reason
, void *pReserved
)
86 TRACE("(%p, %d, %p)\n", hinstDLL
, reason
, pReserved
);
90 case DLL_PROCESS_ATTACH
:
92 DisableThreadLibraryCalls( hinstDLL
);
93 #ifdef HAVE_FAUDIOLINKEDVERSION
94 TRACE("Using FAudio version %d\n", FAudioLinkedVersion() );
101 HRESULT WINAPI
DllCanUnloadNow(void)
106 HRESULT WINAPI
DllRegisterServer(void)
109 return __wine_register_resources(instance
);
112 HRESULT WINAPI
DllUnregisterServer(void)
115 return __wine_unregister_resources(instance
);
118 /* Effect Wrapping */
120 static inline XA2XAPOImpl
*impl_from_FAPO(FAPO
*iface
)
122 return CONTAINING_RECORD(iface
, XA2XAPOImpl
, FAPO_vtbl
);
125 static int32_t FAPOCALL
XAPO_AddRef(void *iface
)
127 XA2XAPOImpl
*This
= impl_from_FAPO(iface
);
129 return InterlockedIncrement(&This
->ref
);
132 static int32_t FAPOCALL
XAPO_Release(void *iface
)
135 XA2XAPOImpl
*This
= impl_from_FAPO(iface
);
137 r
= InterlockedDecrement(&This
->ref
);
139 IXAPO_Release(This
->xapo
);
140 if(This
->xapo_params
)
141 IXAPOParameters_Release(This
->xapo_params
);
147 static uint32_t FAPOCALL
XAPO_GetRegistrationProperties(void *iface
,
148 FAPORegistrationProperties
**ppRegistrationProperties
)
150 XA2XAPOImpl
*This
= impl_from_FAPO(iface
);
151 XAPO_REGISTRATION_PROPERTIES
*xprops
;
156 hr
= IXAPO_GetRegistrationProperties(This
->xapo
, &xprops
);
160 /* TODO: check for version == 20 and use XAPO20_REGISTRATION_PROPERTIES */
161 *ppRegistrationProperties
= (FAPORegistrationProperties
*) xprops
;
165 static uint32_t FAPOCALL
XAPO_IsInputFormatSupported(void *iface
,
166 const FAudioWaveFormatEx
*pOutputFormat
, const FAudioWaveFormatEx
*pRequestedInputFormat
,
167 FAudioWaveFormatEx
**ppSupportedInputFormat
)
169 XA2XAPOImpl
*This
= impl_from_FAPO(iface
);
171 return IXAPO_IsInputFormatSupported(This
->xapo
, (const WAVEFORMATEX
*)pOutputFormat
,
172 (const WAVEFORMATEX
*)pRequestedInputFormat
, (WAVEFORMATEX
**)ppSupportedInputFormat
);
175 static uint32_t FAPOCALL
XAPO_IsOutputFormatSupported(void *iface
,
176 const FAudioWaveFormatEx
*pInputFormat
, const FAudioWaveFormatEx
*pRequestedOutputFormat
,
177 FAudioWaveFormatEx
**ppSupportedOutputFormat
)
179 XA2XAPOImpl
*This
= impl_from_FAPO(iface
);
181 return IXAPO_IsOutputFormatSupported(This
->xapo
, (const WAVEFORMATEX
*)pInputFormat
,
182 (const WAVEFORMATEX
*)pRequestedOutputFormat
, (WAVEFORMATEX
**)ppSupportedOutputFormat
);
185 static uint32_t FAPOCALL
XAPO_Initialize(void *iface
, const void *pData
,
186 uint32_t DataByteSize
)
188 XA2XAPOImpl
*This
= impl_from_FAPO(iface
);
190 return IXAPO_Initialize(This
->xapo
, pData
, DataByteSize
);
193 static void FAPOCALL
XAPO_Reset(void *iface
)
195 XA2XAPOImpl
*This
= impl_from_FAPO(iface
);
197 IXAPO_Reset(This
->xapo
);
200 static uint32_t FAPOCALL
XAPO_LockForProcess(void *iface
,
201 uint32_t InputLockedParameterCount
,
202 const FAPOLockForProcessBufferParameters
*pInputLockedParameters
,
203 uint32_t OutputLockedParameterCount
,
204 const FAPOLockForProcessBufferParameters
*pOutputLockedParameters
)
206 XA2XAPOImpl
*This
= impl_from_FAPO(iface
);
208 return IXAPO_LockForProcess(This
->xapo
,
209 InputLockedParameterCount
,
210 (const XAPO_LOCKFORPROCESS_BUFFER_PARAMETERS
*)pInputLockedParameters
,
211 OutputLockedParameterCount
,
212 (const XAPO_LOCKFORPROCESS_BUFFER_PARAMETERS
*)pOutputLockedParameters
);
215 static void FAPOCALL
XAPO_UnlockForProcess(void *iface
)
217 XA2XAPOImpl
*This
= impl_from_FAPO(iface
);
219 IXAPO_UnlockForProcess(This
->xapo
);
222 static void FAPOCALL
XAPO_Process(void *iface
,
223 uint32_t InputProcessParameterCount
,
224 const FAPOProcessBufferParameters
* pInputProcessParameters
,
225 uint32_t OutputProcessParameterCount
,
226 FAPOProcessBufferParameters
* pOutputProcessParameters
,
229 XA2XAPOImpl
*This
= impl_from_FAPO(iface
);
231 IXAPO_Process(This
->xapo
, InputProcessParameterCount
,
232 (const XAPO_PROCESS_BUFFER_PARAMETERS
*)pInputProcessParameters
,
233 OutputProcessParameterCount
,
234 (XAPO_PROCESS_BUFFER_PARAMETERS
*)pOutputProcessParameters
,
238 static uint32_t FAPOCALL
XAPO_CalcInputFrames(void *iface
,
239 uint32_t OutputFrameCount
)
241 XA2XAPOImpl
*This
= impl_from_FAPO(iface
);
243 return IXAPO_CalcInputFrames(This
->xapo
, OutputFrameCount
);
246 static uint32_t FAPOCALL
XAPO_CalcOutputFrames(void *iface
,
247 uint32_t InputFrameCount
)
249 XA2XAPOImpl
*This
= impl_from_FAPO(iface
);
251 return IXAPO_CalcOutputFrames(This
->xapo
, InputFrameCount
);
254 static void FAPOCALL
XAPO_SetParameters(void *iface
,
255 const void *pParameters
, uint32_t ParametersByteSize
)
257 XA2XAPOImpl
*This
= impl_from_FAPO(iface
);
259 if(This
->xapo_params
)
260 IXAPOParameters_SetParameters(This
->xapo_params
, pParameters
, ParametersByteSize
);
263 static void FAPOCALL
XAPO_GetParameters(void *iface
,
264 void *pParameters
, uint32_t ParametersByteSize
)
266 XA2XAPOImpl
*This
= impl_from_FAPO(iface
);
268 if(This
->xapo_params
)
269 IXAPOParameters_GetParameters(This
->xapo_params
, pParameters
, ParametersByteSize
);
271 memset(pParameters
, 0, ParametersByteSize
);
274 static const FAPO FAPO_Vtbl
= {
277 XAPO_GetRegistrationProperties
,
278 XAPO_IsInputFormatSupported
,
279 XAPO_IsOutputFormatSupported
,
283 XAPO_UnlockForProcess
,
285 XAPO_CalcInputFrames
,
286 XAPO_CalcOutputFrames
,
291 static XA2XAPOImpl
*wrap_xapo(IUnknown
*unk
)
295 IXAPOParameters
*xapo_params
;
299 hr
= IUnknown_QueryInterface(unk
, &IID_IXAPO27
, (void**)&xapo
);
301 hr
= IUnknown_QueryInterface(unk
, &IID_IXAPO
, (void**)&xapo
);
304 WARN("XAPO doesn't support IXAPO? %p\n", unk
);
309 hr
= IUnknown_QueryInterface(unk
, &IID_IXAPO27Parameters
, (void**)&xapo_params
);
311 hr
= IUnknown_QueryInterface(unk
, &IID_IXAPOParameters
, (void**)&xapo_params
);
314 TRACE("XAPO doesn't support IXAPOParameters %p\n", unk
);
318 ret
= heap_alloc(sizeof(*ret
));
321 ret
->xapo_params
= xapo_params
;
322 ret
->FAPO_vtbl
= FAPO_Vtbl
;
325 TRACE("wrapped IXAPO %p with %p\n", xapo
, ret
);
330 FAudioEffectChain
*wrap_effect_chain(const XAUDIO2_EFFECT_CHAIN
*pEffectChain
)
332 FAudioEffectChain
*ret
;
338 ret
= heap_alloc(sizeof(*ret
) + sizeof(FAudioEffectDescriptor
) * pEffectChain
->EffectCount
);
340 ret
->EffectCount
= pEffectChain
->EffectCount
;
341 ret
->pEffectDescriptors
= (void*)(ret
+ 1);
343 for(i
= 0; i
< ret
->EffectCount
; ++i
){
344 ret
->pEffectDescriptors
[i
].pEffect
= &wrap_xapo(pEffectChain
->pEffectDescriptors
[i
].pEffect
)->FAPO_vtbl
;
345 ret
->pEffectDescriptors
[i
].InitialState
= pEffectChain
->pEffectDescriptors
[i
].InitialState
;
346 ret
->pEffectDescriptors
[i
].OutputChannels
= pEffectChain
->pEffectDescriptors
[i
].OutputChannels
;
352 static void free_effect_chain(FAudioEffectChain
*chain
)
357 for(i
= 0; i
< chain
->EffectCount
; ++i
)
358 XAPO_Release(chain
->pEffectDescriptors
[i
].pEffect
);
364 static FAudioVoiceSends
*wrap_voice_sends(const XAUDIO2_VOICE_SENDS
*sends
)
366 FAudioVoiceSends
*ret
;
372 ret
= heap_alloc(sizeof(*ret
) + sends
->SendCount
* sizeof(FAudioSendDescriptor
));
373 ret
->SendCount
= sends
->SendCount
;
374 ret
->pSends
= (FAudioSendDescriptor
*)(ret
+ 1);
375 for(i
= 0; i
< sends
->SendCount
; ++i
){
376 XA2VoiceImpl
*voice
= impl_from_IXAudio2Voice(sends
->pSends
[i
].pOutputVoice
);
377 ret
->pSends
[i
].pOutputVoice
= voice
->faudio_voice
;
378 ret
->pSends
[i
].Flags
= sends
->pSends
[i
].Flags
;
383 static void free_voice_sends(FAudioVoiceSends
*sends
)
390 /* Voice Callbacks */
392 static inline XA2VoiceImpl
*impl_from_FAudioVoiceCallback(FAudioVoiceCallback
*iface
)
394 return CONTAINING_RECORD(iface
, XA2VoiceImpl
, FAudioVoiceCallback_vtbl
);
397 static void FAUDIOCALL
XA2VCB_OnVoiceProcessingPassStart(FAudioVoiceCallback
*iface
,
398 UINT32 BytesRequired
)
400 XA2VoiceImpl
*This
= impl_from_FAudioVoiceCallback(iface
);
404 IXAudio20VoiceCallback_OnVoiceProcessingPassStart((IXAudio20VoiceCallback
*)This
->cb
);
406 IXAudio2VoiceCallback_OnVoiceProcessingPassStart(This
->cb
, BytesRequired
);
410 static void FAUDIOCALL
XA2VCB_OnVoiceProcessingPassEnd(FAudioVoiceCallback
*iface
)
412 XA2VoiceImpl
*This
= impl_from_FAudioVoiceCallback(iface
);
415 IXAudio2VoiceCallback_OnVoiceProcessingPassEnd(This
->cb
);
418 static void FAUDIOCALL
XA2VCB_OnStreamEnd(FAudioVoiceCallback
*iface
)
420 XA2VoiceImpl
*This
= impl_from_FAudioVoiceCallback(iface
);
423 IXAudio2VoiceCallback_OnStreamEnd(This
->cb
);
426 static void FAUDIOCALL
XA2VCB_OnBufferStart(FAudioVoiceCallback
*iface
,
427 void *pBufferContext
)
429 XA2VoiceImpl
*This
= impl_from_FAudioVoiceCallback(iface
);
432 IXAudio2VoiceCallback_OnBufferStart(This
->cb
, pBufferContext
);
435 static void FAUDIOCALL
XA2VCB_OnBufferEnd(FAudioVoiceCallback
*iface
,
436 void *pBufferContext
)
438 XA2VoiceImpl
*This
= impl_from_FAudioVoiceCallback(iface
);
441 IXAudio2VoiceCallback_OnBufferEnd(This
->cb
, pBufferContext
);
444 static void FAUDIOCALL
XA2VCB_OnLoopEnd(FAudioVoiceCallback
*iface
,
445 void *pBufferContext
)
447 XA2VoiceImpl
*This
= impl_from_FAudioVoiceCallback(iface
);
450 IXAudio2VoiceCallback_OnLoopEnd(This
->cb
, pBufferContext
);
453 static void FAUDIOCALL
XA2VCB_OnVoiceError(FAudioVoiceCallback
*iface
,
454 void *pBufferContext
, unsigned int Error
)
456 XA2VoiceImpl
*This
= impl_from_FAudioVoiceCallback(iface
);
459 IXAudio2VoiceCallback_OnVoiceError(This
->cb
, pBufferContext
, (HRESULT
)Error
);
462 static const FAudioVoiceCallback FAudioVoiceCallback_Vtbl
= {
464 XA2VCB_OnBufferStart
,
468 XA2VCB_OnVoiceProcessingPassEnd
,
469 XA2VCB_OnVoiceProcessingPassStart
472 /* Engine Callbacks */
474 static inline IXAudio2Impl
*impl_from_FAudioEngineCallback(FAudioEngineCallback
*iface
)
476 return CONTAINING_RECORD(iface
, IXAudio2Impl
, FAudioEngineCallback_vtbl
);
479 static void FAUDIOCALL
XA2ECB_OnProcessingPassStart(FAudioEngineCallback
*iface
)
481 IXAudio2Impl
*This
= impl_from_FAudioEngineCallback(iface
);
484 for(i
= 0; i
< This
->ncbs
&& This
->cbs
[i
]; ++i
)
485 IXAudio2EngineCallback_OnProcessingPassStart(This
->cbs
[i
]);
488 static void FAUDIOCALL
XA2ECB_OnProcessingPassEnd(FAudioEngineCallback
*iface
)
490 IXAudio2Impl
*This
= impl_from_FAudioEngineCallback(iface
);
493 for(i
= 0; i
< This
->ncbs
&& This
->cbs
[i
]; ++i
)
494 IXAudio2EngineCallback_OnProcessingPassEnd(This
->cbs
[i
]);
497 static void FAUDIOCALL
XA2ECB_OnCriticalError(FAudioEngineCallback
*iface
,
500 IXAudio2Impl
*This
= impl_from_FAudioEngineCallback(iface
);
503 for(i
= 0; i
< This
->ncbs
&& This
->cbs
[i
]; ++i
)
504 IXAudio2EngineCallback_OnCriticalError(This
->cbs
[i
], error
);
507 static const FAudioEngineCallback FAudioEngineCallback_Vtbl
= {
508 XA2ECB_OnCriticalError
,
509 XA2ECB_OnProcessingPassEnd
,
510 XA2ECB_OnProcessingPassStart
513 /* Common Voice Functions */
515 static inline void destroy_voice(XA2VoiceImpl
*This
)
517 FAudioVoice_DestroyVoice(This
->faudio_voice
);
518 free_effect_chain(This
->effect_chain
);
519 This
->effect_chain
= NULL
;
520 This
->in_use
= FALSE
;
525 static inline XA2VoiceImpl
*impl_from_IXAudio2SourceVoice(IXAudio2SourceVoice
*iface
)
527 return CONTAINING_RECORD(iface
, XA2VoiceImpl
, IXAudio2SourceVoice_iface
);
530 static void WINAPI
XA2SRC_GetVoiceDetails(IXAudio2SourceVoice
*iface
,
531 XAUDIO2_VOICE_DETAILS
*pVoiceDetails
)
533 XA2VoiceImpl
*This
= impl_from_IXAudio2SourceVoice(iface
);
534 TRACE("%p, %p\n", This
, pVoiceDetails
);
535 FAudioVoice_GetVoiceDetails(This
->faudio_voice
, (FAudioVoiceDetails
*)pVoiceDetails
);
538 static HRESULT WINAPI
XA2SRC_SetOutputVoices(IXAudio2SourceVoice
*iface
,
539 const XAUDIO2_VOICE_SENDS
*pSendList
)
541 XA2VoiceImpl
*This
= impl_from_IXAudio2SourceVoice(iface
);
542 FAudioVoiceSends
*faudio_sends
;
545 TRACE("%p, %p\n", This
, pSendList
);
547 faudio_sends
= wrap_voice_sends(pSendList
);
549 hr
= FAudioVoice_SetOutputVoices(This
->faudio_voice
, faudio_sends
);
551 free_voice_sends(faudio_sends
);
556 static HRESULT WINAPI
XA2SRC_SetEffectChain(IXAudio2SourceVoice
*iface
,
557 const XAUDIO2_EFFECT_CHAIN
*pEffectChain
)
559 XA2VoiceImpl
*This
= impl_from_IXAudio2SourceVoice(iface
);
562 TRACE("%p, %p\n", This
, pEffectChain
);
564 free_effect_chain(This
->effect_chain
);
565 This
->effect_chain
= wrap_effect_chain(pEffectChain
);
567 hr
= FAudioVoice_SetEffectChain(This
->faudio_voice
, This
->effect_chain
);
572 static HRESULT WINAPI
XA2SRC_EnableEffect(IXAudio2SourceVoice
*iface
, UINT32 EffectIndex
,
575 XA2VoiceImpl
*This
= impl_from_IXAudio2SourceVoice(iface
);
576 TRACE("%p, %u, 0x%x\n", This
, EffectIndex
, OperationSet
);
577 return FAudioVoice_EnableEffect(This
->faudio_voice
, EffectIndex
, OperationSet
);
580 static HRESULT WINAPI
XA2SRC_DisableEffect(IXAudio2SourceVoice
*iface
, UINT32 EffectIndex
,
583 XA2VoiceImpl
*This
= impl_from_IXAudio2SourceVoice(iface
);
584 TRACE("%p, %u, 0x%x\n", This
, EffectIndex
, OperationSet
);
585 return FAudioVoice_DisableEffect(This
->faudio_voice
, EffectIndex
, OperationSet
);
588 static void WINAPI
XA2SRC_GetEffectState(IXAudio2SourceVoice
*iface
, UINT32 EffectIndex
,
591 XA2VoiceImpl
*This
= impl_from_IXAudio2SourceVoice(iface
);
592 TRACE("%p, %u, %p\n", This
, EffectIndex
, pEnabled
);
593 FAudioVoice_GetEffectState(This
->faudio_voice
, EffectIndex
, (int32_t*)pEnabled
);
596 static HRESULT WINAPI
XA2SRC_SetEffectParameters(IXAudio2SourceVoice
*iface
,
597 UINT32 EffectIndex
, const void *pParameters
, UINT32 ParametersByteSize
,
600 XA2VoiceImpl
*This
= impl_from_IXAudio2SourceVoice(iface
);
601 TRACE("%p, %u, %p, 0x%x, 0x%x\n", This
, EffectIndex
, pParameters
,
602 ParametersByteSize
, OperationSet
);
603 return FAudioVoice_SetEffectParameters(This
->faudio_voice
, EffectIndex
,
604 pParameters
, ParametersByteSize
, OperationSet
);
607 static HRESULT WINAPI
XA2SRC_GetEffectParameters(IXAudio2SourceVoice
*iface
,
608 UINT32 EffectIndex
, void *pParameters
, UINT32 ParametersByteSize
)
610 XA2VoiceImpl
*This
= impl_from_IXAudio2SourceVoice(iface
);
611 TRACE("%p, %u, %p, 0x%x\n", This
, EffectIndex
, pParameters
,
613 return FAudioVoice_GetEffectParameters(This
->faudio_voice
, EffectIndex
,
614 pParameters
, ParametersByteSize
);
617 static HRESULT WINAPI
XA2SRC_SetFilterParameters(IXAudio2SourceVoice
*iface
,
618 const XAUDIO2_FILTER_PARAMETERS
*pParameters
, UINT32 OperationSet
)
620 XA2VoiceImpl
*This
= impl_from_IXAudio2SourceVoice(iface
);
621 TRACE("%p, %p, 0x%x\n", This
, pParameters
, OperationSet
);
622 return FAudioVoice_SetFilterParameters(This
->faudio_voice
,
623 (const FAudioFilterParameters
*)pParameters
, OperationSet
);
626 static void WINAPI
XA2SRC_GetFilterParameters(IXAudio2SourceVoice
*iface
,
627 XAUDIO2_FILTER_PARAMETERS
*pParameters
)
629 XA2VoiceImpl
*This
= impl_from_IXAudio2SourceVoice(iface
);
630 TRACE("%p, %p\n", This
, pParameters
);
631 FAudioVoice_GetFilterParameters(This
->faudio_voice
, (FAudioFilterParameters
*)pParameters
);
634 static HRESULT WINAPI
XA2SRC_SetOutputFilterParameters(IXAudio2SourceVoice
*iface
,
635 IXAudio2Voice
*pDestinationVoice
,
636 const XAUDIO2_FILTER_PARAMETERS
*pParameters
, UINT32 OperationSet
)
638 XA2VoiceImpl
*This
= impl_from_IXAudio2SourceVoice(iface
);
639 XA2VoiceImpl
*dst
= pDestinationVoice
? impl_from_IXAudio2Voice(pDestinationVoice
) : NULL
;
641 TRACE("%p, %p, %p, 0x%x\n", This
, pDestinationVoice
, pParameters
, OperationSet
);
643 return FAudioVoice_SetOutputFilterParameters(This
->faudio_voice
,
644 dst
? dst
->faudio_voice
: NULL
, (const FAudioFilterParameters
*)pParameters
, OperationSet
);
647 static void WINAPI
XA2SRC_GetOutputFilterParameters(IXAudio2SourceVoice
*iface
,
648 IXAudio2Voice
*pDestinationVoice
,
649 XAUDIO2_FILTER_PARAMETERS
*pParameters
)
651 XA2VoiceImpl
*This
= impl_from_IXAudio2SourceVoice(iface
);
652 XA2VoiceImpl
*dst
= pDestinationVoice
? impl_from_IXAudio2Voice(pDestinationVoice
) : NULL
;
654 TRACE("%p, %p, %p\n", This
, pDestinationVoice
, pParameters
);
656 FAudioVoice_GetOutputFilterParameters(This
->faudio_voice
,
657 dst
? dst
->faudio_voice
: NULL
, (FAudioFilterParameters
*)pParameters
);
660 static HRESULT WINAPI
XA2SRC_SetVolume(IXAudio2SourceVoice
*iface
, float Volume
,
663 XA2VoiceImpl
*This
= impl_from_IXAudio2SourceVoice(iface
);
664 TRACE("%p, %f, 0x%x\n", This
, Volume
, OperationSet
);
665 return FAudioVoice_SetVolume(This
->faudio_voice
, Volume
, OperationSet
);
668 static void WINAPI
XA2SRC_GetVolume(IXAudio2SourceVoice
*iface
, float *pVolume
)
670 XA2VoiceImpl
*This
= impl_from_IXAudio2SourceVoice(iface
);
671 TRACE("%p, %p\n", This
, pVolume
);
672 return FAudioVoice_GetVolume(This
->faudio_voice
, pVolume
);
675 static HRESULT WINAPI
XA2SRC_SetChannelVolumes(IXAudio2SourceVoice
*iface
, UINT32 Channels
,
676 const float *pVolumes
, UINT32 OperationSet
)
678 XA2VoiceImpl
*This
= impl_from_IXAudio2SourceVoice(iface
);
679 TRACE("%p, %u, %p, 0x%x\n", This
, Channels
, pVolumes
, OperationSet
);
680 return FAudioVoice_SetChannelVolumes(This
->faudio_voice
, Channels
,
681 pVolumes
, OperationSet
);
684 static void WINAPI
XA2SRC_GetChannelVolumes(IXAudio2SourceVoice
*iface
, UINT32 Channels
,
687 XA2VoiceImpl
*This
= impl_from_IXAudio2SourceVoice(iface
);
688 TRACE("%p, %u, %p\n", This
, Channels
, pVolumes
);
689 return FAudioVoice_GetChannelVolumes(This
->faudio_voice
, Channels
,
693 static HRESULT WINAPI
XA2SRC_SetOutputMatrix(IXAudio2SourceVoice
*iface
,
694 IXAudio2Voice
*pDestinationVoice
, UINT32 SourceChannels
,
695 UINT32 DestinationChannels
, const float *pLevelMatrix
,
698 XA2VoiceImpl
*This
= impl_from_IXAudio2SourceVoice(iface
);
699 XA2VoiceImpl
*dst
= pDestinationVoice
? impl_from_IXAudio2Voice(pDestinationVoice
) : NULL
;
701 TRACE("%p, %p, %u, %u, %p, 0x%x\n", This
, pDestinationVoice
,
702 SourceChannels
, DestinationChannels
, pLevelMatrix
, OperationSet
);
704 return FAudioVoice_SetOutputMatrix(This
->faudio_voice
, dst
? dst
->faudio_voice
: NULL
,
705 SourceChannels
, DestinationChannels
, pLevelMatrix
, OperationSet
);
708 static void WINAPI
XA2SRC_GetOutputMatrix(IXAudio2SourceVoice
*iface
,
709 IXAudio2Voice
*pDestinationVoice
, UINT32 SourceChannels
,
710 UINT32 DestinationChannels
, float *pLevelMatrix
)
712 XA2VoiceImpl
*This
= impl_from_IXAudio2SourceVoice(iface
);
713 XA2VoiceImpl
*dst
= pDestinationVoice
? impl_from_IXAudio2Voice(pDestinationVoice
) : NULL
;
715 TRACE("%p, %p, %u, %u, %p\n", This
, pDestinationVoice
,
716 SourceChannels
, DestinationChannels
, pLevelMatrix
);
718 FAudioVoice_GetOutputMatrix(This
->faudio_voice
, dst
? dst
->faudio_voice
: NULL
,
719 SourceChannels
, DestinationChannels
, pLevelMatrix
);
722 static void WINAPI
XA2SRC_DestroyVoice(IXAudio2SourceVoice
*iface
)
724 XA2VoiceImpl
*This
= impl_from_IXAudio2SourceVoice(iface
);
728 EnterCriticalSection(&This
->lock
);
732 LeaveCriticalSection(&This
->lock
);
735 static HRESULT WINAPI
XA2SRC_Start(IXAudio2SourceVoice
*iface
, UINT32 Flags
,
738 XA2VoiceImpl
*This
= impl_from_IXAudio2SourceVoice(iface
);
740 TRACE("%p, 0x%x, 0x%x\n", This
, Flags
, OperationSet
);
742 return FAudioSourceVoice_Start(This
->faudio_voice
, Flags
, OperationSet
);
745 static HRESULT WINAPI
XA2SRC_Stop(IXAudio2SourceVoice
*iface
, UINT32 Flags
,
748 XA2VoiceImpl
*This
= impl_from_IXAudio2SourceVoice(iface
);
750 TRACE("%p, 0x%x, 0x%x\n", This
, Flags
, OperationSet
);
752 return FAudioSourceVoice_Stop(This
->faudio_voice
, Flags
, OperationSet
);
755 static HRESULT WINAPI
XA2SRC_SubmitSourceBuffer(IXAudio2SourceVoice
*iface
,
756 const XAUDIO2_BUFFER
*pBuffer
, const XAUDIO2_BUFFER_WMA
*pBufferWMA
)
758 XA2VoiceImpl
*This
= impl_from_IXAudio2SourceVoice(iface
);
760 TRACE("%p, %p, %p\n", This
, pBuffer
, pBufferWMA
);
762 return FAudioSourceVoice_SubmitSourceBuffer(This
->faudio_voice
, (FAudioBuffer
*)pBuffer
, (FAudioBufferWMA
*)pBufferWMA
);
765 static HRESULT WINAPI
XA2SRC_FlushSourceBuffers(IXAudio2SourceVoice
*iface
)
767 XA2VoiceImpl
*This
= impl_from_IXAudio2SourceVoice(iface
);
771 return FAudioSourceVoice_FlushSourceBuffers(This
->faudio_voice
);
774 static HRESULT WINAPI
XA2SRC_Discontinuity(IXAudio2SourceVoice
*iface
)
776 XA2VoiceImpl
*This
= impl_from_IXAudio2SourceVoice(iface
);
780 return FAudioSourceVoice_Discontinuity(This
->faudio_voice
);
783 static HRESULT WINAPI
XA2SRC_ExitLoop(IXAudio2SourceVoice
*iface
, UINT32 OperationSet
)
785 XA2VoiceImpl
*This
= impl_from_IXAudio2SourceVoice(iface
);
787 TRACE("%p, 0x%x\n", This
, OperationSet
);
789 return FAudioSourceVoice_ExitLoop(This
->faudio_voice
, OperationSet
);
792 static void WINAPI
XA2SRC_GetState(IXAudio2SourceVoice
*iface
,
793 XAUDIO2_VOICE_STATE
*pVoiceState
, UINT32 Flags
)
795 XA2VoiceImpl
*This
= impl_from_IXAudio2SourceVoice(iface
);
797 TRACE("%p, %p, 0x%x\n", This
, pVoiceState
, Flags
);
799 return FAudioSourceVoice_GetState(This
->faudio_voice
, (FAudioVoiceState
*)pVoiceState
, Flags
);
802 static HRESULT WINAPI
XA2SRC_SetFrequencyRatio(IXAudio2SourceVoice
*iface
,
803 float Ratio
, UINT32 OperationSet
)
805 XA2VoiceImpl
*This
= impl_from_IXAudio2SourceVoice(iface
);
807 TRACE("%p, %f, 0x%x\n", This
, Ratio
, OperationSet
);
809 return FAudioSourceVoice_SetFrequencyRatio(This
->faudio_voice
, Ratio
, OperationSet
);
812 static void WINAPI
XA2SRC_GetFrequencyRatio(IXAudio2SourceVoice
*iface
, float *pRatio
)
814 XA2VoiceImpl
*This
= impl_from_IXAudio2SourceVoice(iface
);
816 TRACE("%p, %p\n", This
, pRatio
);
818 return FAudioSourceVoice_GetFrequencyRatio(This
->faudio_voice
, pRatio
);
821 static HRESULT WINAPI
XA2SRC_SetSourceSampleRate(
822 IXAudio2SourceVoice
*iface
,
823 UINT32 NewSourceSampleRate
)
825 XA2VoiceImpl
*This
= impl_from_IXAudio2SourceVoice(iface
);
827 TRACE("%p, %u\n", This
, NewSourceSampleRate
);
829 return FAudioSourceVoice_SetSourceSampleRate(This
->faudio_voice
, NewSourceSampleRate
);
832 static const IXAudio2SourceVoiceVtbl XAudio2SourceVoice_Vtbl
= {
833 XA2SRC_GetVoiceDetails
,
834 XA2SRC_SetOutputVoices
,
835 XA2SRC_SetEffectChain
,
837 XA2SRC_DisableEffect
,
838 XA2SRC_GetEffectState
,
839 XA2SRC_SetEffectParameters
,
840 XA2SRC_GetEffectParameters
,
841 XA2SRC_SetFilterParameters
,
842 XA2SRC_GetFilterParameters
,
843 XA2SRC_SetOutputFilterParameters
,
844 XA2SRC_GetOutputFilterParameters
,
847 XA2SRC_SetChannelVolumes
,
848 XA2SRC_GetChannelVolumes
,
849 XA2SRC_SetOutputMatrix
,
850 XA2SRC_GetOutputMatrix
,
854 XA2SRC_SubmitSourceBuffer
,
855 XA2SRC_FlushSourceBuffers
,
856 XA2SRC_Discontinuity
,
859 XA2SRC_SetFrequencyRatio
,
860 XA2SRC_GetFrequencyRatio
,
861 XA2SRC_SetSourceSampleRate
866 static inline XA2VoiceImpl
*impl_from_IXAudio2SubmixVoice(IXAudio2SubmixVoice
*iface
)
868 return CONTAINING_RECORD(iface
, XA2VoiceImpl
, IXAudio2SubmixVoice_iface
);
871 static void WINAPI
XA2SUB_GetVoiceDetails(IXAudio2SubmixVoice
*iface
,
872 XAUDIO2_VOICE_DETAILS
*pVoiceDetails
)
874 XA2VoiceImpl
*This
= impl_from_IXAudio2SubmixVoice(iface
);
875 TRACE("%p, %p\n", This
, pVoiceDetails
);
876 FAudioVoice_GetVoiceDetails(This
->faudio_voice
, (FAudioVoiceDetails
*)pVoiceDetails
);
879 static HRESULT WINAPI
XA2SUB_SetOutputVoices(IXAudio2SubmixVoice
*iface
,
880 const XAUDIO2_VOICE_SENDS
*pSendList
)
882 XA2VoiceImpl
*This
= impl_from_IXAudio2SubmixVoice(iface
);
883 FAudioVoiceSends
*faudio_sends
;
886 TRACE("%p, %p\n", This
, pSendList
);
888 faudio_sends
= wrap_voice_sends(pSendList
);
890 hr
= FAudioVoice_SetOutputVoices(This
->faudio_voice
, faudio_sends
);
892 free_voice_sends(faudio_sends
);
897 static HRESULT WINAPI
XA2SUB_SetEffectChain(IXAudio2SubmixVoice
*iface
,
898 const XAUDIO2_EFFECT_CHAIN
*pEffectChain
)
900 XA2VoiceImpl
*This
= impl_from_IXAudio2SubmixVoice(iface
);
903 TRACE("%p, %p\n", This
, pEffectChain
);
905 free_effect_chain(This
->effect_chain
);
906 This
->effect_chain
= wrap_effect_chain(pEffectChain
);
908 hr
= FAudioVoice_SetEffectChain(This
->faudio_voice
, This
->effect_chain
);
913 static HRESULT WINAPI
XA2SUB_EnableEffect(IXAudio2SubmixVoice
*iface
, UINT32 EffectIndex
,
916 XA2VoiceImpl
*This
= impl_from_IXAudio2SubmixVoice(iface
);
917 TRACE("%p, %u, 0x%x\n", This
, EffectIndex
, OperationSet
);
918 return FAudioVoice_EnableEffect(This
->faudio_voice
, EffectIndex
, OperationSet
);
921 static HRESULT WINAPI
XA2SUB_DisableEffect(IXAudio2SubmixVoice
*iface
, UINT32 EffectIndex
,
924 XA2VoiceImpl
*This
= impl_from_IXAudio2SubmixVoice(iface
);
925 TRACE("%p, %u, 0x%x\n", This
, EffectIndex
, OperationSet
);
926 return FAudioVoice_DisableEffect(This
->faudio_voice
, EffectIndex
, OperationSet
);
929 static void WINAPI
XA2SUB_GetEffectState(IXAudio2SubmixVoice
*iface
, UINT32 EffectIndex
,
932 XA2VoiceImpl
*This
= impl_from_IXAudio2SubmixVoice(iface
);
933 TRACE("%p, %u, %p\n", This
, EffectIndex
, pEnabled
);
934 FAudioVoice_GetEffectState(This
->faudio_voice
, EffectIndex
, (int32_t*)pEnabled
);
937 static HRESULT WINAPI
XA2SUB_SetEffectParameters(IXAudio2SubmixVoice
*iface
,
938 UINT32 EffectIndex
, const void *pParameters
, UINT32 ParametersByteSize
,
941 XA2VoiceImpl
*This
= impl_from_IXAudio2SubmixVoice(iface
);
942 TRACE("%p, %u, %p, 0x%x, 0x%x\n", This
, EffectIndex
, pParameters
,
943 ParametersByteSize
, OperationSet
);
944 return FAudioVoice_SetEffectParameters(This
->faudio_voice
, EffectIndex
,
945 pParameters
, ParametersByteSize
, OperationSet
);
948 static HRESULT WINAPI
XA2SUB_GetEffectParameters(IXAudio2SubmixVoice
*iface
,
949 UINT32 EffectIndex
, void *pParameters
, UINT32 ParametersByteSize
)
951 XA2VoiceImpl
*This
= impl_from_IXAudio2SubmixVoice(iface
);
952 TRACE("%p, %u, %p, 0x%x\n", This
, EffectIndex
, pParameters
,
954 return FAudioVoice_GetEffectParameters(This
->faudio_voice
, EffectIndex
,
955 pParameters
, ParametersByteSize
);
958 static HRESULT WINAPI
XA2SUB_SetFilterParameters(IXAudio2SubmixVoice
*iface
,
959 const XAUDIO2_FILTER_PARAMETERS
*pParameters
, UINT32 OperationSet
)
961 XA2VoiceImpl
*This
= impl_from_IXAudio2SubmixVoice(iface
);
962 TRACE("%p, %p, 0x%x\n", This
, pParameters
, OperationSet
);
963 return FAudioVoice_SetFilterParameters(This
->faudio_voice
, (const FAudioFilterParameters
*)pParameters
,
967 static void WINAPI
XA2SUB_GetFilterParameters(IXAudio2SubmixVoice
*iface
,
968 XAUDIO2_FILTER_PARAMETERS
*pParameters
)
970 XA2VoiceImpl
*This
= impl_from_IXAudio2SubmixVoice(iface
);
971 TRACE("%p, %p\n", This
, pParameters
);
972 FAudioVoice_GetFilterParameters(This
->faudio_voice
, (FAudioFilterParameters
*)pParameters
);
975 static HRESULT WINAPI
XA2SUB_SetOutputFilterParameters(IXAudio2SubmixVoice
*iface
,
976 IXAudio2Voice
*pDestinationVoice
,
977 const XAUDIO2_FILTER_PARAMETERS
*pParameters
, UINT32 OperationSet
)
979 XA2VoiceImpl
*This
= impl_from_IXAudio2SubmixVoice(iface
);
980 XA2VoiceImpl
*dst
= pDestinationVoice
? impl_from_IXAudio2Voice(pDestinationVoice
) : NULL
;
982 TRACE("%p, %p, %p, 0x%x\n", This
, pDestinationVoice
, pParameters
, OperationSet
);
984 return FAudioVoice_SetOutputFilterParameters(This
->faudio_voice
,
985 dst
? dst
->faudio_voice
: NULL
, (const FAudioFilterParameters
*)pParameters
, OperationSet
);
988 static void WINAPI
XA2SUB_GetOutputFilterParameters(IXAudio2SubmixVoice
*iface
,
989 IXAudio2Voice
*pDestinationVoice
,
990 XAUDIO2_FILTER_PARAMETERS
*pParameters
)
992 XA2VoiceImpl
*This
= impl_from_IXAudio2SubmixVoice(iface
);
993 XA2VoiceImpl
*dst
= pDestinationVoice
? impl_from_IXAudio2Voice(pDestinationVoice
) : NULL
;
995 TRACE("%p, %p, %p\n", This
, pDestinationVoice
, pParameters
);
997 FAudioVoice_GetOutputFilterParameters(This
->faudio_voice
,
998 dst
? dst
->faudio_voice
: NULL
, (FAudioFilterParameters
*)pParameters
);
1001 static HRESULT WINAPI
XA2SUB_SetVolume(IXAudio2SubmixVoice
*iface
, float Volume
,
1002 UINT32 OperationSet
)
1004 XA2VoiceImpl
*This
= impl_from_IXAudio2SubmixVoice(iface
);
1005 TRACE("%p, %f, 0x%x\n", This
, Volume
, OperationSet
);
1006 return FAudioVoice_SetVolume(This
->faudio_voice
, Volume
, OperationSet
);
1009 static void WINAPI
XA2SUB_GetVolume(IXAudio2SubmixVoice
*iface
, float *pVolume
)
1011 XA2VoiceImpl
*This
= impl_from_IXAudio2SubmixVoice(iface
);
1012 TRACE("%p, %p\n", This
, pVolume
);
1013 return FAudioVoice_GetVolume(This
->faudio_voice
, pVolume
);
1016 static HRESULT WINAPI
XA2SUB_SetChannelVolumes(IXAudio2SubmixVoice
*iface
, UINT32 Channels
,
1017 const float *pVolumes
, UINT32 OperationSet
)
1019 XA2VoiceImpl
*This
= impl_from_IXAudio2SubmixVoice(iface
);
1020 TRACE("%p, %u, %p, 0x%x\n", This
, Channels
, pVolumes
, OperationSet
);
1021 return FAudioVoice_SetChannelVolumes(This
->faudio_voice
, Channels
,
1022 pVolumes
, OperationSet
);
1025 static void WINAPI
XA2SUB_GetChannelVolumes(IXAudio2SubmixVoice
*iface
, UINT32 Channels
,
1028 XA2VoiceImpl
*This
= impl_from_IXAudio2SubmixVoice(iface
);
1029 TRACE("%p, %u, %p\n", This
, Channels
, pVolumes
);
1030 return FAudioVoice_GetChannelVolumes(This
->faudio_voice
, Channels
,
1034 static HRESULT WINAPI
XA2SUB_SetOutputMatrix(IXAudio2SubmixVoice
*iface
,
1035 IXAudio2Voice
*pDestinationVoice
, UINT32 SourceChannels
,
1036 UINT32 DestinationChannels
, const float *pLevelMatrix
,
1037 UINT32 OperationSet
)
1039 XA2VoiceImpl
*This
= impl_from_IXAudio2SubmixVoice(iface
);
1040 XA2VoiceImpl
*dst
= pDestinationVoice
? impl_from_IXAudio2Voice(pDestinationVoice
) : NULL
;
1042 TRACE("%p, %p, %u, %u, %p, 0x%x\n", This
, pDestinationVoice
,
1043 SourceChannels
, DestinationChannels
, pLevelMatrix
, OperationSet
);
1045 return FAudioVoice_SetOutputMatrix(This
->faudio_voice
, dst
? dst
->faudio_voice
: NULL
,
1046 SourceChannels
, DestinationChannels
, pLevelMatrix
, OperationSet
);
1049 static void WINAPI
XA2SUB_GetOutputMatrix(IXAudio2SubmixVoice
*iface
,
1050 IXAudio2Voice
*pDestinationVoice
, UINT32 SourceChannels
,
1051 UINT32 DestinationChannels
, float *pLevelMatrix
)
1053 XA2VoiceImpl
*This
= impl_from_IXAudio2SubmixVoice(iface
);
1054 XA2VoiceImpl
*dst
= pDestinationVoice
? impl_from_IXAudio2Voice(pDestinationVoice
) : NULL
;
1056 TRACE("%p, %p, %u, %u, %p\n", This
, pDestinationVoice
,
1057 SourceChannels
, DestinationChannels
, pLevelMatrix
);
1059 FAudioVoice_GetOutputMatrix(This
->faudio_voice
, dst
? dst
->faudio_voice
: NULL
,
1060 SourceChannels
, DestinationChannels
, pLevelMatrix
);
1063 static void WINAPI
XA2SUB_DestroyVoice(IXAudio2SubmixVoice
*iface
)
1065 XA2VoiceImpl
*This
= impl_from_IXAudio2SubmixVoice(iface
);
1067 TRACE("%p\n", This
);
1069 EnterCriticalSection(&This
->lock
);
1071 destroy_voice(This
);
1073 LeaveCriticalSection(&This
->lock
);
1076 static const struct IXAudio2SubmixVoiceVtbl XAudio2SubmixVoice_Vtbl
= {
1077 XA2SUB_GetVoiceDetails
,
1078 XA2SUB_SetOutputVoices
,
1079 XA2SUB_SetEffectChain
,
1080 XA2SUB_EnableEffect
,
1081 XA2SUB_DisableEffect
,
1082 XA2SUB_GetEffectState
,
1083 XA2SUB_SetEffectParameters
,
1084 XA2SUB_GetEffectParameters
,
1085 XA2SUB_SetFilterParameters
,
1086 XA2SUB_GetFilterParameters
,
1087 XA2SUB_SetOutputFilterParameters
,
1088 XA2SUB_GetOutputFilterParameters
,
1091 XA2SUB_SetChannelVolumes
,
1092 XA2SUB_GetChannelVolumes
,
1093 XA2SUB_SetOutputMatrix
,
1094 XA2SUB_GetOutputMatrix
,
1098 /* Mastering Voices */
1100 static inline XA2VoiceImpl
*impl_from_IXAudio2MasteringVoice(IXAudio2MasteringVoice
*iface
)
1102 return CONTAINING_RECORD(iface
, XA2VoiceImpl
, IXAudio2MasteringVoice_iface
);
1105 static void WINAPI
XA2M_GetVoiceDetails(IXAudio2MasteringVoice
*iface
,
1106 XAUDIO2_VOICE_DETAILS
*pVoiceDetails
)
1108 XA2VoiceImpl
*This
= impl_from_IXAudio2MasteringVoice(iface
);
1109 TRACE("%p, %p\n", This
, pVoiceDetails
);
1110 FAudioVoice_GetVoiceDetails(This
->faudio_voice
, (FAudioVoiceDetails
*)pVoiceDetails
);
1113 static HRESULT WINAPI
XA2M_SetOutputVoices(IXAudio2MasteringVoice
*iface
,
1114 const XAUDIO2_VOICE_SENDS
*pSendList
)
1116 XA2VoiceImpl
*This
= impl_from_IXAudio2MasteringVoice(iface
);
1117 FAudioVoiceSends
*faudio_sends
;
1120 TRACE("%p, %p\n", This
, pSendList
);
1122 faudio_sends
= wrap_voice_sends(pSendList
);
1124 hr
= FAudioVoice_SetOutputVoices(This
->faudio_voice
, faudio_sends
);
1126 free_voice_sends(faudio_sends
);
1131 static HRESULT WINAPI
XA2M_SetEffectChain(IXAudio2MasteringVoice
*iface
,
1132 const XAUDIO2_EFFECT_CHAIN
*pEffectChain
)
1134 XA2VoiceImpl
*This
= impl_from_IXAudio2MasteringVoice(iface
);
1137 TRACE("%p, %p\n", This
, pEffectChain
);
1139 free_effect_chain(This
->effect_chain
);
1140 This
->effect_chain
= wrap_effect_chain(pEffectChain
);
1142 hr
= FAudioVoice_SetEffectChain(This
->faudio_voice
, This
->effect_chain
);
1147 static HRESULT WINAPI
XA2M_EnableEffect(IXAudio2MasteringVoice
*iface
, UINT32 EffectIndex
,
1148 UINT32 OperationSet
)
1150 XA2VoiceImpl
*This
= impl_from_IXAudio2MasteringVoice(iface
);
1151 TRACE("%p, %u, 0x%x\n", This
, EffectIndex
, OperationSet
);
1152 return FAudioVoice_EnableEffect(This
->faudio_voice
, EffectIndex
, OperationSet
);
1155 static HRESULT WINAPI
XA2M_DisableEffect(IXAudio2MasteringVoice
*iface
, UINT32 EffectIndex
,
1156 UINT32 OperationSet
)
1158 XA2VoiceImpl
*This
= impl_from_IXAudio2MasteringVoice(iface
);
1159 TRACE("%p, %u, 0x%x\n", This
, EffectIndex
, OperationSet
);
1160 return FAudioVoice_DisableEffect(This
->faudio_voice
, EffectIndex
, OperationSet
);
1163 static void WINAPI
XA2M_GetEffectState(IXAudio2MasteringVoice
*iface
, UINT32 EffectIndex
,
1166 XA2VoiceImpl
*This
= impl_from_IXAudio2MasteringVoice(iface
);
1167 TRACE("%p, %u, %p\n", This
, EffectIndex
, pEnabled
);
1168 FAudioVoice_GetEffectState(This
->faudio_voice
, EffectIndex
, (int32_t*)pEnabled
);
1171 static HRESULT WINAPI
XA2M_SetEffectParameters(IXAudio2MasteringVoice
*iface
,
1172 UINT32 EffectIndex
, const void *pParameters
, UINT32 ParametersByteSize
,
1173 UINT32 OperationSet
)
1175 XA2VoiceImpl
*This
= impl_from_IXAudio2MasteringVoice(iface
);
1176 TRACE("%p, %u, %p, 0x%x, 0x%x\n", This
, EffectIndex
, pParameters
,
1177 ParametersByteSize
, OperationSet
);
1178 return FAudioVoice_SetEffectParameters(This
->faudio_voice
, EffectIndex
,
1179 pParameters
, ParametersByteSize
, OperationSet
);
1182 static HRESULT WINAPI
XA2M_GetEffectParameters(IXAudio2MasteringVoice
*iface
,
1183 UINT32 EffectIndex
, void *pParameters
, UINT32 ParametersByteSize
)
1185 XA2VoiceImpl
*This
= impl_from_IXAudio2MasteringVoice(iface
);
1186 TRACE("%p, %u, %p, 0x%x\n", This
, EffectIndex
, pParameters
,
1187 ParametersByteSize
);
1188 return FAudioVoice_GetEffectParameters(This
->faudio_voice
, EffectIndex
,
1189 pParameters
, ParametersByteSize
);
1192 static HRESULT WINAPI
XA2M_SetFilterParameters(IXAudio2MasteringVoice
*iface
,
1193 const XAUDIO2_FILTER_PARAMETERS
*pParameters
, UINT32 OperationSet
)
1195 XA2VoiceImpl
*This
= impl_from_IXAudio2MasteringVoice(iface
);
1196 TRACE("%p, %p, 0x%x\n", This
, pParameters
, OperationSet
);
1197 return FAudioVoice_SetFilterParameters(This
->faudio_voice
, (const FAudioFilterParameters
*)pParameters
,
1201 static void WINAPI
XA2M_GetFilterParameters(IXAudio2MasteringVoice
*iface
,
1202 XAUDIO2_FILTER_PARAMETERS
*pParameters
)
1204 XA2VoiceImpl
*This
= impl_from_IXAudio2MasteringVoice(iface
);
1205 TRACE("%p, %p\n", This
, pParameters
);
1206 FAudioVoice_GetFilterParameters(This
->faudio_voice
, (FAudioFilterParameters
*)pParameters
);
1209 static HRESULT WINAPI
XA2M_SetOutputFilterParameters(IXAudio2MasteringVoice
*iface
,
1210 IXAudio2Voice
*pDestinationVoice
,
1211 const XAUDIO2_FILTER_PARAMETERS
*pParameters
, UINT32 OperationSet
)
1213 XA2VoiceImpl
*This
= impl_from_IXAudio2MasteringVoice(iface
);
1214 XA2VoiceImpl
*dst
= pDestinationVoice
? impl_from_IXAudio2Voice(pDestinationVoice
) : NULL
;
1216 TRACE("%p, %p, %p, 0x%x\n", This
, pDestinationVoice
, pParameters
, OperationSet
);
1218 return FAudioVoice_SetOutputFilterParameters(This
->faudio_voice
,
1219 dst
? dst
->faudio_voice
: NULL
, (const FAudioFilterParameters
*)pParameters
, OperationSet
);
1222 static void WINAPI
XA2M_GetOutputFilterParameters(IXAudio2MasteringVoice
*iface
,
1223 IXAudio2Voice
*pDestinationVoice
,
1224 XAUDIO2_FILTER_PARAMETERS
*pParameters
)
1226 XA2VoiceImpl
*This
= impl_from_IXAudio2MasteringVoice(iface
);
1227 XA2VoiceImpl
*dst
= pDestinationVoice
? impl_from_IXAudio2Voice(pDestinationVoice
) : NULL
;
1229 TRACE("%p, %p, %p\n", This
, pDestinationVoice
, pParameters
);
1231 FAudioVoice_GetOutputFilterParameters(This
->faudio_voice
,
1232 dst
? dst
->faudio_voice
: NULL
, (FAudioFilterParameters
*)pParameters
);
1235 static HRESULT WINAPI
XA2M_SetVolume(IXAudio2MasteringVoice
*iface
, float Volume
,
1236 UINT32 OperationSet
)
1238 XA2VoiceImpl
*This
= impl_from_IXAudio2MasteringVoice(iface
);
1239 TRACE("%p, %f, 0x%x\n", This
, Volume
, OperationSet
);
1240 return FAudioVoice_SetVolume(This
->faudio_voice
, Volume
, OperationSet
);
1243 static void WINAPI
XA2M_GetVolume(IXAudio2MasteringVoice
*iface
, float *pVolume
)
1245 XA2VoiceImpl
*This
= impl_from_IXAudio2MasteringVoice(iface
);
1246 TRACE("%p, %p\n", This
, pVolume
);
1247 return FAudioVoice_GetVolume(This
->faudio_voice
, pVolume
);
1250 static HRESULT WINAPI
XA2M_SetChannelVolumes(IXAudio2MasteringVoice
*iface
, UINT32 Channels
,
1251 const float *pVolumes
, UINT32 OperationSet
)
1253 XA2VoiceImpl
*This
= impl_from_IXAudio2MasteringVoice(iface
);
1254 TRACE("%p, %u, %p, 0x%x\n", This
, Channels
, pVolumes
, OperationSet
);
1255 return FAudioVoice_SetChannelVolumes(This
->faudio_voice
, Channels
,
1256 pVolumes
, OperationSet
);
1259 static void WINAPI
XA2M_GetChannelVolumes(IXAudio2MasteringVoice
*iface
, UINT32 Channels
,
1262 XA2VoiceImpl
*This
= impl_from_IXAudio2MasteringVoice(iface
);
1263 TRACE("%p, %u, %p\n", This
, Channels
, pVolumes
);
1264 return FAudioVoice_GetChannelVolumes(This
->faudio_voice
, Channels
,
1268 static HRESULT WINAPI
XA2M_SetOutputMatrix(IXAudio2MasteringVoice
*iface
,
1269 IXAudio2Voice
*pDestinationVoice
, UINT32 SourceChannels
,
1270 UINT32 DestinationChannels
, const float *pLevelMatrix
,
1271 UINT32 OperationSet
)
1273 XA2VoiceImpl
*This
= impl_from_IXAudio2MasteringVoice(iface
);
1274 XA2VoiceImpl
*dst
= pDestinationVoice
? impl_from_IXAudio2Voice(pDestinationVoice
) : NULL
;
1276 TRACE("%p, %p, %u, %u, %p, 0x%x\n", This
, pDestinationVoice
,
1277 SourceChannels
, DestinationChannels
, pLevelMatrix
, OperationSet
);
1279 return FAudioVoice_SetOutputMatrix(This
->faudio_voice
, dst
? dst
->faudio_voice
: NULL
,
1280 SourceChannels
, DestinationChannels
, pLevelMatrix
, OperationSet
);
1283 static void WINAPI
XA2M_GetOutputMatrix(IXAudio2MasteringVoice
*iface
,
1284 IXAudio2Voice
*pDestinationVoice
, UINT32 SourceChannels
,
1285 UINT32 DestinationChannels
, float *pLevelMatrix
)
1287 XA2VoiceImpl
*This
= impl_from_IXAudio2MasteringVoice(iface
);
1288 XA2VoiceImpl
*dst
= pDestinationVoice
? impl_from_IXAudio2Voice(pDestinationVoice
) : NULL
;
1290 TRACE("%p, %p, %u, %u, %p\n", This
, pDestinationVoice
,
1291 SourceChannels
, DestinationChannels
, pLevelMatrix
);
1293 FAudioVoice_GetOutputMatrix(This
->faudio_voice
, dst
? dst
->faudio_voice
: NULL
,
1294 SourceChannels
, DestinationChannels
, pLevelMatrix
);
1297 static void WINAPI
XA2M_DestroyVoice(IXAudio2MasteringVoice
*iface
)
1299 XA2VoiceImpl
*This
= impl_from_IXAudio2MasteringVoice(iface
);
1301 TRACE("%p\n", This
);
1303 EnterCriticalSection(&This
->lock
);
1305 destroy_voice(This
);
1306 pthread_mutex_lock(&This
->engine_lock
);
1307 This
->engine_params
.proc
= NULL
;
1308 pthread_cond_broadcast(&This
->engine_ready
);
1309 pthread_mutex_unlock(&This
->engine_lock
);
1311 WaitForSingleObject(This
->engine_thread
, INFINITE
);
1312 This
->engine_thread
= NULL
;
1314 LeaveCriticalSection(&This
->lock
);
1317 static void WINAPI
XA2M_GetChannelMask(IXAudio2MasteringVoice
*iface
,
1318 DWORD
*pChannelMask
)
1320 XA2VoiceImpl
*This
= impl_from_IXAudio2MasteringVoice(iface
);
1322 TRACE("%p, %p\n", This
, pChannelMask
);
1324 FAudioMasteringVoice_GetChannelMask(This
->faudio_voice
, pChannelMask
);
1327 static const struct IXAudio2MasteringVoiceVtbl XAudio2MasteringVoice_Vtbl
= {
1328 XA2M_GetVoiceDetails
,
1329 XA2M_SetOutputVoices
,
1330 XA2M_SetEffectChain
,
1333 XA2M_GetEffectState
,
1334 XA2M_SetEffectParameters
,
1335 XA2M_GetEffectParameters
,
1336 XA2M_SetFilterParameters
,
1337 XA2M_GetFilterParameters
,
1338 XA2M_SetOutputFilterParameters
,
1339 XA2M_GetOutputFilterParameters
,
1342 XA2M_SetChannelVolumes
,
1343 XA2M_GetChannelVolumes
,
1344 XA2M_SetOutputMatrix
,
1345 XA2M_GetOutputMatrix
,
1350 /* More Common Voice Functions */
1352 static XA2VoiceImpl
*impl_from_IXAudio2Voice(IXAudio2Voice
*iface
)
1354 if(iface
->lpVtbl
== (void*)&XAudio2SourceVoice_Vtbl
)
1355 return impl_from_IXAudio2SourceVoice((IXAudio2SourceVoice
*)iface
);
1356 if(iface
->lpVtbl
== (void*)&XAudio2MasteringVoice_Vtbl
)
1357 return impl_from_IXAudio2MasteringVoice((IXAudio2MasteringVoice
*)iface
);
1358 if(iface
->lpVtbl
== (void*)&XAudio2SubmixVoice_Vtbl
)
1359 return impl_from_IXAudio2SubmixVoice((IXAudio2SubmixVoice
*)iface
);
1360 #if XAUDIO2_VER == 0
1361 if(iface
->lpVtbl
== (void*)&XAudio20SourceVoice_Vtbl
)
1362 return impl_from_IXAudio20SourceVoice((IXAudio20SourceVoice
*)iface
);
1363 if(iface
->lpVtbl
== (void*)&XAudio20SubmixVoice_Vtbl
)
1364 return impl_from_IXAudio20SubmixVoice((IXAudio20SubmixVoice
*)iface
);
1365 if(iface
->lpVtbl
== (void*)&XAudio20MasteringVoice_Vtbl
)
1366 return impl_from_IXAudio20MasteringVoice((IXAudio20MasteringVoice
*)iface
);
1367 #elif XAUDIO2_VER <= 3
1368 if(iface
->lpVtbl
== (void*)&XAudio23SourceVoice_Vtbl
)
1369 return impl_from_IXAudio23SourceVoice((IXAudio23SourceVoice
*)iface
);
1370 if(iface
->lpVtbl
== (void*)&XAudio23SubmixVoice_Vtbl
)
1371 return impl_from_IXAudio23SubmixVoice((IXAudio23SubmixVoice
*)iface
);
1372 if(iface
->lpVtbl
== (void*)&XAudio23MasteringVoice_Vtbl
)
1373 return impl_from_IXAudio23MasteringVoice((IXAudio23MasteringVoice
*)iface
);
1374 #elif XAUDIO2_VER <= 7
1375 if(iface
->lpVtbl
== (void*)&XAudio27SourceVoice_Vtbl
)
1376 return impl_from_IXAudio27SourceVoice((IXAudio27SourceVoice
*)iface
);
1377 if(iface
->lpVtbl
== (void*)&XAudio27SubmixVoice_Vtbl
)
1378 return impl_from_IXAudio27SubmixVoice((IXAudio27SubmixVoice
*)iface
);
1379 if(iface
->lpVtbl
== (void*)&XAudio27MasteringVoice_Vtbl
)
1380 return impl_from_IXAudio27MasteringVoice((IXAudio27MasteringVoice
*)iface
);
1382 ERR("invalid IXAudio2Voice pointer: %p\n", iface
);
1386 /* XAudio2 Engine Implementation */
1388 static inline IXAudio2Impl
*impl_from_IXAudio2(IXAudio2
*iface
)
1390 return CONTAINING_RECORD(iface
, IXAudio2Impl
, IXAudio2_iface
);
1393 static HRESULT WINAPI
IXAudio2Impl_QueryInterface(IXAudio2
*iface
, REFIID riid
,
1396 IXAudio2Impl
*This
= impl_from_IXAudio2(iface
);
1398 TRACE("(%p)->(%s, %p)\n", This
, debugstr_guid(riid
), ppvObject
);
1400 if(IsEqualGUID(riid
, &IID_IUnknown
) ||
1401 #if XAUDIO2_VER == 8
1402 IsEqualGUID(riid
, &IID_IXAudio28
) ||
1404 IsEqualGUID(riid
, &IID_IXAudio2
))
1405 *ppvObject
= &This
->IXAudio2_iface
;
1406 else if(IsEqualGUID(riid
, &IID_IXAudio27
)){
1407 /* all xaudio versions before 28 share an IID */
1408 #if XAUDIO2_VER == 0
1409 *ppvObject
= &This
->IXAudio20_iface
;
1410 #elif XAUDIO2_VER <= 2
1411 *ppvObject
= &This
->IXAudio22_iface
;
1412 #elif XAUDIO2_VER <= 3
1413 *ppvObject
= &This
->IXAudio23_iface
;
1414 #elif XAUDIO2_VER <= 7
1415 *ppvObject
= &This
->IXAudio27_iface
;
1423 IUnknown_AddRef((IUnknown
*)*ppvObject
);
1427 FIXME("(%p)->(%s,%p), not found\n", This
,debugstr_guid(riid
), ppvObject
);
1429 return E_NOINTERFACE
;
1432 static ULONG WINAPI
IXAudio2Impl_AddRef(IXAudio2
*iface
)
1434 IXAudio2Impl
*This
= impl_from_IXAudio2(iface
);
1435 ULONG ref
= FAudio_AddRef(This
->faudio
);
1436 TRACE("(%p)->(): Refcount now %u\n", This
, ref
);
1440 static ULONG WINAPI
IXAudio2Impl_Release(IXAudio2
*iface
)
1442 IXAudio2Impl
*This
= impl_from_IXAudio2(iface
);
1443 ULONG ref
= FAudio_Release(This
->faudio
);
1445 TRACE("(%p)->(): Refcount now %u\n", This
, ref
);
1448 XA2VoiceImpl
*v
, *v2
;
1450 LIST_FOR_EACH_ENTRY_SAFE(v
, v2
, &This
->voices
, XA2VoiceImpl
, entry
){
1451 v
->lock
.DebugInfo
->Spare
[0] = 0;
1452 DeleteCriticalSection(&v
->lock
);
1453 HeapFree(GetProcessHeap(), 0, v
);
1456 HeapFree(GetProcessHeap(), 0, This
->cbs
);
1458 This
->lock
.DebugInfo
->Spare
[0] = 0;
1459 DeleteCriticalSection(&This
->lock
);
1461 HeapFree(GetProcessHeap(), 0, This
);
1466 static HRESULT WINAPI
IXAudio2Impl_RegisterForCallbacks(IXAudio2
*iface
,
1467 IXAudio2EngineCallback
*pCallback
)
1469 IXAudio2Impl
*This
= impl_from_IXAudio2(iface
);
1472 TRACE("(%p)->(%p)\n", This
, pCallback
);
1474 EnterCriticalSection(&This
->lock
);
1476 for(i
= 0; i
< This
->ncbs
; ++i
){
1477 if(!This
->cbs
[i
] || This
->cbs
[i
] == pCallback
){
1478 This
->cbs
[i
] = pCallback
;
1479 LeaveCriticalSection(&This
->lock
);
1485 This
->cbs
= heap_realloc(This
->cbs
, This
->ncbs
* sizeof(*This
->cbs
));
1487 This
->cbs
[i
] = pCallback
;
1489 LeaveCriticalSection(&This
->lock
);
1494 static void WINAPI
IXAudio2Impl_UnregisterForCallbacks(IXAudio2
*iface
,
1495 IXAudio2EngineCallback
*pCallback
)
1497 IXAudio2Impl
*This
= impl_from_IXAudio2(iface
);
1500 TRACE("(%p)->(%p)\n", This
, pCallback
);
1502 EnterCriticalSection(&This
->lock
);
1504 if(This
->ncbs
== 0){
1505 LeaveCriticalSection(&This
->lock
);
1509 for(i
= 0; i
< This
->ncbs
; ++i
){
1510 if(This
->cbs
[i
] == pCallback
)
1514 for(; i
< This
->ncbs
- 1 && This
->cbs
[i
+ 1]; ++i
)
1515 This
->cbs
[i
] = This
->cbs
[i
+ 1];
1518 This
->cbs
[i
] = NULL
;
1520 LeaveCriticalSection(&This
->lock
);
1523 static inline XA2VoiceImpl
*create_voice(IXAudio2Impl
*This
)
1525 XA2VoiceImpl
*voice
;
1527 voice
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(*voice
));
1531 list_add_head(&This
->voices
, &voice
->entry
);
1533 voice
->IXAudio2SourceVoice_iface
.lpVtbl
= &XAudio2SourceVoice_Vtbl
;
1534 #if XAUDIO2_VER == 0
1535 voice
->IXAudio20SourceVoice_iface
.lpVtbl
= &XAudio20SourceVoice_Vtbl
;
1536 #elif XAUDIO2_VER <= 3
1537 voice
->IXAudio23SourceVoice_iface
.lpVtbl
= &XAudio23SourceVoice_Vtbl
;
1538 #elif XAUDIO2_VER <= 7
1539 voice
->IXAudio27SourceVoice_iface
.lpVtbl
= &XAudio27SourceVoice_Vtbl
;
1542 voice
->IXAudio2SubmixVoice_iface
.lpVtbl
= &XAudio2SubmixVoice_Vtbl
;
1543 #if XAUDIO2_VER == 0
1544 voice
->IXAudio20SubmixVoice_iface
.lpVtbl
= &XAudio20SubmixVoice_Vtbl
;
1545 #elif XAUDIO2_VER <= 3
1546 voice
->IXAudio23SubmixVoice_iface
.lpVtbl
= &XAudio23SubmixVoice_Vtbl
;
1547 #elif XAUDIO2_VER <= 7
1548 voice
->IXAudio27SubmixVoice_iface
.lpVtbl
= &XAudio27SubmixVoice_Vtbl
;
1551 voice
->FAudioVoiceCallback_vtbl
= FAudioVoiceCallback_Vtbl
;
1553 InitializeCriticalSection(&voice
->lock
);
1554 voice
->lock
.DebugInfo
->Spare
[0] = (DWORD_PTR
)(__FILE__
": XA2VoiceImpl.lock");
1559 static HRESULT WINAPI
IXAudio2Impl_CreateSourceVoice(IXAudio2
*iface
,
1560 IXAudio2SourceVoice
**ppSourceVoice
, const WAVEFORMATEX
*pSourceFormat
,
1561 UINT32 flags
, float maxFrequencyRatio
,
1562 IXAudio2VoiceCallback
*pCallback
, const XAUDIO2_VOICE_SENDS
*pSendList
,
1563 const XAUDIO2_EFFECT_CHAIN
*pEffectChain
)
1565 IXAudio2Impl
*This
= impl_from_IXAudio2(iface
);
1568 FAudioVoiceSends
*faudio_sends
;
1570 TRACE("(%p)->(%p, %p, 0x%x, %f, %p, %p, %p)\n", This
, ppSourceVoice
,
1571 pSourceFormat
, flags
, maxFrequencyRatio
, pCallback
, pSendList
,
1574 EnterCriticalSection(&This
->lock
);
1576 LIST_FOR_EACH_ENTRY(src
, &This
->voices
, XA2VoiceImpl
, entry
){
1577 EnterCriticalSection(&src
->lock
);
1580 LeaveCriticalSection(&src
->lock
);
1583 if(&src
->entry
== &This
->voices
){
1584 src
= create_voice(This
);
1585 EnterCriticalSection(&src
->lock
);
1588 LeaveCriticalSection(&This
->lock
);
1590 src
->effect_chain
= wrap_effect_chain(pEffectChain
);
1591 faudio_sends
= wrap_voice_sends(pSendList
);
1593 hr
= FAudio_CreateSourceVoice(This
->faudio
, &src
->faudio_voice
,
1594 (FAudioWaveFormatEx
*)pSourceFormat
, flags
, maxFrequencyRatio
,
1595 &src
->FAudioVoiceCallback_vtbl
, faudio_sends
,
1597 free_voice_sends(faudio_sends
);
1599 LeaveCriticalSection(&This
->lock
);
1603 src
->cb
= pCallback
;
1605 LeaveCriticalSection(&src
->lock
);
1607 #if XAUDIO2_VER == 0
1608 *ppSourceVoice
= (IXAudio2SourceVoice
*)&src
->IXAudio20SourceVoice_iface
;
1609 #elif XAUDIO2_VER <= 3
1610 *ppSourceVoice
= (IXAudio2SourceVoice
*)&src
->IXAudio23SourceVoice_iface
;
1611 #elif XAUDIO2_VER <= 7
1612 *ppSourceVoice
= (IXAudio2SourceVoice
*)&src
->IXAudio27SourceVoice_iface
;
1614 *ppSourceVoice
= &src
->IXAudio2SourceVoice_iface
;
1617 TRACE("Created source voice: %p\n", src
);
1622 static HRESULT WINAPI
IXAudio2Impl_CreateSubmixVoice(IXAudio2
*iface
,
1623 IXAudio2SubmixVoice
**ppSubmixVoice
, UINT32 inputChannels
,
1624 UINT32 inputSampleRate
, UINT32 flags
, UINT32 processingStage
,
1625 const XAUDIO2_VOICE_SENDS
*pSendList
,
1626 const XAUDIO2_EFFECT_CHAIN
*pEffectChain
)
1629 IXAudio2Impl
*This
= impl_from_IXAudio2(iface
);
1631 FAudioVoiceSends
*faudio_sends
;
1633 TRACE("(%p)->(%p, %u, %u, 0x%x, %u, %p, %p)\n", This
, ppSubmixVoice
,
1634 inputChannels
, inputSampleRate
, flags
, processingStage
, pSendList
,
1637 EnterCriticalSection(&This
->lock
);
1639 LIST_FOR_EACH_ENTRY(sub
, &This
->voices
, XA2VoiceImpl
, entry
){
1640 EnterCriticalSection(&sub
->lock
);
1643 LeaveCriticalSection(&sub
->lock
);
1646 if(&sub
->entry
== &This
->voices
){
1647 sub
= create_voice(This
);
1648 EnterCriticalSection(&sub
->lock
);
1651 LeaveCriticalSection(&This
->lock
);
1653 sub
->effect_chain
= wrap_effect_chain(pEffectChain
);
1654 faudio_sends
= wrap_voice_sends(pSendList
);
1656 hr
= FAudio_CreateSubmixVoice(This
->faudio
, &sub
->faudio_voice
, inputChannels
,
1657 inputSampleRate
, flags
, processingStage
, faudio_sends
,
1659 free_voice_sends(faudio_sends
);
1661 LeaveCriticalSection(&sub
->lock
);
1666 LeaveCriticalSection(&sub
->lock
);
1668 #if XAUDIO2_VER == 0
1669 *ppSubmixVoice
= (IXAudio2SubmixVoice
*)&sub
->IXAudio20SubmixVoice_iface
;
1670 #elif XAUDIO2_VER <= 3
1671 *ppSubmixVoice
= (IXAudio2SubmixVoice
*)&sub
->IXAudio23SubmixVoice_iface
;
1672 #elif XAUDIO2_VER <= 7
1673 *ppSubmixVoice
= (IXAudio2SubmixVoice
*)&sub
->IXAudio27SubmixVoice_iface
;
1675 *ppSubmixVoice
= &sub
->IXAudio2SubmixVoice_iface
;
1678 TRACE("Created submix voice: %p\n", sub
);
1683 /* called thread created by SDL, must not access Wine TEB */
1684 void engine_cb(FAudioEngineCallEXT proc
, FAudio
*faudio
, float *stream
, void *user
)
1686 XA2VoiceImpl
*This
= user
;
1688 pthread_mutex_lock(&This
->engine_lock
);
1690 This
->engine_params
.proc
= proc
;
1691 This
->engine_params
.stream
= stream
;
1692 This
->engine_params
.faudio
= faudio
;
1694 pthread_cond_broadcast(&This
->engine_ready
);
1696 while(This
->engine_params
.proc
)
1697 pthread_cond_wait(&This
->engine_done
, &This
->engine_lock
);
1699 pthread_mutex_unlock(&This
->engine_lock
);
1702 /* wine thread, OK to access TEB, invoke client code, etc */
1703 DWORD WINAPI
engine_thread(void *user
)
1705 XA2VoiceImpl
*This
= user
;
1707 pthread_mutex_lock(&This
->engine_lock
);
1709 pthread_cond_broadcast(&This
->engine_done
);
1712 pthread_cond_wait(&This
->engine_ready
, &This
->engine_lock
);
1714 if(This
->engine_params
.proc
){
1715 This
->engine_params
.proc(This
->engine_params
.faudio
, This
->engine_params
.stream
);
1716 This
->engine_params
.proc
= NULL
;
1717 pthread_cond_broadcast(&This
->engine_done
);
1719 }while(This
->in_use
);
1721 pthread_mutex_unlock(&This
->engine_lock
);
1726 static HRESULT WINAPI
IXAudio2Impl_CreateMasteringVoice(IXAudio2
*iface
,
1727 IXAudio2MasteringVoice
**ppMasteringVoice
, UINT32 inputChannels
,
1728 UINT32 inputSampleRate
, UINT32 flags
, const WCHAR
*deviceId
,
1729 const XAUDIO2_EFFECT_CHAIN
*pEffectChain
,
1730 AUDIO_STREAM_CATEGORY streamCategory
)
1732 IXAudio2Impl
*This
= impl_from_IXAudio2(iface
);
1734 TRACE("(%p)->(%p, %u, %u, 0x%x, %s, %p, 0x%x)\n", This
,
1735 ppMasteringVoice
, inputChannels
, inputSampleRate
, flags
,
1736 wine_dbgstr_w(deviceId
), pEffectChain
, streamCategory
);
1738 EnterCriticalSection(&This
->lock
);
1740 /* Note that we don't have paths for each XAUDIO2_VER here.
1741 * All versions < 8 have a very different CreateMasteringVoice, so we
1742 * implement those separately in compat.c.
1745 *ppMasteringVoice
= &This
->mst
.IXAudio2MasteringVoice_iface
;
1747 EnterCriticalSection(&This
->mst
.lock
);
1749 if(This
->mst
.in_use
){
1750 LeaveCriticalSection(&This
->mst
.lock
);
1751 LeaveCriticalSection(&This
->lock
);
1752 return COMPAT_E_INVALID_CALL
;
1755 LeaveCriticalSection(&This
->lock
);
1757 This
->mst
.effect_chain
= wrap_effect_chain(pEffectChain
);
1759 pthread_mutex_lock(&This
->mst
.engine_lock
);
1761 This
->mst
.engine_thread
= CreateThread(NULL
, 0, &engine_thread
, &This
->mst
, 0, NULL
);
1763 pthread_cond_wait(&This
->mst
.engine_done
, &This
->mst
.engine_lock
);
1765 pthread_mutex_unlock(&This
->mst
.engine_lock
);
1767 FAudio_SetEngineProcedureEXT(This
->faudio
, &engine_cb
, &This
->mst
);
1769 FAudio_CreateMasteringVoice8(This
->faudio
, &This
->mst
.faudio_voice
, inputChannels
,
1770 inputSampleRate
, flags
, NULL
/* TODO: (uint16_t*)deviceId */,
1771 This
->mst
.effect_chain
, (FAudioStreamCategory
)streamCategory
);
1773 This
->mst
.in_use
= TRUE
;
1775 LeaveCriticalSection(&This
->mst
.lock
);
1780 static HRESULT WINAPI
IXAudio2Impl_StartEngine(IXAudio2
*iface
)
1782 IXAudio2Impl
*This
= impl_from_IXAudio2(iface
);
1784 TRACE("(%p)->()\n", This
);
1786 return FAudio_StartEngine(This
->faudio
);
1789 static void WINAPI
IXAudio2Impl_StopEngine(IXAudio2
*iface
)
1791 IXAudio2Impl
*This
= impl_from_IXAudio2(iface
);
1793 TRACE("(%p)->()\n", This
);
1795 FAudio_StopEngine(This
->faudio
);
1798 static HRESULT WINAPI
IXAudio2Impl_CommitChanges(IXAudio2
*iface
,
1799 UINT32 operationSet
)
1801 IXAudio2Impl
*This
= impl_from_IXAudio2(iface
);
1803 TRACE("(%p)->(0x%x)\n", This
, operationSet
);
1805 #ifdef HAVE_FAUDIO_COMMITOPERATIONSET
1806 return FAudio_CommitOperationSet(This
->faudio
, operationSet
);
1808 return FAudio_CommitChanges(This
->faudio
);
1812 static void WINAPI
IXAudio2Impl_GetPerformanceData(IXAudio2
*iface
,
1813 XAUDIO2_PERFORMANCE_DATA
*pPerfData
)
1815 IXAudio2Impl
*This
= impl_from_IXAudio2(iface
);
1817 TRACE("(%p)->(%p)\n", This
, pPerfData
);
1819 FAudio_GetPerformanceData(This
->faudio
, (FAudioPerformanceData
*)pPerfData
);
1822 static void WINAPI
IXAudio2Impl_SetDebugConfiguration(IXAudio2
*iface
,
1823 const XAUDIO2_DEBUG_CONFIGURATION
*pDebugConfiguration
,
1826 IXAudio2Impl
*This
= impl_from_IXAudio2(iface
);
1828 TRACE("(%p)->(%p, %p)\n", This
, pDebugConfiguration
, pReserved
);
1830 FAudio_SetDebugConfiguration(This
->faudio
, (FAudioDebugConfiguration
*)pDebugConfiguration
, pReserved
);
1834 static const IXAudio2Vtbl XAudio2_Vtbl
=
1836 IXAudio2Impl_QueryInterface
,
1837 IXAudio2Impl_AddRef
,
1838 IXAudio2Impl_Release
,
1839 IXAudio2Impl_RegisterForCallbacks
,
1840 IXAudio2Impl_UnregisterForCallbacks
,
1841 IXAudio2Impl_CreateSourceVoice
,
1842 IXAudio2Impl_CreateSubmixVoice
,
1843 IXAudio2Impl_CreateMasteringVoice
,
1844 IXAudio2Impl_StartEngine
,
1845 IXAudio2Impl_StopEngine
,
1846 IXAudio2Impl_CommitChanges
,
1847 IXAudio2Impl_GetPerformanceData
,
1848 IXAudio2Impl_SetDebugConfiguration
1851 /* XAudio2 ClassFactory */
1854 IClassFactory IClassFactory_iface
;
1858 static struct xaudio2_cf
*impl_from_IClassFactory(IClassFactory
*iface
)
1860 return CONTAINING_RECORD(iface
, struct xaudio2_cf
, IClassFactory_iface
);
1863 static HRESULT WINAPI
XAudio2CF_QueryInterface(IClassFactory
*iface
, REFIID riid
, void **ppobj
)
1865 if(IsEqualGUID(riid
, &IID_IUnknown
)
1866 || IsEqualGUID(riid
, &IID_IClassFactory
))
1868 IClassFactory_AddRef(iface
);
1874 WARN("(%p)->(%s, %p): interface not found\n", iface
, debugstr_guid(riid
), ppobj
);
1875 return E_NOINTERFACE
;
1878 static ULONG WINAPI
XAudio2CF_AddRef(IClassFactory
*iface
)
1880 struct xaudio2_cf
*This
= impl_from_IClassFactory(iface
);
1881 ULONG ref
= InterlockedIncrement(&This
->ref
);
1882 TRACE("(%p)->(): Refcount now %u\n", This
, ref
);
1886 static ULONG WINAPI
XAudio2CF_Release(IClassFactory
*iface
)
1888 struct xaudio2_cf
*This
= impl_from_IClassFactory(iface
);
1889 ULONG ref
= InterlockedDecrement(&This
->ref
);
1890 TRACE("(%p)->(): Refcount now %u\n", This
, ref
);
1892 HeapFree(GetProcessHeap(), 0, This
);
1896 static HRESULT WINAPI
XAudio2CF_CreateInstance(IClassFactory
*iface
, IUnknown
*pOuter
,
1897 REFIID riid
, void **ppobj
)
1899 struct xaudio2_cf
*This
= impl_from_IClassFactory(iface
);
1901 IXAudio2Impl
*object
;
1903 TRACE("(%p)->(%p,%s,%p)\n", This
, pOuter
, debugstr_guid(riid
), ppobj
);
1908 return CLASS_E_NOAGGREGATION
;
1910 object
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(*object
));
1912 return E_OUTOFMEMORY
;
1914 object
->IXAudio2_iface
.lpVtbl
= &XAudio2_Vtbl
;
1916 #if XAUDIO2_VER == 0
1917 object
->IXAudio20_iface
.lpVtbl
= &XAudio20_Vtbl
;
1918 #elif XAUDIO2_VER <= 2
1919 object
->IXAudio22_iface
.lpVtbl
= &XAudio22_Vtbl
;
1920 #elif XAUDIO2_VER <= 3
1921 object
->IXAudio23_iface
.lpVtbl
= &XAudio23_Vtbl
;
1922 #elif XAUDIO2_VER <= 7
1923 object
->IXAudio27_iface
.lpVtbl
= &XAudio27_Vtbl
;
1926 object
->mst
.IXAudio2MasteringVoice_iface
.lpVtbl
= &XAudio2MasteringVoice_Vtbl
;
1928 #if XAUDIO2_VER == 0
1929 object
->mst
.IXAudio20MasteringVoice_iface
.lpVtbl
= &XAudio20MasteringVoice_Vtbl
;
1930 #elif XAUDIO2_VER <= 3
1931 object
->mst
.IXAudio23MasteringVoice_iface
.lpVtbl
= &XAudio23MasteringVoice_Vtbl
;
1932 #elif XAUDIO2_VER <= 7
1933 object
->mst
.IXAudio27MasteringVoice_iface
.lpVtbl
= &XAudio27MasteringVoice_Vtbl
;
1936 object
->FAudioEngineCallback_vtbl
= FAudioEngineCallback_Vtbl
;
1938 list_init(&object
->voices
);
1940 InitializeCriticalSection(&object
->lock
);
1941 object
->lock
.DebugInfo
->Spare
[0] = (DWORD_PTR
)(__FILE__
": IXAudio2Impl.lock");
1943 InitializeCriticalSection(&object
->mst
.lock
);
1944 object
->mst
.lock
.DebugInfo
->Spare
[0] = (DWORD_PTR
)(__FILE__
": XA2MasteringVoice.lock");
1946 pthread_mutex_init(&object
->mst
.engine_lock
, NULL
);
1947 pthread_cond_init(&object
->mst
.engine_done
, NULL
);
1948 pthread_cond_init(&object
->mst
.engine_ready
, NULL
);
1950 FAudioCOMConstructWithCustomAllocatorEXT(
1953 XAudio_Internal_Malloc
,
1954 XAudio_Internal_Free
,
1955 XAudio_Internal_Realloc
1958 FAudio_RegisterForCallbacks(object
->faudio
, &object
->FAudioEngineCallback_vtbl
);
1960 hr
= IXAudio2_QueryInterface(&object
->IXAudio2_iface
, riid
, ppobj
);
1961 IXAudio2_Release(&object
->IXAudio2_iface
);
1966 TRACE("Created XAudio version %u: %p\n", 20 + XAUDIO2_VER
, object
);
1971 static HRESULT WINAPI
XAudio2CF_LockServer(IClassFactory
*iface
, BOOL dolock
)
1973 struct xaudio2_cf
*This
= impl_from_IClassFactory(iface
);
1974 FIXME("(%p)->(%d): stub!\n", This
, dolock
);
1978 static const IClassFactoryVtbl XAudio2CF_Vtbl
=
1980 XAudio2CF_QueryInterface
,
1983 XAudio2CF_CreateInstance
,
1984 XAudio2CF_LockServer
1987 /* Engine Generators */
1989 static inline HRESULT
make_xaudio2_factory(REFIID riid
, void **ppv
)
1992 struct xaudio2_cf
*ret
= HeapAlloc(GetProcessHeap(), 0, sizeof(struct xaudio2_cf
));
1993 ret
->IClassFactory_iface
.lpVtbl
= &XAudio2CF_Vtbl
;
1995 hr
= IClassFactory_QueryInterface(&ret
->IClassFactory_iface
, riid
, ppv
);
1997 HeapFree(GetProcessHeap(), 0, ret
);
2001 HRESULT
xaudio2_initialize(IXAudio2Impl
*This
, UINT32 flags
, XAUDIO2_PROCESSOR proc
)
2003 if(proc
!= XAUDIO2_ANY_PROCESSOR
)
2004 WARN("Processor affinity not implemented in FAudio\n");
2005 return FAudio_Initialize(This
->faudio
, flags
, FAUDIO_DEFAULT_PROCESSOR
);
2008 HRESULT WINAPI
DllGetClassObject(REFCLSID rclsid
, REFIID riid
, void **ppv
)
2010 TRACE("(%s, %s, %p)\n", debugstr_guid(rclsid
), debugstr_guid(riid
), ppv
);
2012 if(IsEqualGUID(rclsid
, &CLSID_XAudio20
) ||
2013 IsEqualGUID(rclsid
, &CLSID_XAudio21
) ||
2014 IsEqualGUID(rclsid
, &CLSID_XAudio22
) ||
2015 IsEqualGUID(rclsid
, &CLSID_XAudio23
) ||
2016 IsEqualGUID(rclsid
, &CLSID_XAudio24
) ||
2017 IsEqualGUID(rclsid
, &CLSID_XAudio25
) ||
2018 IsEqualGUID(rclsid
, &CLSID_XAudio26
) ||
2019 IsEqualGUID(rclsid
, &CLSID_XAudio27
))
2020 return make_xaudio2_factory(riid
, ppv
);
2022 if(IsEqualGUID(rclsid
, &CLSID_AudioVolumeMeter20
) ||
2023 IsEqualGUID(rclsid
, &CLSID_AudioVolumeMeter21
) ||
2024 IsEqualGUID(rclsid
, &CLSID_AudioVolumeMeter22
) ||
2025 IsEqualGUID(rclsid
, &CLSID_AudioVolumeMeter23
) ||
2026 IsEqualGUID(rclsid
, &CLSID_AudioVolumeMeter24
) ||
2027 IsEqualGUID(rclsid
, &CLSID_AudioVolumeMeter25
) ||
2028 IsEqualGUID(rclsid
, &CLSID_AudioVolumeMeter26
) ||
2029 IsEqualGUID(rclsid
, &CLSID_AudioVolumeMeter27
))
2030 return make_xapo_factory(&CLSID_AudioVolumeMeter27
, riid
, ppv
);
2032 if(IsEqualGUID(rclsid
, &CLSID_AudioReverb20
) ||
2033 IsEqualGUID(rclsid
, &CLSID_AudioReverb21
) ||
2034 IsEqualGUID(rclsid
, &CLSID_AudioReverb22
) ||
2035 IsEqualGUID(rclsid
, &CLSID_AudioReverb23
) ||
2036 IsEqualGUID(rclsid
, &CLSID_AudioReverb24
) ||
2037 IsEqualGUID(rclsid
, &CLSID_AudioReverb25
) ||
2038 IsEqualGUID(rclsid
, &CLSID_AudioReverb26
) ||
2039 IsEqualGUID(rclsid
, &CLSID_AudioReverb27
))
2040 return make_xapo_factory(&CLSID_AudioReverb27
, riid
, ppv
);
2042 return CLASS_E_CLASSNOTAVAILABLE
;
2045 #if XAUDIO2_VER >= 8
2046 HRESULT WINAPI
XAudio2Create(IXAudio2
**ppxa2
, UINT32 flags
, XAUDIO2_PROCESSOR proc
)
2052 TRACE("%p 0x%x 0x%x\n", ppxa2
, flags
, proc
);
2054 hr
= make_xaudio2_factory(&IID_IClassFactory
, (void**)&cf
);
2058 hr
= IClassFactory_CreateInstance(cf
, NULL
, &IID_IXAudio2
, (void**)&xa2
);
2059 IClassFactory_Release(cf
);
2063 hr
= xaudio2_initialize(impl_from_IXAudio2(xa2
), flags
, proc
);
2065 IXAudio2_Release(xa2
);
2074 HRESULT WINAPI
CreateAudioVolumeMeter(IUnknown
**out
)
2081 hr
= make_xapo_factory(&CLSID_AudioVolumeMeter27
, &IID_IClassFactory
, (void**)&cf
);
2085 hr
= IClassFactory_CreateInstance(cf
, NULL
, &IID_IUnknown
, (void**)out
);
2087 IClassFactory_Release(cf
);
2092 HRESULT WINAPI
CreateAudioReverb(IUnknown
**out
)
2099 hr
= make_xapo_factory(&CLSID_AudioReverb27
, &IID_IClassFactory
, (void**)&cf
);
2103 hr
= IClassFactory_CreateInstance(cf
, NULL
, &IID_IUnknown
, (void**)out
);
2105 IClassFactory_Release(cf
);
2109 #endif /* XAUDIO2_VER >= 8 */