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"
32 #include "xaudio2fx.h"
38 #include "wine/debug.h"
39 #include "wine/heap.h"
41 WINE_DEFAULT_DEBUG_CHANNEL(xaudio2
);
43 #if XAUDIO2_VER != 0 && defined(__i386__)
44 /* EVE Online uses an OnVoiceProcessingPassStart callback which corrupts %esi;
45 * League of Legends uses a callback which corrupts %ebx. */
46 #define IXAudio2VoiceCallback_OnVoiceProcessingPassStart(a, b) call_on_voice_processing_pass_start(a, b)
47 extern void call_on_voice_processing_pass_start(IXAudio2VoiceCallback
*This
, UINT32 BytesRequired
);
48 __ASM_GLOBAL_FUNC( call_on_voice_processing_pass_start
,
50 __ASM_CFI(".cfi_adjust_cfa_offset 4\n\t")
51 __ASM_CFI(".cfi_rel_offset %ebp,0\n\t")
53 __ASM_CFI(".cfi_def_cfa_register %ebp\n\t")
55 __ASM_CFI(".cfi_rel_offset %esi,-4\n\t")
57 __ASM_CFI(".cfi_rel_offset %edi,-8\n\t")
59 __ASM_CFI(".cfi_rel_offset %ebx,-12\n\t")
61 "pushl 12(%ebp)\n\t" /* BytesRequired */
62 "pushl 8(%ebp)\n\t" /* This */
63 "movl 8(%ebp),%eax\n\t"
64 "movl 0(%eax),%eax\n\t"
65 "call *0(%eax)\n\t" /* This->lpVtbl->OnVoiceProcessingPassStart */
66 "leal -12(%ebp),%esp\n\t"
68 __ASM_CFI(".cfi_same_value %ebx\n\t")
70 __ASM_CFI(".cfi_same_value %edi\n\t")
72 __ASM_CFI(".cfi_same_value %esi\n\t")
74 __ASM_CFI(".cfi_def_cfa %esp,4\n\t")
75 __ASM_CFI(".cfi_same_value %ebp\n\t")
79 static XA2VoiceImpl
*impl_from_IXAudio2Voice(IXAudio2Voice
*iface
);
81 BOOL WINAPI
DllMain(HINSTANCE hinstDLL
, DWORD reason
, void *pReserved
)
83 TRACE("(%p, %ld, %p)\n", hinstDLL
, reason
, pReserved
);
87 case DLL_PROCESS_ATTACH
:
88 DisableThreadLibraryCalls( hinstDLL
);
89 TRACE("Using FAudio version %d\n", FAudioLinkedVersion() );
97 static inline XA2XAPOImpl
*impl_from_FAPO(FAPO
*iface
)
99 return CONTAINING_RECORD(iface
, XA2XAPOImpl
, FAPO_vtbl
);
102 static int32_t FAPOCALL
XAPO_AddRef(void *iface
)
104 XA2XAPOImpl
*This
= impl_from_FAPO(iface
);
106 return InterlockedIncrement(&This
->ref
);
109 static int32_t FAPOCALL
XAPO_Release(void *iface
)
112 XA2XAPOImpl
*This
= impl_from_FAPO(iface
);
114 r
= InterlockedDecrement(&This
->ref
);
116 IXAPO_Release(This
->xapo
);
117 if(This
->xapo_params
)
118 IXAPOParameters_Release(This
->xapo_params
);
124 static uint32_t FAPOCALL
XAPO_GetRegistrationProperties(void *iface
,
125 FAPORegistrationProperties
**ppRegistrationProperties
)
127 XA2XAPOImpl
*This
= impl_from_FAPO(iface
);
128 XAPO_REGISTRATION_PROPERTIES
*xprops
;
133 hr
= IXAPO_GetRegistrationProperties(This
->xapo
, &xprops
);
137 /* TODO: check for version == 20 and use XAPO20_REGISTRATION_PROPERTIES */
138 *ppRegistrationProperties
= (FAPORegistrationProperties
*) xprops
;
142 static uint32_t FAPOCALL
XAPO_IsInputFormatSupported(void *iface
,
143 const FAudioWaveFormatEx
*pOutputFormat
, const FAudioWaveFormatEx
*pRequestedInputFormat
,
144 FAudioWaveFormatEx
**ppSupportedInputFormat
)
146 XA2XAPOImpl
*This
= impl_from_FAPO(iface
);
148 return IXAPO_IsInputFormatSupported(This
->xapo
, (const WAVEFORMATEX
*)pOutputFormat
,
149 (const WAVEFORMATEX
*)pRequestedInputFormat
, (WAVEFORMATEX
**)ppSupportedInputFormat
);
152 static uint32_t FAPOCALL
XAPO_IsOutputFormatSupported(void *iface
,
153 const FAudioWaveFormatEx
*pInputFormat
, const FAudioWaveFormatEx
*pRequestedOutputFormat
,
154 FAudioWaveFormatEx
**ppSupportedOutputFormat
)
156 XA2XAPOImpl
*This
= impl_from_FAPO(iface
);
158 return IXAPO_IsOutputFormatSupported(This
->xapo
, (const WAVEFORMATEX
*)pInputFormat
,
159 (const WAVEFORMATEX
*)pRequestedOutputFormat
, (WAVEFORMATEX
**)ppSupportedOutputFormat
);
162 static uint32_t FAPOCALL
XAPO_Initialize(void *iface
, const void *pData
,
163 uint32_t DataByteSize
)
165 XA2XAPOImpl
*This
= impl_from_FAPO(iface
);
167 return IXAPO_Initialize(This
->xapo
, pData
, DataByteSize
);
170 static void FAPOCALL
XAPO_Reset(void *iface
)
172 XA2XAPOImpl
*This
= impl_from_FAPO(iface
);
174 IXAPO_Reset(This
->xapo
);
177 static uint32_t FAPOCALL
XAPO_LockForProcess(void *iface
,
178 uint32_t InputLockedParameterCount
,
179 const FAPOLockForProcessBufferParameters
*pInputLockedParameters
,
180 uint32_t OutputLockedParameterCount
,
181 const FAPOLockForProcessBufferParameters
*pOutputLockedParameters
)
183 XA2XAPOImpl
*This
= impl_from_FAPO(iface
);
185 return IXAPO_LockForProcess(This
->xapo
,
186 InputLockedParameterCount
,
187 (const XAPO_LOCKFORPROCESS_BUFFER_PARAMETERS
*)pInputLockedParameters
,
188 OutputLockedParameterCount
,
189 (const XAPO_LOCKFORPROCESS_BUFFER_PARAMETERS
*)pOutputLockedParameters
);
192 static void FAPOCALL
XAPO_UnlockForProcess(void *iface
)
194 XA2XAPOImpl
*This
= impl_from_FAPO(iface
);
196 IXAPO_UnlockForProcess(This
->xapo
);
199 static void FAPOCALL
XAPO_Process(void *iface
,
200 uint32_t InputProcessParameterCount
,
201 const FAPOProcessBufferParameters
* pInputProcessParameters
,
202 uint32_t OutputProcessParameterCount
,
203 FAPOProcessBufferParameters
* pOutputProcessParameters
,
206 XA2XAPOImpl
*This
= impl_from_FAPO(iface
);
208 IXAPO_Process(This
->xapo
, InputProcessParameterCount
,
209 (const XAPO_PROCESS_BUFFER_PARAMETERS
*)pInputProcessParameters
,
210 OutputProcessParameterCount
,
211 (XAPO_PROCESS_BUFFER_PARAMETERS
*)pOutputProcessParameters
,
215 static uint32_t FAPOCALL
XAPO_CalcInputFrames(void *iface
,
216 uint32_t OutputFrameCount
)
218 XA2XAPOImpl
*This
= impl_from_FAPO(iface
);
220 return IXAPO_CalcInputFrames(This
->xapo
, OutputFrameCount
);
223 static uint32_t FAPOCALL
XAPO_CalcOutputFrames(void *iface
,
224 uint32_t InputFrameCount
)
226 XA2XAPOImpl
*This
= impl_from_FAPO(iface
);
228 return IXAPO_CalcOutputFrames(This
->xapo
, InputFrameCount
);
231 static void FAPOCALL
XAPO_SetParameters(void *iface
,
232 const void *pParameters
, uint32_t ParametersByteSize
)
234 XA2XAPOImpl
*This
= impl_from_FAPO(iface
);
236 if(This
->xapo_params
)
237 IXAPOParameters_SetParameters(This
->xapo_params
, pParameters
, ParametersByteSize
);
240 static void FAPOCALL
XAPO_GetParameters(void *iface
,
241 void *pParameters
, uint32_t ParametersByteSize
)
243 XA2XAPOImpl
*This
= impl_from_FAPO(iface
);
245 if(This
->xapo_params
)
246 IXAPOParameters_GetParameters(This
->xapo_params
, pParameters
, ParametersByteSize
);
248 memset(pParameters
, 0, ParametersByteSize
);
251 static const FAPO FAPO_Vtbl
= {
254 XAPO_GetRegistrationProperties
,
255 XAPO_IsInputFormatSupported
,
256 XAPO_IsOutputFormatSupported
,
260 XAPO_UnlockForProcess
,
262 XAPO_CalcInputFrames
,
263 XAPO_CalcOutputFrames
,
268 static XA2XAPOImpl
*wrap_xapo(IUnknown
*unk
)
272 IXAPOParameters
*xapo_params
;
276 hr
= IUnknown_QueryInterface(unk
, &IID_IXAPO27
, (void**)&xapo
);
278 hr
= IUnknown_QueryInterface(unk
, &IID_IXAPO
, (void**)&xapo
);
281 WARN("XAPO doesn't support IXAPO? %p\n", unk
);
286 hr
= IUnknown_QueryInterface(unk
, &IID_IXAPO27Parameters
, (void**)&xapo_params
);
288 hr
= IUnknown_QueryInterface(unk
, &IID_IXAPOParameters
, (void**)&xapo_params
);
291 TRACE("XAPO doesn't support IXAPOParameters %p\n", unk
);
295 ret
= heap_alloc(sizeof(*ret
));
298 ret
->xapo_params
= xapo_params
;
299 ret
->FAPO_vtbl
= FAPO_Vtbl
;
302 TRACE("wrapped IXAPO %p with %p\n", xapo
, ret
);
307 FAudioEffectChain
*wrap_effect_chain(const XAUDIO2_EFFECT_CHAIN
*pEffectChain
)
309 FAudioEffectChain
*ret
;
315 ret
= heap_alloc(sizeof(*ret
) + sizeof(FAudioEffectDescriptor
) * pEffectChain
->EffectCount
);
317 ret
->EffectCount
= pEffectChain
->EffectCount
;
318 ret
->pEffectDescriptors
= (void*)(ret
+ 1);
320 for(i
= 0; i
< ret
->EffectCount
; ++i
){
321 ret
->pEffectDescriptors
[i
].pEffect
= &wrap_xapo(pEffectChain
->pEffectDescriptors
[i
].pEffect
)->FAPO_vtbl
;
322 ret
->pEffectDescriptors
[i
].InitialState
= pEffectChain
->pEffectDescriptors
[i
].InitialState
;
323 ret
->pEffectDescriptors
[i
].OutputChannels
= pEffectChain
->pEffectDescriptors
[i
].OutputChannels
;
329 static void free_effect_chain(FAudioEffectChain
*chain
)
334 for(i
= 0; i
< chain
->EffectCount
; ++i
)
335 XAPO_Release(chain
->pEffectDescriptors
[i
].pEffect
);
341 static FAudioVoiceSends
*wrap_voice_sends(const XAUDIO2_VOICE_SENDS
*sends
)
343 FAudioVoiceSends
*ret
;
349 ret
= heap_alloc(sizeof(*ret
) + sends
->SendCount
* sizeof(FAudioSendDescriptor
));
350 ret
->SendCount
= sends
->SendCount
;
351 ret
->pSends
= (FAudioSendDescriptor
*)(ret
+ 1);
352 for(i
= 0; i
< sends
->SendCount
; ++i
){
353 XA2VoiceImpl
*voice
= impl_from_IXAudio2Voice(sends
->pSends
[i
].pOutputVoice
);
354 ret
->pSends
[i
].pOutputVoice
= voice
->faudio_voice
;
355 ret
->pSends
[i
].Flags
= sends
->pSends
[i
].Flags
;
360 static void free_voice_sends(FAudioVoiceSends
*sends
)
367 /* Voice Callbacks */
369 static inline XA2VoiceImpl
*impl_from_FAudioVoiceCallback(FAudioVoiceCallback
*iface
)
371 return CONTAINING_RECORD(iface
, XA2VoiceImpl
, FAudioVoiceCallback_vtbl
);
374 static void FAUDIOCALL
XA2VCB_OnVoiceProcessingPassStart(FAudioVoiceCallback
*iface
,
375 UINT32 BytesRequired
)
377 XA2VoiceImpl
*This
= impl_from_FAudioVoiceCallback(iface
);
381 IXAudio20VoiceCallback_OnVoiceProcessingPassStart((IXAudio20VoiceCallback
*)This
->cb
);
383 IXAudio2VoiceCallback_OnVoiceProcessingPassStart(This
->cb
, BytesRequired
);
387 static void FAUDIOCALL
XA2VCB_OnVoiceProcessingPassEnd(FAudioVoiceCallback
*iface
)
389 XA2VoiceImpl
*This
= impl_from_FAudioVoiceCallback(iface
);
392 IXAudio2VoiceCallback_OnVoiceProcessingPassEnd(This
->cb
);
395 static void FAUDIOCALL
XA2VCB_OnStreamEnd(FAudioVoiceCallback
*iface
)
397 XA2VoiceImpl
*This
= impl_from_FAudioVoiceCallback(iface
);
400 IXAudio2VoiceCallback_OnStreamEnd(This
->cb
);
403 static void FAUDIOCALL
XA2VCB_OnBufferStart(FAudioVoiceCallback
*iface
,
404 void *pBufferContext
)
406 XA2VoiceImpl
*This
= impl_from_FAudioVoiceCallback(iface
);
409 IXAudio2VoiceCallback_OnBufferStart(This
->cb
, pBufferContext
);
412 static void FAUDIOCALL
XA2VCB_OnBufferEnd(FAudioVoiceCallback
*iface
,
413 void *pBufferContext
)
415 XA2VoiceImpl
*This
= impl_from_FAudioVoiceCallback(iface
);
418 IXAudio2VoiceCallback_OnBufferEnd(This
->cb
, pBufferContext
);
421 static void FAUDIOCALL
XA2VCB_OnLoopEnd(FAudioVoiceCallback
*iface
,
422 void *pBufferContext
)
424 XA2VoiceImpl
*This
= impl_from_FAudioVoiceCallback(iface
);
427 IXAudio2VoiceCallback_OnLoopEnd(This
->cb
, pBufferContext
);
430 static void FAUDIOCALL
XA2VCB_OnVoiceError(FAudioVoiceCallback
*iface
,
431 void *pBufferContext
, unsigned int Error
)
433 XA2VoiceImpl
*This
= impl_from_FAudioVoiceCallback(iface
);
436 IXAudio2VoiceCallback_OnVoiceError(This
->cb
, pBufferContext
, (HRESULT
)Error
);
439 static const FAudioVoiceCallback FAudioVoiceCallback_Vtbl
= {
441 XA2VCB_OnBufferStart
,
445 XA2VCB_OnVoiceProcessingPassEnd
,
446 XA2VCB_OnVoiceProcessingPassStart
449 /* Engine Callbacks */
451 static inline IXAudio2Impl
*impl_from_FAudioEngineCallback(FAudioEngineCallback
*iface
)
453 return CONTAINING_RECORD(iface
, IXAudio2Impl
, FAudioEngineCallback_vtbl
);
456 static void FAUDIOCALL
XA2ECB_OnProcessingPassStart(FAudioEngineCallback
*iface
)
458 IXAudio2Impl
*This
= impl_from_FAudioEngineCallback(iface
);
461 for(i
= 0; i
< This
->ncbs
&& This
->cbs
[i
]; ++i
)
462 IXAudio2EngineCallback_OnProcessingPassStart(This
->cbs
[i
]);
465 static void FAUDIOCALL
XA2ECB_OnProcessingPassEnd(FAudioEngineCallback
*iface
)
467 IXAudio2Impl
*This
= impl_from_FAudioEngineCallback(iface
);
470 for(i
= 0; i
< This
->ncbs
&& This
->cbs
[i
]; ++i
)
471 IXAudio2EngineCallback_OnProcessingPassEnd(This
->cbs
[i
]);
474 static void FAUDIOCALL
XA2ECB_OnCriticalError(FAudioEngineCallback
*iface
,
477 IXAudio2Impl
*This
= impl_from_FAudioEngineCallback(iface
);
480 for(i
= 0; i
< This
->ncbs
&& This
->cbs
[i
]; ++i
)
481 IXAudio2EngineCallback_OnCriticalError(This
->cbs
[i
], error
);
484 static const FAudioEngineCallback FAudioEngineCallback_Vtbl
= {
485 XA2ECB_OnCriticalError
,
486 XA2ECB_OnProcessingPassEnd
,
487 XA2ECB_OnProcessingPassStart
490 /* Common Voice Functions */
492 static inline void destroy_voice(XA2VoiceImpl
*This
)
494 FAudioVoice_DestroyVoice(This
->faudio_voice
);
495 free_effect_chain(This
->effect_chain
);
496 This
->effect_chain
= NULL
;
497 This
->in_use
= FALSE
;
502 static inline XA2VoiceImpl
*impl_from_IXAudio2SourceVoice(IXAudio2SourceVoice
*iface
)
504 return CONTAINING_RECORD(iface
, XA2VoiceImpl
, IXAudio2SourceVoice_iface
);
507 static void WINAPI
XA2SRC_GetVoiceDetails(IXAudio2SourceVoice
*iface
,
508 XAUDIO2_VOICE_DETAILS
*pVoiceDetails
)
510 XA2VoiceImpl
*This
= impl_from_IXAudio2SourceVoice(iface
);
511 TRACE("%p, %p\n", This
, pVoiceDetails
);
512 FAudioVoice_GetVoiceDetails(This
->faudio_voice
, (FAudioVoiceDetails
*)pVoiceDetails
);
515 static HRESULT WINAPI
XA2SRC_SetOutputVoices(IXAudio2SourceVoice
*iface
,
516 const XAUDIO2_VOICE_SENDS
*pSendList
)
518 XA2VoiceImpl
*This
= impl_from_IXAudio2SourceVoice(iface
);
519 FAudioVoiceSends
*faudio_sends
;
522 TRACE("%p, %p\n", This
, pSendList
);
524 faudio_sends
= wrap_voice_sends(pSendList
);
526 hr
= FAudioVoice_SetOutputVoices(This
->faudio_voice
, faudio_sends
);
528 free_voice_sends(faudio_sends
);
533 static HRESULT WINAPI
XA2SRC_SetEffectChain(IXAudio2SourceVoice
*iface
,
534 const XAUDIO2_EFFECT_CHAIN
*pEffectChain
)
536 XA2VoiceImpl
*This
= impl_from_IXAudio2SourceVoice(iface
);
539 TRACE("%p, %p\n", This
, pEffectChain
);
541 free_effect_chain(This
->effect_chain
);
542 This
->effect_chain
= wrap_effect_chain(pEffectChain
);
544 hr
= FAudioVoice_SetEffectChain(This
->faudio_voice
, This
->effect_chain
);
549 static HRESULT WINAPI
XA2SRC_EnableEffect(IXAudio2SourceVoice
*iface
, UINT32 EffectIndex
,
552 XA2VoiceImpl
*This
= impl_from_IXAudio2SourceVoice(iface
);
553 TRACE("%p, %u, 0x%x\n", This
, EffectIndex
, OperationSet
);
554 return FAudioVoice_EnableEffect(This
->faudio_voice
, EffectIndex
, OperationSet
);
557 static HRESULT WINAPI
XA2SRC_DisableEffect(IXAudio2SourceVoice
*iface
, UINT32 EffectIndex
,
560 XA2VoiceImpl
*This
= impl_from_IXAudio2SourceVoice(iface
);
561 TRACE("%p, %u, 0x%x\n", This
, EffectIndex
, OperationSet
);
562 return FAudioVoice_DisableEffect(This
->faudio_voice
, EffectIndex
, OperationSet
);
565 static void WINAPI
XA2SRC_GetEffectState(IXAudio2SourceVoice
*iface
, UINT32 EffectIndex
,
568 XA2VoiceImpl
*This
= impl_from_IXAudio2SourceVoice(iface
);
569 TRACE("%p, %u, %p\n", This
, EffectIndex
, pEnabled
);
570 FAudioVoice_GetEffectState(This
->faudio_voice
, EffectIndex
, (int32_t*)pEnabled
);
573 static HRESULT WINAPI
XA2SRC_SetEffectParameters(IXAudio2SourceVoice
*iface
,
574 UINT32 EffectIndex
, const void *pParameters
, UINT32 ParametersByteSize
,
577 XA2VoiceImpl
*This
= impl_from_IXAudio2SourceVoice(iface
);
578 TRACE("%p, %u, %p, 0x%x, 0x%x\n", This
, EffectIndex
, pParameters
,
579 ParametersByteSize
, OperationSet
);
580 return FAudioVoice_SetEffectParameters(This
->faudio_voice
, EffectIndex
,
581 pParameters
, ParametersByteSize
, OperationSet
);
584 static HRESULT WINAPI
XA2SRC_GetEffectParameters(IXAudio2SourceVoice
*iface
,
585 UINT32 EffectIndex
, void *pParameters
, UINT32 ParametersByteSize
)
587 XA2VoiceImpl
*This
= impl_from_IXAudio2SourceVoice(iface
);
588 TRACE("%p, %u, %p, 0x%x\n", This
, EffectIndex
, pParameters
,
590 return FAudioVoice_GetEffectParameters(This
->faudio_voice
, EffectIndex
,
591 pParameters
, ParametersByteSize
);
594 static HRESULT WINAPI
XA2SRC_SetFilterParameters(IXAudio2SourceVoice
*iface
,
595 const XAUDIO2_FILTER_PARAMETERS
*pParameters
, UINT32 OperationSet
)
597 XA2VoiceImpl
*This
= impl_from_IXAudio2SourceVoice(iface
);
598 TRACE("%p, %p, 0x%x\n", This
, pParameters
, OperationSet
);
599 return FAudioVoice_SetFilterParameters(This
->faudio_voice
,
600 (const FAudioFilterParameters
*)pParameters
, OperationSet
);
603 static void WINAPI
XA2SRC_GetFilterParameters(IXAudio2SourceVoice
*iface
,
604 XAUDIO2_FILTER_PARAMETERS
*pParameters
)
606 XA2VoiceImpl
*This
= impl_from_IXAudio2SourceVoice(iface
);
607 TRACE("%p, %p\n", This
, pParameters
);
608 FAudioVoice_GetFilterParameters(This
->faudio_voice
, (FAudioFilterParameters
*)pParameters
);
611 static HRESULT WINAPI
XA2SRC_SetOutputFilterParameters(IXAudio2SourceVoice
*iface
,
612 IXAudio2Voice
*pDestinationVoice
,
613 const XAUDIO2_FILTER_PARAMETERS
*pParameters
, UINT32 OperationSet
)
615 XA2VoiceImpl
*This
= impl_from_IXAudio2SourceVoice(iface
);
616 XA2VoiceImpl
*dst
= pDestinationVoice
? impl_from_IXAudio2Voice(pDestinationVoice
) : NULL
;
618 TRACE("%p, %p, %p, 0x%x\n", This
, pDestinationVoice
, pParameters
, OperationSet
);
620 return FAudioVoice_SetOutputFilterParameters(This
->faudio_voice
,
621 dst
? dst
->faudio_voice
: NULL
, (const FAudioFilterParameters
*)pParameters
, OperationSet
);
624 static void WINAPI
XA2SRC_GetOutputFilterParameters(IXAudio2SourceVoice
*iface
,
625 IXAudio2Voice
*pDestinationVoice
,
626 XAUDIO2_FILTER_PARAMETERS
*pParameters
)
628 XA2VoiceImpl
*This
= impl_from_IXAudio2SourceVoice(iface
);
629 XA2VoiceImpl
*dst
= pDestinationVoice
? impl_from_IXAudio2Voice(pDestinationVoice
) : NULL
;
631 TRACE("%p, %p, %p\n", This
, pDestinationVoice
, pParameters
);
633 FAudioVoice_GetOutputFilterParameters(This
->faudio_voice
,
634 dst
? dst
->faudio_voice
: NULL
, (FAudioFilterParameters
*)pParameters
);
637 static HRESULT WINAPI
XA2SRC_SetVolume(IXAudio2SourceVoice
*iface
, float Volume
,
640 XA2VoiceImpl
*This
= impl_from_IXAudio2SourceVoice(iface
);
641 TRACE("%p, %f, 0x%x\n", This
, Volume
, OperationSet
);
642 return FAudioVoice_SetVolume(This
->faudio_voice
, Volume
, OperationSet
);
645 static void WINAPI
XA2SRC_GetVolume(IXAudio2SourceVoice
*iface
, float *pVolume
)
647 XA2VoiceImpl
*This
= impl_from_IXAudio2SourceVoice(iface
);
648 TRACE("%p, %p\n", This
, pVolume
);
649 return FAudioVoice_GetVolume(This
->faudio_voice
, pVolume
);
652 static HRESULT WINAPI
XA2SRC_SetChannelVolumes(IXAudio2SourceVoice
*iface
, UINT32 Channels
,
653 const float *pVolumes
, UINT32 OperationSet
)
655 XA2VoiceImpl
*This
= impl_from_IXAudio2SourceVoice(iface
);
656 TRACE("%p, %u, %p, 0x%x\n", This
, Channels
, pVolumes
, OperationSet
);
657 return FAudioVoice_SetChannelVolumes(This
->faudio_voice
, Channels
,
658 pVolumes
, OperationSet
);
661 static void WINAPI
XA2SRC_GetChannelVolumes(IXAudio2SourceVoice
*iface
, UINT32 Channels
,
664 XA2VoiceImpl
*This
= impl_from_IXAudio2SourceVoice(iface
);
665 TRACE("%p, %u, %p\n", This
, Channels
, pVolumes
);
666 return FAudioVoice_GetChannelVolumes(This
->faudio_voice
, Channels
,
670 static HRESULT WINAPI
XA2SRC_SetOutputMatrix(IXAudio2SourceVoice
*iface
,
671 IXAudio2Voice
*pDestinationVoice
, UINT32 SourceChannels
,
672 UINT32 DestinationChannels
, const float *pLevelMatrix
,
675 XA2VoiceImpl
*This
= impl_from_IXAudio2SourceVoice(iface
);
676 XA2VoiceImpl
*dst
= pDestinationVoice
? impl_from_IXAudio2Voice(pDestinationVoice
) : NULL
;
678 TRACE("%p, %p, %u, %u, %p, 0x%x\n", This
, pDestinationVoice
,
679 SourceChannels
, DestinationChannels
, pLevelMatrix
, OperationSet
);
681 return FAudioVoice_SetOutputMatrix(This
->faudio_voice
, dst
? dst
->faudio_voice
: NULL
,
682 SourceChannels
, DestinationChannels
, pLevelMatrix
, OperationSet
);
685 static void WINAPI
XA2SRC_GetOutputMatrix(IXAudio2SourceVoice
*iface
,
686 IXAudio2Voice
*pDestinationVoice
, UINT32 SourceChannels
,
687 UINT32 DestinationChannels
, float *pLevelMatrix
)
689 XA2VoiceImpl
*This
= impl_from_IXAudio2SourceVoice(iface
);
690 XA2VoiceImpl
*dst
= pDestinationVoice
? impl_from_IXAudio2Voice(pDestinationVoice
) : NULL
;
692 TRACE("%p, %p, %u, %u, %p\n", This
, pDestinationVoice
,
693 SourceChannels
, DestinationChannels
, pLevelMatrix
);
695 FAudioVoice_GetOutputMatrix(This
->faudio_voice
, dst
? dst
->faudio_voice
: NULL
,
696 SourceChannels
, DestinationChannels
, pLevelMatrix
);
699 static void WINAPI
XA2SRC_DestroyVoice(IXAudio2SourceVoice
*iface
)
701 XA2VoiceImpl
*This
= impl_from_IXAudio2SourceVoice(iface
);
705 EnterCriticalSection(&This
->lock
);
709 LeaveCriticalSection(&This
->lock
);
712 static HRESULT WINAPI
XA2SRC_Start(IXAudio2SourceVoice
*iface
, UINT32 Flags
,
715 XA2VoiceImpl
*This
= impl_from_IXAudio2SourceVoice(iface
);
717 TRACE("%p, 0x%x, 0x%x\n", This
, Flags
, OperationSet
);
719 return FAudioSourceVoice_Start(This
->faudio_voice
, Flags
, OperationSet
);
722 static HRESULT WINAPI
XA2SRC_Stop(IXAudio2SourceVoice
*iface
, UINT32 Flags
,
725 XA2VoiceImpl
*This
= impl_from_IXAudio2SourceVoice(iface
);
727 TRACE("%p, 0x%x, 0x%x\n", This
, Flags
, OperationSet
);
729 return FAudioSourceVoice_Stop(This
->faudio_voice
, Flags
, OperationSet
);
732 static HRESULT WINAPI
XA2SRC_SubmitSourceBuffer(IXAudio2SourceVoice
*iface
,
733 const XAUDIO2_BUFFER
*pBuffer
, const XAUDIO2_BUFFER_WMA
*pBufferWMA
)
735 XA2VoiceImpl
*This
= impl_from_IXAudio2SourceVoice(iface
);
737 TRACE("%p, %p, %p\n", This
, pBuffer
, pBufferWMA
);
739 return FAudioSourceVoice_SubmitSourceBuffer(This
->faudio_voice
, (FAudioBuffer
*)pBuffer
, (FAudioBufferWMA
*)pBufferWMA
);
742 static HRESULT WINAPI
XA2SRC_FlushSourceBuffers(IXAudio2SourceVoice
*iface
)
744 XA2VoiceImpl
*This
= impl_from_IXAudio2SourceVoice(iface
);
748 return FAudioSourceVoice_FlushSourceBuffers(This
->faudio_voice
);
751 static HRESULT WINAPI
XA2SRC_Discontinuity(IXAudio2SourceVoice
*iface
)
753 XA2VoiceImpl
*This
= impl_from_IXAudio2SourceVoice(iface
);
757 return FAudioSourceVoice_Discontinuity(This
->faudio_voice
);
760 static HRESULT WINAPI
XA2SRC_ExitLoop(IXAudio2SourceVoice
*iface
, UINT32 OperationSet
)
762 XA2VoiceImpl
*This
= impl_from_IXAudio2SourceVoice(iface
);
764 TRACE("%p, 0x%x\n", This
, OperationSet
);
766 return FAudioSourceVoice_ExitLoop(This
->faudio_voice
, OperationSet
);
769 static void WINAPI
XA2SRC_GetState(IXAudio2SourceVoice
*iface
,
770 XAUDIO2_VOICE_STATE
*pVoiceState
, UINT32 Flags
)
772 XA2VoiceImpl
*This
= impl_from_IXAudio2SourceVoice(iface
);
774 TRACE("%p, %p, 0x%x\n", This
, pVoiceState
, Flags
);
776 return FAudioSourceVoice_GetState(This
->faudio_voice
, (FAudioVoiceState
*)pVoiceState
, Flags
);
779 static HRESULT WINAPI
XA2SRC_SetFrequencyRatio(IXAudio2SourceVoice
*iface
,
780 float Ratio
, UINT32 OperationSet
)
782 XA2VoiceImpl
*This
= impl_from_IXAudio2SourceVoice(iface
);
784 TRACE("%p, %f, 0x%x\n", This
, Ratio
, OperationSet
);
786 return FAudioSourceVoice_SetFrequencyRatio(This
->faudio_voice
, Ratio
, OperationSet
);
789 static void WINAPI
XA2SRC_GetFrequencyRatio(IXAudio2SourceVoice
*iface
, float *pRatio
)
791 XA2VoiceImpl
*This
= impl_from_IXAudio2SourceVoice(iface
);
793 TRACE("%p, %p\n", This
, pRatio
);
795 return FAudioSourceVoice_GetFrequencyRatio(This
->faudio_voice
, pRatio
);
798 static HRESULT WINAPI
XA2SRC_SetSourceSampleRate(
799 IXAudio2SourceVoice
*iface
,
800 UINT32 NewSourceSampleRate
)
802 XA2VoiceImpl
*This
= impl_from_IXAudio2SourceVoice(iface
);
804 TRACE("%p, %u\n", This
, NewSourceSampleRate
);
806 return FAudioSourceVoice_SetSourceSampleRate(This
->faudio_voice
, NewSourceSampleRate
);
809 static const IXAudio2SourceVoiceVtbl XAudio2SourceVoice_Vtbl
= {
810 XA2SRC_GetVoiceDetails
,
811 XA2SRC_SetOutputVoices
,
812 XA2SRC_SetEffectChain
,
814 XA2SRC_DisableEffect
,
815 XA2SRC_GetEffectState
,
816 XA2SRC_SetEffectParameters
,
817 XA2SRC_GetEffectParameters
,
818 XA2SRC_SetFilterParameters
,
819 XA2SRC_GetFilterParameters
,
820 XA2SRC_SetOutputFilterParameters
,
821 XA2SRC_GetOutputFilterParameters
,
824 XA2SRC_SetChannelVolumes
,
825 XA2SRC_GetChannelVolumes
,
826 XA2SRC_SetOutputMatrix
,
827 XA2SRC_GetOutputMatrix
,
831 XA2SRC_SubmitSourceBuffer
,
832 XA2SRC_FlushSourceBuffers
,
833 XA2SRC_Discontinuity
,
836 XA2SRC_SetFrequencyRatio
,
837 XA2SRC_GetFrequencyRatio
,
838 XA2SRC_SetSourceSampleRate
843 static inline XA2VoiceImpl
*impl_from_IXAudio2SubmixVoice(IXAudio2SubmixVoice
*iface
)
845 return CONTAINING_RECORD(iface
, XA2VoiceImpl
, IXAudio2SubmixVoice_iface
);
848 static void WINAPI
XA2SUB_GetVoiceDetails(IXAudio2SubmixVoice
*iface
,
849 XAUDIO2_VOICE_DETAILS
*pVoiceDetails
)
851 XA2VoiceImpl
*This
= impl_from_IXAudio2SubmixVoice(iface
);
852 TRACE("%p, %p\n", This
, pVoiceDetails
);
853 FAudioVoice_GetVoiceDetails(This
->faudio_voice
, (FAudioVoiceDetails
*)pVoiceDetails
);
856 static HRESULT WINAPI
XA2SUB_SetOutputVoices(IXAudio2SubmixVoice
*iface
,
857 const XAUDIO2_VOICE_SENDS
*pSendList
)
859 XA2VoiceImpl
*This
= impl_from_IXAudio2SubmixVoice(iface
);
860 FAudioVoiceSends
*faudio_sends
;
863 TRACE("%p, %p\n", This
, pSendList
);
865 faudio_sends
= wrap_voice_sends(pSendList
);
867 hr
= FAudioVoice_SetOutputVoices(This
->faudio_voice
, faudio_sends
);
869 free_voice_sends(faudio_sends
);
874 static HRESULT WINAPI
XA2SUB_SetEffectChain(IXAudio2SubmixVoice
*iface
,
875 const XAUDIO2_EFFECT_CHAIN
*pEffectChain
)
877 XA2VoiceImpl
*This
= impl_from_IXAudio2SubmixVoice(iface
);
880 TRACE("%p, %p\n", This
, pEffectChain
);
882 free_effect_chain(This
->effect_chain
);
883 This
->effect_chain
= wrap_effect_chain(pEffectChain
);
885 hr
= FAudioVoice_SetEffectChain(This
->faudio_voice
, This
->effect_chain
);
890 static HRESULT WINAPI
XA2SUB_EnableEffect(IXAudio2SubmixVoice
*iface
, UINT32 EffectIndex
,
893 XA2VoiceImpl
*This
= impl_from_IXAudio2SubmixVoice(iface
);
894 TRACE("%p, %u, 0x%x\n", This
, EffectIndex
, OperationSet
);
895 return FAudioVoice_EnableEffect(This
->faudio_voice
, EffectIndex
, OperationSet
);
898 static HRESULT WINAPI
XA2SUB_DisableEffect(IXAudio2SubmixVoice
*iface
, UINT32 EffectIndex
,
901 XA2VoiceImpl
*This
= impl_from_IXAudio2SubmixVoice(iface
);
902 TRACE("%p, %u, 0x%x\n", This
, EffectIndex
, OperationSet
);
903 return FAudioVoice_DisableEffect(This
->faudio_voice
, EffectIndex
, OperationSet
);
906 static void WINAPI
XA2SUB_GetEffectState(IXAudio2SubmixVoice
*iface
, UINT32 EffectIndex
,
909 XA2VoiceImpl
*This
= impl_from_IXAudio2SubmixVoice(iface
);
910 TRACE("%p, %u, %p\n", This
, EffectIndex
, pEnabled
);
911 FAudioVoice_GetEffectState(This
->faudio_voice
, EffectIndex
, (int32_t*)pEnabled
);
914 static HRESULT WINAPI
XA2SUB_SetEffectParameters(IXAudio2SubmixVoice
*iface
,
915 UINT32 EffectIndex
, const void *pParameters
, UINT32 ParametersByteSize
,
918 XA2VoiceImpl
*This
= impl_from_IXAudio2SubmixVoice(iface
);
919 TRACE("%p, %u, %p, 0x%x, 0x%x\n", This
, EffectIndex
, pParameters
,
920 ParametersByteSize
, OperationSet
);
921 return FAudioVoice_SetEffectParameters(This
->faudio_voice
, EffectIndex
,
922 pParameters
, ParametersByteSize
, OperationSet
);
925 static HRESULT WINAPI
XA2SUB_GetEffectParameters(IXAudio2SubmixVoice
*iface
,
926 UINT32 EffectIndex
, void *pParameters
, UINT32 ParametersByteSize
)
928 XA2VoiceImpl
*This
= impl_from_IXAudio2SubmixVoice(iface
);
929 TRACE("%p, %u, %p, 0x%x\n", This
, EffectIndex
, pParameters
,
931 return FAudioVoice_GetEffectParameters(This
->faudio_voice
, EffectIndex
,
932 pParameters
, ParametersByteSize
);
935 static HRESULT WINAPI
XA2SUB_SetFilterParameters(IXAudio2SubmixVoice
*iface
,
936 const XAUDIO2_FILTER_PARAMETERS
*pParameters
, UINT32 OperationSet
)
938 XA2VoiceImpl
*This
= impl_from_IXAudio2SubmixVoice(iface
);
939 TRACE("%p, %p, 0x%x\n", This
, pParameters
, OperationSet
);
940 return FAudioVoice_SetFilterParameters(This
->faudio_voice
, (const FAudioFilterParameters
*)pParameters
,
944 static void WINAPI
XA2SUB_GetFilterParameters(IXAudio2SubmixVoice
*iface
,
945 XAUDIO2_FILTER_PARAMETERS
*pParameters
)
947 XA2VoiceImpl
*This
= impl_from_IXAudio2SubmixVoice(iface
);
948 TRACE("%p, %p\n", This
, pParameters
);
949 FAudioVoice_GetFilterParameters(This
->faudio_voice
, (FAudioFilterParameters
*)pParameters
);
952 static HRESULT WINAPI
XA2SUB_SetOutputFilterParameters(IXAudio2SubmixVoice
*iface
,
953 IXAudio2Voice
*pDestinationVoice
,
954 const XAUDIO2_FILTER_PARAMETERS
*pParameters
, UINT32 OperationSet
)
956 XA2VoiceImpl
*This
= impl_from_IXAudio2SubmixVoice(iface
);
957 XA2VoiceImpl
*dst
= pDestinationVoice
? impl_from_IXAudio2Voice(pDestinationVoice
) : NULL
;
959 TRACE("%p, %p, %p, 0x%x\n", This
, pDestinationVoice
, pParameters
, OperationSet
);
961 return FAudioVoice_SetOutputFilterParameters(This
->faudio_voice
,
962 dst
? dst
->faudio_voice
: NULL
, (const FAudioFilterParameters
*)pParameters
, OperationSet
);
965 static void WINAPI
XA2SUB_GetOutputFilterParameters(IXAudio2SubmixVoice
*iface
,
966 IXAudio2Voice
*pDestinationVoice
,
967 XAUDIO2_FILTER_PARAMETERS
*pParameters
)
969 XA2VoiceImpl
*This
= impl_from_IXAudio2SubmixVoice(iface
);
970 XA2VoiceImpl
*dst
= pDestinationVoice
? impl_from_IXAudio2Voice(pDestinationVoice
) : NULL
;
972 TRACE("%p, %p, %p\n", This
, pDestinationVoice
, pParameters
);
974 FAudioVoice_GetOutputFilterParameters(This
->faudio_voice
,
975 dst
? dst
->faudio_voice
: NULL
, (FAudioFilterParameters
*)pParameters
);
978 static HRESULT WINAPI
XA2SUB_SetVolume(IXAudio2SubmixVoice
*iface
, float Volume
,
981 XA2VoiceImpl
*This
= impl_from_IXAudio2SubmixVoice(iface
);
982 TRACE("%p, %f, 0x%x\n", This
, Volume
, OperationSet
);
983 return FAudioVoice_SetVolume(This
->faudio_voice
, Volume
, OperationSet
);
986 static void WINAPI
XA2SUB_GetVolume(IXAudio2SubmixVoice
*iface
, float *pVolume
)
988 XA2VoiceImpl
*This
= impl_from_IXAudio2SubmixVoice(iface
);
989 TRACE("%p, %p\n", This
, pVolume
);
990 return FAudioVoice_GetVolume(This
->faudio_voice
, pVolume
);
993 static HRESULT WINAPI
XA2SUB_SetChannelVolumes(IXAudio2SubmixVoice
*iface
, UINT32 Channels
,
994 const float *pVolumes
, UINT32 OperationSet
)
996 XA2VoiceImpl
*This
= impl_from_IXAudio2SubmixVoice(iface
);
997 TRACE("%p, %u, %p, 0x%x\n", This
, Channels
, pVolumes
, OperationSet
);
998 return FAudioVoice_SetChannelVolumes(This
->faudio_voice
, Channels
,
999 pVolumes
, OperationSet
);
1002 static void WINAPI
XA2SUB_GetChannelVolumes(IXAudio2SubmixVoice
*iface
, UINT32 Channels
,
1005 XA2VoiceImpl
*This
= impl_from_IXAudio2SubmixVoice(iface
);
1006 TRACE("%p, %u, %p\n", This
, Channels
, pVolumes
);
1007 return FAudioVoice_GetChannelVolumes(This
->faudio_voice
, Channels
,
1011 static HRESULT WINAPI
XA2SUB_SetOutputMatrix(IXAudio2SubmixVoice
*iface
,
1012 IXAudio2Voice
*pDestinationVoice
, UINT32 SourceChannels
,
1013 UINT32 DestinationChannels
, const float *pLevelMatrix
,
1014 UINT32 OperationSet
)
1016 XA2VoiceImpl
*This
= impl_from_IXAudio2SubmixVoice(iface
);
1017 XA2VoiceImpl
*dst
= pDestinationVoice
? impl_from_IXAudio2Voice(pDestinationVoice
) : NULL
;
1019 TRACE("%p, %p, %u, %u, %p, 0x%x\n", This
, pDestinationVoice
,
1020 SourceChannels
, DestinationChannels
, pLevelMatrix
, OperationSet
);
1022 return FAudioVoice_SetOutputMatrix(This
->faudio_voice
, dst
? dst
->faudio_voice
: NULL
,
1023 SourceChannels
, DestinationChannels
, pLevelMatrix
, OperationSet
);
1026 static void WINAPI
XA2SUB_GetOutputMatrix(IXAudio2SubmixVoice
*iface
,
1027 IXAudio2Voice
*pDestinationVoice
, UINT32 SourceChannels
,
1028 UINT32 DestinationChannels
, float *pLevelMatrix
)
1030 XA2VoiceImpl
*This
= impl_from_IXAudio2SubmixVoice(iface
);
1031 XA2VoiceImpl
*dst
= pDestinationVoice
? impl_from_IXAudio2Voice(pDestinationVoice
) : NULL
;
1033 TRACE("%p, %p, %u, %u, %p\n", This
, pDestinationVoice
,
1034 SourceChannels
, DestinationChannels
, pLevelMatrix
);
1036 FAudioVoice_GetOutputMatrix(This
->faudio_voice
, dst
? dst
->faudio_voice
: NULL
,
1037 SourceChannels
, DestinationChannels
, pLevelMatrix
);
1040 static void WINAPI
XA2SUB_DestroyVoice(IXAudio2SubmixVoice
*iface
)
1042 XA2VoiceImpl
*This
= impl_from_IXAudio2SubmixVoice(iface
);
1044 TRACE("%p\n", This
);
1046 EnterCriticalSection(&This
->lock
);
1048 destroy_voice(This
);
1050 LeaveCriticalSection(&This
->lock
);
1053 static const struct IXAudio2SubmixVoiceVtbl XAudio2SubmixVoice_Vtbl
= {
1054 XA2SUB_GetVoiceDetails
,
1055 XA2SUB_SetOutputVoices
,
1056 XA2SUB_SetEffectChain
,
1057 XA2SUB_EnableEffect
,
1058 XA2SUB_DisableEffect
,
1059 XA2SUB_GetEffectState
,
1060 XA2SUB_SetEffectParameters
,
1061 XA2SUB_GetEffectParameters
,
1062 XA2SUB_SetFilterParameters
,
1063 XA2SUB_GetFilterParameters
,
1064 XA2SUB_SetOutputFilterParameters
,
1065 XA2SUB_GetOutputFilterParameters
,
1068 XA2SUB_SetChannelVolumes
,
1069 XA2SUB_GetChannelVolumes
,
1070 XA2SUB_SetOutputMatrix
,
1071 XA2SUB_GetOutputMatrix
,
1075 /* Mastering Voices */
1077 static inline XA2VoiceImpl
*impl_from_IXAudio2MasteringVoice(IXAudio2MasteringVoice
*iface
)
1079 return CONTAINING_RECORD(iface
, XA2VoiceImpl
, IXAudio2MasteringVoice_iface
);
1082 static void WINAPI
XA2M_GetVoiceDetails(IXAudio2MasteringVoice
*iface
,
1083 XAUDIO2_VOICE_DETAILS
*pVoiceDetails
)
1085 XA2VoiceImpl
*This
= impl_from_IXAudio2MasteringVoice(iface
);
1086 TRACE("%p, %p\n", This
, pVoiceDetails
);
1087 FAudioVoice_GetVoiceDetails(This
->faudio_voice
, (FAudioVoiceDetails
*)pVoiceDetails
);
1090 static HRESULT WINAPI
XA2M_SetOutputVoices(IXAudio2MasteringVoice
*iface
,
1091 const XAUDIO2_VOICE_SENDS
*pSendList
)
1093 XA2VoiceImpl
*This
= impl_from_IXAudio2MasteringVoice(iface
);
1094 FAudioVoiceSends
*faudio_sends
;
1097 TRACE("%p, %p\n", This
, pSendList
);
1099 faudio_sends
= wrap_voice_sends(pSendList
);
1101 hr
= FAudioVoice_SetOutputVoices(This
->faudio_voice
, faudio_sends
);
1103 free_voice_sends(faudio_sends
);
1108 static HRESULT WINAPI
XA2M_SetEffectChain(IXAudio2MasteringVoice
*iface
,
1109 const XAUDIO2_EFFECT_CHAIN
*pEffectChain
)
1111 XA2VoiceImpl
*This
= impl_from_IXAudio2MasteringVoice(iface
);
1114 TRACE("%p, %p\n", This
, pEffectChain
);
1116 free_effect_chain(This
->effect_chain
);
1117 This
->effect_chain
= wrap_effect_chain(pEffectChain
);
1119 hr
= FAudioVoice_SetEffectChain(This
->faudio_voice
, This
->effect_chain
);
1124 static HRESULT WINAPI
XA2M_EnableEffect(IXAudio2MasteringVoice
*iface
, UINT32 EffectIndex
,
1125 UINT32 OperationSet
)
1127 XA2VoiceImpl
*This
= impl_from_IXAudio2MasteringVoice(iface
);
1128 TRACE("%p, %u, 0x%x\n", This
, EffectIndex
, OperationSet
);
1129 return FAudioVoice_EnableEffect(This
->faudio_voice
, EffectIndex
, OperationSet
);
1132 static HRESULT WINAPI
XA2M_DisableEffect(IXAudio2MasteringVoice
*iface
, UINT32 EffectIndex
,
1133 UINT32 OperationSet
)
1135 XA2VoiceImpl
*This
= impl_from_IXAudio2MasteringVoice(iface
);
1136 TRACE("%p, %u, 0x%x\n", This
, EffectIndex
, OperationSet
);
1137 return FAudioVoice_DisableEffect(This
->faudio_voice
, EffectIndex
, OperationSet
);
1140 static void WINAPI
XA2M_GetEffectState(IXAudio2MasteringVoice
*iface
, UINT32 EffectIndex
,
1143 XA2VoiceImpl
*This
= impl_from_IXAudio2MasteringVoice(iface
);
1144 TRACE("%p, %u, %p\n", This
, EffectIndex
, pEnabled
);
1145 FAudioVoice_GetEffectState(This
->faudio_voice
, EffectIndex
, (int32_t*)pEnabled
);
1148 static HRESULT WINAPI
XA2M_SetEffectParameters(IXAudio2MasteringVoice
*iface
,
1149 UINT32 EffectIndex
, const void *pParameters
, UINT32 ParametersByteSize
,
1150 UINT32 OperationSet
)
1152 XA2VoiceImpl
*This
= impl_from_IXAudio2MasteringVoice(iface
);
1153 TRACE("%p, %u, %p, 0x%x, 0x%x\n", This
, EffectIndex
, pParameters
,
1154 ParametersByteSize
, OperationSet
);
1155 return FAudioVoice_SetEffectParameters(This
->faudio_voice
, EffectIndex
,
1156 pParameters
, ParametersByteSize
, OperationSet
);
1159 static HRESULT WINAPI
XA2M_GetEffectParameters(IXAudio2MasteringVoice
*iface
,
1160 UINT32 EffectIndex
, void *pParameters
, UINT32 ParametersByteSize
)
1162 XA2VoiceImpl
*This
= impl_from_IXAudio2MasteringVoice(iface
);
1163 TRACE("%p, %u, %p, 0x%x\n", This
, EffectIndex
, pParameters
,
1164 ParametersByteSize
);
1165 return FAudioVoice_GetEffectParameters(This
->faudio_voice
, EffectIndex
,
1166 pParameters
, ParametersByteSize
);
1169 static HRESULT WINAPI
XA2M_SetFilterParameters(IXAudio2MasteringVoice
*iface
,
1170 const XAUDIO2_FILTER_PARAMETERS
*pParameters
, UINT32 OperationSet
)
1172 XA2VoiceImpl
*This
= impl_from_IXAudio2MasteringVoice(iface
);
1173 TRACE("%p, %p, 0x%x\n", This
, pParameters
, OperationSet
);
1174 return FAudioVoice_SetFilterParameters(This
->faudio_voice
, (const FAudioFilterParameters
*)pParameters
,
1178 static void WINAPI
XA2M_GetFilterParameters(IXAudio2MasteringVoice
*iface
,
1179 XAUDIO2_FILTER_PARAMETERS
*pParameters
)
1181 XA2VoiceImpl
*This
= impl_from_IXAudio2MasteringVoice(iface
);
1182 TRACE("%p, %p\n", This
, pParameters
);
1183 FAudioVoice_GetFilterParameters(This
->faudio_voice
, (FAudioFilterParameters
*)pParameters
);
1186 static HRESULT WINAPI
XA2M_SetOutputFilterParameters(IXAudio2MasteringVoice
*iface
,
1187 IXAudio2Voice
*pDestinationVoice
,
1188 const XAUDIO2_FILTER_PARAMETERS
*pParameters
, UINT32 OperationSet
)
1190 XA2VoiceImpl
*This
= impl_from_IXAudio2MasteringVoice(iface
);
1191 XA2VoiceImpl
*dst
= pDestinationVoice
? impl_from_IXAudio2Voice(pDestinationVoice
) : NULL
;
1193 TRACE("%p, %p, %p, 0x%x\n", This
, pDestinationVoice
, pParameters
, OperationSet
);
1195 return FAudioVoice_SetOutputFilterParameters(This
->faudio_voice
,
1196 dst
? dst
->faudio_voice
: NULL
, (const FAudioFilterParameters
*)pParameters
, OperationSet
);
1199 static void WINAPI
XA2M_GetOutputFilterParameters(IXAudio2MasteringVoice
*iface
,
1200 IXAudio2Voice
*pDestinationVoice
,
1201 XAUDIO2_FILTER_PARAMETERS
*pParameters
)
1203 XA2VoiceImpl
*This
= impl_from_IXAudio2MasteringVoice(iface
);
1204 XA2VoiceImpl
*dst
= pDestinationVoice
? impl_from_IXAudio2Voice(pDestinationVoice
) : NULL
;
1206 TRACE("%p, %p, %p\n", This
, pDestinationVoice
, pParameters
);
1208 FAudioVoice_GetOutputFilterParameters(This
->faudio_voice
,
1209 dst
? dst
->faudio_voice
: NULL
, (FAudioFilterParameters
*)pParameters
);
1212 static HRESULT WINAPI
XA2M_SetVolume(IXAudio2MasteringVoice
*iface
, float Volume
,
1213 UINT32 OperationSet
)
1215 XA2VoiceImpl
*This
= impl_from_IXAudio2MasteringVoice(iface
);
1216 TRACE("%p, %f, 0x%x\n", This
, Volume
, OperationSet
);
1217 return FAudioVoice_SetVolume(This
->faudio_voice
, Volume
, OperationSet
);
1220 static void WINAPI
XA2M_GetVolume(IXAudio2MasteringVoice
*iface
, float *pVolume
)
1222 XA2VoiceImpl
*This
= impl_from_IXAudio2MasteringVoice(iface
);
1223 TRACE("%p, %p\n", This
, pVolume
);
1224 return FAudioVoice_GetVolume(This
->faudio_voice
, pVolume
);
1227 static HRESULT WINAPI
XA2M_SetChannelVolumes(IXAudio2MasteringVoice
*iface
, UINT32 Channels
,
1228 const float *pVolumes
, UINT32 OperationSet
)
1230 XA2VoiceImpl
*This
= impl_from_IXAudio2MasteringVoice(iface
);
1231 TRACE("%p, %u, %p, 0x%x\n", This
, Channels
, pVolumes
, OperationSet
);
1232 return FAudioVoice_SetChannelVolumes(This
->faudio_voice
, Channels
,
1233 pVolumes
, OperationSet
);
1236 static void WINAPI
XA2M_GetChannelVolumes(IXAudio2MasteringVoice
*iface
, UINT32 Channels
,
1239 XA2VoiceImpl
*This
= impl_from_IXAudio2MasteringVoice(iface
);
1240 TRACE("%p, %u, %p\n", This
, Channels
, pVolumes
);
1241 return FAudioVoice_GetChannelVolumes(This
->faudio_voice
, Channels
,
1245 static HRESULT WINAPI
XA2M_SetOutputMatrix(IXAudio2MasteringVoice
*iface
,
1246 IXAudio2Voice
*pDestinationVoice
, UINT32 SourceChannels
,
1247 UINT32 DestinationChannels
, const float *pLevelMatrix
,
1248 UINT32 OperationSet
)
1250 XA2VoiceImpl
*This
= impl_from_IXAudio2MasteringVoice(iface
);
1251 XA2VoiceImpl
*dst
= pDestinationVoice
? impl_from_IXAudio2Voice(pDestinationVoice
) : NULL
;
1253 TRACE("%p, %p, %u, %u, %p, 0x%x\n", This
, pDestinationVoice
,
1254 SourceChannels
, DestinationChannels
, pLevelMatrix
, OperationSet
);
1256 return FAudioVoice_SetOutputMatrix(This
->faudio_voice
, dst
? dst
->faudio_voice
: NULL
,
1257 SourceChannels
, DestinationChannels
, pLevelMatrix
, OperationSet
);
1260 static void WINAPI
XA2M_GetOutputMatrix(IXAudio2MasteringVoice
*iface
,
1261 IXAudio2Voice
*pDestinationVoice
, UINT32 SourceChannels
,
1262 UINT32 DestinationChannels
, float *pLevelMatrix
)
1264 XA2VoiceImpl
*This
= impl_from_IXAudio2MasteringVoice(iface
);
1265 XA2VoiceImpl
*dst
= pDestinationVoice
? impl_from_IXAudio2Voice(pDestinationVoice
) : NULL
;
1267 TRACE("%p, %p, %u, %u, %p\n", This
, pDestinationVoice
,
1268 SourceChannels
, DestinationChannels
, pLevelMatrix
);
1270 FAudioVoice_GetOutputMatrix(This
->faudio_voice
, dst
? dst
->faudio_voice
: NULL
,
1271 SourceChannels
, DestinationChannels
, pLevelMatrix
);
1274 static void WINAPI
XA2M_DestroyVoice(IXAudio2MasteringVoice
*iface
)
1276 XA2VoiceImpl
*This
= impl_from_IXAudio2MasteringVoice(iface
);
1278 TRACE("%p\n", This
);
1280 EnterCriticalSection(&This
->lock
);
1282 destroy_voice(This
);
1284 LeaveCriticalSection(&This
->lock
);
1287 static void WINAPI
XA2M_GetChannelMask(IXAudio2MasteringVoice
*iface
,
1288 DWORD
*pChannelMask
)
1290 XA2VoiceImpl
*This
= impl_from_IXAudio2MasteringVoice(iface
);
1292 TRACE("%p, %p\n", This
, pChannelMask
);
1294 FAudioMasteringVoice_GetChannelMask(This
->faudio_voice
, (uint32_t *)pChannelMask
);
1297 static const struct IXAudio2MasteringVoiceVtbl XAudio2MasteringVoice_Vtbl
= {
1298 XA2M_GetVoiceDetails
,
1299 XA2M_SetOutputVoices
,
1300 XA2M_SetEffectChain
,
1303 XA2M_GetEffectState
,
1304 XA2M_SetEffectParameters
,
1305 XA2M_GetEffectParameters
,
1306 XA2M_SetFilterParameters
,
1307 XA2M_GetFilterParameters
,
1308 XA2M_SetOutputFilterParameters
,
1309 XA2M_GetOutputFilterParameters
,
1312 XA2M_SetChannelVolumes
,
1313 XA2M_GetChannelVolumes
,
1314 XA2M_SetOutputMatrix
,
1315 XA2M_GetOutputMatrix
,
1320 /* More Common Voice Functions */
1322 static XA2VoiceImpl
*impl_from_IXAudio2Voice(IXAudio2Voice
*iface
)
1324 if(iface
->lpVtbl
== (void*)&XAudio2SourceVoice_Vtbl
)
1325 return impl_from_IXAudio2SourceVoice((IXAudio2SourceVoice
*)iface
);
1326 if(iface
->lpVtbl
== (void*)&XAudio2MasteringVoice_Vtbl
)
1327 return impl_from_IXAudio2MasteringVoice((IXAudio2MasteringVoice
*)iface
);
1328 if(iface
->lpVtbl
== (void*)&XAudio2SubmixVoice_Vtbl
)
1329 return impl_from_IXAudio2SubmixVoice((IXAudio2SubmixVoice
*)iface
);
1330 #if XAUDIO2_VER == 0
1331 if(iface
->lpVtbl
== (void*)&XAudio20SourceVoice_Vtbl
)
1332 return impl_from_IXAudio20SourceVoice((IXAudio20SourceVoice
*)iface
);
1333 if(iface
->lpVtbl
== (void*)&XAudio20SubmixVoice_Vtbl
)
1334 return impl_from_IXAudio20SubmixVoice((IXAudio20SubmixVoice
*)iface
);
1335 if(iface
->lpVtbl
== (void*)&XAudio20MasteringVoice_Vtbl
)
1336 return impl_from_IXAudio20MasteringVoice((IXAudio20MasteringVoice
*)iface
);
1337 #elif XAUDIO2_VER <= 3
1338 if(iface
->lpVtbl
== (void*)&XAudio23SourceVoice_Vtbl
)
1339 return impl_from_IXAudio23SourceVoice((IXAudio23SourceVoice
*)iface
);
1340 if(iface
->lpVtbl
== (void*)&XAudio23SubmixVoice_Vtbl
)
1341 return impl_from_IXAudio23SubmixVoice((IXAudio23SubmixVoice
*)iface
);
1342 if(iface
->lpVtbl
== (void*)&XAudio23MasteringVoice_Vtbl
)
1343 return impl_from_IXAudio23MasteringVoice((IXAudio23MasteringVoice
*)iface
);
1344 #elif XAUDIO2_VER <= 7
1345 if(iface
->lpVtbl
== (void*)&XAudio27SourceVoice_Vtbl
)
1346 return impl_from_IXAudio27SourceVoice((IXAudio27SourceVoice
*)iface
);
1347 if(iface
->lpVtbl
== (void*)&XAudio27SubmixVoice_Vtbl
)
1348 return impl_from_IXAudio27SubmixVoice((IXAudio27SubmixVoice
*)iface
);
1349 if(iface
->lpVtbl
== (void*)&XAudio27MasteringVoice_Vtbl
)
1350 return impl_from_IXAudio27MasteringVoice((IXAudio27MasteringVoice
*)iface
);
1352 ERR("invalid IXAudio2Voice pointer: %p\n", iface
);
1356 /* XAudio2 Engine Implementation */
1358 static inline IXAudio2Impl
*impl_from_IXAudio2(IXAudio2
*iface
)
1360 return CONTAINING_RECORD(iface
, IXAudio2Impl
, IXAudio2_iface
);
1363 static HRESULT WINAPI
IXAudio2Impl_QueryInterface(IXAudio2
*iface
, REFIID riid
,
1366 IXAudio2Impl
*This
= impl_from_IXAudio2(iface
);
1368 TRACE("(%p)->(%s, %p)\n", This
, debugstr_guid(riid
), ppvObject
);
1370 if(IsEqualGUID(riid
, &IID_IUnknown
) ||
1371 #if XAUDIO2_VER == 8
1372 IsEqualGUID(riid
, &IID_IXAudio28
) ||
1374 IsEqualGUID(riid
, &IID_IXAudio2
))
1375 *ppvObject
= &This
->IXAudio2_iface
;
1376 else if(IsEqualGUID(riid
, &IID_IXAudio27
)){
1377 /* all xaudio versions before 28 share an IID */
1378 #if XAUDIO2_VER == 0
1379 *ppvObject
= &This
->IXAudio20_iface
;
1380 #elif XAUDIO2_VER <= 2
1381 *ppvObject
= &This
->IXAudio22_iface
;
1382 #elif XAUDIO2_VER <= 3
1383 *ppvObject
= &This
->IXAudio23_iface
;
1384 #elif XAUDIO2_VER <= 7
1385 *ppvObject
= &This
->IXAudio27_iface
;
1393 IUnknown_AddRef((IUnknown
*)*ppvObject
);
1397 FIXME("(%p)->(%s,%p), not found\n", This
,debugstr_guid(riid
), ppvObject
);
1399 return E_NOINTERFACE
;
1402 static ULONG WINAPI
IXAudio2Impl_AddRef(IXAudio2
*iface
)
1404 IXAudio2Impl
*This
= impl_from_IXAudio2(iface
);
1405 ULONG ref
= FAudio_AddRef(This
->faudio
);
1406 TRACE("(%p)->(): Refcount now %lu\n", This
, ref
);
1410 static ULONG WINAPI
IXAudio2Impl_Release(IXAudio2
*iface
)
1412 IXAudio2Impl
*This
= impl_from_IXAudio2(iface
);
1413 ULONG ref
= FAudio_Release(This
->faudio
);
1415 TRACE("(%p)->(): Refcount now %lu\n", This
, ref
);
1418 XA2VoiceImpl
*v
, *v2
;
1420 LIST_FOR_EACH_ENTRY_SAFE(v
, v2
, &This
->voices
, XA2VoiceImpl
, entry
){
1421 v
->lock
.DebugInfo
->Spare
[0] = 0;
1422 DeleteCriticalSection(&v
->lock
);
1423 HeapFree(GetProcessHeap(), 0, v
);
1426 HeapFree(GetProcessHeap(), 0, This
->cbs
);
1428 This
->lock
.DebugInfo
->Spare
[0] = 0;
1429 DeleteCriticalSection(&This
->lock
);
1431 HeapFree(GetProcessHeap(), 0, This
);
1436 static HRESULT WINAPI
IXAudio2Impl_RegisterForCallbacks(IXAudio2
*iface
,
1437 IXAudio2EngineCallback
*pCallback
)
1439 IXAudio2Impl
*This
= impl_from_IXAudio2(iface
);
1442 TRACE("(%p)->(%p)\n", This
, pCallback
);
1444 EnterCriticalSection(&This
->lock
);
1446 for(i
= 0; i
< This
->ncbs
; ++i
){
1447 if(!This
->cbs
[i
] || This
->cbs
[i
] == pCallback
){
1448 This
->cbs
[i
] = pCallback
;
1449 LeaveCriticalSection(&This
->lock
);
1455 This
->cbs
= heap_realloc(This
->cbs
, This
->ncbs
* sizeof(*This
->cbs
));
1457 This
->cbs
[i
] = pCallback
;
1459 LeaveCriticalSection(&This
->lock
);
1464 static void WINAPI
IXAudio2Impl_UnregisterForCallbacks(IXAudio2
*iface
,
1465 IXAudio2EngineCallback
*pCallback
)
1467 IXAudio2Impl
*This
= impl_from_IXAudio2(iface
);
1470 TRACE("(%p)->(%p)\n", This
, pCallback
);
1472 EnterCriticalSection(&This
->lock
);
1474 if(This
->ncbs
== 0){
1475 LeaveCriticalSection(&This
->lock
);
1479 for(i
= 0; i
< This
->ncbs
; ++i
){
1480 if(This
->cbs
[i
] == pCallback
)
1484 for(; i
< This
->ncbs
- 1 && This
->cbs
[i
+ 1]; ++i
)
1485 This
->cbs
[i
] = This
->cbs
[i
+ 1];
1488 This
->cbs
[i
] = NULL
;
1490 LeaveCriticalSection(&This
->lock
);
1493 static inline XA2VoiceImpl
*create_voice(IXAudio2Impl
*This
)
1495 XA2VoiceImpl
*voice
;
1497 voice
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(*voice
));
1501 list_add_head(&This
->voices
, &voice
->entry
);
1503 voice
->IXAudio2SourceVoice_iface
.lpVtbl
= &XAudio2SourceVoice_Vtbl
;
1504 #if XAUDIO2_VER == 0
1505 voice
->IXAudio20SourceVoice_iface
.lpVtbl
= &XAudio20SourceVoice_Vtbl
;
1506 #elif XAUDIO2_VER <= 3
1507 voice
->IXAudio23SourceVoice_iface
.lpVtbl
= &XAudio23SourceVoice_Vtbl
;
1508 #elif XAUDIO2_VER <= 7
1509 voice
->IXAudio27SourceVoice_iface
.lpVtbl
= &XAudio27SourceVoice_Vtbl
;
1512 voice
->IXAudio2SubmixVoice_iface
.lpVtbl
= &XAudio2SubmixVoice_Vtbl
;
1513 #if XAUDIO2_VER == 0
1514 voice
->IXAudio20SubmixVoice_iface
.lpVtbl
= &XAudio20SubmixVoice_Vtbl
;
1515 #elif XAUDIO2_VER <= 3
1516 voice
->IXAudio23SubmixVoice_iface
.lpVtbl
= &XAudio23SubmixVoice_Vtbl
;
1517 #elif XAUDIO2_VER <= 7
1518 voice
->IXAudio27SubmixVoice_iface
.lpVtbl
= &XAudio27SubmixVoice_Vtbl
;
1521 voice
->FAudioVoiceCallback_vtbl
= FAudioVoiceCallback_Vtbl
;
1523 InitializeCriticalSection(&voice
->lock
);
1524 voice
->lock
.DebugInfo
->Spare
[0] = (DWORD_PTR
)(__FILE__
": XA2VoiceImpl.lock");
1529 static HRESULT WINAPI
IXAudio2Impl_CreateSourceVoice(IXAudio2
*iface
,
1530 IXAudio2SourceVoice
**ppSourceVoice
, const WAVEFORMATEX
*pSourceFormat
,
1531 UINT32 flags
, float maxFrequencyRatio
,
1532 IXAudio2VoiceCallback
*pCallback
, const XAUDIO2_VOICE_SENDS
*pSendList
,
1533 const XAUDIO2_EFFECT_CHAIN
*pEffectChain
)
1535 IXAudio2Impl
*This
= impl_from_IXAudio2(iface
);
1538 FAudioVoiceSends
*faudio_sends
;
1540 TRACE("(%p)->(%p, %p, 0x%x, %f, %p, %p, %p)\n", This
, ppSourceVoice
,
1541 pSourceFormat
, flags
, maxFrequencyRatio
, pCallback
, pSendList
,
1544 EnterCriticalSection(&This
->lock
);
1546 LIST_FOR_EACH_ENTRY(src
, &This
->voices
, XA2VoiceImpl
, entry
){
1547 EnterCriticalSection(&src
->lock
);
1550 LeaveCriticalSection(&src
->lock
);
1553 if(&src
->entry
== &This
->voices
){
1554 src
= create_voice(This
);
1555 EnterCriticalSection(&src
->lock
);
1558 LeaveCriticalSection(&This
->lock
);
1560 src
->effect_chain
= wrap_effect_chain(pEffectChain
);
1561 faudio_sends
= wrap_voice_sends(pSendList
);
1563 hr
= FAudio_CreateSourceVoice(This
->faudio
, &src
->faudio_voice
,
1564 (FAudioWaveFormatEx
*)pSourceFormat
, flags
, maxFrequencyRatio
,
1565 &src
->FAudioVoiceCallback_vtbl
, faudio_sends
,
1567 free_voice_sends(faudio_sends
);
1569 LeaveCriticalSection(&This
->lock
);
1573 src
->cb
= pCallback
;
1575 LeaveCriticalSection(&src
->lock
);
1577 #if XAUDIO2_VER == 0
1578 *ppSourceVoice
= (IXAudio2SourceVoice
*)&src
->IXAudio20SourceVoice_iface
;
1579 #elif XAUDIO2_VER <= 3
1580 *ppSourceVoice
= (IXAudio2SourceVoice
*)&src
->IXAudio23SourceVoice_iface
;
1581 #elif XAUDIO2_VER <= 7
1582 *ppSourceVoice
= (IXAudio2SourceVoice
*)&src
->IXAudio27SourceVoice_iface
;
1584 *ppSourceVoice
= &src
->IXAudio2SourceVoice_iface
;
1587 TRACE("Created source voice: %p\n", src
);
1592 static HRESULT WINAPI
IXAudio2Impl_CreateSubmixVoice(IXAudio2
*iface
,
1593 IXAudio2SubmixVoice
**ppSubmixVoice
, UINT32 inputChannels
,
1594 UINT32 inputSampleRate
, UINT32 flags
, UINT32 processingStage
,
1595 const XAUDIO2_VOICE_SENDS
*pSendList
,
1596 const XAUDIO2_EFFECT_CHAIN
*pEffectChain
)
1599 IXAudio2Impl
*This
= impl_from_IXAudio2(iface
);
1601 FAudioVoiceSends
*faudio_sends
;
1603 TRACE("(%p)->(%p, %u, %u, 0x%x, %u, %p, %p)\n", This
, ppSubmixVoice
,
1604 inputChannels
, inputSampleRate
, flags
, processingStage
, pSendList
,
1607 EnterCriticalSection(&This
->lock
);
1609 LIST_FOR_EACH_ENTRY(sub
, &This
->voices
, XA2VoiceImpl
, entry
){
1610 EnterCriticalSection(&sub
->lock
);
1613 LeaveCriticalSection(&sub
->lock
);
1616 if(&sub
->entry
== &This
->voices
){
1617 sub
= create_voice(This
);
1618 EnterCriticalSection(&sub
->lock
);
1621 LeaveCriticalSection(&This
->lock
);
1623 sub
->effect_chain
= wrap_effect_chain(pEffectChain
);
1624 faudio_sends
= wrap_voice_sends(pSendList
);
1626 hr
= FAudio_CreateSubmixVoice(This
->faudio
, &sub
->faudio_voice
, inputChannels
,
1627 inputSampleRate
, flags
, processingStage
, faudio_sends
,
1629 free_voice_sends(faudio_sends
);
1631 LeaveCriticalSection(&sub
->lock
);
1636 LeaveCriticalSection(&sub
->lock
);
1638 #if XAUDIO2_VER == 0
1639 *ppSubmixVoice
= (IXAudio2SubmixVoice
*)&sub
->IXAudio20SubmixVoice_iface
;
1640 #elif XAUDIO2_VER <= 3
1641 *ppSubmixVoice
= (IXAudio2SubmixVoice
*)&sub
->IXAudio23SubmixVoice_iface
;
1642 #elif XAUDIO2_VER <= 7
1643 *ppSubmixVoice
= (IXAudio2SubmixVoice
*)&sub
->IXAudio27SubmixVoice_iface
;
1645 *ppSubmixVoice
= &sub
->IXAudio2SubmixVoice_iface
;
1648 TRACE("Created submix voice: %p\n", sub
);
1653 static HRESULT WINAPI
IXAudio2Impl_CreateMasteringVoice(IXAudio2
*iface
,
1654 IXAudio2MasteringVoice
**ppMasteringVoice
, UINT32 inputChannels
,
1655 UINT32 inputSampleRate
, UINT32 flags
, const WCHAR
*deviceId
,
1656 const XAUDIO2_EFFECT_CHAIN
*pEffectChain
,
1657 AUDIO_STREAM_CATEGORY streamCategory
)
1659 IXAudio2Impl
*This
= impl_from_IXAudio2(iface
);
1661 TRACE("(%p)->(%p, %u, %u, 0x%x, %s, %p, 0x%x)\n", This
,
1662 ppMasteringVoice
, inputChannels
, inputSampleRate
, flags
,
1663 wine_dbgstr_w(deviceId
), pEffectChain
, streamCategory
);
1665 EnterCriticalSection(&This
->lock
);
1667 /* Note that we don't have paths for each XAUDIO2_VER here.
1668 * All versions < 8 have a very different CreateMasteringVoice, so we
1669 * implement those separately in compat.c.
1672 *ppMasteringVoice
= &This
->mst
.IXAudio2MasteringVoice_iface
;
1674 EnterCriticalSection(&This
->mst
.lock
);
1676 if(This
->mst
.in_use
){
1677 LeaveCriticalSection(&This
->mst
.lock
);
1678 LeaveCriticalSection(&This
->lock
);
1679 return COMPAT_E_INVALID_CALL
;
1682 LeaveCriticalSection(&This
->lock
);
1684 This
->mst
.effect_chain
= wrap_effect_chain(pEffectChain
);
1686 FAudio_CreateMasteringVoice8(This
->faudio
, &This
->mst
.faudio_voice
, inputChannels
,
1687 inputSampleRate
, flags
, NULL
/* TODO: (uint16_t*)deviceId */,
1688 This
->mst
.effect_chain
, (FAudioStreamCategory
)streamCategory
);
1690 This
->mst
.in_use
= TRUE
;
1692 LeaveCriticalSection(&This
->mst
.lock
);
1697 static HRESULT WINAPI
IXAudio2Impl_StartEngine(IXAudio2
*iface
)
1699 IXAudio2Impl
*This
= impl_from_IXAudio2(iface
);
1701 TRACE("(%p)->()\n", This
);
1703 return FAudio_StartEngine(This
->faudio
);
1706 static void WINAPI
IXAudio2Impl_StopEngine(IXAudio2
*iface
)
1708 IXAudio2Impl
*This
= impl_from_IXAudio2(iface
);
1710 TRACE("(%p)->()\n", This
);
1712 FAudio_StopEngine(This
->faudio
);
1715 static HRESULT WINAPI
IXAudio2Impl_CommitChanges(IXAudio2
*iface
,
1716 UINT32 operationSet
)
1718 IXAudio2Impl
*This
= impl_from_IXAudio2(iface
);
1720 TRACE("(%p)->(0x%x)\n", This
, operationSet
);
1722 return FAudio_CommitOperationSet(This
->faudio
, operationSet
);
1725 static void WINAPI
IXAudio2Impl_GetPerformanceData(IXAudio2
*iface
,
1726 XAUDIO2_PERFORMANCE_DATA
*pPerfData
)
1728 IXAudio2Impl
*This
= impl_from_IXAudio2(iface
);
1730 TRACE("(%p)->(%p)\n", This
, pPerfData
);
1732 FAudio_GetPerformanceData(This
->faudio
, (FAudioPerformanceData
*)pPerfData
);
1735 static void WINAPI
IXAudio2Impl_SetDebugConfiguration(IXAudio2
*iface
,
1736 const XAUDIO2_DEBUG_CONFIGURATION
*pDebugConfiguration
,
1739 IXAudio2Impl
*This
= impl_from_IXAudio2(iface
);
1741 TRACE("(%p)->(%p, %p)\n", This
, pDebugConfiguration
, pReserved
);
1743 FAudio_SetDebugConfiguration(This
->faudio
, (FAudioDebugConfiguration
*)pDebugConfiguration
, pReserved
);
1747 static const IXAudio2Vtbl XAudio2_Vtbl
=
1749 IXAudio2Impl_QueryInterface
,
1750 IXAudio2Impl_AddRef
,
1751 IXAudio2Impl_Release
,
1752 IXAudio2Impl_RegisterForCallbacks
,
1753 IXAudio2Impl_UnregisterForCallbacks
,
1754 IXAudio2Impl_CreateSourceVoice
,
1755 IXAudio2Impl_CreateSubmixVoice
,
1756 IXAudio2Impl_CreateMasteringVoice
,
1757 IXAudio2Impl_StartEngine
,
1758 IXAudio2Impl_StopEngine
,
1759 IXAudio2Impl_CommitChanges
,
1760 IXAudio2Impl_GetPerformanceData
,
1761 IXAudio2Impl_SetDebugConfiguration
1764 /* XAudio2 ClassFactory */
1767 IClassFactory IClassFactory_iface
;
1771 static struct xaudio2_cf
*impl_from_IClassFactory(IClassFactory
*iface
)
1773 return CONTAINING_RECORD(iface
, struct xaudio2_cf
, IClassFactory_iface
);
1776 static HRESULT WINAPI
XAudio2CF_QueryInterface(IClassFactory
*iface
, REFIID riid
, void **ppobj
)
1778 if(IsEqualGUID(riid
, &IID_IUnknown
)
1779 || IsEqualGUID(riid
, &IID_IClassFactory
))
1781 IClassFactory_AddRef(iface
);
1787 WARN("(%p)->(%s, %p): interface not found\n", iface
, debugstr_guid(riid
), ppobj
);
1788 return E_NOINTERFACE
;
1791 static ULONG WINAPI
XAudio2CF_AddRef(IClassFactory
*iface
)
1793 struct xaudio2_cf
*This
= impl_from_IClassFactory(iface
);
1794 ULONG ref
= InterlockedIncrement(&This
->ref
);
1795 TRACE("(%p)->(): Refcount now %lu\n", This
, ref
);
1799 static ULONG WINAPI
XAudio2CF_Release(IClassFactory
*iface
)
1801 struct xaudio2_cf
*This
= impl_from_IClassFactory(iface
);
1802 ULONG ref
= InterlockedDecrement(&This
->ref
);
1803 TRACE("(%p)->(): Refcount now %lu\n", This
, ref
);
1805 HeapFree(GetProcessHeap(), 0, This
);
1809 static HRESULT WINAPI
XAudio2CF_CreateInstance(IClassFactory
*iface
, IUnknown
*pOuter
,
1810 REFIID riid
, void **ppobj
)
1812 struct xaudio2_cf
*This
= impl_from_IClassFactory(iface
);
1814 IXAudio2Impl
*object
;
1816 TRACE("(%p)->(%p,%s,%p)\n", This
, pOuter
, debugstr_guid(riid
), ppobj
);
1821 return CLASS_E_NOAGGREGATION
;
1823 object
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(*object
));
1825 return E_OUTOFMEMORY
;
1827 object
->IXAudio2_iface
.lpVtbl
= &XAudio2_Vtbl
;
1829 #if XAUDIO2_VER == 0
1830 object
->IXAudio20_iface
.lpVtbl
= &XAudio20_Vtbl
;
1831 #elif XAUDIO2_VER <= 2
1832 object
->IXAudio22_iface
.lpVtbl
= &XAudio22_Vtbl
;
1833 #elif XAUDIO2_VER <= 3
1834 object
->IXAudio23_iface
.lpVtbl
= &XAudio23_Vtbl
;
1835 #elif XAUDIO2_VER <= 7
1836 object
->IXAudio27_iface
.lpVtbl
= &XAudio27_Vtbl
;
1839 object
->mst
.IXAudio2MasteringVoice_iface
.lpVtbl
= &XAudio2MasteringVoice_Vtbl
;
1841 #if XAUDIO2_VER == 0
1842 object
->mst
.IXAudio20MasteringVoice_iface
.lpVtbl
= &XAudio20MasteringVoice_Vtbl
;
1843 #elif XAUDIO2_VER <= 3
1844 object
->mst
.IXAudio23MasteringVoice_iface
.lpVtbl
= &XAudio23MasteringVoice_Vtbl
;
1845 #elif XAUDIO2_VER <= 7
1846 object
->mst
.IXAudio27MasteringVoice_iface
.lpVtbl
= &XAudio27MasteringVoice_Vtbl
;
1849 object
->FAudioEngineCallback_vtbl
= FAudioEngineCallback_Vtbl
;
1851 list_init(&object
->voices
);
1853 InitializeCriticalSection(&object
->lock
);
1854 object
->lock
.DebugInfo
->Spare
[0] = (DWORD_PTR
)(__FILE__
": IXAudio2Impl.lock");
1856 InitializeCriticalSection(&object
->mst
.lock
);
1857 object
->mst
.lock
.DebugInfo
->Spare
[0] = (DWORD_PTR
)(__FILE__
": XA2MasteringVoice.lock");
1859 FAudioCOMConstructWithCustomAllocatorEXT(
1862 XAudio_Internal_Malloc
,
1863 XAudio_Internal_Free
,
1864 XAudio_Internal_Realloc
1867 FAudio_RegisterForCallbacks(object
->faudio
, &object
->FAudioEngineCallback_vtbl
);
1869 hr
= IXAudio2_QueryInterface(&object
->IXAudio2_iface
, riid
, ppobj
);
1870 IXAudio2_Release(&object
->IXAudio2_iface
);
1875 TRACE("Created XAudio version %u: %p\n", 20 + XAUDIO2_VER
, object
);
1880 static HRESULT WINAPI
XAudio2CF_LockServer(IClassFactory
*iface
, BOOL dolock
)
1882 struct xaudio2_cf
*This
= impl_from_IClassFactory(iface
);
1883 FIXME("(%p)->(%d): stub!\n", This
, dolock
);
1887 static const IClassFactoryVtbl XAudio2CF_Vtbl
=
1889 XAudio2CF_QueryInterface
,
1892 XAudio2CF_CreateInstance
,
1893 XAudio2CF_LockServer
1896 /* Engine Generators */
1898 static inline HRESULT
make_xaudio2_factory(REFIID riid
, void **ppv
)
1901 struct xaudio2_cf
*ret
= HeapAlloc(GetProcessHeap(), 0, sizeof(struct xaudio2_cf
));
1902 ret
->IClassFactory_iface
.lpVtbl
= &XAudio2CF_Vtbl
;
1904 hr
= IClassFactory_QueryInterface(&ret
->IClassFactory_iface
, riid
, ppv
);
1906 HeapFree(GetProcessHeap(), 0, ret
);
1910 HRESULT
xaudio2_initialize(IXAudio2Impl
*This
, UINT32 flags
, XAUDIO2_PROCESSOR proc
)
1912 if(proc
!= XAUDIO2_ANY_PROCESSOR
)
1913 WARN("Processor affinity not implemented in FAudio\n");
1914 return FAudio_Initialize(This
->faudio
, flags
, FAUDIO_DEFAULT_PROCESSOR
);
1917 HRESULT WINAPI
DllGetClassObject(REFCLSID rclsid
, REFIID riid
, void **ppv
)
1919 TRACE("(%s, %s, %p)\n", debugstr_guid(rclsid
), debugstr_guid(riid
), ppv
);
1921 if(IsEqualGUID(rclsid
, &CLSID_XAudio20
) ||
1922 IsEqualGUID(rclsid
, &CLSID_XAudio21
) ||
1923 IsEqualGUID(rclsid
, &CLSID_XAudio22
) ||
1924 IsEqualGUID(rclsid
, &CLSID_XAudio23
) ||
1925 IsEqualGUID(rclsid
, &CLSID_XAudio24
) ||
1926 IsEqualGUID(rclsid
, &CLSID_XAudio25
) ||
1927 IsEqualGUID(rclsid
, &CLSID_XAudio26
) ||
1928 IsEqualGUID(rclsid
, &CLSID_XAudio27
))
1929 return make_xaudio2_factory(riid
, ppv
);
1931 if(IsEqualGUID(rclsid
, &CLSID_AudioVolumeMeter20
) ||
1932 IsEqualGUID(rclsid
, &CLSID_AudioVolumeMeter21
) ||
1933 IsEqualGUID(rclsid
, &CLSID_AudioVolumeMeter22
) ||
1934 IsEqualGUID(rclsid
, &CLSID_AudioVolumeMeter23
) ||
1935 IsEqualGUID(rclsid
, &CLSID_AudioVolumeMeter24
) ||
1936 IsEqualGUID(rclsid
, &CLSID_AudioVolumeMeter25
) ||
1937 IsEqualGUID(rclsid
, &CLSID_AudioVolumeMeter26
) ||
1938 IsEqualGUID(rclsid
, &CLSID_AudioVolumeMeter27
))
1939 return make_xapo_factory(&CLSID_AudioVolumeMeter27
, riid
, ppv
);
1941 if(IsEqualGUID(rclsid
, &CLSID_AudioReverb20
) ||
1942 IsEqualGUID(rclsid
, &CLSID_AudioReverb21
) ||
1943 IsEqualGUID(rclsid
, &CLSID_AudioReverb22
) ||
1944 IsEqualGUID(rclsid
, &CLSID_AudioReverb23
) ||
1945 IsEqualGUID(rclsid
, &CLSID_AudioReverb24
) ||
1946 IsEqualGUID(rclsid
, &CLSID_AudioReverb25
) ||
1947 IsEqualGUID(rclsid
, &CLSID_AudioReverb26
) ||
1948 IsEqualGUID(rclsid
, &CLSID_AudioReverb27
))
1949 return make_xapo_factory(&CLSID_AudioReverb27
, riid
, ppv
);
1951 return CLASS_E_CLASSNOTAVAILABLE
;
1954 #if XAUDIO2_VER >= 8
1955 HRESULT WINAPI
XAudio2Create(IXAudio2
**ppxa2
, UINT32 flags
, XAUDIO2_PROCESSOR proc
)
1961 TRACE("%p 0x%x 0x%x\n", ppxa2
, flags
, proc
);
1963 hr
= make_xaudio2_factory(&IID_IClassFactory
, (void**)&cf
);
1967 hr
= IClassFactory_CreateInstance(cf
, NULL
, &IID_IXAudio2
, (void**)&xa2
);
1968 IClassFactory_Release(cf
);
1972 hr
= xaudio2_initialize(impl_from_IXAudio2(xa2
), flags
, proc
);
1974 IXAudio2_Release(xa2
);
1983 HRESULT WINAPI
CreateAudioVolumeMeter(IUnknown
**out
)
1990 hr
= make_xapo_factory(&CLSID_AudioVolumeMeter27
, &IID_IClassFactory
, (void**)&cf
);
1994 hr
= IClassFactory_CreateInstance(cf
, NULL
, &IID_IUnknown
, (void**)out
);
1996 IClassFactory_Release(cf
);
2001 HRESULT WINAPI
CreateAudioReverb(IUnknown
**out
)
2008 hr
= make_xapo_factory(&CLSID_AudioReverb27
, &IID_IClassFactory
, (void**)&cf
);
2012 hr
= IClassFactory_CreateInstance(cf
, NULL
, &IID_IUnknown
, (void**)out
);
2014 IClassFactory_Release(cf
);
2018 #endif /* XAUDIO2_VER >= 8 */