maintainers: Update the Direct3D section.
[wine.git] / dlls / xactengine3_7 / xact_dll.c
blob98c3cf8f0762582705f9d78dde6ad58ed7359afd
1 /*
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
19 #include <stdarg.h>
20 #include <FACT.h>
22 #define NONAMELESSUNION
23 #define COBJMACROS
24 #include "objbase.h"
26 #if XACT3_VER < 0x0300
27 #include "xact2wb.h"
28 #include "initguid.h"
29 #include "xact.h"
30 #else
31 #include "xact3wb.h"
32 #include "xaudio2.h"
33 #include "initguid.h"
34 #include "xact3.h"
35 #endif
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
53 #endif
55 typedef struct _XACT3CueImpl {
56 IXACT3Cue IXACT3Cue_iface;
57 FACTCue *fact_cue;
58 } XACT3CueImpl;
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);
95 UINT ret;
97 TRACE("(%p)\n", iface);
99 ret = FACTCue_Destroy(This->fact_cue);
100 if (ret != 0)
101 WARN("FACTCue_Destroy returned %d\n", ret);
102 HeapFree(GetProcessHeap(), 0, This);
103 return S_OK;
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);
113 return E_NOTIMPL;
116 static HRESULT WINAPI IXACT3CueImpl_SetChannelMap(IXACT3Cue *iface, XACTCHANNELMAP *map)
118 FIXME("(%p)->(%p)\n", iface, map);
120 return E_NOTIMPL;
123 static HRESULT WINAPI IXACT3CueImpl_GetChannelVolume(IXACT3Cue *iface, XACTCHANNELVOLUME *volume)
125 FIXME("(%p)->(%p)\n", iface, volume);
127 return E_NOTIMPL;
130 static HRESULT WINAPI IXACT3CueImpl_SetChannelVolume(IXACT3Cue *iface, XACTCHANNELVOLUME *volume)
132 FIXME("(%p)->(%p)\n", iface, volume);
134 return E_NOTIMPL;
137 #endif
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;
197 HRESULT hr;
199 TRACE("(%p)->(%p)\n", iface, ppProperties);
201 hr = FACTCue_GetProperties(This->fact_cue, &fProps);
202 if(FAILED(hr))
203 return hr;
205 *ppProperties = (XACT_CUE_INSTANCE_PROPERTIES*) fProps;
206 return hr;
208 #endif
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);
216 return S_OK;
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);
226 return S_OK;
228 #endif
230 static const IXACT3CueVtbl XACT3Cue_Vtbl =
232 IXACT3CueImpl_Play,
233 IXACT3CueImpl_Stop,
234 IXACT3CueImpl_GetState,
235 IXACT3CueImpl_Destroy,
236 #if XACT3_VER < 0x0300
237 IXACT3CueImpl_GetChannelMap,
238 IXACT3CueImpl_SetChannelMap,
239 IXACT3CueImpl_GetChannelVolume,
240 IXACT3CueImpl_SetChannelVolume,
241 #endif
242 IXACT3CueImpl_SetMatrixCoefficients,
243 IXACT3CueImpl_GetVariableIndex,
244 IXACT3CueImpl_SetVariable,
245 IXACT3CueImpl_GetVariable,
246 IXACT3CueImpl_Pause,
247 #if XACT3_VER >= 0x0205
248 IXACT3CueImpl_GetProperties,
249 #endif
250 #if XACT3_VER >= 0x0300
251 IXACT3CueImpl_SetOutputVoices,
252 IXACT3CueImpl_SetOutputVoiceMatrix
253 #endif
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);
298 #endif
300 static HRESULT WINAPI IXACT3SoundBankImpl_Prepare(IXACT3SoundBank *iface,
301 XACTINDEX nCueIndex, DWORD dwFlags, XACTTIME timeOffset,
302 IXACT3Cue** ppCue)
304 XACT3SoundBankImpl *This = impl_from_IXACT3SoundBank(iface);
305 XACT3CueImpl *cue;
306 FACTCue *fcue;
307 UINT ret;
309 TRACE("(%p)->(%u, 0x%lx, %lu, %p)\n", This, nCueIndex, dwFlags, timeOffset,
310 ppCue);
312 ret = FACTSoundBank_Prepare(This->fact_soundbank, nCueIndex, dwFlags,
313 timeOffset, &fcue);
314 if(ret != 0)
316 ERR("Failed to CreateCue: %d\n", ret);
317 return E_FAIL;
320 cue = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*cue));
321 if (!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);
334 return S_OK;
337 static HRESULT WINAPI IXACT3SoundBankImpl_Play(IXACT3SoundBank *iface,
338 XACTINDEX nCueIndex, DWORD dwFlags, XACTTIME timeOffset,
339 IXACT3Cue** ppCue)
341 XACT3SoundBankImpl *This = impl_from_IXACT3SoundBank(iface);
342 XACT3CueImpl *cue;
343 FACTCue *fcue;
344 HRESULT hr;
346 TRACE("(%p)->(%u, 0x%lx, %lu, %p)\n", This, nCueIndex, dwFlags, timeOffset,
347 ppCue);
349 /* If the application doesn't want a handle, don't generate one at all.
350 * Let the engine handle that memory instead.
351 * -flibit
353 if (ppCue == NULL){
354 hr = FACTSoundBank_Play(This->fact_soundbank, nCueIndex, dwFlags,
355 timeOffset, NULL);
356 }else{
357 hr = FACTSoundBank_Play(This->fact_soundbank, nCueIndex, dwFlags,
358 timeOffset, &fcue);
359 if(FAILED(hr))
360 return hr;
362 cue = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*cue));
363 if (!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;
375 return hr;
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);
391 HRESULT hr;
393 TRACE("(%p)\n", This);
395 hr = FACTSoundBank_Destroy(This->fact_soundbank);
396 HeapFree(GetProcessHeap(), 0, This);
397 return hr;
400 static HRESULT WINAPI IXACT3SoundBankImpl_GetState(IXACT3SoundBank *iface,
401 DWORD *pdwState)
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,
416 #endif
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;
429 FACTWave *fact_wave;
430 } XACT3WaveImpl;
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);
440 HRESULT hr;
442 TRACE("(%p)\n", This);
444 hr = FACTWave_Destroy(This->fact_wave);
445 HeapFree(GetProcessHeap(), 0, This);
446 return hr;
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,
530 IXACT3WaveImpl_Play,
531 IXACT3WaveImpl_Stop,
532 IXACT3WaveImpl_Pause,
533 IXACT3WaveImpl_GetState,
534 IXACT3WaveImpl_SetPitch,
535 IXACT3WaveImpl_SetVolume,
536 IXACT3WaveImpl_SetMatrixCoefficients,
537 IXACT3WaveImpl_GetProperties
540 #endif
542 typedef struct _XACT3WaveBankImpl {
543 IXACT3WaveBank IXACT3WaveBank_iface;
545 FACTWaveBank *fact_wavebank;
546 } XACT3WaveBankImpl;
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);
556 HRESULT hr;
558 TRACE("(%p)\n", This);
560 hr = FACTWaveBank_Destroy(This->fact_wavebank);
561 HeapFree(GetProcessHeap(), 0, This);
562 return hr;
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);
603 XACT3WaveImpl *wave;
604 FACTWave *fwave;
605 UINT ret;
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);
612 if(ret != 0)
614 ERR("Failed to CreateWave: %d\n", ret);
615 return E_FAIL;
618 wave = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*wave));
619 if (!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);
632 return S_OK;
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);
640 XACT3WaveImpl *wave;
641 FACTWave *fwave;
642 HRESULT hr;
644 TRACE("(%p)->(0x%x, %lu, 0x%lx, %u, %p)\n", This, nWaveIndex, dwFlags, dwPlayOffset,
645 nLoopCount, ppWave);
647 /* If the application doesn't want a handle, don't generate one at all.
648 * Let the engine handle that memory instead.
649 * -flibit
651 if (ppWave == NULL){
652 hr = FACTWaveBank_Play(This->fact_wavebank, nWaveIndex, dwFlags,
653 dwPlayOffset, nLoopCount, NULL);
654 }else{
655 hr = FACTWaveBank_Play(This->fact_wavebank, nWaveIndex, dwFlags,
656 dwPlayOffset, nLoopCount, &fwave);
657 if(FAILED(hr))
658 return hr;
660 wave = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*wave));
661 if (!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;
673 return hr;
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);
686 #endif
688 static HRESULT WINAPI IXACT3WaveBankImpl_GetState(IXACT3WaveBank *iface,
689 DWORD *pdwState)
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,
708 #endif
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;
720 } XACT3EngineImpl;
722 typedef struct wrap_readfile_struct {
723 XACT3EngineImpl *engine;
724 HANDLE file;
725 } wrap_readfile_struct;
727 static int32_t FACTCALL wrap_readfile(
728 void* hFile,
729 void* lpBuffer,
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(
740 void* hFile,
741 FACTOverlapped *lpOverlapped,
742 uint32_t *lpNumberOfBytesTransferred,
743 int32_t bWait)
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;
766 else
767 *ppvObject = NULL;
769 if (*ppvObject){
770 IUnknown_AddRef((IUnknown*)*ppvObject);
771 return S_OK;
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);
784 return 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);
794 if (!ref)
795 HeapFree(GetProcessHeap(), 0, This);
796 return ref;
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);
833 #endif
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 */
840 if (!engine)
842 WARN("Notification context is NULL\n");
843 return;
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;
854 UINT ret;
856 TRACE("(%p)->(%p)\n", This, pParams);
858 memset(&params, 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.
878 * -flibit
880 if (pParams->pXAudio2 != NULL){
881 FIXME("pXAudio2 parameter not supported!\n");
883 if (pParams->pMasteringVoice != NULL){
884 FIXME("pMasteringVoice parameter not supported!\n");
887 #endif
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)
898 GetOverlappedResult;
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, &params);
906 if (ret != 0)
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;
936 FACTSoundBank *fsb;
937 UINT ret;
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);
944 if(ret != 0)
946 ERR("Failed to CreateSoundBank: %d\n", ret);
947 return E_FAIL;
950 sb = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*sb));
951 if (!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);
964 return S_OK;
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;
973 FACTWaveBank *fwb;
974 UINT ret;
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);
981 if(ret != 0)
983 ERR("Failed to CreateWaveBank: %d\n", ret);
984 return E_FAIL;
987 wb = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*wb));
988 if (!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);
1001 return S_OK;
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;
1012 FACTWaveBank *fwb;
1013 UINT ret;
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,
1028 &fwb);
1029 if(ret != 0)
1031 ERR("Failed to CreateWaveBank: %d\n", ret);
1032 return E_FAIL;
1035 wb = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*wb));
1036 if (!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);
1049 return S_OK;
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);
1061 return E_NOTIMPL;
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);
1072 return E_NOTIMPL;
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;
1083 UINT ret;
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);
1093 return E_FAIL;
1096 wave = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*wave));
1097 if (!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);
1109 return S_OK;
1112 #endif
1114 enum {
1115 NOTIFY_SoundBank = 0x01,
1116 NOTIFY_WaveBank = 0x02,
1117 NOTIFY_Cue = 0x04,
1118 NOTIFY_Wave = 0x08,
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
1129 X(CUEPREPARED);
1130 X(CUEPLAY);
1131 X(CUESTOP);
1132 X(CUEDESTROYED);
1133 X(MARKER);
1134 X(SOUNDBANKDESTROYED);
1135 X(WAVEBANKDESTROYED);
1136 X(LOCALVARIABLECHANGED);
1137 X(GLOBALVARIABLECHANGED);
1138 X(GUICONNECTED);
1139 X(GUIDISCONNECTED);
1140 X(WAVEPLAY);
1141 X(WAVESTOP);
1142 X(WAVEBANKPREPARED);
1143 X(WAVEBANKSTREAMING_INVALIDCONTENT);
1144 #if XACT3_VER >= 0x0205
1145 X(WAVEPREPARED);
1146 X(WAVELOOPED);
1147 X(WAVEDESTROYED);
1148 #endif
1149 #undef X
1151 FIXME("unknown type %#x\n", type);
1152 return 0;
1155 static inline void unwrap_notificationdesc(FACTNotificationDescription *fd,
1156 const XACT_NOTIFICATION_DESCRIPTION *xd)
1158 DWORD flags = 0;
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;
1207 #endif
1209 if (flags & NOTIFY_Cue && xd->pCue != NULL)
1211 XACT3CueImpl *cue = impl_from_IXACT3Cue(xd->pCue);
1212 if (cue)
1213 fd->pCue = cue->fact_cue;
1216 if (flags & NOTIFY_SoundBank && xd->pSoundBank != NULL)
1218 XACT3SoundBankImpl *sound = impl_from_IXACT3SoundBank(xd->pSoundBank);
1219 if (sound)
1220 fd->pSoundBank = sound->fact_soundbank;
1223 if (flags & NOTIFY_WaveBank && xd->pWaveBank != NULL)
1225 XACT3WaveBankImpl *bank = impl_from_IXACT3WaveBank(xd->pWaveBank);
1226 if (bank)
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);
1234 if (wave)
1235 fd->pWave = wave->fact_wave;
1237 #endif
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,
1314 szFriendlyName);
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,
1346 #endif
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,
1357 #endif
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))
1389 *ppobj = iface;
1390 return S_OK;
1393 *ppobj = NULL;
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)
1400 return 2;
1403 static ULONG WINAPI XACT3CF_Release(IClassFactory *iface)
1405 return 1;
1408 static HRESULT WINAPI XACT3CF_CreateInstance(IClassFactory *iface, IUnknown *pOuter,
1409 REFIID riid, void **ppobj)
1411 HRESULT hr;
1412 XACT3EngineImpl *object;
1414 TRACE("(%p)->(%p,%s,%p)\n", iface, pOuter, debugstr_guid(riid), ppobj);
1416 *ppobj = NULL;
1418 if(pOuter)
1419 return CLASS_E_NOAGGREGATION;
1421 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
1422 if(!object)
1423 return E_OUTOFMEMORY;
1425 object->IXACT3Engine_iface.lpVtbl = &XACT3Engine_Vtbl;
1427 FACTCreateEngineWithCustomAllocatorEXT(
1429 &object->fact_engine,
1430 XACT_Internal_Malloc,
1431 XACT_Internal_Free,
1432 XACT_Internal_Realloc
1435 hr = IXACT3Engine_QueryInterface(&object->IXACT3Engine_iface, riid, ppobj);
1436 if(FAILED(hr)){
1437 HeapFree(GetProcessHeap(), 0, object);
1438 return hr;
1441 return hr;
1444 static HRESULT WINAPI XACT3CF_LockServer(IClassFactory *iface, BOOL dolock)
1446 TRACE("(%p)->(%d): stub!\n", iface, dolock);
1447 return S_OK;
1450 static const IClassFactoryVtbl XACT3CF_Vtbl =
1452 XACT3CF_QueryInterface,
1453 XACT3CF_AddRef,
1454 XACT3CF_Release,
1455 XACT3CF_CreateInstance,
1456 XACT3CF_LockServer
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);
1465 switch (reason)
1467 case DLL_PROCESS_ATTACH:
1468 DisableThreadLibraryCalls( hinstDLL );
1469 TRACE("Using FAudio version %d\n", FAudioLinkedVersion() );
1470 break;
1472 return TRUE;
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;