Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
wine-mirror
GitHub Repository: wine-mirror/wine
Path: blob/master/libs/faudio/src/FACT_internal.h
8530 views
1
/* FAudio - XAudio Reimplementation for FNA
2
*
3
* Copyright (c) 2011-2024 Ethan Lee, Luigi Auriemma, and the MonoGame Team
4
*
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.
8
*
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:
12
*
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.
17
*
18
* 2. Altered source versions must be plainly marked as such, and must not be
19
* misrepresented as being the original software.
20
*
21
* 3. This notice may not be removed or altered from any source distribution.
22
*
23
* Ethan "flibitijibibo" Lee <[email protected]>
24
*
25
*/
26
27
#include "FACT.h"
28
#include "FACT3D.h"
29
#include "FAudio_internal.h"
30
31
/* Internal AudioEngine Types */
32
33
#define ACCESSIBILITY_PUBLIC 0x1
34
#define ACCESSIBILITY_READONLY 0x2
35
#define ACCESSIBILITY_CUE 0x4
36
#define ACCESSIBILITY_RESERVED 0x8
37
38
enum max_instance_behavior
39
{
40
MAX_INSTANCE_BEHAVIOR_FAIL = 0,
41
MAX_INSTANCE_BEHAVIOR_QUEUE = 1,
42
MAX_INSTANCE_BEHAVIOR_REPLACE_OLDEST = 2,
43
MAX_INSTANCE_BEHAVIOR_REPLACE_QUIETEST = 3,
44
MAX_INSTANCE_BEHAVIOR_REPLACE_LOWEST_PRIORITY = 4,
45
};
46
47
typedef struct FACTAudioCategory
48
{
49
uint8_t instanceLimit;
50
uint16_t fadeInMS;
51
uint16_t fadeOutMS;
52
enum max_instance_behavior maxInstanceBehavior;
53
int16_t parentCategory;
54
float volume;
55
uint8_t visibility;
56
57
uint8_t instanceCount;
58
float currentVolume;
59
} FACTAudioCategory;
60
61
typedef struct FACTVariable
62
{
63
uint8_t accessibility;
64
float initialValue;
65
float minValue;
66
float maxValue;
67
} FACTVariable;
68
69
enum rpc_point_type
70
{
71
RPC_POINT_TYPE_LINEAR = 0,
72
RPC_POINT_TYPE_FAST = 1,
73
RPC_POINT_TYPE_SLOW = 2,
74
RPC_POINT_TYPE_SINCOS = 3,
75
};
76
77
typedef struct FACTRPCPoint
78
{
79
float x;
80
float y;
81
enum rpc_point_type type;
82
} FACTRPCPoint;
83
84
typedef enum FACTRPCParameter
85
{
86
RPC_PARAMETER_VOLUME,
87
RPC_PARAMETER_PITCH,
88
RPC_PARAMETER_REVERBSEND,
89
RPC_PARAMETER_FILTERFREQUENCY,
90
RPC_PARAMETER_FILTERQFACTOR,
91
RPC_PARAMETER_COUNT /* If >=, DSP Parameter! */
92
} FACTRPCParameter;
93
94
typedef struct FACTRPC
95
{
96
uint16_t variable;
97
uint8_t pointCount;
98
uint16_t parameter;
99
FACTRPCPoint *points;
100
} FACTRPC;
101
102
typedef struct FACTDSPParameter
103
{
104
uint8_t type;
105
float value;
106
float minVal;
107
float maxVal;
108
uint16_t unknown;
109
} FACTDSPParameter;
110
111
typedef struct FACTDSPPreset
112
{
113
uint8_t accessibility;
114
uint16_t parameterCount;
115
FACTDSPParameter *parameters;
116
} FACTDSPPreset;
117
118
/* Internal SoundBank Types */
119
120
typedef enum
121
{
122
FACTEVENT_STOP = 0,
123
FACTEVENT_PLAYWAVE = 1,
124
FACTEVENT_PLAYWAVETRACKVARIATION = 3,
125
FACTEVENT_PLAYWAVEEFFECTVARIATION = 4,
126
FACTEVENT_PLAYWAVETRACKEFFECTVARIATION = 6,
127
FACTEVENT_PITCH = 7,
128
FACTEVENT_VOLUME = 8,
129
FACTEVENT_MARKER = 9,
130
FACTEVENT_PITCHREPEATING = 16,
131
FACTEVENT_VOLUMEREPEATING = 17,
132
FACTEVENT_MARKERREPEATING = 18
133
} FACTEventType;
134
135
enum variation_type
136
{
137
VARIATION_TYPE_ORDERED = 0,
138
VARIATION_TYPE_ORDERED_FROM_RANDOM = 1,
139
VARIATION_TYPE_RANDOM = 2,
140
VARIATION_TYPE_RANDOM_NO_REPEATS = 3,
141
VARIATION_TYPE_SHUFFLE = 4,
142
};
143
144
#define VARIATION_TYPE_MASK 0x7
145
146
#define EVENT_WAVE_HAS_VARIATION 0x0040
147
148
#define EVENT_STOP_IMMEDIATE 0x01
149
#define EVENT_STOP_CUE 0x02
150
151
#define EVENT_SETTINGS_RAMP 0x01
152
153
#define EVENT_EQUATION_ADD 0x01
154
#define EVENT_EQUATION_VALUE 0x04
155
#define EVENT_EQUATION_RANDOM 0x08
156
157
typedef struct FACTEvent
158
{
159
uint16_t type;
160
uint16_t timestamp;
161
uint16_t randomOffset;
162
FAUDIONAMELESS union
163
{
164
/* Play Wave Event */
165
struct
166
{
167
uint8_t flags;
168
uint8_t loopCount;
169
uint16_t position;
170
uint16_t angle;
171
172
bool isComplex;
173
FAUDIONAMELESS union
174
{
175
struct
176
{
177
uint16_t wave_index;
178
uint8_t wavebank;
179
} simple;
180
struct
181
{
182
enum variation_type variation_type;
183
bool has_variation;
184
uint16_t wave_count;
185
uint16_t *wave_indices;
186
uint8_t *wavebanks;
187
uint8_t *weights;
188
} complex;
189
};
190
191
/* Effect Variation */
192
int16_t minPitch;
193
int16_t maxPitch;
194
float minVolume;
195
float maxVolume;
196
float minFrequency;
197
float maxFrequency;
198
float minQFactor;
199
float maxQFactor;
200
uint16_t variationFlags;
201
} wave;
202
/* Set Pitch/Volume Event */
203
struct
204
{
205
uint8_t settings;
206
uint16_t repeats;
207
uint16_t frequency;
208
FAUDIONAMELESS union
209
{
210
struct
211
{
212
float initialValue;
213
float initialSlope;
214
float slopeDelta;
215
uint16_t duration;
216
} ramp;
217
struct
218
{
219
uint8_t flags;
220
float value1;
221
float value2;
222
} equation;
223
};
224
} value;
225
/* Stop Event */
226
struct
227
{
228
uint8_t flags;
229
} stop;
230
/* Marker Event */
231
struct
232
{
233
uint32_t marker;
234
uint16_t repeats;
235
uint16_t frequency;
236
} marker;
237
};
238
} FACTEvent;
239
240
struct rpc_codes
241
{
242
const uint32_t *codes;
243
uint8_t count;
244
};
245
246
typedef struct FACTTrack
247
{
248
uint32_t code;
249
250
float volume;
251
uint8_t filter;
252
uint8_t qfactor;
253
uint16_t frequency;
254
255
struct rpc_codes rpc_codes;
256
257
uint8_t eventCount;
258
const FACTEvent *events;
259
} FACTTrack;
260
261
#define SOUND_FLAG_COMPLEX 0x01
262
#define SOUND_FLAG_HAS_RPC 0x02
263
#define SOUND_FLAG_HAS_TRACK_RPC 0x04
264
#define SOUND_FLAG_RPC_MASK 0x0e
265
#define SOUND_FLAG_HAS_DSP 0x10
266
267
typedef struct FACTSound
268
{
269
uint8_t flags;
270
uint16_t category;
271
float volume;
272
int16_t pitch;
273
uint8_t priority;
274
275
struct rpc_codes rpc_codes;
276
277
uint8_t trackCount;
278
uint8_t dspCodeCount;
279
280
const FACTTrack *tracks;
281
uint32_t *dspCodes;
282
} FACTSound;
283
284
#define CUE_FLAG_SINGLE_SOUND 0x04
285
286
typedef struct FACTCueData
287
{
288
uint8_t flags;
289
uint32_t sbCode;
290
uint32_t transitionOffset;
291
uint8_t instanceLimit;
292
uint16_t fadeInMS;
293
uint16_t fadeOutMS;
294
enum max_instance_behavior maxInstanceBehavior;
295
uint8_t instanceCount;
296
} FACTCueData;
297
298
typedef struct FACTVariation
299
{
300
FAUDIONAMELESS union
301
{
302
struct
303
{
304
uint16_t track;
305
uint8_t wavebank;
306
} simple;
307
uint32_t soundCode;
308
};
309
union
310
{
311
struct
312
{
313
uint8_t weight_min, weight_max;
314
} noninteractive;
315
struct
316
{
317
float var_min, var_max;
318
} interactive;
319
};
320
uint32_t linger;
321
} FACTVariation;
322
323
enum variation_table_type
324
{
325
VARIATION_TABLE_TYPE_WAVE = 0,
326
VARIATION_TABLE_TYPE_SOUND = 1,
327
VARIATION_TABLE_TYPE_CLIP = 2,
328
VARIATION_TABLE_TYPE_INTERACTIVE = 3,
329
VARIATION_TABLE_TYPE_COMPACT_WAVE = 4,
330
};
331
332
#define VARIATION_TABLE_TYPE_MASK 0x7
333
334
#define VARIATION_FLAG_VOLUME_ADD 0x0001
335
#define VARIATION_FLAG_PITCH_ADD 0x0004
336
#define VARIATION_FLAG_FREQUENCY_ADD 0x0010
337
#define VARIATION_FLAG_Q_ADD 0x0040
338
#define VARIATION_FLAG_PITCH_NEW_ON_LOOP 0x0100
339
#define VARIATION_FLAG_VOLUME_NEW_ON_LOOP 0x0200
340
#define VARIATION_FLAG_FREQUENCY_Q_NEW_ON_LOOP 0x0c00
341
#define VARIATION_FLAG_PITCH 0x1000
342
#define VARIATION_FLAG_VOLUME 0x2000
343
#define VARIATION_FLAG_FREQUENCY_Q 0xc000
344
345
#define VARIATION_FLAG_LOOP_MASK (VARIATION_FLAG_PITCH_NEW_ON_LOOP \
346
| VARIATION_FLAG_VOLUME_NEW_ON_LOOP | VARIATION_FLAG_FREQUENCY_Q_NEW_ON_LOOP)
347
348
typedef struct FACTVariationTable
349
{
350
uint32_t code;
351
enum variation_table_type type;
352
int16_t variable;
353
bool isComplex;
354
355
uint16_t entryCount;
356
FACTVariation *entries;
357
} FACTVariationTable;
358
359
typedef struct FACTTransition
360
{
361
int32_t soundCode;
362
uint32_t srcMarkerMin;
363
uint32_t srcMarkerMax;
364
uint32_t dstMarkerMin;
365
uint32_t dstMarkerMax;
366
uint16_t fadeIn;
367
uint16_t fadeOut;
368
uint16_t flags;
369
} FACTTransition;
370
371
typedef struct FACTTransitionTable
372
{
373
uint32_t entryCount;
374
FACTTransition *entries;
375
} FACTTransitionTable;
376
377
/* Internal WaveBank Types */
378
379
typedef struct FACTSeekTable
380
{
381
uint32_t entryCount;
382
uint32_t *entries;
383
} FACTSeekTable;
384
385
/* Internal Cue Types */
386
387
typedef struct FACTInstanceRPCData
388
{
389
float rpcVolume;
390
float rpcPitch;
391
float rpcReverbSend;
392
float rpcFilterFreq;
393
float rpcFilterQFactor;
394
} FACTInstanceRPCData;
395
396
typedef struct FACTEventInstance
397
{
398
uint32_t timestamp;
399
uint16_t loopCount;
400
bool finished;
401
FAUDIONAMELESS union
402
{
403
float value;
404
uint32_t valuei;
405
};
406
} FACTEventInstance;
407
408
typedef struct FACTTrackInstance
409
{
410
/* Tracks which events have fired */
411
FACTEventInstance *events;
412
413
/* RPC instance data */
414
FACTInstanceRPCData rpcData;
415
416
/* SetPitch/SetVolume data */
417
float evtPitch;
418
float evtVolume;
419
420
/* Wave playback */
421
struct
422
{
423
FACTWave *wave;
424
float baseVolume;
425
int16_t basePitch;
426
float baseQFactor;
427
float baseFrequency;
428
} activeWave, upcomingWave;
429
const FACTEvent *waveEvt;
430
FACTEventInstance *waveEvtInst;
431
} FACTTrackInstance;
432
433
typedef struct FACTSoundInstance
434
{
435
/* Base Sound reference */
436
const FACTSound *sound;
437
438
/* Per-instance track information */
439
FACTTrackInstance *tracks;
440
441
/* RPC instance data */
442
FACTInstanceRPCData rpcData;
443
444
/* Fade data */
445
uint32_t fadeStart;
446
uint16_t fadeTarget;
447
enum
448
{
449
SOUND_STATE_STOPPED,
450
SOUND_STATE_FADE_IN,
451
SOUND_STATE_PLAYING,
452
SOUND_STATE_FADE_OUT,
453
SOUND_STATE_RELEASE_RPC,
454
} state;
455
456
/* index in the parent cue's variation table */
457
uint16_t variation_index;
458
459
/* Engine references */
460
FACTCue *parentCue;
461
} FACTSoundInstance;
462
463
/* Internal Wave Types */
464
465
typedef struct FACTWaveCallback
466
{
467
FAudioVoiceCallback callback;
468
FACTWave *wave;
469
} FACTWaveCallback;
470
471
/* Public XACT Types */
472
473
struct FACTAudioEngine
474
{
475
uint32_t refcount;
476
FACTNotificationCallback notificationCallback;
477
FACTReadFileCallback pReadFile;
478
FACTGetOverlappedResultCallback pGetOverlappedResult;
479
480
uint16_t categoryCount;
481
uint16_t variableCount;
482
uint16_t rpcCount;
483
uint16_t dspPresetCount;
484
uint16_t dspParameterCount;
485
486
char **categoryNames;
487
char **variableNames;
488
uint32_t *rpcCodes;
489
uint32_t *dspPresetCodes;
490
491
FACTAudioCategory *categories;
492
FACTVariable *variables;
493
FACTRPC *rpcs;
494
FACTDSPPreset *dspPresets;
495
496
/* Engine references */
497
LinkedList *sbList;
498
LinkedList *wbList;
499
FAudioMutex sbLock;
500
FAudioMutex wbLock;
501
float *globalVariableValues;
502
503
/* FAudio references */
504
FAudio *audio;
505
FAudioMasteringVoice *master;
506
FAudioSubmixVoice *reverbVoice;
507
FAudioWaveFormatExtensible output_format;
508
509
/* Engine thread */
510
FAudioThread apiThread;
511
FAudioMutex apiLock;
512
bool initialized;
513
514
/* Allocator callbacks */
515
FAudioMallocFunc pMalloc;
516
FAudioFreeFunc pFree;
517
FAudioReallocFunc pRealloc;
518
519
FACTNotificationDescription *notifications;
520
size_t notification_count, notifications_capacity;
521
522
/* Wave banks to send PREPARED notifications for.
523
* These are queued and processed in DoWork(). */
524
FACTWaveBank **prepared_wavebanks;
525
size_t prepared_wavebank_count, prepared_wavebanks_capacity;
526
527
/* Settings handle */
528
void *settings;
529
};
530
531
struct FACTSoundBank
532
{
533
/* Engine references */
534
FACTAudioEngine *parentEngine;
535
FACTCue *cueList;
536
537
/* Array sizes */
538
uint16_t cueCount;
539
uint8_t wavebankCount;
540
uint16_t soundCount;
541
uint16_t variationCount;
542
uint16_t transitionCount;
543
544
/* Strings, strings everywhere! */
545
char **wavebankNames;
546
char **cueNames;
547
548
/* Actual SoundBank information */
549
char *name;
550
FACTCueData *cues;
551
const FACTSound *sounds;
552
uint32_t *soundCodes;
553
FACTVariationTable *variations;
554
FACTTransitionTable *transitions;
555
uint32_t *transitionCodes;
556
};
557
558
struct FACTWaveBank
559
{
560
/* Engine references */
561
FACTAudioEngine *parentEngine;
562
LinkedList *waveList;
563
FAudioMutex waveLock;
564
565
/* Actual WaveBank information */
566
char *name;
567
uint32_t entryCount;
568
FACTWaveBankEntry *entries;
569
uint32_t *entryRefs;
570
FACTSeekTable *seekTables;
571
char *waveBankNames;
572
573
/* I/O information */
574
uint32_t packetSize;
575
bool streaming;
576
uint8_t *packetBuffer;
577
uint32_t packetBufferLen;
578
void* io;
579
};
580
581
struct FACTWave
582
{
583
/* Engine references */
584
FACTWaveBank *parentBank;
585
FACTCue *parentCue;
586
uint16_t index;
587
588
/* Only used for GetProperties(). */
589
bool background_music;
590
591
/* Playback */
592
uint32_t state;
593
float volume;
594
int16_t pitch;
595
uint8_t loopCount;
596
597
/* Stream data */
598
uint32_t streamSize;
599
uint32_t streamOffset;
600
uint8_t *streamCache;
601
602
/* FAudio references */
603
uint16_t srcChannels;
604
FAudioSourceVoice *voice;
605
FACTWaveCallback callback;
606
};
607
608
struct FACTCue
609
{
610
/* Engine references */
611
FACTSoundBank *parentBank;
612
FACTCue *next;
613
bool managed;
614
uint16_t index;
615
616
/* Sound data */
617
FACTCueData *data;
618
FAUDIONAMELESS union
619
{
620
FACTVariationTable *variation;
621
622
/* This is only used in scenarios where there is only one
623
* Sound; XACT does not generate variation tables for
624
* Cues with only one Sound.
625
*/
626
const FACTSound *sound;
627
};
628
629
/* Instance data */
630
float *variableValues;
631
float interactive;
632
633
/* Playback */
634
uint32_t state;
635
FACTWave *simpleWave;
636
FACTSoundInstance *playingSound;
637
uint32_t maxRpcReleaseTime;
638
639
/* 3D Data */
640
bool active3D;
641
uint32_t srcChannels;
642
uint32_t dstChannels;
643
float matrixCoefficients[2 * 8]; /* Stereo input, 7.1 output */
644
645
/* Timer */
646
uint32_t start;
647
uint32_t elapsed;
648
};
649
650
/* Internal functions */
651
652
void FACT_INTERNAL_GetNextWave(FACTCue *cue, const FACTSound *sound, const FACTTrack *track,
653
FACTTrackInstance *trackInst, const FACTEvent *evt, FACTEventInstance *evtInst);
654
void create_sound(FACTCue *cue);
655
bool play_sound(FACTCue *cue);
656
void FACT_INTERNAL_DestroySound(FACTSoundInstance *sound);
657
void FACT_INTERNAL_BeginFadeOut(FACTSoundInstance *sound, uint16_t fadeOutMS);
658
void FACT_INTERNAL_BeginReleaseRPC(FACTSoundInstance *sound, uint16_t releaseMS);
659
660
void FACT_INTERNAL_SendCueNotification(FACTCue *cue, uint8_t type);
661
662
/* FACT Thread */
663
664
int32_t FAUDIOCALL FACT_INTERNAL_APIThread(void* enginePtr);
665
666
/* FAudio callbacks */
667
668
void FACT_INTERNAL_OnBufferEnd(FAudioVoiceCallback *callback, void* pContext);
669
void FACT_INTERNAL_OnStreamEnd(FAudioVoiceCallback *callback);
670
671
/* FAudioIOStream functions */
672
673
int32_t FACTCALL FACT_INTERNAL_DefaultReadFile(
674
void *hFile,
675
void *buffer,
676
uint32_t nNumberOfBytesToRead,
677
uint32_t *lpNumberOfBytesRead,
678
FACTOverlapped *lpOverlapped
679
);
680
681
int32_t FACTCALL FACT_INTERNAL_DefaultGetOverlappedResult(
682
void *hFile,
683
FACTOverlapped *lpOverlapped,
684
uint32_t *lpNumberOfBytesTransferred,
685
int32_t bWait
686
);
687
688
/* Parsing functions */
689
690
uint32_t FACT_INTERNAL_ParseAudioEngine(
691
FACTAudioEngine *pEngine,
692
const FACTRuntimeParameters *pParams
693
);
694
uint32_t FACT_INTERNAL_ParseSoundBank(
695
FACTAudioEngine *pEngine,
696
const void *pvBuffer,
697
uint32_t dwSize,
698
FACTSoundBank **ppSoundBank
699
);
700
uint32_t FACT_INTERNAL_ParseWaveBank(
701
FACTAudioEngine *pEngine,
702
void* io,
703
uint32_t offset,
704
uint32_t packetSize,
705
FACTReadFileCallback pRead,
706
FACTGetOverlappedResultCallback pOverlap,
707
bool isStreaming,
708
FACTWaveBank **ppWaveBank
709
);
710
711
/* vim: set noexpandtab shiftwidth=8 tabstop=8: */
712
713