1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
|
#ifndef SFX_H
#define SFX_H
#include "ultra64.h"
#include "versions.h"
#include "z_math.h"
#include "assert.h"
#define MAX_CHANNELS_PER_BANK 3
typedef enum SfxBankType {
/* 0 */ BANK_PLAYER,
/* 1 */ BANK_ITEM,
/* 2 */ BANK_ENV,
/* 3 */ BANK_ENEMY,
/* 4 */ BANK_SYSTEM,
/* 5 */ BANK_OCARINA,
/* 6 */ BANK_VOICE
} SfxBankType;
typedef enum SfxState {
/* 0 */ SFX_STATE_EMPTY,
/* 1 */ SFX_STATE_QUEUED,
/* 2 */ SFX_STATE_READY,
/* 3 */ SFX_STATE_PLAYING_REFRESH,
/* 4 */ SFX_STATE_PLAYING_1,
/* 5 */ SFX_STATE_PLAYING_2
} SfxState;
typedef struct SfxBankEntry {
/* 0x00 */ f32* posX;
/* 0x04 */ f32* posY;
/* 0x08 */ f32* posZ;
/* 0x0C */ u8 token;
/* 0x10 */ f32* freqScale;
/* 0x14 */ f32* vol;
/* 0x18 */ s8* reverbAdd;
/* 0x1C */ f32 dist;
/* 0x20 */ u32 priority; // lower is more prioritized
/* 0x24 */ u8 sfxImportance;
/* 0x26 */ u16 sfxParams;
/* 0x28 */ u16 sfxId;
/* 0x2A */ u8 state; // uses SfxState enum
/* 0x2B */ u8 freshness;
/* 0x2C */ u8 prev;
/* 0x2D */ u8 next;
/* 0x2E */ u8 channelIndex;
/* 0x2F */ u8 unk_2F;
} SfxBankEntry; // size = 0x30
/*
* SFX IDs
*
* index 0000000111111111 observed in audio code
* & 200 0000001000000000 single bit
* & 400 0000010000000000 single bit
* & 800 0000100000000000 single bit, what we currently call SFX_FLAG
* & 600 0000011000000000 2 bits
* & A00 0000101000000000 2 bits
* & C00 0000110000000000 2 bits, observed in audio code
* & E00 0000111000000000 all 3 bits
* bank 1111000000000000 observed in audio code
*/
#define DEFINE_SFX(_0, enum, _2, _3, _4, _5) enum,
typedef enum SfxId {
NA_SE_NONE, // Requesting a sfx with this id will play no sound
NA_SE_PL_BASE = 0x7FF,
#include "tables/sfx/playerbank_table.h"
NA_SE_PL_END,
NA_SE_IT_BASE = 0x17FF,
#include "tables/sfx/itembank_table.h"
NA_SE_IT_END,
NA_SE_EV_BASE = 0x27FF,
#include "tables/sfx/environmentbank_table.h"
NA_SE_EV_END,
NA_SE_EN_BASE = 0x37FF,
#include "tables/sfx/enemybank_table.h"
NA_SE_EN_END,
NA_SE_SY_BASE = 0x47FF,
#include "tables/sfx/systembank_table.h"
NA_SE_SY_END,
NA_SE_OC_BASE = 0x57FF,
#include "tables/sfx/ocarinabank_table.h"
NA_SE_OC_END,
NA_SE_VO_BASE = 0x67FF,
#include "tables/sfx/voicebank_table.h"
NA_SE_VO_END,
NA_SE_MAX
} SfxId;
// These limits are due to the way Sequence 0 is programmed. There is also a global limit of 512 entries for every bank
// enforced in Audio_PlayActiveSfx in sfx.c
static_assert(NA_SE_PL_END - (NA_SE_PL_BASE + 1) <= 256, "Player Bank SFX Table is limited to 256 entries due to Sequence 0");
static_assert(NA_SE_IT_END - (NA_SE_IT_BASE + 1) <= 128, "Item Bank SFX Table is limited to 128 entries due to Sequence 0");
static_assert(NA_SE_EV_END - (NA_SE_EV_BASE + 1) <= 256, "Environment Bank SFX Table is limited to 256 entries due to Sequence 0");
static_assert(NA_SE_EN_END - (NA_SE_EN_BASE + 1) <= 512, "Enemy Bank SFX Table is limited to 512 entries due to Sequence 0");
static_assert(NA_SE_SY_END - (NA_SE_SY_BASE + 1) <= 128, "System Bank SFX Table is limited to 128 entries due to Sequence 0");
static_assert(NA_SE_OC_END - (NA_SE_OC_BASE + 1) <= 128, "Ocarina Bank SFX Table is limited to 128 entries due to Sequence 0");
static_assert(NA_SE_VO_END - (NA_SE_VO_BASE + 1) <= 256, "Voice Bank SFX Table is limited to 256 entries due to Sequence 0");
#undef DEFINE_SFX
#define SFX_BANK_SHIFT(sfxId) (((sfxId) >> 12) & 0xFF)
#define SFX_BANK_MASK(sfxId) ((sfxId) & 0xF000)
#define SFX_INDEX(sfxId) ((sfxId) & 0x01FF)
#define SFX_BANK(sfxId) SFX_BANK_SHIFT(SFX_BANK_MASK(sfxId))
#define SFX_FLAG 0x800
typedef struct ActiveSfx {
u32 priority; // lower is more prioritized
u8 entryIndex;
} ActiveSfx;
// SfxParams bit-packing
#define SFX_PARAM_01_SHIFT 0
#define SFX_PARAM_01_MASK (3 << SFX_PARAM_01_SHIFT)
#define SFX_FLAG_2 (1 << 2)
#define SFX_FLAG_3 (1 << 3)
#define SFX_FLAG_4 (1 << 4)
#define SFX_FLAG_5 (1 << 5)
#define SFX_PARAM_67_SHIFT 6
#define SFX_PARAM_67_MASK (3 << SFX_PARAM_67_SHIFT)
#define SFX_FLAG_9 (1 << 9)
#define SFX_FLAG_10_SHIFT 10
#define SFX_FLAG_10 (1 << SFX_FLAG_10_SHIFT)
#define SFX_FLAG_11 (1 << 11)
#define SFX_FLAG_12 (1 << 12)
#define SFX_FLAG_13 (1 << 13)
#define SFX_FLAG_14 (1 << 14)
#define SFX_FLAG_15 (1 << 15)
typedef struct SfxParams {
u8 importance;
u16 params;
} SfxParams;
#if DEBUG_FEATURES
#define SFX_DIST_SCALING 1.0f
#else
#define SFX_DIST_SCALING 10.0f
#endif
#define SFX_PLAY_CENTERED(sfxId) \
Audio_PlaySfxGeneral(sfxId, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, \
&gSfxDefaultReverb);
#define SFX_PLAY_AT_POS(projectedPos, sfxId) \
Audio_PlaySfxGeneral(sfxId, projectedPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, \
&gSfxDefaultReverb);
void Audio_SetSfxBanksMute(u16 muteMask);
void Audio_QueueSeqCmdMute(u8 channelIndex);
void Audio_ClearBGMMute(u8 channelIndex);
void Audio_PlaySfxGeneral(u16 sfxId, Vec3f* pos, u8 token, f32* freqScale, f32* vol, s8* reverbAdd);
void Audio_ProcessSfxRequest(void);
void Audio_ChooseActiveSfx(u8 bankId);
void Audio_PlayActiveSfx(u8 bankId);
void Audio_StopSfxByBank(u8 bankId);
void Audio_RemoveSfxFromBankByPos(u8 bankId, Vec3f* pos);
void Audio_StopSfxByPosAndBank(u8 bankId, Vec3f* pos);
void Audio_StopSfxByPos(Vec3f* pos);
void Audio_StopSfxByPosAndId(Vec3f* pos, u16 sfxId);
void Audio_StopSfxByTokenAndId(u8 token, u16 sfxId);
void Audio_StopSfxById(u32 sfxId);
void Audio_ProcessSfxRequests(void);
void func_800F8F88(void);
u8 Audio_IsSfxPlaying(u32 sfxId);
void Audio_ResetSfx(void);
extern SfxParams* gSfxParams[7];
extern char D_80133390[];
extern char D_80133398[];
extern u8 gSfxRequestWriteIndex;
extern u8 gSfxRequestReadIndex;
extern SfxBankEntry* gSfxBanks[7];
extern u8 gSfxBankSizes[];
extern u8 gSfxChannelLayout;
extern u16 D_801333D0;
extern Vec3f gSfxDefaultPos;
extern f32 gSfxDefaultFreqAndVolScale;
extern s8 gSfxDefaultReverb;
#if DEBUG_FEATURES
extern u8 D_801333F0;
extern u8 gAudioSfxSwapOff;
extern u8 D_801333F8;
#endif
extern SfxBankEntry D_8016BAD0[9];
extern SfxBankEntry D_8016BC80[12];
extern SfxBankEntry D_8016BEC0[22];
extern SfxBankEntry D_8016C2E0[20];
extern SfxBankEntry D_8016C6A0[8];
extern SfxBankEntry D_8016C820[3];
extern SfxBankEntry D_8016C8B0[5];
extern ActiveSfx gActiveSfx[7][MAX_CHANNELS_PER_BANK]; // total size = 0xA8
extern u8 gSfxBankMuted[];
extern u16 gAudioSfxSwapSource[10];
extern u16 gAudioSfxSwapTarget[10];
extern u8 gAudioSfxSwapMode[10];
#endif
|