2 * Copyright (c) 2018 Ethan Lee for CodeWeavers
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
24 #define NONAMELESSUNION
28 #if XACT3_VER < 0x0300
34 #include "wine/debug.h"
36 WINE_DEFAULT_DEBUG_CHANNEL(xact3
);
38 #if XACT3_VER < 0x0300
39 #define IID_IXACT3Engine IID_IXACTEngine
40 #define IXACT3Cue IXACTCue
41 #define IXACT3CueVtbl IXACTCueVtbl
42 #define IXACT3Engine IXACTEngine
43 #define IXACT3EngineVtbl IXACTEngineVtbl
44 #define IXACT3Engine_QueryInterface IXACTEngine_QueryInterface
45 #define IXACT3SoundBank IXACTSoundBank
46 #define IXACT3SoundBankVtbl IXACTSoundBankVtbl
47 #define IXACT3Wave IXACTWave
48 #define IXACT3WaveVtbl IXACTWaveVtbl
49 #define IXACT3WaveBank IXACTWaveBank
50 #define IXACT3WaveBankVtbl IXACTWaveBankVtbl
53 typedef struct _XACT3CueImpl
{
54 IXACT3Cue IXACT3Cue_iface
;
58 static inline XACT3CueImpl
*impl_from_IXACT3Cue(IXACT3Cue
*iface
)
60 return CONTAINING_RECORD(iface
, XACT3CueImpl
, IXACT3Cue_iface
);
63 static HRESULT WINAPI
IXACT3CueImpl_Play(IXACT3Cue
*iface
)
65 XACT3CueImpl
*This
= impl_from_IXACT3Cue(iface
);
67 TRACE("(%p)\n", iface
);
69 return FACTCue_Play(This
->fact_cue
);
72 static HRESULT WINAPI
IXACT3CueImpl_Stop(IXACT3Cue
*iface
, DWORD dwFlags
)
74 XACT3CueImpl
*This
= impl_from_IXACT3Cue(iface
);
76 TRACE("(%p)->(%u)\n", iface
, dwFlags
);
78 return FACTCue_Stop(This
->fact_cue
, dwFlags
);
81 static HRESULT WINAPI
IXACT3CueImpl_GetState(IXACT3Cue
*iface
, DWORD
*pdwState
)
83 XACT3CueImpl
*This
= impl_from_IXACT3Cue(iface
);
85 TRACE("(%p)->(%p)\n", iface
, pdwState
);
87 return FACTCue_GetState(This
->fact_cue
, pdwState
);
90 static HRESULT WINAPI
IXACT3CueImpl_Destroy(IXACT3Cue
*iface
)
92 XACT3CueImpl
*This
= impl_from_IXACT3Cue(iface
);
95 TRACE("(%p)\n", iface
);
97 ret
= FACTCue_Destroy(This
->fact_cue
);
99 WARN("FACTCue_Destroy returned %d\n", ret
);
100 HeapFree(GetProcessHeap(), 0, This
);
104 #if XACT3_VER < 0x0300
106 static HRESULT WINAPI
IXACT3CueImpl_GetChannelMap(IXACT3Cue
*iface
,
107 XACTCHANNELMAP
*map
, DWORD size
, DWORD
*needed_size
)
109 FIXME("(%p)->(%p, %u, %p)\n", iface
, map
, size
, needed_size
);
114 static HRESULT WINAPI
IXACT3CueImpl_SetChannelMap(IXACT3Cue
*iface
, XACTCHANNELMAP
*map
)
116 FIXME("(%p)->(%p)\n", iface
, map
);
121 static HRESULT WINAPI
IXACT3CueImpl_GetChannelVolume(IXACT3Cue
*iface
, XACTCHANNELVOLUME
*volume
)
123 FIXME("(%p)->(%p)\n", iface
, volume
);
128 static HRESULT WINAPI
IXACT3CueImpl_SetChannelVolume(IXACT3Cue
*iface
, XACTCHANNELVOLUME
*volume
)
130 FIXME("(%p)->(%p)\n", iface
, volume
);
137 static HRESULT WINAPI
IXACT3CueImpl_SetMatrixCoefficients(IXACT3Cue
*iface
,
138 UINT32 uSrcChannelCount
, UINT32 uDstChannelCount
,
139 float *pMatrixCoefficients
)
141 XACT3CueImpl
*This
= impl_from_IXACT3Cue(iface
);
143 TRACE("(%p)->(%u, %u, %p)\n", iface
, uSrcChannelCount
, uDstChannelCount
,
144 pMatrixCoefficients
);
146 return FACTCue_SetMatrixCoefficients(This
->fact_cue
, uSrcChannelCount
,
147 uDstChannelCount
, pMatrixCoefficients
);
150 static XACTVARIABLEINDEX WINAPI
IXACT3CueImpl_GetVariableIndex(IXACT3Cue
*iface
,
151 PCSTR szFriendlyName
)
153 XACT3CueImpl
*This
= impl_from_IXACT3Cue(iface
);
155 TRACE("(%p)->(%s)\n", iface
, szFriendlyName
);
157 return FACTCue_GetVariableIndex(This
->fact_cue
, szFriendlyName
);
160 static HRESULT WINAPI
IXACT3CueImpl_SetVariable(IXACT3Cue
*iface
,
161 XACTVARIABLEINDEX nIndex
, XACTVARIABLEVALUE nValue
)
163 XACT3CueImpl
*This
= impl_from_IXACT3Cue(iface
);
165 TRACE("(%p)->(%u, %f)\n", iface
, nIndex
, nValue
);
167 return FACTCue_SetVariable(This
->fact_cue
, nIndex
, nValue
);
170 static HRESULT WINAPI
IXACT3CueImpl_GetVariable(IXACT3Cue
*iface
,
171 XACTVARIABLEINDEX nIndex
, XACTVARIABLEVALUE
*nValue
)
173 XACT3CueImpl
*This
= impl_from_IXACT3Cue(iface
);
175 TRACE("(%p)->(%u, %p)\n", iface
, nIndex
, nValue
);
177 return FACTCue_GetVariable(This
->fact_cue
, nIndex
, nValue
);
180 static HRESULT WINAPI
IXACT3CueImpl_Pause(IXACT3Cue
*iface
, BOOL fPause
)
182 XACT3CueImpl
*This
= impl_from_IXACT3Cue(iface
);
184 TRACE("(%p)->(%u)\n", iface
, fPause
);
186 return FACTCue_Pause(This
->fact_cue
, fPause
);
189 #if XACT3_VER >= 0x0205
190 static HRESULT WINAPI
IXACT3CueImpl_GetProperties(IXACT3Cue
*iface
,
191 XACT_CUE_INSTANCE_PROPERTIES
**ppProperties
)
193 XACT3CueImpl
*This
= impl_from_IXACT3Cue(iface
);
194 FACTCueInstanceProperties
*fProps
;
197 TRACE("(%p)->(%p)\n", iface
, ppProperties
);
199 hr
= FACTCue_GetProperties(This
->fact_cue
, &fProps
);
203 *ppProperties
= (XACT_CUE_INSTANCE_PROPERTIES
*) fProps
;
208 #if XACT3_VER >= 0x0300
209 static HRESULT WINAPI
IXACT3CueImpl_SetOutputVoices(IXACT3Cue
*iface
,
210 const XAUDIO2_VOICE_SENDS
*pSendList
)
212 XACT3CueImpl
*This
= impl_from_IXACT3Cue(iface
);
213 FIXME("(%p)->(%p): stub!\n", This
, pSendList
);
217 static HRESULT WINAPI
IXACT3CueImpl_SetOutputVoiceMatrix(IXACT3Cue
*iface
,
218 IXAudio2Voice
*pDestinationVoice
, UINT32 SourceChannels
,
219 UINT32 DestinationChannels
, const float *pLevelMatrix
)
221 XACT3CueImpl
*This
= impl_from_IXACT3Cue(iface
);
222 FIXME("(%p)->(%p %u %u %p): stub!\n", This
, pDestinationVoice
, SourceChannels
,
223 DestinationChannels
, pLevelMatrix
);
228 static const IXACT3CueVtbl XACT3Cue_Vtbl
=
232 IXACT3CueImpl_GetState
,
233 IXACT3CueImpl_Destroy
,
234 #if XACT3_VER < 0x0300
235 IXACT3CueImpl_GetChannelMap
,
236 IXACT3CueImpl_SetChannelMap
,
237 IXACT3CueImpl_GetChannelVolume
,
238 IXACT3CueImpl_SetChannelVolume
,
240 IXACT3CueImpl_SetMatrixCoefficients
,
241 IXACT3CueImpl_GetVariableIndex
,
242 IXACT3CueImpl_SetVariable
,
243 IXACT3CueImpl_GetVariable
,
245 #if XACT3_VER >= 0x0205
246 IXACT3CueImpl_GetProperties
,
248 #if XACT3_VER >= 0x0300
249 IXACT3CueImpl_SetOutputVoices
,
250 IXACT3CueImpl_SetOutputVoiceMatrix
254 typedef struct _XACT3SoundBankImpl
{
255 IXACT3SoundBank IXACT3SoundBank_iface
;
257 FACTSoundBank
*fact_soundbank
;
258 } XACT3SoundBankImpl
;
260 static inline XACT3SoundBankImpl
*impl_from_IXACT3SoundBank(IXACT3SoundBank
*iface
)
262 return CONTAINING_RECORD(iface
, XACT3SoundBankImpl
, IXACT3SoundBank_iface
);
265 static XACTINDEX WINAPI
IXACT3SoundBankImpl_GetCueIndex(IXACT3SoundBank
*iface
,
266 PCSTR szFriendlyName
)
268 XACT3SoundBankImpl
*This
= impl_from_IXACT3SoundBank(iface
);
270 TRACE("(%p)->(%s)\n", This
, szFriendlyName
);
272 return FACTSoundBank_GetCueIndex(This
->fact_soundbank
, szFriendlyName
);
275 #if XACT3_VER >= 0x0205
276 static HRESULT WINAPI
IXACT3SoundBankImpl_GetNumCues(IXACT3SoundBank
*iface
,
277 XACTINDEX
*pnNumCues
)
279 XACT3SoundBankImpl
*This
= impl_from_IXACT3SoundBank(iface
);
281 TRACE("(%p)->(%p)\n", This
, pnNumCues
);
283 return FACTSoundBank_GetNumCues(This
->fact_soundbank
, pnNumCues
);
286 static HRESULT WINAPI
IXACT3SoundBankImpl_GetCueProperties(IXACT3SoundBank
*iface
,
287 XACTINDEX nCueIndex
, XACT_CUE_PROPERTIES
*pProperties
)
289 XACT3SoundBankImpl
*This
= impl_from_IXACT3SoundBank(iface
);
291 TRACE("(%p)->(%u, %p)\n", This
, nCueIndex
, pProperties
);
293 return FACTSoundBank_GetCueProperties(This
->fact_soundbank
, nCueIndex
,
294 (FACTCueProperties
*) pProperties
);
298 static HRESULT WINAPI
IXACT3SoundBankImpl_Prepare(IXACT3SoundBank
*iface
,
299 XACTINDEX nCueIndex
, DWORD dwFlags
, XACTTIME timeOffset
,
302 XACT3SoundBankImpl
*This
= impl_from_IXACT3SoundBank(iface
);
307 TRACE("(%p)->(%u, 0x%x, %u, %p)\n", This
, nCueIndex
, dwFlags
, timeOffset
,
310 ret
= FACTSoundBank_Prepare(This
->fact_soundbank
, nCueIndex
, dwFlags
,
314 ERR("Failed to CreateCue: %d\n", ret
);
318 cue
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(*cue
));
321 FACTCue_Destroy(fcue
);
322 ERR("Failed to allocate XACT3CueImpl!\n");
323 return E_OUTOFMEMORY
;
326 cue
->IXACT3Cue_iface
.lpVtbl
= &XACT3Cue_Vtbl
;
327 cue
->fact_cue
= fcue
;
328 *ppCue
= &cue
->IXACT3Cue_iface
;
330 TRACE("Created Cue: %p\n", cue
);
335 static HRESULT WINAPI
IXACT3SoundBankImpl_Play(IXACT3SoundBank
*iface
,
336 XACTINDEX nCueIndex
, DWORD dwFlags
, XACTTIME timeOffset
,
339 XACT3SoundBankImpl
*This
= impl_from_IXACT3SoundBank(iface
);
344 TRACE("(%p)->(%u, 0x%x, %u, %p)\n", This
, nCueIndex
, dwFlags
, timeOffset
,
347 /* If the application doesn't want a handle, don't generate one at all.
348 * Let the engine handle that memory instead.
352 hr
= FACTSoundBank_Play(This
->fact_soundbank
, nCueIndex
, dwFlags
,
355 hr
= FACTSoundBank_Play(This
->fact_soundbank
, nCueIndex
, dwFlags
,
360 cue
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(*cue
));
363 FACTCue_Destroy(fcue
);
364 ERR("Failed to allocate XACT3CueImpl!\n");
365 return E_OUTOFMEMORY
;
368 cue
->IXACT3Cue_iface
.lpVtbl
= &XACT3Cue_Vtbl
;
369 cue
->fact_cue
= fcue
;
370 *ppCue
= &cue
->IXACT3Cue_iface
;
376 static HRESULT WINAPI
IXACT3SoundBankImpl_Stop(IXACT3SoundBank
*iface
,
377 XACTINDEX nCueIndex
, DWORD dwFlags
)
379 XACT3SoundBankImpl
*This
= impl_from_IXACT3SoundBank(iface
);
381 TRACE("(%p)->(%u)\n", This
, dwFlags
);
383 return FACTSoundBank_Stop(This
->fact_soundbank
, nCueIndex
, dwFlags
);
386 static HRESULT WINAPI
IXACT3SoundBankImpl_Destroy(IXACT3SoundBank
*iface
)
388 XACT3SoundBankImpl
*This
= impl_from_IXACT3SoundBank(iface
);
391 TRACE("(%p)\n", This
);
393 hr
= FACTSoundBank_Destroy(This
->fact_soundbank
);
394 HeapFree(GetProcessHeap(), 0, This
);
398 static HRESULT WINAPI
IXACT3SoundBankImpl_GetState(IXACT3SoundBank
*iface
,
401 XACT3SoundBankImpl
*This
= impl_from_IXACT3SoundBank(iface
);
403 TRACE("(%p)->(%p)\n", This
, pdwState
);
405 return FACTSoundBank_GetState(This
->fact_soundbank
, pdwState
);
408 static const IXACT3SoundBankVtbl XACT3SoundBank_Vtbl
=
410 IXACT3SoundBankImpl_GetCueIndex
,
411 #if XACT3_VER >= 0x0205
412 IXACT3SoundBankImpl_GetNumCues
,
413 IXACT3SoundBankImpl_GetCueProperties
,
415 IXACT3SoundBankImpl_Prepare
,
416 IXACT3SoundBankImpl_Play
,
417 IXACT3SoundBankImpl_Stop
,
418 IXACT3SoundBankImpl_Destroy
,
419 IXACT3SoundBankImpl_GetState
422 #if XACT3_VER >= 0x0205
424 typedef struct _XACT3WaveImpl
{
425 IXACT3Wave IXACT3Wave_iface
;
430 static inline XACT3WaveImpl
*impl_from_IXACT3Wave(IXACT3Wave
*iface
)
432 return CONTAINING_RECORD(iface
, XACT3WaveImpl
, IXACT3Wave_iface
);
435 static HRESULT WINAPI
IXACT3WaveImpl_Destroy(IXACT3Wave
*iface
)
437 XACT3WaveImpl
*This
= impl_from_IXACT3Wave(iface
);
440 TRACE("(%p)\n", This
);
442 hr
= FACTWave_Destroy(This
->fact_wave
);
443 HeapFree(GetProcessHeap(), 0, This
);
447 static HRESULT WINAPI
IXACT3WaveImpl_Play(IXACT3Wave
*iface
)
449 XACT3WaveImpl
*This
= impl_from_IXACT3Wave(iface
);
451 TRACE("(%p)\n", This
);
453 return FACTWave_Play(This
->fact_wave
);
456 static HRESULT WINAPI
IXACT3WaveImpl_Stop(IXACT3Wave
*iface
, DWORD dwFlags
)
458 XACT3WaveImpl
*This
= impl_from_IXACT3Wave(iface
);
460 TRACE("(%p)->(0x%x)\n", This
, dwFlags
);
462 return FACTWave_Stop(This
->fact_wave
, dwFlags
);
465 static HRESULT WINAPI
IXACT3WaveImpl_Pause(IXACT3Wave
*iface
, BOOL fPause
)
467 XACT3WaveImpl
*This
= impl_from_IXACT3Wave(iface
);
469 TRACE("(%p)->(%u)\n", This
, fPause
);
471 return FACTWave_Pause(This
->fact_wave
, fPause
);
474 static HRESULT WINAPI
IXACT3WaveImpl_GetState(IXACT3Wave
*iface
, DWORD
*pdwState
)
476 XACT3WaveImpl
*This
= impl_from_IXACT3Wave(iface
);
478 TRACE("(%p)->(%p)\n", This
, pdwState
);
480 return FACTWave_GetState(This
->fact_wave
, pdwState
);
483 static HRESULT WINAPI
IXACT3WaveImpl_SetPitch(IXACT3Wave
*iface
, XACTPITCH pitch
)
485 XACT3WaveImpl
*This
= impl_from_IXACT3Wave(iface
);
487 TRACE("(%p)->(%d)\n", This
, pitch
);
489 return FACTWave_SetPitch(This
->fact_wave
, pitch
);
492 static HRESULT WINAPI
IXACT3WaveImpl_SetVolume(IXACT3Wave
*iface
, XACTVOLUME volume
)
494 XACT3WaveImpl
*This
= impl_from_IXACT3Wave(iface
);
496 TRACE("(%p)->(%f)\n", This
, volume
);
498 return FACTWave_SetVolume(This
->fact_wave
, volume
);
501 static HRESULT WINAPI
IXACT3WaveImpl_SetMatrixCoefficients(IXACT3Wave
*iface
,
502 UINT32 uSrcChannelCount
, UINT32 uDstChannelCount
,
503 float *pMatrixCoefficients
)
505 XACT3WaveImpl
*This
= impl_from_IXACT3Wave(iface
);
507 TRACE("(%p)->(%u, %u, %p)\n", This
, uSrcChannelCount
, uDstChannelCount
,
508 pMatrixCoefficients
);
510 return FACTWave_SetMatrixCoefficients(This
->fact_wave
, uSrcChannelCount
,
511 uDstChannelCount
, pMatrixCoefficients
);
514 static HRESULT WINAPI
IXACT3WaveImpl_GetProperties(IXACT3Wave
*iface
,
515 XACT_WAVE_INSTANCE_PROPERTIES
*pProperties
)
517 XACT3WaveImpl
*This
= impl_from_IXACT3Wave(iface
);
519 TRACE("(%p)->(%p)\n", This
, pProperties
);
521 return FACTWave_GetProperties(This
->fact_wave
,
522 (FACTWaveInstanceProperties
*) pProperties
);
525 static const IXACT3WaveVtbl XACT3Wave_Vtbl
=
527 IXACT3WaveImpl_Destroy
,
530 IXACT3WaveImpl_Pause
,
531 IXACT3WaveImpl_GetState
,
532 IXACT3WaveImpl_SetPitch
,
533 IXACT3WaveImpl_SetVolume
,
534 IXACT3WaveImpl_SetMatrixCoefficients
,
535 IXACT3WaveImpl_GetProperties
540 typedef struct _XACT3WaveBankImpl
{
541 IXACT3WaveBank IXACT3WaveBank_iface
;
543 FACTWaveBank
*fact_wavebank
;
546 static inline XACT3WaveBankImpl
*impl_from_IXACT3WaveBank(IXACT3WaveBank
*iface
)
548 return CONTAINING_RECORD(iface
, XACT3WaveBankImpl
, IXACT3WaveBank_iface
);
551 static HRESULT WINAPI
IXACT3WaveBankImpl_Destroy(IXACT3WaveBank
*iface
)
553 XACT3WaveBankImpl
*This
= impl_from_IXACT3WaveBank(iface
);
556 TRACE("(%p)\n", This
);
558 hr
= FACTWaveBank_Destroy(This
->fact_wavebank
);
559 HeapFree(GetProcessHeap(), 0, This
);
563 #if XACT3_VER >= 0x0205
565 static HRESULT WINAPI
IXACT3WaveBankImpl_GetNumWaves(IXACT3WaveBank
*iface
,
566 XACTINDEX
*pnNumWaves
)
568 XACT3WaveBankImpl
*This
= impl_from_IXACT3WaveBank(iface
);
570 TRACE("(%p)->(%p)\n", This
, pnNumWaves
);
572 return FACTWaveBank_GetNumWaves(This
->fact_wavebank
, pnNumWaves
);
575 static XACTINDEX WINAPI
IXACT3WaveBankImpl_GetWaveIndex(IXACT3WaveBank
*iface
,
576 PCSTR szFriendlyName
)
578 XACT3WaveBankImpl
*This
= impl_from_IXACT3WaveBank(iface
);
580 TRACE("(%p)->(%s)\n", This
, szFriendlyName
);
582 return FACTWaveBank_GetWaveIndex(This
->fact_wavebank
, szFriendlyName
);
585 static HRESULT WINAPI
IXACT3WaveBankImpl_GetWaveProperties(IXACT3WaveBank
*iface
,
586 XACTINDEX nWaveIndex
, XACT_WAVE_PROPERTIES
*pWaveProperties
)
588 XACT3WaveBankImpl
*This
= impl_from_IXACT3WaveBank(iface
);
590 TRACE("(%p)->(%u, %p)\n", This
, nWaveIndex
, pWaveProperties
);
592 return FACTWaveBank_GetWaveProperties(This
->fact_wavebank
, nWaveIndex
,
593 (FACTWaveProperties
*) pWaveProperties
);
596 static HRESULT WINAPI
IXACT3WaveBankImpl_Prepare(IXACT3WaveBank
*iface
,
597 XACTINDEX nWaveIndex
, DWORD dwFlags
, DWORD dwPlayOffset
,
598 XACTLOOPCOUNT nLoopCount
, IXACT3Wave
** ppWave
)
600 XACT3WaveBankImpl
*This
= impl_from_IXACT3WaveBank(iface
);
605 TRACE("(%p)->(0x%x, %u, 0x%x, %u, %p)\n", This
, nWaveIndex
, dwFlags
,
606 dwPlayOffset
, nLoopCount
, ppWave
);
608 ret
= FACTWaveBank_Prepare(This
->fact_wavebank
, nWaveIndex
, dwFlags
,
609 dwPlayOffset
, nLoopCount
, &fwave
);
612 ERR("Failed to CreateWave: %d\n", ret
);
616 wave
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(*wave
));
619 FACTWave_Destroy(fwave
);
620 ERR("Failed to allocate XACT3WaveImpl!\n");
621 return E_OUTOFMEMORY
;
624 wave
->IXACT3Wave_iface
.lpVtbl
= &XACT3Wave_Vtbl
;
625 wave
->fact_wave
= fwave
;
626 *ppWave
= &wave
->IXACT3Wave_iface
;
628 TRACE("Created Wave: %p\n", wave
);
633 static HRESULT WINAPI
IXACT3WaveBankImpl_Play(IXACT3WaveBank
*iface
,
634 XACTINDEX nWaveIndex
, DWORD dwFlags
, DWORD dwPlayOffset
,
635 XACTLOOPCOUNT nLoopCount
, IXACT3Wave
** ppWave
)
637 XACT3WaveBankImpl
*This
= impl_from_IXACT3WaveBank(iface
);
642 TRACE("(%p)->(0x%x, %u, 0x%x, %u, %p)\n", This
, nWaveIndex
, dwFlags
, dwPlayOffset
,
645 /* If the application doesn't want a handle, don't generate one at all.
646 * Let the engine handle that memory instead.
650 hr
= FACTWaveBank_Play(This
->fact_wavebank
, nWaveIndex
, dwFlags
,
651 dwPlayOffset
, nLoopCount
, NULL
);
653 hr
= FACTWaveBank_Play(This
->fact_wavebank
, nWaveIndex
, dwFlags
,
654 dwPlayOffset
, nLoopCount
, &fwave
);
658 wave
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(*wave
));
661 FACTWave_Destroy(fwave
);
662 ERR("Failed to allocate XACT3WaveImpl!\n");
663 return E_OUTOFMEMORY
;
666 wave
->IXACT3Wave_iface
.lpVtbl
= &XACT3Wave_Vtbl
;
667 wave
->fact_wave
= fwave
;
668 *ppWave
= &wave
->IXACT3Wave_iface
;
674 static HRESULT WINAPI
IXACT3WaveBankImpl_Stop(IXACT3WaveBank
*iface
,
675 XACTINDEX nWaveIndex
, DWORD dwFlags
)
677 XACT3WaveBankImpl
*This
= impl_from_IXACT3WaveBank(iface
);
679 TRACE("(%p)->(%u, %u)\n", This
, nWaveIndex
, dwFlags
);
681 return FACTWaveBank_Stop(This
->fact_wavebank
, nWaveIndex
, dwFlags
);
686 static HRESULT WINAPI
IXACT3WaveBankImpl_GetState(IXACT3WaveBank
*iface
,
689 XACT3WaveBankImpl
*This
= impl_from_IXACT3WaveBank(iface
);
691 TRACE("(%p)->(%p)\n", This
, pdwState
);
693 return FACTWaveBank_GetState(This
->fact_wavebank
, pdwState
);
696 static const IXACT3WaveBankVtbl XACT3WaveBank_Vtbl
=
698 IXACT3WaveBankImpl_Destroy
,
699 #if XACT3_VER >= 0x0205
700 IXACT3WaveBankImpl_GetNumWaves
,
701 IXACT3WaveBankImpl_GetWaveIndex
,
702 IXACT3WaveBankImpl_GetWaveProperties
,
703 IXACT3WaveBankImpl_Prepare
,
704 IXACT3WaveBankImpl_Play
,
705 IXACT3WaveBankImpl_Stop
,
707 IXACT3WaveBankImpl_GetState
710 typedef struct _XACT3EngineImpl
{
711 IXACT3Engine IXACT3Engine_iface
;
713 FACTAudioEngine
*fact_engine
;
715 XACT_READFILE_CALLBACK pReadFile
;
716 XACT_GETOVERLAPPEDRESULT_CALLBACK pGetOverlappedResult
;
717 XACT_NOTIFICATION_CALLBACK notification_callback
;
720 typedef struct wrap_readfile_struct
{
721 XACT3EngineImpl
*engine
;
723 } wrap_readfile_struct
;
725 static int32_t FACTCALL
wrap_readfile(
728 uint32_t nNumberOfBytesRead
,
729 uint32_t *lpNumberOfBytesRead
,
730 FACTOverlapped
*lpOverlapped
)
732 wrap_readfile_struct
*wrap
= (wrap_readfile_struct
*) hFile
;
733 return wrap
->engine
->pReadFile(wrap
->file
, lpBuffer
, nNumberOfBytesRead
,
734 lpNumberOfBytesRead
, (LPOVERLAPPED
)lpOverlapped
);
737 static int32_t FACTCALL
wrap_getoverlappedresult(
739 FACTOverlapped
*lpOverlapped
,
740 uint32_t *lpNumberOfBytesTransferred
,
743 wrap_readfile_struct
*wrap
= (wrap_readfile_struct
*) hFile
;
744 return wrap
->engine
->pGetOverlappedResult(wrap
->file
, (LPOVERLAPPED
)lpOverlapped
,
745 lpNumberOfBytesTransferred
, bWait
);
748 static inline XACT3EngineImpl
*impl_from_IXACT3Engine(IXACT3Engine
*iface
)
750 return CONTAINING_RECORD(iface
, XACT3EngineImpl
, IXACT3Engine_iface
);
753 static HRESULT WINAPI
IXACT3EngineImpl_QueryInterface(IXACT3Engine
*iface
,
754 REFIID riid
, void **ppvObject
)
756 XACT3EngineImpl
*This
= impl_from_IXACT3Engine(iface
);
758 TRACE("(%p)->(%s, %p)\n", This
, debugstr_guid(riid
), ppvObject
);
760 if(IsEqualGUID(riid
, &IID_IUnknown
) ||
761 IsEqualGUID(riid
, &IID_IXACT3Engine
)){
762 *ppvObject
= &This
->IXACT3Engine_iface
;
768 IUnknown_AddRef((IUnknown
*)*ppvObject
);
772 FIXME("(%p)->(%s,%p), not found\n", This
, debugstr_guid(riid
), ppvObject
);
774 return E_NOINTERFACE
;
777 static ULONG WINAPI
IXACT3EngineImpl_AddRef(IXACT3Engine
*iface
)
779 XACT3EngineImpl
*This
= impl_from_IXACT3Engine(iface
);
780 ULONG ref
= FACTAudioEngine_AddRef(This
->fact_engine
);
781 TRACE("(%p)->(): Refcount now %u\n", This
, ref
);
785 static ULONG WINAPI
IXACT3EngineImpl_Release(IXACT3Engine
*iface
)
787 XACT3EngineImpl
*This
= impl_from_IXACT3Engine(iface
);
788 ULONG ref
= FACTAudioEngine_Release(This
->fact_engine
);
790 TRACE("(%p)->(): Refcount now %u\n", This
, ref
);
793 HeapFree(GetProcessHeap(), 0, This
);
797 static HRESULT WINAPI
IXACT3EngineImpl_GetRendererCount(IXACT3Engine
*iface
,
798 XACTINDEX
*pnRendererCount
)
800 XACT3EngineImpl
*This
= impl_from_IXACT3Engine(iface
);
802 TRACE("(%p)->(%p)\n", This
, pnRendererCount
);
804 return FACTAudioEngine_GetRendererCount(This
->fact_engine
, pnRendererCount
);
807 static HRESULT WINAPI
IXACT3EngineImpl_GetRendererDetails(IXACT3Engine
*iface
,
808 XACTINDEX nRendererIndex
, XACT_RENDERER_DETAILS
*pRendererDetails
)
810 XACT3EngineImpl
*This
= impl_from_IXACT3Engine(iface
);
812 TRACE("(%p)->(%d, %p)\n", This
, nRendererIndex
, pRendererDetails
);
814 return FACTAudioEngine_GetRendererDetails(This
->fact_engine
,
815 nRendererIndex
, (FACTRendererDetails
*) pRendererDetails
);
818 #if XACT3_VER >= 0x0205
820 static HRESULT WINAPI
IXACT3EngineImpl_GetFinalMixFormat(IXACT3Engine
*iface
,
821 WAVEFORMATEXTENSIBLE
*pFinalMixFormat
)
823 XACT3EngineImpl
*This
= impl_from_IXACT3Engine(iface
);
825 TRACE("(%p)->(%p)\n", This
, pFinalMixFormat
);
827 return FACTAudioEngine_GetFinalMixFormat(This
->fact_engine
,
828 (FAudioWaveFormatExtensible
*) pFinalMixFormat
);
833 static void FACTCALL
fact_notification_cb(const FACTNotification
*notification
)
835 XACT3EngineImpl
*engine
= (XACT3EngineImpl
*)notification
->pvContext
;
837 /* Older versions of FAudio don't pass through the context */
840 WARN("Notification context is NULL\n");
844 FIXME("Unsupported callback type %d\n", notification
->type
);
847 static HRESULT WINAPI
IXACT3EngineImpl_Initialize(IXACT3Engine
*iface
,
848 const XACT_RUNTIME_PARAMETERS
*pParams
)
850 XACT3EngineImpl
*This
= impl_from_IXACT3Engine(iface
);
851 FACTRuntimeParameters params
;
854 TRACE("(%p)->(%p)\n", This
, pParams
);
856 memset(¶ms
, 0, sizeof(FACTRuntimeParameters
));
857 /* Explicitly copy to the FAudio structure as the packing is wrong under 64 bits */
858 params
.lookAheadTime
= pParams
->lookAheadTime
;
859 params
.pGlobalSettingsBuffer
= pParams
->pGlobalSettingsBuffer
;
860 params
.globalSettingsBufferSize
= pParams
->globalSettingsBufferSize
;
861 params
.globalSettingsFlags
= pParams
->globalSettingsFlags
;
862 params
.globalSettingsAllocAttributes
= pParams
->globalSettingsAllocAttributes
;
863 params
.pRendererID
= (int16_t*)pParams
->pRendererID
;
864 params
.pXAudio2
= NULL
;
865 params
.pMasteringVoice
= NULL
;
867 #if XACT3_VER >= 0x0300
868 /* FIXME: pXAudio2 and pMasteringVoice are pointers to
869 * IXAudio2/IXAudio2MasteringVoice objects. FACT wants pointers to
870 * FAudio/FAudioMasteringVoice objects. In Wine's XAudio2 implementation, we
871 * actually have them available, but only if you access their internal data.
872 * For now we can just force these pointers to NULL, as XACT simply
873 * generates its own engine and endpoint in that situation. These parameters
874 * are mostly an optimization for games with multiple XACT3Engines that want
875 * a single engine running everything.
878 if (pParams
->pXAudio2
!= NULL
){
879 FIXME("pXAudio2 parameter not supported!\n");
881 if (pParams
->pMasteringVoice
!= NULL
){
882 FIXME("pMasteringVoice parameter not supported!\n");
887 /* Force Windows I/O, do NOT use the FACT default! */
888 This
->pReadFile
= (XACT_READFILE_CALLBACK
)
889 pParams
->fileIOCallbacks
.readFileCallback
;
890 This
->pGetOverlappedResult
= (XACT_GETOVERLAPPEDRESULT_CALLBACK
)
891 pParams
->fileIOCallbacks
.getOverlappedResultCallback
;
892 if (This
->pReadFile
== NULL
)
893 This
->pReadFile
= (XACT_READFILE_CALLBACK
) ReadFile
;
894 if (This
->pGetOverlappedResult
== NULL
)
895 This
->pGetOverlappedResult
= (XACT_GETOVERLAPPEDRESULT_CALLBACK
)
897 params
.fileIOCallbacks
.readFileCallback
= wrap_readfile
;
898 params
.fileIOCallbacks
.getOverlappedResultCallback
= wrap_getoverlappedresult
;
899 params
.fnNotificationCallback
= fact_notification_cb
;
901 This
->notification_callback
= (XACT_NOTIFICATION_CALLBACK
)pParams
->fnNotificationCallback
;
903 ret
= FACTAudioEngine_Initialize(This
->fact_engine
, ¶ms
);
905 WARN("FACTAudioEngine_Initialize returned %d\n", ret
);
907 return !ret
? S_OK
: E_FAIL
;
910 static HRESULT WINAPI
IXACT3EngineImpl_ShutDown(IXACT3Engine
*iface
)
912 XACT3EngineImpl
*This
= impl_from_IXACT3Engine(iface
);
914 TRACE("(%p)\n", This
);
916 return FACTAudioEngine_ShutDown(This
->fact_engine
);
919 static HRESULT WINAPI
IXACT3EngineImpl_DoWork(IXACT3Engine
*iface
)
921 XACT3EngineImpl
*This
= impl_from_IXACT3Engine(iface
);
923 TRACE("(%p)\n", This
);
925 return FACTAudioEngine_DoWork(This
->fact_engine
);
928 static HRESULT WINAPI
IXACT3EngineImpl_CreateSoundBank(IXACT3Engine
*iface
,
929 const void* pvBuffer
, DWORD dwSize
, DWORD dwFlags
,
930 DWORD dwAllocAttributes
, IXACT3SoundBank
**ppSoundBank
)
932 XACT3EngineImpl
*This
= impl_from_IXACT3Engine(iface
);
933 XACT3SoundBankImpl
*sb
;
937 TRACE("(%p)->(%p, %u, 0x%x, 0x%x, %p): stub!\n", This
, pvBuffer
, dwSize
, dwFlags
,
938 dwAllocAttributes
, ppSoundBank
);
940 ret
= FACTAudioEngine_CreateSoundBank(This
->fact_engine
, pvBuffer
, dwSize
,
941 dwFlags
, dwAllocAttributes
, &fsb
);
944 ERR("Failed to CreateSoundBank: %d\n", ret
);
948 sb
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(*sb
));
951 FACTSoundBank_Destroy(fsb
);
952 ERR("Failed to allocate XACT3SoundBankImpl!\n");
953 return E_OUTOFMEMORY
;
956 sb
->IXACT3SoundBank_iface
.lpVtbl
= &XACT3SoundBank_Vtbl
;
957 sb
->fact_soundbank
= fsb
;
958 *ppSoundBank
= &sb
->IXACT3SoundBank_iface
;
960 TRACE("Created SoundBank: %p\n", sb
);
965 static HRESULT WINAPI
IXACT3EngineImpl_CreateInMemoryWaveBank(IXACT3Engine
*iface
,
966 const void* pvBuffer
, DWORD dwSize
, DWORD dwFlags
,
967 DWORD dwAllocAttributes
, IXACT3WaveBank
**ppWaveBank
)
969 XACT3EngineImpl
*This
= impl_from_IXACT3Engine(iface
);
970 XACT3WaveBankImpl
*wb
;
974 TRACE("(%p)->(%p, %u, 0x%x, 0x%x, %p)\n", This
, pvBuffer
, dwSize
, dwFlags
,
975 dwAllocAttributes
, ppWaveBank
);
977 ret
= FACTAudioEngine_CreateInMemoryWaveBank(This
->fact_engine
, pvBuffer
,
978 dwSize
, dwFlags
, dwAllocAttributes
, &fwb
);
981 ERR("Failed to CreateWaveBank: %d\n", ret
);
985 wb
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(*wb
));
988 FACTWaveBank_Destroy(fwb
);
989 ERR("Failed to allocate XACT3WaveBankImpl!\n");
990 return E_OUTOFMEMORY
;
993 wb
->IXACT3WaveBank_iface
.lpVtbl
= &XACT3WaveBank_Vtbl
;
994 wb
->fact_wavebank
= fwb
;
995 *ppWaveBank
= &wb
->IXACT3WaveBank_iface
;
997 TRACE("Created in-memory WaveBank: %p\n", wb
);
1002 static HRESULT WINAPI
IXACT3EngineImpl_CreateStreamingWaveBank(IXACT3Engine
*iface
,
1003 const XACT_WAVEBANK_STREAMING_PARAMETERS
*pParms
,
1004 IXACT3WaveBank
**ppWaveBank
)
1006 XACT3EngineImpl
*This
= impl_from_IXACT3Engine(iface
);
1007 FACTStreamingParameters fakeParms
;
1008 wrap_readfile_struct
*fake
;
1009 XACT3WaveBankImpl
*wb
;
1013 TRACE("(%p)->(%p, %p)\n", This
, pParms
, ppWaveBank
);
1015 /* We have to wrap the file to fix up the callbacks! */
1016 fake
= (wrap_readfile_struct
*) CoTaskMemAlloc(
1017 sizeof(wrap_readfile_struct
));
1018 fake
->engine
= This
;
1019 fake
->file
= pParms
->file
;
1020 fakeParms
.file
= fake
;
1021 fakeParms
.flags
= pParms
->flags
;
1022 fakeParms
.offset
= pParms
->offset
;
1023 fakeParms
.packetSize
= pParms
->packetSize
;
1025 ret
= FACTAudioEngine_CreateStreamingWaveBank(This
->fact_engine
, &fakeParms
,
1029 ERR("Failed to CreateWaveBank: %d\n", ret
);
1033 wb
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(*wb
));
1036 FACTWaveBank_Destroy(fwb
);
1037 ERR("Failed to allocate XACT3WaveBankImpl!\n");
1038 return E_OUTOFMEMORY
;
1041 wb
->IXACT3WaveBank_iface
.lpVtbl
= &XACT3WaveBank_Vtbl
;
1042 wb
->fact_wavebank
= fwb
;
1043 *ppWaveBank
= &wb
->IXACT3WaveBank_iface
;
1045 TRACE("Created streaming WaveBank: %p\n", wb
);
1050 #if XACT3_VER >= 0x0205
1052 static HRESULT WINAPI
IXACT3EngineImpl_PrepareInMemoryWave(IXACT3Engine
*iface
,
1053 DWORD dwFlags
, WAVEBANKENTRY entry
, DWORD
*pdwSeekTable
,
1054 BYTE
*pbWaveData
, DWORD dwPlayOffset
, XACTLOOPCOUNT nLoopCount
,
1055 IXACT3Wave
**ppWave
)
1057 XACT3EngineImpl
*This
= impl_from_IXACT3Engine(iface
);
1058 FIXME("(%p): stub!\n", This
);
1062 static HRESULT WINAPI
IXACT3EngineImpl_PrepareStreamingWave(IXACT3Engine
*iface
,
1063 DWORD dwFlags
, WAVEBANKENTRY entry
,
1064 XACT_STREAMING_PARAMETERS streamingParams
, DWORD dwAlignment
,
1065 DWORD
*pdwSeekTable
, DWORD dwPlayOffset
, XACTLOOPCOUNT nLoopCount
,
1066 IXACT3Wave
**ppWave
)
1068 XACT3EngineImpl
*This
= impl_from_IXACT3Engine(iface
);
1069 FIXME("(%p): stub!\n", This
);
1073 static HRESULT WINAPI
IXACT3EngineImpl_PrepareWave(IXACT3Engine
*iface
,
1074 DWORD dwFlags
, PCSTR szWavePath
, WORD wStreamingPacketSize
,
1075 DWORD dwAlignment
, DWORD dwPlayOffset
, XACTLOOPCOUNT nLoopCount
,
1076 IXACT3Wave
**ppWave
)
1078 XACT3EngineImpl
*This
= impl_from_IXACT3Engine(iface
);
1079 XACT3WaveImpl
*wave
;
1080 FACTWave
*fwave
= NULL
;
1083 TRACE("(%p)->(0x%08x, %s, %d, %d, %d, %d, %p)\n", This
, dwFlags
, debugstr_a(szWavePath
),
1084 wStreamingPacketSize
, dwAlignment
, dwPlayOffset
, nLoopCount
, ppWave
);
1086 ret
= FACTAudioEngine_PrepareWave(This
->fact_engine
, dwFlags
, szWavePath
, wStreamingPacketSize
,
1087 dwAlignment
, dwPlayOffset
, nLoopCount
, &fwave
);
1088 if(ret
!= 0 || !fwave
)
1090 ERR("Failed to CreateWave: %d (%p)\n", ret
, fwave
);
1094 wave
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(*wave
));
1097 FACTWave_Destroy(fwave
);
1098 return E_OUTOFMEMORY
;
1101 wave
->IXACT3Wave_iface
.lpVtbl
= &XACT3Wave_Vtbl
;
1102 wave
->fact_wave
= fwave
;
1103 *ppWave
= &wave
->IXACT3Wave_iface
;
1105 TRACE("Created Wave: %p\n", wave
);
1113 NOTIFY_SoundBank
= 0x01,
1114 NOTIFY_WaveBank
= 0x02,
1117 NOTIFY_cueIndex
= 0x10,
1118 NOTIFY_waveIndex
= 0x20
1121 /* these constants don't have the same values across xactengine versions */
1122 static uint8_t fact_notification_type_from_xact(XACTNOTIFICATIONTYPE type
)
1124 /* we can't use a switch statement, because the constants are static const
1125 * variables, and some compilers can't deal with that */
1126 #define X(a) if (type == XACTNOTIFICATIONTYPE_##a) return FACTNOTIFICATIONTYPE_##a
1132 X(SOUNDBANKDESTROYED
);
1133 X(WAVEBANKDESTROYED
);
1134 X(LOCALVARIABLECHANGED
);
1135 X(GLOBALVARIABLECHANGED
);
1140 X(WAVEBANKPREPARED
);
1141 X(WAVEBANKSTREAMING_INVALIDCONTENT
);
1142 #if XACT3_VER >= 0x0205
1149 FIXME("unknown type %#x\n", type
);
1153 static inline void unwrap_notificationdesc(FACTNotificationDescription
*fd
,
1154 const XACT_NOTIFICATION_DESCRIPTION
*xd
)
1158 TRACE("Type %d\n", xd
->type
);
1160 memset(fd
, 0, sizeof(*fd
));
1162 fd
->type
= fact_notification_type_from_xact(xd
->type
);
1164 /* we can't use a switch statement, because the constants are static const
1165 * variables, and some compilers can't deal with that */
1167 /* Supports SoundBank, Cue index, Cue instance */
1168 if (fd
->type
== FACTNOTIFICATIONTYPE_CUEPREPARED
|| fd
->type
== FACTNOTIFICATIONTYPE_CUEPLAY
||
1169 fd
->type
== FACTNOTIFICATIONTYPE_CUESTOP
|| fd
->type
== FACTNOTIFICATIONTYPE_CUEDESTROYED
||
1170 fd
->type
== FACTNOTIFICATIONTYPE_MARKER
|| fd
->type
== FACTNOTIFICATIONTYPE_LOCALVARIABLECHANGED
)
1172 flags
= NOTIFY_SoundBank
| NOTIFY_cueIndex
| NOTIFY_Cue
;
1174 /* Supports WaveBank */
1175 else if (fd
->type
== FACTNOTIFICATIONTYPE_WAVEBANKDESTROYED
|| fd
->type
== FACTNOTIFICATIONTYPE_WAVEBANKPREPARED
||
1176 fd
->type
== FACTNOTIFICATIONTYPE_WAVEBANKSTREAMING_INVALIDCONTENT
)
1178 flags
= NOTIFY_WaveBank
;
1180 /* Supports NOTIFY_SoundBank */
1181 else if (fd
->type
== FACTNOTIFICATIONTYPE_SOUNDBANKDESTROYED
)
1183 flags
= NOTIFY_SoundBank
;
1185 /* Supports SoundBank, SoundBank, Cue index, Cue instance, WaveBank, Wave instance */
1186 else if (fd
->type
== FACTNOTIFICATIONTYPE_WAVEPLAY
|| fd
->type
== FACTNOTIFICATIONTYPE_WAVESTOP
||
1187 fd
->type
== FACTNOTIFICATIONTYPE_WAVELOOPED
)
1189 flags
= NOTIFY_SoundBank
| NOTIFY_cueIndex
| NOTIFY_Cue
| NOTIFY_WaveBank
| NOTIFY_Wave
;
1191 /* Supports WaveBank, Wave index, Wave instance */
1192 else if (fd
->type
== FACTNOTIFICATIONTYPE_WAVEPREPARED
|| fd
->type
== FACTNOTIFICATIONTYPE_WAVEDESTROYED
)
1194 flags
= NOTIFY_WaveBank
| NOTIFY_waveIndex
| NOTIFY_Wave
;
1197 /* We have to unwrap the FACT object first! */
1198 fd
->flags
= xd
->flags
;
1199 fd
->pvContext
= xd
->pvContext
;
1200 if (flags
& NOTIFY_cueIndex
)
1201 fd
->cueIndex
= xd
->cueIndex
;
1202 #if XACT3_VER >= 0x0205
1203 if (flags
& NOTIFY_waveIndex
)
1204 fd
->waveIndex
= xd
->waveIndex
;
1207 if (flags
& NOTIFY_Cue
&& xd
->pCue
!= NULL
)
1209 XACT3CueImpl
*cue
= impl_from_IXACT3Cue(xd
->pCue
);
1211 fd
->pCue
= cue
->fact_cue
;
1214 if (flags
& NOTIFY_SoundBank
&& xd
->pSoundBank
!= NULL
)
1216 XACT3SoundBankImpl
*sound
= impl_from_IXACT3SoundBank(xd
->pSoundBank
);
1218 fd
->pSoundBank
= sound
->fact_soundbank
;
1221 if (flags
& NOTIFY_WaveBank
&& xd
->pWaveBank
!= NULL
)
1223 XACT3WaveBankImpl
*bank
= impl_from_IXACT3WaveBank(xd
->pWaveBank
);
1225 fd
->pWaveBank
= bank
->fact_wavebank
;
1228 #if XACT3_VER >= 0x0205
1229 if (flags
& NOTIFY_Wave
&& xd
->pWave
!= NULL
)
1231 XACT3WaveImpl
*wave
= impl_from_IXACT3Wave(xd
->pWave
);
1233 fd
->pWave
= wave
->fact_wave
;
1238 static HRESULT WINAPI
IXACT3EngineImpl_RegisterNotification(IXACT3Engine
*iface
,
1239 const XACT_NOTIFICATION_DESCRIPTION
*pNotificationDesc
)
1241 XACT3EngineImpl
*This
= impl_from_IXACT3Engine(iface
);
1242 FACTNotificationDescription fdesc
;
1244 TRACE("(%p)->(%p)\n", This
, pNotificationDesc
);
1246 unwrap_notificationdesc(&fdesc
, pNotificationDesc
);
1247 fdesc
.pvContext
= This
;
1248 return FACTAudioEngine_RegisterNotification(This
->fact_engine
, &fdesc
);
1251 static HRESULT WINAPI
IXACT3EngineImpl_UnRegisterNotification(IXACT3Engine
*iface
,
1252 const XACT_NOTIFICATION_DESCRIPTION
*pNotificationDesc
)
1254 XACT3EngineImpl
*This
= impl_from_IXACT3Engine(iface
);
1255 FACTNotificationDescription fdesc
;
1257 TRACE("(%p)->(%p)\n", This
, pNotificationDesc
);
1259 unwrap_notificationdesc(&fdesc
, pNotificationDesc
);
1260 fdesc
.pvContext
= This
;
1261 return FACTAudioEngine_UnRegisterNotification(This
->fact_engine
, &fdesc
);
1264 static XACTCATEGORY WINAPI
IXACT3EngineImpl_GetCategory(IXACT3Engine
*iface
,
1265 PCSTR szFriendlyName
)
1267 XACT3EngineImpl
*This
= impl_from_IXACT3Engine(iface
);
1269 TRACE("(%p)->(%s)\n", This
, szFriendlyName
);
1271 return FACTAudioEngine_GetCategory(This
->fact_engine
, szFriendlyName
);
1274 static HRESULT WINAPI
IXACT3EngineImpl_Stop(IXACT3Engine
*iface
,
1275 XACTCATEGORY nCategory
, DWORD dwFlags
)
1277 XACT3EngineImpl
*This
= impl_from_IXACT3Engine(iface
);
1279 TRACE("(%p)->(%u, 0x%x)\n", This
, nCategory
, dwFlags
);
1281 return FACTAudioEngine_Stop(This
->fact_engine
, nCategory
, dwFlags
);
1284 static HRESULT WINAPI
IXACT3EngineImpl_SetVolume(IXACT3Engine
*iface
,
1285 XACTCATEGORY nCategory
, XACTVOLUME nVolume
)
1287 XACT3EngineImpl
*This
= impl_from_IXACT3Engine(iface
);
1289 TRACE("(%p)->(%u, %f)\n", This
, nCategory
, nVolume
);
1291 return FACTAudioEngine_SetVolume(This
->fact_engine
, nCategory
, nVolume
);
1294 static HRESULT WINAPI
IXACT3EngineImpl_Pause(IXACT3Engine
*iface
,
1295 XACTCATEGORY nCategory
, BOOL fPause
)
1297 XACT3EngineImpl
*This
= impl_from_IXACT3Engine(iface
);
1299 TRACE("(%p)->(%u, %u)\n", This
, nCategory
, fPause
);
1301 return FACTAudioEngine_Pause(This
->fact_engine
, nCategory
, fPause
);
1304 static XACTVARIABLEINDEX WINAPI
IXACT3EngineImpl_GetGlobalVariableIndex(
1305 IXACT3Engine
*iface
, PCSTR szFriendlyName
)
1307 XACT3EngineImpl
*This
= impl_from_IXACT3Engine(iface
);
1309 TRACE("(%p)->(%s)\n", This
, szFriendlyName
);
1311 return FACTAudioEngine_GetGlobalVariableIndex(This
->fact_engine
,
1315 static HRESULT WINAPI
IXACT3EngineImpl_SetGlobalVariable(IXACT3Engine
*iface
,
1316 XACTVARIABLEINDEX nIndex
, XACTVARIABLEVALUE nValue
)
1318 XACT3EngineImpl
*This
= impl_from_IXACT3Engine(iface
);
1320 TRACE("(%p)->(%u, %f)\n", This
, nIndex
, nValue
);
1322 return FACTAudioEngine_SetGlobalVariable(This
->fact_engine
, nIndex
, nValue
);
1325 static HRESULT WINAPI
IXACT3EngineImpl_GetGlobalVariable(IXACT3Engine
*iface
,
1326 XACTVARIABLEINDEX nIndex
, XACTVARIABLEVALUE
*nValue
)
1328 XACT3EngineImpl
*This
= impl_from_IXACT3Engine(iface
);
1330 TRACE("(%p)->(%u, %p)\n", This
, nIndex
, nValue
);
1332 return FACTAudioEngine_GetGlobalVariable(This
->fact_engine
, nIndex
, nValue
);
1335 static const IXACT3EngineVtbl XACT3Engine_Vtbl
=
1337 IXACT3EngineImpl_QueryInterface
,
1338 IXACT3EngineImpl_AddRef
,
1339 IXACT3EngineImpl_Release
,
1340 IXACT3EngineImpl_GetRendererCount
,
1341 IXACT3EngineImpl_GetRendererDetails
,
1342 #if XACT3_VER >= 0x0205
1343 IXACT3EngineImpl_GetFinalMixFormat
,
1345 IXACT3EngineImpl_Initialize
,
1346 IXACT3EngineImpl_ShutDown
,
1347 IXACT3EngineImpl_DoWork
,
1348 IXACT3EngineImpl_CreateSoundBank
,
1349 IXACT3EngineImpl_CreateInMemoryWaveBank
,
1350 IXACT3EngineImpl_CreateStreamingWaveBank
,
1351 #if XACT3_VER >= 0x0205
1352 IXACT3EngineImpl_PrepareWave
,
1353 IXACT3EngineImpl_PrepareInMemoryWave
,
1354 IXACT3EngineImpl_PrepareStreamingWave
,
1356 IXACT3EngineImpl_RegisterNotification
,
1357 IXACT3EngineImpl_UnRegisterNotification
,
1358 IXACT3EngineImpl_GetCategory
,
1359 IXACT3EngineImpl_Stop
,
1360 IXACT3EngineImpl_SetVolume
,
1361 IXACT3EngineImpl_Pause
,
1362 IXACT3EngineImpl_GetGlobalVariableIndex
,
1363 IXACT3EngineImpl_SetGlobalVariable
,
1364 IXACT3EngineImpl_GetGlobalVariable
1367 void* XACT_Internal_Malloc(size_t size
)
1369 return CoTaskMemAlloc(size
);
1372 void XACT_Internal_Free(void* ptr
)
1374 return CoTaskMemFree(ptr
);
1377 void* XACT_Internal_Realloc(void* ptr
, size_t size
)
1379 return CoTaskMemRealloc(ptr
, size
);
1382 static HRESULT WINAPI
XACT3CF_QueryInterface(IClassFactory
*iface
, REFIID riid
, void **ppobj
)
1384 if(IsEqualGUID(riid
, &IID_IUnknown
) ||
1385 IsEqualGUID(riid
, &IID_IClassFactory
))
1392 WARN("(%p)->(%s, %p): interface not found\n", iface
, debugstr_guid(riid
), ppobj
);
1393 return E_NOINTERFACE
;
1396 static ULONG WINAPI
XACT3CF_AddRef(IClassFactory
*iface
)
1401 static ULONG WINAPI
XACT3CF_Release(IClassFactory
*iface
)
1406 static HRESULT WINAPI
XACT3CF_CreateInstance(IClassFactory
*iface
, IUnknown
*pOuter
,
1407 REFIID riid
, void **ppobj
)
1410 XACT3EngineImpl
*object
;
1412 TRACE("(%p)->(%p,%s,%p)\n", iface
, pOuter
, debugstr_guid(riid
), ppobj
);
1417 return CLASS_E_NOAGGREGATION
;
1419 object
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(*object
));
1421 return E_OUTOFMEMORY
;
1423 object
->IXACT3Engine_iface
.lpVtbl
= &XACT3Engine_Vtbl
;
1425 FACTCreateEngineWithCustomAllocatorEXT(
1427 &object
->fact_engine
,
1428 XACT_Internal_Malloc
,
1430 XACT_Internal_Realloc
1433 hr
= IXACT3Engine_QueryInterface(&object
->IXACT3Engine_iface
, riid
, ppobj
);
1435 HeapFree(GetProcessHeap(), 0, object
);
1442 static HRESULT WINAPI
XACT3CF_LockServer(IClassFactory
*iface
, BOOL dolock
)
1444 TRACE("(%p)->(%d): stub!\n", iface
, dolock
);
1448 static const IClassFactoryVtbl XACT3CF_Vtbl
=
1450 XACT3CF_QueryInterface
,
1453 XACT3CF_CreateInstance
,
1457 static IClassFactory XACTFactory
= { &XACT3CF_Vtbl
};
1459 BOOL WINAPI
DllMain(HINSTANCE hinstDLL
, DWORD reason
, void *pReserved
)
1461 TRACE("(%p, %d, %p)\n", hinstDLL
, reason
, pReserved
);
1465 case DLL_PROCESS_ATTACH
:
1466 DisableThreadLibraryCalls( hinstDLL
);
1468 #ifdef HAVE_FAUDIOLINKEDVERSION
1469 TRACE("Using FAudio version %d\n", FAudioLinkedVersion() );
1477 HRESULT WINAPI
DllGetClassObject(REFCLSID rclsid
, REFIID riid
, void **ppv
)
1479 if (IsEqualGUID(rclsid
, &CLSID_XACTEngine
))
1481 TRACE("(%s, %s, %p)\n", debugstr_guid(rclsid
), debugstr_guid(riid
), ppv
);
1482 return IClassFactory_QueryInterface(&XACTFactory
, riid
, ppv
);
1485 FIXME("Unknown class %s\n", debugstr_guid(rclsid
));
1486 return CLASS_E_CLASSNOTAVAILABLE
;