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
22 #define NONAMELESSUNION
26 #if XACT3_VER < 0x0300
36 #include "wine/debug.h"
38 WINE_DEFAULT_DEBUG_CHANNEL(xact3
);
40 #if XACT3_VER < 0x0300
41 #define IID_IXACT3Engine IID_IXACTEngine
42 #define IXACT3Cue IXACTCue
43 #define IXACT3CueVtbl IXACTCueVtbl
44 #define IXACT3Engine IXACTEngine
45 #define IXACT3EngineVtbl IXACTEngineVtbl
46 #define IXACT3Engine_QueryInterface IXACTEngine_QueryInterface
47 #define IXACT3SoundBank IXACTSoundBank
48 #define IXACT3SoundBankVtbl IXACTSoundBankVtbl
49 #define IXACT3Wave IXACTWave
50 #define IXACT3WaveVtbl IXACTWaveVtbl
51 #define IXACT3WaveBank IXACTWaveBank
52 #define IXACT3WaveBankVtbl IXACTWaveBankVtbl
55 typedef struct _XACT3CueImpl
{
56 IXACT3Cue IXACT3Cue_iface
;
60 static inline XACT3CueImpl
*impl_from_IXACT3Cue(IXACT3Cue
*iface
)
62 return CONTAINING_RECORD(iface
, XACT3CueImpl
, IXACT3Cue_iface
);
65 static HRESULT WINAPI
IXACT3CueImpl_Play(IXACT3Cue
*iface
)
67 XACT3CueImpl
*This
= impl_from_IXACT3Cue(iface
);
69 TRACE("(%p)\n", iface
);
71 return FACTCue_Play(This
->fact_cue
);
74 static HRESULT WINAPI
IXACT3CueImpl_Stop(IXACT3Cue
*iface
, DWORD dwFlags
)
76 XACT3CueImpl
*This
= impl_from_IXACT3Cue(iface
);
78 TRACE("(%p)->(%lu)\n", iface
, dwFlags
);
80 return FACTCue_Stop(This
->fact_cue
, dwFlags
);
83 static HRESULT WINAPI
IXACT3CueImpl_GetState(IXACT3Cue
*iface
, DWORD
*pdwState
)
85 XACT3CueImpl
*This
= impl_from_IXACT3Cue(iface
);
87 TRACE("(%p)->(%p)\n", iface
, pdwState
);
89 return FACTCue_GetState(This
->fact_cue
, (uint32_t *)pdwState
);
92 static HRESULT WINAPI
IXACT3CueImpl_Destroy(IXACT3Cue
*iface
)
94 XACT3CueImpl
*This
= impl_from_IXACT3Cue(iface
);
97 TRACE("(%p)\n", iface
);
99 ret
= FACTCue_Destroy(This
->fact_cue
);
101 WARN("FACTCue_Destroy returned %d\n", ret
);
102 HeapFree(GetProcessHeap(), 0, This
);
106 #if XACT3_VER < 0x0300
108 static HRESULT WINAPI
IXACT3CueImpl_GetChannelMap(IXACT3Cue
*iface
,
109 XACTCHANNELMAP
*map
, DWORD size
, DWORD
*needed_size
)
111 FIXME("(%p)->(%p, %lu, %p)\n", iface
, map
, size
, needed_size
);
116 static HRESULT WINAPI
IXACT3CueImpl_SetChannelMap(IXACT3Cue
*iface
, XACTCHANNELMAP
*map
)
118 FIXME("(%p)->(%p)\n", iface
, map
);
123 static HRESULT WINAPI
IXACT3CueImpl_GetChannelVolume(IXACT3Cue
*iface
, XACTCHANNELVOLUME
*volume
)
125 FIXME("(%p)->(%p)\n", iface
, volume
);
130 static HRESULT WINAPI
IXACT3CueImpl_SetChannelVolume(IXACT3Cue
*iface
, XACTCHANNELVOLUME
*volume
)
132 FIXME("(%p)->(%p)\n", iface
, volume
);
139 static HRESULT WINAPI
IXACT3CueImpl_SetMatrixCoefficients(IXACT3Cue
*iface
,
140 UINT32 uSrcChannelCount
, UINT32 uDstChannelCount
,
141 float *pMatrixCoefficients
)
143 XACT3CueImpl
*This
= impl_from_IXACT3Cue(iface
);
145 TRACE("(%p)->(%u, %u, %p)\n", iface
, uSrcChannelCount
, uDstChannelCount
,
146 pMatrixCoefficients
);
148 return FACTCue_SetMatrixCoefficients(This
->fact_cue
, uSrcChannelCount
,
149 uDstChannelCount
, pMatrixCoefficients
);
152 static XACTVARIABLEINDEX WINAPI
IXACT3CueImpl_GetVariableIndex(IXACT3Cue
*iface
,
153 PCSTR szFriendlyName
)
155 XACT3CueImpl
*This
= impl_from_IXACT3Cue(iface
);
157 TRACE("(%p)->(%s)\n", iface
, szFriendlyName
);
159 return FACTCue_GetVariableIndex(This
->fact_cue
, szFriendlyName
);
162 static HRESULT WINAPI
IXACT3CueImpl_SetVariable(IXACT3Cue
*iface
,
163 XACTVARIABLEINDEX nIndex
, XACTVARIABLEVALUE nValue
)
165 XACT3CueImpl
*This
= impl_from_IXACT3Cue(iface
);
167 TRACE("(%p)->(%u, %f)\n", iface
, nIndex
, nValue
);
169 return FACTCue_SetVariable(This
->fact_cue
, nIndex
, nValue
);
172 static HRESULT WINAPI
IXACT3CueImpl_GetVariable(IXACT3Cue
*iface
,
173 XACTVARIABLEINDEX nIndex
, XACTVARIABLEVALUE
*nValue
)
175 XACT3CueImpl
*This
= impl_from_IXACT3Cue(iface
);
177 TRACE("(%p)->(%u, %p)\n", iface
, nIndex
, nValue
);
179 return FACTCue_GetVariable(This
->fact_cue
, nIndex
, nValue
);
182 static HRESULT WINAPI
IXACT3CueImpl_Pause(IXACT3Cue
*iface
, BOOL fPause
)
184 XACT3CueImpl
*This
= impl_from_IXACT3Cue(iface
);
186 TRACE("(%p)->(%u)\n", iface
, fPause
);
188 return FACTCue_Pause(This
->fact_cue
, fPause
);
191 #if XACT3_VER >= 0x0205
192 static HRESULT WINAPI
IXACT3CueImpl_GetProperties(IXACT3Cue
*iface
,
193 XACT_CUE_INSTANCE_PROPERTIES
**ppProperties
)
195 XACT3CueImpl
*This
= impl_from_IXACT3Cue(iface
);
196 FACTCueInstanceProperties
*fProps
;
199 TRACE("(%p)->(%p)\n", iface
, ppProperties
);
201 hr
= FACTCue_GetProperties(This
->fact_cue
, &fProps
);
205 *ppProperties
= (XACT_CUE_INSTANCE_PROPERTIES
*) fProps
;
210 #if XACT3_VER >= 0x0300
211 static HRESULT WINAPI
IXACT3CueImpl_SetOutputVoices(IXACT3Cue
*iface
,
212 const XAUDIO2_VOICE_SENDS
*pSendList
)
214 XACT3CueImpl
*This
= impl_from_IXACT3Cue(iface
);
215 FIXME("(%p)->(%p): stub!\n", This
, pSendList
);
219 static HRESULT WINAPI
IXACT3CueImpl_SetOutputVoiceMatrix(IXACT3Cue
*iface
,
220 IXAudio2Voice
*pDestinationVoice
, UINT32 SourceChannels
,
221 UINT32 DestinationChannels
, const float *pLevelMatrix
)
223 XACT3CueImpl
*This
= impl_from_IXACT3Cue(iface
);
224 FIXME("(%p)->(%p %u %u %p): stub!\n", This
, pDestinationVoice
, SourceChannels
,
225 DestinationChannels
, pLevelMatrix
);
230 static const IXACT3CueVtbl XACT3Cue_Vtbl
=
234 IXACT3CueImpl_GetState
,
235 IXACT3CueImpl_Destroy
,
236 #if XACT3_VER < 0x0300
237 IXACT3CueImpl_GetChannelMap
,
238 IXACT3CueImpl_SetChannelMap
,
239 IXACT3CueImpl_GetChannelVolume
,
240 IXACT3CueImpl_SetChannelVolume
,
242 IXACT3CueImpl_SetMatrixCoefficients
,
243 IXACT3CueImpl_GetVariableIndex
,
244 IXACT3CueImpl_SetVariable
,
245 IXACT3CueImpl_GetVariable
,
247 #if XACT3_VER >= 0x0205
248 IXACT3CueImpl_GetProperties
,
250 #if XACT3_VER >= 0x0300
251 IXACT3CueImpl_SetOutputVoices
,
252 IXACT3CueImpl_SetOutputVoiceMatrix
256 typedef struct _XACT3SoundBankImpl
{
257 IXACT3SoundBank IXACT3SoundBank_iface
;
259 FACTSoundBank
*fact_soundbank
;
260 } XACT3SoundBankImpl
;
262 static inline XACT3SoundBankImpl
*impl_from_IXACT3SoundBank(IXACT3SoundBank
*iface
)
264 return CONTAINING_RECORD(iface
, XACT3SoundBankImpl
, IXACT3SoundBank_iface
);
267 static XACTINDEX WINAPI
IXACT3SoundBankImpl_GetCueIndex(IXACT3SoundBank
*iface
,
268 PCSTR szFriendlyName
)
270 XACT3SoundBankImpl
*This
= impl_from_IXACT3SoundBank(iface
);
272 TRACE("(%p)->(%s)\n", This
, szFriendlyName
);
274 return FACTSoundBank_GetCueIndex(This
->fact_soundbank
, szFriendlyName
);
277 #if XACT3_VER >= 0x0205
278 static HRESULT WINAPI
IXACT3SoundBankImpl_GetNumCues(IXACT3SoundBank
*iface
,
279 XACTINDEX
*pnNumCues
)
281 XACT3SoundBankImpl
*This
= impl_from_IXACT3SoundBank(iface
);
283 TRACE("(%p)->(%p)\n", This
, pnNumCues
);
285 return FACTSoundBank_GetNumCues(This
->fact_soundbank
, pnNumCues
);
288 static HRESULT WINAPI
IXACT3SoundBankImpl_GetCueProperties(IXACT3SoundBank
*iface
,
289 XACTINDEX nCueIndex
, XACT_CUE_PROPERTIES
*pProperties
)
291 XACT3SoundBankImpl
*This
= impl_from_IXACT3SoundBank(iface
);
293 TRACE("(%p)->(%u, %p)\n", This
, nCueIndex
, pProperties
);
295 return FACTSoundBank_GetCueProperties(This
->fact_soundbank
, nCueIndex
,
296 (FACTCueProperties
*) pProperties
);
300 static HRESULT WINAPI
IXACT3SoundBankImpl_Prepare(IXACT3SoundBank
*iface
,
301 XACTINDEX nCueIndex
, DWORD dwFlags
, XACTTIME timeOffset
,
304 XACT3SoundBankImpl
*This
= impl_from_IXACT3SoundBank(iface
);
309 TRACE("(%p)->(%u, 0x%lx, %lu, %p)\n", This
, nCueIndex
, dwFlags
, timeOffset
,
312 ret
= FACTSoundBank_Prepare(This
->fact_soundbank
, nCueIndex
, dwFlags
,
316 ERR("Failed to CreateCue: %d\n", ret
);
320 cue
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(*cue
));
323 FACTCue_Destroy(fcue
);
324 ERR("Failed to allocate XACT3CueImpl!\n");
325 return E_OUTOFMEMORY
;
328 cue
->IXACT3Cue_iface
.lpVtbl
= &XACT3Cue_Vtbl
;
329 cue
->fact_cue
= fcue
;
330 *ppCue
= &cue
->IXACT3Cue_iface
;
332 TRACE("Created Cue: %p\n", cue
);
337 static HRESULT WINAPI
IXACT3SoundBankImpl_Play(IXACT3SoundBank
*iface
,
338 XACTINDEX nCueIndex
, DWORD dwFlags
, XACTTIME timeOffset
,
341 XACT3SoundBankImpl
*This
= impl_from_IXACT3SoundBank(iface
);
346 TRACE("(%p)->(%u, 0x%lx, %lu, %p)\n", This
, nCueIndex
, dwFlags
, timeOffset
,
349 /* If the application doesn't want a handle, don't generate one at all.
350 * Let the engine handle that memory instead.
354 hr
= FACTSoundBank_Play(This
->fact_soundbank
, nCueIndex
, dwFlags
,
357 hr
= FACTSoundBank_Play(This
->fact_soundbank
, nCueIndex
, dwFlags
,
362 cue
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(*cue
));
365 FACTCue_Destroy(fcue
);
366 ERR("Failed to allocate XACT3CueImpl!\n");
367 return E_OUTOFMEMORY
;
370 cue
->IXACT3Cue_iface
.lpVtbl
= &XACT3Cue_Vtbl
;
371 cue
->fact_cue
= fcue
;
372 *ppCue
= &cue
->IXACT3Cue_iface
;
378 static HRESULT WINAPI
IXACT3SoundBankImpl_Stop(IXACT3SoundBank
*iface
,
379 XACTINDEX nCueIndex
, DWORD dwFlags
)
381 XACT3SoundBankImpl
*This
= impl_from_IXACT3SoundBank(iface
);
383 TRACE("(%p)->(%lu)\n", This
, dwFlags
);
385 return FACTSoundBank_Stop(This
->fact_soundbank
, nCueIndex
, dwFlags
);
388 static HRESULT WINAPI
IXACT3SoundBankImpl_Destroy(IXACT3SoundBank
*iface
)
390 XACT3SoundBankImpl
*This
= impl_from_IXACT3SoundBank(iface
);
393 TRACE("(%p)\n", This
);
395 hr
= FACTSoundBank_Destroy(This
->fact_soundbank
);
396 HeapFree(GetProcessHeap(), 0, This
);
400 static HRESULT WINAPI
IXACT3SoundBankImpl_GetState(IXACT3SoundBank
*iface
,
403 XACT3SoundBankImpl
*This
= impl_from_IXACT3SoundBank(iface
);
405 TRACE("(%p)->(%p)\n", This
, pdwState
);
407 return FACTSoundBank_GetState(This
->fact_soundbank
, (uint32_t *)pdwState
);
410 static const IXACT3SoundBankVtbl XACT3SoundBank_Vtbl
=
412 IXACT3SoundBankImpl_GetCueIndex
,
413 #if XACT3_VER >= 0x0205
414 IXACT3SoundBankImpl_GetNumCues
,
415 IXACT3SoundBankImpl_GetCueProperties
,
417 IXACT3SoundBankImpl_Prepare
,
418 IXACT3SoundBankImpl_Play
,
419 IXACT3SoundBankImpl_Stop
,
420 IXACT3SoundBankImpl_Destroy
,
421 IXACT3SoundBankImpl_GetState
424 #if XACT3_VER >= 0x0205
426 typedef struct _XACT3WaveImpl
{
427 IXACT3Wave IXACT3Wave_iface
;
432 static inline XACT3WaveImpl
*impl_from_IXACT3Wave(IXACT3Wave
*iface
)
434 return CONTAINING_RECORD(iface
, XACT3WaveImpl
, IXACT3Wave_iface
);
437 static HRESULT WINAPI
IXACT3WaveImpl_Destroy(IXACT3Wave
*iface
)
439 XACT3WaveImpl
*This
= impl_from_IXACT3Wave(iface
);
442 TRACE("(%p)\n", This
);
444 hr
= FACTWave_Destroy(This
->fact_wave
);
445 HeapFree(GetProcessHeap(), 0, This
);
449 static HRESULT WINAPI
IXACT3WaveImpl_Play(IXACT3Wave
*iface
)
451 XACT3WaveImpl
*This
= impl_from_IXACT3Wave(iface
);
453 TRACE("(%p)\n", This
);
455 return FACTWave_Play(This
->fact_wave
);
458 static HRESULT WINAPI
IXACT3WaveImpl_Stop(IXACT3Wave
*iface
, DWORD dwFlags
)
460 XACT3WaveImpl
*This
= impl_from_IXACT3Wave(iface
);
462 TRACE("(%p)->(0x%lx)\n", This
, dwFlags
);
464 return FACTWave_Stop(This
->fact_wave
, dwFlags
);
467 static HRESULT WINAPI
IXACT3WaveImpl_Pause(IXACT3Wave
*iface
, BOOL fPause
)
469 XACT3WaveImpl
*This
= impl_from_IXACT3Wave(iface
);
471 TRACE("(%p)->(%u)\n", This
, fPause
);
473 return FACTWave_Pause(This
->fact_wave
, fPause
);
476 static HRESULT WINAPI
IXACT3WaveImpl_GetState(IXACT3Wave
*iface
, DWORD
*pdwState
)
478 XACT3WaveImpl
*This
= impl_from_IXACT3Wave(iface
);
480 TRACE("(%p)->(%p)\n", This
, pdwState
);
482 return FACTWave_GetState(This
->fact_wave
, (uint32_t *)pdwState
);
485 static HRESULT WINAPI
IXACT3WaveImpl_SetPitch(IXACT3Wave
*iface
, XACTPITCH pitch
)
487 XACT3WaveImpl
*This
= impl_from_IXACT3Wave(iface
);
489 TRACE("(%p)->(%d)\n", This
, pitch
);
491 return FACTWave_SetPitch(This
->fact_wave
, pitch
);
494 static HRESULT WINAPI
IXACT3WaveImpl_SetVolume(IXACT3Wave
*iface
, XACTVOLUME volume
)
496 XACT3WaveImpl
*This
= impl_from_IXACT3Wave(iface
);
498 TRACE("(%p)->(%f)\n", This
, volume
);
500 return FACTWave_SetVolume(This
->fact_wave
, volume
);
503 static HRESULT WINAPI
IXACT3WaveImpl_SetMatrixCoefficients(IXACT3Wave
*iface
,
504 UINT32 uSrcChannelCount
, UINT32 uDstChannelCount
,
505 float *pMatrixCoefficients
)
507 XACT3WaveImpl
*This
= impl_from_IXACT3Wave(iface
);
509 TRACE("(%p)->(%u, %u, %p)\n", This
, uSrcChannelCount
, uDstChannelCount
,
510 pMatrixCoefficients
);
512 return FACTWave_SetMatrixCoefficients(This
->fact_wave
, uSrcChannelCount
,
513 uDstChannelCount
, pMatrixCoefficients
);
516 static HRESULT WINAPI
IXACT3WaveImpl_GetProperties(IXACT3Wave
*iface
,
517 XACT_WAVE_INSTANCE_PROPERTIES
*pProperties
)
519 XACT3WaveImpl
*This
= impl_from_IXACT3Wave(iface
);
521 TRACE("(%p)->(%p)\n", This
, pProperties
);
523 return FACTWave_GetProperties(This
->fact_wave
,
524 (FACTWaveInstanceProperties
*) pProperties
);
527 static const IXACT3WaveVtbl XACT3Wave_Vtbl
=
529 IXACT3WaveImpl_Destroy
,
532 IXACT3WaveImpl_Pause
,
533 IXACT3WaveImpl_GetState
,
534 IXACT3WaveImpl_SetPitch
,
535 IXACT3WaveImpl_SetVolume
,
536 IXACT3WaveImpl_SetMatrixCoefficients
,
537 IXACT3WaveImpl_GetProperties
542 typedef struct _XACT3WaveBankImpl
{
543 IXACT3WaveBank IXACT3WaveBank_iface
;
545 FACTWaveBank
*fact_wavebank
;
548 static inline XACT3WaveBankImpl
*impl_from_IXACT3WaveBank(IXACT3WaveBank
*iface
)
550 return CONTAINING_RECORD(iface
, XACT3WaveBankImpl
, IXACT3WaveBank_iface
);
553 static HRESULT WINAPI
IXACT3WaveBankImpl_Destroy(IXACT3WaveBank
*iface
)
555 XACT3WaveBankImpl
*This
= impl_from_IXACT3WaveBank(iface
);
558 TRACE("(%p)\n", This
);
560 hr
= FACTWaveBank_Destroy(This
->fact_wavebank
);
561 HeapFree(GetProcessHeap(), 0, This
);
565 #if XACT3_VER >= 0x0205
567 static HRESULT WINAPI
IXACT3WaveBankImpl_GetNumWaves(IXACT3WaveBank
*iface
,
568 XACTINDEX
*pnNumWaves
)
570 XACT3WaveBankImpl
*This
= impl_from_IXACT3WaveBank(iface
);
572 TRACE("(%p)->(%p)\n", This
, pnNumWaves
);
574 return FACTWaveBank_GetNumWaves(This
->fact_wavebank
, pnNumWaves
);
577 static XACTINDEX WINAPI
IXACT3WaveBankImpl_GetWaveIndex(IXACT3WaveBank
*iface
,
578 PCSTR szFriendlyName
)
580 XACT3WaveBankImpl
*This
= impl_from_IXACT3WaveBank(iface
);
582 TRACE("(%p)->(%s)\n", This
, szFriendlyName
);
584 return FACTWaveBank_GetWaveIndex(This
->fact_wavebank
, szFriendlyName
);
587 static HRESULT WINAPI
IXACT3WaveBankImpl_GetWaveProperties(IXACT3WaveBank
*iface
,
588 XACTINDEX nWaveIndex
, XACT_WAVE_PROPERTIES
*pWaveProperties
)
590 XACT3WaveBankImpl
*This
= impl_from_IXACT3WaveBank(iface
);
592 TRACE("(%p)->(%u, %p)\n", This
, nWaveIndex
, pWaveProperties
);
594 return FACTWaveBank_GetWaveProperties(This
->fact_wavebank
, nWaveIndex
,
595 (FACTWaveProperties
*) pWaveProperties
);
598 static HRESULT WINAPI
IXACT3WaveBankImpl_Prepare(IXACT3WaveBank
*iface
,
599 XACTINDEX nWaveIndex
, DWORD dwFlags
, DWORD dwPlayOffset
,
600 XACTLOOPCOUNT nLoopCount
, IXACT3Wave
** ppWave
)
602 XACT3WaveBankImpl
*This
= impl_from_IXACT3WaveBank(iface
);
607 TRACE("(%p)->(0x%x, %lu, 0x%lx, %u, %p)\n", This
, nWaveIndex
, dwFlags
,
608 dwPlayOffset
, nLoopCount
, ppWave
);
610 ret
= FACTWaveBank_Prepare(This
->fact_wavebank
, nWaveIndex
, dwFlags
,
611 dwPlayOffset
, nLoopCount
, &fwave
);
614 ERR("Failed to CreateWave: %d\n", ret
);
618 wave
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(*wave
));
621 FACTWave_Destroy(fwave
);
622 ERR("Failed to allocate XACT3WaveImpl!\n");
623 return E_OUTOFMEMORY
;
626 wave
->IXACT3Wave_iface
.lpVtbl
= &XACT3Wave_Vtbl
;
627 wave
->fact_wave
= fwave
;
628 *ppWave
= &wave
->IXACT3Wave_iface
;
630 TRACE("Created Wave: %p\n", wave
);
635 static HRESULT WINAPI
IXACT3WaveBankImpl_Play(IXACT3WaveBank
*iface
,
636 XACTINDEX nWaveIndex
, DWORD dwFlags
, DWORD dwPlayOffset
,
637 XACTLOOPCOUNT nLoopCount
, IXACT3Wave
** ppWave
)
639 XACT3WaveBankImpl
*This
= impl_from_IXACT3WaveBank(iface
);
644 TRACE("(%p)->(0x%x, %lu, 0x%lx, %u, %p)\n", This
, nWaveIndex
, dwFlags
, dwPlayOffset
,
647 /* If the application doesn't want a handle, don't generate one at all.
648 * Let the engine handle that memory instead.
652 hr
= FACTWaveBank_Play(This
->fact_wavebank
, nWaveIndex
, dwFlags
,
653 dwPlayOffset
, nLoopCount
, NULL
);
655 hr
= FACTWaveBank_Play(This
->fact_wavebank
, nWaveIndex
, dwFlags
,
656 dwPlayOffset
, nLoopCount
, &fwave
);
660 wave
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(*wave
));
663 FACTWave_Destroy(fwave
);
664 ERR("Failed to allocate XACT3WaveImpl!\n");
665 return E_OUTOFMEMORY
;
668 wave
->IXACT3Wave_iface
.lpVtbl
= &XACT3Wave_Vtbl
;
669 wave
->fact_wave
= fwave
;
670 *ppWave
= &wave
->IXACT3Wave_iface
;
676 static HRESULT WINAPI
IXACT3WaveBankImpl_Stop(IXACT3WaveBank
*iface
,
677 XACTINDEX nWaveIndex
, DWORD dwFlags
)
679 XACT3WaveBankImpl
*This
= impl_from_IXACT3WaveBank(iface
);
681 TRACE("(%p)->(%u, %lu)\n", This
, nWaveIndex
, dwFlags
);
683 return FACTWaveBank_Stop(This
->fact_wavebank
, nWaveIndex
, dwFlags
);
688 static HRESULT WINAPI
IXACT3WaveBankImpl_GetState(IXACT3WaveBank
*iface
,
691 XACT3WaveBankImpl
*This
= impl_from_IXACT3WaveBank(iface
);
693 TRACE("(%p)->(%p)\n", This
, pdwState
);
695 return FACTWaveBank_GetState(This
->fact_wavebank
, (uint32_t *)pdwState
);
698 static const IXACT3WaveBankVtbl XACT3WaveBank_Vtbl
=
700 IXACT3WaveBankImpl_Destroy
,
701 #if XACT3_VER >= 0x0205
702 IXACT3WaveBankImpl_GetNumWaves
,
703 IXACT3WaveBankImpl_GetWaveIndex
,
704 IXACT3WaveBankImpl_GetWaveProperties
,
705 IXACT3WaveBankImpl_Prepare
,
706 IXACT3WaveBankImpl_Play
,
707 IXACT3WaveBankImpl_Stop
,
709 IXACT3WaveBankImpl_GetState
712 typedef struct _XACT3EngineImpl
{
713 IXACT3Engine IXACT3Engine_iface
;
715 FACTAudioEngine
*fact_engine
;
717 XACT_READFILE_CALLBACK pReadFile
;
718 XACT_GETOVERLAPPEDRESULT_CALLBACK pGetOverlappedResult
;
719 XACT_NOTIFICATION_CALLBACK notification_callback
;
722 typedef struct wrap_readfile_struct
{
723 XACT3EngineImpl
*engine
;
725 } wrap_readfile_struct
;
727 static int32_t FACTCALL
wrap_readfile(
730 uint32_t nNumberOfBytesRead
,
731 uint32_t *lpNumberOfBytesRead
,
732 FACTOverlapped
*lpOverlapped
)
734 wrap_readfile_struct
*wrap
= (wrap_readfile_struct
*) hFile
;
735 return wrap
->engine
->pReadFile(wrap
->file
, lpBuffer
, nNumberOfBytesRead
,
736 (DWORD
*)lpNumberOfBytesRead
, (LPOVERLAPPED
)lpOverlapped
);
739 static int32_t FACTCALL
wrap_getoverlappedresult(
741 FACTOverlapped
*lpOverlapped
,
742 uint32_t *lpNumberOfBytesTransferred
,
745 wrap_readfile_struct
*wrap
= (wrap_readfile_struct
*) hFile
;
746 return wrap
->engine
->pGetOverlappedResult(wrap
->file
, (LPOVERLAPPED
)lpOverlapped
,
747 (DWORD
*)lpNumberOfBytesTransferred
, bWait
);
750 static inline XACT3EngineImpl
*impl_from_IXACT3Engine(IXACT3Engine
*iface
)
752 return CONTAINING_RECORD(iface
, XACT3EngineImpl
, IXACT3Engine_iface
);
755 static HRESULT WINAPI
IXACT3EngineImpl_QueryInterface(IXACT3Engine
*iface
,
756 REFIID riid
, void **ppvObject
)
758 XACT3EngineImpl
*This
= impl_from_IXACT3Engine(iface
);
760 TRACE("(%p)->(%s, %p)\n", This
, debugstr_guid(riid
), ppvObject
);
762 if(IsEqualGUID(riid
, &IID_IUnknown
) ||
763 IsEqualGUID(riid
, &IID_IXACT3Engine
)){
764 *ppvObject
= &This
->IXACT3Engine_iface
;
770 IUnknown_AddRef((IUnknown
*)*ppvObject
);
774 FIXME("(%p)->(%s,%p), not found\n", This
, debugstr_guid(riid
), ppvObject
);
776 return E_NOINTERFACE
;
779 static ULONG WINAPI
IXACT3EngineImpl_AddRef(IXACT3Engine
*iface
)
781 XACT3EngineImpl
*This
= impl_from_IXACT3Engine(iface
);
782 ULONG ref
= FACTAudioEngine_AddRef(This
->fact_engine
);
783 TRACE("(%p)->(): Refcount now %lu\n", This
, ref
);
787 static ULONG WINAPI
IXACT3EngineImpl_Release(IXACT3Engine
*iface
)
789 XACT3EngineImpl
*This
= impl_from_IXACT3Engine(iface
);
790 ULONG ref
= FACTAudioEngine_Release(This
->fact_engine
);
792 TRACE("(%p)->(): Refcount now %lu\n", This
, ref
);
795 HeapFree(GetProcessHeap(), 0, This
);
799 static HRESULT WINAPI
IXACT3EngineImpl_GetRendererCount(IXACT3Engine
*iface
,
800 XACTINDEX
*pnRendererCount
)
802 XACT3EngineImpl
*This
= impl_from_IXACT3Engine(iface
);
804 TRACE("(%p)->(%p)\n", This
, pnRendererCount
);
806 return FACTAudioEngine_GetRendererCount(This
->fact_engine
, pnRendererCount
);
809 static HRESULT WINAPI
IXACT3EngineImpl_GetRendererDetails(IXACT3Engine
*iface
,
810 XACTINDEX nRendererIndex
, XACT_RENDERER_DETAILS
*pRendererDetails
)
812 XACT3EngineImpl
*This
= impl_from_IXACT3Engine(iface
);
814 TRACE("(%p)->(%d, %p)\n", This
, nRendererIndex
, pRendererDetails
);
816 return FACTAudioEngine_GetRendererDetails(This
->fact_engine
,
817 nRendererIndex
, (FACTRendererDetails
*) pRendererDetails
);
820 #if XACT3_VER >= 0x0205
822 static HRESULT WINAPI
IXACT3EngineImpl_GetFinalMixFormat(IXACT3Engine
*iface
,
823 WAVEFORMATEXTENSIBLE
*pFinalMixFormat
)
825 XACT3EngineImpl
*This
= impl_from_IXACT3Engine(iface
);
827 TRACE("(%p)->(%p)\n", This
, pFinalMixFormat
);
829 return FACTAudioEngine_GetFinalMixFormat(This
->fact_engine
,
830 (FAudioWaveFormatExtensible
*) pFinalMixFormat
);
835 static void FACTCALL
fact_notification_cb(const FACTNotification
*notification
)
837 XACT3EngineImpl
*engine
= (XACT3EngineImpl
*)notification
->pvContext
;
839 /* Older versions of FAudio don't pass through the context */
842 WARN("Notification context is NULL\n");
846 FIXME("Unsupported callback type %d\n", notification
->type
);
849 static HRESULT WINAPI
IXACT3EngineImpl_Initialize(IXACT3Engine
*iface
,
850 const XACT_RUNTIME_PARAMETERS
*pParams
)
852 XACT3EngineImpl
*This
= impl_from_IXACT3Engine(iface
);
853 FACTRuntimeParameters params
;
856 TRACE("(%p)->(%p)\n", This
, pParams
);
858 memset(¶ms
, 0, sizeof(FACTRuntimeParameters
));
859 /* Explicitly copy to the FAudio structure as the packing is wrong under 64 bits */
860 params
.lookAheadTime
= pParams
->lookAheadTime
;
861 params
.pGlobalSettingsBuffer
= pParams
->pGlobalSettingsBuffer
;
862 params
.globalSettingsBufferSize
= pParams
->globalSettingsBufferSize
;
863 params
.globalSettingsFlags
= pParams
->globalSettingsFlags
;
864 params
.globalSettingsAllocAttributes
= pParams
->globalSettingsAllocAttributes
;
865 params
.pRendererID
= (int16_t*)pParams
->pRendererID
;
866 params
.pXAudio2
= NULL
;
867 params
.pMasteringVoice
= NULL
;
869 #if XACT3_VER >= 0x0300
870 /* FIXME: pXAudio2 and pMasteringVoice are pointers to
871 * IXAudio2/IXAudio2MasteringVoice objects. FACT wants pointers to
872 * FAudio/FAudioMasteringVoice objects. In Wine's XAudio2 implementation, we
873 * actually have them available, but only if you access their internal data.
874 * For now we can just force these pointers to NULL, as XACT simply
875 * generates its own engine and endpoint in that situation. These parameters
876 * are mostly an optimization for games with multiple XACT3Engines that want
877 * a single engine running everything.
880 if (pParams
->pXAudio2
!= NULL
){
881 FIXME("pXAudio2 parameter not supported!\n");
883 if (pParams
->pMasteringVoice
!= NULL
){
884 FIXME("pMasteringVoice parameter not supported!\n");
889 /* Force Windows I/O, do NOT use the FACT default! */
890 This
->pReadFile
= (XACT_READFILE_CALLBACK
)
891 pParams
->fileIOCallbacks
.readFileCallback
;
892 This
->pGetOverlappedResult
= (XACT_GETOVERLAPPEDRESULT_CALLBACK
)
893 pParams
->fileIOCallbacks
.getOverlappedResultCallback
;
894 if (This
->pReadFile
== NULL
)
895 This
->pReadFile
= (XACT_READFILE_CALLBACK
) ReadFile
;
896 if (This
->pGetOverlappedResult
== NULL
)
897 This
->pGetOverlappedResult
= (XACT_GETOVERLAPPEDRESULT_CALLBACK
)
899 params
.fileIOCallbacks
.readFileCallback
= wrap_readfile
;
900 params
.fileIOCallbacks
.getOverlappedResultCallback
= wrap_getoverlappedresult
;
901 params
.fnNotificationCallback
= fact_notification_cb
;
903 This
->notification_callback
= (XACT_NOTIFICATION_CALLBACK
)pParams
->fnNotificationCallback
;
905 ret
= FACTAudioEngine_Initialize(This
->fact_engine
, ¶ms
);
907 WARN("FACTAudioEngine_Initialize returned %d\n", ret
);
909 return !ret
? S_OK
: E_FAIL
;
912 static HRESULT WINAPI
IXACT3EngineImpl_ShutDown(IXACT3Engine
*iface
)
914 XACT3EngineImpl
*This
= impl_from_IXACT3Engine(iface
);
916 TRACE("(%p)\n", This
);
918 return FACTAudioEngine_ShutDown(This
->fact_engine
);
921 static HRESULT WINAPI
IXACT3EngineImpl_DoWork(IXACT3Engine
*iface
)
923 XACT3EngineImpl
*This
= impl_from_IXACT3Engine(iface
);
925 TRACE("(%p)\n", This
);
927 return FACTAudioEngine_DoWork(This
->fact_engine
);
930 static HRESULT WINAPI
IXACT3EngineImpl_CreateSoundBank(IXACT3Engine
*iface
,
931 const void* pvBuffer
, DWORD dwSize
, DWORD dwFlags
,
932 DWORD dwAllocAttributes
, IXACT3SoundBank
**ppSoundBank
)
934 XACT3EngineImpl
*This
= impl_from_IXACT3Engine(iface
);
935 XACT3SoundBankImpl
*sb
;
939 TRACE("(%p)->(%p, %lu, 0x%lx, 0x%lx, %p): stub!\n", This
, pvBuffer
, dwSize
, dwFlags
,
940 dwAllocAttributes
, ppSoundBank
);
942 ret
= FACTAudioEngine_CreateSoundBank(This
->fact_engine
, pvBuffer
, dwSize
,
943 dwFlags
, dwAllocAttributes
, &fsb
);
946 ERR("Failed to CreateSoundBank: %d\n", ret
);
950 sb
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(*sb
));
953 FACTSoundBank_Destroy(fsb
);
954 ERR("Failed to allocate XACT3SoundBankImpl!\n");
955 return E_OUTOFMEMORY
;
958 sb
->IXACT3SoundBank_iface
.lpVtbl
= &XACT3SoundBank_Vtbl
;
959 sb
->fact_soundbank
= fsb
;
960 *ppSoundBank
= &sb
->IXACT3SoundBank_iface
;
962 TRACE("Created SoundBank: %p\n", sb
);
967 static HRESULT WINAPI
IXACT3EngineImpl_CreateInMemoryWaveBank(IXACT3Engine
*iface
,
968 const void* pvBuffer
, DWORD dwSize
, DWORD dwFlags
,
969 DWORD dwAllocAttributes
, IXACT3WaveBank
**ppWaveBank
)
971 XACT3EngineImpl
*This
= impl_from_IXACT3Engine(iface
);
972 XACT3WaveBankImpl
*wb
;
976 TRACE("(%p)->(%p, %lu, 0x%lx, 0x%lx, %p)\n", This
, pvBuffer
, dwSize
, dwFlags
,
977 dwAllocAttributes
, ppWaveBank
);
979 ret
= FACTAudioEngine_CreateInMemoryWaveBank(This
->fact_engine
, pvBuffer
,
980 dwSize
, dwFlags
, dwAllocAttributes
, &fwb
);
983 ERR("Failed to CreateWaveBank: %d\n", ret
);
987 wb
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(*wb
));
990 FACTWaveBank_Destroy(fwb
);
991 ERR("Failed to allocate XACT3WaveBankImpl!\n");
992 return E_OUTOFMEMORY
;
995 wb
->IXACT3WaveBank_iface
.lpVtbl
= &XACT3WaveBank_Vtbl
;
996 wb
->fact_wavebank
= fwb
;
997 *ppWaveBank
= &wb
->IXACT3WaveBank_iface
;
999 TRACE("Created in-memory WaveBank: %p\n", wb
);
1004 static HRESULT WINAPI
IXACT3EngineImpl_CreateStreamingWaveBank(IXACT3Engine
*iface
,
1005 const XACT_WAVEBANK_STREAMING_PARAMETERS
*pParms
,
1006 IXACT3WaveBank
**ppWaveBank
)
1008 XACT3EngineImpl
*This
= impl_from_IXACT3Engine(iface
);
1009 FACTStreamingParameters fakeParms
;
1010 wrap_readfile_struct
*fake
;
1011 XACT3WaveBankImpl
*wb
;
1015 TRACE("(%p)->(%p, %p)\n", This
, pParms
, ppWaveBank
);
1017 /* We have to wrap the file to fix up the callbacks! */
1018 fake
= (wrap_readfile_struct
*) CoTaskMemAlloc(
1019 sizeof(wrap_readfile_struct
));
1020 fake
->engine
= This
;
1021 fake
->file
= pParms
->file
;
1022 fakeParms
.file
= fake
;
1023 fakeParms
.flags
= pParms
->flags
;
1024 fakeParms
.offset
= pParms
->offset
;
1025 fakeParms
.packetSize
= pParms
->packetSize
;
1027 ret
= FACTAudioEngine_CreateStreamingWaveBank(This
->fact_engine
, &fakeParms
,
1031 ERR("Failed to CreateWaveBank: %d\n", ret
);
1035 wb
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(*wb
));
1038 FACTWaveBank_Destroy(fwb
);
1039 ERR("Failed to allocate XACT3WaveBankImpl!\n");
1040 return E_OUTOFMEMORY
;
1043 wb
->IXACT3WaveBank_iface
.lpVtbl
= &XACT3WaveBank_Vtbl
;
1044 wb
->fact_wavebank
= fwb
;
1045 *ppWaveBank
= &wb
->IXACT3WaveBank_iface
;
1047 TRACE("Created streaming WaveBank: %p\n", wb
);
1052 #if XACT3_VER >= 0x0205
1054 static HRESULT WINAPI
IXACT3EngineImpl_PrepareInMemoryWave(IXACT3Engine
*iface
,
1055 DWORD dwFlags
, WAVEBANKENTRY entry
, DWORD
*pdwSeekTable
,
1056 BYTE
*pbWaveData
, DWORD dwPlayOffset
, XACTLOOPCOUNT nLoopCount
,
1057 IXACT3Wave
**ppWave
)
1059 XACT3EngineImpl
*This
= impl_from_IXACT3Engine(iface
);
1060 FIXME("(%p): stub!\n", This
);
1064 static HRESULT WINAPI
IXACT3EngineImpl_PrepareStreamingWave(IXACT3Engine
*iface
,
1065 DWORD dwFlags
, WAVEBANKENTRY entry
,
1066 XACT_STREAMING_PARAMETERS streamingParams
, DWORD dwAlignment
,
1067 DWORD
*pdwSeekTable
, DWORD dwPlayOffset
, XACTLOOPCOUNT nLoopCount
,
1068 IXACT3Wave
**ppWave
)
1070 XACT3EngineImpl
*This
= impl_from_IXACT3Engine(iface
);
1071 FIXME("(%p): stub!\n", This
);
1075 static HRESULT WINAPI
IXACT3EngineImpl_PrepareWave(IXACT3Engine
*iface
,
1076 DWORD dwFlags
, PCSTR szWavePath
, WORD wStreamingPacketSize
,
1077 DWORD dwAlignment
, DWORD dwPlayOffset
, XACTLOOPCOUNT nLoopCount
,
1078 IXACT3Wave
**ppWave
)
1080 XACT3EngineImpl
*This
= impl_from_IXACT3Engine(iface
);
1081 XACT3WaveImpl
*wave
;
1082 FACTWave
*fwave
= NULL
;
1085 TRACE("(%p)->(0x%08lx, %s, %d, %ld, %ld, %d, %p)\n", This
, dwFlags
, debugstr_a(szWavePath
),
1086 wStreamingPacketSize
, dwAlignment
, dwPlayOffset
, nLoopCount
, ppWave
);
1088 ret
= FACTAudioEngine_PrepareWave(This
->fact_engine
, dwFlags
, szWavePath
, wStreamingPacketSize
,
1089 dwAlignment
, dwPlayOffset
, nLoopCount
, &fwave
);
1090 if(ret
!= 0 || !fwave
)
1092 ERR("Failed to CreateWave: %d (%p)\n", ret
, fwave
);
1096 wave
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(*wave
));
1099 FACTWave_Destroy(fwave
);
1100 return E_OUTOFMEMORY
;
1103 wave
->IXACT3Wave_iface
.lpVtbl
= &XACT3Wave_Vtbl
;
1104 wave
->fact_wave
= fwave
;
1105 *ppWave
= &wave
->IXACT3Wave_iface
;
1107 TRACE("Created Wave: %p\n", wave
);
1115 NOTIFY_SoundBank
= 0x01,
1116 NOTIFY_WaveBank
= 0x02,
1119 NOTIFY_cueIndex
= 0x10,
1120 NOTIFY_waveIndex
= 0x20
1123 /* these constants don't have the same values across xactengine versions */
1124 static uint8_t fact_notification_type_from_xact(XACTNOTIFICATIONTYPE type
)
1126 /* we can't use a switch statement, because the constants are static const
1127 * variables, and some compilers can't deal with that */
1128 #define X(a) if (type == XACTNOTIFICATIONTYPE_##a) return FACTNOTIFICATIONTYPE_##a
1134 X(SOUNDBANKDESTROYED
);
1135 X(WAVEBANKDESTROYED
);
1136 X(LOCALVARIABLECHANGED
);
1137 X(GLOBALVARIABLECHANGED
);
1142 X(WAVEBANKPREPARED
);
1143 X(WAVEBANKSTREAMING_INVALIDCONTENT
);
1144 #if XACT3_VER >= 0x0205
1151 FIXME("unknown type %#x\n", type
);
1155 static inline void unwrap_notificationdesc(FACTNotificationDescription
*fd
,
1156 const XACT_NOTIFICATION_DESCRIPTION
*xd
)
1160 TRACE("Type %d\n", xd
->type
);
1162 memset(fd
, 0, sizeof(*fd
));
1164 fd
->type
= fact_notification_type_from_xact(xd
->type
);
1166 /* we can't use a switch statement, because the constants are static const
1167 * variables, and some compilers can't deal with that */
1169 /* Supports SoundBank, Cue index, Cue instance */
1170 if (fd
->type
== FACTNOTIFICATIONTYPE_CUEPREPARED
|| fd
->type
== FACTNOTIFICATIONTYPE_CUEPLAY
||
1171 fd
->type
== FACTNOTIFICATIONTYPE_CUESTOP
|| fd
->type
== FACTNOTIFICATIONTYPE_CUEDESTROYED
||
1172 fd
->type
== FACTNOTIFICATIONTYPE_MARKER
|| fd
->type
== FACTNOTIFICATIONTYPE_LOCALVARIABLECHANGED
)
1174 flags
= NOTIFY_SoundBank
| NOTIFY_cueIndex
| NOTIFY_Cue
;
1176 /* Supports WaveBank */
1177 else if (fd
->type
== FACTNOTIFICATIONTYPE_WAVEBANKDESTROYED
|| fd
->type
== FACTNOTIFICATIONTYPE_WAVEBANKPREPARED
||
1178 fd
->type
== FACTNOTIFICATIONTYPE_WAVEBANKSTREAMING_INVALIDCONTENT
)
1180 flags
= NOTIFY_WaveBank
;
1182 /* Supports NOTIFY_SoundBank */
1183 else if (fd
->type
== FACTNOTIFICATIONTYPE_SOUNDBANKDESTROYED
)
1185 flags
= NOTIFY_SoundBank
;
1187 /* Supports SoundBank, SoundBank, Cue index, Cue instance, WaveBank, Wave instance */
1188 else if (fd
->type
== FACTNOTIFICATIONTYPE_WAVEPLAY
|| fd
->type
== FACTNOTIFICATIONTYPE_WAVESTOP
||
1189 fd
->type
== FACTNOTIFICATIONTYPE_WAVELOOPED
)
1191 flags
= NOTIFY_SoundBank
| NOTIFY_cueIndex
| NOTIFY_Cue
| NOTIFY_WaveBank
| NOTIFY_Wave
;
1193 /* Supports WaveBank, Wave index, Wave instance */
1194 else if (fd
->type
== FACTNOTIFICATIONTYPE_WAVEPREPARED
|| fd
->type
== FACTNOTIFICATIONTYPE_WAVEDESTROYED
)
1196 flags
= NOTIFY_WaveBank
| NOTIFY_waveIndex
| NOTIFY_Wave
;
1199 /* We have to unwrap the FACT object first! */
1200 fd
->flags
= xd
->flags
;
1201 fd
->pvContext
= xd
->pvContext
;
1202 if (flags
& NOTIFY_cueIndex
)
1203 fd
->cueIndex
= xd
->cueIndex
;
1204 #if XACT3_VER >= 0x0205
1205 if (flags
& NOTIFY_waveIndex
)
1206 fd
->waveIndex
= xd
->waveIndex
;
1209 if (flags
& NOTIFY_Cue
&& xd
->pCue
!= NULL
)
1211 XACT3CueImpl
*cue
= impl_from_IXACT3Cue(xd
->pCue
);
1213 fd
->pCue
= cue
->fact_cue
;
1216 if (flags
& NOTIFY_SoundBank
&& xd
->pSoundBank
!= NULL
)
1218 XACT3SoundBankImpl
*sound
= impl_from_IXACT3SoundBank(xd
->pSoundBank
);
1220 fd
->pSoundBank
= sound
->fact_soundbank
;
1223 if (flags
& NOTIFY_WaveBank
&& xd
->pWaveBank
!= NULL
)
1225 XACT3WaveBankImpl
*bank
= impl_from_IXACT3WaveBank(xd
->pWaveBank
);
1227 fd
->pWaveBank
= bank
->fact_wavebank
;
1230 #if XACT3_VER >= 0x0205
1231 if (flags
& NOTIFY_Wave
&& xd
->pWave
!= NULL
)
1233 XACT3WaveImpl
*wave
= impl_from_IXACT3Wave(xd
->pWave
);
1235 fd
->pWave
= wave
->fact_wave
;
1240 static HRESULT WINAPI
IXACT3EngineImpl_RegisterNotification(IXACT3Engine
*iface
,
1241 const XACT_NOTIFICATION_DESCRIPTION
*pNotificationDesc
)
1243 XACT3EngineImpl
*This
= impl_from_IXACT3Engine(iface
);
1244 FACTNotificationDescription fdesc
;
1246 TRACE("(%p)->(%p)\n", This
, pNotificationDesc
);
1248 unwrap_notificationdesc(&fdesc
, pNotificationDesc
);
1249 fdesc
.pvContext
= This
;
1250 return FACTAudioEngine_RegisterNotification(This
->fact_engine
, &fdesc
);
1253 static HRESULT WINAPI
IXACT3EngineImpl_UnRegisterNotification(IXACT3Engine
*iface
,
1254 const XACT_NOTIFICATION_DESCRIPTION
*pNotificationDesc
)
1256 XACT3EngineImpl
*This
= impl_from_IXACT3Engine(iface
);
1257 FACTNotificationDescription fdesc
;
1259 TRACE("(%p)->(%p)\n", This
, pNotificationDesc
);
1261 unwrap_notificationdesc(&fdesc
, pNotificationDesc
);
1262 fdesc
.pvContext
= This
;
1263 return FACTAudioEngine_UnRegisterNotification(This
->fact_engine
, &fdesc
);
1266 static XACTCATEGORY WINAPI
IXACT3EngineImpl_GetCategory(IXACT3Engine
*iface
,
1267 PCSTR szFriendlyName
)
1269 XACT3EngineImpl
*This
= impl_from_IXACT3Engine(iface
);
1271 TRACE("(%p)->(%s)\n", This
, szFriendlyName
);
1273 return FACTAudioEngine_GetCategory(This
->fact_engine
, szFriendlyName
);
1276 static HRESULT WINAPI
IXACT3EngineImpl_Stop(IXACT3Engine
*iface
,
1277 XACTCATEGORY nCategory
, DWORD dwFlags
)
1279 XACT3EngineImpl
*This
= impl_from_IXACT3Engine(iface
);
1281 TRACE("(%p)->(%u, 0x%lx)\n", This
, nCategory
, dwFlags
);
1283 return FACTAudioEngine_Stop(This
->fact_engine
, nCategory
, dwFlags
);
1286 static HRESULT WINAPI
IXACT3EngineImpl_SetVolume(IXACT3Engine
*iface
,
1287 XACTCATEGORY nCategory
, XACTVOLUME nVolume
)
1289 XACT3EngineImpl
*This
= impl_from_IXACT3Engine(iface
);
1291 TRACE("(%p)->(%u, %f)\n", This
, nCategory
, nVolume
);
1293 return FACTAudioEngine_SetVolume(This
->fact_engine
, nCategory
, nVolume
);
1296 static HRESULT WINAPI
IXACT3EngineImpl_Pause(IXACT3Engine
*iface
,
1297 XACTCATEGORY nCategory
, BOOL fPause
)
1299 XACT3EngineImpl
*This
= impl_from_IXACT3Engine(iface
);
1301 TRACE("(%p)->(%u, %u)\n", This
, nCategory
, fPause
);
1303 return FACTAudioEngine_Pause(This
->fact_engine
, nCategory
, fPause
);
1306 static XACTVARIABLEINDEX WINAPI
IXACT3EngineImpl_GetGlobalVariableIndex(
1307 IXACT3Engine
*iface
, PCSTR szFriendlyName
)
1309 XACT3EngineImpl
*This
= impl_from_IXACT3Engine(iface
);
1311 TRACE("(%p)->(%s)\n", This
, szFriendlyName
);
1313 return FACTAudioEngine_GetGlobalVariableIndex(This
->fact_engine
,
1317 static HRESULT WINAPI
IXACT3EngineImpl_SetGlobalVariable(IXACT3Engine
*iface
,
1318 XACTVARIABLEINDEX nIndex
, XACTVARIABLEVALUE nValue
)
1320 XACT3EngineImpl
*This
= impl_from_IXACT3Engine(iface
);
1322 TRACE("(%p)->(%u, %f)\n", This
, nIndex
, nValue
);
1324 return FACTAudioEngine_SetGlobalVariable(This
->fact_engine
, nIndex
, nValue
);
1327 static HRESULT WINAPI
IXACT3EngineImpl_GetGlobalVariable(IXACT3Engine
*iface
,
1328 XACTVARIABLEINDEX nIndex
, XACTVARIABLEVALUE
*nValue
)
1330 XACT3EngineImpl
*This
= impl_from_IXACT3Engine(iface
);
1332 TRACE("(%p)->(%u, %p)\n", This
, nIndex
, nValue
);
1334 return FACTAudioEngine_GetGlobalVariable(This
->fact_engine
, nIndex
, nValue
);
1337 static const IXACT3EngineVtbl XACT3Engine_Vtbl
=
1339 IXACT3EngineImpl_QueryInterface
,
1340 IXACT3EngineImpl_AddRef
,
1341 IXACT3EngineImpl_Release
,
1342 IXACT3EngineImpl_GetRendererCount
,
1343 IXACT3EngineImpl_GetRendererDetails
,
1344 #if XACT3_VER >= 0x0205
1345 IXACT3EngineImpl_GetFinalMixFormat
,
1347 IXACT3EngineImpl_Initialize
,
1348 IXACT3EngineImpl_ShutDown
,
1349 IXACT3EngineImpl_DoWork
,
1350 IXACT3EngineImpl_CreateSoundBank
,
1351 IXACT3EngineImpl_CreateInMemoryWaveBank
,
1352 IXACT3EngineImpl_CreateStreamingWaveBank
,
1353 #if XACT3_VER >= 0x0205
1354 IXACT3EngineImpl_PrepareWave
,
1355 IXACT3EngineImpl_PrepareInMemoryWave
,
1356 IXACT3EngineImpl_PrepareStreamingWave
,
1358 IXACT3EngineImpl_RegisterNotification
,
1359 IXACT3EngineImpl_UnRegisterNotification
,
1360 IXACT3EngineImpl_GetCategory
,
1361 IXACT3EngineImpl_Stop
,
1362 IXACT3EngineImpl_SetVolume
,
1363 IXACT3EngineImpl_Pause
,
1364 IXACT3EngineImpl_GetGlobalVariableIndex
,
1365 IXACT3EngineImpl_SetGlobalVariable
,
1366 IXACT3EngineImpl_GetGlobalVariable
1369 void* XACT_Internal_Malloc(size_t size
)
1371 return CoTaskMemAlloc(size
);
1374 void XACT_Internal_Free(void* ptr
)
1376 return CoTaskMemFree(ptr
);
1379 void* XACT_Internal_Realloc(void* ptr
, size_t size
)
1381 return CoTaskMemRealloc(ptr
, size
);
1384 static HRESULT WINAPI
XACT3CF_QueryInterface(IClassFactory
*iface
, REFIID riid
, void **ppobj
)
1386 if(IsEqualGUID(riid
, &IID_IUnknown
) ||
1387 IsEqualGUID(riid
, &IID_IClassFactory
))
1394 WARN("(%p)->(%s, %p): interface not found\n", iface
, debugstr_guid(riid
), ppobj
);
1395 return E_NOINTERFACE
;
1398 static ULONG WINAPI
XACT3CF_AddRef(IClassFactory
*iface
)
1403 static ULONG WINAPI
XACT3CF_Release(IClassFactory
*iface
)
1408 static HRESULT WINAPI
XACT3CF_CreateInstance(IClassFactory
*iface
, IUnknown
*pOuter
,
1409 REFIID riid
, void **ppobj
)
1412 XACT3EngineImpl
*object
;
1414 TRACE("(%p)->(%p,%s,%p)\n", iface
, pOuter
, debugstr_guid(riid
), ppobj
);
1419 return CLASS_E_NOAGGREGATION
;
1421 object
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(*object
));
1423 return E_OUTOFMEMORY
;
1425 object
->IXACT3Engine_iface
.lpVtbl
= &XACT3Engine_Vtbl
;
1427 FACTCreateEngineWithCustomAllocatorEXT(
1429 &object
->fact_engine
,
1430 XACT_Internal_Malloc
,
1432 XACT_Internal_Realloc
1435 hr
= IXACT3Engine_QueryInterface(&object
->IXACT3Engine_iface
, riid
, ppobj
);
1437 HeapFree(GetProcessHeap(), 0, object
);
1444 static HRESULT WINAPI
XACT3CF_LockServer(IClassFactory
*iface
, BOOL dolock
)
1446 TRACE("(%p)->(%d): stub!\n", iface
, dolock
);
1450 static const IClassFactoryVtbl XACT3CF_Vtbl
=
1452 XACT3CF_QueryInterface
,
1455 XACT3CF_CreateInstance
,
1459 static IClassFactory XACTFactory
= { &XACT3CF_Vtbl
};
1461 BOOL WINAPI
DllMain(HINSTANCE hinstDLL
, DWORD reason
, void *pReserved
)
1463 TRACE("(%p, %ld, %p)\n", hinstDLL
, reason
, pReserved
);
1467 case DLL_PROCESS_ATTACH
:
1468 DisableThreadLibraryCalls( hinstDLL
);
1469 TRACE("Using FAudio version %d\n", FAudioLinkedVersion() );
1475 HRESULT WINAPI
DllGetClassObject(REFCLSID rclsid
, REFIID riid
, void **ppv
)
1477 if (IsEqualGUID(rclsid
, &CLSID_XACTEngine
))
1479 TRACE("(%s, %s, %p)\n", debugstr_guid(rclsid
), debugstr_guid(riid
), ppv
);
1480 return IClassFactory_QueryInterface(&XACTFactory
, riid
, ppv
);
1483 FIXME("Unknown class %s\n", debugstr_guid(rclsid
));
1484 return CLASS_E_CLASSNOTAVAILABLE
;