2 * Copyright (c) 2015 Mark Harmstone
3 * Copyright (c) 2015 Andrew Eikum for CodeWeavers
4 * Copyright (c) 2018 Ethan Lee for CodeWeavers
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
25 #define NONAMELESSUNION
29 #include "xaudio_private.h"
30 #include "xaudio2fx.h"
39 #include "wine/debug.h"
40 #include "wine/heap.h"
42 WINE_DEFAULT_DEBUG_CHANNEL(xaudio2
);
44 #if XAUDIO2_VER != 0 && defined(__i386__)
45 /* EVE Online uses an OnVoiceProcessingPassStart callback which corrupts %esi;
46 * League of Legends uses a callback which corrupts %ebx. */
47 #define IXAudio2VoiceCallback_OnVoiceProcessingPassStart(a, b) call_on_voice_processing_pass_start(a, b)
48 extern void call_on_voice_processing_pass_start(IXAudio2VoiceCallback
*This
, UINT32 BytesRequired
);
49 __ASM_GLOBAL_FUNC( call_on_voice_processing_pass_start
,
51 __ASM_CFI(".cfi_adjust_cfa_offset 4\n\t")
52 __ASM_CFI(".cfi_rel_offset %ebp,0\n\t")
54 __ASM_CFI(".cfi_def_cfa_register %ebp\n\t")
56 __ASM_CFI(".cfi_rel_offset %esi,-4\n\t")
58 __ASM_CFI(".cfi_rel_offset %edi,-8\n\t")
60 __ASM_CFI(".cfi_rel_offset %ebx,-12\n\t")
62 "pushl 12(%ebp)\n\t" /* BytesRequired */
63 "pushl 8(%ebp)\n\t" /* This */
64 "movl 8(%ebp),%eax\n\t"
65 "movl 0(%eax),%eax\n\t"
66 "call *0(%eax)\n\t" /* This->lpVtbl->OnVoiceProcessingPassStart */
67 "leal -12(%ebp),%esp\n\t"
69 __ASM_CFI(".cfi_same_value %ebx\n\t")
71 __ASM_CFI(".cfi_same_value %edi\n\t")
73 __ASM_CFI(".cfi_same_value %esi\n\t")
75 __ASM_CFI(".cfi_def_cfa %esp,4\n\t")
76 __ASM_CFI(".cfi_same_value %ebp\n\t")
80 static XA2VoiceImpl
*impl_from_IXAudio2Voice(IXAudio2Voice
*iface
);
82 BOOL WINAPI
DllMain(HINSTANCE hinstDLL
, DWORD reason
, void *pReserved
)
84 TRACE("(%p, %d, %p)\n", hinstDLL
, reason
, pReserved
);
88 case DLL_PROCESS_ATTACH
:
89 DisableThreadLibraryCalls( hinstDLL
);
90 #ifdef HAVE_FAUDIOLINKEDVERSION
91 TRACE("Using FAudio version %d\n", FAudioLinkedVersion() );
100 static inline XA2XAPOImpl
*impl_from_FAPO(FAPO
*iface
)
102 return CONTAINING_RECORD(iface
, XA2XAPOImpl
, FAPO_vtbl
);
105 static int32_t FAPOCALL
XAPO_AddRef(void *iface
)
107 XA2XAPOImpl
*This
= impl_from_FAPO(iface
);
109 return InterlockedIncrement(&This
->ref
);
112 static int32_t FAPOCALL
XAPO_Release(void *iface
)
115 XA2XAPOImpl
*This
= impl_from_FAPO(iface
);
117 r
= InterlockedDecrement(&This
->ref
);
119 IXAPO_Release(This
->xapo
);
120 if(This
->xapo_params
)
121 IXAPOParameters_Release(This
->xapo_params
);
127 static uint32_t FAPOCALL
XAPO_GetRegistrationProperties(void *iface
,
128 FAPORegistrationProperties
**ppRegistrationProperties
)
130 XA2XAPOImpl
*This
= impl_from_FAPO(iface
);
131 XAPO_REGISTRATION_PROPERTIES
*xprops
;
136 hr
= IXAPO_GetRegistrationProperties(This
->xapo
, &xprops
);
140 /* TODO: check for version == 20 and use XAPO20_REGISTRATION_PROPERTIES */
141 *ppRegistrationProperties
= (FAPORegistrationProperties
*) xprops
;
145 static uint32_t FAPOCALL
XAPO_IsInputFormatSupported(void *iface
,
146 const FAudioWaveFormatEx
*pOutputFormat
, const FAudioWaveFormatEx
*pRequestedInputFormat
,
147 FAudioWaveFormatEx
**ppSupportedInputFormat
)
149 XA2XAPOImpl
*This
= impl_from_FAPO(iface
);
151 return IXAPO_IsInputFormatSupported(This
->xapo
, (const WAVEFORMATEX
*)pOutputFormat
,
152 (const WAVEFORMATEX
*)pRequestedInputFormat
, (WAVEFORMATEX
**)ppSupportedInputFormat
);
155 static uint32_t FAPOCALL
XAPO_IsOutputFormatSupported(void *iface
,
156 const FAudioWaveFormatEx
*pInputFormat
, const FAudioWaveFormatEx
*pRequestedOutputFormat
,
157 FAudioWaveFormatEx
**ppSupportedOutputFormat
)
159 XA2XAPOImpl
*This
= impl_from_FAPO(iface
);
161 return IXAPO_IsOutputFormatSupported(This
->xapo
, (const WAVEFORMATEX
*)pInputFormat
,
162 (const WAVEFORMATEX
*)pRequestedOutputFormat
, (WAVEFORMATEX
**)ppSupportedOutputFormat
);
165 static uint32_t FAPOCALL
XAPO_Initialize(void *iface
, const void *pData
,
166 uint32_t DataByteSize
)
168 XA2XAPOImpl
*This
= impl_from_FAPO(iface
);
170 return IXAPO_Initialize(This
->xapo
, pData
, DataByteSize
);
173 static void FAPOCALL
XAPO_Reset(void *iface
)
175 XA2XAPOImpl
*This
= impl_from_FAPO(iface
);
177 IXAPO_Reset(This
->xapo
);
180 static uint32_t FAPOCALL
XAPO_LockForProcess(void *iface
,
181 uint32_t InputLockedParameterCount
,
182 const FAPOLockForProcessBufferParameters
*pInputLockedParameters
,
183 uint32_t OutputLockedParameterCount
,
184 const FAPOLockForProcessBufferParameters
*pOutputLockedParameters
)
186 XA2XAPOImpl
*This
= impl_from_FAPO(iface
);
188 return IXAPO_LockForProcess(This
->xapo
,
189 InputLockedParameterCount
,
190 (const XAPO_LOCKFORPROCESS_BUFFER_PARAMETERS
*)pInputLockedParameters
,
191 OutputLockedParameterCount
,
192 (const XAPO_LOCKFORPROCESS_BUFFER_PARAMETERS
*)pOutputLockedParameters
);
195 static void FAPOCALL
XAPO_UnlockForProcess(void *iface
)
197 XA2XAPOImpl
*This
= impl_from_FAPO(iface
);
199 IXAPO_UnlockForProcess(This
->xapo
);
202 static void FAPOCALL
XAPO_Process(void *iface
,
203 uint32_t InputProcessParameterCount
,
204 const FAPOProcessBufferParameters
* pInputProcessParameters
,
205 uint32_t OutputProcessParameterCount
,
206 FAPOProcessBufferParameters
* pOutputProcessParameters
,
209 XA2XAPOImpl
*This
= impl_from_FAPO(iface
);
211 IXAPO_Process(This
->xapo
, InputProcessParameterCount
,
212 (const XAPO_PROCESS_BUFFER_PARAMETERS
*)pInputProcessParameters
,
213 OutputProcessParameterCount
,
214 (XAPO_PROCESS_BUFFER_PARAMETERS
*)pOutputProcessParameters
,
218 static uint32_t FAPOCALL
XAPO_CalcInputFrames(void *iface
,
219 uint32_t OutputFrameCount
)
221 XA2XAPOImpl
*This
= impl_from_FAPO(iface
);
223 return IXAPO_CalcInputFrames(This
->xapo
, OutputFrameCount
);
226 static uint32_t FAPOCALL
XAPO_CalcOutputFrames(void *iface
,
227 uint32_t InputFrameCount
)
229 XA2XAPOImpl
*This
= impl_from_FAPO(iface
);
231 return IXAPO_CalcOutputFrames(This
->xapo
, InputFrameCount
);
234 static void FAPOCALL
XAPO_SetParameters(void *iface
,
235 const void *pParameters
, uint32_t ParametersByteSize
)
237 XA2XAPOImpl
*This
= impl_from_FAPO(iface
);
239 if(This
->xapo_params
)
240 IXAPOParameters_SetParameters(This
->xapo_params
, pParameters
, ParametersByteSize
);
243 static void FAPOCALL
XAPO_GetParameters(void *iface
,
244 void *pParameters
, uint32_t ParametersByteSize
)
246 XA2XAPOImpl
*This
= impl_from_FAPO(iface
);
248 if(This
->xapo_params
)
249 IXAPOParameters_GetParameters(This
->xapo_params
, pParameters
, ParametersByteSize
);
251 memset(pParameters
, 0, ParametersByteSize
);
254 static const FAPO FAPO_Vtbl
= {
257 XAPO_GetRegistrationProperties
,
258 XAPO_IsInputFormatSupported
,
259 XAPO_IsOutputFormatSupported
,
263 XAPO_UnlockForProcess
,
265 XAPO_CalcInputFrames
,
266 XAPO_CalcOutputFrames
,
271 static XA2XAPOImpl
*wrap_xapo(IUnknown
*unk
)
275 IXAPOParameters
*xapo_params
;
279 hr
= IUnknown_QueryInterface(unk
, &IID_IXAPO27
, (void**)&xapo
);
281 hr
= IUnknown_QueryInterface(unk
, &IID_IXAPO
, (void**)&xapo
);
284 WARN("XAPO doesn't support IXAPO? %p\n", unk
);
289 hr
= IUnknown_QueryInterface(unk
, &IID_IXAPO27Parameters
, (void**)&xapo_params
);
291 hr
= IUnknown_QueryInterface(unk
, &IID_IXAPOParameters
, (void**)&xapo_params
);
294 TRACE("XAPO doesn't support IXAPOParameters %p\n", unk
);
298 ret
= heap_alloc(sizeof(*ret
));
301 ret
->xapo_params
= xapo_params
;
302 ret
->FAPO_vtbl
= FAPO_Vtbl
;
305 TRACE("wrapped IXAPO %p with %p\n", xapo
, ret
);
310 FAudioEffectChain
*wrap_effect_chain(const XAUDIO2_EFFECT_CHAIN
*pEffectChain
)
312 FAudioEffectChain
*ret
;
318 ret
= heap_alloc(sizeof(*ret
) + sizeof(FAudioEffectDescriptor
) * pEffectChain
->EffectCount
);
320 ret
->EffectCount
= pEffectChain
->EffectCount
;
321 ret
->pEffectDescriptors
= (void*)(ret
+ 1);
323 for(i
= 0; i
< ret
->EffectCount
; ++i
){
324 ret
->pEffectDescriptors
[i
].pEffect
= &wrap_xapo(pEffectChain
->pEffectDescriptors
[i
].pEffect
)->FAPO_vtbl
;
325 ret
->pEffectDescriptors
[i
].InitialState
= pEffectChain
->pEffectDescriptors
[i
].InitialState
;
326 ret
->pEffectDescriptors
[i
].OutputChannels
= pEffectChain
->pEffectDescriptors
[i
].OutputChannels
;
332 static void free_effect_chain(FAudioEffectChain
*chain
)
337 for(i
= 0; i
< chain
->EffectCount
; ++i
)
338 XAPO_Release(chain
->pEffectDescriptors
[i
].pEffect
);
344 static FAudioVoiceSends
*wrap_voice_sends(const XAUDIO2_VOICE_SENDS
*sends
)
346 FAudioVoiceSends
*ret
;
352 ret
= heap_alloc(sizeof(*ret
) + sends
->SendCount
* sizeof(FAudioSendDescriptor
));
353 ret
->SendCount
= sends
->SendCount
;
354 ret
->pSends
= (FAudioSendDescriptor
*)(ret
+ 1);
355 for(i
= 0; i
< sends
->SendCount
; ++i
){
356 XA2VoiceImpl
*voice
= impl_from_IXAudio2Voice(sends
->pSends
[i
].pOutputVoice
);
357 ret
->pSends
[i
].pOutputVoice
= voice
->faudio_voice
;
358 ret
->pSends
[i
].Flags
= sends
->pSends
[i
].Flags
;
363 static void free_voice_sends(FAudioVoiceSends
*sends
)
370 /* Voice Callbacks */
372 static inline XA2VoiceImpl
*impl_from_FAudioVoiceCallback(FAudioVoiceCallback
*iface
)
374 return CONTAINING_RECORD(iface
, XA2VoiceImpl
, FAudioVoiceCallback_vtbl
);
377 static void FAUDIOCALL
XA2VCB_OnVoiceProcessingPassStart(FAudioVoiceCallback
*iface
,
378 UINT32 BytesRequired
)
380 XA2VoiceImpl
*This
= impl_from_FAudioVoiceCallback(iface
);
384 IXAudio20VoiceCallback_OnVoiceProcessingPassStart((IXAudio20VoiceCallback
*)This
->cb
);
386 IXAudio2VoiceCallback_OnVoiceProcessingPassStart(This
->cb
, BytesRequired
);
390 static void FAUDIOCALL
XA2VCB_OnVoiceProcessingPassEnd(FAudioVoiceCallback
*iface
)
392 XA2VoiceImpl
*This
= impl_from_FAudioVoiceCallback(iface
);
395 IXAudio2VoiceCallback_OnVoiceProcessingPassEnd(This
->cb
);
398 static void FAUDIOCALL
XA2VCB_OnStreamEnd(FAudioVoiceCallback
*iface
)
400 XA2VoiceImpl
*This
= impl_from_FAudioVoiceCallback(iface
);
403 IXAudio2VoiceCallback_OnStreamEnd(This
->cb
);
406 static void FAUDIOCALL
XA2VCB_OnBufferStart(FAudioVoiceCallback
*iface
,
407 void *pBufferContext
)
409 XA2VoiceImpl
*This
= impl_from_FAudioVoiceCallback(iface
);
412 IXAudio2VoiceCallback_OnBufferStart(This
->cb
, pBufferContext
);
415 static void FAUDIOCALL
XA2VCB_OnBufferEnd(FAudioVoiceCallback
*iface
,
416 void *pBufferContext
)
418 XA2VoiceImpl
*This
= impl_from_FAudioVoiceCallback(iface
);
421 IXAudio2VoiceCallback_OnBufferEnd(This
->cb
, pBufferContext
);
424 static void FAUDIOCALL
XA2VCB_OnLoopEnd(FAudioVoiceCallback
*iface
,
425 void *pBufferContext
)
427 XA2VoiceImpl
*This
= impl_from_FAudioVoiceCallback(iface
);
430 IXAudio2VoiceCallback_OnLoopEnd(This
->cb
, pBufferContext
);
433 static void FAUDIOCALL
XA2VCB_OnVoiceError(FAudioVoiceCallback
*iface
,
434 void *pBufferContext
, unsigned int Error
)
436 XA2VoiceImpl
*This
= impl_from_FAudioVoiceCallback(iface
);
439 IXAudio2VoiceCallback_OnVoiceError(This
->cb
, pBufferContext
, (HRESULT
)Error
);
442 static const FAudioVoiceCallback FAudioVoiceCallback_Vtbl
= {
444 XA2VCB_OnBufferStart
,
448 XA2VCB_OnVoiceProcessingPassEnd
,
449 XA2VCB_OnVoiceProcessingPassStart
452 /* Engine Callbacks */
454 static inline IXAudio2Impl
*impl_from_FAudioEngineCallback(FAudioEngineCallback
*iface
)
456 return CONTAINING_RECORD(iface
, IXAudio2Impl
, FAudioEngineCallback_vtbl
);
459 static void FAUDIOCALL
XA2ECB_OnProcessingPassStart(FAudioEngineCallback
*iface
)
461 IXAudio2Impl
*This
= impl_from_FAudioEngineCallback(iface
);
464 for(i
= 0; i
< This
->ncbs
&& This
->cbs
[i
]; ++i
)
465 IXAudio2EngineCallback_OnProcessingPassStart(This
->cbs
[i
]);
468 static void FAUDIOCALL
XA2ECB_OnProcessingPassEnd(FAudioEngineCallback
*iface
)
470 IXAudio2Impl
*This
= impl_from_FAudioEngineCallback(iface
);
473 for(i
= 0; i
< This
->ncbs
&& This
->cbs
[i
]; ++i
)
474 IXAudio2EngineCallback_OnProcessingPassEnd(This
->cbs
[i
]);
477 static void FAUDIOCALL
XA2ECB_OnCriticalError(FAudioEngineCallback
*iface
,
480 IXAudio2Impl
*This
= impl_from_FAudioEngineCallback(iface
);
483 for(i
= 0; i
< This
->ncbs
&& This
->cbs
[i
]; ++i
)
484 IXAudio2EngineCallback_OnCriticalError(This
->cbs
[i
], error
);
487 static const FAudioEngineCallback FAudioEngineCallback_Vtbl
= {
488 XA2ECB_OnCriticalError
,
489 XA2ECB_OnProcessingPassEnd
,
490 XA2ECB_OnProcessingPassStart
493 /* Common Voice Functions */
495 static inline void destroy_voice(XA2VoiceImpl
*This
)
497 FAudioVoice_DestroyVoice(This
->faudio_voice
);
498 free_effect_chain(This
->effect_chain
);
499 This
->effect_chain
= NULL
;
500 This
->in_use
= FALSE
;
505 static inline XA2VoiceImpl
*impl_from_IXAudio2SourceVoice(IXAudio2SourceVoice
*iface
)
507 return CONTAINING_RECORD(iface
, XA2VoiceImpl
, IXAudio2SourceVoice_iface
);
510 static void WINAPI
XA2SRC_GetVoiceDetails(IXAudio2SourceVoice
*iface
,
511 XAUDIO2_VOICE_DETAILS
*pVoiceDetails
)
513 XA2VoiceImpl
*This
= impl_from_IXAudio2SourceVoice(iface
);
514 TRACE("%p, %p\n", This
, pVoiceDetails
);
515 FAudioVoice_GetVoiceDetails(This
->faudio_voice
, (FAudioVoiceDetails
*)pVoiceDetails
);
518 static HRESULT WINAPI
XA2SRC_SetOutputVoices(IXAudio2SourceVoice
*iface
,
519 const XAUDIO2_VOICE_SENDS
*pSendList
)
521 XA2VoiceImpl
*This
= impl_from_IXAudio2SourceVoice(iface
);
522 FAudioVoiceSends
*faudio_sends
;
525 TRACE("%p, %p\n", This
, pSendList
);
527 faudio_sends
= wrap_voice_sends(pSendList
);
529 hr
= FAudioVoice_SetOutputVoices(This
->faudio_voice
, faudio_sends
);
531 free_voice_sends(faudio_sends
);
536 static HRESULT WINAPI
XA2SRC_SetEffectChain(IXAudio2SourceVoice
*iface
,
537 const XAUDIO2_EFFECT_CHAIN
*pEffectChain
)
539 XA2VoiceImpl
*This
= impl_from_IXAudio2SourceVoice(iface
);
542 TRACE("%p, %p\n", This
, pEffectChain
);
544 free_effect_chain(This
->effect_chain
);
545 This
->effect_chain
= wrap_effect_chain(pEffectChain
);
547 hr
= FAudioVoice_SetEffectChain(This
->faudio_voice
, This
->effect_chain
);
552 static HRESULT WINAPI
XA2SRC_EnableEffect(IXAudio2SourceVoice
*iface
, UINT32 EffectIndex
,
555 XA2VoiceImpl
*This
= impl_from_IXAudio2SourceVoice(iface
);
556 TRACE("%p, %u, 0x%x\n", This
, EffectIndex
, OperationSet
);
557 return FAudioVoice_EnableEffect(This
->faudio_voice
, EffectIndex
, OperationSet
);
560 static HRESULT WINAPI
XA2SRC_DisableEffect(IXAudio2SourceVoice
*iface
, UINT32 EffectIndex
,
563 XA2VoiceImpl
*This
= impl_from_IXAudio2SourceVoice(iface
);
564 TRACE("%p, %u, 0x%x\n", This
, EffectIndex
, OperationSet
);
565 return FAudioVoice_DisableEffect(This
->faudio_voice
, EffectIndex
, OperationSet
);
568 static void WINAPI
XA2SRC_GetEffectState(IXAudio2SourceVoice
*iface
, UINT32 EffectIndex
,
571 XA2VoiceImpl
*This
= impl_from_IXAudio2SourceVoice(iface
);
572 TRACE("%p, %u, %p\n", This
, EffectIndex
, pEnabled
);
573 FAudioVoice_GetEffectState(This
->faudio_voice
, EffectIndex
, (int32_t*)pEnabled
);
576 static HRESULT WINAPI
XA2SRC_SetEffectParameters(IXAudio2SourceVoice
*iface
,
577 UINT32 EffectIndex
, const void *pParameters
, UINT32 ParametersByteSize
,
580 XA2VoiceImpl
*This
= impl_from_IXAudio2SourceVoice(iface
);
581 TRACE("%p, %u, %p, 0x%x, 0x%x\n", This
, EffectIndex
, pParameters
,
582 ParametersByteSize
, OperationSet
);
583 return FAudioVoice_SetEffectParameters(This
->faudio_voice
, EffectIndex
,
584 pParameters
, ParametersByteSize
, OperationSet
);
587 static HRESULT WINAPI
XA2SRC_GetEffectParameters(IXAudio2SourceVoice
*iface
,
588 UINT32 EffectIndex
, void *pParameters
, UINT32 ParametersByteSize
)
590 XA2VoiceImpl
*This
= impl_from_IXAudio2SourceVoice(iface
);
591 TRACE("%p, %u, %p, 0x%x\n", This
, EffectIndex
, pParameters
,
593 return FAudioVoice_GetEffectParameters(This
->faudio_voice
, EffectIndex
,
594 pParameters
, ParametersByteSize
);
597 static HRESULT WINAPI
XA2SRC_SetFilterParameters(IXAudio2SourceVoice
*iface
,
598 const XAUDIO2_FILTER_PARAMETERS
*pParameters
, UINT32 OperationSet
)
600 XA2VoiceImpl
*This
= impl_from_IXAudio2SourceVoice(iface
);
601 TRACE("%p, %p, 0x%x\n", This
, pParameters
, OperationSet
);
602 return FAudioVoice_SetFilterParameters(This
->faudio_voice
,
603 (const FAudioFilterParameters
*)pParameters
, OperationSet
);
606 static void WINAPI
XA2SRC_GetFilterParameters(IXAudio2SourceVoice
*iface
,
607 XAUDIO2_FILTER_PARAMETERS
*pParameters
)
609 XA2VoiceImpl
*This
= impl_from_IXAudio2SourceVoice(iface
);
610 TRACE("%p, %p\n", This
, pParameters
);
611 FAudioVoice_GetFilterParameters(This
->faudio_voice
, (FAudioFilterParameters
*)pParameters
);
614 static HRESULT WINAPI
XA2SRC_SetOutputFilterParameters(IXAudio2SourceVoice
*iface
,
615 IXAudio2Voice
*pDestinationVoice
,
616 const XAUDIO2_FILTER_PARAMETERS
*pParameters
, UINT32 OperationSet
)
618 XA2VoiceImpl
*This
= impl_from_IXAudio2SourceVoice(iface
);
619 XA2VoiceImpl
*dst
= pDestinationVoice
? impl_from_IXAudio2Voice(pDestinationVoice
) : NULL
;
621 TRACE("%p, %p, %p, 0x%x\n", This
, pDestinationVoice
, pParameters
, OperationSet
);
623 return FAudioVoice_SetOutputFilterParameters(This
->faudio_voice
,
624 dst
? dst
->faudio_voice
: NULL
, (const FAudioFilterParameters
*)pParameters
, OperationSet
);
627 static void WINAPI
XA2SRC_GetOutputFilterParameters(IXAudio2SourceVoice
*iface
,
628 IXAudio2Voice
*pDestinationVoice
,
629 XAUDIO2_FILTER_PARAMETERS
*pParameters
)
631 XA2VoiceImpl
*This
= impl_from_IXAudio2SourceVoice(iface
);
632 XA2VoiceImpl
*dst
= pDestinationVoice
? impl_from_IXAudio2Voice(pDestinationVoice
) : NULL
;
634 TRACE("%p, %p, %p\n", This
, pDestinationVoice
, pParameters
);
636 FAudioVoice_GetOutputFilterParameters(This
->faudio_voice
,
637 dst
? dst
->faudio_voice
: NULL
, (FAudioFilterParameters
*)pParameters
);
640 static HRESULT WINAPI
XA2SRC_SetVolume(IXAudio2SourceVoice
*iface
, float Volume
,
643 XA2VoiceImpl
*This
= impl_from_IXAudio2SourceVoice(iface
);
644 TRACE("%p, %f, 0x%x\n", This
, Volume
, OperationSet
);
645 return FAudioVoice_SetVolume(This
->faudio_voice
, Volume
, OperationSet
);
648 static void WINAPI
XA2SRC_GetVolume(IXAudio2SourceVoice
*iface
, float *pVolume
)
650 XA2VoiceImpl
*This
= impl_from_IXAudio2SourceVoice(iface
);
651 TRACE("%p, %p\n", This
, pVolume
);
652 return FAudioVoice_GetVolume(This
->faudio_voice
, pVolume
);
655 static HRESULT WINAPI
XA2SRC_SetChannelVolumes(IXAudio2SourceVoice
*iface
, UINT32 Channels
,
656 const float *pVolumes
, UINT32 OperationSet
)
658 XA2VoiceImpl
*This
= impl_from_IXAudio2SourceVoice(iface
);
659 TRACE("%p, %u, %p, 0x%x\n", This
, Channels
, pVolumes
, OperationSet
);
660 return FAudioVoice_SetChannelVolumes(This
->faudio_voice
, Channels
,
661 pVolumes
, OperationSet
);
664 static void WINAPI
XA2SRC_GetChannelVolumes(IXAudio2SourceVoice
*iface
, UINT32 Channels
,
667 XA2VoiceImpl
*This
= impl_from_IXAudio2SourceVoice(iface
);
668 TRACE("%p, %u, %p\n", This
, Channels
, pVolumes
);
669 return FAudioVoice_GetChannelVolumes(This
->faudio_voice
, Channels
,
673 static HRESULT WINAPI
XA2SRC_SetOutputMatrix(IXAudio2SourceVoice
*iface
,
674 IXAudio2Voice
*pDestinationVoice
, UINT32 SourceChannels
,
675 UINT32 DestinationChannels
, const float *pLevelMatrix
,
678 XA2VoiceImpl
*This
= impl_from_IXAudio2SourceVoice(iface
);
679 XA2VoiceImpl
*dst
= pDestinationVoice
? impl_from_IXAudio2Voice(pDestinationVoice
) : NULL
;
681 TRACE("%p, %p, %u, %u, %p, 0x%x\n", This
, pDestinationVoice
,
682 SourceChannels
, DestinationChannels
, pLevelMatrix
, OperationSet
);
684 return FAudioVoice_SetOutputMatrix(This
->faudio_voice
, dst
? dst
->faudio_voice
: NULL
,
685 SourceChannels
, DestinationChannels
, pLevelMatrix
, OperationSet
);
688 static void WINAPI
XA2SRC_GetOutputMatrix(IXAudio2SourceVoice
*iface
,
689 IXAudio2Voice
*pDestinationVoice
, UINT32 SourceChannels
,
690 UINT32 DestinationChannels
, float *pLevelMatrix
)
692 XA2VoiceImpl
*This
= impl_from_IXAudio2SourceVoice(iface
);
693 XA2VoiceImpl
*dst
= pDestinationVoice
? impl_from_IXAudio2Voice(pDestinationVoice
) : NULL
;
695 TRACE("%p, %p, %u, %u, %p\n", This
, pDestinationVoice
,
696 SourceChannels
, DestinationChannels
, pLevelMatrix
);
698 FAudioVoice_GetOutputMatrix(This
->faudio_voice
, dst
? dst
->faudio_voice
: NULL
,
699 SourceChannels
, DestinationChannels
, pLevelMatrix
);
702 static void WINAPI
XA2SRC_DestroyVoice(IXAudio2SourceVoice
*iface
)
704 XA2VoiceImpl
*This
= impl_from_IXAudio2SourceVoice(iface
);
708 EnterCriticalSection(&This
->lock
);
712 LeaveCriticalSection(&This
->lock
);
715 static HRESULT WINAPI
XA2SRC_Start(IXAudio2SourceVoice
*iface
, UINT32 Flags
,
718 XA2VoiceImpl
*This
= impl_from_IXAudio2SourceVoice(iface
);
720 TRACE("%p, 0x%x, 0x%x\n", This
, Flags
, OperationSet
);
722 return FAudioSourceVoice_Start(This
->faudio_voice
, Flags
, OperationSet
);
725 static HRESULT WINAPI
XA2SRC_Stop(IXAudio2SourceVoice
*iface
, UINT32 Flags
,
728 XA2VoiceImpl
*This
= impl_from_IXAudio2SourceVoice(iface
);
730 TRACE("%p, 0x%x, 0x%x\n", This
, Flags
, OperationSet
);
732 return FAudioSourceVoice_Stop(This
->faudio_voice
, Flags
, OperationSet
);
735 static HRESULT WINAPI
XA2SRC_SubmitSourceBuffer(IXAudio2SourceVoice
*iface
,
736 const XAUDIO2_BUFFER
*pBuffer
, const XAUDIO2_BUFFER_WMA
*pBufferWMA
)
738 XA2VoiceImpl
*This
= impl_from_IXAudio2SourceVoice(iface
);
740 TRACE("%p, %p, %p\n", This
, pBuffer
, pBufferWMA
);
742 return FAudioSourceVoice_SubmitSourceBuffer(This
->faudio_voice
, (FAudioBuffer
*)pBuffer
, (FAudioBufferWMA
*)pBufferWMA
);
745 static HRESULT WINAPI
XA2SRC_FlushSourceBuffers(IXAudio2SourceVoice
*iface
)
747 XA2VoiceImpl
*This
= impl_from_IXAudio2SourceVoice(iface
);
751 return FAudioSourceVoice_FlushSourceBuffers(This
->faudio_voice
);
754 static HRESULT WINAPI
XA2SRC_Discontinuity(IXAudio2SourceVoice
*iface
)
756 XA2VoiceImpl
*This
= impl_from_IXAudio2SourceVoice(iface
);
760 return FAudioSourceVoice_Discontinuity(This
->faudio_voice
);
763 static HRESULT WINAPI
XA2SRC_ExitLoop(IXAudio2SourceVoice
*iface
, UINT32 OperationSet
)
765 XA2VoiceImpl
*This
= impl_from_IXAudio2SourceVoice(iface
);
767 TRACE("%p, 0x%x\n", This
, OperationSet
);
769 return FAudioSourceVoice_ExitLoop(This
->faudio_voice
, OperationSet
);
772 static void WINAPI
XA2SRC_GetState(IXAudio2SourceVoice
*iface
,
773 XAUDIO2_VOICE_STATE
*pVoiceState
, UINT32 Flags
)
775 XA2VoiceImpl
*This
= impl_from_IXAudio2SourceVoice(iface
);
777 TRACE("%p, %p, 0x%x\n", This
, pVoiceState
, Flags
);
779 return FAudioSourceVoice_GetState(This
->faudio_voice
, (FAudioVoiceState
*)pVoiceState
, Flags
);
782 static HRESULT WINAPI
XA2SRC_SetFrequencyRatio(IXAudio2SourceVoice
*iface
,
783 float Ratio
, UINT32 OperationSet
)
785 XA2VoiceImpl
*This
= impl_from_IXAudio2SourceVoice(iface
);
787 TRACE("%p, %f, 0x%x\n", This
, Ratio
, OperationSet
);
789 return FAudioSourceVoice_SetFrequencyRatio(This
->faudio_voice
, Ratio
, OperationSet
);
792 static void WINAPI
XA2SRC_GetFrequencyRatio(IXAudio2SourceVoice
*iface
, float *pRatio
)
794 XA2VoiceImpl
*This
= impl_from_IXAudio2SourceVoice(iface
);
796 TRACE("%p, %p\n", This
, pRatio
);
798 return FAudioSourceVoice_GetFrequencyRatio(This
->faudio_voice
, pRatio
);
801 static HRESULT WINAPI
XA2SRC_SetSourceSampleRate(
802 IXAudio2SourceVoice
*iface
,
803 UINT32 NewSourceSampleRate
)
805 XA2VoiceImpl
*This
= impl_from_IXAudio2SourceVoice(iface
);
807 TRACE("%p, %u\n", This
, NewSourceSampleRate
);
809 return FAudioSourceVoice_SetSourceSampleRate(This
->faudio_voice
, NewSourceSampleRate
);
812 static const IXAudio2SourceVoiceVtbl XAudio2SourceVoice_Vtbl
= {
813 XA2SRC_GetVoiceDetails
,
814 XA2SRC_SetOutputVoices
,
815 XA2SRC_SetEffectChain
,
817 XA2SRC_DisableEffect
,
818 XA2SRC_GetEffectState
,
819 XA2SRC_SetEffectParameters
,
820 XA2SRC_GetEffectParameters
,
821 XA2SRC_SetFilterParameters
,
822 XA2SRC_GetFilterParameters
,
823 XA2SRC_SetOutputFilterParameters
,
824 XA2SRC_GetOutputFilterParameters
,
827 XA2SRC_SetChannelVolumes
,
828 XA2SRC_GetChannelVolumes
,
829 XA2SRC_SetOutputMatrix
,
830 XA2SRC_GetOutputMatrix
,
834 XA2SRC_SubmitSourceBuffer
,
835 XA2SRC_FlushSourceBuffers
,
836 XA2SRC_Discontinuity
,
839 XA2SRC_SetFrequencyRatio
,
840 XA2SRC_GetFrequencyRatio
,
841 XA2SRC_SetSourceSampleRate
846 static inline XA2VoiceImpl
*impl_from_IXAudio2SubmixVoice(IXAudio2SubmixVoice
*iface
)
848 return CONTAINING_RECORD(iface
, XA2VoiceImpl
, IXAudio2SubmixVoice_iface
);
851 static void WINAPI
XA2SUB_GetVoiceDetails(IXAudio2SubmixVoice
*iface
,
852 XAUDIO2_VOICE_DETAILS
*pVoiceDetails
)
854 XA2VoiceImpl
*This
= impl_from_IXAudio2SubmixVoice(iface
);
855 TRACE("%p, %p\n", This
, pVoiceDetails
);
856 FAudioVoice_GetVoiceDetails(This
->faudio_voice
, (FAudioVoiceDetails
*)pVoiceDetails
);
859 static HRESULT WINAPI
XA2SUB_SetOutputVoices(IXAudio2SubmixVoice
*iface
,
860 const XAUDIO2_VOICE_SENDS
*pSendList
)
862 XA2VoiceImpl
*This
= impl_from_IXAudio2SubmixVoice(iface
);
863 FAudioVoiceSends
*faudio_sends
;
866 TRACE("%p, %p\n", This
, pSendList
);
868 faudio_sends
= wrap_voice_sends(pSendList
);
870 hr
= FAudioVoice_SetOutputVoices(This
->faudio_voice
, faudio_sends
);
872 free_voice_sends(faudio_sends
);
877 static HRESULT WINAPI
XA2SUB_SetEffectChain(IXAudio2SubmixVoice
*iface
,
878 const XAUDIO2_EFFECT_CHAIN
*pEffectChain
)
880 XA2VoiceImpl
*This
= impl_from_IXAudio2SubmixVoice(iface
);
883 TRACE("%p, %p\n", This
, pEffectChain
);
885 free_effect_chain(This
->effect_chain
);
886 This
->effect_chain
= wrap_effect_chain(pEffectChain
);
888 hr
= FAudioVoice_SetEffectChain(This
->faudio_voice
, This
->effect_chain
);
893 static HRESULT WINAPI
XA2SUB_EnableEffect(IXAudio2SubmixVoice
*iface
, UINT32 EffectIndex
,
896 XA2VoiceImpl
*This
= impl_from_IXAudio2SubmixVoice(iface
);
897 TRACE("%p, %u, 0x%x\n", This
, EffectIndex
, OperationSet
);
898 return FAudioVoice_EnableEffect(This
->faudio_voice
, EffectIndex
, OperationSet
);
901 static HRESULT WINAPI
XA2SUB_DisableEffect(IXAudio2SubmixVoice
*iface
, UINT32 EffectIndex
,
904 XA2VoiceImpl
*This
= impl_from_IXAudio2SubmixVoice(iface
);
905 TRACE("%p, %u, 0x%x\n", This
, EffectIndex
, OperationSet
);
906 return FAudioVoice_DisableEffect(This
->faudio_voice
, EffectIndex
, OperationSet
);
909 static void WINAPI
XA2SUB_GetEffectState(IXAudio2SubmixVoice
*iface
, UINT32 EffectIndex
,
912 XA2VoiceImpl
*This
= impl_from_IXAudio2SubmixVoice(iface
);
913 TRACE("%p, %u, %p\n", This
, EffectIndex
, pEnabled
);
914 FAudioVoice_GetEffectState(This
->faudio_voice
, EffectIndex
, (int32_t*)pEnabled
);
917 static HRESULT WINAPI
XA2SUB_SetEffectParameters(IXAudio2SubmixVoice
*iface
,
918 UINT32 EffectIndex
, const void *pParameters
, UINT32 ParametersByteSize
,
921 XA2VoiceImpl
*This
= impl_from_IXAudio2SubmixVoice(iface
);
922 TRACE("%p, %u, %p, 0x%x, 0x%x\n", This
, EffectIndex
, pParameters
,
923 ParametersByteSize
, OperationSet
);
924 return FAudioVoice_SetEffectParameters(This
->faudio_voice
, EffectIndex
,
925 pParameters
, ParametersByteSize
, OperationSet
);
928 static HRESULT WINAPI
XA2SUB_GetEffectParameters(IXAudio2SubmixVoice
*iface
,
929 UINT32 EffectIndex
, void *pParameters
, UINT32 ParametersByteSize
)
931 XA2VoiceImpl
*This
= impl_from_IXAudio2SubmixVoice(iface
);
932 TRACE("%p, %u, %p, 0x%x\n", This
, EffectIndex
, pParameters
,
934 return FAudioVoice_GetEffectParameters(This
->faudio_voice
, EffectIndex
,
935 pParameters
, ParametersByteSize
);
938 static HRESULT WINAPI
XA2SUB_SetFilterParameters(IXAudio2SubmixVoice
*iface
,
939 const XAUDIO2_FILTER_PARAMETERS
*pParameters
, UINT32 OperationSet
)
941 XA2VoiceImpl
*This
= impl_from_IXAudio2SubmixVoice(iface
);
942 TRACE("%p, %p, 0x%x\n", This
, pParameters
, OperationSet
);
943 return FAudioVoice_SetFilterParameters(This
->faudio_voice
, (const FAudioFilterParameters
*)pParameters
,
947 static void WINAPI
XA2SUB_GetFilterParameters(IXAudio2SubmixVoice
*iface
,
948 XAUDIO2_FILTER_PARAMETERS
*pParameters
)
950 XA2VoiceImpl
*This
= impl_from_IXAudio2SubmixVoice(iface
);
951 TRACE("%p, %p\n", This
, pParameters
);
952 FAudioVoice_GetFilterParameters(This
->faudio_voice
, (FAudioFilterParameters
*)pParameters
);
955 static HRESULT WINAPI
XA2SUB_SetOutputFilterParameters(IXAudio2SubmixVoice
*iface
,
956 IXAudio2Voice
*pDestinationVoice
,
957 const XAUDIO2_FILTER_PARAMETERS
*pParameters
, UINT32 OperationSet
)
959 XA2VoiceImpl
*This
= impl_from_IXAudio2SubmixVoice(iface
);
960 XA2VoiceImpl
*dst
= pDestinationVoice
? impl_from_IXAudio2Voice(pDestinationVoice
) : NULL
;
962 TRACE("%p, %p, %p, 0x%x\n", This
, pDestinationVoice
, pParameters
, OperationSet
);
964 return FAudioVoice_SetOutputFilterParameters(This
->faudio_voice
,
965 dst
? dst
->faudio_voice
: NULL
, (const FAudioFilterParameters
*)pParameters
, OperationSet
);
968 static void WINAPI
XA2SUB_GetOutputFilterParameters(IXAudio2SubmixVoice
*iface
,
969 IXAudio2Voice
*pDestinationVoice
,
970 XAUDIO2_FILTER_PARAMETERS
*pParameters
)
972 XA2VoiceImpl
*This
= impl_from_IXAudio2SubmixVoice(iface
);
973 XA2VoiceImpl
*dst
= pDestinationVoice
? impl_from_IXAudio2Voice(pDestinationVoice
) : NULL
;
975 TRACE("%p, %p, %p\n", This
, pDestinationVoice
, pParameters
);
977 FAudioVoice_GetOutputFilterParameters(This
->faudio_voice
,
978 dst
? dst
->faudio_voice
: NULL
, (FAudioFilterParameters
*)pParameters
);
981 static HRESULT WINAPI
XA2SUB_SetVolume(IXAudio2SubmixVoice
*iface
, float Volume
,
984 XA2VoiceImpl
*This
= impl_from_IXAudio2SubmixVoice(iface
);
985 TRACE("%p, %f, 0x%x\n", This
, Volume
, OperationSet
);
986 return FAudioVoice_SetVolume(This
->faudio_voice
, Volume
, OperationSet
);
989 static void WINAPI
XA2SUB_GetVolume(IXAudio2SubmixVoice
*iface
, float *pVolume
)
991 XA2VoiceImpl
*This
= impl_from_IXAudio2SubmixVoice(iface
);
992 TRACE("%p, %p\n", This
, pVolume
);
993 return FAudioVoice_GetVolume(This
->faudio_voice
, pVolume
);
996 static HRESULT WINAPI
XA2SUB_SetChannelVolumes(IXAudio2SubmixVoice
*iface
, UINT32 Channels
,
997 const float *pVolumes
, UINT32 OperationSet
)
999 XA2VoiceImpl
*This
= impl_from_IXAudio2SubmixVoice(iface
);
1000 TRACE("%p, %u, %p, 0x%x\n", This
, Channels
, pVolumes
, OperationSet
);
1001 return FAudioVoice_SetChannelVolumes(This
->faudio_voice
, Channels
,
1002 pVolumes
, OperationSet
);
1005 static void WINAPI
XA2SUB_GetChannelVolumes(IXAudio2SubmixVoice
*iface
, UINT32 Channels
,
1008 XA2VoiceImpl
*This
= impl_from_IXAudio2SubmixVoice(iface
);
1009 TRACE("%p, %u, %p\n", This
, Channels
, pVolumes
);
1010 return FAudioVoice_GetChannelVolumes(This
->faudio_voice
, Channels
,
1014 static HRESULT WINAPI
XA2SUB_SetOutputMatrix(IXAudio2SubmixVoice
*iface
,
1015 IXAudio2Voice
*pDestinationVoice
, UINT32 SourceChannels
,
1016 UINT32 DestinationChannels
, const float *pLevelMatrix
,
1017 UINT32 OperationSet
)
1019 XA2VoiceImpl
*This
= impl_from_IXAudio2SubmixVoice(iface
);
1020 XA2VoiceImpl
*dst
= pDestinationVoice
? impl_from_IXAudio2Voice(pDestinationVoice
) : NULL
;
1022 TRACE("%p, %p, %u, %u, %p, 0x%x\n", This
, pDestinationVoice
,
1023 SourceChannels
, DestinationChannels
, pLevelMatrix
, OperationSet
);
1025 return FAudioVoice_SetOutputMatrix(This
->faudio_voice
, dst
? dst
->faudio_voice
: NULL
,
1026 SourceChannels
, DestinationChannels
, pLevelMatrix
, OperationSet
);
1029 static void WINAPI
XA2SUB_GetOutputMatrix(IXAudio2SubmixVoice
*iface
,
1030 IXAudio2Voice
*pDestinationVoice
, UINT32 SourceChannels
,
1031 UINT32 DestinationChannels
, float *pLevelMatrix
)
1033 XA2VoiceImpl
*This
= impl_from_IXAudio2SubmixVoice(iface
);
1034 XA2VoiceImpl
*dst
= pDestinationVoice
? impl_from_IXAudio2Voice(pDestinationVoice
) : NULL
;
1036 TRACE("%p, %p, %u, %u, %p\n", This
, pDestinationVoice
,
1037 SourceChannels
, DestinationChannels
, pLevelMatrix
);
1039 FAudioVoice_GetOutputMatrix(This
->faudio_voice
, dst
? dst
->faudio_voice
: NULL
,
1040 SourceChannels
, DestinationChannels
, pLevelMatrix
);
1043 static void WINAPI
XA2SUB_DestroyVoice(IXAudio2SubmixVoice
*iface
)
1045 XA2VoiceImpl
*This
= impl_from_IXAudio2SubmixVoice(iface
);
1047 TRACE("%p\n", This
);
1049 EnterCriticalSection(&This
->lock
);
1051 destroy_voice(This
);
1053 LeaveCriticalSection(&This
->lock
);
1056 static const struct IXAudio2SubmixVoiceVtbl XAudio2SubmixVoice_Vtbl
= {
1057 XA2SUB_GetVoiceDetails
,
1058 XA2SUB_SetOutputVoices
,
1059 XA2SUB_SetEffectChain
,
1060 XA2SUB_EnableEffect
,
1061 XA2SUB_DisableEffect
,
1062 XA2SUB_GetEffectState
,
1063 XA2SUB_SetEffectParameters
,
1064 XA2SUB_GetEffectParameters
,
1065 XA2SUB_SetFilterParameters
,
1066 XA2SUB_GetFilterParameters
,
1067 XA2SUB_SetOutputFilterParameters
,
1068 XA2SUB_GetOutputFilterParameters
,
1071 XA2SUB_SetChannelVolumes
,
1072 XA2SUB_GetChannelVolumes
,
1073 XA2SUB_SetOutputMatrix
,
1074 XA2SUB_GetOutputMatrix
,
1078 /* Mastering Voices */
1080 static inline XA2VoiceImpl
*impl_from_IXAudio2MasteringVoice(IXAudio2MasteringVoice
*iface
)
1082 return CONTAINING_RECORD(iface
, XA2VoiceImpl
, IXAudio2MasteringVoice_iface
);
1085 static void WINAPI
XA2M_GetVoiceDetails(IXAudio2MasteringVoice
*iface
,
1086 XAUDIO2_VOICE_DETAILS
*pVoiceDetails
)
1088 XA2VoiceImpl
*This
= impl_from_IXAudio2MasteringVoice(iface
);
1089 TRACE("%p, %p\n", This
, pVoiceDetails
);
1090 FAudioVoice_GetVoiceDetails(This
->faudio_voice
, (FAudioVoiceDetails
*)pVoiceDetails
);
1093 static HRESULT WINAPI
XA2M_SetOutputVoices(IXAudio2MasteringVoice
*iface
,
1094 const XAUDIO2_VOICE_SENDS
*pSendList
)
1096 XA2VoiceImpl
*This
= impl_from_IXAudio2MasteringVoice(iface
);
1097 FAudioVoiceSends
*faudio_sends
;
1100 TRACE("%p, %p\n", This
, pSendList
);
1102 faudio_sends
= wrap_voice_sends(pSendList
);
1104 hr
= FAudioVoice_SetOutputVoices(This
->faudio_voice
, faudio_sends
);
1106 free_voice_sends(faudio_sends
);
1111 static HRESULT WINAPI
XA2M_SetEffectChain(IXAudio2MasteringVoice
*iface
,
1112 const XAUDIO2_EFFECT_CHAIN
*pEffectChain
)
1114 XA2VoiceImpl
*This
= impl_from_IXAudio2MasteringVoice(iface
);
1117 TRACE("%p, %p\n", This
, pEffectChain
);
1119 free_effect_chain(This
->effect_chain
);
1120 This
->effect_chain
= wrap_effect_chain(pEffectChain
);
1122 hr
= FAudioVoice_SetEffectChain(This
->faudio_voice
, This
->effect_chain
);
1127 static HRESULT WINAPI
XA2M_EnableEffect(IXAudio2MasteringVoice
*iface
, UINT32 EffectIndex
,
1128 UINT32 OperationSet
)
1130 XA2VoiceImpl
*This
= impl_from_IXAudio2MasteringVoice(iface
);
1131 TRACE("%p, %u, 0x%x\n", This
, EffectIndex
, OperationSet
);
1132 return FAudioVoice_EnableEffect(This
->faudio_voice
, EffectIndex
, OperationSet
);
1135 static HRESULT WINAPI
XA2M_DisableEffect(IXAudio2MasteringVoice
*iface
, UINT32 EffectIndex
,
1136 UINT32 OperationSet
)
1138 XA2VoiceImpl
*This
= impl_from_IXAudio2MasteringVoice(iface
);
1139 TRACE("%p, %u, 0x%x\n", This
, EffectIndex
, OperationSet
);
1140 return FAudioVoice_DisableEffect(This
->faudio_voice
, EffectIndex
, OperationSet
);
1143 static void WINAPI
XA2M_GetEffectState(IXAudio2MasteringVoice
*iface
, UINT32 EffectIndex
,
1146 XA2VoiceImpl
*This
= impl_from_IXAudio2MasteringVoice(iface
);
1147 TRACE("%p, %u, %p\n", This
, EffectIndex
, pEnabled
);
1148 FAudioVoice_GetEffectState(This
->faudio_voice
, EffectIndex
, (int32_t*)pEnabled
);
1151 static HRESULT WINAPI
XA2M_SetEffectParameters(IXAudio2MasteringVoice
*iface
,
1152 UINT32 EffectIndex
, const void *pParameters
, UINT32 ParametersByteSize
,
1153 UINT32 OperationSet
)
1155 XA2VoiceImpl
*This
= impl_from_IXAudio2MasteringVoice(iface
);
1156 TRACE("%p, %u, %p, 0x%x, 0x%x\n", This
, EffectIndex
, pParameters
,
1157 ParametersByteSize
, OperationSet
);
1158 return FAudioVoice_SetEffectParameters(This
->faudio_voice
, EffectIndex
,
1159 pParameters
, ParametersByteSize
, OperationSet
);
1162 static HRESULT WINAPI
XA2M_GetEffectParameters(IXAudio2MasteringVoice
*iface
,
1163 UINT32 EffectIndex
, void *pParameters
, UINT32 ParametersByteSize
)
1165 XA2VoiceImpl
*This
= impl_from_IXAudio2MasteringVoice(iface
);
1166 TRACE("%p, %u, %p, 0x%x\n", This
, EffectIndex
, pParameters
,
1167 ParametersByteSize
);
1168 return FAudioVoice_GetEffectParameters(This
->faudio_voice
, EffectIndex
,
1169 pParameters
, ParametersByteSize
);
1172 static HRESULT WINAPI
XA2M_SetFilterParameters(IXAudio2MasteringVoice
*iface
,
1173 const XAUDIO2_FILTER_PARAMETERS
*pParameters
, UINT32 OperationSet
)
1175 XA2VoiceImpl
*This
= impl_from_IXAudio2MasteringVoice(iface
);
1176 TRACE("%p, %p, 0x%x\n", This
, pParameters
, OperationSet
);
1177 return FAudioVoice_SetFilterParameters(This
->faudio_voice
, (const FAudioFilterParameters
*)pParameters
,
1181 static void WINAPI
XA2M_GetFilterParameters(IXAudio2MasteringVoice
*iface
,
1182 XAUDIO2_FILTER_PARAMETERS
*pParameters
)
1184 XA2VoiceImpl
*This
= impl_from_IXAudio2MasteringVoice(iface
);
1185 TRACE("%p, %p\n", This
, pParameters
);
1186 FAudioVoice_GetFilterParameters(This
->faudio_voice
, (FAudioFilterParameters
*)pParameters
);
1189 static HRESULT WINAPI
XA2M_SetOutputFilterParameters(IXAudio2MasteringVoice
*iface
,
1190 IXAudio2Voice
*pDestinationVoice
,
1191 const XAUDIO2_FILTER_PARAMETERS
*pParameters
, UINT32 OperationSet
)
1193 XA2VoiceImpl
*This
= impl_from_IXAudio2MasteringVoice(iface
);
1194 XA2VoiceImpl
*dst
= pDestinationVoice
? impl_from_IXAudio2Voice(pDestinationVoice
) : NULL
;
1196 TRACE("%p, %p, %p, 0x%x\n", This
, pDestinationVoice
, pParameters
, OperationSet
);
1198 return FAudioVoice_SetOutputFilterParameters(This
->faudio_voice
,
1199 dst
? dst
->faudio_voice
: NULL
, (const FAudioFilterParameters
*)pParameters
, OperationSet
);
1202 static void WINAPI
XA2M_GetOutputFilterParameters(IXAudio2MasteringVoice
*iface
,
1203 IXAudio2Voice
*pDestinationVoice
,
1204 XAUDIO2_FILTER_PARAMETERS
*pParameters
)
1206 XA2VoiceImpl
*This
= impl_from_IXAudio2MasteringVoice(iface
);
1207 XA2VoiceImpl
*dst
= pDestinationVoice
? impl_from_IXAudio2Voice(pDestinationVoice
) : NULL
;
1209 TRACE("%p, %p, %p\n", This
, pDestinationVoice
, pParameters
);
1211 FAudioVoice_GetOutputFilterParameters(This
->faudio_voice
,
1212 dst
? dst
->faudio_voice
: NULL
, (FAudioFilterParameters
*)pParameters
);
1215 static HRESULT WINAPI
XA2M_SetVolume(IXAudio2MasteringVoice
*iface
, float Volume
,
1216 UINT32 OperationSet
)
1218 XA2VoiceImpl
*This
= impl_from_IXAudio2MasteringVoice(iface
);
1219 TRACE("%p, %f, 0x%x\n", This
, Volume
, OperationSet
);
1220 return FAudioVoice_SetVolume(This
->faudio_voice
, Volume
, OperationSet
);
1223 static void WINAPI
XA2M_GetVolume(IXAudio2MasteringVoice
*iface
, float *pVolume
)
1225 XA2VoiceImpl
*This
= impl_from_IXAudio2MasteringVoice(iface
);
1226 TRACE("%p, %p\n", This
, pVolume
);
1227 return FAudioVoice_GetVolume(This
->faudio_voice
, pVolume
);
1230 static HRESULT WINAPI
XA2M_SetChannelVolumes(IXAudio2MasteringVoice
*iface
, UINT32 Channels
,
1231 const float *pVolumes
, UINT32 OperationSet
)
1233 XA2VoiceImpl
*This
= impl_from_IXAudio2MasteringVoice(iface
);
1234 TRACE("%p, %u, %p, 0x%x\n", This
, Channels
, pVolumes
, OperationSet
);
1235 return FAudioVoice_SetChannelVolumes(This
->faudio_voice
, Channels
,
1236 pVolumes
, OperationSet
);
1239 static void WINAPI
XA2M_GetChannelVolumes(IXAudio2MasteringVoice
*iface
, UINT32 Channels
,
1242 XA2VoiceImpl
*This
= impl_from_IXAudio2MasteringVoice(iface
);
1243 TRACE("%p, %u, %p\n", This
, Channels
, pVolumes
);
1244 return FAudioVoice_GetChannelVolumes(This
->faudio_voice
, Channels
,
1248 static HRESULT WINAPI
XA2M_SetOutputMatrix(IXAudio2MasteringVoice
*iface
,
1249 IXAudio2Voice
*pDestinationVoice
, UINT32 SourceChannels
,
1250 UINT32 DestinationChannels
, const float *pLevelMatrix
,
1251 UINT32 OperationSet
)
1253 XA2VoiceImpl
*This
= impl_from_IXAudio2MasteringVoice(iface
);
1254 XA2VoiceImpl
*dst
= pDestinationVoice
? impl_from_IXAudio2Voice(pDestinationVoice
) : NULL
;
1256 TRACE("%p, %p, %u, %u, %p, 0x%x\n", This
, pDestinationVoice
,
1257 SourceChannels
, DestinationChannels
, pLevelMatrix
, OperationSet
);
1259 return FAudioVoice_SetOutputMatrix(This
->faudio_voice
, dst
? dst
->faudio_voice
: NULL
,
1260 SourceChannels
, DestinationChannels
, pLevelMatrix
, OperationSet
);
1263 static void WINAPI
XA2M_GetOutputMatrix(IXAudio2MasteringVoice
*iface
,
1264 IXAudio2Voice
*pDestinationVoice
, UINT32 SourceChannels
,
1265 UINT32 DestinationChannels
, float *pLevelMatrix
)
1267 XA2VoiceImpl
*This
= impl_from_IXAudio2MasteringVoice(iface
);
1268 XA2VoiceImpl
*dst
= pDestinationVoice
? impl_from_IXAudio2Voice(pDestinationVoice
) : NULL
;
1270 TRACE("%p, %p, %u, %u, %p\n", This
, pDestinationVoice
,
1271 SourceChannels
, DestinationChannels
, pLevelMatrix
);
1273 FAudioVoice_GetOutputMatrix(This
->faudio_voice
, dst
? dst
->faudio_voice
: NULL
,
1274 SourceChannels
, DestinationChannels
, pLevelMatrix
);
1277 static void WINAPI
XA2M_DestroyVoice(IXAudio2MasteringVoice
*iface
)
1279 XA2VoiceImpl
*This
= impl_from_IXAudio2MasteringVoice(iface
);
1281 TRACE("%p\n", This
);
1283 EnterCriticalSection(&This
->lock
);
1285 destroy_voice(This
);
1286 pthread_mutex_lock(&This
->engine_lock
);
1287 This
->engine_params
.proc
= NULL
;
1288 pthread_cond_broadcast(&This
->engine_ready
);
1289 pthread_mutex_unlock(&This
->engine_lock
);
1291 WaitForSingleObject(This
->engine_thread
, INFINITE
);
1292 This
->engine_thread
= NULL
;
1294 LeaveCriticalSection(&This
->lock
);
1297 static void WINAPI
XA2M_GetChannelMask(IXAudio2MasteringVoice
*iface
,
1298 DWORD
*pChannelMask
)
1300 XA2VoiceImpl
*This
= impl_from_IXAudio2MasteringVoice(iface
);
1302 TRACE("%p, %p\n", This
, pChannelMask
);
1304 FAudioMasteringVoice_GetChannelMask(This
->faudio_voice
, pChannelMask
);
1307 static const struct IXAudio2MasteringVoiceVtbl XAudio2MasteringVoice_Vtbl
= {
1308 XA2M_GetVoiceDetails
,
1309 XA2M_SetOutputVoices
,
1310 XA2M_SetEffectChain
,
1313 XA2M_GetEffectState
,
1314 XA2M_SetEffectParameters
,
1315 XA2M_GetEffectParameters
,
1316 XA2M_SetFilterParameters
,
1317 XA2M_GetFilterParameters
,
1318 XA2M_SetOutputFilterParameters
,
1319 XA2M_GetOutputFilterParameters
,
1322 XA2M_SetChannelVolumes
,
1323 XA2M_GetChannelVolumes
,
1324 XA2M_SetOutputMatrix
,
1325 XA2M_GetOutputMatrix
,
1330 /* More Common Voice Functions */
1332 static XA2VoiceImpl
*impl_from_IXAudio2Voice(IXAudio2Voice
*iface
)
1334 if(iface
->lpVtbl
== (void*)&XAudio2SourceVoice_Vtbl
)
1335 return impl_from_IXAudio2SourceVoice((IXAudio2SourceVoice
*)iface
);
1336 if(iface
->lpVtbl
== (void*)&XAudio2MasteringVoice_Vtbl
)
1337 return impl_from_IXAudio2MasteringVoice((IXAudio2MasteringVoice
*)iface
);
1338 if(iface
->lpVtbl
== (void*)&XAudio2SubmixVoice_Vtbl
)
1339 return impl_from_IXAudio2SubmixVoice((IXAudio2SubmixVoice
*)iface
);
1340 #if XAUDIO2_VER == 0
1341 if(iface
->lpVtbl
== (void*)&XAudio20SourceVoice_Vtbl
)
1342 return impl_from_IXAudio20SourceVoice((IXAudio20SourceVoice
*)iface
);
1343 if(iface
->lpVtbl
== (void*)&XAudio20SubmixVoice_Vtbl
)
1344 return impl_from_IXAudio20SubmixVoice((IXAudio20SubmixVoice
*)iface
);
1345 if(iface
->lpVtbl
== (void*)&XAudio20MasteringVoice_Vtbl
)
1346 return impl_from_IXAudio20MasteringVoice((IXAudio20MasteringVoice
*)iface
);
1347 #elif XAUDIO2_VER <= 3
1348 if(iface
->lpVtbl
== (void*)&XAudio23SourceVoice_Vtbl
)
1349 return impl_from_IXAudio23SourceVoice((IXAudio23SourceVoice
*)iface
);
1350 if(iface
->lpVtbl
== (void*)&XAudio23SubmixVoice_Vtbl
)
1351 return impl_from_IXAudio23SubmixVoice((IXAudio23SubmixVoice
*)iface
);
1352 if(iface
->lpVtbl
== (void*)&XAudio23MasteringVoice_Vtbl
)
1353 return impl_from_IXAudio23MasteringVoice((IXAudio23MasteringVoice
*)iface
);
1354 #elif XAUDIO2_VER <= 7
1355 if(iface
->lpVtbl
== (void*)&XAudio27SourceVoice_Vtbl
)
1356 return impl_from_IXAudio27SourceVoice((IXAudio27SourceVoice
*)iface
);
1357 if(iface
->lpVtbl
== (void*)&XAudio27SubmixVoice_Vtbl
)
1358 return impl_from_IXAudio27SubmixVoice((IXAudio27SubmixVoice
*)iface
);
1359 if(iface
->lpVtbl
== (void*)&XAudio27MasteringVoice_Vtbl
)
1360 return impl_from_IXAudio27MasteringVoice((IXAudio27MasteringVoice
*)iface
);
1362 ERR("invalid IXAudio2Voice pointer: %p\n", iface
);
1366 /* XAudio2 Engine Implementation */
1368 static inline IXAudio2Impl
*impl_from_IXAudio2(IXAudio2
*iface
)
1370 return CONTAINING_RECORD(iface
, IXAudio2Impl
, IXAudio2_iface
);
1373 static HRESULT WINAPI
IXAudio2Impl_QueryInterface(IXAudio2
*iface
, REFIID riid
,
1376 IXAudio2Impl
*This
= impl_from_IXAudio2(iface
);
1378 TRACE("(%p)->(%s, %p)\n", This
, debugstr_guid(riid
), ppvObject
);
1380 if(IsEqualGUID(riid
, &IID_IUnknown
) ||
1381 #if XAUDIO2_VER == 8
1382 IsEqualGUID(riid
, &IID_IXAudio28
) ||
1384 IsEqualGUID(riid
, &IID_IXAudio2
))
1385 *ppvObject
= &This
->IXAudio2_iface
;
1386 else if(IsEqualGUID(riid
, &IID_IXAudio27
)){
1387 /* all xaudio versions before 28 share an IID */
1388 #if XAUDIO2_VER == 0
1389 *ppvObject
= &This
->IXAudio20_iface
;
1390 #elif XAUDIO2_VER <= 2
1391 *ppvObject
= &This
->IXAudio22_iface
;
1392 #elif XAUDIO2_VER <= 3
1393 *ppvObject
= &This
->IXAudio23_iface
;
1394 #elif XAUDIO2_VER <= 7
1395 *ppvObject
= &This
->IXAudio27_iface
;
1403 IUnknown_AddRef((IUnknown
*)*ppvObject
);
1407 FIXME("(%p)->(%s,%p), not found\n", This
,debugstr_guid(riid
), ppvObject
);
1409 return E_NOINTERFACE
;
1412 static ULONG WINAPI
IXAudio2Impl_AddRef(IXAudio2
*iface
)
1414 IXAudio2Impl
*This
= impl_from_IXAudio2(iface
);
1415 ULONG ref
= FAudio_AddRef(This
->faudio
);
1416 TRACE("(%p)->(): Refcount now %u\n", This
, ref
);
1420 static ULONG WINAPI
IXAudio2Impl_Release(IXAudio2
*iface
)
1422 IXAudio2Impl
*This
= impl_from_IXAudio2(iface
);
1423 ULONG ref
= FAudio_Release(This
->faudio
);
1425 TRACE("(%p)->(): Refcount now %u\n", This
, ref
);
1428 XA2VoiceImpl
*v
, *v2
;
1430 LIST_FOR_EACH_ENTRY_SAFE(v
, v2
, &This
->voices
, XA2VoiceImpl
, entry
){
1431 v
->lock
.DebugInfo
->Spare
[0] = 0;
1432 DeleteCriticalSection(&v
->lock
);
1433 HeapFree(GetProcessHeap(), 0, v
);
1436 HeapFree(GetProcessHeap(), 0, This
->cbs
);
1438 This
->lock
.DebugInfo
->Spare
[0] = 0;
1439 DeleteCriticalSection(&This
->lock
);
1441 HeapFree(GetProcessHeap(), 0, This
);
1446 static HRESULT WINAPI
IXAudio2Impl_RegisterForCallbacks(IXAudio2
*iface
,
1447 IXAudio2EngineCallback
*pCallback
)
1449 IXAudio2Impl
*This
= impl_from_IXAudio2(iface
);
1452 TRACE("(%p)->(%p)\n", This
, pCallback
);
1454 EnterCriticalSection(&This
->lock
);
1456 for(i
= 0; i
< This
->ncbs
; ++i
){
1457 if(!This
->cbs
[i
] || This
->cbs
[i
] == pCallback
){
1458 This
->cbs
[i
] = pCallback
;
1459 LeaveCriticalSection(&This
->lock
);
1465 This
->cbs
= heap_realloc(This
->cbs
, This
->ncbs
* sizeof(*This
->cbs
));
1467 This
->cbs
[i
] = pCallback
;
1469 LeaveCriticalSection(&This
->lock
);
1474 static void WINAPI
IXAudio2Impl_UnregisterForCallbacks(IXAudio2
*iface
,
1475 IXAudio2EngineCallback
*pCallback
)
1477 IXAudio2Impl
*This
= impl_from_IXAudio2(iface
);
1480 TRACE("(%p)->(%p)\n", This
, pCallback
);
1482 EnterCriticalSection(&This
->lock
);
1484 if(This
->ncbs
== 0){
1485 LeaveCriticalSection(&This
->lock
);
1489 for(i
= 0; i
< This
->ncbs
; ++i
){
1490 if(This
->cbs
[i
] == pCallback
)
1494 for(; i
< This
->ncbs
- 1 && This
->cbs
[i
+ 1]; ++i
)
1495 This
->cbs
[i
] = This
->cbs
[i
+ 1];
1498 This
->cbs
[i
] = NULL
;
1500 LeaveCriticalSection(&This
->lock
);
1503 static inline XA2VoiceImpl
*create_voice(IXAudio2Impl
*This
)
1505 XA2VoiceImpl
*voice
;
1507 voice
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(*voice
));
1511 list_add_head(&This
->voices
, &voice
->entry
);
1513 voice
->IXAudio2SourceVoice_iface
.lpVtbl
= &XAudio2SourceVoice_Vtbl
;
1514 #if XAUDIO2_VER == 0
1515 voice
->IXAudio20SourceVoice_iface
.lpVtbl
= &XAudio20SourceVoice_Vtbl
;
1516 #elif XAUDIO2_VER <= 3
1517 voice
->IXAudio23SourceVoice_iface
.lpVtbl
= &XAudio23SourceVoice_Vtbl
;
1518 #elif XAUDIO2_VER <= 7
1519 voice
->IXAudio27SourceVoice_iface
.lpVtbl
= &XAudio27SourceVoice_Vtbl
;
1522 voice
->IXAudio2SubmixVoice_iface
.lpVtbl
= &XAudio2SubmixVoice_Vtbl
;
1523 #if XAUDIO2_VER == 0
1524 voice
->IXAudio20SubmixVoice_iface
.lpVtbl
= &XAudio20SubmixVoice_Vtbl
;
1525 #elif XAUDIO2_VER <= 3
1526 voice
->IXAudio23SubmixVoice_iface
.lpVtbl
= &XAudio23SubmixVoice_Vtbl
;
1527 #elif XAUDIO2_VER <= 7
1528 voice
->IXAudio27SubmixVoice_iface
.lpVtbl
= &XAudio27SubmixVoice_Vtbl
;
1531 voice
->FAudioVoiceCallback_vtbl
= FAudioVoiceCallback_Vtbl
;
1533 InitializeCriticalSection(&voice
->lock
);
1534 voice
->lock
.DebugInfo
->Spare
[0] = (DWORD_PTR
)(__FILE__
": XA2VoiceImpl.lock");
1539 static HRESULT WINAPI
IXAudio2Impl_CreateSourceVoice(IXAudio2
*iface
,
1540 IXAudio2SourceVoice
**ppSourceVoice
, const WAVEFORMATEX
*pSourceFormat
,
1541 UINT32 flags
, float maxFrequencyRatio
,
1542 IXAudio2VoiceCallback
*pCallback
, const XAUDIO2_VOICE_SENDS
*pSendList
,
1543 const XAUDIO2_EFFECT_CHAIN
*pEffectChain
)
1545 IXAudio2Impl
*This
= impl_from_IXAudio2(iface
);
1548 FAudioVoiceSends
*faudio_sends
;
1550 TRACE("(%p)->(%p, %p, 0x%x, %f, %p, %p, %p)\n", This
, ppSourceVoice
,
1551 pSourceFormat
, flags
, maxFrequencyRatio
, pCallback
, pSendList
,
1554 EnterCriticalSection(&This
->lock
);
1556 LIST_FOR_EACH_ENTRY(src
, &This
->voices
, XA2VoiceImpl
, entry
){
1557 EnterCriticalSection(&src
->lock
);
1560 LeaveCriticalSection(&src
->lock
);
1563 if(&src
->entry
== &This
->voices
){
1564 src
= create_voice(This
);
1565 EnterCriticalSection(&src
->lock
);
1568 LeaveCriticalSection(&This
->lock
);
1570 src
->effect_chain
= wrap_effect_chain(pEffectChain
);
1571 faudio_sends
= wrap_voice_sends(pSendList
);
1573 hr
= FAudio_CreateSourceVoice(This
->faudio
, &src
->faudio_voice
,
1574 (FAudioWaveFormatEx
*)pSourceFormat
, flags
, maxFrequencyRatio
,
1575 &src
->FAudioVoiceCallback_vtbl
, faudio_sends
,
1577 free_voice_sends(faudio_sends
);
1579 LeaveCriticalSection(&This
->lock
);
1583 src
->cb
= pCallback
;
1585 LeaveCriticalSection(&src
->lock
);
1587 #if XAUDIO2_VER == 0
1588 *ppSourceVoice
= (IXAudio2SourceVoice
*)&src
->IXAudio20SourceVoice_iface
;
1589 #elif XAUDIO2_VER <= 3
1590 *ppSourceVoice
= (IXAudio2SourceVoice
*)&src
->IXAudio23SourceVoice_iface
;
1591 #elif XAUDIO2_VER <= 7
1592 *ppSourceVoice
= (IXAudio2SourceVoice
*)&src
->IXAudio27SourceVoice_iface
;
1594 *ppSourceVoice
= &src
->IXAudio2SourceVoice_iface
;
1597 TRACE("Created source voice: %p\n", src
);
1602 static HRESULT WINAPI
IXAudio2Impl_CreateSubmixVoice(IXAudio2
*iface
,
1603 IXAudio2SubmixVoice
**ppSubmixVoice
, UINT32 inputChannels
,
1604 UINT32 inputSampleRate
, UINT32 flags
, UINT32 processingStage
,
1605 const XAUDIO2_VOICE_SENDS
*pSendList
,
1606 const XAUDIO2_EFFECT_CHAIN
*pEffectChain
)
1609 IXAudio2Impl
*This
= impl_from_IXAudio2(iface
);
1611 FAudioVoiceSends
*faudio_sends
;
1613 TRACE("(%p)->(%p, %u, %u, 0x%x, %u, %p, %p)\n", This
, ppSubmixVoice
,
1614 inputChannels
, inputSampleRate
, flags
, processingStage
, pSendList
,
1617 EnterCriticalSection(&This
->lock
);
1619 LIST_FOR_EACH_ENTRY(sub
, &This
->voices
, XA2VoiceImpl
, entry
){
1620 EnterCriticalSection(&sub
->lock
);
1623 LeaveCriticalSection(&sub
->lock
);
1626 if(&sub
->entry
== &This
->voices
){
1627 sub
= create_voice(This
);
1628 EnterCriticalSection(&sub
->lock
);
1631 LeaveCriticalSection(&This
->lock
);
1633 sub
->effect_chain
= wrap_effect_chain(pEffectChain
);
1634 faudio_sends
= wrap_voice_sends(pSendList
);
1636 hr
= FAudio_CreateSubmixVoice(This
->faudio
, &sub
->faudio_voice
, inputChannels
,
1637 inputSampleRate
, flags
, processingStage
, faudio_sends
,
1639 free_voice_sends(faudio_sends
);
1641 LeaveCriticalSection(&sub
->lock
);
1646 LeaveCriticalSection(&sub
->lock
);
1648 #if XAUDIO2_VER == 0
1649 *ppSubmixVoice
= (IXAudio2SubmixVoice
*)&sub
->IXAudio20SubmixVoice_iface
;
1650 #elif XAUDIO2_VER <= 3
1651 *ppSubmixVoice
= (IXAudio2SubmixVoice
*)&sub
->IXAudio23SubmixVoice_iface
;
1652 #elif XAUDIO2_VER <= 7
1653 *ppSubmixVoice
= (IXAudio2SubmixVoice
*)&sub
->IXAudio27SubmixVoice_iface
;
1655 *ppSubmixVoice
= &sub
->IXAudio2SubmixVoice_iface
;
1658 TRACE("Created submix voice: %p\n", sub
);
1663 /* called thread created by SDL, must not access Wine TEB */
1664 void engine_cb(FAudioEngineCallEXT proc
, FAudio
*faudio
, float *stream
, void *user
)
1666 XA2VoiceImpl
*This
= user
;
1668 pthread_mutex_lock(&This
->engine_lock
);
1670 This
->engine_params
.proc
= proc
;
1671 This
->engine_params
.stream
= stream
;
1672 This
->engine_params
.faudio
= faudio
;
1674 pthread_cond_broadcast(&This
->engine_ready
);
1676 while(This
->engine_params
.proc
)
1677 pthread_cond_wait(&This
->engine_done
, &This
->engine_lock
);
1679 pthread_mutex_unlock(&This
->engine_lock
);
1682 /* wine thread, OK to access TEB, invoke client code, etc */
1683 DWORD WINAPI
engine_thread(void *user
)
1685 XA2VoiceImpl
*This
= user
;
1687 pthread_mutex_lock(&This
->engine_lock
);
1689 pthread_cond_broadcast(&This
->engine_done
);
1692 pthread_cond_wait(&This
->engine_ready
, &This
->engine_lock
);
1694 if(This
->engine_params
.proc
){
1695 This
->engine_params
.proc(This
->engine_params
.faudio
, This
->engine_params
.stream
);
1696 This
->engine_params
.proc
= NULL
;
1697 pthread_cond_broadcast(&This
->engine_done
);
1699 }while(This
->in_use
);
1701 pthread_mutex_unlock(&This
->engine_lock
);
1706 static HRESULT WINAPI
IXAudio2Impl_CreateMasteringVoice(IXAudio2
*iface
,
1707 IXAudio2MasteringVoice
**ppMasteringVoice
, UINT32 inputChannels
,
1708 UINT32 inputSampleRate
, UINT32 flags
, const WCHAR
*deviceId
,
1709 const XAUDIO2_EFFECT_CHAIN
*pEffectChain
,
1710 AUDIO_STREAM_CATEGORY streamCategory
)
1712 IXAudio2Impl
*This
= impl_from_IXAudio2(iface
);
1714 TRACE("(%p)->(%p, %u, %u, 0x%x, %s, %p, 0x%x)\n", This
,
1715 ppMasteringVoice
, inputChannels
, inputSampleRate
, flags
,
1716 wine_dbgstr_w(deviceId
), pEffectChain
, streamCategory
);
1718 EnterCriticalSection(&This
->lock
);
1720 /* Note that we don't have paths for each XAUDIO2_VER here.
1721 * All versions < 8 have a very different CreateMasteringVoice, so we
1722 * implement those separately in compat.c.
1725 *ppMasteringVoice
= &This
->mst
.IXAudio2MasteringVoice_iface
;
1727 EnterCriticalSection(&This
->mst
.lock
);
1729 if(This
->mst
.in_use
){
1730 LeaveCriticalSection(&This
->mst
.lock
);
1731 LeaveCriticalSection(&This
->lock
);
1732 return COMPAT_E_INVALID_CALL
;
1735 LeaveCriticalSection(&This
->lock
);
1737 This
->mst
.effect_chain
= wrap_effect_chain(pEffectChain
);
1739 pthread_mutex_lock(&This
->mst
.engine_lock
);
1741 This
->mst
.engine_thread
= CreateThread(NULL
, 0, &engine_thread
, &This
->mst
, 0, NULL
);
1743 pthread_cond_wait(&This
->mst
.engine_done
, &This
->mst
.engine_lock
);
1745 pthread_mutex_unlock(&This
->mst
.engine_lock
);
1747 FAudio_SetEngineProcedureEXT(This
->faudio
, &engine_cb
, &This
->mst
);
1749 FAudio_CreateMasteringVoice8(This
->faudio
, &This
->mst
.faudio_voice
, inputChannels
,
1750 inputSampleRate
, flags
, NULL
/* TODO: (uint16_t*)deviceId */,
1751 This
->mst
.effect_chain
, (FAudioStreamCategory
)streamCategory
);
1753 This
->mst
.in_use
= TRUE
;
1755 LeaveCriticalSection(&This
->mst
.lock
);
1760 static HRESULT WINAPI
IXAudio2Impl_StartEngine(IXAudio2
*iface
)
1762 IXAudio2Impl
*This
= impl_from_IXAudio2(iface
);
1764 TRACE("(%p)->()\n", This
);
1766 return FAudio_StartEngine(This
->faudio
);
1769 static void WINAPI
IXAudio2Impl_StopEngine(IXAudio2
*iface
)
1771 IXAudio2Impl
*This
= impl_from_IXAudio2(iface
);
1773 TRACE("(%p)->()\n", This
);
1775 FAudio_StopEngine(This
->faudio
);
1778 static HRESULT WINAPI
IXAudio2Impl_CommitChanges(IXAudio2
*iface
,
1779 UINT32 operationSet
)
1781 IXAudio2Impl
*This
= impl_from_IXAudio2(iface
);
1783 TRACE("(%p)->(0x%x)\n", This
, operationSet
);
1785 #ifdef HAVE_FAUDIO_COMMITOPERATIONSET
1786 return FAudio_CommitOperationSet(This
->faudio
, operationSet
);
1788 return FAudio_CommitChanges(This
->faudio
);
1792 static void WINAPI
IXAudio2Impl_GetPerformanceData(IXAudio2
*iface
,
1793 XAUDIO2_PERFORMANCE_DATA
*pPerfData
)
1795 IXAudio2Impl
*This
= impl_from_IXAudio2(iface
);
1797 TRACE("(%p)->(%p)\n", This
, pPerfData
);
1799 FAudio_GetPerformanceData(This
->faudio
, (FAudioPerformanceData
*)pPerfData
);
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
);
1814 static const IXAudio2Vtbl XAudio2_Vtbl
=
1816 IXAudio2Impl_QueryInterface
,
1817 IXAudio2Impl_AddRef
,
1818 IXAudio2Impl_Release
,
1819 IXAudio2Impl_RegisterForCallbacks
,
1820 IXAudio2Impl_UnregisterForCallbacks
,
1821 IXAudio2Impl_CreateSourceVoice
,
1822 IXAudio2Impl_CreateSubmixVoice
,
1823 IXAudio2Impl_CreateMasteringVoice
,
1824 IXAudio2Impl_StartEngine
,
1825 IXAudio2Impl_StopEngine
,
1826 IXAudio2Impl_CommitChanges
,
1827 IXAudio2Impl_GetPerformanceData
,
1828 IXAudio2Impl_SetDebugConfiguration
1831 /* XAudio2 ClassFactory */
1834 IClassFactory IClassFactory_iface
;
1838 static struct xaudio2_cf
*impl_from_IClassFactory(IClassFactory
*iface
)
1840 return CONTAINING_RECORD(iface
, struct xaudio2_cf
, IClassFactory_iface
);
1843 static HRESULT WINAPI
XAudio2CF_QueryInterface(IClassFactory
*iface
, REFIID riid
, void **ppobj
)
1845 if(IsEqualGUID(riid
, &IID_IUnknown
)
1846 || IsEqualGUID(riid
, &IID_IClassFactory
))
1848 IClassFactory_AddRef(iface
);
1854 WARN("(%p)->(%s, %p): interface not found\n", iface
, debugstr_guid(riid
), ppobj
);
1855 return E_NOINTERFACE
;
1858 static ULONG WINAPI
XAudio2CF_AddRef(IClassFactory
*iface
)
1860 struct xaudio2_cf
*This
= impl_from_IClassFactory(iface
);
1861 ULONG ref
= InterlockedIncrement(&This
->ref
);
1862 TRACE("(%p)->(): Refcount now %u\n", This
, ref
);
1866 static ULONG WINAPI
XAudio2CF_Release(IClassFactory
*iface
)
1868 struct xaudio2_cf
*This
= impl_from_IClassFactory(iface
);
1869 ULONG ref
= InterlockedDecrement(&This
->ref
);
1870 TRACE("(%p)->(): Refcount now %u\n", This
, ref
);
1872 HeapFree(GetProcessHeap(), 0, This
);
1876 static HRESULT WINAPI
XAudio2CF_CreateInstance(IClassFactory
*iface
, IUnknown
*pOuter
,
1877 REFIID riid
, void **ppobj
)
1879 struct xaudio2_cf
*This
= impl_from_IClassFactory(iface
);
1881 IXAudio2Impl
*object
;
1883 TRACE("(%p)->(%p,%s,%p)\n", This
, pOuter
, debugstr_guid(riid
), ppobj
);
1888 return CLASS_E_NOAGGREGATION
;
1890 object
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(*object
));
1892 return E_OUTOFMEMORY
;
1894 object
->IXAudio2_iface
.lpVtbl
= &XAudio2_Vtbl
;
1896 #if XAUDIO2_VER == 0
1897 object
->IXAudio20_iface
.lpVtbl
= &XAudio20_Vtbl
;
1898 #elif XAUDIO2_VER <= 2
1899 object
->IXAudio22_iface
.lpVtbl
= &XAudio22_Vtbl
;
1900 #elif XAUDIO2_VER <= 3
1901 object
->IXAudio23_iface
.lpVtbl
= &XAudio23_Vtbl
;
1902 #elif XAUDIO2_VER <= 7
1903 object
->IXAudio27_iface
.lpVtbl
= &XAudio27_Vtbl
;
1906 object
->mst
.IXAudio2MasteringVoice_iface
.lpVtbl
= &XAudio2MasteringVoice_Vtbl
;
1908 #if XAUDIO2_VER == 0
1909 object
->mst
.IXAudio20MasteringVoice_iface
.lpVtbl
= &XAudio20MasteringVoice_Vtbl
;
1910 #elif XAUDIO2_VER <= 3
1911 object
->mst
.IXAudio23MasteringVoice_iface
.lpVtbl
= &XAudio23MasteringVoice_Vtbl
;
1912 #elif XAUDIO2_VER <= 7
1913 object
->mst
.IXAudio27MasteringVoice_iface
.lpVtbl
= &XAudio27MasteringVoice_Vtbl
;
1916 object
->FAudioEngineCallback_vtbl
= FAudioEngineCallback_Vtbl
;
1918 list_init(&object
->voices
);
1920 InitializeCriticalSection(&object
->lock
);
1921 object
->lock
.DebugInfo
->Spare
[0] = (DWORD_PTR
)(__FILE__
": IXAudio2Impl.lock");
1923 InitializeCriticalSection(&object
->mst
.lock
);
1924 object
->mst
.lock
.DebugInfo
->Spare
[0] = (DWORD_PTR
)(__FILE__
": XA2MasteringVoice.lock");
1926 pthread_mutex_init(&object
->mst
.engine_lock
, NULL
);
1927 pthread_cond_init(&object
->mst
.engine_done
, NULL
);
1928 pthread_cond_init(&object
->mst
.engine_ready
, NULL
);
1930 FAudioCOMConstructWithCustomAllocatorEXT(
1933 XAudio_Internal_Malloc
,
1934 XAudio_Internal_Free
,
1935 XAudio_Internal_Realloc
1938 FAudio_RegisterForCallbacks(object
->faudio
, &object
->FAudioEngineCallback_vtbl
);
1940 hr
= IXAudio2_QueryInterface(&object
->IXAudio2_iface
, riid
, ppobj
);
1941 IXAudio2_Release(&object
->IXAudio2_iface
);
1946 TRACE("Created XAudio version %u: %p\n", 20 + XAUDIO2_VER
, object
);
1951 static HRESULT WINAPI
XAudio2CF_LockServer(IClassFactory
*iface
, BOOL dolock
)
1953 struct xaudio2_cf
*This
= impl_from_IClassFactory(iface
);
1954 FIXME("(%p)->(%d): stub!\n", This
, dolock
);
1958 static const IClassFactoryVtbl XAudio2CF_Vtbl
=
1960 XAudio2CF_QueryInterface
,
1963 XAudio2CF_CreateInstance
,
1964 XAudio2CF_LockServer
1967 /* Engine Generators */
1969 static inline HRESULT
make_xaudio2_factory(REFIID riid
, void **ppv
)
1972 struct xaudio2_cf
*ret
= HeapAlloc(GetProcessHeap(), 0, sizeof(struct xaudio2_cf
));
1973 ret
->IClassFactory_iface
.lpVtbl
= &XAudio2CF_Vtbl
;
1975 hr
= IClassFactory_QueryInterface(&ret
->IClassFactory_iface
, riid
, ppv
);
1977 HeapFree(GetProcessHeap(), 0, ret
);
1981 HRESULT
xaudio2_initialize(IXAudio2Impl
*This
, UINT32 flags
, XAUDIO2_PROCESSOR proc
)
1983 if(proc
!= XAUDIO2_ANY_PROCESSOR
)
1984 WARN("Processor affinity not implemented in FAudio\n");
1985 return FAudio_Initialize(This
->faudio
, flags
, FAUDIO_DEFAULT_PROCESSOR
);
1988 HRESULT WINAPI
DllGetClassObject(REFCLSID rclsid
, REFIID riid
, void **ppv
)
1990 TRACE("(%s, %s, %p)\n", debugstr_guid(rclsid
), debugstr_guid(riid
), ppv
);
1992 if(IsEqualGUID(rclsid
, &CLSID_XAudio20
) ||
1993 IsEqualGUID(rclsid
, &CLSID_XAudio21
) ||
1994 IsEqualGUID(rclsid
, &CLSID_XAudio22
) ||
1995 IsEqualGUID(rclsid
, &CLSID_XAudio23
) ||
1996 IsEqualGUID(rclsid
, &CLSID_XAudio24
) ||
1997 IsEqualGUID(rclsid
, &CLSID_XAudio25
) ||
1998 IsEqualGUID(rclsid
, &CLSID_XAudio26
) ||
1999 IsEqualGUID(rclsid
, &CLSID_XAudio27
))
2000 return make_xaudio2_factory(riid
, ppv
);
2002 if(IsEqualGUID(rclsid
, &CLSID_AudioVolumeMeter20
) ||
2003 IsEqualGUID(rclsid
, &CLSID_AudioVolumeMeter21
) ||
2004 IsEqualGUID(rclsid
, &CLSID_AudioVolumeMeter22
) ||
2005 IsEqualGUID(rclsid
, &CLSID_AudioVolumeMeter23
) ||
2006 IsEqualGUID(rclsid
, &CLSID_AudioVolumeMeter24
) ||
2007 IsEqualGUID(rclsid
, &CLSID_AudioVolumeMeter25
) ||
2008 IsEqualGUID(rclsid
, &CLSID_AudioVolumeMeter26
) ||
2009 IsEqualGUID(rclsid
, &CLSID_AudioVolumeMeter27
))
2010 return make_xapo_factory(&CLSID_AudioVolumeMeter27
, riid
, ppv
);
2012 if(IsEqualGUID(rclsid
, &CLSID_AudioReverb20
) ||
2013 IsEqualGUID(rclsid
, &CLSID_AudioReverb21
) ||
2014 IsEqualGUID(rclsid
, &CLSID_AudioReverb22
) ||
2015 IsEqualGUID(rclsid
, &CLSID_AudioReverb23
) ||
2016 IsEqualGUID(rclsid
, &CLSID_AudioReverb24
) ||
2017 IsEqualGUID(rclsid
, &CLSID_AudioReverb25
) ||
2018 IsEqualGUID(rclsid
, &CLSID_AudioReverb26
) ||
2019 IsEqualGUID(rclsid
, &CLSID_AudioReverb27
))
2020 return make_xapo_factory(&CLSID_AudioReverb27
, riid
, ppv
);
2022 return CLASS_E_CLASSNOTAVAILABLE
;
2025 #if XAUDIO2_VER >= 8
2026 HRESULT WINAPI
XAudio2Create(IXAudio2
**ppxa2
, UINT32 flags
, XAUDIO2_PROCESSOR proc
)
2032 TRACE("%p 0x%x 0x%x\n", ppxa2
, flags
, proc
);
2034 hr
= make_xaudio2_factory(&IID_IClassFactory
, (void**)&cf
);
2038 hr
= IClassFactory_CreateInstance(cf
, NULL
, &IID_IXAudio2
, (void**)&xa2
);
2039 IClassFactory_Release(cf
);
2043 hr
= xaudio2_initialize(impl_from_IXAudio2(xa2
), flags
, proc
);
2045 IXAudio2_Release(xa2
);
2054 HRESULT WINAPI
CreateAudioVolumeMeter(IUnknown
**out
)
2061 hr
= make_xapo_factory(&CLSID_AudioVolumeMeter27
, &IID_IClassFactory
, (void**)&cf
);
2065 hr
= IClassFactory_CreateInstance(cf
, NULL
, &IID_IUnknown
, (void**)out
);
2067 IClassFactory_Release(cf
);
2072 HRESULT WINAPI
CreateAudioReverb(IUnknown
**out
)
2079 hr
= make_xapo_factory(&CLSID_AudioReverb27
, &IID_IClassFactory
, (void**)&cf
);
2083 hr
= IClassFactory_CreateInstance(cf
, NULL
, &IID_IUnknown
, (void**)out
);
2085 IClassFactory_Release(cf
);
2089 #endif /* XAUDIO2_VER >= 8 */