1 #include "xact3.h"
2 
3 #include <assert.h>
4 
5 extern "C" int32_t FACTCALL ReadFile(
6 	void* hFile,
7 	void* lpBuffer,
8 	uint32_t nNumberOfBytesToRead,
9 	uint32_t *lpNumberOfBytesRead,
10 	FACTOverlapped *lpOverlapped
11 );
12 extern "C" int32_t FACTCALL GetOverlappedResult(
13 	void* hFile,
14 	FACTOverlapped *lpOverlapped,
15 	uint32_t *lpNumberOfBytesTransferred,
16 	int32_t bWait
17 );
18 
19 /* IXACT3Cue Implementation */
20 
21 class XACT3CueImpl : public IXACT3Cue
22 {
23 public:
XACT3CueImpl(FACTCue * newCue)24 	XACT3CueImpl(FACTCue *newCue)
25 	{
26 		cue = newCue;
27 	}
Play()28 	COM_METHOD(HRESULT) Play()
29 	{
30 		return FACTCue_Play(cue);
31 	}
Stop(uint32_t dwFlags)32 	COM_METHOD(HRESULT) Stop(uint32_t dwFlags)
33 	{
34 		return FACTCue_Stop(cue, dwFlags);
35 	};
GetState(uint32_t * pdwState)36 	COM_METHOD(HRESULT) GetState(uint32_t *pdwState)
37 	{
38 		return FACTCue_GetState(cue, pdwState);
39 	}
Destroy()40 	COM_METHOD(HRESULT) Destroy()
41 	{
42 		return FACTCue_Destroy(cue);
43 	}
SetMatrixCoefficients(uint32_t uSrcChannelCount,uint32_t uDstChannelCount,float * pMatrixCoefficients)44 	COM_METHOD(HRESULT) SetMatrixCoefficients(
45 		uint32_t uSrcChannelCount,
46 		uint32_t uDstChannelCount,
47 		float *pMatrixCoefficients
48 	) {
49 		return FACTCue_SetMatrixCoefficients(
50 			cue,
51 			uSrcChannelCount,
52 			uDstChannelCount,
53 			pMatrixCoefficients
54 		);
55 	}
GetVariableIndex(const char * szFriendlyName)56 	COM_METHOD(uint16_t) GetVariableIndex(const char *szFriendlyName)
57 	{
58 		return FACTCue_GetVariableIndex(cue, szFriendlyName);
59 	}
SetVariable(uint16_t nIndex,float nValue)60 	COM_METHOD(HRESULT) SetVariable(uint16_t nIndex, float nValue)
61 	{
62 		return FACTCue_SetVariable(cue, nIndex, nValue);
63 	}
GetVariable(uint16_t nIndex,float * nValue)64 	COM_METHOD(HRESULT) GetVariable(uint16_t nIndex, float *nValue)
65 	{
66 		return FACTCue_GetVariable(cue, nIndex, nValue);
67 	}
Pause(int32_t fPause)68 	COM_METHOD(HRESULT) Pause(int32_t fPause)
69 	{
70 		return FACTCue_Pause(cue, fPause);
71 	}
GetProperties(XACT_CUE_INSTANCE_PROPERTIES ** ppProperties)72 	COM_METHOD(HRESULT) GetProperties(
73 		XACT_CUE_INSTANCE_PROPERTIES **ppProperties
74 	) {
75 		return FACTCue_GetProperties(cue, ppProperties);
76 	}
77 #if XACT3_VERSION >= 5
SetOutputVoices(const XAUDIO2_VOICE_SENDS * pSendList)78 	COM_METHOD(HRESULT) SetOutputVoices(
79 		const XAUDIO2_VOICE_SENDS *pSendList /* Optional! */
80 	) {
81 		/* TODO: SetOutputVoices */
82 		return 0;
83 	}
SetOutputVoiceMatrix(const IXAudio2Voice * pDestinationVoice,uint32_t SourceChannels,uint32_t DestinationChannels,const float * pLevelMatrix)84 	COM_METHOD(HRESULT) SetOutputVoiceMatrix(
85 		const IXAudio2Voice *pDestinationVoice, /* Optional! */
86 		uint32_t SourceChannels,
87 		uint32_t DestinationChannels,
88 		const float *pLevelMatrix /* SourceChannels * DestinationChannels */
89 	) {
90 		/* TODO: SetOutputVoiceMatrix */
91 		return 0;
92 	}
93 #endif /* #if XACT3_VERSION >= 5 */
94 
95 	FACTCue *cue;
96 };
97 
98 /* IXACT3Wave Implementation */
99 
100 class XACT3WaveImpl : public IXACT3Wave
101 {
102 public:
XACT3WaveImpl(FACTWave * newWave)103 	XACT3WaveImpl(FACTWave *newWave)
104 	{
105 		wave = newWave;
106 	}
Destroy()107 	COM_METHOD(HRESULT) Destroy()
108 	{
109 		return FACTWave_Destroy(wave);
110 	}
Play()111 	COM_METHOD(HRESULT) Play()
112 	{
113 		return FACTWave_Play(wave);
114 	}
Stop(uint32_t dwFlags)115 	COM_METHOD(HRESULT) Stop(uint32_t dwFlags)
116 	{
117 		return FACTWave_Stop(wave, dwFlags);
118 	}
Pause(int32_t fPause)119 	COM_METHOD(HRESULT) Pause(int32_t fPause)
120 	{
121 		return FACTWave_Pause(wave, fPause);
122 	}
GetState(uint32_t * pdwState)123 	COM_METHOD(HRESULT) GetState(uint32_t *pdwState)
124 	{
125 		return FACTWave_GetState(wave, pdwState);
126 	}
SetPitch(int16_t pitch)127 	COM_METHOD(HRESULT) SetPitch(int16_t pitch)
128 	{
129 		return FACTWave_SetPitch(wave, pitch);
130 	}
SetVolume(float volume)131 	COM_METHOD(HRESULT) SetVolume(float volume)
132 	{
133 		return FACTWave_SetVolume(wave, volume);
134 	}
SetMatrixCoefficients(uint32_t uSrcChannelCount,uint32_t uDstChannelCount,float * pMatrixCoefficients)135 	COM_METHOD(HRESULT) SetMatrixCoefficients(
136 		uint32_t uSrcChannelCount,
137 		uint32_t uDstChannelCount,
138 		float *pMatrixCoefficients
139 	) {
140 		return FACTWave_SetMatrixCoefficients(
141 			wave,
142 			uSrcChannelCount,
143 			uDstChannelCount,
144 			pMatrixCoefficients
145 		);
146 	}
GetProperties(XACT_WAVE_INSTANCE_PROPERTIES * pProperties)147 	COM_METHOD(HRESULT) GetProperties(
148 		XACT_WAVE_INSTANCE_PROPERTIES *pProperties
149 	) {
150 		return FACTWave_GetProperties(wave, pProperties);
151 	}
152 
153 	FACTWave *wave;
154 };
155 
156 /* IXACT3SoundBank Implementation */
157 
158 class XACT3SoundBankImpl : public IXACT3SoundBank
159 {
160 public:
XACT3SoundBankImpl(FACTSoundBank * newSoundBank)161 	XACT3SoundBankImpl(FACTSoundBank *newSoundBank)
162 	{
163 		soundBank = newSoundBank;
164 	}
GetCueIndex(const char * szFriendlyName)165 	COM_METHOD(uint16_t) GetCueIndex(const char *szFriendlyName)
166 	{
167 		return FACTSoundBank_GetCueIndex(soundBank, szFriendlyName);
168 	}
GetNumCues(uint16_t * pnNumCues)169 	COM_METHOD(HRESULT) GetNumCues(uint16_t *pnNumCues)
170 	{
171 		return FACTSoundBank_GetNumCues(soundBank, pnNumCues);
172 	}
GetCueProperties(uint16_t nCueIndex,XACT_CUE_PROPERTIES * pProperties)173 	COM_METHOD(HRESULT) GetCueProperties(
174 		uint16_t nCueIndex,
175 		XACT_CUE_PROPERTIES *pProperties
176 	) {
177 		return FACTSoundBank_GetCueProperties(
178 			soundBank,
179 			nCueIndex,
180 			pProperties
181 		);
182 	}
Prepare(uint16_t nCueIndex,uint32_t dwFlags,int32_t timeOffset,IXACT3Cue ** ppCue)183 	COM_METHOD(HRESULT) Prepare(
184 		uint16_t nCueIndex,
185 		uint32_t dwFlags,
186 		int32_t timeOffset,
187 		IXACT3Cue** ppCue
188 	) {
189 		FACTCue *cue;
190 		HRESULT retval = FACTSoundBank_Prepare(
191 			soundBank,
192 			nCueIndex,
193 			dwFlags,
194 			timeOffset,
195 			&cue
196 		);
197 		*ppCue = new XACT3CueImpl(cue);
198 		return retval;
199 	}
Play(uint16_t nCueIndex,uint32_t dwFlags,int32_t timeOffset,IXACT3Cue ** ppCue)200 	COM_METHOD(HRESULT) Play(
201 		uint16_t nCueIndex,
202 		uint32_t dwFlags,
203 		int32_t timeOffset,
204 		IXACT3Cue** ppCue /* Optional! */
205 	) {
206 		if (ppCue == NULL)
207 		{
208 			return FACTSoundBank_Play(
209 				soundBank,
210 				nCueIndex,
211 				dwFlags,
212 				timeOffset,
213 				NULL
214 			);
215 		}
216 		FACTCue *cue;
217 		HRESULT retval = FACTSoundBank_Play(
218 			soundBank,
219 			nCueIndex,
220 			dwFlags,
221 			timeOffset,
222 			&cue
223 		);
224 		*ppCue = new XACT3CueImpl(cue);
225 		return retval;
226 	}
Stop(uint16_t nCueIndex,uint32_t dwFlags)227 	COM_METHOD(HRESULT) Stop(uint16_t nCueIndex, uint32_t dwFlags)
228 	{
229 		return FACTSoundBank_Stop(soundBank, nCueIndex, dwFlags);
230 	}
Destroy()231 	COM_METHOD(HRESULT) Destroy()
232 	{
233 		return FACTSoundBank_Destroy(soundBank);
234 	}
GetState(uint32_t * pdwState)235 	COM_METHOD(HRESULT) GetState(uint32_t *pdwState)
236 	{
237 		return FACTSoundBank_GetState(soundBank, pdwState);
238 	}
239 
240 	FACTSoundBank *soundBank;
241 };
242 
243 /* IXACT3WaveBank Implementation */
244 
245 class XACT3WaveBankImpl : public IXACT3WaveBank
246 {
247 public:
XACT3WaveBankImpl(FACTWaveBank * newWaveBank)248 	XACT3WaveBankImpl(FACTWaveBank *newWaveBank)
249 	{
250 		waveBank = newWaveBank;
251 	}
Destroy()252 	COM_METHOD(HRESULT) Destroy()
253 	{
254 		return FACTWaveBank_Destroy(waveBank);
255 	}
GetNumWaves(uint16_t * pnNumWaves)256 	COM_METHOD(HRESULT) GetNumWaves(uint16_t *pnNumWaves)
257 	{
258 		return FACTWaveBank_GetNumWaves(waveBank, pnNumWaves);
259 	}
GetWaveIndex(const char * szFriendlyName)260 	COM_METHOD(uint16_t) GetWaveIndex(const char *szFriendlyName)
261 	{
262 		return FACTWaveBank_GetWaveIndex(waveBank, szFriendlyName);
263 	}
GetWaveProperties(uint16_t nWaveIndex,XACT_WAVE_PROPERTIES * pWaveProperties)264 	COM_METHOD(HRESULT) GetWaveProperties(
265 		uint16_t nWaveIndex,
266 		XACT_WAVE_PROPERTIES *pWaveProperties
267 	) {
268 		return FACTWaveBank_GetWaveProperties(
269 			waveBank,
270 			nWaveIndex,
271 			pWaveProperties
272 		);
273 	}
Prepare(uint16_t nWaveIndex,uint32_t dwFlags,uint32_t dwPlayOffset,uint8_t nLoopCount,IXACT3Wave ** ppWave)274 	COM_METHOD(HRESULT) Prepare(
275 		uint16_t nWaveIndex,
276 		uint32_t dwFlags,
277 		uint32_t dwPlayOffset,
278 		uint8_t nLoopCount,
279 		IXACT3Wave **ppWave
280 	) {
281 		FACTWave *wave;
282 		HRESULT retval = FACTWaveBank_Prepare(
283 			waveBank,
284 			nWaveIndex,
285 			dwFlags,
286 			dwPlayOffset,
287 			nLoopCount,
288 			&wave
289 		);
290 		*ppWave = new XACT3WaveImpl(wave);
291 		return retval;
292 	}
Play(uint16_t nWaveIndex,uint32_t dwFlags,uint32_t dwPlayOffset,uint8_t nLoopCount,IXACT3Wave ** ppWave)293 	COM_METHOD(HRESULT) Play(
294 		uint16_t nWaveIndex,
295 		uint32_t dwFlags,
296 		uint32_t dwPlayOffset,
297 		uint8_t nLoopCount,
298 		IXACT3Wave **ppWave
299 	) {
300 		if (ppWave == NULL)
301 		{
302 			return FACTWaveBank_Play(
303 				waveBank,
304 				nWaveIndex,
305 				dwFlags,
306 				dwPlayOffset,
307 				nLoopCount,
308 				NULL
309 			);
310 		}
311 		FACTWave *wave;
312 		HRESULT retval = FACTWaveBank_Play(
313 			waveBank,
314 			nWaveIndex,
315 			dwFlags,
316 			dwPlayOffset,
317 			nLoopCount,
318 			&wave
319 		);
320 		*ppWave = new XACT3WaveImpl(wave);
321 		return retval;
322 	}
Stop(uint16_t nWaveIndex,uint32_t dwFlags)323 	COM_METHOD(HRESULT) Stop(
324 		uint16_t nWaveIndex,
325 		uint32_t dwFlags
326 	) {
327 		return FACTWaveBank_Stop(waveBank, nWaveIndex, dwFlags);
328 	}
GetState(uint32_t * pdwState)329 	COM_METHOD(HRESULT) GetState(uint32_t *pdwState)
330 	{
331 		return FACTWaveBank_GetState(waveBank, pdwState);
332 	}
333 
334 	FACTWaveBank *waveBank;
335 };
336 
337 /* IXACT3Engine Implementation */
338 
XACT3_INTERNAL_Malloc(size_t size)339 void* CDECL XACT3_INTERNAL_Malloc(size_t size)
340 {
341 	return CoTaskMemAlloc(size);
342 }
XACT3_INTERNAL_Free(void * ptr)343 void CDECL XACT3_INTERNAL_Free(void* ptr)
344 {
345 	CoTaskMemFree(ptr);
346 }
XACT3_INTERNAL_Realloc(void * ptr,size_t size)347 void* CDECL XACT3_INTERNAL_Realloc(void* ptr, size_t size)
348 {
349 	return CoTaskMemRealloc(ptr, size);
350 }
351 
352 class XACT3EngineImpl : public IXACT3Engine
353 {
354 public:
XACT3EngineImpl()355 	XACT3EngineImpl()
356 	{
357 		FACTCreateEngineWithCustomAllocatorEXT(
358 			0,
359 			&engine,
360 			XACT3_INTERNAL_Malloc,
361 			XACT3_INTERNAL_Free,
362 			XACT3_INTERNAL_Realloc
363 		);
364 	}
QueryInterface(REFIID riid,void ** ppvInterface)365 	COM_METHOD(HRESULT) QueryInterface(REFIID riid, void **ppvInterface)
366 	{
367 		if (guid_equals(riid, IID_IXACT3Engine))
368 		{
369 			*ppvInterface = static_cast<IXACT3Engine *>(this);
370 		}
371 		else if (guid_equals(riid, IID_IUnknown))
372 		{
373 			*ppvInterface = static_cast<IUnknown *>(this);
374 		}
375 		else
376 		{
377 			*ppvInterface = NULL;
378 			return E_NOINTERFACE;
379 		}
380 
381 		reinterpret_cast<IUnknown *>(*ppvInterface)->AddRef();
382 
383 		return S_OK;
384 	}
AddRef()385 	COM_METHOD(ULONG) AddRef()
386 	{
387 		return FACTAudioEngine_AddRef(engine);
388 	}
Release()389 	COM_METHOD(ULONG) Release()
390 	{
391 		ULONG refcount = FACTAudioEngine_Release(engine);
392 		if (refcount == 0)
393 		{
394 			delete this;
395 		}
396 		return 1;
397 	}
GetRendererCount(uint16_t * pnRendererCount)398 	COM_METHOD(HRESULT) GetRendererCount(
399 		uint16_t *pnRendererCount
400 	) {
401 		return FACTAudioEngine_GetRendererCount(
402 			engine,
403 			pnRendererCount
404 		);
405 	}
GetRendererDetails(uint16_t nRendererIndex,XACT_RENDERER_DETAILS * pRendererDetails)406 	COM_METHOD(HRESULT) GetRendererDetails(
407 		uint16_t nRendererIndex,
408 		XACT_RENDERER_DETAILS *pRendererDetails
409 	) {
410 		return FACTAudioEngine_GetRendererDetails(
411 			engine,
412 			nRendererIndex,
413 			pRendererDetails
414 		);
415 	}
GetFinalMixFormat(WAVEFORMATEXTENSIBLE * pFinalMixFormat)416 	COM_METHOD(HRESULT) GetFinalMixFormat(
417 		WAVEFORMATEXTENSIBLE *pFinalMixFormat
418 	) {
419 		return FACTAudioEngine_GetFinalMixFormat(
420 			engine,
421 			pFinalMixFormat
422 		);
423 	}
Initialize(const XACT_RUNTIME_PARAMETERS * pParams)424 	COM_METHOD(HRESULT) Initialize(
425 		const XACT_RUNTIME_PARAMETERS *pParams
426 	) {
427 		XACT_RUNTIME_PARAMETERS params;
428 
429 		/* TODO: Unwrap FAudio/FAudioMasteringVoice */
430 		assert(pParams->pXAudio2 == NULL);
431 		assert(pParams->pMasteringVoice == NULL);
432 
433 		/* Copy so we can modify the parameters a bit... */
434 		params = *pParams;
435 		params.pXAudio2 = NULL;
436 		params.pMasteringVoice = NULL;
437 
438 		/* Force Win32 I/O, do NOT use the default! */
439 		if (pParams->fileIOCallbacks.readFileCallback == NULL)
440 		{
441 			params.fileIOCallbacks.readFileCallback = ReadFile;
442 		}
443 		if (pParams->fileIOCallbacks.getOverlappedResultCallback == NULL)
444 		{
445 			params.fileIOCallbacks.getOverlappedResultCallback = GetOverlappedResult;
446 		}
447 
448 		return FACTAudioEngine_Initialize(engine, &params);
449 	}
ShutDown()450 	COM_METHOD(HRESULT) ShutDown()
451 	{
452 		return FACTAudioEngine_ShutDown(engine);
453 	}
DoWork()454 	COM_METHOD(HRESULT) DoWork()
455 	{
456 		return FACTAudioEngine_DoWork(engine);
457 	}
CreateSoundBank(const void * pvBuffer,uint32_t dwSize,uint32_t dwFlags,uint32_t dwAllocAttributes,IXACT3SoundBank ** ppSoundBank)458 	COM_METHOD(HRESULT) CreateSoundBank(
459 		const void *pvBuffer,
460 		uint32_t dwSize,
461 		uint32_t dwFlags,
462 		uint32_t dwAllocAttributes,
463 		IXACT3SoundBank **ppSoundBank
464 	) {
465 		FACTSoundBank *soundBank;
466 		HRESULT retval = FACTAudioEngine_CreateSoundBank(
467 			engine,
468 			pvBuffer,
469 			dwSize,
470 			dwFlags,
471 			dwAllocAttributes,
472 			&soundBank
473 		);
474 		*ppSoundBank = new XACT3SoundBankImpl(soundBank);
475 		return retval;
476 	}
CreateInMemoryWaveBank(const void * pvBuffer,uint32_t dwSize,uint32_t dwFlags,uint32_t dwAllocAttributes,IXACT3WaveBank ** ppWaveBank)477 	COM_METHOD(HRESULT) CreateInMemoryWaveBank(
478 		const void *pvBuffer,
479 		uint32_t dwSize,
480 		uint32_t dwFlags,
481 		uint32_t dwAllocAttributes,
482 		IXACT3WaveBank **ppWaveBank
483 	) {
484 		FACTWaveBank *waveBank;
485 		HRESULT retval = FACTAudioEngine_CreateInMemoryWaveBank(
486 			engine,
487 			pvBuffer,
488 			dwSize,
489 			dwFlags,
490 			dwAllocAttributes,
491 			&waveBank
492 		);
493 		*ppWaveBank = new XACT3WaveBankImpl(waveBank);
494 		return retval;
495 	}
CreateStreamingWaveBank(const XACT_STREAMING_PARAMETERS * pParms,IXACT3WaveBank ** ppWaveBank)496 	COM_METHOD(HRESULT) CreateStreamingWaveBank(
497 		const XACT_STREAMING_PARAMETERS *pParms,
498 		IXACT3WaveBank **ppWaveBank
499 	) {
500 		FACTWaveBank *waveBank;
501 		HRESULT retval = FACTAudioEngine_CreateStreamingWaveBank(
502 			engine,
503 			pParms,
504 			&waveBank
505 		);
506 		*ppWaveBank = new XACT3WaveBankImpl(waveBank);
507 		return retval;
508 	}
PrepareWave(uint32_t dwFlags,const char * szWavePath,uint32_t wStreamingPacketSize,uint32_t dwAlignment,uint32_t dwPlayOffset,uint8_t nLoopCount,IXACT3Wave ** ppWave)509 	COM_METHOD(HRESULT) PrepareWave(
510 		uint32_t dwFlags,
511 		const char *szWavePath,
512 		uint32_t wStreamingPacketSize,
513 		uint32_t dwAlignment,
514 		uint32_t dwPlayOffset,
515 		uint8_t nLoopCount,
516 		IXACT3Wave **ppWave
517 	) {
518 		/* TODO: See FACT.c */
519 		return 0;
520 	}
PrepareInMemoryWave(uint32_t dwFlags,WAVEBANKENTRY entry,uint32_t * pdwSeekTable,uint8_t * pbWaveData,uint32_t dwPlayOffset,uint8_t nLoopCount,IXACT3Wave ** ppWave)521 	COM_METHOD(HRESULT) PrepareInMemoryWave(
522 		uint32_t dwFlags,
523 		WAVEBANKENTRY entry,
524 		uint32_t *pdwSeekTable, /* Optional! */
525 		uint8_t *pbWaveData,
526 		uint32_t dwPlayOffset,
527 		uint8_t nLoopCount,
528 		IXACT3Wave **ppWave
529 	) {
530 		/* TODO: See FACT.c */
531 		return 0;
532 	}
PrepareStreamingWave(uint32_t dwFlags,WAVEBANKENTRY entry,XACT_STREAMING_PARAMETERS streamingParams,uint32_t dwAlignment,uint32_t * pdwSeekTable,uint8_t * pbWaveData,uint32_t dwPlayOffset,uint8_t nLoopCount,IXACT3Wave ** ppWave)533 	COM_METHOD(HRESULT) PrepareStreamingWave(
534 		uint32_t dwFlags,
535 		WAVEBANKENTRY entry,
536 		XACT_STREAMING_PARAMETERS streamingParams,
537 		uint32_t dwAlignment,
538 		uint32_t *pdwSeekTable, /* Optional! */
539 		uint8_t *pbWaveData,
540 		uint32_t dwPlayOffset,
541 		uint8_t nLoopCount,
542 		IXACT3Wave **ppWave
543 	) {
544 		/* TODO: See FACT.c */
545 		return 0;
546 	}
RegisterNotification(const XACT_NOTIFICATION_DESCRIPTION * pNotificationDescription)547 	COM_METHOD(HRESULT) RegisterNotification(
548 		const XACT_NOTIFICATION_DESCRIPTION *pNotificationDescription
549 	) {
550 		/* We have to unwrap the FACT object first! */
551 		FACTNotificationDescription desc;
552 		desc.type = pNotificationDescription->type;
553 		desc.flags = pNotificationDescription->flags;
554 		desc.cueIndex = pNotificationDescription->cueIndex;
555 		desc.waveIndex = pNotificationDescription->waveIndex;
556 		desc.pvContext = pNotificationDescription->pvContext;
557 		if (desc.type == FACTNOTIFICATIONTYPE_CUEDESTROYED)
558 		{
559 			desc.pCue = ((XACT3CueImpl*) pNotificationDescription->pCue)->cue;
560 		}
561 		else if (desc.type == FACTNOTIFICATIONTYPE_SOUNDBANKDESTROYED)
562 		{
563 			if (pNotificationDescription->pSoundBank != NULL)
564 			{
565 				desc.pSoundBank = ((XACT3SoundBankImpl*) pNotificationDescription->pSoundBank)->soundBank;
566 			}
567 			else
568 			{
569 				desc.pSoundBank = NULL;
570 			}
571 		}
572 		else if (desc.type == FACTNOTIFICATIONTYPE_WAVEBANKDESTROYED)
573 		{
574 			desc.pWaveBank = ((XACT3WaveBankImpl*) pNotificationDescription->pWaveBank)->waveBank;
575 		}
576 		else if (desc.type == FACTNOTIFICATIONTYPE_WAVEDESTROYED)
577 		{
578 			desc.pWave = ((XACT3WaveImpl*) pNotificationDescription->pWave)->wave;
579 		}
580 		// If you didn't hit an above if, get ready for an assert!
581 
582 		return FACTAudioEngine_RegisterNotification(engine, &desc);
583 	}
UnRegisterNotification(const XACT_NOTIFICATION_DESCRIPTION * pNotificationDescription)584 	COM_METHOD(HRESULT) UnRegisterNotification(
585 		const XACT_NOTIFICATION_DESCRIPTION *pNotificationDescription
586 	) {
587 		/* We have to unwrap the FACT object first! */
588 		FACTNotificationDescription desc;
589 		desc.type = pNotificationDescription->type;
590 		desc.flags = pNotificationDescription->flags;
591 		desc.cueIndex = pNotificationDescription->cueIndex;
592 		desc.waveIndex = pNotificationDescription->waveIndex;
593 		desc.pvContext = pNotificationDescription->pvContext;
594 		if (desc.type == FACTNOTIFICATIONTYPE_CUEDESTROYED)
595 		{
596 			desc.pCue = ((XACT3CueImpl*) pNotificationDescription->pCue)->cue;
597 		}
598 		else if (desc.type == FACTNOTIFICATIONTYPE_SOUNDBANKDESTROYED)
599 		{
600 			desc.pSoundBank = ((XACT3SoundBankImpl*) pNotificationDescription->pSoundBank)->soundBank;
601 		}
602 		else if (desc.type == FACTNOTIFICATIONTYPE_WAVEBANKDESTROYED)
603 		{
604 			desc.pWaveBank = ((XACT3WaveBankImpl*) pNotificationDescription->pWaveBank)->waveBank;
605 		}
606 		else if (desc.type == FACTNOTIFICATIONTYPE_WAVEDESTROYED)
607 		{
608 			desc.pWave = ((XACT3WaveImpl*) pNotificationDescription->pWave)->wave;
609 		}
610 		// If you didn't hit an above if, get ready for an assert!
611 
612 		return FACTAudioEngine_UnRegisterNotification(engine, &desc);
613 	}
GetCategory(const char * szFriendlyName)614 	COM_METHOD(uint16_t) GetCategory(const char *szFriendlyName)
615 	{
616 		return FACTAudioEngine_GetCategory(engine, szFriendlyName);
617 	}
Stop(uint16_t nCategory,uint32_t dwFlags)618 	COM_METHOD(HRESULT) Stop(uint16_t nCategory, uint32_t dwFlags)
619 	{
620 		return FACTAudioEngine_Stop(engine, nCategory, dwFlags);
621 	}
SetVolume(uint16_t nCategory,float volume)622 	COM_METHOD(HRESULT) SetVolume(uint16_t nCategory, float volume)
623 	{
624 		return FACTAudioEngine_SetVolume(engine, nCategory, volume);
625 	}
Pause(uint16_t nCategory,int32_t fPause)626 	COM_METHOD(HRESULT) Pause(uint16_t nCategory, int32_t fPause)
627 	{
628 		return FACTAudioEngine_Pause(engine, nCategory, fPause);
629 	}
GetGlobalVariableIndex(const char * szFriendlyName)630 	COM_METHOD(uint16_t) GetGlobalVariableIndex(
631 		const char *szFriendlyName
632 	) {
633 		return FACTAudioEngine_GetGlobalVariableIndex(
634 			engine,
635 			szFriendlyName
636 		);
637 	}
SetGlobalVariable(uint16_t nIndex,float nValue)638 	COM_METHOD(HRESULT) SetGlobalVariable(
639 		uint16_t nIndex,
640 		float nValue
641 	) {
642 		return FACTAudioEngine_SetGlobalVariable(
643 			engine,
644 			nIndex,
645 			nValue
646 		);
647 	}
GetGlobalVariable(uint16_t nIndex,float * pnValue)648 	COM_METHOD(HRESULT) GetGlobalVariable(
649 		uint16_t nIndex,
650 		float *pnValue
651 	) {
652 		return FACTAudioEngine_GetGlobalVariable(
653 			engine,
654 			nIndex,
655 			pnValue
656 		);
657 
658 	}
659 private:
660 	FACTAudioEngine *engine;
661 };
662 
663 /* Create Function */
664 
CreateXACT3EngineInternal()665 void *CreateXACT3EngineInternal()
666 {
667 	return new XACT3EngineImpl();
668 }
669