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