wined3d: Rename gen_ffp_frag_op().
[wine.git] / dlls / xactengine3_7 / xact_dll.c
blob231ef753f22c88d8bf53026a5f1c5d1d1d897ca7
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 "config.h"
21 #include <stdarg.h>
22 #include <FACT.h>
24 #define NONAMELESSUNION
25 #define COBJMACROS
27 #include "initguid.h"
28 #if XACT3_VER < 0x0300
29 #include "xact.h"
30 #else
31 #include "xact3.h"
32 #endif
33 #include "rpcproxy.h"
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
51 #endif
53 typedef struct _XACT3CueImpl {
54 IXACT3Cue IXACT3Cue_iface;
55 FACTCue *fact_cue;
56 } XACT3CueImpl;
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);
93 UINT ret;
95 TRACE("(%p)\n", iface);
97 ret = FACTCue_Destroy(This->fact_cue);
98 if (ret != 0)
99 WARN("FACTCue_Destroy returned %d\n", ret);
100 HeapFree(GetProcessHeap(), 0, This);
101 return S_OK;
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);
111 return E_NOTIMPL;
114 static HRESULT WINAPI IXACT3CueImpl_SetChannelMap(IXACT3Cue *iface, XACTCHANNELMAP *map)
116 FIXME("(%p)->(%p)\n", iface, map);
118 return E_NOTIMPL;
121 static HRESULT WINAPI IXACT3CueImpl_GetChannelVolume(IXACT3Cue *iface, XACTCHANNELVOLUME *volume)
123 FIXME("(%p)->(%p)\n", iface, volume);
125 return E_NOTIMPL;
128 static HRESULT WINAPI IXACT3CueImpl_SetChannelVolume(IXACT3Cue *iface, XACTCHANNELVOLUME *volume)
130 FIXME("(%p)->(%p)\n", iface, volume);
132 return E_NOTIMPL;
135 #endif
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;
195 HRESULT hr;
197 TRACE("(%p)->(%p)\n", iface, ppProperties);
199 hr = FACTCue_GetProperties(This->fact_cue, &fProps);
200 if(FAILED(hr))
201 return hr;
203 *ppProperties = (XACT_CUE_INSTANCE_PROPERTIES*) fProps;
204 return hr;
206 #endif
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);
214 return S_OK;
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);
224 return S_OK;
226 #endif
228 static const IXACT3CueVtbl XACT3Cue_Vtbl =
230 IXACT3CueImpl_Play,
231 IXACT3CueImpl_Stop,
232 IXACT3CueImpl_GetState,
233 IXACT3CueImpl_Destroy,
234 #if XACT3_VER < 0x0300
235 IXACT3CueImpl_GetChannelMap,
236 IXACT3CueImpl_SetChannelMap,
237 IXACT3CueImpl_GetChannelVolume,
238 IXACT3CueImpl_SetChannelVolume,
239 #endif
240 IXACT3CueImpl_SetMatrixCoefficients,
241 IXACT3CueImpl_GetVariableIndex,
242 IXACT3CueImpl_SetVariable,
243 IXACT3CueImpl_GetVariable,
244 IXACT3CueImpl_Pause,
245 #if XACT3_VER >= 0x0205
246 IXACT3CueImpl_GetProperties,
247 #endif
248 #if XACT3_VER >= 0x0300
249 IXACT3CueImpl_SetOutputVoices,
250 IXACT3CueImpl_SetOutputVoiceMatrix
251 #endif
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);
296 #endif
298 static HRESULT WINAPI IXACT3SoundBankImpl_Prepare(IXACT3SoundBank *iface,
299 XACTINDEX nCueIndex, DWORD dwFlags, XACTTIME timeOffset,
300 IXACT3Cue** ppCue)
302 XACT3SoundBankImpl *This = impl_from_IXACT3SoundBank(iface);
303 XACT3CueImpl *cue;
304 FACTCue *fcue;
305 UINT ret;
307 TRACE("(%p)->(%u, 0x%x, %u, %p)\n", This, nCueIndex, dwFlags, timeOffset,
308 ppCue);
310 ret = FACTSoundBank_Prepare(This->fact_soundbank, nCueIndex, dwFlags,
311 timeOffset, &fcue);
312 if(ret != 0)
314 ERR("Failed to CreateCue: %d\n", ret);
315 return E_FAIL;
318 cue = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*cue));
319 if (!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);
332 return S_OK;
335 static HRESULT WINAPI IXACT3SoundBankImpl_Play(IXACT3SoundBank *iface,
336 XACTINDEX nCueIndex, DWORD dwFlags, XACTTIME timeOffset,
337 IXACT3Cue** ppCue)
339 XACT3SoundBankImpl *This = impl_from_IXACT3SoundBank(iface);
340 XACT3CueImpl *cue;
341 FACTCue *fcue;
342 HRESULT hr;
344 TRACE("(%p)->(%u, 0x%x, %u, %p)\n", This, nCueIndex, dwFlags, timeOffset,
345 ppCue);
347 /* If the application doesn't want a handle, don't generate one at all.
348 * Let the engine handle that memory instead.
349 * -flibit
351 if (ppCue == NULL){
352 hr = FACTSoundBank_Play(This->fact_soundbank, nCueIndex, dwFlags,
353 timeOffset, NULL);
354 }else{
355 hr = FACTSoundBank_Play(This->fact_soundbank, nCueIndex, dwFlags,
356 timeOffset, &fcue);
357 if(FAILED(hr))
358 return hr;
360 cue = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*cue));
361 if (!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;
373 return hr;
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);
389 HRESULT hr;
391 TRACE("(%p)\n", This);
393 hr = FACTSoundBank_Destroy(This->fact_soundbank);
394 HeapFree(GetProcessHeap(), 0, This);
395 return hr;
398 static HRESULT WINAPI IXACT3SoundBankImpl_GetState(IXACT3SoundBank *iface,
399 DWORD *pdwState)
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,
414 #endif
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;
427 FACTWave *fact_wave;
428 } XACT3WaveImpl;
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);
438 HRESULT hr;
440 TRACE("(%p)\n", This);
442 hr = FACTWave_Destroy(This->fact_wave);
443 HeapFree(GetProcessHeap(), 0, This);
444 return hr;
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,
528 IXACT3WaveImpl_Play,
529 IXACT3WaveImpl_Stop,
530 IXACT3WaveImpl_Pause,
531 IXACT3WaveImpl_GetState,
532 IXACT3WaveImpl_SetPitch,
533 IXACT3WaveImpl_SetVolume,
534 IXACT3WaveImpl_SetMatrixCoefficients,
535 IXACT3WaveImpl_GetProperties
538 #endif
540 typedef struct _XACT3WaveBankImpl {
541 IXACT3WaveBank IXACT3WaveBank_iface;
543 FACTWaveBank *fact_wavebank;
544 } XACT3WaveBankImpl;
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);
554 HRESULT hr;
556 TRACE("(%p)\n", This);
558 hr = FACTWaveBank_Destroy(This->fact_wavebank);
559 HeapFree(GetProcessHeap(), 0, This);
560 return hr;
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);
601 XACT3WaveImpl *wave;
602 FACTWave *fwave;
603 UINT ret;
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);
610 if(ret != 0)
612 ERR("Failed to CreateWave: %d\n", ret);
613 return E_FAIL;
616 wave = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*wave));
617 if (!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);
630 return S_OK;
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);
638 XACT3WaveImpl *wave;
639 FACTWave *fwave;
640 HRESULT hr;
642 TRACE("(%p)->(0x%x, %u, 0x%x, %u, %p)\n", This, nWaveIndex, dwFlags, dwPlayOffset,
643 nLoopCount, ppWave);
645 /* If the application doesn't want a handle, don't generate one at all.
646 * Let the engine handle that memory instead.
647 * -flibit
649 if (ppWave == NULL){
650 hr = FACTWaveBank_Play(This->fact_wavebank, nWaveIndex, dwFlags,
651 dwPlayOffset, nLoopCount, NULL);
652 }else{
653 hr = FACTWaveBank_Play(This->fact_wavebank, nWaveIndex, dwFlags,
654 dwPlayOffset, nLoopCount, &fwave);
655 if(FAILED(hr))
656 return hr;
658 wave = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*wave));
659 if (!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;
671 return hr;
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);
684 #endif
686 static HRESULT WINAPI IXACT3WaveBankImpl_GetState(IXACT3WaveBank *iface,
687 DWORD *pdwState)
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,
706 #endif
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;
718 } XACT3EngineImpl;
720 typedef struct wrap_readfile_struct {
721 XACT3EngineImpl *engine;
722 HANDLE file;
723 } wrap_readfile_struct;
725 static int32_t FACTCALL wrap_readfile(
726 void* hFile,
727 void* lpBuffer,
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(
738 void* hFile,
739 FACTOverlapped *lpOverlapped,
740 uint32_t *lpNumberOfBytesTransferred,
741 int32_t bWait)
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;
764 else
765 *ppvObject = NULL;
767 if (*ppvObject){
768 IUnknown_AddRef((IUnknown*)*ppvObject);
769 return S_OK;
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);
782 return 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);
792 if (!ref)
793 HeapFree(GetProcessHeap(), 0, This);
794 return ref;
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);
831 #endif
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 */
838 if (!engine)
840 WARN("Notification context is NULL\n");
841 return;
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;
852 UINT ret;
854 TRACE("(%p)->(%p)\n", This, pParams);
856 memset(&params, 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.
876 * -flibit
878 if (pParams->pXAudio2 != NULL){
879 FIXME("pXAudio2 parameter not supported!\n");
881 if (pParams->pMasteringVoice != NULL){
882 FIXME("pMasteringVoice parameter not supported!\n");
885 #endif
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)
896 GetOverlappedResult;
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, &params);
904 if (ret != 0)
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;
934 FACTSoundBank *fsb;
935 UINT ret;
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);
942 if(ret != 0)
944 ERR("Failed to CreateSoundBank: %d\n", ret);
945 return E_FAIL;
948 sb = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*sb));
949 if (!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);
962 return S_OK;
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;
971 FACTWaveBank *fwb;
972 UINT ret;
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);
979 if(ret != 0)
981 ERR("Failed to CreateWaveBank: %d\n", ret);
982 return E_FAIL;
985 wb = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*wb));
986 if (!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);
999 return S_OK;
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;
1010 FACTWaveBank *fwb;
1011 UINT ret;
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,
1026 &fwb);
1027 if(ret != 0)
1029 ERR("Failed to CreateWaveBank: %d\n", ret);
1030 return E_FAIL;
1033 wb = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*wb));
1034 if (!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);
1047 return S_OK;
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);
1059 return E_NOTIMPL;
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);
1070 return E_NOTIMPL;
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;
1081 UINT ret;
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);
1091 return E_FAIL;
1094 wave = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*wave));
1095 if (!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);
1107 return S_OK;
1110 #endif
1112 enum {
1113 NOTIFY_SoundBank = 0x01,
1114 NOTIFY_WaveBank = 0x02,
1115 NOTIFY_Cue = 0x04,
1116 NOTIFY_Wave = 0x08,
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
1127 X(CUEPREPARED);
1128 X(CUEPLAY);
1129 X(CUESTOP);
1130 X(CUEDESTROYED);
1131 X(MARKER);
1132 X(SOUNDBANKDESTROYED);
1133 X(WAVEBANKDESTROYED);
1134 X(LOCALVARIABLECHANGED);
1135 X(GLOBALVARIABLECHANGED);
1136 X(GUICONNECTED);
1137 X(GUIDISCONNECTED);
1138 X(WAVEPLAY);
1139 X(WAVESTOP);
1140 X(WAVEBANKPREPARED);
1141 X(WAVEBANKSTREAMING_INVALIDCONTENT);
1142 #if XACT3_VER >= 0x0205
1143 X(WAVEPREPARED);
1144 X(WAVELOOPED);
1145 X(WAVEDESTROYED);
1146 #endif
1147 #undef X
1149 FIXME("unknown type %#x\n", type);
1150 return 0;
1153 static inline void unwrap_notificationdesc(FACTNotificationDescription *fd,
1154 const XACT_NOTIFICATION_DESCRIPTION *xd)
1156 DWORD flags = 0;
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;
1205 #endif
1207 if (flags & NOTIFY_Cue && xd->pCue != NULL)
1209 XACT3CueImpl *cue = impl_from_IXACT3Cue(xd->pCue);
1210 if (cue)
1211 fd->pCue = cue->fact_cue;
1214 if (flags & NOTIFY_SoundBank && xd->pSoundBank != NULL)
1216 XACT3SoundBankImpl *sound = impl_from_IXACT3SoundBank(xd->pSoundBank);
1217 if (sound)
1218 fd->pSoundBank = sound->fact_soundbank;
1221 if (flags & NOTIFY_WaveBank && xd->pWaveBank != NULL)
1223 XACT3WaveBankImpl *bank = impl_from_IXACT3WaveBank(xd->pWaveBank);
1224 if (bank)
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);
1232 if (wave)
1233 fd->pWave = wave->fact_wave;
1235 #endif
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,
1312 szFriendlyName);
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,
1344 #endif
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,
1355 #endif
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))
1387 *ppobj = iface;
1388 return S_OK;
1391 *ppobj = NULL;
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)
1398 return 2;
1401 static ULONG WINAPI XACT3CF_Release(IClassFactory *iface)
1403 return 1;
1406 static HRESULT WINAPI XACT3CF_CreateInstance(IClassFactory *iface, IUnknown *pOuter,
1407 REFIID riid, void **ppobj)
1409 HRESULT hr;
1410 XACT3EngineImpl *object;
1412 TRACE("(%p)->(%p,%s,%p)\n", iface, pOuter, debugstr_guid(riid), ppobj);
1414 *ppobj = NULL;
1416 if(pOuter)
1417 return CLASS_E_NOAGGREGATION;
1419 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
1420 if(!object)
1421 return E_OUTOFMEMORY;
1423 object->IXACT3Engine_iface.lpVtbl = &XACT3Engine_Vtbl;
1425 FACTCreateEngineWithCustomAllocatorEXT(
1427 &object->fact_engine,
1428 XACT_Internal_Malloc,
1429 XACT_Internal_Free,
1430 XACT_Internal_Realloc
1433 hr = IXACT3Engine_QueryInterface(&object->IXACT3Engine_iface, riid, ppobj);
1434 if(FAILED(hr)){
1435 HeapFree(GetProcessHeap(), 0, object);
1436 return hr;
1439 return hr;
1442 static HRESULT WINAPI XACT3CF_LockServer(IClassFactory *iface, BOOL dolock)
1444 TRACE("(%p)->(%d): stub!\n", iface, dolock);
1445 return S_OK;
1448 static const IClassFactoryVtbl XACT3CF_Vtbl =
1450 XACT3CF_QueryInterface,
1451 XACT3CF_AddRef,
1452 XACT3CF_Release,
1453 XACT3CF_CreateInstance,
1454 XACT3CF_LockServer
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);
1463 switch (reason)
1465 case DLL_PROCESS_ATTACH:
1466 DisableThreadLibraryCalls( hinstDLL );
1468 #ifdef HAVE_FAUDIOLINKEDVERSION
1469 TRACE("Using FAudio version %d\n", FAudioLinkedVersion() );
1470 #endif
1472 break;
1474 return TRUE;
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;