crypt32: Fix adding trusted roots to store.
[wine/zf.git] / dlls / xactengine3_7 / xact_dll.c
blob281aecc154b9fbd174a4009aaa60c6540f516817
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 #include "xact3.h"
29 #include "rpcproxy.h"
30 #include "wine/debug.h"
32 WINE_DEFAULT_DEBUG_CHANNEL(xact3);
34 static HINSTANCE instance;
36 typedef struct _XACT3CueImpl {
37 IXACT3Cue IXACT3Cue_iface;
38 FACTCue *fact_cue;
39 } XACT3CueImpl;
41 static inline XACT3CueImpl *impl_from_IXACT3Cue(IXACT3Cue *iface)
43 return CONTAINING_RECORD(iface, XACT3CueImpl, IXACT3Cue_iface);
46 static HRESULT WINAPI IXACT3CueImpl_Play(IXACT3Cue *iface)
48 XACT3CueImpl *This = impl_from_IXACT3Cue(iface);
50 TRACE("(%p)\n", iface);
52 return FACTCue_Play(This->fact_cue);
55 static HRESULT WINAPI IXACT3CueImpl_Stop(IXACT3Cue *iface, DWORD dwFlags)
57 XACT3CueImpl *This = impl_from_IXACT3Cue(iface);
59 TRACE("(%p)->(%u)\n", iface, dwFlags);
61 return FACTCue_Stop(This->fact_cue, dwFlags);
64 static HRESULT WINAPI IXACT3CueImpl_GetState(IXACT3Cue *iface, DWORD *pdwState)
66 XACT3CueImpl *This = impl_from_IXACT3Cue(iface);
68 TRACE("(%p)->(%p)\n", iface, pdwState);
70 return FACTCue_GetState(This->fact_cue, pdwState);
73 static HRESULT WINAPI IXACT3CueImpl_Destroy(IXACT3Cue *iface)
75 XACT3CueImpl *This = impl_from_IXACT3Cue(iface);
76 UINT ret;
78 TRACE("(%p)\n", iface);
80 ret = FACTCue_Destroy(This->fact_cue);
81 if (ret != 0)
82 WARN("FACTCue_Destroy returned %d\n", ret);
83 HeapFree(GetProcessHeap(), 0, This);
84 return S_OK;
87 static HRESULT WINAPI IXACT3CueImpl_SetMatrixCoefficients(IXACT3Cue *iface,
88 UINT32 uSrcChannelCount, UINT32 uDstChannelCount,
89 float *pMatrixCoefficients)
91 XACT3CueImpl *This = impl_from_IXACT3Cue(iface);
93 TRACE("(%p)->(%u, %u, %p)\n", iface, uSrcChannelCount, uDstChannelCount,
94 pMatrixCoefficients);
96 return FACTCue_SetMatrixCoefficients(This->fact_cue, uSrcChannelCount,
97 uDstChannelCount, pMatrixCoefficients);
100 static XACTVARIABLEINDEX WINAPI IXACT3CueImpl_GetVariableIndex(IXACT3Cue *iface,
101 PCSTR szFriendlyName)
103 XACT3CueImpl *This = impl_from_IXACT3Cue(iface);
105 TRACE("(%p)->(%s)\n", iface, szFriendlyName);
107 return FACTCue_GetVariableIndex(This->fact_cue, szFriendlyName);
110 static HRESULT WINAPI IXACT3CueImpl_SetVariable(IXACT3Cue *iface,
111 XACTVARIABLEINDEX nIndex, XACTVARIABLEVALUE nValue)
113 XACT3CueImpl *This = impl_from_IXACT3Cue(iface);
115 TRACE("(%p)->(%u, %f)\n", iface, nIndex, nValue);
117 return FACTCue_SetVariable(This->fact_cue, nIndex, nValue);
120 static HRESULT WINAPI IXACT3CueImpl_GetVariable(IXACT3Cue *iface,
121 XACTVARIABLEINDEX nIndex, XACTVARIABLEVALUE *nValue)
123 XACT3CueImpl *This = impl_from_IXACT3Cue(iface);
125 TRACE("(%p)->(%u, %p)\n", iface, nIndex, nValue);
127 return FACTCue_GetVariable(This->fact_cue, nIndex, nValue);
130 static HRESULT WINAPI IXACT3CueImpl_Pause(IXACT3Cue *iface, BOOL fPause)
132 XACT3CueImpl *This = impl_from_IXACT3Cue(iface);
134 TRACE("(%p)->(%u)\n", iface, fPause);
136 return FACTCue_Pause(This->fact_cue, fPause);
139 static HRESULT WINAPI IXACT3CueImpl_GetProperties(IXACT3Cue *iface,
140 XACT_CUE_INSTANCE_PROPERTIES **ppProperties)
142 XACT3CueImpl *This = impl_from_IXACT3Cue(iface);
143 FACTCueInstanceProperties *fProps;
144 HRESULT hr;
146 TRACE("(%p)->(%p)\n", iface, ppProperties);
148 hr = FACTCue_GetProperties(This->fact_cue, &fProps);
149 if(FAILED(hr))
150 return hr;
152 *ppProperties = (XACT_CUE_INSTANCE_PROPERTIES*) fProps;
153 return hr;
156 static HRESULT WINAPI IXACT3CueImpl_SetOutputVoices(IXACT3Cue *iface,
157 const XAUDIO2_VOICE_SENDS *pSendList)
159 XACT3CueImpl *This = impl_from_IXACT3Cue(iface);
160 FIXME("(%p)->(%p): stub!\n", This, pSendList);
161 return S_OK;
164 static HRESULT WINAPI IXACT3CueImpl_SetOutputVoiceMatrix(IXACT3Cue *iface,
165 IXAudio2Voice *pDestinationVoice, UINT32 SourceChannels,
166 UINT32 DestinationChannels, const float *pLevelMatrix)
168 XACT3CueImpl *This = impl_from_IXACT3Cue(iface);
169 FIXME("(%p)->(%p %u %u %p): stub!\n", This, pDestinationVoice, SourceChannels,
170 DestinationChannels, pLevelMatrix);
171 return S_OK;
174 static const IXACT3CueVtbl XACT3Cue_Vtbl =
176 IXACT3CueImpl_Play,
177 IXACT3CueImpl_Stop,
178 IXACT3CueImpl_GetState,
179 IXACT3CueImpl_Destroy,
180 IXACT3CueImpl_SetMatrixCoefficients,
181 IXACT3CueImpl_GetVariableIndex,
182 IXACT3CueImpl_SetVariable,
183 IXACT3CueImpl_GetVariable,
184 IXACT3CueImpl_Pause,
185 IXACT3CueImpl_GetProperties,
186 IXACT3CueImpl_SetOutputVoices,
187 IXACT3CueImpl_SetOutputVoiceMatrix
190 typedef struct _XACT3SoundBankImpl {
191 IXACT3SoundBank IXACT3SoundBank_iface;
193 FACTSoundBank *fact_soundbank;
194 } XACT3SoundBankImpl;
196 static inline XACT3SoundBankImpl *impl_from_IXACT3SoundBank(IXACT3SoundBank *iface)
198 return CONTAINING_RECORD(iface, XACT3SoundBankImpl, IXACT3SoundBank_iface);
201 static XACTINDEX WINAPI IXACT3SoundBankImpl_GetCueIndex(IXACT3SoundBank *iface,
202 PCSTR szFriendlyName)
204 XACT3SoundBankImpl *This = impl_from_IXACT3SoundBank(iface);
206 TRACE("(%p)->(%s)\n", This, szFriendlyName);
208 return FACTSoundBank_GetCueIndex(This->fact_soundbank, szFriendlyName);
211 static HRESULT WINAPI IXACT3SoundBankImpl_GetNumCues(IXACT3SoundBank *iface,
212 XACTINDEX *pnNumCues)
214 XACT3SoundBankImpl *This = impl_from_IXACT3SoundBank(iface);
216 TRACE("(%p)->(%p)\n", This, pnNumCues);
218 return FACTSoundBank_GetNumCues(This->fact_soundbank, pnNumCues);
221 static HRESULT WINAPI IXACT3SoundBankImpl_GetCueProperties(IXACT3SoundBank *iface,
222 XACTINDEX nCueIndex, XACT_CUE_PROPERTIES *pProperties)
224 XACT3SoundBankImpl *This = impl_from_IXACT3SoundBank(iface);
226 TRACE("(%p)->(%u, %p)\n", This, nCueIndex, pProperties);
228 return FACTSoundBank_GetCueProperties(This->fact_soundbank, nCueIndex,
229 (FACTCueProperties*) pProperties);
232 static HRESULT WINAPI IXACT3SoundBankImpl_Prepare(IXACT3SoundBank *iface,
233 XACTINDEX nCueIndex, DWORD dwFlags, XACTTIME timeOffset,
234 IXACT3Cue** ppCue)
236 XACT3SoundBankImpl *This = impl_from_IXACT3SoundBank(iface);
237 XACT3CueImpl *cue;
238 FACTCue *fcue;
239 UINT ret;
241 TRACE("(%p)->(%u, 0x%x, %u, %p)\n", This, nCueIndex, dwFlags, timeOffset,
242 ppCue);
244 ret = FACTSoundBank_Prepare(This->fact_soundbank, nCueIndex, dwFlags,
245 timeOffset, &fcue);
246 if(ret != 0)
248 ERR("Failed to CreateCue: %d\n", ret);
249 return E_FAIL;
252 cue = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*cue));
253 if (!cue)
255 FACTCue_Destroy(fcue);
256 ERR("Failed to allocate XACT3CueImpl!");
257 return E_OUTOFMEMORY;
260 cue->IXACT3Cue_iface.lpVtbl = &XACT3Cue_Vtbl;
261 cue->fact_cue = fcue;
262 *ppCue = &cue->IXACT3Cue_iface;
264 TRACE("Created Cue: %p\n", cue);
266 return S_OK;
269 static HRESULT WINAPI IXACT3SoundBankImpl_Play(IXACT3SoundBank *iface,
270 XACTINDEX nCueIndex, DWORD dwFlags, XACTTIME timeOffset,
271 IXACT3Cue** ppCue)
273 XACT3SoundBankImpl *This = impl_from_IXACT3SoundBank(iface);
274 XACT3CueImpl *cue;
275 FACTCue *fcue;
276 HRESULT hr;
278 TRACE("(%p)->(%u, 0x%x, %u, %p)\n", This, nCueIndex, dwFlags, timeOffset,
279 ppCue);
281 /* If the application doesn't want a handle, don't generate one at all.
282 * Let the engine handle that memory instead.
283 * -flibit
285 if (ppCue == NULL){
286 hr = FACTSoundBank_Play(This->fact_soundbank, nCueIndex, dwFlags,
287 timeOffset, NULL);
288 }else{
289 hr = FACTSoundBank_Play(This->fact_soundbank, nCueIndex, dwFlags,
290 timeOffset, &fcue);
291 if(FAILED(hr))
292 return hr;
294 cue = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*cue));
295 if (!cue)
297 FACTCue_Destroy(fcue);
298 ERR("Failed to allocate XACT3CueImpl!");
299 return E_OUTOFMEMORY;
302 cue->IXACT3Cue_iface.lpVtbl = &XACT3Cue_Vtbl;
303 cue->fact_cue = fcue;
304 *ppCue = &cue->IXACT3Cue_iface;
307 return hr;
310 static HRESULT WINAPI IXACT3SoundBankImpl_Stop(IXACT3SoundBank *iface,
311 XACTINDEX nCueIndex, DWORD dwFlags)
313 XACT3SoundBankImpl *This = impl_from_IXACT3SoundBank(iface);
315 TRACE("(%p)->(%u)\n", This, dwFlags);
317 return FACTSoundBank_Stop(This->fact_soundbank, nCueIndex, dwFlags);
320 static HRESULT WINAPI IXACT3SoundBankImpl_Destroy(IXACT3SoundBank *iface)
322 XACT3SoundBankImpl *This = impl_from_IXACT3SoundBank(iface);
323 HRESULT hr;
325 TRACE("(%p)\n", This);
327 hr = FACTSoundBank_Destroy(This->fact_soundbank);
328 HeapFree(GetProcessHeap(), 0, This);
329 return hr;
332 static HRESULT WINAPI IXACT3SoundBankImpl_GetState(IXACT3SoundBank *iface,
333 DWORD *pdwState)
335 XACT3SoundBankImpl *This = impl_from_IXACT3SoundBank(iface);
337 TRACE("(%p)->(%p)\n", This, pdwState);
339 return FACTSoundBank_GetState(This->fact_soundbank, pdwState);
342 static const IXACT3SoundBankVtbl XACT3SoundBank_Vtbl =
344 IXACT3SoundBankImpl_GetCueIndex,
345 IXACT3SoundBankImpl_GetNumCues,
346 IXACT3SoundBankImpl_GetCueProperties,
347 IXACT3SoundBankImpl_Prepare,
348 IXACT3SoundBankImpl_Play,
349 IXACT3SoundBankImpl_Stop,
350 IXACT3SoundBankImpl_Destroy,
351 IXACT3SoundBankImpl_GetState
354 typedef struct _XACT3WaveImpl {
355 IXACT3Wave IXACT3Wave_iface;
357 FACTWave *fact_wave;
358 } XACT3WaveImpl;
360 static inline XACT3WaveImpl *impl_from_IXACT3Wave(IXACT3Wave *iface)
362 return CONTAINING_RECORD(iface, XACT3WaveImpl, IXACT3Wave_iface);
365 static HRESULT WINAPI IXACT3WaveImpl_Destroy(IXACT3Wave *iface)
367 XACT3WaveImpl *This = impl_from_IXACT3Wave(iface);
368 HRESULT hr;
370 TRACE("(%p)\n", This);
372 hr = FACTWave_Destroy(This->fact_wave);
373 HeapFree(GetProcessHeap(), 0, This);
374 return hr;
377 static HRESULT WINAPI IXACT3WaveImpl_Play(IXACT3Wave *iface)
379 XACT3WaveImpl *This = impl_from_IXACT3Wave(iface);
381 TRACE("(%p)\n", This);
383 return FACTWave_Play(This->fact_wave);
386 static HRESULT WINAPI IXACT3WaveImpl_Stop(IXACT3Wave *iface, DWORD dwFlags)
388 XACT3WaveImpl *This = impl_from_IXACT3Wave(iface);
390 TRACE("(%p)->(0x%x)\n", This, dwFlags);
392 return FACTWave_Stop(This->fact_wave, dwFlags);
395 static HRESULT WINAPI IXACT3WaveImpl_Pause(IXACT3Wave *iface, BOOL fPause)
397 XACT3WaveImpl *This = impl_from_IXACT3Wave(iface);
399 TRACE("(%p)->(%u)\n", This, fPause);
401 return FACTWave_Pause(This->fact_wave, fPause);
404 static HRESULT WINAPI IXACT3WaveImpl_GetState(IXACT3Wave *iface, DWORD *pdwState)
406 XACT3WaveImpl *This = impl_from_IXACT3Wave(iface);
408 TRACE("(%p)->(%p)\n", This, pdwState);
410 return FACTWave_GetState(This->fact_wave, pdwState);
413 static HRESULT WINAPI IXACT3WaveImpl_SetPitch(IXACT3Wave *iface, XACTPITCH pitch)
415 XACT3WaveImpl *This = impl_from_IXACT3Wave(iface);
417 TRACE("(%p)->(%d)\n", This, pitch);
419 return FACTWave_SetPitch(This->fact_wave, pitch);
422 static HRESULT WINAPI IXACT3WaveImpl_SetVolume(IXACT3Wave *iface, XACTVOLUME volume)
424 XACT3WaveImpl *This = impl_from_IXACT3Wave(iface);
426 TRACE("(%p)->(%f)\n", This, volume);
428 return FACTWave_SetVolume(This->fact_wave, volume);
431 static HRESULT WINAPI IXACT3WaveImpl_SetMatrixCoefficients(IXACT3Wave *iface,
432 UINT32 uSrcChannelCount, UINT32 uDstChannelCount,
433 float *pMatrixCoefficients)
435 XACT3WaveImpl *This = impl_from_IXACT3Wave(iface);
437 TRACE("(%p)->(%u, %u, %p)\n", This, uSrcChannelCount, uDstChannelCount,
438 pMatrixCoefficients);
440 return FACTWave_SetMatrixCoefficients(This->fact_wave, uSrcChannelCount,
441 uDstChannelCount, pMatrixCoefficients);
444 static HRESULT WINAPI IXACT3WaveImpl_GetProperties(IXACT3Wave *iface,
445 XACT_WAVE_INSTANCE_PROPERTIES *pProperties)
447 XACT3WaveImpl *This = impl_from_IXACT3Wave(iface);
449 TRACE("(%p)->(%p)\n", This, pProperties);
451 return FACTWave_GetProperties(This->fact_wave,
452 (FACTWaveInstanceProperties*) pProperties);
455 static const IXACT3WaveVtbl XACT3Wave_Vtbl =
457 IXACT3WaveImpl_Destroy,
458 IXACT3WaveImpl_Play,
459 IXACT3WaveImpl_Stop,
460 IXACT3WaveImpl_Pause,
461 IXACT3WaveImpl_GetState,
462 IXACT3WaveImpl_SetPitch,
463 IXACT3WaveImpl_SetVolume,
464 IXACT3WaveImpl_SetMatrixCoefficients,
465 IXACT3WaveImpl_GetProperties
468 typedef struct _XACT3WaveBankImpl {
469 IXACT3WaveBank IXACT3WaveBank_iface;
471 FACTWaveBank *fact_wavebank;
472 } XACT3WaveBankImpl;
474 static inline XACT3WaveBankImpl *impl_from_IXACT3WaveBank(IXACT3WaveBank *iface)
476 return CONTAINING_RECORD(iface, XACT3WaveBankImpl, IXACT3WaveBank_iface);
479 static HRESULT WINAPI IXACT3WaveBankImpl_Destroy(IXACT3WaveBank *iface)
481 XACT3WaveBankImpl *This = impl_from_IXACT3WaveBank(iface);
482 HRESULT hr;
484 TRACE("(%p)\n", This);
486 hr = FACTWaveBank_Destroy(This->fact_wavebank);
487 HeapFree(GetProcessHeap(), 0, This);
488 return hr;
491 static HRESULT WINAPI IXACT3WaveBankImpl_GetNumWaves(IXACT3WaveBank *iface,
492 XACTINDEX *pnNumWaves)
494 XACT3WaveBankImpl *This = impl_from_IXACT3WaveBank(iface);
496 TRACE("(%p)->(%p)\n", This, pnNumWaves);
498 return FACTWaveBank_GetNumWaves(This->fact_wavebank, pnNumWaves);
501 static XACTINDEX WINAPI IXACT3WaveBankImpl_GetWaveIndex(IXACT3WaveBank *iface,
502 PCSTR szFriendlyName)
504 XACT3WaveBankImpl *This = impl_from_IXACT3WaveBank(iface);
506 TRACE("(%p)->(%s)\n", This, szFriendlyName);
508 return FACTWaveBank_GetWaveIndex(This->fact_wavebank, szFriendlyName);
511 static HRESULT WINAPI IXACT3WaveBankImpl_GetWaveProperties(IXACT3WaveBank *iface,
512 XACTINDEX nWaveIndex, XACT_WAVE_PROPERTIES *pWaveProperties)
514 XACT3WaveBankImpl *This = impl_from_IXACT3WaveBank(iface);
516 TRACE("(%p)->(%u, %p)\n", This, nWaveIndex, pWaveProperties);
518 return FACTWaveBank_GetWaveProperties(This->fact_wavebank, nWaveIndex,
519 (FACTWaveProperties*) pWaveProperties);
522 static HRESULT WINAPI IXACT3WaveBankImpl_Prepare(IXACT3WaveBank *iface,
523 XACTINDEX nWaveIndex, DWORD dwFlags, DWORD dwPlayOffset,
524 XACTLOOPCOUNT nLoopCount, IXACT3Wave** ppWave)
526 XACT3WaveBankImpl *This = impl_from_IXACT3WaveBank(iface);
527 XACT3WaveImpl *wave;
528 FACTWave *fwave;
529 UINT ret;
531 TRACE("(%p)->(0x%x, %u, 0x%x, %u, %p)\n", This, nWaveIndex, dwFlags,
532 dwPlayOffset, nLoopCount, ppWave);
534 ret = FACTWaveBank_Prepare(This->fact_wavebank, nWaveIndex, dwFlags,
535 dwPlayOffset, nLoopCount, &fwave);
536 if(ret != 0)
538 ERR("Failed to CreateWave: %d\n", ret);
539 return E_FAIL;
542 wave = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*wave));
543 if (!wave)
545 FACTWave_Destroy(fwave);
546 ERR("Failed to allocate XACT3WaveImpl!");
547 return E_OUTOFMEMORY;
550 wave->IXACT3Wave_iface.lpVtbl = &XACT3Wave_Vtbl;
551 wave->fact_wave = fwave;
552 *ppWave = &wave->IXACT3Wave_iface;
554 TRACE("Created Wave: %p\n", wave);
556 return S_OK;
559 static HRESULT WINAPI IXACT3WaveBankImpl_Play(IXACT3WaveBank *iface,
560 XACTINDEX nWaveIndex, DWORD dwFlags, DWORD dwPlayOffset,
561 XACTLOOPCOUNT nLoopCount, IXACT3Wave** ppWave)
563 XACT3WaveBankImpl *This = impl_from_IXACT3WaveBank(iface);
564 XACT3WaveImpl *wave;
565 FACTWave *fwave;
566 HRESULT hr;
568 TRACE("(%p)->(0x%x, %u, 0x%x, %u, %p)\n", This, nWaveIndex, dwFlags, dwPlayOffset,
569 nLoopCount, ppWave);
571 /* If the application doesn't want a handle, don't generate one at all.
572 * Let the engine handle that memory instead.
573 * -flibit
575 if (ppWave == NULL){
576 hr = FACTWaveBank_Play(This->fact_wavebank, nWaveIndex, dwFlags,
577 dwPlayOffset, nLoopCount, NULL);
578 }else{
579 hr = FACTWaveBank_Play(This->fact_wavebank, nWaveIndex, dwFlags,
580 dwPlayOffset, nLoopCount, &fwave);
581 if(FAILED(hr))
582 return hr;
584 wave = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*wave));
585 if (!wave)
587 FACTWave_Destroy(fwave);
588 ERR("Failed to allocate XACT3WaveImpl!");
589 return E_OUTOFMEMORY;
592 wave->IXACT3Wave_iface.lpVtbl = &XACT3Wave_Vtbl;
593 wave->fact_wave = fwave;
594 *ppWave = &wave->IXACT3Wave_iface;
597 return hr;
600 static HRESULT WINAPI IXACT3WaveBankImpl_Stop(IXACT3WaveBank *iface,
601 XACTINDEX nWaveIndex, DWORD dwFlags)
603 XACT3WaveBankImpl *This = impl_from_IXACT3WaveBank(iface);
605 TRACE("(%p)->(%u, %u)\n", This, nWaveIndex, dwFlags);
607 return FACTWaveBank_Stop(This->fact_wavebank, nWaveIndex, dwFlags);
610 static HRESULT WINAPI IXACT3WaveBankImpl_GetState(IXACT3WaveBank *iface,
611 DWORD *pdwState)
613 XACT3WaveBankImpl *This = impl_from_IXACT3WaveBank(iface);
615 TRACE("(%p)->(%p)\n", This, pdwState);
617 return FACTWaveBank_GetState(This->fact_wavebank, pdwState);
620 static const IXACT3WaveBankVtbl XACT3WaveBank_Vtbl =
622 IXACT3WaveBankImpl_Destroy,
623 IXACT3WaveBankImpl_GetNumWaves,
624 IXACT3WaveBankImpl_GetWaveIndex,
625 IXACT3WaveBankImpl_GetWaveProperties,
626 IXACT3WaveBankImpl_Prepare,
627 IXACT3WaveBankImpl_Play,
628 IXACT3WaveBankImpl_Stop,
629 IXACT3WaveBankImpl_GetState
632 typedef struct _XACT3EngineImpl {
633 IXACT3Engine IXACT3Engine_iface;
635 FACTAudioEngine *fact_engine;
637 XACT_READFILE_CALLBACK pReadFile;
638 XACT_GETOVERLAPPEDRESULT_CALLBACK pGetOverlappedResult;
639 XACT_NOTIFICATION_CALLBACK notification_callback;
640 } XACT3EngineImpl;
642 typedef struct wrap_readfile_struct {
643 XACT3EngineImpl *engine;
644 HANDLE file;
645 } wrap_readfile_struct;
647 static int32_t FACTCALL wrap_readfile(
648 void* hFile,
649 void* lpBuffer,
650 uint32_t nNumberOfBytesRead,
651 uint32_t *lpNumberOfBytesRead,
652 FACTOverlapped *lpOverlapped)
654 wrap_readfile_struct *wrap = (wrap_readfile_struct*) hFile;
655 return wrap->engine->pReadFile(wrap->file, lpBuffer, nNumberOfBytesRead,
656 lpNumberOfBytesRead, (LPOVERLAPPED)lpOverlapped);
659 static int32_t FACTCALL wrap_getoverlappedresult(
660 void* hFile,
661 FACTOverlapped *lpOverlapped,
662 uint32_t *lpNumberOfBytesTransferred,
663 int32_t bWait)
665 wrap_readfile_struct *wrap = (wrap_readfile_struct*) hFile;
666 return wrap->engine->pGetOverlappedResult(wrap->file, (LPOVERLAPPED)lpOverlapped,
667 lpNumberOfBytesTransferred, bWait);
670 static inline XACT3EngineImpl *impl_from_IXACT3Engine(IXACT3Engine *iface)
672 return CONTAINING_RECORD(iface, XACT3EngineImpl, IXACT3Engine_iface);
675 static HRESULT WINAPI IXACT3EngineImpl_QueryInterface(IXACT3Engine *iface,
676 REFIID riid, void **ppvObject)
678 XACT3EngineImpl *This = impl_from_IXACT3Engine(iface);
680 TRACE("(%p)->(%s, %p)\n", This, debugstr_guid(riid), ppvObject);
682 if(IsEqualGUID(riid, &IID_IUnknown) ||
683 IsEqualGUID(riid, &IID_IXACT3Engine)){
684 *ppvObject = &This->IXACT3Engine_iface;
686 else
687 *ppvObject = NULL;
689 if (*ppvObject){
690 IUnknown_AddRef((IUnknown*)*ppvObject);
691 return S_OK;
694 FIXME("(%p)->(%s,%p), not found\n", This, debugstr_guid(riid), ppvObject);
696 return E_NOINTERFACE;
699 static ULONG WINAPI IXACT3EngineImpl_AddRef(IXACT3Engine *iface)
701 XACT3EngineImpl *This = impl_from_IXACT3Engine(iface);
702 ULONG ref = FACTAudioEngine_AddRef(This->fact_engine);
703 TRACE("(%p)->(): Refcount now %u\n", This, ref);
704 return ref;
707 static ULONG WINAPI IXACT3EngineImpl_Release(IXACT3Engine *iface)
709 XACT3EngineImpl *This = impl_from_IXACT3Engine(iface);
710 ULONG ref = FACTAudioEngine_Release(This->fact_engine);
712 TRACE("(%p)->(): Refcount now %u\n", This, ref);
714 if (!ref)
715 HeapFree(GetProcessHeap(), 0, This);
716 return ref;
719 static HRESULT WINAPI IXACT3EngineImpl_GetRendererCount(IXACT3Engine *iface,
720 XACTINDEX *pnRendererCount)
722 XACT3EngineImpl *This = impl_from_IXACT3Engine(iface);
724 TRACE("(%p)->(%p)\n", This, pnRendererCount);
726 return FACTAudioEngine_GetRendererCount(This->fact_engine, pnRendererCount);
729 static HRESULT WINAPI IXACT3EngineImpl_GetRendererDetails(IXACT3Engine *iface,
730 XACTINDEX nRendererIndex, XACT_RENDERER_DETAILS *pRendererDetails)
732 XACT3EngineImpl *This = impl_from_IXACT3Engine(iface);
734 TRACE("(%p)->(%d, %p)\n", This, nRendererIndex, pRendererDetails);
736 return FACTAudioEngine_GetRendererDetails(This->fact_engine,
737 nRendererIndex, (FACTRendererDetails*) pRendererDetails);
740 static HRESULT WINAPI IXACT3EngineImpl_GetFinalMixFormat(IXACT3Engine *iface,
741 WAVEFORMATEXTENSIBLE *pFinalMixFormat)
743 XACT3EngineImpl *This = impl_from_IXACT3Engine(iface);
745 TRACE("(%p)->(%p)\n", This, pFinalMixFormat);
747 return FACTAudioEngine_GetFinalMixFormat(This->fact_engine,
748 (FAudioWaveFormatExtensible*) pFinalMixFormat);
751 static void FACTCALL fact_notification_cb(const FACTNotification *notification)
753 XACT3EngineImpl *engine = (XACT3EngineImpl *)notification->pvContext;
755 /* Older versions of FAudio don't pass through the context */
756 if (!engine)
758 WARN("Notification context is NULL\n");
759 return;
762 if (notification->type == XACTNOTIFICATIONTYPE_SOUNDBANKDESTROYED)
764 FIXME("Callback XACTNOTIFICATIONTYPE_SOUNDBANKDESTROYED\n");
766 else
767 FIXME("Unsupported callback type %d\n", notification->type);
770 static HRESULT WINAPI IXACT3EngineImpl_Initialize(IXACT3Engine *iface,
771 const XACT_RUNTIME_PARAMETERS *pParams)
773 XACT3EngineImpl *This = impl_from_IXACT3Engine(iface);
774 FACTRuntimeParameters params;
775 UINT ret;
777 TRACE("(%p)->(%p)\n", This, pParams);
779 memset(&params, 0, sizeof(FACTRuntimeParameters));
780 /* Explicitly copy to the FAudio structure as the packing is wrong under 64 bits */
781 params.lookAheadTime = pParams->lookAheadTime;
782 params.pGlobalSettingsBuffer = pParams->pGlobalSettingsBuffer;
783 params.globalSettingsBufferSize = pParams->globalSettingsBufferSize;
784 params.globalSettingsFlags = pParams->globalSettingsFlags;
785 params.globalSettingsAllocAttributes = pParams->globalSettingsAllocAttributes;
786 params.pRendererID = (int16_t*)pParams->pRendererID;
787 params.pXAudio2 = NULL;
788 params.pMasteringVoice = NULL;
790 /* FIXME: pXAudio2 and pMasteringVoice are pointers to
791 * IXAudio2/IXAudio2MasteringVoice objects. FACT wants pointers to
792 * FAudio/FAudioMasteringVoice objects. In Wine's XAudio2 implementation, we
793 * actually have them available, but only if you access their internal data.
794 * For now we can just force these pointers to NULL, as XACT simply
795 * generates its own engine and endpoint in that situation. These parameters
796 * are mostly an optimization for games with multiple XACT3Engines that want
797 * a single engine running everything.
798 * -flibit
800 if (pParams->pXAudio2 != NULL){
801 FIXME("pXAudio2 parameter not supported!\n");
803 if (pParams->pMasteringVoice != NULL){
804 FIXME("pMasteringVoice parameter not supported!\n");
808 /* Force Windows I/O, do NOT use the FACT default! */
809 This->pReadFile = (XACT_READFILE_CALLBACK)
810 pParams->fileIOCallbacks.readFileCallback;
811 This->pGetOverlappedResult = (XACT_GETOVERLAPPEDRESULT_CALLBACK)
812 pParams->fileIOCallbacks.getOverlappedResultCallback;
813 if (This->pReadFile == NULL)
814 This->pReadFile = (XACT_READFILE_CALLBACK) ReadFile;
815 if (This->pGetOverlappedResult == NULL)
816 This->pGetOverlappedResult = (XACT_GETOVERLAPPEDRESULT_CALLBACK)
817 GetOverlappedResult;
818 params.fileIOCallbacks.readFileCallback = wrap_readfile;
819 params.fileIOCallbacks.getOverlappedResultCallback = wrap_getoverlappedresult;
820 params.fnNotificationCallback = fact_notification_cb;
822 This->notification_callback = (XACT_NOTIFICATION_CALLBACK)pParams->fnNotificationCallback;
824 ret = FACTAudioEngine_Initialize(This->fact_engine, &params);
825 if (ret != 0)
826 WARN("FACTAudioEngine_Initialize returned %d\n", ret);
828 return !ret ? S_OK : E_FAIL;
831 static HRESULT WINAPI IXACT3EngineImpl_ShutDown(IXACT3Engine *iface)
833 XACT3EngineImpl *This = impl_from_IXACT3Engine(iface);
835 TRACE("(%p)\n", This);
837 return FACTAudioEngine_ShutDown(This->fact_engine);
840 static HRESULT WINAPI IXACT3EngineImpl_DoWork(IXACT3Engine *iface)
842 XACT3EngineImpl *This = impl_from_IXACT3Engine(iface);
844 TRACE("(%p)\n", This);
846 return FACTAudioEngine_DoWork(This->fact_engine);
849 static HRESULT WINAPI IXACT3EngineImpl_CreateSoundBank(IXACT3Engine *iface,
850 const void* pvBuffer, DWORD dwSize, DWORD dwFlags,
851 DWORD dwAllocAttributes, IXACT3SoundBank **ppSoundBank)
853 XACT3EngineImpl *This = impl_from_IXACT3Engine(iface);
854 XACT3SoundBankImpl *sb;
855 FACTSoundBank *fsb;
856 UINT ret;
858 TRACE("(%p)->(%p, %u, 0x%x, 0x%x, %p): stub!\n", This, pvBuffer, dwSize, dwFlags,
859 dwAllocAttributes, ppSoundBank);
861 ret = FACTAudioEngine_CreateSoundBank(This->fact_engine, pvBuffer, dwSize,
862 dwFlags, dwAllocAttributes, &fsb);
863 if(ret != 0)
865 ERR("Failed to CreateSoundBank: %d\n", ret);
866 return E_FAIL;
869 sb = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*sb));
870 if (!sb)
872 FACTSoundBank_Destroy(fsb);
873 ERR("Failed to allocate XACT3SoundBankImpl!");
874 return E_OUTOFMEMORY;
877 sb->IXACT3SoundBank_iface.lpVtbl = &XACT3SoundBank_Vtbl;
878 sb->fact_soundbank = fsb;
879 *ppSoundBank = &sb->IXACT3SoundBank_iface;
881 TRACE("Created SoundBank: %p\n", sb);
883 return S_OK;
886 static HRESULT WINAPI IXACT3EngineImpl_CreateInMemoryWaveBank(IXACT3Engine *iface,
887 const void* pvBuffer, DWORD dwSize, DWORD dwFlags,
888 DWORD dwAllocAttributes, IXACT3WaveBank **ppWaveBank)
890 XACT3EngineImpl *This = impl_from_IXACT3Engine(iface);
891 XACT3WaveBankImpl *wb;
892 FACTWaveBank *fwb;
893 UINT ret;
895 TRACE("(%p)->(%p, %u, 0x%x, 0x%x, %p)\n", This, pvBuffer, dwSize, dwFlags,
896 dwAllocAttributes, ppWaveBank);
898 ret = FACTAudioEngine_CreateInMemoryWaveBank(This->fact_engine, pvBuffer,
899 dwSize, dwFlags, dwAllocAttributes, &fwb);
900 if(ret != 0)
902 ERR("Failed to CreateWaveBank: %d\n", ret);
903 return E_FAIL;
906 wb = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*wb));
907 if (!wb)
909 FACTWaveBank_Destroy(fwb);
910 ERR("Failed to allocate XACT3WaveBankImpl!");
911 return E_OUTOFMEMORY;
914 wb->IXACT3WaveBank_iface.lpVtbl = &XACT3WaveBank_Vtbl;
915 wb->fact_wavebank = fwb;
916 *ppWaveBank = &wb->IXACT3WaveBank_iface;
918 TRACE("Created in-memory WaveBank: %p\n", wb);
920 return S_OK;
923 static HRESULT WINAPI IXACT3EngineImpl_CreateStreamingWaveBank(IXACT3Engine *iface,
924 const XACT_WAVEBANK_STREAMING_PARAMETERS *pParms,
925 IXACT3WaveBank **ppWaveBank)
927 XACT3EngineImpl *This = impl_from_IXACT3Engine(iface);
928 FACTStreamingParameters fakeParms;
929 wrap_readfile_struct *fake;
930 XACT3WaveBankImpl *wb;
931 FACTWaveBank *fwb;
932 UINT ret;
934 TRACE("(%p)->(%p, %p)\n", This, pParms, ppWaveBank);
936 /* We have to wrap the file to fix up the callbacks! */
937 fake = (wrap_readfile_struct*) CoTaskMemAlloc(
938 sizeof(wrap_readfile_struct));
939 fake->engine = This;
940 fake->file = pParms->file;
941 fakeParms.file = fake;
942 fakeParms.flags = pParms->flags;
943 fakeParms.offset = pParms->offset;
944 fakeParms.packetSize = pParms->packetSize;
946 ret = FACTAudioEngine_CreateStreamingWaveBank(This->fact_engine, &fakeParms,
947 &fwb);
948 if(ret != 0)
950 ERR("Failed to CreateWaveBank: %d\n", ret);
951 return E_FAIL;
954 wb = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*wb));
955 if (!wb)
957 FACTWaveBank_Destroy(fwb);
958 ERR("Failed to allocate XACT3WaveBankImpl!");
959 return E_OUTOFMEMORY;
962 wb->IXACT3WaveBank_iface.lpVtbl = &XACT3WaveBank_Vtbl;
963 wb->fact_wavebank = fwb;
964 *ppWaveBank = &wb->IXACT3WaveBank_iface;
966 TRACE("Created streaming WaveBank: %p\n", wb);
968 return S_OK;
971 static HRESULT WINAPI IXACT3EngineImpl_PrepareInMemoryWave(IXACT3Engine *iface,
972 DWORD dwFlags, WAVEBANKENTRY entry, DWORD *pdwSeekTable,
973 BYTE *pbWaveData, DWORD dwPlayOffset, XACTLOOPCOUNT nLoopCount,
974 IXACT3Wave **ppWave)
976 XACT3EngineImpl *This = impl_from_IXACT3Engine(iface);
977 FIXME("(%p): stub!\n", This);
978 return E_NOTIMPL;
981 static HRESULT WINAPI IXACT3EngineImpl_PrepareStreamingWave(IXACT3Engine *iface,
982 DWORD dwFlags, WAVEBANKENTRY entry,
983 XACT_STREAMING_PARAMETERS streamingParams, DWORD dwAlignment,
984 DWORD *pdwSeekTable, DWORD dwPlayOffset, XACTLOOPCOUNT nLoopCount,
985 IXACT3Wave **ppWave)
987 XACT3EngineImpl *This = impl_from_IXACT3Engine(iface);
988 FIXME("(%p): stub!\n", This);
989 return E_NOTIMPL;
992 static HRESULT WINAPI IXACT3EngineImpl_PrepareWave(IXACT3Engine *iface,
993 DWORD dwFlags, PCSTR szWavePath, WORD wStreamingPacketSize,
994 DWORD dwAlignment, DWORD dwPlayOffset, XACTLOOPCOUNT nLoopCount,
995 IXACT3Wave **ppWave)
997 XACT3EngineImpl *This = impl_from_IXACT3Engine(iface);
998 FIXME("(%p): stub!\n", This);
999 return E_NOTIMPL;
1002 enum {
1003 NOTIFY_SoundBank = 0x01,
1004 NOTIFY_WaveBank = 0x02,
1005 NOTIFY_Cue = 0x04,
1006 NOTIFY_Wave = 0x08,
1007 NOTIFY_cueIndex = 0x10,
1008 NOTIFY_waveIndex = 0x20
1011 static inline void unwrap_notificationdesc(FACTNotificationDescription *fd,
1012 const XACT_NOTIFICATION_DESCRIPTION *xd)
1014 DWORD flags = 0;
1016 TRACE("Type %d\n", xd->type);
1018 memset(fd, 0, sizeof(*fd));
1020 /* Supports SoundBank, Cue index, Cue instance */
1021 if (xd->type == XACTNOTIFICATIONTYPE_CUEPREPARED || xd->type == XACTNOTIFICATIONTYPE_CUEPLAY ||
1022 xd->type == XACTNOTIFICATIONTYPE_CUESTOP || xd->type == XACTNOTIFICATIONTYPE_CUEDESTROYED ||
1023 xd->type == XACTNOTIFICATIONTYPE_MARKER || xd->type == XACTNOTIFICATIONTYPE_LOCALVARIABLECHANGED)
1025 flags = NOTIFY_SoundBank | NOTIFY_cueIndex | NOTIFY_Cue;
1027 /* Supports WaveBank */
1028 else if (xd->type == XACTNOTIFICATIONTYPE_WAVEBANKDESTROYED || xd->type == XACTNOTIFICATIONTYPE_WAVEBANKPREPARED ||
1029 xd->type == XACTNOTIFICATIONTYPE_WAVEBANKSTREAMING_INVALIDCONTENT)
1031 flags = NOTIFY_WaveBank;
1033 /* Supports NOTIFY_SoundBank */
1034 else if (xd->type == XACTNOTIFICATIONTYPE_SOUNDBANKDESTROYED)
1036 flags = NOTIFY_SoundBank;
1038 /* Supports WaveBank, Wave index, Wave instance */
1039 else if (xd->type == XACTNOTIFICATIONTYPE_WAVEPREPARED || xd->type == XACTNOTIFICATIONTYPE_WAVEDESTROYED)
1041 flags = NOTIFY_WaveBank | NOTIFY_waveIndex | NOTIFY_Wave;
1043 /* Supports SoundBank, SoundBank, Cue index, Cue instance, WaveBank, Wave instance */
1044 else if (xd->type == XACTNOTIFICATIONTYPE_WAVEPLAY || xd->type == XACTNOTIFICATIONTYPE_WAVESTOP ||
1045 xd->type == XACTNOTIFICATIONTYPE_WAVELOOPED)
1047 flags = NOTIFY_SoundBank | NOTIFY_cueIndex | NOTIFY_Cue | NOTIFY_WaveBank | NOTIFY_Wave;
1050 /* We have to unwrap the FACT object first! */
1051 fd->type = xd->type;
1052 fd->flags = xd->flags;
1053 fd->pvContext = xd->pvContext;
1054 if (flags & NOTIFY_cueIndex)
1055 fd->cueIndex = xd->cueIndex;
1056 if (flags & NOTIFY_waveIndex)
1057 fd->waveIndex = xd->waveIndex;
1059 if (flags & NOTIFY_Cue && xd->pCue != NULL)
1061 XACT3CueImpl *cue = impl_from_IXACT3Cue(xd->pCue);
1062 if (cue)
1063 fd->pCue = cue->fact_cue;
1066 if (flags & NOTIFY_SoundBank && xd->pSoundBank != NULL)
1068 XACT3SoundBankImpl *sound = impl_from_IXACT3SoundBank(xd->pSoundBank);
1069 if (sound)
1070 fd->pSoundBank = sound->fact_soundbank;
1073 if (flags & NOTIFY_WaveBank && xd->pWaveBank != NULL)
1075 XACT3WaveBankImpl *bank = impl_from_IXACT3WaveBank(xd->pWaveBank);
1076 if (bank)
1077 fd->pWaveBank = bank->fact_wavebank;
1080 if (flags & NOTIFY_Wave && xd->pWave != NULL)
1082 XACT3WaveImpl *wave = impl_from_IXACT3Wave(xd->pWave);
1083 if (wave)
1084 fd->pWave = wave->fact_wave;
1088 static HRESULT WINAPI IXACT3EngineImpl_RegisterNotification(IXACT3Engine *iface,
1089 const XACT_NOTIFICATION_DESCRIPTION *pNotificationDesc)
1091 XACT3EngineImpl *This = impl_from_IXACT3Engine(iface);
1092 FACTNotificationDescription fdesc;
1094 TRACE("(%p)->(%p)\n", This, pNotificationDesc);
1096 unwrap_notificationdesc(&fdesc, pNotificationDesc);
1097 fdesc.pvContext = This;
1098 return FACTAudioEngine_RegisterNotification(This->fact_engine, &fdesc);
1101 static HRESULT WINAPI IXACT3EngineImpl_UnRegisterNotification(IXACT3Engine *iface,
1102 const XACT_NOTIFICATION_DESCRIPTION *pNotificationDesc)
1104 XACT3EngineImpl *This = impl_from_IXACT3Engine(iface);
1105 FACTNotificationDescription fdesc;
1107 TRACE("(%p)->(%p)\n", This, pNotificationDesc);
1109 unwrap_notificationdesc(&fdesc, pNotificationDesc);
1110 fdesc.pvContext = This;
1111 return FACTAudioEngine_UnRegisterNotification(This->fact_engine, &fdesc);
1114 static XACTCATEGORY WINAPI IXACT3EngineImpl_GetCategory(IXACT3Engine *iface,
1115 PCSTR szFriendlyName)
1117 XACT3EngineImpl *This = impl_from_IXACT3Engine(iface);
1119 TRACE("(%p)->(%s)\n", This, szFriendlyName);
1121 return FACTAudioEngine_GetCategory(This->fact_engine, szFriendlyName);
1124 static HRESULT WINAPI IXACT3EngineImpl_Stop(IXACT3Engine *iface,
1125 XACTCATEGORY nCategory, DWORD dwFlags)
1127 XACT3EngineImpl *This = impl_from_IXACT3Engine(iface);
1129 TRACE("(%p)->(%u, 0x%x)\n", This, nCategory, dwFlags);
1131 return FACTAudioEngine_Stop(This->fact_engine, nCategory, dwFlags);
1134 static HRESULT WINAPI IXACT3EngineImpl_SetVolume(IXACT3Engine *iface,
1135 XACTCATEGORY nCategory, XACTVOLUME nVolume)
1137 XACT3EngineImpl *This = impl_from_IXACT3Engine(iface);
1139 TRACE("(%p)->(%u, %f)\n", This, nCategory, nVolume);
1141 return FACTAudioEngine_SetVolume(This->fact_engine, nCategory, nVolume);
1144 static HRESULT WINAPI IXACT3EngineImpl_Pause(IXACT3Engine *iface,
1145 XACTCATEGORY nCategory, BOOL fPause)
1147 XACT3EngineImpl *This = impl_from_IXACT3Engine(iface);
1149 TRACE("(%p)->(%u, %u)\n", This, nCategory, fPause);
1151 return FACTAudioEngine_Pause(This->fact_engine, nCategory, fPause);
1154 static XACTVARIABLEINDEX WINAPI IXACT3EngineImpl_GetGlobalVariableIndex(
1155 IXACT3Engine *iface, PCSTR szFriendlyName)
1157 XACT3EngineImpl *This = impl_from_IXACT3Engine(iface);
1159 TRACE("(%p)->(%s)\n", This, szFriendlyName);
1161 return FACTAudioEngine_GetGlobalVariableIndex(This->fact_engine,
1162 szFriendlyName);
1165 static HRESULT WINAPI IXACT3EngineImpl_SetGlobalVariable(IXACT3Engine *iface,
1166 XACTVARIABLEINDEX nIndex, XACTVARIABLEVALUE nValue)
1168 XACT3EngineImpl *This = impl_from_IXACT3Engine(iface);
1170 TRACE("(%p)->(%u, %f)\n", This, nIndex, nValue);
1172 return FACTAudioEngine_SetGlobalVariable(This->fact_engine, nIndex, nValue);
1175 static HRESULT WINAPI IXACT3EngineImpl_GetGlobalVariable(IXACT3Engine *iface,
1176 XACTVARIABLEINDEX nIndex, XACTVARIABLEVALUE *nValue)
1178 XACT3EngineImpl *This = impl_from_IXACT3Engine(iface);
1180 TRACE("(%p)->(%u, %p)\n", This, nIndex, nValue);
1182 return FACTAudioEngine_GetGlobalVariable(This->fact_engine, nIndex, nValue);
1185 static const IXACT3EngineVtbl XACT3Engine_Vtbl =
1187 IXACT3EngineImpl_QueryInterface,
1188 IXACT3EngineImpl_AddRef,
1189 IXACT3EngineImpl_Release,
1190 IXACT3EngineImpl_GetRendererCount,
1191 IXACT3EngineImpl_GetRendererDetails,
1192 IXACT3EngineImpl_GetFinalMixFormat,
1193 IXACT3EngineImpl_Initialize,
1194 IXACT3EngineImpl_ShutDown,
1195 IXACT3EngineImpl_DoWork,
1196 IXACT3EngineImpl_CreateSoundBank,
1197 IXACT3EngineImpl_CreateInMemoryWaveBank,
1198 IXACT3EngineImpl_CreateStreamingWaveBank,
1199 IXACT3EngineImpl_PrepareWave,
1200 IXACT3EngineImpl_PrepareInMemoryWave,
1201 IXACT3EngineImpl_PrepareStreamingWave,
1202 IXACT3EngineImpl_RegisterNotification,
1203 IXACT3EngineImpl_UnRegisterNotification,
1204 IXACT3EngineImpl_GetCategory,
1205 IXACT3EngineImpl_Stop,
1206 IXACT3EngineImpl_SetVolume,
1207 IXACT3EngineImpl_Pause,
1208 IXACT3EngineImpl_GetGlobalVariableIndex,
1209 IXACT3EngineImpl_SetGlobalVariable,
1210 IXACT3EngineImpl_GetGlobalVariable
1213 void* XACT_Internal_Malloc(size_t size)
1215 return CoTaskMemAlloc(size);
1218 void XACT_Internal_Free(void* ptr)
1220 return CoTaskMemFree(ptr);
1223 void* XACT_Internal_Realloc(void* ptr, size_t size)
1225 return CoTaskMemRealloc(ptr, size);
1228 static HRESULT WINAPI XACT3CF_QueryInterface(IClassFactory *iface, REFIID riid, void **ppobj)
1230 if(IsEqualGUID(riid, &IID_IUnknown) ||
1231 IsEqualGUID(riid, &IID_IClassFactory))
1233 *ppobj = iface;
1234 return S_OK;
1237 *ppobj = NULL;
1238 WARN("(%p)->(%s, %p): interface not found\n", iface, debugstr_guid(riid), ppobj);
1239 return E_NOINTERFACE;
1242 static ULONG WINAPI XACT3CF_AddRef(IClassFactory *iface)
1244 return 2;
1247 static ULONG WINAPI XACT3CF_Release(IClassFactory *iface)
1249 return 1;
1252 static HRESULT WINAPI XACT3CF_CreateInstance(IClassFactory *iface, IUnknown *pOuter,
1253 REFIID riid, void **ppobj)
1255 HRESULT hr;
1256 XACT3EngineImpl *object;
1258 TRACE("(%p)->(%p,%s,%p)\n", iface, pOuter, debugstr_guid(riid), ppobj);
1260 *ppobj = NULL;
1262 if(pOuter)
1263 return CLASS_E_NOAGGREGATION;
1265 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
1266 if(!object)
1267 return E_OUTOFMEMORY;
1269 object->IXACT3Engine_iface.lpVtbl = &XACT3Engine_Vtbl;
1271 FACTCreateEngineWithCustomAllocatorEXT(
1273 &object->fact_engine,
1274 XACT_Internal_Malloc,
1275 XACT_Internal_Free,
1276 XACT_Internal_Realloc
1279 hr = IXACT3Engine_QueryInterface(&object->IXACT3Engine_iface, riid, ppobj);
1280 if(FAILED(hr)){
1281 HeapFree(GetProcessHeap(), 0, object);
1282 return hr;
1285 return hr;
1288 static HRESULT WINAPI XACT3CF_LockServer(IClassFactory *iface, BOOL dolock)
1290 TRACE("(%p)->(%d): stub!\n", iface, dolock);
1291 return S_OK;
1294 static const IClassFactoryVtbl XACT3CF_Vtbl =
1296 XACT3CF_QueryInterface,
1297 XACT3CF_AddRef,
1298 XACT3CF_Release,
1299 XACT3CF_CreateInstance,
1300 XACT3CF_LockServer
1303 static IClassFactory XACTFactory = { &XACT3CF_Vtbl };
1305 BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD reason, void *pReserved)
1307 TRACE("(%p, %d, %p)\n", hinstDLL, reason, pReserved);
1309 switch (reason)
1311 case DLL_PROCESS_ATTACH:
1312 instance = hinstDLL;
1313 DisableThreadLibraryCalls( hinstDLL );
1315 #ifdef HAVE_FAUDIOLINKEDVERSION
1316 TRACE("Using FAudio version %d\n", FAudioLinkedVersion() );
1317 #endif
1319 break;
1321 return TRUE;
1324 HRESULT WINAPI DllCanUnloadNow(void)
1326 return S_FALSE;
1329 HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, void **ppv)
1331 if (IsEqualGUID(rclsid, &CLSID_XACTEngine))
1333 TRACE("(%s, %s, %p)\n", debugstr_guid(rclsid), debugstr_guid(riid), ppv);
1334 return IClassFactory_QueryInterface(&XACTFactory, riid, ppv);
1337 FIXME("Unknown class %s\n", debugstr_guid(rclsid));
1338 return CLASS_E_CLASSNOTAVAILABLE;
1341 HRESULT WINAPI DllRegisterServer(void)
1343 return __wine_register_resources(instance);
1346 HRESULT WINAPI DllUnregisterServer(void)
1348 return __wine_unregister_resources(instance);