mfplay: Implement GetCharacteristics().
[wine/zf.git] / dlls / xactengine3_7 / xact_dll.c
blob3fbb4875930dc72139c775d080943cf3d1c875b9
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!\n");
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!\n");
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!\n");
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!\n");
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!\n");
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!\n");
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!\n");
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 XACT3WaveImpl *wave;
999 FACTWave *fwave = NULL;
1000 UINT ret;
1002 TRACE("(%p)->(0x%08x, %s, %d, %d, %d, %d, %p)\n", This, dwFlags, debugstr_a(szWavePath),
1003 wStreamingPacketSize, dwAlignment, dwPlayOffset, nLoopCount, ppWave);
1005 ret = FACTAudioEngine_PrepareWave(This->fact_engine, dwFlags, szWavePath, wStreamingPacketSize,
1006 dwAlignment, dwPlayOffset, nLoopCount, &fwave);
1007 if(ret != 0 || !fwave)
1009 ERR("Failed to CreateWave: %d (%p)\n", ret, fwave);
1010 return E_FAIL;
1013 wave = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*wave));
1014 if (!wave)
1016 FACTWave_Destroy(fwave);
1017 return E_OUTOFMEMORY;
1020 wave->IXACT3Wave_iface.lpVtbl = &XACT3Wave_Vtbl;
1021 wave->fact_wave = fwave;
1022 *ppWave = &wave->IXACT3Wave_iface;
1024 TRACE("Created Wave: %p\n", wave);
1026 return S_OK;
1029 enum {
1030 NOTIFY_SoundBank = 0x01,
1031 NOTIFY_WaveBank = 0x02,
1032 NOTIFY_Cue = 0x04,
1033 NOTIFY_Wave = 0x08,
1034 NOTIFY_cueIndex = 0x10,
1035 NOTIFY_waveIndex = 0x20
1038 static inline void unwrap_notificationdesc(FACTNotificationDescription *fd,
1039 const XACT_NOTIFICATION_DESCRIPTION *xd)
1041 DWORD flags = 0;
1043 TRACE("Type %d\n", xd->type);
1045 memset(fd, 0, sizeof(*fd));
1047 /* Supports SoundBank, Cue index, Cue instance */
1048 if (xd->type == XACTNOTIFICATIONTYPE_CUEPREPARED || xd->type == XACTNOTIFICATIONTYPE_CUEPLAY ||
1049 xd->type == XACTNOTIFICATIONTYPE_CUESTOP || xd->type == XACTNOTIFICATIONTYPE_CUEDESTROYED ||
1050 xd->type == XACTNOTIFICATIONTYPE_MARKER || xd->type == XACTNOTIFICATIONTYPE_LOCALVARIABLECHANGED)
1052 flags = NOTIFY_SoundBank | NOTIFY_cueIndex | NOTIFY_Cue;
1054 /* Supports WaveBank */
1055 else if (xd->type == XACTNOTIFICATIONTYPE_WAVEBANKDESTROYED || xd->type == XACTNOTIFICATIONTYPE_WAVEBANKPREPARED ||
1056 xd->type == XACTNOTIFICATIONTYPE_WAVEBANKSTREAMING_INVALIDCONTENT)
1058 flags = NOTIFY_WaveBank;
1060 /* Supports NOTIFY_SoundBank */
1061 else if (xd->type == XACTNOTIFICATIONTYPE_SOUNDBANKDESTROYED)
1063 flags = NOTIFY_SoundBank;
1065 /* Supports WaveBank, Wave index, Wave instance */
1066 else if (xd->type == XACTNOTIFICATIONTYPE_WAVEPREPARED || xd->type == XACTNOTIFICATIONTYPE_WAVEDESTROYED)
1068 flags = NOTIFY_WaveBank | NOTIFY_waveIndex | NOTIFY_Wave;
1070 /* Supports SoundBank, SoundBank, Cue index, Cue instance, WaveBank, Wave instance */
1071 else if (xd->type == XACTNOTIFICATIONTYPE_WAVEPLAY || xd->type == XACTNOTIFICATIONTYPE_WAVESTOP ||
1072 xd->type == XACTNOTIFICATIONTYPE_WAVELOOPED)
1074 flags = NOTIFY_SoundBank | NOTIFY_cueIndex | NOTIFY_Cue | NOTIFY_WaveBank | NOTIFY_Wave;
1077 /* We have to unwrap the FACT object first! */
1078 fd->type = xd->type;
1079 fd->flags = xd->flags;
1080 fd->pvContext = xd->pvContext;
1081 if (flags & NOTIFY_cueIndex)
1082 fd->cueIndex = xd->cueIndex;
1083 if (flags & NOTIFY_waveIndex)
1084 fd->waveIndex = xd->waveIndex;
1086 if (flags & NOTIFY_Cue && xd->pCue != NULL)
1088 XACT3CueImpl *cue = impl_from_IXACT3Cue(xd->pCue);
1089 if (cue)
1090 fd->pCue = cue->fact_cue;
1093 if (flags & NOTIFY_SoundBank && xd->pSoundBank != NULL)
1095 XACT3SoundBankImpl *sound = impl_from_IXACT3SoundBank(xd->pSoundBank);
1096 if (sound)
1097 fd->pSoundBank = sound->fact_soundbank;
1100 if (flags & NOTIFY_WaveBank && xd->pWaveBank != NULL)
1102 XACT3WaveBankImpl *bank = impl_from_IXACT3WaveBank(xd->pWaveBank);
1103 if (bank)
1104 fd->pWaveBank = bank->fact_wavebank;
1107 if (flags & NOTIFY_Wave && xd->pWave != NULL)
1109 XACT3WaveImpl *wave = impl_from_IXACT3Wave(xd->pWave);
1110 if (wave)
1111 fd->pWave = wave->fact_wave;
1115 static HRESULT WINAPI IXACT3EngineImpl_RegisterNotification(IXACT3Engine *iface,
1116 const XACT_NOTIFICATION_DESCRIPTION *pNotificationDesc)
1118 XACT3EngineImpl *This = impl_from_IXACT3Engine(iface);
1119 FACTNotificationDescription fdesc;
1121 TRACE("(%p)->(%p)\n", This, pNotificationDesc);
1123 unwrap_notificationdesc(&fdesc, pNotificationDesc);
1124 fdesc.pvContext = This;
1125 return FACTAudioEngine_RegisterNotification(This->fact_engine, &fdesc);
1128 static HRESULT WINAPI IXACT3EngineImpl_UnRegisterNotification(IXACT3Engine *iface,
1129 const XACT_NOTIFICATION_DESCRIPTION *pNotificationDesc)
1131 XACT3EngineImpl *This = impl_from_IXACT3Engine(iface);
1132 FACTNotificationDescription fdesc;
1134 TRACE("(%p)->(%p)\n", This, pNotificationDesc);
1136 unwrap_notificationdesc(&fdesc, pNotificationDesc);
1137 fdesc.pvContext = This;
1138 return FACTAudioEngine_UnRegisterNotification(This->fact_engine, &fdesc);
1141 static XACTCATEGORY WINAPI IXACT3EngineImpl_GetCategory(IXACT3Engine *iface,
1142 PCSTR szFriendlyName)
1144 XACT3EngineImpl *This = impl_from_IXACT3Engine(iface);
1146 TRACE("(%p)->(%s)\n", This, szFriendlyName);
1148 return FACTAudioEngine_GetCategory(This->fact_engine, szFriendlyName);
1151 static HRESULT WINAPI IXACT3EngineImpl_Stop(IXACT3Engine *iface,
1152 XACTCATEGORY nCategory, DWORD dwFlags)
1154 XACT3EngineImpl *This = impl_from_IXACT3Engine(iface);
1156 TRACE("(%p)->(%u, 0x%x)\n", This, nCategory, dwFlags);
1158 return FACTAudioEngine_Stop(This->fact_engine, nCategory, dwFlags);
1161 static HRESULT WINAPI IXACT3EngineImpl_SetVolume(IXACT3Engine *iface,
1162 XACTCATEGORY nCategory, XACTVOLUME nVolume)
1164 XACT3EngineImpl *This = impl_from_IXACT3Engine(iface);
1166 TRACE("(%p)->(%u, %f)\n", This, nCategory, nVolume);
1168 return FACTAudioEngine_SetVolume(This->fact_engine, nCategory, nVolume);
1171 static HRESULT WINAPI IXACT3EngineImpl_Pause(IXACT3Engine *iface,
1172 XACTCATEGORY nCategory, BOOL fPause)
1174 XACT3EngineImpl *This = impl_from_IXACT3Engine(iface);
1176 TRACE("(%p)->(%u, %u)\n", This, nCategory, fPause);
1178 return FACTAudioEngine_Pause(This->fact_engine, nCategory, fPause);
1181 static XACTVARIABLEINDEX WINAPI IXACT3EngineImpl_GetGlobalVariableIndex(
1182 IXACT3Engine *iface, PCSTR szFriendlyName)
1184 XACT3EngineImpl *This = impl_from_IXACT3Engine(iface);
1186 TRACE("(%p)->(%s)\n", This, szFriendlyName);
1188 return FACTAudioEngine_GetGlobalVariableIndex(This->fact_engine,
1189 szFriendlyName);
1192 static HRESULT WINAPI IXACT3EngineImpl_SetGlobalVariable(IXACT3Engine *iface,
1193 XACTVARIABLEINDEX nIndex, XACTVARIABLEVALUE nValue)
1195 XACT3EngineImpl *This = impl_from_IXACT3Engine(iface);
1197 TRACE("(%p)->(%u, %f)\n", This, nIndex, nValue);
1199 return FACTAudioEngine_SetGlobalVariable(This->fact_engine, nIndex, nValue);
1202 static HRESULT WINAPI IXACT3EngineImpl_GetGlobalVariable(IXACT3Engine *iface,
1203 XACTVARIABLEINDEX nIndex, XACTVARIABLEVALUE *nValue)
1205 XACT3EngineImpl *This = impl_from_IXACT3Engine(iface);
1207 TRACE("(%p)->(%u, %p)\n", This, nIndex, nValue);
1209 return FACTAudioEngine_GetGlobalVariable(This->fact_engine, nIndex, nValue);
1212 static const IXACT3EngineVtbl XACT3Engine_Vtbl =
1214 IXACT3EngineImpl_QueryInterface,
1215 IXACT3EngineImpl_AddRef,
1216 IXACT3EngineImpl_Release,
1217 IXACT3EngineImpl_GetRendererCount,
1218 IXACT3EngineImpl_GetRendererDetails,
1219 IXACT3EngineImpl_GetFinalMixFormat,
1220 IXACT3EngineImpl_Initialize,
1221 IXACT3EngineImpl_ShutDown,
1222 IXACT3EngineImpl_DoWork,
1223 IXACT3EngineImpl_CreateSoundBank,
1224 IXACT3EngineImpl_CreateInMemoryWaveBank,
1225 IXACT3EngineImpl_CreateStreamingWaveBank,
1226 IXACT3EngineImpl_PrepareWave,
1227 IXACT3EngineImpl_PrepareInMemoryWave,
1228 IXACT3EngineImpl_PrepareStreamingWave,
1229 IXACT3EngineImpl_RegisterNotification,
1230 IXACT3EngineImpl_UnRegisterNotification,
1231 IXACT3EngineImpl_GetCategory,
1232 IXACT3EngineImpl_Stop,
1233 IXACT3EngineImpl_SetVolume,
1234 IXACT3EngineImpl_Pause,
1235 IXACT3EngineImpl_GetGlobalVariableIndex,
1236 IXACT3EngineImpl_SetGlobalVariable,
1237 IXACT3EngineImpl_GetGlobalVariable
1240 void* XACT_Internal_Malloc(size_t size)
1242 return CoTaskMemAlloc(size);
1245 void XACT_Internal_Free(void* ptr)
1247 return CoTaskMemFree(ptr);
1250 void* XACT_Internal_Realloc(void* ptr, size_t size)
1252 return CoTaskMemRealloc(ptr, size);
1255 static HRESULT WINAPI XACT3CF_QueryInterface(IClassFactory *iface, REFIID riid, void **ppobj)
1257 if(IsEqualGUID(riid, &IID_IUnknown) ||
1258 IsEqualGUID(riid, &IID_IClassFactory))
1260 *ppobj = iface;
1261 return S_OK;
1264 *ppobj = NULL;
1265 WARN("(%p)->(%s, %p): interface not found\n", iface, debugstr_guid(riid), ppobj);
1266 return E_NOINTERFACE;
1269 static ULONG WINAPI XACT3CF_AddRef(IClassFactory *iface)
1271 return 2;
1274 static ULONG WINAPI XACT3CF_Release(IClassFactory *iface)
1276 return 1;
1279 static HRESULT WINAPI XACT3CF_CreateInstance(IClassFactory *iface, IUnknown *pOuter,
1280 REFIID riid, void **ppobj)
1282 HRESULT hr;
1283 XACT3EngineImpl *object;
1285 TRACE("(%p)->(%p,%s,%p)\n", iface, pOuter, debugstr_guid(riid), ppobj);
1287 *ppobj = NULL;
1289 if(pOuter)
1290 return CLASS_E_NOAGGREGATION;
1292 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
1293 if(!object)
1294 return E_OUTOFMEMORY;
1296 object->IXACT3Engine_iface.lpVtbl = &XACT3Engine_Vtbl;
1298 FACTCreateEngineWithCustomAllocatorEXT(
1300 &object->fact_engine,
1301 XACT_Internal_Malloc,
1302 XACT_Internal_Free,
1303 XACT_Internal_Realloc
1306 hr = IXACT3Engine_QueryInterface(&object->IXACT3Engine_iface, riid, ppobj);
1307 if(FAILED(hr)){
1308 HeapFree(GetProcessHeap(), 0, object);
1309 return hr;
1312 return hr;
1315 static HRESULT WINAPI XACT3CF_LockServer(IClassFactory *iface, BOOL dolock)
1317 TRACE("(%p)->(%d): stub!\n", iface, dolock);
1318 return S_OK;
1321 static const IClassFactoryVtbl XACT3CF_Vtbl =
1323 XACT3CF_QueryInterface,
1324 XACT3CF_AddRef,
1325 XACT3CF_Release,
1326 XACT3CF_CreateInstance,
1327 XACT3CF_LockServer
1330 static IClassFactory XACTFactory = { &XACT3CF_Vtbl };
1332 BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD reason, void *pReserved)
1334 TRACE("(%p, %d, %p)\n", hinstDLL, reason, pReserved);
1336 switch (reason)
1338 case DLL_PROCESS_ATTACH:
1339 instance = hinstDLL;
1340 DisableThreadLibraryCalls( hinstDLL );
1342 #ifdef HAVE_FAUDIOLINKEDVERSION
1343 TRACE("Using FAudio version %d\n", FAudioLinkedVersion() );
1344 #endif
1346 break;
1348 return TRUE;
1351 HRESULT WINAPI DllCanUnloadNow(void)
1353 return S_FALSE;
1356 HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, void **ppv)
1358 if (IsEqualGUID(rclsid, &CLSID_XACTEngine))
1360 TRACE("(%s, %s, %p)\n", debugstr_guid(rclsid), debugstr_guid(riid), ppv);
1361 return IClassFactory_QueryInterface(&XACTFactory, riid, ppv);
1364 FIXME("Unknown class %s\n", debugstr_guid(rclsid));
1365 return CLASS_E_CLASSNOTAVAILABLE;
1368 HRESULT WINAPI DllRegisterServer(void)
1370 return __wine_register_resources(instance);
1373 HRESULT WINAPI DllUnregisterServer(void)
1375 return __wine_unregister_resources(instance);