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
27 #include "mmdeviceapi.h"
30 #include "xaudio_private.h"
36 #include "wine/debug.h"
38 WINE_DEFAULT_DEBUG_CHANNEL(xaudio2
);
40 #if XAUDIO2_VER != 0 && defined(__i386__)
41 /* EVE Online uses an OnVoiceProcessingPassStart callback which corrupts %esi;
42 * League of Legends uses a callback which corrupts %ebx. */
43 #define IXAudio2VoiceCallback_OnVoiceProcessingPassStart(a, b) call_on_voice_processing_pass_start(a, b)
44 extern void call_on_voice_processing_pass_start(IXAudio2VoiceCallback
*This
, UINT32 BytesRequired
);
45 __ASM_GLOBAL_FUNC( call_on_voice_processing_pass_start
,
47 __ASM_CFI(".cfi_adjust_cfa_offset 4\n\t")
48 __ASM_CFI(".cfi_rel_offset %ebp,0\n\t")
50 __ASM_CFI(".cfi_def_cfa_register %ebp\n\t")
52 __ASM_CFI(".cfi_rel_offset %esi,-4\n\t")
54 __ASM_CFI(".cfi_rel_offset %edi,-8\n\t")
56 __ASM_CFI(".cfi_rel_offset %ebx,-12\n\t")
58 "pushl 12(%ebp)\n\t" /* BytesRequired */
59 "pushl 8(%ebp)\n\t" /* This */
60 "movl 8(%ebp),%eax\n\t"
61 "movl 0(%eax),%eax\n\t"
62 "call *0(%eax)\n\t" /* This->lpVtbl->OnVoiceProcessingPassStart */
63 "leal -12(%ebp),%esp\n\t"
65 __ASM_CFI(".cfi_same_value %ebx\n\t")
67 __ASM_CFI(".cfi_same_value %edi\n\t")
69 __ASM_CFI(".cfi_same_value %esi\n\t")
71 __ASM_CFI(".cfi_def_cfa %esp,4\n\t")
72 __ASM_CFI(".cfi_same_value %ebp\n\t")
76 static XA2VoiceImpl
*impl_from_IXAudio2Voice(IXAudio2Voice
*iface
);
78 BOOL WINAPI
DllMain(HINSTANCE hinstDLL
, DWORD reason
, void *pReserved
)
80 TRACE("(%p, %ld, %p)\n", hinstDLL
, reason
, pReserved
);
84 case DLL_PROCESS_ATTACH
:
85 DisableThreadLibraryCalls( hinstDLL
);
86 TRACE("Using FAudio version %d\n", FAudioLinkedVersion() );
94 static inline XA2XAPOImpl
*impl_from_FAPO(FAPO
*iface
)
96 return CONTAINING_RECORD(iface
, XA2XAPOImpl
, FAPO_vtbl
);
99 static int32_t FAPOCALL
XAPO_AddRef(void *iface
)
101 XA2XAPOImpl
*This
= impl_from_FAPO(iface
);
103 return InterlockedIncrement(&This
->ref
);
106 static int32_t FAPOCALL
XAPO_Release(void *iface
)
109 XA2XAPOImpl
*This
= impl_from_FAPO(iface
);
111 r
= InterlockedDecrement(&This
->ref
);
113 IXAPO_Release(This
->xapo
);
114 if(This
->xapo_params
)
115 IXAPOParameters_Release(This
->xapo_params
);
121 static uint32_t FAPOCALL
XAPO_GetRegistrationProperties(void *iface
,
122 FAPORegistrationProperties
**ppRegistrationProperties
)
124 XA2XAPOImpl
*This
= impl_from_FAPO(iface
);
125 XAPO_REGISTRATION_PROPERTIES
*xprops
;
130 hr
= IXAPO_GetRegistrationProperties(This
->xapo
, &xprops
);
134 /* TODO: check for version == 20 and use XAPO20_REGISTRATION_PROPERTIES */
135 *ppRegistrationProperties
= (FAPORegistrationProperties
*) xprops
;
139 static uint32_t FAPOCALL
XAPO_IsInputFormatSupported(void *iface
,
140 const FAudioWaveFormatEx
*pOutputFormat
, const FAudioWaveFormatEx
*pRequestedInputFormat
,
141 FAudioWaveFormatEx
**ppSupportedInputFormat
)
143 XA2XAPOImpl
*This
= impl_from_FAPO(iface
);
145 return IXAPO_IsInputFormatSupported(This
->xapo
, (const WAVEFORMATEX
*)pOutputFormat
,
146 (const WAVEFORMATEX
*)pRequestedInputFormat
, (WAVEFORMATEX
**)ppSupportedInputFormat
);
149 static uint32_t FAPOCALL
XAPO_IsOutputFormatSupported(void *iface
,
150 const FAudioWaveFormatEx
*pInputFormat
, const FAudioWaveFormatEx
*pRequestedOutputFormat
,
151 FAudioWaveFormatEx
**ppSupportedOutputFormat
)
153 XA2XAPOImpl
*This
= impl_from_FAPO(iface
);
155 return IXAPO_IsOutputFormatSupported(This
->xapo
, (const WAVEFORMATEX
*)pInputFormat
,
156 (const WAVEFORMATEX
*)pRequestedOutputFormat
, (WAVEFORMATEX
**)ppSupportedOutputFormat
);
159 static uint32_t FAPOCALL
XAPO_Initialize(void *iface
, const void *pData
,
160 uint32_t DataByteSize
)
162 XA2XAPOImpl
*This
= impl_from_FAPO(iface
);
164 return IXAPO_Initialize(This
->xapo
, pData
, DataByteSize
);
167 static void FAPOCALL
XAPO_Reset(void *iface
)
169 XA2XAPOImpl
*This
= impl_from_FAPO(iface
);
171 IXAPO_Reset(This
->xapo
);
174 static uint32_t FAPOCALL
XAPO_LockForProcess(void *iface
,
175 uint32_t InputLockedParameterCount
,
176 const FAPOLockForProcessBufferParameters
*pInputLockedParameters
,
177 uint32_t OutputLockedParameterCount
,
178 const FAPOLockForProcessBufferParameters
*pOutputLockedParameters
)
180 XA2XAPOImpl
*This
= impl_from_FAPO(iface
);
182 return IXAPO_LockForProcess(This
->xapo
,
183 InputLockedParameterCount
,
184 (const XAPO_LOCKFORPROCESS_BUFFER_PARAMETERS
*)pInputLockedParameters
,
185 OutputLockedParameterCount
,
186 (const XAPO_LOCKFORPROCESS_BUFFER_PARAMETERS
*)pOutputLockedParameters
);
189 static void FAPOCALL
XAPO_UnlockForProcess(void *iface
)
191 XA2XAPOImpl
*This
= impl_from_FAPO(iface
);
193 IXAPO_UnlockForProcess(This
->xapo
);
196 static void FAPOCALL
XAPO_Process(void *iface
,
197 uint32_t InputProcessParameterCount
,
198 const FAPOProcessBufferParameters
* pInputProcessParameters
,
199 uint32_t OutputProcessParameterCount
,
200 FAPOProcessBufferParameters
* pOutputProcessParameters
,
203 XA2XAPOImpl
*This
= impl_from_FAPO(iface
);
205 IXAPO_Process(This
->xapo
, InputProcessParameterCount
,
206 (const XAPO_PROCESS_BUFFER_PARAMETERS
*)pInputProcessParameters
,
207 OutputProcessParameterCount
,
208 (XAPO_PROCESS_BUFFER_PARAMETERS
*)pOutputProcessParameters
,
212 static uint32_t FAPOCALL
XAPO_CalcInputFrames(void *iface
,
213 uint32_t OutputFrameCount
)
215 XA2XAPOImpl
*This
= impl_from_FAPO(iface
);
217 return IXAPO_CalcInputFrames(This
->xapo
, OutputFrameCount
);
220 static uint32_t FAPOCALL
XAPO_CalcOutputFrames(void *iface
,
221 uint32_t InputFrameCount
)
223 XA2XAPOImpl
*This
= impl_from_FAPO(iface
);
225 return IXAPO_CalcOutputFrames(This
->xapo
, InputFrameCount
);
228 static void FAPOCALL
XAPO_SetParameters(void *iface
,
229 const void *pParameters
, uint32_t ParametersByteSize
)
231 XA2XAPOImpl
*This
= impl_from_FAPO(iface
);
233 if(This
->xapo_params
)
234 IXAPOParameters_SetParameters(This
->xapo_params
, pParameters
, ParametersByteSize
);
237 static void FAPOCALL
XAPO_GetParameters(void *iface
,
238 void *pParameters
, uint32_t ParametersByteSize
)
240 XA2XAPOImpl
*This
= impl_from_FAPO(iface
);
242 if(This
->xapo_params
)
243 IXAPOParameters_GetParameters(This
->xapo_params
, pParameters
, ParametersByteSize
);
245 memset(pParameters
, 0, ParametersByteSize
);
248 static const FAPO FAPO_Vtbl
= {
251 XAPO_GetRegistrationProperties
,
252 XAPO_IsInputFormatSupported
,
253 XAPO_IsOutputFormatSupported
,
257 XAPO_UnlockForProcess
,
259 XAPO_CalcInputFrames
,
260 XAPO_CalcOutputFrames
,
265 static XA2XAPOImpl
*wrap_xapo(IUnknown
*unk
)
269 IXAPOParameters
*xapo_params
;
273 hr
= IUnknown_QueryInterface(unk
, &IID_IXAPO27
, (void**)&xapo
);
275 hr
= IUnknown_QueryInterface(unk
, &IID_IXAPO
, (void**)&xapo
);
278 WARN("XAPO doesn't support IXAPO? %p\n", unk
);
283 hr
= IUnknown_QueryInterface(unk
, &IID_IXAPO27Parameters
, (void**)&xapo_params
);
285 hr
= IUnknown_QueryInterface(unk
, &IID_IXAPOParameters
, (void**)&xapo_params
);
288 TRACE("XAPO doesn't support IXAPOParameters %p\n", unk
);
292 ret
= malloc(sizeof(*ret
));
295 ret
->xapo_params
= xapo_params
;
296 ret
->FAPO_vtbl
= FAPO_Vtbl
;
299 TRACE("wrapped IXAPO %p with %p\n", xapo
, ret
);
304 FAudioEffectChain
*wrap_effect_chain(const XAUDIO2_EFFECT_CHAIN
*pEffectChain
)
306 FAudioEffectChain
*ret
;
312 ret
= malloc(sizeof(*ret
) + sizeof(FAudioEffectDescriptor
) * pEffectChain
->EffectCount
);
314 ret
->EffectCount
= pEffectChain
->EffectCount
;
315 ret
->pEffectDescriptors
= (void*)(ret
+ 1);
317 for(i
= 0; i
< ret
->EffectCount
; ++i
){
318 ret
->pEffectDescriptors
[i
].pEffect
= &wrap_xapo(pEffectChain
->pEffectDescriptors
[i
].pEffect
)->FAPO_vtbl
;
319 ret
->pEffectDescriptors
[i
].InitialState
= pEffectChain
->pEffectDescriptors
[i
].InitialState
;
320 ret
->pEffectDescriptors
[i
].OutputChannels
= pEffectChain
->pEffectDescriptors
[i
].OutputChannels
;
326 static void free_effect_chain(FAudioEffectChain
*chain
)
331 for(i
= 0; i
< chain
->EffectCount
; ++i
)
332 XAPO_Release(chain
->pEffectDescriptors
[i
].pEffect
);
338 static FAudioVoiceSends
*wrap_voice_sends(const XAUDIO2_VOICE_SENDS
*sends
)
340 FAudioVoiceSends
*ret
;
347 ret
= malloc(sizeof(*ret
) + sends
->OutputCount
* sizeof(FAudioSendDescriptor
));
348 ret
->SendCount
= sends
->OutputCount
;
349 ret
->pSends
= (FAudioSendDescriptor
*)(ret
+ 1);
350 for(i
= 0; i
< sends
->OutputCount
; ++i
){
351 XA2VoiceImpl
*voice
= impl_from_IXAudio2Voice(sends
->pOutputVoices
[i
]);
352 ret
->pSends
[i
].pOutputVoice
= voice
->faudio_voice
;
353 ret
->pSends
[i
].Flags
= 0;
356 ret
= malloc(sizeof(*ret
) + sends
->SendCount
* sizeof(FAudioSendDescriptor
));
357 ret
->SendCount
= sends
->SendCount
;
358 ret
->pSends
= (FAudioSendDescriptor
*)(ret
+ 1);
359 for(i
= 0; i
< sends
->SendCount
; ++i
){
360 XA2VoiceImpl
*voice
= impl_from_IXAudio2Voice(sends
->pSends
[i
].pOutputVoice
);
361 ret
->pSends
[i
].pOutputVoice
= voice
->faudio_voice
;
362 ret
->pSends
[i
].Flags
= sends
->pSends
[i
].Flags
;
368 static void free_voice_sends(FAudioVoiceSends
*sends
)
375 /* Voice Callbacks */
377 static inline XA2VoiceImpl
*impl_from_FAudioVoiceCallback(FAudioVoiceCallback
*iface
)
379 return CONTAINING_RECORD(iface
, XA2VoiceImpl
, FAudioVoiceCallback_vtbl
);
382 static void FAUDIOCALL
XA2VCB_OnVoiceProcessingPassStart(FAudioVoiceCallback
*iface
,
383 UINT32 BytesRequired
)
385 XA2VoiceImpl
*This
= impl_from_FAudioVoiceCallback(iface
);
388 IXAudio2VoiceCallback_OnVoiceProcessingPassStart(This
->cb
395 static void FAUDIOCALL
XA2VCB_OnVoiceProcessingPassEnd(FAudioVoiceCallback
*iface
)
397 XA2VoiceImpl
*This
= impl_from_FAudioVoiceCallback(iface
);
400 IXAudio2VoiceCallback_OnVoiceProcessingPassEnd(This
->cb
);
403 static void FAUDIOCALL
XA2VCB_OnStreamEnd(FAudioVoiceCallback
*iface
)
405 XA2VoiceImpl
*This
= impl_from_FAudioVoiceCallback(iface
);
408 IXAudio2VoiceCallback_OnStreamEnd(This
->cb
);
411 static void FAUDIOCALL
XA2VCB_OnBufferStart(FAudioVoiceCallback
*iface
,
412 void *pBufferContext
)
414 XA2VoiceImpl
*This
= impl_from_FAudioVoiceCallback(iface
);
417 IXAudio2VoiceCallback_OnBufferStart(This
->cb
, pBufferContext
);
420 static void FAUDIOCALL
XA2VCB_OnBufferEnd(FAudioVoiceCallback
*iface
,
421 void *pBufferContext
)
423 XA2VoiceImpl
*This
= impl_from_FAudioVoiceCallback(iface
);
426 IXAudio2VoiceCallback_OnBufferEnd(This
->cb
, pBufferContext
);
429 static void FAUDIOCALL
XA2VCB_OnLoopEnd(FAudioVoiceCallback
*iface
,
430 void *pBufferContext
)
432 XA2VoiceImpl
*This
= impl_from_FAudioVoiceCallback(iface
);
435 IXAudio2VoiceCallback_OnLoopEnd(This
->cb
, pBufferContext
);
438 static void FAUDIOCALL
XA2VCB_OnVoiceError(FAudioVoiceCallback
*iface
,
439 void *pBufferContext
, unsigned int Error
)
441 XA2VoiceImpl
*This
= impl_from_FAudioVoiceCallback(iface
);
444 IXAudio2VoiceCallback_OnVoiceError(This
->cb
, pBufferContext
, (HRESULT
)Error
);
447 static const FAudioVoiceCallback FAudioVoiceCallback_Vtbl
= {
449 XA2VCB_OnBufferStart
,
453 XA2VCB_OnVoiceProcessingPassEnd
,
454 XA2VCB_OnVoiceProcessingPassStart
457 /* Engine Callbacks */
459 static inline IXAudio2Impl
*impl_from_FAudioEngineCallback(FAudioEngineCallback
*iface
)
461 return CONTAINING_RECORD(iface
, IXAudio2Impl
, FAudioEngineCallback_vtbl
);
464 static void FAUDIOCALL
XA2ECB_OnProcessingPassStart(FAudioEngineCallback
*iface
)
466 IXAudio2Impl
*This
= impl_from_FAudioEngineCallback(iface
);
469 for(i
= 0; i
< This
->ncbs
&& This
->cbs
[i
]; ++i
)
470 IXAudio2EngineCallback_OnProcessingPassStart(This
->cbs
[i
]);
473 static void FAUDIOCALL
XA2ECB_OnProcessingPassEnd(FAudioEngineCallback
*iface
)
475 IXAudio2Impl
*This
= impl_from_FAudioEngineCallback(iface
);
478 for(i
= 0; i
< This
->ncbs
&& This
->cbs
[i
]; ++i
)
479 IXAudio2EngineCallback_OnProcessingPassEnd(This
->cbs
[i
]);
482 static void FAUDIOCALL
XA2ECB_OnCriticalError(FAudioEngineCallback
*iface
,
485 IXAudio2Impl
*This
= impl_from_FAudioEngineCallback(iface
);
488 for(i
= 0; i
< This
->ncbs
&& This
->cbs
[i
]; ++i
)
489 IXAudio2EngineCallback_OnCriticalError(This
->cbs
[i
], error
);
492 static const FAudioEngineCallback FAudioEngineCallback_Vtbl
= {
493 XA2ECB_OnCriticalError
,
494 XA2ECB_OnProcessingPassEnd
,
495 XA2ECB_OnProcessingPassStart
498 /* Common Voice Functions */
500 static inline void destroy_voice(XA2VoiceImpl
*This
)
502 FAudioVoice_DestroyVoice(This
->faudio_voice
);
503 free_effect_chain(This
->effect_chain
);
504 This
->effect_chain
= NULL
;
505 This
->in_use
= FALSE
;
508 static void get_voice_details(XA2VoiceImpl
*voice
, XAUDIO2_VOICE_DETAILS
*details
)
510 FAudioVoiceDetails faudio_details
;
512 TRACE("%p, %p\n", voice
, details
);
514 FAudioVoice_GetVoiceDetails(voice
->faudio_voice
, &faudio_details
);
515 details
->CreationFlags
= faudio_details
.CreationFlags
;
517 details
->ActiveFlags
= faudio_details
.ActiveFlags
;
519 details
->InputChannels
= faudio_details
.InputChannels
;
520 details
->InputSampleRate
= faudio_details
.InputSampleRate
;
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
, XAUDIO2_VOICE_DETAILS
*details
)
532 XA2VoiceImpl
*voice
= impl_from_IXAudio2SourceVoice(iface
);
534 get_voice_details(voice
, details
);
537 static HRESULT WINAPI
XA2SRC_SetOutputVoices(IXAudio2SourceVoice
*iface
,
538 const XAUDIO2_VOICE_SENDS
*pSendList
)
540 XA2VoiceImpl
*This
= impl_from_IXAudio2SourceVoice(iface
);
541 FAudioVoiceSends
*faudio_sends
;
544 TRACE("%p, %p\n", This
, pSendList
);
546 faudio_sends
= wrap_voice_sends(pSendList
);
548 hr
= FAudioVoice_SetOutputVoices(This
->faudio_voice
, faudio_sends
);
550 free_voice_sends(faudio_sends
);
555 static HRESULT WINAPI
XA2SRC_SetEffectChain(IXAudio2SourceVoice
*iface
,
556 const XAUDIO2_EFFECT_CHAIN
*pEffectChain
)
558 XA2VoiceImpl
*This
= impl_from_IXAudio2SourceVoice(iface
);
561 TRACE("%p, %p\n", This
, pEffectChain
);
563 free_effect_chain(This
->effect_chain
);
564 This
->effect_chain
= wrap_effect_chain(pEffectChain
);
566 hr
= FAudioVoice_SetEffectChain(This
->faudio_voice
, This
->effect_chain
);
571 static HRESULT WINAPI
XA2SRC_EnableEffect(IXAudio2SourceVoice
*iface
, UINT32 EffectIndex
,
574 XA2VoiceImpl
*This
= impl_from_IXAudio2SourceVoice(iface
);
575 TRACE("%p, %u, 0x%x\n", This
, EffectIndex
, OperationSet
);
576 return FAudioVoice_EnableEffect(This
->faudio_voice
, EffectIndex
, OperationSet
);
579 static HRESULT WINAPI
XA2SRC_DisableEffect(IXAudio2SourceVoice
*iface
, UINT32 EffectIndex
,
582 XA2VoiceImpl
*This
= impl_from_IXAudio2SourceVoice(iface
);
583 TRACE("%p, %u, 0x%x\n", This
, EffectIndex
, OperationSet
);
584 return FAudioVoice_DisableEffect(This
->faudio_voice
, EffectIndex
, OperationSet
);
587 static void WINAPI
XA2SRC_GetEffectState(IXAudio2SourceVoice
*iface
, UINT32 EffectIndex
,
590 XA2VoiceImpl
*This
= impl_from_IXAudio2SourceVoice(iface
);
591 TRACE("%p, %u, %p\n", This
, EffectIndex
, pEnabled
);
592 FAudioVoice_GetEffectState(This
->faudio_voice
, EffectIndex
, (int32_t*)pEnabled
);
595 static HRESULT WINAPI
XA2SRC_SetEffectParameters(IXAudio2SourceVoice
*iface
,
596 UINT32 EffectIndex
, const void *pParameters
, UINT32 ParametersByteSize
,
599 XA2VoiceImpl
*This
= impl_from_IXAudio2SourceVoice(iface
);
600 TRACE("%p, %u, %p, 0x%x, 0x%x\n", This
, EffectIndex
, pParameters
,
601 ParametersByteSize
, OperationSet
);
602 return FAudioVoice_SetEffectParameters(This
->faudio_voice
, EffectIndex
,
603 pParameters
, ParametersByteSize
, OperationSet
);
606 static HRESULT WINAPI
XA2SRC_GetEffectParameters(IXAudio2SourceVoice
*iface
,
607 UINT32 EffectIndex
, void *pParameters
, UINT32 ParametersByteSize
)
609 XA2VoiceImpl
*This
= impl_from_IXAudio2SourceVoice(iface
);
610 TRACE("%p, %u, %p, 0x%x\n", This
, EffectIndex
, pParameters
,
612 return FAudioVoice_GetEffectParameters(This
->faudio_voice
, EffectIndex
,
613 pParameters
, ParametersByteSize
);
616 static HRESULT WINAPI
XA2SRC_SetFilterParameters(IXAudio2SourceVoice
*iface
,
617 const XAUDIO2_FILTER_PARAMETERS
*pParameters
, UINT32 OperationSet
)
619 XA2VoiceImpl
*This
= impl_from_IXAudio2SourceVoice(iface
);
620 TRACE("%p, %p, 0x%x\n", This
, pParameters
, OperationSet
);
621 return FAudioVoice_SetFilterParameters(This
->faudio_voice
,
622 (const FAudioFilterParameters
*)pParameters
, OperationSet
);
625 static void WINAPI
XA2SRC_GetFilterParameters(IXAudio2SourceVoice
*iface
,
626 XAUDIO2_FILTER_PARAMETERS
*pParameters
)
628 XA2VoiceImpl
*This
= impl_from_IXAudio2SourceVoice(iface
);
629 TRACE("%p, %p\n", This
, pParameters
);
630 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
);
661 static HRESULT WINAPI
XA2SRC_SetVolume(IXAudio2SourceVoice
*iface
, float Volume
,
664 XA2VoiceImpl
*This
= impl_from_IXAudio2SourceVoice(iface
);
665 TRACE("%p, %f, 0x%x\n", This
, Volume
, OperationSet
);
666 return FAudioVoice_SetVolume(This
->faudio_voice
, Volume
, OperationSet
);
669 static void WINAPI
XA2SRC_GetVolume(IXAudio2SourceVoice
*iface
, float *pVolume
)
671 XA2VoiceImpl
*This
= impl_from_IXAudio2SourceVoice(iface
);
672 TRACE("%p, %p\n", This
, pVolume
);
673 return FAudioVoice_GetVolume(This
->faudio_voice
, pVolume
);
676 static HRESULT WINAPI
XA2SRC_SetChannelVolumes(IXAudio2SourceVoice
*iface
, UINT32 Channels
,
677 const float *pVolumes
, UINT32 OperationSet
)
679 XA2VoiceImpl
*This
= impl_from_IXAudio2SourceVoice(iface
);
680 TRACE("%p, %u, %p, 0x%x\n", This
, Channels
, pVolumes
, OperationSet
);
681 return FAudioVoice_SetChannelVolumes(This
->faudio_voice
, Channels
,
682 pVolumes
, OperationSet
);
685 static void WINAPI
XA2SRC_GetChannelVolumes(IXAudio2SourceVoice
*iface
, UINT32 Channels
,
688 XA2VoiceImpl
*This
= impl_from_IXAudio2SourceVoice(iface
);
689 TRACE("%p, %u, %p\n", This
, Channels
, pVolumes
);
690 return FAudioVoice_GetChannelVolumes(This
->faudio_voice
, Channels
,
694 static HRESULT WINAPI
XA2SRC_SetOutputMatrix(IXAudio2SourceVoice
*iface
,
695 IXAudio2Voice
*pDestinationVoice
, UINT32 SourceChannels
,
696 UINT32 DestinationChannels
, const float *pLevelMatrix
,
699 XA2VoiceImpl
*This
= impl_from_IXAudio2SourceVoice(iface
);
700 XA2VoiceImpl
*dst
= pDestinationVoice
? impl_from_IXAudio2Voice(pDestinationVoice
) : NULL
;
702 TRACE("%p, %p, %u, %u, %p, 0x%x\n", This
, pDestinationVoice
,
703 SourceChannels
, DestinationChannels
, pLevelMatrix
, OperationSet
);
705 return FAudioVoice_SetOutputMatrix(This
->faudio_voice
, dst
? dst
->faudio_voice
: NULL
,
706 SourceChannels
, DestinationChannels
, pLevelMatrix
, OperationSet
);
714 WINAPI
XA2SRC_GetOutputMatrix(IXAudio2SourceVoice
*iface
,
715 IXAudio2Voice
*pDestinationVoice
, UINT32 SourceChannels
,
716 UINT32 DestinationChannels
, float *pLevelMatrix
)
718 XA2VoiceImpl
*This
= impl_from_IXAudio2SourceVoice(iface
);
719 XA2VoiceImpl
*dst
= pDestinationVoice
? impl_from_IXAudio2Voice(pDestinationVoice
) : NULL
;
721 TRACE("%p, %p, %u, %u, %p\n", This
, pDestinationVoice
,
722 SourceChannels
, DestinationChannels
, pLevelMatrix
);
724 FAudioVoice_GetOutputMatrix(This
->faudio_voice
, dst
? dst
->faudio_voice
: NULL
,
725 SourceChannels
, DestinationChannels
, pLevelMatrix
);
731 static void WINAPI
XA2SRC_DestroyVoice(IXAudio2SourceVoice
*iface
)
733 XA2VoiceImpl
*This
= impl_from_IXAudio2SourceVoice(iface
);
737 EnterCriticalSection(&This
->lock
);
741 LeaveCriticalSection(&This
->lock
);
744 static HRESULT WINAPI
XA2SRC_Start(IXAudio2SourceVoice
*iface
, UINT32 Flags
,
747 XA2VoiceImpl
*This
= impl_from_IXAudio2SourceVoice(iface
);
749 TRACE("%p, 0x%x, 0x%x\n", This
, Flags
, OperationSet
);
751 return FAudioSourceVoice_Start(This
->faudio_voice
, Flags
, OperationSet
);
754 static HRESULT WINAPI
XA2SRC_Stop(IXAudio2SourceVoice
*iface
, UINT32 Flags
,
757 XA2VoiceImpl
*This
= impl_from_IXAudio2SourceVoice(iface
);
759 TRACE("%p, 0x%x, 0x%x\n", This
, Flags
, OperationSet
);
761 return FAudioSourceVoice_Stop(This
->faudio_voice
, Flags
, OperationSet
);
764 static HRESULT WINAPI
XA2SRC_SubmitSourceBuffer(IXAudio2SourceVoice
*iface
,
765 const XAUDIO2_BUFFER
*pBuffer
, const XAUDIO2_BUFFER_WMA
*pBufferWMA
)
767 XA2VoiceImpl
*This
= impl_from_IXAudio2SourceVoice(iface
);
769 TRACE("%p, %p, %p\n", This
, pBuffer
, pBufferWMA
);
771 return FAudioSourceVoice_SubmitSourceBuffer(This
->faudio_voice
, (FAudioBuffer
*)pBuffer
, (FAudioBufferWMA
*)pBufferWMA
);
774 static HRESULT WINAPI
XA2SRC_FlushSourceBuffers(IXAudio2SourceVoice
*iface
)
776 XA2VoiceImpl
*This
= impl_from_IXAudio2SourceVoice(iface
);
780 return FAudioSourceVoice_FlushSourceBuffers(This
->faudio_voice
);
783 static HRESULT WINAPI
XA2SRC_Discontinuity(IXAudio2SourceVoice
*iface
)
785 XA2VoiceImpl
*This
= impl_from_IXAudio2SourceVoice(iface
);
789 return FAudioSourceVoice_Discontinuity(This
->faudio_voice
);
792 static HRESULT WINAPI
XA2SRC_ExitLoop(IXAudio2SourceVoice
*iface
, UINT32 OperationSet
)
794 XA2VoiceImpl
*This
= impl_from_IXAudio2SourceVoice(iface
);
796 TRACE("%p, 0x%x\n", This
, OperationSet
);
798 return FAudioSourceVoice_ExitLoop(This
->faudio_voice
, OperationSet
);
802 static void WINAPI
XA2SRC_GetState(IXAudio2SourceVoice
*iface
, XAUDIO2_VOICE_STATE
*pVoiceState
, UINT32 Flags
)
804 static void WINAPI
XA2SRC_GetState(IXAudio2SourceVoice
*iface
, XAUDIO2_VOICE_STATE
*pVoiceState
)
807 XA2VoiceImpl
*This
= impl_from_IXAudio2SourceVoice(iface
);
812 TRACE("%p, %p, 0x%x\n", This
, pVoiceState
, Flags
);
814 return FAudioSourceVoice_GetState(This
->faudio_voice
, (FAudioVoiceState
*)pVoiceState
, Flags
);
817 static HRESULT WINAPI
XA2SRC_SetFrequencyRatio(IXAudio2SourceVoice
*iface
,
818 float Ratio
, UINT32 OperationSet
)
820 XA2VoiceImpl
*This
= impl_from_IXAudio2SourceVoice(iface
);
822 TRACE("%p, %f, 0x%x\n", This
, Ratio
, OperationSet
);
824 return FAudioSourceVoice_SetFrequencyRatio(This
->faudio_voice
, Ratio
, OperationSet
);
827 static void WINAPI
XA2SRC_GetFrequencyRatio(IXAudio2SourceVoice
*iface
, float *pRatio
)
829 XA2VoiceImpl
*This
= impl_from_IXAudio2SourceVoice(iface
);
831 TRACE("%p, %p\n", This
, pRatio
);
833 return FAudioSourceVoice_GetFrequencyRatio(This
->faudio_voice
, pRatio
);
837 static HRESULT WINAPI
XA2SRC_SetSourceSampleRate(
838 IXAudio2SourceVoice
*iface
,
839 UINT32 NewSourceSampleRate
)
841 XA2VoiceImpl
*This
= impl_from_IXAudio2SourceVoice(iface
);
843 TRACE("%p, %u\n", This
, NewSourceSampleRate
);
845 return FAudioSourceVoice_SetSourceSampleRate(This
->faudio_voice
, NewSourceSampleRate
);
849 static const IXAudio2SourceVoiceVtbl XAudio2SourceVoice_Vtbl
= {
850 XA2SRC_GetVoiceDetails
,
851 XA2SRC_SetOutputVoices
,
852 XA2SRC_SetEffectChain
,
854 XA2SRC_DisableEffect
,
855 XA2SRC_GetEffectState
,
856 XA2SRC_SetEffectParameters
,
857 XA2SRC_GetEffectParameters
,
858 XA2SRC_SetFilterParameters
,
859 XA2SRC_GetFilterParameters
,
861 XA2SRC_SetOutputFilterParameters
,
862 XA2SRC_GetOutputFilterParameters
,
866 XA2SRC_SetChannelVolumes
,
867 XA2SRC_GetChannelVolumes
,
868 XA2SRC_SetOutputMatrix
,
869 XA2SRC_GetOutputMatrix
,
873 XA2SRC_SubmitSourceBuffer
,
874 XA2SRC_FlushSourceBuffers
,
875 XA2SRC_Discontinuity
,
878 XA2SRC_SetFrequencyRatio
,
879 XA2SRC_GetFrequencyRatio
,
881 XA2SRC_SetSourceSampleRate
887 static inline XA2VoiceImpl
*impl_from_IXAudio2SubmixVoice(IXAudio2SubmixVoice
*iface
)
889 return CONTAINING_RECORD(iface
, XA2VoiceImpl
, IXAudio2SubmixVoice_iface
);
892 static void WINAPI
XA2SUB_GetVoiceDetails(IXAudio2SubmixVoice
*iface
, XAUDIO2_VOICE_DETAILS
*details
)
894 XA2VoiceImpl
*voice
= impl_from_IXAudio2SubmixVoice(iface
);
896 get_voice_details(voice
, details
);
899 static HRESULT WINAPI
XA2SUB_SetOutputVoices(IXAudio2SubmixVoice
*iface
,
900 const XAUDIO2_VOICE_SENDS
*pSendList
)
902 XA2VoiceImpl
*This
= impl_from_IXAudio2SubmixVoice(iface
);
903 FAudioVoiceSends
*faudio_sends
;
906 TRACE("%p, %p\n", This
, pSendList
);
908 faudio_sends
= wrap_voice_sends(pSendList
);
910 hr
= FAudioVoice_SetOutputVoices(This
->faudio_voice
, faudio_sends
);
912 free_voice_sends(faudio_sends
);
917 static HRESULT WINAPI
XA2SUB_SetEffectChain(IXAudio2SubmixVoice
*iface
,
918 const XAUDIO2_EFFECT_CHAIN
*pEffectChain
)
920 XA2VoiceImpl
*This
= impl_from_IXAudio2SubmixVoice(iface
);
923 TRACE("%p, %p\n", This
, pEffectChain
);
925 free_effect_chain(This
->effect_chain
);
926 This
->effect_chain
= wrap_effect_chain(pEffectChain
);
928 hr
= FAudioVoice_SetEffectChain(This
->faudio_voice
, This
->effect_chain
);
933 static HRESULT WINAPI
XA2SUB_EnableEffect(IXAudio2SubmixVoice
*iface
, UINT32 EffectIndex
,
936 XA2VoiceImpl
*This
= impl_from_IXAudio2SubmixVoice(iface
);
937 TRACE("%p, %u, 0x%x\n", This
, EffectIndex
, OperationSet
);
938 return FAudioVoice_EnableEffect(This
->faudio_voice
, EffectIndex
, OperationSet
);
941 static HRESULT WINAPI
XA2SUB_DisableEffect(IXAudio2SubmixVoice
*iface
, UINT32 EffectIndex
,
944 XA2VoiceImpl
*This
= impl_from_IXAudio2SubmixVoice(iface
);
945 TRACE("%p, %u, 0x%x\n", This
, EffectIndex
, OperationSet
);
946 return FAudioVoice_DisableEffect(This
->faudio_voice
, EffectIndex
, OperationSet
);
949 static void WINAPI
XA2SUB_GetEffectState(IXAudio2SubmixVoice
*iface
, UINT32 EffectIndex
,
952 XA2VoiceImpl
*This
= impl_from_IXAudio2SubmixVoice(iface
);
953 TRACE("%p, %u, %p\n", This
, EffectIndex
, pEnabled
);
954 FAudioVoice_GetEffectState(This
->faudio_voice
, EffectIndex
, (int32_t*)pEnabled
);
957 static HRESULT WINAPI
XA2SUB_SetEffectParameters(IXAudio2SubmixVoice
*iface
,
958 UINT32 EffectIndex
, const void *pParameters
, UINT32 ParametersByteSize
,
961 XA2VoiceImpl
*This
= impl_from_IXAudio2SubmixVoice(iface
);
962 TRACE("%p, %u, %p, 0x%x, 0x%x\n", This
, EffectIndex
, pParameters
,
963 ParametersByteSize
, OperationSet
);
964 return FAudioVoice_SetEffectParameters(This
->faudio_voice
, EffectIndex
,
965 pParameters
, ParametersByteSize
, OperationSet
);
968 static HRESULT WINAPI
XA2SUB_GetEffectParameters(IXAudio2SubmixVoice
*iface
,
969 UINT32 EffectIndex
, void *pParameters
, UINT32 ParametersByteSize
)
971 XA2VoiceImpl
*This
= impl_from_IXAudio2SubmixVoice(iface
);
972 TRACE("%p, %u, %p, 0x%x\n", This
, EffectIndex
, pParameters
,
974 return FAudioVoice_GetEffectParameters(This
->faudio_voice
, EffectIndex
,
975 pParameters
, ParametersByteSize
);
978 static HRESULT WINAPI
XA2SUB_SetFilterParameters(IXAudio2SubmixVoice
*iface
,
979 const XAUDIO2_FILTER_PARAMETERS
*pParameters
, UINT32 OperationSet
)
981 XA2VoiceImpl
*This
= impl_from_IXAudio2SubmixVoice(iface
);
982 TRACE("%p, %p, 0x%x\n", This
, pParameters
, OperationSet
);
983 return FAudioVoice_SetFilterParameters(This
->faudio_voice
, (const FAudioFilterParameters
*)pParameters
,
987 static void WINAPI
XA2SUB_GetFilterParameters(IXAudio2SubmixVoice
*iface
,
988 XAUDIO2_FILTER_PARAMETERS
*pParameters
)
990 XA2VoiceImpl
*This
= impl_from_IXAudio2SubmixVoice(iface
);
991 TRACE("%p, %p\n", This
, pParameters
);
992 FAudioVoice_GetFilterParameters(This
->faudio_voice
, (FAudioFilterParameters
*)pParameters
);
996 static HRESULT WINAPI
XA2SUB_SetOutputFilterParameters(IXAudio2SubmixVoice
*iface
,
997 IXAudio2Voice
*pDestinationVoice
,
998 const XAUDIO2_FILTER_PARAMETERS
*pParameters
, UINT32 OperationSet
)
1000 XA2VoiceImpl
*This
= impl_from_IXAudio2SubmixVoice(iface
);
1001 XA2VoiceImpl
*dst
= pDestinationVoice
? impl_from_IXAudio2Voice(pDestinationVoice
) : NULL
;
1003 TRACE("%p, %p, %p, 0x%x\n", This
, pDestinationVoice
, pParameters
, OperationSet
);
1005 return FAudioVoice_SetOutputFilterParameters(This
->faudio_voice
,
1006 dst
? dst
->faudio_voice
: NULL
, (const FAudioFilterParameters
*)pParameters
, OperationSet
);
1009 static void WINAPI
XA2SUB_GetOutputFilterParameters(IXAudio2SubmixVoice
*iface
,
1010 IXAudio2Voice
*pDestinationVoice
,
1011 XAUDIO2_FILTER_PARAMETERS
*pParameters
)
1013 XA2VoiceImpl
*This
= impl_from_IXAudio2SubmixVoice(iface
);
1014 XA2VoiceImpl
*dst
= pDestinationVoice
? impl_from_IXAudio2Voice(pDestinationVoice
) : NULL
;
1016 TRACE("%p, %p, %p\n", This
, pDestinationVoice
, pParameters
);
1018 FAudioVoice_GetOutputFilterParameters(This
->faudio_voice
,
1019 dst
? dst
->faudio_voice
: NULL
, (FAudioFilterParameters
*)pParameters
);
1023 static HRESULT WINAPI
XA2SUB_SetVolume(IXAudio2SubmixVoice
*iface
, float Volume
,
1024 UINT32 OperationSet
)
1026 XA2VoiceImpl
*This
= impl_from_IXAudio2SubmixVoice(iface
);
1027 TRACE("%p, %f, 0x%x\n", This
, Volume
, OperationSet
);
1028 return FAudioVoice_SetVolume(This
->faudio_voice
, Volume
, OperationSet
);
1031 static void WINAPI
XA2SUB_GetVolume(IXAudio2SubmixVoice
*iface
, float *pVolume
)
1033 XA2VoiceImpl
*This
= impl_from_IXAudio2SubmixVoice(iface
);
1034 TRACE("%p, %p\n", This
, pVolume
);
1035 return FAudioVoice_GetVolume(This
->faudio_voice
, pVolume
);
1038 static HRESULT WINAPI
XA2SUB_SetChannelVolumes(IXAudio2SubmixVoice
*iface
, UINT32 Channels
,
1039 const float *pVolumes
, UINT32 OperationSet
)
1041 XA2VoiceImpl
*This
= impl_from_IXAudio2SubmixVoice(iface
);
1042 TRACE("%p, %u, %p, 0x%x\n", This
, Channels
, pVolumes
, OperationSet
);
1043 return FAudioVoice_SetChannelVolumes(This
->faudio_voice
, Channels
,
1044 pVolumes
, OperationSet
);
1047 static void WINAPI
XA2SUB_GetChannelVolumes(IXAudio2SubmixVoice
*iface
, UINT32 Channels
,
1050 XA2VoiceImpl
*This
= impl_from_IXAudio2SubmixVoice(iface
);
1051 TRACE("%p, %u, %p\n", This
, Channels
, pVolumes
);
1052 return FAudioVoice_GetChannelVolumes(This
->faudio_voice
, Channels
,
1056 static HRESULT WINAPI
XA2SUB_SetOutputMatrix(IXAudio2SubmixVoice
*iface
,
1057 IXAudio2Voice
*pDestinationVoice
, UINT32 SourceChannels
,
1058 UINT32 DestinationChannels
, const float *pLevelMatrix
,
1059 UINT32 OperationSet
)
1061 XA2VoiceImpl
*This
= impl_from_IXAudio2SubmixVoice(iface
);
1062 XA2VoiceImpl
*dst
= pDestinationVoice
? impl_from_IXAudio2Voice(pDestinationVoice
) : NULL
;
1064 TRACE("%p, %p, %u, %u, %p, 0x%x\n", This
, pDestinationVoice
,
1065 SourceChannels
, DestinationChannels
, pLevelMatrix
, OperationSet
);
1067 return FAudioVoice_SetOutputMatrix(This
->faudio_voice
, dst
? dst
->faudio_voice
: NULL
,
1068 SourceChannels
, DestinationChannels
, pLevelMatrix
, OperationSet
);
1071 #if XAUDIO2_VER == 0
1076 WINAPI
XA2SUB_GetOutputMatrix(IXAudio2SubmixVoice
*iface
,
1077 IXAudio2Voice
*pDestinationVoice
, UINT32 SourceChannels
,
1078 UINT32 DestinationChannels
, float *pLevelMatrix
)
1080 XA2VoiceImpl
*This
= impl_from_IXAudio2SubmixVoice(iface
);
1081 XA2VoiceImpl
*dst
= pDestinationVoice
? impl_from_IXAudio2Voice(pDestinationVoice
) : NULL
;
1083 TRACE("%p, %p, %u, %u, %p\n", This
, pDestinationVoice
,
1084 SourceChannels
, DestinationChannels
, pLevelMatrix
);
1086 FAudioVoice_GetOutputMatrix(This
->faudio_voice
, dst
? dst
->faudio_voice
: NULL
,
1087 SourceChannels
, DestinationChannels
, pLevelMatrix
);
1088 #if XAUDIO2_VER == 0
1093 static void WINAPI
XA2SUB_DestroyVoice(IXAudio2SubmixVoice
*iface
)
1095 XA2VoiceImpl
*This
= impl_from_IXAudio2SubmixVoice(iface
);
1097 TRACE("%p\n", This
);
1099 EnterCriticalSection(&This
->lock
);
1101 destroy_voice(This
);
1103 LeaveCriticalSection(&This
->lock
);
1106 static const struct IXAudio2SubmixVoiceVtbl XAudio2SubmixVoice_Vtbl
= {
1107 XA2SUB_GetVoiceDetails
,
1108 XA2SUB_SetOutputVoices
,
1109 XA2SUB_SetEffectChain
,
1110 XA2SUB_EnableEffect
,
1111 XA2SUB_DisableEffect
,
1112 XA2SUB_GetEffectState
,
1113 XA2SUB_SetEffectParameters
,
1114 XA2SUB_GetEffectParameters
,
1115 XA2SUB_SetFilterParameters
,
1116 XA2SUB_GetFilterParameters
,
1117 #if XAUDIO2_VER >= 4
1118 XA2SUB_SetOutputFilterParameters
,
1119 XA2SUB_GetOutputFilterParameters
,
1123 XA2SUB_SetChannelVolumes
,
1124 XA2SUB_GetChannelVolumes
,
1125 XA2SUB_SetOutputMatrix
,
1126 XA2SUB_GetOutputMatrix
,
1130 /* Mastering Voices */
1132 static inline XA2VoiceImpl
*impl_from_IXAudio2MasteringVoice(IXAudio2MasteringVoice
*iface
)
1134 return CONTAINING_RECORD(iface
, XA2VoiceImpl
, IXAudio2MasteringVoice_iface
);
1137 static void WINAPI
XA2M_GetVoiceDetails(IXAudio2MasteringVoice
*iface
, XAUDIO2_VOICE_DETAILS
*details
)
1139 XA2VoiceImpl
*voice
= impl_from_IXAudio2MasteringVoice(iface
);
1141 get_voice_details(voice
, details
);
1144 static HRESULT WINAPI
XA2M_SetOutputVoices(IXAudio2MasteringVoice
*iface
,
1145 const XAUDIO2_VOICE_SENDS
*pSendList
)
1147 XA2VoiceImpl
*This
= impl_from_IXAudio2MasteringVoice(iface
);
1148 FAudioVoiceSends
*faudio_sends
;
1151 TRACE("%p, %p\n", This
, pSendList
);
1153 faudio_sends
= wrap_voice_sends(pSendList
);
1155 hr
= FAudioVoice_SetOutputVoices(This
->faudio_voice
, faudio_sends
);
1157 free_voice_sends(faudio_sends
);
1162 static HRESULT WINAPI
XA2M_SetEffectChain(IXAudio2MasteringVoice
*iface
,
1163 const XAUDIO2_EFFECT_CHAIN
*pEffectChain
)
1165 XA2VoiceImpl
*This
= impl_from_IXAudio2MasteringVoice(iface
);
1168 TRACE("%p, %p\n", This
, pEffectChain
);
1170 free_effect_chain(This
->effect_chain
);
1171 This
->effect_chain
= wrap_effect_chain(pEffectChain
);
1173 hr
= FAudioVoice_SetEffectChain(This
->faudio_voice
, This
->effect_chain
);
1178 static HRESULT WINAPI
XA2M_EnableEffect(IXAudio2MasteringVoice
*iface
, UINT32 EffectIndex
,
1179 UINT32 OperationSet
)
1181 XA2VoiceImpl
*This
= impl_from_IXAudio2MasteringVoice(iface
);
1182 TRACE("%p, %u, 0x%x\n", This
, EffectIndex
, OperationSet
);
1183 return FAudioVoice_EnableEffect(This
->faudio_voice
, EffectIndex
, OperationSet
);
1186 static HRESULT WINAPI
XA2M_DisableEffect(IXAudio2MasteringVoice
*iface
, UINT32 EffectIndex
,
1187 UINT32 OperationSet
)
1189 XA2VoiceImpl
*This
= impl_from_IXAudio2MasteringVoice(iface
);
1190 TRACE("%p, %u, 0x%x\n", This
, EffectIndex
, OperationSet
);
1191 return FAudioVoice_DisableEffect(This
->faudio_voice
, EffectIndex
, OperationSet
);
1194 static void WINAPI
XA2M_GetEffectState(IXAudio2MasteringVoice
*iface
, UINT32 EffectIndex
,
1197 XA2VoiceImpl
*This
= impl_from_IXAudio2MasteringVoice(iface
);
1198 TRACE("%p, %u, %p\n", This
, EffectIndex
, pEnabled
);
1199 FAudioVoice_GetEffectState(This
->faudio_voice
, EffectIndex
, (int32_t*)pEnabled
);
1202 static HRESULT WINAPI
XA2M_SetEffectParameters(IXAudio2MasteringVoice
*iface
,
1203 UINT32 EffectIndex
, const void *pParameters
, UINT32 ParametersByteSize
,
1204 UINT32 OperationSet
)
1206 XA2VoiceImpl
*This
= impl_from_IXAudio2MasteringVoice(iface
);
1207 TRACE("%p, %u, %p, 0x%x, 0x%x\n", This
, EffectIndex
, pParameters
,
1208 ParametersByteSize
, OperationSet
);
1209 return FAudioVoice_SetEffectParameters(This
->faudio_voice
, EffectIndex
,
1210 pParameters
, ParametersByteSize
, OperationSet
);
1213 static HRESULT WINAPI
XA2M_GetEffectParameters(IXAudio2MasteringVoice
*iface
,
1214 UINT32 EffectIndex
, void *pParameters
, UINT32 ParametersByteSize
)
1216 XA2VoiceImpl
*This
= impl_from_IXAudio2MasteringVoice(iface
);
1217 TRACE("%p, %u, %p, 0x%x\n", This
, EffectIndex
, pParameters
,
1218 ParametersByteSize
);
1219 return FAudioVoice_GetEffectParameters(This
->faudio_voice
, EffectIndex
,
1220 pParameters
, ParametersByteSize
);
1223 static HRESULT WINAPI
XA2M_SetFilterParameters(IXAudio2MasteringVoice
*iface
,
1224 const XAUDIO2_FILTER_PARAMETERS
*pParameters
, UINT32 OperationSet
)
1226 XA2VoiceImpl
*This
= impl_from_IXAudio2MasteringVoice(iface
);
1227 TRACE("%p, %p, 0x%x\n", This
, pParameters
, OperationSet
);
1228 return FAudioVoice_SetFilterParameters(This
->faudio_voice
, (const FAudioFilterParameters
*)pParameters
,
1232 static void WINAPI
XA2M_GetFilterParameters(IXAudio2MasteringVoice
*iface
,
1233 XAUDIO2_FILTER_PARAMETERS
*pParameters
)
1235 XA2VoiceImpl
*This
= impl_from_IXAudio2MasteringVoice(iface
);
1236 TRACE("%p, %p\n", This
, pParameters
);
1237 FAudioVoice_GetFilterParameters(This
->faudio_voice
, (FAudioFilterParameters
*)pParameters
);
1240 #if XAUDIO2_VER >= 4
1241 static HRESULT WINAPI
XA2M_SetOutputFilterParameters(IXAudio2MasteringVoice
*iface
,
1242 IXAudio2Voice
*pDestinationVoice
,
1243 const XAUDIO2_FILTER_PARAMETERS
*pParameters
, UINT32 OperationSet
)
1245 XA2VoiceImpl
*This
= impl_from_IXAudio2MasteringVoice(iface
);
1246 XA2VoiceImpl
*dst
= pDestinationVoice
? impl_from_IXAudio2Voice(pDestinationVoice
) : NULL
;
1248 TRACE("%p, %p, %p, 0x%x\n", This
, pDestinationVoice
, pParameters
, OperationSet
);
1250 return FAudioVoice_SetOutputFilterParameters(This
->faudio_voice
,
1251 dst
? dst
->faudio_voice
: NULL
, (const FAudioFilterParameters
*)pParameters
, OperationSet
);
1254 static void WINAPI
XA2M_GetOutputFilterParameters(IXAudio2MasteringVoice
*iface
,
1255 IXAudio2Voice
*pDestinationVoice
,
1256 XAUDIO2_FILTER_PARAMETERS
*pParameters
)
1258 XA2VoiceImpl
*This
= impl_from_IXAudio2MasteringVoice(iface
);
1259 XA2VoiceImpl
*dst
= pDestinationVoice
? impl_from_IXAudio2Voice(pDestinationVoice
) : NULL
;
1261 TRACE("%p, %p, %p\n", This
, pDestinationVoice
, pParameters
);
1263 FAudioVoice_GetOutputFilterParameters(This
->faudio_voice
,
1264 dst
? dst
->faudio_voice
: NULL
, (FAudioFilterParameters
*)pParameters
);
1268 static HRESULT WINAPI
XA2M_SetVolume(IXAudio2MasteringVoice
*iface
, float Volume
,
1269 UINT32 OperationSet
)
1271 XA2VoiceImpl
*This
= impl_from_IXAudio2MasteringVoice(iface
);
1272 TRACE("%p, %f, 0x%x\n", This
, Volume
, OperationSet
);
1273 return FAudioVoice_SetVolume(This
->faudio_voice
, Volume
, OperationSet
);
1276 static void WINAPI
XA2M_GetVolume(IXAudio2MasteringVoice
*iface
, float *pVolume
)
1278 XA2VoiceImpl
*This
= impl_from_IXAudio2MasteringVoice(iface
);
1279 TRACE("%p, %p\n", This
, pVolume
);
1280 return FAudioVoice_GetVolume(This
->faudio_voice
, pVolume
);
1283 static HRESULT WINAPI
XA2M_SetChannelVolumes(IXAudio2MasteringVoice
*iface
, UINT32 Channels
,
1284 const float *pVolumes
, UINT32 OperationSet
)
1286 XA2VoiceImpl
*This
= impl_from_IXAudio2MasteringVoice(iface
);
1287 TRACE("%p, %u, %p, 0x%x\n", This
, Channels
, pVolumes
, OperationSet
);
1288 return FAudioVoice_SetChannelVolumes(This
->faudio_voice
, Channels
,
1289 pVolumes
, OperationSet
);
1292 static void WINAPI
XA2M_GetChannelVolumes(IXAudio2MasteringVoice
*iface
, UINT32 Channels
,
1295 XA2VoiceImpl
*This
= impl_from_IXAudio2MasteringVoice(iface
);
1296 TRACE("%p, %u, %p\n", This
, Channels
, pVolumes
);
1297 return FAudioVoice_GetChannelVolumes(This
->faudio_voice
, Channels
,
1301 static HRESULT WINAPI
XA2M_SetOutputMatrix(IXAudio2MasteringVoice
*iface
,
1302 IXAudio2Voice
*pDestinationVoice
, UINT32 SourceChannels
,
1303 UINT32 DestinationChannels
, const float *pLevelMatrix
,
1304 UINT32 OperationSet
)
1306 XA2VoiceImpl
*This
= impl_from_IXAudio2MasteringVoice(iface
);
1307 XA2VoiceImpl
*dst
= pDestinationVoice
? impl_from_IXAudio2Voice(pDestinationVoice
) : NULL
;
1309 TRACE("%p, %p, %u, %u, %p, 0x%x\n", This
, pDestinationVoice
,
1310 SourceChannels
, DestinationChannels
, pLevelMatrix
, OperationSet
);
1312 return FAudioVoice_SetOutputMatrix(This
->faudio_voice
, dst
? dst
->faudio_voice
: NULL
,
1313 SourceChannels
, DestinationChannels
, pLevelMatrix
, OperationSet
);
1316 #if XAUDIO2_VER == 0
1321 WINAPI
XA2M_GetOutputMatrix(IXAudio2MasteringVoice
*iface
,
1322 IXAudio2Voice
*pDestinationVoice
, UINT32 SourceChannels
,
1323 UINT32 DestinationChannels
, float *pLevelMatrix
)
1325 XA2VoiceImpl
*This
= impl_from_IXAudio2MasteringVoice(iface
);
1326 XA2VoiceImpl
*dst
= pDestinationVoice
? impl_from_IXAudio2Voice(pDestinationVoice
) : NULL
;
1328 TRACE("%p, %p, %u, %u, %p\n", This
, pDestinationVoice
,
1329 SourceChannels
, DestinationChannels
, pLevelMatrix
);
1331 FAudioVoice_GetOutputMatrix(This
->faudio_voice
, dst
? dst
->faudio_voice
: NULL
,
1332 SourceChannels
, DestinationChannels
, pLevelMatrix
);
1333 #if XAUDIO2_VER == 0
1338 static void WINAPI
XA2M_DestroyVoice(IXAudio2MasteringVoice
*iface
)
1340 XA2VoiceImpl
*This
= impl_from_IXAudio2MasteringVoice(iface
);
1342 TRACE("%p\n", This
);
1344 EnterCriticalSection(&This
->lock
);
1346 destroy_voice(This
);
1348 LeaveCriticalSection(&This
->lock
);
1351 #if XAUDIO2_VER >= 8
1352 static void WINAPI
XA2M_GetChannelMask(IXAudio2MasteringVoice
*iface
,
1353 DWORD
*pChannelMask
)
1355 XA2VoiceImpl
*This
= impl_from_IXAudio2MasteringVoice(iface
);
1357 TRACE("%p, %p\n", This
, pChannelMask
);
1359 FAudioMasteringVoice_GetChannelMask(This
->faudio_voice
, (uint32_t *)pChannelMask
);
1363 static const struct IXAudio2MasteringVoiceVtbl XAudio2MasteringVoice_Vtbl
= {
1364 XA2M_GetVoiceDetails
,
1365 XA2M_SetOutputVoices
,
1366 XA2M_SetEffectChain
,
1369 XA2M_GetEffectState
,
1370 XA2M_SetEffectParameters
,
1371 XA2M_GetEffectParameters
,
1372 XA2M_SetFilterParameters
,
1373 XA2M_GetFilterParameters
,
1374 #if XAUDIO2_VER >= 4
1375 XA2M_SetOutputFilterParameters
,
1376 XA2M_GetOutputFilterParameters
,
1380 XA2M_SetChannelVolumes
,
1381 XA2M_GetChannelVolumes
,
1382 XA2M_SetOutputMatrix
,
1383 XA2M_GetOutputMatrix
,
1385 #if XAUDIO2_VER >= 8
1390 /* More Common Voice Functions */
1392 static XA2VoiceImpl
*impl_from_IXAudio2Voice(IXAudio2Voice
*iface
)
1394 if(iface
->lpVtbl
== (void*)&XAudio2SourceVoice_Vtbl
)
1395 return impl_from_IXAudio2SourceVoice((IXAudio2SourceVoice
*)iface
);
1396 if(iface
->lpVtbl
== (void*)&XAudio2MasteringVoice_Vtbl
)
1397 return impl_from_IXAudio2MasteringVoice((IXAudio2MasteringVoice
*)iface
);
1398 if(iface
->lpVtbl
== (void*)&XAudio2SubmixVoice_Vtbl
)
1399 return impl_from_IXAudio2SubmixVoice((IXAudio2SubmixVoice
*)iface
);
1400 ERR("invalid IXAudio2Voice pointer: %p\n", iface
);
1404 /* XAudio2 Engine Implementation */
1406 static inline IXAudio2Impl
*impl_from_IXAudio2(IXAudio2
*iface
)
1408 return CONTAINING_RECORD(iface
, IXAudio2Impl
, IXAudio2_iface
);
1411 static HRESULT WINAPI
IXAudio2Impl_QueryInterface(IXAudio2
*iface
, REFIID riid
,
1414 IXAudio2Impl
*This
= impl_from_IXAudio2(iface
);
1416 TRACE("(%p)->(%s, %p)\n", This
, debugstr_guid(riid
), ppvObject
);
1418 if(IsEqualGUID(riid
, &IID_IUnknown
) ||
1419 IsEqualGUID(riid
, &IID_IXAudio2
))
1420 *ppvObject
= &This
->IXAudio2_iface
;
1425 IUnknown_AddRef((IUnknown
*)*ppvObject
);
1429 FIXME("(%p)->(%s,%p), not found\n", This
,debugstr_guid(riid
), ppvObject
);
1431 return E_NOINTERFACE
;
1434 static ULONG WINAPI
IXAudio2Impl_AddRef(IXAudio2
*iface
)
1436 IXAudio2Impl
*This
= impl_from_IXAudio2(iface
);
1437 ULONG ref
= FAudio_AddRef(This
->faudio
);
1438 TRACE("(%p)->(): Refcount now %lu\n", This
, ref
);
1442 static ULONG WINAPI
IXAudio2Impl_Release(IXAudio2
*iface
)
1444 IXAudio2Impl
*This
= impl_from_IXAudio2(iface
);
1445 ULONG ref
= FAudio_Release(This
->faudio
);
1447 TRACE("(%p)->(): Refcount now %lu\n", This
, ref
);
1450 XA2VoiceImpl
*v
, *v2
;
1452 LIST_FOR_EACH_ENTRY_SAFE(v
, v2
, &This
->voices
, XA2VoiceImpl
, entry
){
1453 v
->lock
.DebugInfo
->Spare
[0] = 0;
1454 DeleteCriticalSection(&v
->lock
);
1460 This
->lock
.DebugInfo
->Spare
[0] = 0;
1461 DeleteCriticalSection(&This
->lock
);
1468 #if XAUDIO2_VER <= 7
1469 static HRESULT WINAPI
IXAudio2Impl_GetDeviceCount(IXAudio2
*iface
, UINT32
*count
)
1471 IXAudio2Impl
*audio
= impl_from_IXAudio2(iface
);
1473 TRACE("%p, %p\n", audio
, count
);
1475 return FAudio_GetDeviceCount(audio
->faudio
, count
);
1478 static HRESULT WINAPI
IXAudio2Impl_GetDeviceDetails(IXAudio2
*iface
, UINT32 index
,
1479 XAUDIO2_DEVICE_DETAILS
*details
)
1481 IXAudio2Impl
*audio
= impl_from_IXAudio2(iface
);
1483 TRACE("%p, %u, %p\n", audio
, index
, details
);
1485 return FAudio_GetDeviceDetails(audio
->faudio
, index
, (FAudioDeviceDetails
*)details
);
1488 static HRESULT WINAPI
IXAudio2Impl_Initialize(IXAudio2
*iface
, UINT32 flags
, XAUDIO2_PROCESSOR processor
)
1490 IXAudio2Impl
*audio
= impl_from_IXAudio2(iface
);
1492 TRACE("%p, %#x, %#x\n", audio
, flags
, processor
);
1494 return xaudio2_initialize(audio
, flags
, processor
);
1498 static HRESULT WINAPI
IXAudio2Impl_RegisterForCallbacks(IXAudio2
*iface
,
1499 IXAudio2EngineCallback
*pCallback
)
1501 IXAudio2Impl
*This
= impl_from_IXAudio2(iface
);
1504 TRACE("(%p)->(%p)\n", This
, pCallback
);
1506 EnterCriticalSection(&This
->lock
);
1508 for(i
= 0; i
< This
->ncbs
; ++i
){
1509 if(!This
->cbs
[i
] || This
->cbs
[i
] == pCallback
){
1510 This
->cbs
[i
] = pCallback
;
1511 LeaveCriticalSection(&This
->lock
);
1517 This
->cbs
= realloc(This
->cbs
, This
->ncbs
* sizeof(*This
->cbs
));
1519 This
->cbs
[i
] = pCallback
;
1521 LeaveCriticalSection(&This
->lock
);
1526 static void WINAPI
IXAudio2Impl_UnregisterForCallbacks(IXAudio2
*iface
,
1527 IXAudio2EngineCallback
*pCallback
)
1529 IXAudio2Impl
*This
= impl_from_IXAudio2(iface
);
1532 TRACE("(%p)->(%p)\n", This
, pCallback
);
1534 EnterCriticalSection(&This
->lock
);
1536 if(This
->ncbs
== 0){
1537 LeaveCriticalSection(&This
->lock
);
1541 for(i
= 0; i
< This
->ncbs
; ++i
){
1542 if(This
->cbs
[i
] == pCallback
)
1546 for(; i
< This
->ncbs
- 1 && This
->cbs
[i
+ 1]; ++i
)
1547 This
->cbs
[i
] = This
->cbs
[i
+ 1];
1550 This
->cbs
[i
] = NULL
;
1552 LeaveCriticalSection(&This
->lock
);
1555 static inline XA2VoiceImpl
*create_voice(IXAudio2Impl
*This
)
1557 XA2VoiceImpl
*voice
;
1559 voice
= calloc(1, sizeof(*voice
));
1563 list_add_head(&This
->voices
, &voice
->entry
);
1565 voice
->IXAudio2SourceVoice_iface
.lpVtbl
= &XAudio2SourceVoice_Vtbl
;
1566 voice
->IXAudio2SubmixVoice_iface
.lpVtbl
= &XAudio2SubmixVoice_Vtbl
;
1567 voice
->FAudioVoiceCallback_vtbl
= FAudioVoiceCallback_Vtbl
;
1569 InitializeCriticalSection(&voice
->lock
);
1570 voice
->lock
.DebugInfo
->Spare
[0] = (DWORD_PTR
)(__FILE__
": XA2VoiceImpl.lock");
1575 static HRESULT WINAPI
IXAudio2Impl_CreateSourceVoice(IXAudio2
*iface
,
1576 IXAudio2SourceVoice
**ppSourceVoice
, const WAVEFORMATEX
*pSourceFormat
,
1577 UINT32 flags
, float maxFrequencyRatio
,
1578 IXAudio2VoiceCallback
*pCallback
, const XAUDIO2_VOICE_SENDS
*pSendList
,
1579 const XAUDIO2_EFFECT_CHAIN
*pEffectChain
)
1581 IXAudio2Impl
*This
= impl_from_IXAudio2(iface
);
1584 FAudioVoiceSends
*faudio_sends
;
1586 TRACE("(%p)->(%p, %p, 0x%x, %f, %p, %p, %p)\n", This
, ppSourceVoice
,
1587 pSourceFormat
, flags
, maxFrequencyRatio
, pCallback
, pSendList
,
1590 EnterCriticalSection(&This
->lock
);
1592 LIST_FOR_EACH_ENTRY(src
, &This
->voices
, XA2VoiceImpl
, entry
){
1593 EnterCriticalSection(&src
->lock
);
1596 LeaveCriticalSection(&src
->lock
);
1599 if(&src
->entry
== &This
->voices
){
1600 src
= create_voice(This
);
1601 EnterCriticalSection(&src
->lock
);
1604 LeaveCriticalSection(&This
->lock
);
1606 src
->effect_chain
= wrap_effect_chain(pEffectChain
);
1607 faudio_sends
= wrap_voice_sends(pSendList
);
1609 hr
= FAudio_CreateSourceVoice(This
->faudio
, &src
->faudio_voice
,
1610 (FAudioWaveFormatEx
*)pSourceFormat
, flags
, maxFrequencyRatio
,
1611 &src
->FAudioVoiceCallback_vtbl
, faudio_sends
,
1613 free_voice_sends(faudio_sends
);
1615 LeaveCriticalSection(&This
->lock
);
1619 src
->cb
= pCallback
;
1621 LeaveCriticalSection(&src
->lock
);
1623 *ppSourceVoice
= &src
->IXAudio2SourceVoice_iface
;
1625 TRACE("Created source voice: %p\n", src
);
1630 static HRESULT WINAPI
IXAudio2Impl_CreateSubmixVoice(IXAudio2
*iface
,
1631 IXAudio2SubmixVoice
**ppSubmixVoice
, UINT32 inputChannels
,
1632 UINT32 inputSampleRate
, UINT32 flags
, UINT32 processingStage
,
1633 const XAUDIO2_VOICE_SENDS
*pSendList
,
1634 const XAUDIO2_EFFECT_CHAIN
*pEffectChain
)
1637 IXAudio2Impl
*This
= impl_from_IXAudio2(iface
);
1639 FAudioVoiceSends
*faudio_sends
;
1641 TRACE("(%p)->(%p, %u, %u, 0x%x, %u, %p, %p)\n", This
, ppSubmixVoice
,
1642 inputChannels
, inputSampleRate
, flags
, processingStage
, pSendList
,
1645 EnterCriticalSection(&This
->lock
);
1647 LIST_FOR_EACH_ENTRY(sub
, &This
->voices
, XA2VoiceImpl
, entry
){
1648 EnterCriticalSection(&sub
->lock
);
1651 LeaveCriticalSection(&sub
->lock
);
1654 if(&sub
->entry
== &This
->voices
){
1655 sub
= create_voice(This
);
1656 EnterCriticalSection(&sub
->lock
);
1659 LeaveCriticalSection(&This
->lock
);
1661 sub
->effect_chain
= wrap_effect_chain(pEffectChain
);
1662 faudio_sends
= wrap_voice_sends(pSendList
);
1664 hr
= FAudio_CreateSubmixVoice(This
->faudio
, &sub
->faudio_voice
, inputChannels
,
1665 inputSampleRate
, flags
, processingStage
, faudio_sends
,
1667 free_voice_sends(faudio_sends
);
1669 LeaveCriticalSection(&sub
->lock
);
1674 LeaveCriticalSection(&sub
->lock
);
1676 *ppSubmixVoice
= &sub
->IXAudio2SubmixVoice_iface
;
1678 TRACE("Created submix voice: %p\n", sub
);
1683 static HRESULT WINAPI
IXAudio2Impl_CreateMasteringVoice(IXAudio2
*iface
,
1684 IXAudio2MasteringVoice
**ppMasteringVoice
, UINT32 inputChannels
,
1685 UINT32 inputSampleRate
, UINT32 flags
,
1686 #if XAUDIO2_VER >= 8
1687 const WCHAR
*deviceId
,
1691 const XAUDIO2_EFFECT_CHAIN
*pEffectChain
1692 #if XAUDIO2_VER >= 8
1693 , AUDIO_STREAM_CATEGORY streamCategory
1697 IXAudio2Impl
*This
= impl_from_IXAudio2(iface
);
1699 TRACE("(%p)->(%p, %u, %u, 0x%x, %p)\n", This
,
1700 ppMasteringVoice
, inputChannels
, inputSampleRate
, flags
, pEffectChain
);
1702 EnterCriticalSection(&This
->lock
);
1704 *ppMasteringVoice
= &This
->mst
.IXAudio2MasteringVoice_iface
;
1706 EnterCriticalSection(&This
->mst
.lock
);
1708 if(This
->mst
.in_use
){
1709 LeaveCriticalSection(&This
->mst
.lock
);
1710 LeaveCriticalSection(&This
->lock
);
1711 return COMPAT_E_INVALID_CALL
;
1714 LeaveCriticalSection(&This
->lock
);
1716 This
->mst
.effect_chain
= wrap_effect_chain(pEffectChain
);
1718 #if XAUDIO2_VER >= 8
1719 TRACE("device id %s, category %#x\n", debugstr_w(deviceId
), streamCategory
);
1721 FAudio_CreateMasteringVoice8(This
->faudio
, &This
->mst
.faudio_voice
, inputChannels
,
1722 inputSampleRate
, flags
, NULL
/* TODO: (uint16_t*)deviceId */,
1723 This
->mst
.effect_chain
, (FAudioStreamCategory
)streamCategory
);
1725 TRACE("device index %u\n", index
);
1727 FAudio_CreateMasteringVoice(This
->faudio
, &This
->mst
.faudio_voice
, inputChannels
,
1728 inputSampleRate
, flags
, index
, This
->mst
.effect_chain
);
1731 This
->mst
.in_use
= TRUE
;
1733 LeaveCriticalSection(&This
->mst
.lock
);
1738 static HRESULT WINAPI
IXAudio2Impl_StartEngine(IXAudio2
*iface
)
1740 IXAudio2Impl
*This
= impl_from_IXAudio2(iface
);
1742 TRACE("(%p)->()\n", This
);
1744 return FAudio_StartEngine(This
->faudio
);
1747 static void WINAPI
IXAudio2Impl_StopEngine(IXAudio2
*iface
)
1749 IXAudio2Impl
*This
= impl_from_IXAudio2(iface
);
1751 TRACE("(%p)->()\n", This
);
1753 FAudio_StopEngine(This
->faudio
);
1756 static HRESULT WINAPI
IXAudio2Impl_CommitChanges(IXAudio2
*iface
,
1757 UINT32 operationSet
)
1759 IXAudio2Impl
*This
= impl_from_IXAudio2(iface
);
1761 TRACE("(%p)->(0x%x)\n", This
, operationSet
);
1763 return FAudio_CommitOperationSet(This
->faudio
, operationSet
);
1766 static void WINAPI
IXAudio2Impl_GetPerformanceData(IXAudio2
*iface
, XAUDIO2_PERFORMANCE_DATA
*data
)
1768 IXAudio2Impl
*audio
= impl_from_IXAudio2(iface
);
1769 FAudioPerformanceData faudio_data
;
1771 TRACE("(%p)->(%p)\n", audio
, data
);
1773 FAudio_GetPerformanceData(audio
->faudio
, &faudio_data
);
1775 data
->AudioCyclesSinceLastQuery
= faudio_data
.AudioCyclesSinceLastQuery
;
1776 data
->TotalCyclesSinceLastQuery
= faudio_data
.TotalCyclesSinceLastQuery
;
1777 data
->MinimumCyclesPerQuantum
= faudio_data
.MinimumCyclesPerQuantum
;
1778 data
->MaximumCyclesPerQuantum
= faudio_data
.MaximumCyclesPerQuantum
;
1779 data
->MemoryUsageInBytes
= faudio_data
.MemoryUsageInBytes
;
1780 data
->CurrentLatencyInSamples
= faudio_data
.CurrentLatencyInSamples
;
1781 #if XAUDIO2_VER == 0
1782 data
->GlitchesSinceLastQuery
= faudio_data
.GlitchesSinceEngineStarted
- audio
->last_query_glitches
;
1783 audio
->last_query_glitches
= faudio_data
.GlitchesSinceEngineStarted
;
1785 data
->GlitchesSinceEngineStarted
= faudio_data
.GlitchesSinceEngineStarted
;
1787 data
->ActiveSourceVoiceCount
= faudio_data
.ActiveSourceVoiceCount
;
1788 data
->TotalSourceVoiceCount
= faudio_data
.TotalSourceVoiceCount
;
1789 data
->ActiveSubmixVoiceCount
= faudio_data
.ActiveSubmixVoiceCount
;
1790 #if XAUDIO2_VER <= 2
1791 data
->TotalSubmixVoiceCount
= faudio_data
.ActiveSubmixVoiceCount
;
1793 data
->ActiveResamplerCount
= faudio_data
.ActiveResamplerCount
;
1794 data
->ActiveMatrixMixCount
= faudio_data
.ActiveMatrixMixCount
;
1796 data
->ActiveXmaSourceVoices
= faudio_data
.ActiveXmaSourceVoices
;
1797 data
->ActiveXmaStreams
= faudio_data
.ActiveXmaStreams
;
1800 static void WINAPI
IXAudio2Impl_SetDebugConfiguration(IXAudio2
*iface
,
1801 const XAUDIO2_DEBUG_CONFIGURATION
*pDebugConfiguration
,
1804 IXAudio2Impl
*This
= impl_from_IXAudio2(iface
);
1806 TRACE("(%p)->(%p, %p)\n", This
, pDebugConfiguration
, pReserved
);
1808 FAudio_SetDebugConfiguration(This
->faudio
, (FAudioDebugConfiguration
*)pDebugConfiguration
, pReserved
);
1811 static const IXAudio2Vtbl XAudio2_Vtbl
=
1813 IXAudio2Impl_QueryInterface
,
1814 IXAudio2Impl_AddRef
,
1815 IXAudio2Impl_Release
,
1816 #if XAUDIO2_VER <= 7
1817 IXAudio2Impl_GetDeviceCount
,
1818 IXAudio2Impl_GetDeviceDetails
,
1819 IXAudio2Impl_Initialize
,
1821 IXAudio2Impl_RegisterForCallbacks
,
1822 IXAudio2Impl_UnregisterForCallbacks
,
1823 IXAudio2Impl_CreateSourceVoice
,
1824 IXAudio2Impl_CreateSubmixVoice
,
1825 IXAudio2Impl_CreateMasteringVoice
,
1826 IXAudio2Impl_StartEngine
,
1827 IXAudio2Impl_StopEngine
,
1828 IXAudio2Impl_CommitChanges
,
1829 IXAudio2Impl_GetPerformanceData
,
1830 IXAudio2Impl_SetDebugConfiguration
1833 /* XAudio2 ClassFactory */
1836 IClassFactory IClassFactory_iface
;
1840 static struct xaudio2_cf
*impl_from_IClassFactory(IClassFactory
*iface
)
1842 return CONTAINING_RECORD(iface
, struct xaudio2_cf
, IClassFactory_iface
);
1845 static HRESULT WINAPI
XAudio2CF_QueryInterface(IClassFactory
*iface
, REFIID riid
, void **ppobj
)
1847 if(IsEqualGUID(riid
, &IID_IUnknown
)
1848 || IsEqualGUID(riid
, &IID_IClassFactory
))
1850 IClassFactory_AddRef(iface
);
1856 WARN("(%p)->(%s, %p): interface not found\n", iface
, debugstr_guid(riid
), ppobj
);
1857 return E_NOINTERFACE
;
1860 static ULONG WINAPI
XAudio2CF_AddRef(IClassFactory
*iface
)
1862 struct xaudio2_cf
*This
= impl_from_IClassFactory(iface
);
1863 ULONG ref
= InterlockedIncrement(&This
->ref
);
1864 TRACE("(%p)->(): Refcount now %lu\n", This
, ref
);
1868 static ULONG WINAPI
XAudio2CF_Release(IClassFactory
*iface
)
1870 struct xaudio2_cf
*This
= impl_from_IClassFactory(iface
);
1871 ULONG ref
= InterlockedDecrement(&This
->ref
);
1872 TRACE("(%p)->(): Refcount now %lu\n", This
, ref
);
1878 static HRESULT WINAPI
XAudio2CF_CreateInstance(IClassFactory
*iface
, IUnknown
*pOuter
,
1879 REFIID riid
, void **ppobj
)
1881 struct xaudio2_cf
*This
= impl_from_IClassFactory(iface
);
1883 IXAudio2Impl
*object
;
1885 TRACE("(%p)->(%p,%s,%p)\n", This
, pOuter
, debugstr_guid(riid
), ppobj
);
1890 return CLASS_E_NOAGGREGATION
;
1892 object
= calloc(1, sizeof(*object
));
1894 return E_OUTOFMEMORY
;
1896 object
->IXAudio2_iface
.lpVtbl
= &XAudio2_Vtbl
;
1897 object
->mst
.IXAudio2MasteringVoice_iface
.lpVtbl
= &XAudio2MasteringVoice_Vtbl
;
1899 object
->FAudioEngineCallback_vtbl
= FAudioEngineCallback_Vtbl
;
1901 list_init(&object
->voices
);
1903 InitializeCriticalSection(&object
->lock
);
1904 object
->lock
.DebugInfo
->Spare
[0] = (DWORD_PTR
)(__FILE__
": IXAudio2Impl.lock");
1906 InitializeCriticalSection(&object
->mst
.lock
);
1907 object
->mst
.lock
.DebugInfo
->Spare
[0] = (DWORD_PTR
)(__FILE__
": XA2MasteringVoice.lock");
1909 FAudioCOMConstructWithCustomAllocatorEXT(
1912 XAudio_Internal_Malloc
,
1913 XAudio_Internal_Free
,
1914 XAudio_Internal_Realloc
1917 FAudio_RegisterForCallbacks(object
->faudio
, &object
->FAudioEngineCallback_vtbl
);
1919 hr
= IXAudio2_QueryInterface(&object
->IXAudio2_iface
, riid
, ppobj
);
1920 IXAudio2_Release(&object
->IXAudio2_iface
);
1925 TRACE("Created XAudio version %u: %p\n", 20 + XAUDIO2_VER
, object
);
1930 static HRESULT WINAPI
XAudio2CF_LockServer(IClassFactory
*iface
, BOOL dolock
)
1932 struct xaudio2_cf
*This
= impl_from_IClassFactory(iface
);
1933 FIXME("(%p)->(%d): stub!\n", This
, dolock
);
1937 static const IClassFactoryVtbl XAudio2CF_Vtbl
=
1939 XAudio2CF_QueryInterface
,
1942 XAudio2CF_CreateInstance
,
1943 XAudio2CF_LockServer
1946 /* Engine Generators */
1948 static inline HRESULT
make_xaudio2_factory(REFIID riid
, void **ppv
)
1951 struct xaudio2_cf
*ret
= malloc(sizeof(struct xaudio2_cf
));
1952 ret
->IClassFactory_iface
.lpVtbl
= &XAudio2CF_Vtbl
;
1954 hr
= IClassFactory_QueryInterface(&ret
->IClassFactory_iface
, riid
, ppv
);
1960 HRESULT
xaudio2_initialize(IXAudio2Impl
*This
, UINT32 flags
, XAUDIO2_PROCESSOR proc
)
1962 if(proc
!= XAUDIO2_ANY_PROCESSOR
)
1963 WARN("Processor affinity not implemented in FAudio\n");
1964 return FAudio_Initialize(This
->faudio
, flags
, FAUDIO_DEFAULT_PROCESSOR
);
1967 #if XAUDIO2_VER <= 7
1968 HRESULT WINAPI
DllGetClassObject(REFCLSID rclsid
, REFIID riid
, void **ppv
)
1970 TRACE("(%s, %s, %p)\n", debugstr_guid(rclsid
), debugstr_guid(riid
), ppv
);
1972 if (IsEqualGUID(rclsid
, &CLSID_XAudio2
))
1973 return make_xaudio2_factory(riid
, ppv
);
1975 if (IsEqualGUID(rclsid
, &CLSID_AudioVolumeMeter
))
1976 return make_xapo_factory(&CLSID_AudioVolumeMeter
, riid
, ppv
);
1978 if (IsEqualGUID(rclsid
, &CLSID_AudioReverb
))
1979 return make_xapo_factory(&CLSID_AudioReverb
, riid
, ppv
);
1981 return CLASS_E_CLASSNOTAVAILABLE
;
1984 HRESULT WINAPI
XAudio2Create(IXAudio2
**ppxa2
, UINT32 flags
, XAUDIO2_PROCESSOR proc
)
1990 TRACE("%p 0x%x 0x%x\n", ppxa2
, flags
, proc
);
1992 hr
= make_xaudio2_factory(&IID_IClassFactory
, (void**)&cf
);
1996 hr
= IClassFactory_CreateInstance(cf
, NULL
, &IID_IXAudio2
, (void**)&xa2
);
1997 IClassFactory_Release(cf
);
2001 hr
= xaudio2_initialize(impl_from_IXAudio2(xa2
), flags
, proc
);
2003 IXAudio2_Release(xa2
);
2011 #endif /* XAUDIO2_VER >= 8 */