1 /* FAudio - XAudio Reimplementation for FNA
3 * Copyright (c) 2011-2024 Ethan Lee, Luigi Auriemma, and the MonoGame Team
5 * This software is provided 'as-is', without any express or implied warranty.
6 * In no event will the authors be held liable for any damages arising from
7 * the use of this software.
9 * Permission is granted to anyone to use this software for any purpose,
10 * including commercial applications, and to alter it and redistribute it
11 * freely, subject to the following restrictions:
13 * 1. The origin of this software must not be misrepresented; you must not
14 * claim that you wrote the original software. If you use this software in a
15 * product, an acknowledgment in the product documentation would be
16 * appreciated but is not required.
18 * 2. Altered source versions must be plainly marked as such, and must not be
19 * misrepresented as being the original software.
21 * 3. This notice may not be removed or altered from any source distribution.
23 * Ethan "flibitijibibo" Lee <flibitijibibo@flibitijibibo.com>
27 /* This file has no documentation since you are expected to already know how
28 * XACT works if you are still using these APIs!
36 #define FACTAPI FAUDIOAPI
38 #define FACTCALL __stdcall
45 #endif /* __cplusplus */
47 /* Type Declarations */
49 typedef struct FACTAudioEngine FACTAudioEngine
;
50 typedef struct FACTSoundBank FACTSoundBank
;
51 typedef struct FACTWaveBank FACTWaveBank
;
52 typedef struct FACTWave FACTWave
;
53 typedef struct FACTCue FACTCue
;
54 typedef struct FACTNotification FACTNotification
;
56 typedef struct FACTRendererDetails
58 int16_t rendererID
[0xFF]; /* Win32 wchar_t */
59 int16_t displayName
[0xFF]; /* Win32 wchar_t */
60 int32_t defaultDevice
;
61 } FACTRendererDetails
;
63 typedef struct FACTOverlapped
65 void *Internal
; /* ULONG_PTR */
66 void *InternalHigh
; /* ULONG_PTR */
79 typedef int32_t (FACTCALL
* FACTReadFileCallback
)(
82 uint32_t nNumberOfBytesToRead
,
83 uint32_t *lpNumberOfBytesRead
,
84 FACTOverlapped
*lpOverlapped
87 typedef int32_t (FACTCALL
* FACTGetOverlappedResultCallback
)(
89 FACTOverlapped
*lpOverlapped
,
90 uint32_t *lpNumberOfBytesTransferred
,
94 typedef struct FACTFileIOCallbacks
96 FACTReadFileCallback readFileCallback
;
97 FACTGetOverlappedResultCallback getOverlappedResultCallback
;
98 } FACTFileIOCallbacks
;
100 typedef void (FACTCALL
* FACTNotificationCallback
)(
101 const FACTNotification
*pNotification
104 /* FIXME: ABI bug! This should be pack(1) explicitly. Do not memcpy this! */
105 typedef struct FACTRuntimeParameters
107 uint32_t lookAheadTime
;
108 void *pGlobalSettingsBuffer
;
109 uint32_t globalSettingsBufferSize
;
110 uint32_t globalSettingsFlags
;
111 uint32_t globalSettingsAllocAttributes
;
112 FACTFileIOCallbacks fileIOCallbacks
;
113 FACTNotificationCallback fnNotificationCallback
;
114 int16_t *pRendererID
; /* Win32 wchar_t* */
116 FAudioMasteringVoice
*pMasteringVoice
;
117 } FACTRuntimeParameters
;
119 typedef struct FACTStreamingParameters
124 uint16_t packetSize
; /* Measured in DVD sectors, or 2048 bytes */
125 } FACTStreamingParameters
;
127 #define FACT_WAVEBANK_TYPE_BUFFER 0x00000000
128 #define FACT_WAVEBANK_TYPE_STREAMING 0x00000001
129 #define FACT_WAVEBANK_TYPE_MASK 0x00000001
131 #define FACT_WAVEBANK_FLAGS_ENTRYNAMES 0x00010000
132 #define FACT_WAVEBANK_FLAGS_COMPACT 0x00020000
133 #define FACT_WAVEBANK_FLAGS_SYNC_DISABLED 0x00040000
134 #define FACT_WAVEBANK_FLAGS_SEEKTABLES 0x00080000
135 #define FACT_WAVEBANK_FLAGS_MASK 0x000F0000
137 typedef enum FACTWaveBankSegIdx
139 FACT_WAVEBANK_SEGIDX_BANKDATA
= 0,
140 FACT_WAVEBANK_SEGIDX_ENTRYMETADATA
,
141 FACT_WAVEBANK_SEGIDX_SEEKTABLES
,
142 FACT_WAVEBANK_SEGIDX_ENTRYNAMES
,
143 FACT_WAVEBANK_SEGIDX_ENTRYWAVEDATA
,
144 FACT_WAVEBANK_SEGIDX_COUNT
145 } FACTWaveBankSegIdx
;
147 #pragma pack(push, 1)
149 typedef struct FACTWaveBankRegion
153 } FACTWaveBankRegion
;
155 typedef struct FACTWaveBankSampleRegion
157 uint32_t dwStartSample
;
158 uint32_t dwTotalSamples
;
159 } FACTWaveBankSampleRegion
;
161 typedef struct FACTWaveBankHeader
163 uint32_t dwSignature
;
165 uint32_t dwHeaderVersion
;
166 FACTWaveBankRegion Segments
[FACT_WAVEBANK_SEGIDX_COUNT
];
167 } FACTWaveBankHeader
;
169 typedef union FACTWaveBankMiniWaveFormat
171 FAUDIONAMELESS
struct
173 uint32_t wFormatTag
: 2;
174 uint32_t nChannels
: 3;
175 uint32_t nSamplesPerSec
: 18;
176 uint32_t wBlockAlign
: 8;
177 uint32_t wBitsPerSample
: 1;
180 } FACTWaveBankMiniWaveFormat
;
182 typedef struct FACTWaveBankEntry
186 FAUDIONAMELESS
struct
188 uint32_t dwFlags
: 4;
189 uint32_t Duration
: 28;
191 uint32_t dwFlagsAndDuration
;
193 FACTWaveBankMiniWaveFormat Format
;
194 FACTWaveBankRegion PlayRegion
;
195 FACTWaveBankSampleRegion LoopRegion
;
198 typedef struct FACTWaveBankEntryCompact
200 uint32_t dwOffset
: 21;
201 uint32_t dwLengthDeviation
: 11;
202 } FACTWaveBankEntryCompact
;
204 typedef struct FACTWaveBankData
207 uint32_t dwEntryCount
;
209 uint32_t dwEntryMetaDataElementSize
;
210 uint32_t dwEntryNameElementSize
;
211 uint32_t dwAlignment
;
212 FACTWaveBankMiniWaveFormat CompactFormat
;
218 typedef struct FACTWaveProperties
220 char friendlyName
[64];
221 FACTWaveBankMiniWaveFormat format
;
222 uint32_t durationInSamples
;
223 FACTWaveBankSampleRegion loopRegion
;
225 } FACTWaveProperties
;
227 typedef struct FACTWaveInstanceProperties
229 FACTWaveProperties properties
;
230 int32_t backgroundMusic
;
231 } FACTWaveInstanceProperties
;
233 typedef struct FACTCueProperties
235 char friendlyName
[0xFF];
237 uint16_t iaVariableIndex
;
238 uint16_t numVariations
;
239 uint8_t maxInstances
;
240 uint8_t currentInstances
;
243 typedef struct FACTTrackProperties
246 uint16_t numVariations
;
248 uint16_t waveVariation
;
250 } FACTTrackProperties
;
252 typedef struct FACTVariationProperties
259 } FACTVariationProperties
;
261 typedef struct FACTSoundProperties
268 FACTTrackProperties arrTrackProperties
[1];
269 } FACTSoundProperties
;
271 typedef struct FACTSoundVariationProperties
273 FACTVariationProperties variationProperties
;
274 FACTSoundProperties soundProperties
;
275 } FACTSoundVariationProperties
;
277 typedef struct FACTCueInstanceProperties
279 uint32_t allocAttributes
;
280 FACTCueProperties cueProperties
;
281 FACTSoundVariationProperties activeVariationProperties
;
282 } FACTCueInstanceProperties
;
284 #pragma pack(push, 1)
286 typedef struct FACTNotificationDescription
290 FACTSoundBank
*pSoundBank
;
291 FACTWaveBank
*pWaveBank
;
297 } FACTNotificationDescription
;
299 typedef struct FACTNotificationCue
302 FACTSoundBank
*pSoundBank
;
304 } FACTNotificationCue
;
306 typedef struct FACTNotificationMarker
309 FACTSoundBank
*pSoundBank
;
312 } FACTNotificationMarker
;
314 typedef struct FACTNotificationSoundBank
316 FACTSoundBank
*pSoundBank
;
317 } FACTNotificationSoundBank
;
319 typedef struct FACTNotificationWaveBank
321 FACTWaveBank
*pWaveBank
;
322 } FACTNotificationWaveBank
;
324 typedef struct FACTNotificationVariable
327 FACTSoundBank
*pSoundBank
;
329 uint16_t variableIndex
;
332 } FACTNotificationVariable
;
334 typedef struct FACTNotificationGUI
337 } FACTNotificationGUI
;
339 typedef struct FACTNotificationWave
341 FACTWaveBank
*pWaveBank
;
344 FACTSoundBank
*pSoundBank
;
347 } FACTNotificationWave
;
349 struct FACTNotification
356 FACTNotificationCue cue
;
357 FACTNotificationMarker marker
;
358 FACTNotificationSoundBank soundBank
;
359 FACTNotificationWaveBank waveBank
;
360 FACTNotificationVariable variable
;
361 FACTNotificationGUI gui
;
362 FACTNotificationWave wave
;
370 #define FACT_CONTENT_VERSION 46
372 static const uint32_t FACT_FLAG_MANAGEDATA
= 0x00000001;
374 static const uint32_t FACT_FLAG_STOP_RELEASE
= 0x00000000;
375 static const uint32_t FACT_FLAG_STOP_IMMEDIATE
= 0x00000001;
377 static const uint32_t FACT_FLAG_BACKGROUND_MUSIC
= 0x00000002;
378 static const uint32_t FACT_FLAG_UNITS_MS
= 0x00000004;
379 static const uint32_t FACT_FLAG_UNITS_SAMPLES
= 0x00000008;
381 static const uint32_t FACT_STATE_CREATED
= 0x00000001;
382 static const uint32_t FACT_STATE_PREPARING
= 0x00000002;
383 static const uint32_t FACT_STATE_PREPARED
= 0x00000004;
384 static const uint32_t FACT_STATE_PLAYING
= 0x00000008;
385 static const uint32_t FACT_STATE_STOPPING
= 0x00000010;
386 static const uint32_t FACT_STATE_STOPPED
= 0x00000020;
387 static const uint32_t FACT_STATE_PAUSED
= 0x00000040;
388 static const uint32_t FACT_STATE_INUSE
= 0x00000080;
389 static const uint32_t FACT_STATE_PREPAREFAILED
= 0x80000000;
391 static const int16_t FACTPITCH_MIN
= -1200;
392 static const int16_t FACTPITCH_MAX
= 1200;
393 static const int16_t FACTPITCH_MIN_TOTAL
= -2400;
394 static const int16_t FACTPITCH_MAX_TOTAL
= 2400;
396 static const float FACTVOLUME_MIN
= 0.0f
;
397 static const float FACTVOLUME_MAX
= 16777216.0f
;
399 static const uint16_t FACTINDEX_INVALID
= 0xFFFF;
400 static const uint16_t FACTVARIABLEINDEX_INVALID
= 0xFFFF;
401 static const uint16_t FACTCATEGORY_INVALID
= 0xFFFF;
403 static const uint8_t FACTNOTIFICATIONTYPE_CUEPREPARED
= 1;
404 static const uint8_t FACTNOTIFICATIONTYPE_CUEPLAY
= 2;
405 static const uint8_t FACTNOTIFICATIONTYPE_CUESTOP
= 3;
406 static const uint8_t FACTNOTIFICATIONTYPE_CUEDESTROYED
= 4;
407 static const uint8_t FACTNOTIFICATIONTYPE_MARKER
= 5;
408 static const uint8_t FACTNOTIFICATIONTYPE_SOUNDBANKDESTROYED
= 6;
409 static const uint8_t FACTNOTIFICATIONTYPE_WAVEBANKDESTROYED
= 7;
410 static const uint8_t FACTNOTIFICATIONTYPE_LOCALVARIABLECHANGED
= 8;
411 static const uint8_t FACTNOTIFICATIONTYPE_GLOBALVARIABLECHANGED
= 9;
412 static const uint8_t FACTNOTIFICATIONTYPE_GUICONNECTED
= 10;
413 static const uint8_t FACTNOTIFICATIONTYPE_GUIDISCONNECTED
= 11;
414 static const uint8_t FACTNOTIFICATIONTYPE_WAVEPREPARED
= 12;
415 static const uint8_t FACTNOTIFICATIONTYPE_WAVEPLAY
= 13;
416 static const uint8_t FACTNOTIFICATIONTYPE_WAVESTOP
= 14;
417 static const uint8_t FACTNOTIFICATIONTYPE_WAVELOOPED
= 15;
418 static const uint8_t FACTNOTIFICATIONTYPE_WAVEDESTROYED
= 16;
419 static const uint8_t FACTNOTIFICATIONTYPE_WAVEBANKPREPARED
= 17;
420 static const uint8_t FACTNOTIFICATIONTYPE_WAVEBANKSTREAMING_INVALIDCONTENT
= 18;
422 static const uint8_t FACT_FLAG_NOTIFICATION_PERSIST
= 0x01;
424 #define FACT_ENGINE_LOOKAHEAD_DEFAULT 250
426 #define FACT_MAX_WMA_AVG_BYTES_PER_SEC_ENTRIES 7
427 static const uint32_t aWMAAvgBytesPerSec
[] =
438 #define FACT_MAX_WMA_BLOCK_ALIGN_ENTRIES 17
439 static const uint32_t aWMABlockAlign
[] =
460 /* AudioEngine Interface */
462 FACTAPI
uint32_t FACTCreateEngine(
463 uint32_t dwCreationFlags
,
464 FACTAudioEngine
**ppEngine
467 /* See "extensions/CustomAllocatorEXT.txt" for more details. */
468 FACTAPI
uint32_t FACTCreateEngineWithCustomAllocatorEXT(
469 uint32_t dwCreationFlags
,
470 FACTAudioEngine
**ppEngine
,
471 FAudioMallocFunc customMalloc
,
472 FAudioFreeFunc customFree
,
473 FAudioReallocFunc customRealloc
476 FACTAPI
uint32_t FACTAudioEngine_AddRef(FACTAudioEngine
*pEngine
);
478 FACTAPI
uint32_t FACTAudioEngine_Release(FACTAudioEngine
*pEngine
);
480 /* FIXME: QueryInterface? Or just ignore COM garbage... -flibit */
482 FACTAPI
uint32_t FACTAudioEngine_GetRendererCount(
483 FACTAudioEngine
*pEngine
,
484 uint16_t *pnRendererCount
487 FACTAPI
uint32_t FACTAudioEngine_GetRendererDetails(
488 FACTAudioEngine
*pEngine
,
489 uint16_t nRendererIndex
,
490 FACTRendererDetails
*pRendererDetails
493 FACTAPI
uint32_t FACTAudioEngine_GetFinalMixFormat(
494 FACTAudioEngine
*pEngine
,
495 FAudioWaveFormatExtensible
*pFinalMixFormat
498 FACTAPI
uint32_t FACTAudioEngine_Initialize(
499 FACTAudioEngine
*pEngine
,
500 const FACTRuntimeParameters
*pParams
503 FACTAPI
uint32_t FACTAudioEngine_ShutDown(FACTAudioEngine
*pEngine
);
505 FACTAPI
uint32_t FACTAudioEngine_DoWork(FACTAudioEngine
*pEngine
);
507 FACTAPI
uint32_t FACTAudioEngine_CreateSoundBank(
508 FACTAudioEngine
*pEngine
,
509 const void *pvBuffer
,
512 uint32_t dwAllocAttributes
,
513 FACTSoundBank
**ppSoundBank
516 FACTAPI
uint32_t FACTAudioEngine_CreateInMemoryWaveBank(
517 FACTAudioEngine
*pEngine
,
518 const void *pvBuffer
,
521 uint32_t dwAllocAttributes
,
522 FACTWaveBank
**ppWaveBank
525 FACTAPI
uint32_t FACTAudioEngine_CreateStreamingWaveBank(
526 FACTAudioEngine
*pEngine
,
527 const FACTStreamingParameters
*pParms
,
528 FACTWaveBank
**ppWaveBank
531 FACTAPI
uint32_t FACTAudioEngine_PrepareWave(
532 FACTAudioEngine
*pEngine
,
534 const char *szWavePath
,
535 uint32_t wStreamingPacketSize
,
536 uint32_t dwAlignment
,
537 uint32_t dwPlayOffset
,
542 FACTAPI
uint32_t FACTAudioEngine_PrepareInMemoryWave(
543 FACTAudioEngine
*pEngine
,
545 FACTWaveBankEntry entry
,
546 uint32_t *pdwSeekTable
, /* Optional! */
548 uint32_t dwPlayOffset
,
553 FACTAPI
uint32_t FACTAudioEngine_PrepareStreamingWave(
554 FACTAudioEngine
*pEngine
,
556 FACTWaveBankEntry entry
,
557 FACTStreamingParameters streamingParams
,
558 uint32_t dwAlignment
,
559 uint32_t *pdwSeekTable
, /* Optional! */
560 uint8_t *pbWaveData
, /* ABI bug, do not use! */
561 uint32_t dwPlayOffset
,
566 FACTAPI
uint32_t FACTAudioEngine_RegisterNotification(
567 FACTAudioEngine
*pEngine
,
568 const FACTNotificationDescription
*pNotificationDescription
571 FACTAPI
uint32_t FACTAudioEngine_UnRegisterNotification(
572 FACTAudioEngine
*pEngine
,
573 const FACTNotificationDescription
*pNotificationDescription
576 FACTAPI
uint16_t FACTAudioEngine_GetCategory(
577 FACTAudioEngine
*pEngine
,
578 const char *szFriendlyName
581 FACTAPI
uint32_t FACTAudioEngine_Stop(
582 FACTAudioEngine
*pEngine
,
587 FACTAPI
uint32_t FACTAudioEngine_SetVolume(
588 FACTAudioEngine
*pEngine
,
593 FACTAPI
uint32_t FACTAudioEngine_Pause(
594 FACTAudioEngine
*pEngine
,
599 FACTAPI
uint16_t FACTAudioEngine_GetGlobalVariableIndex(
600 FACTAudioEngine
*pEngine
,
601 const char *szFriendlyName
604 FACTAPI
uint32_t FACTAudioEngine_SetGlobalVariable(
605 FACTAudioEngine
*pEngine
,
610 FACTAPI
uint32_t FACTAudioEngine_GetGlobalVariable(
611 FACTAudioEngine
*pEngine
,
616 /* SoundBank Interface */
618 FACTAPI
uint16_t FACTSoundBank_GetCueIndex(
619 FACTSoundBank
*pSoundBank
,
620 const char *szFriendlyName
623 FACTAPI
uint32_t FACTSoundBank_GetNumCues(
624 FACTSoundBank
*pSoundBank
,
628 FACTAPI
uint32_t FACTSoundBank_GetCueProperties(
629 FACTSoundBank
*pSoundBank
,
631 FACTCueProperties
*pProperties
634 FACTAPI
uint32_t FACTSoundBank_Prepare(
635 FACTSoundBank
*pSoundBank
,
642 FACTAPI
uint32_t FACTSoundBank_Play(
643 FACTSoundBank
*pSoundBank
,
647 FACTCue
** ppCue
/* Optional! */
650 #ifndef F3DAUDIO_DSP_SETTINGS_DECL
651 #define F3DAUDIO_DSP_SETTINGS_DECL
652 typedef struct F3DAUDIO_DSP_SETTINGS F3DAUDIO_DSP_SETTINGS
;
653 #endif /* F3DAUDIO_DSP_SETTINGS_DECL */
655 FACTAPI
uint32_t FACTSoundBank_Play3D(
656 FACTSoundBank
*pSoundBank
,
660 F3DAUDIO_DSP_SETTINGS
*pDSPSettings
,
661 FACTCue
** ppCue
/* Optional! */
664 FACTAPI
uint32_t FACTSoundBank_Stop(
665 FACTSoundBank
*pSoundBank
,
670 FACTAPI
uint32_t FACTSoundBank_Destroy(FACTSoundBank
*pSoundBank
);
672 FACTAPI
uint32_t FACTSoundBank_GetState(
673 FACTSoundBank
*pSoundBank
,
677 /* WaveBank Interface */
679 FACTAPI
uint32_t FACTWaveBank_Destroy(FACTWaveBank
*pWaveBank
);
681 FACTAPI
uint32_t FACTWaveBank_GetState(
682 FACTWaveBank
*pWaveBank
,
686 FACTAPI
uint32_t FACTWaveBank_GetNumWaves(
687 FACTWaveBank
*pWaveBank
,
691 FACTAPI
uint16_t FACTWaveBank_GetWaveIndex(
692 FACTWaveBank
*pWaveBank
,
693 const char *szFriendlyName
696 FACTAPI
uint32_t FACTWaveBank_GetWaveProperties(
697 FACTWaveBank
*pWaveBank
,
699 FACTWaveProperties
*pWaveProperties
702 FACTAPI
uint32_t FACTWaveBank_Prepare(
703 FACTWaveBank
*pWaveBank
,
706 uint32_t dwPlayOffset
,
711 FACTAPI
uint32_t FACTWaveBank_Play(
712 FACTWaveBank
*pWaveBank
,
715 uint32_t dwPlayOffset
,
720 FACTAPI
uint32_t FACTWaveBank_Stop(
721 FACTWaveBank
*pWaveBank
,
728 FACTAPI
uint32_t FACTWave_Destroy(FACTWave
*pWave
);
730 FACTAPI
uint32_t FACTWave_Play(FACTWave
*pWave
);
732 FACTAPI
uint32_t FACTWave_Stop(FACTWave
*pWave
, uint32_t dwFlags
);
734 FACTAPI
uint32_t FACTWave_Pause(FACTWave
*pWave
, int32_t fPause
);
736 FACTAPI
uint32_t FACTWave_GetState(FACTWave
*pWave
, uint32_t *pdwState
);
738 FACTAPI
uint32_t FACTWave_SetPitch(FACTWave
*pWave
, int16_t pitch
);
740 FACTAPI
uint32_t FACTWave_SetVolume(FACTWave
*pWave
, float volume
);
742 FACTAPI
uint32_t FACTWave_SetMatrixCoefficients(
744 uint32_t uSrcChannelCount
,
745 uint32_t uDstChannelCount
,
746 float *pMatrixCoefficients
749 FACTAPI
uint32_t FACTWave_GetProperties(
751 FACTWaveInstanceProperties
*pProperties
756 FACTAPI
uint32_t FACTCue_Destroy(FACTCue
*pCue
);
758 FACTAPI
uint32_t FACTCue_Play(FACTCue
*pCue
);
760 FACTAPI
uint32_t FACTCue_Stop(FACTCue
*pCue
, uint32_t dwFlags
);
762 FACTAPI
uint32_t FACTCue_GetState(FACTCue
*pCue
, uint32_t *pdwState
);
764 FACTAPI
uint32_t FACTCue_SetMatrixCoefficients(
766 uint32_t uSrcChannelCount
,
767 uint32_t uDstChannelCount
,
768 float *pMatrixCoefficients
771 FACTAPI
uint16_t FACTCue_GetVariableIndex(
773 const char *szFriendlyName
776 FACTAPI
uint32_t FACTCue_SetVariable(
782 FACTAPI
uint32_t FACTCue_GetVariable(
788 FACTAPI
uint32_t FACTCue_Pause(FACTCue
*pCue
, int32_t fPause
);
790 FACTAPI
uint32_t FACTCue_GetProperties(
792 FACTCueInstanceProperties
**ppProperties
795 FACTAPI
uint32_t FACTCue_SetOutputVoices(
797 const FAudioVoiceSends
*pSendList
/* Optional! */
800 FACTAPI
uint32_t FACTCue_SetOutputVoiceMatrix(
802 const FAudioVoice
*pDestinationVoice
, /* Optional! */
803 uint32_t SourceChannels
,
804 uint32_t DestinationChannels
,
805 const float *pLevelMatrix
/* SourceChannels * DestinationChannels */
810 #endif /* __cplusplus */
814 /* vim: set noexpandtab shiftwidth=8 tabstop=8: */