diff --git a/Makefile b/Makefile
index e5b7949d1d..ee3150e8d7 100644
--- a/Makefile
+++ b/Makefile
@@ -166,6 +166,7 @@ SBC := tools/audio/sbc
SFC := tools/audio/sfc
SFPATCH := tools/audio/sfpatch
ATBLGEN := tools/audio/atblgen
+AFILE_SIZES := tools/audio/afile_sizes
# We want linemarkers in sequence assembly files for better assembler error messages
SEQ_CPP := $(CPP) -x assembler-with-cpp -fno-dollars-in-identifiers
SEQ_CPPFLAGS := -D_LANGUAGE_ASEQ -DMML_VERSION=MML_VERSION_MM -I include -I include/audio -I include/tables/sfx -I $(BUILD_DIR)/assets/audio/soundfonts
@@ -723,8 +724,8 @@ $(BUILD_DIR)/assets/audio/soundfonts/%.o: $(BUILD_DIR)/assets/audio/soundfonts/%
$(LD) -r -T linker_scripts/soundfont.ld $(@:.o=.tmp) -o $(@:.o=.tmp2)
# patch defined symbols to be ABS symbols so that they remain file-relative offsets forever
$(SFPATCH) $(@:.o=.tmp2) $(@:.o=.tmp2)
-# write start and size symbols afterwards, filename != symbolic name so source symbolic name from the .name file written by sfc
- $(OBJCOPY) --add-symbol $$(cat $(<:.c=.name))_Start=.rodata:0,global --redefine-sym __LEN__=$$(cat $(<:.c=.name))_Size $(@:.o=.tmp2) $@
+# write start and size symbols afterwards, filename != symbolic name so source symbolic name from the .name file written by sfc# also write a .note.name section containing the symbolic name of the soundfont
+ $(OBJCOPY) --add-symbol $$(cat $(<:.c=.name) | head -c -1)_Start=.rodata:0,global --redefine-sym __LEN__=$$(cat $(<:.c=.name) | head -c -1)_Size --add-section .note.name=$(<:.c=.name) $(@:.o=.tmp2) $@
# cleanup temp files
@$(RM) $(@:.o=.tmp) $(@:.o=.tmp2)
$(RM_MDEBUG)
@@ -784,6 +785,16 @@ $(BUILD_DIR)/src/audio/tables/%.o: src/audio/tables/%.c
$(BUILD_DIR)/assets/audio/sequence_font_table.o: $(BUILD_DIR)/assets/audio/sequence_font_table.s
$(AS) $(ASFLAGS) $< -o $@
+# make headers with file sizes and amounts
+
+$(BUILD_DIR)/src/audio/session_config.o: $(BUILD_DIR)/assets/audio/soundfont_sizes.h $(BUILD_DIR)/assets/audio/sequence_sizes.h
+
+$(BUILD_DIR)/assets/audio/soundfont_sizes.h: $(SOUNDFONT_O_FILES)
+ $(AFILE_SIZES) $@ NUM_SOUNDFONTS SOUNDFONT_SIZES .rodata $^
+
+$(BUILD_DIR)/assets/audio/sequence_sizes.h: $(SEQUENCE_O_FILES)
+ $(AFILE_SIZES) $@ NUM_SEQUENCES SEQUENCE_SIZES .data $^
+
-include $(DEP_FILES)
# Print target for debugging
diff --git a/assets/xml/audio/samplebanks/SampleBank_0.xml b/assets/xml/audio/samplebanks/SampleBank_0.xml
index 07e4c7a06f..bc1c5bb8d8 100644
--- a/assets/xml/audio/samplebanks/SampleBank_0.xml
+++ b/assets/xml/audio/samplebanks/SampleBank_0.xml
@@ -1,676 +1,676 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/assets/xml/audio/samplebanks/SampleBank_2.xml b/assets/xml/audio/samplebanks/SampleBank_2.xml
index 3fbeefd97f..0512a81d82 100644
--- a/assets/xml/audio/samplebanks/SampleBank_2.xml
+++ b/assets/xml/audio/samplebanks/SampleBank_2.xml
@@ -1,9 +1,9 @@
-
-
-
-
-
-
+
+
+
+
+
+
diff --git a/docs/audio/Samplebank_XML.md b/docs/audio/Samplebank_XML.md
new file mode 100644
index 0000000000..b9c027bcb7
--- /dev/null
+++ b/docs/audio/Samplebank_XML.md
@@ -0,0 +1,77 @@
+# Samplebank XML Format Specification
+
+Samplebank XMLs describe a samplebank file that contains compressed waveform data. It specifies which sample files to include as well as certain global properties such as the index of this samplebank.
+
+---
+
+```xml
+
+```
+Begins a new samplebank.
+
+**Attributes**
+
+- **Name**: The name of the samplebank.
+- **Index**: The index of the samplebank for the samplebank table. Must be a unique index for all samplebanks and pointers.
+- **Medium**: The storage medium, from the `SampleMedium` enum.
+- **CachePolicy**: The cache policy, from the `AudioCacheLoadType` enum.
+- [Optional] **BufferBug**: Whether this samplebank suffers from a buffer clearing bug present in the original audio tools. For matching only.
+
+**Tags**
+
+-
+ ```xml
+
+ ```
+ Create an alternate index that refers to this samplebank.
+
+ **Attributes**
+
+ - **Index**: The alternative index, must be unique among all samplebanks and pointers.
+
+ ---
+
+-
+ ```xml
+
+ ```
+ Adds a **compressed** sample file to the samplebank. The sample should be single-channel and big-endian, in a format that is recognizable by the audio driver such as: pcm16, vadpcm, or half-frame vadpcm.
+
+ **Attributes**
+
+ - **Name**: Name of this sample. Must be a valid C language identifier.
+ - **Path**: Path to aifc file relative to the project root (typically in `$(BUILD_DIR)/assets/audio/samples/`)
+
+ ---
+
+-
+ ```xml
+
+ ```
+ Adds a binary blob to the samplebank. Intended for matching only when data cannot be identified.
+
+ **Attributes**
+
+ - **Name**: Name of this blob. Must be a valid C language identifier.
+ - **Path**: Path to binary file, relative to the project root (typically in `$(BUILD_DIR)/assets/audio/samples/`)
+
+ ---
+
+```xml
+
+```
+---
diff --git a/docs/audio/Soundfont_XML.md b/docs/audio/Soundfont_XML.md
new file mode 100644
index 0000000000..c2d8a572ed
--- /dev/null
+++ b/docs/audio/Soundfont_XML.md
@@ -0,0 +1,319 @@
+# Soundfont XML Format Specification
+
+Soundfont XMLs describe the layout of a single soundfont. These package raw samples together into instruments, of which there are three kinds:
+- **Effects**: These are simple sound effects that just play a single sample without any modulation.
+- **Drums**: These define a MIDI-style percussion key map.
+- **Instruments**: These are instruments that may be played at any key with up to three voices and may be modulated by an envelope.
+
+In the specification, `Note Name`s can be either a MIDI note name e.g. `C4` or it may be a **Zelda64** note number, which are related to MIDI note numbers ($n$) by $(n - 21) \mod 128$.
+
+---
+
+```xml
+
+```
+Begins a new soundfont.
+
+**Attributes**
+- **Name**: Soundfont symbol name. Must be a valid C identifier.
+- **Index**: Soundfont index. Must be an integer.
+- **Medium**: Storage medium. Must be an enum name from `SampleMedium`.
+- **CachePolicy**: Cache policy. Must be an enum name from `AudioCacheLoadType`.
+- **SampleBank**: Path to samplebank xml used by this soundfont.
+- [Optional] **Indirect**: Pointer index if the samplebank is referenced indirectly.
+- [Optional] **SampleBankDD**: Path to samplebank xml used for DD medium.
+- [Optional] **IndirectDD**: Pointer index if the DD samplebank is referenced indirectly.
+- [Optional] **LoopsHaveFrames**: Whether loops in this soundfont store the total frame count of the sample. Must be a boolean.
+- [Optional] **PadToSize**: For matching only. Specifies the total file size the result output should be padded to.
+- [Optional] **NumInstruments**: For matching only. Specifies the total number of instrument pointers. Usually this is automatically assigned based on `max(program_number) + 1` but some vanilla banks don't match this way.
+
+**Tags**
+
+-
+ ```xml
+
+ ```
+ Lists envelopes defined in this soundfont.
+
+ **Attributes**
+
+ N/A
+
+ **Tags**
+
+ -
+ ```xml
+
+ ```
+ Starts a new envelope.
+
+ **Attributes**
+
+ - **Name**: Unique name for this envelope. Must be a valid C identifier.
+ - **Release**: Release rate index (into `gAudioCtx.adsrDecayTable`) for this envelope
+
+ **Tags**
+
+ -
+ ```xml
+
+ ```
+ Add a point to the envelope at (delay, arg)
+
+ **Attributes**
+
+ - **Delay**: Duration until the next point
+ - **Arg**: Value of the envelope at this point
+
+ ---
+
+ -
+ ```xml
+
+ ```
+ Insert a ADSR_DISABLE command
+
+ ---
+
+ -
+ ```xml
+
+ ```
+ Insert a ADSR_HANG command
+
+ ---
+
+ -
+ ```xml
+
+ ```
+ Insert a ADSR_GOTO command
+
+ **Attributes**
+
+ - **Index**: Index of the envelope point to jump to
+
+ ---
+
+ ```xml
+
+ ```
+ ---
+
+ ```xml
+
+ ```
+ ---
+
+-
+ ```xml
+
+ ```
+ Begins a list of samples used in this Soundfont.
+
+ **Attributes**
+
+ - [Optional] **IsDD**: Whether all the samples in the list are on the Disk Drive. The sample data will come from the samplebank `SampleBankDD`. **Default is `false`.** **NOTE this is not fully implemented, it should always be `false`.**
+ - [Optional] **Cached**: Whether all the samples in the list should be added to the `usedSamples` cache. **Default is `false`.**
+
+ **Tags**
+
+ -
+ ```xml
+
+ ```
+ Declares a sample used in this soundfont.
+
+ **Attributes**
+
+ - **Name**: The name of this sample. A sample with this name must be present in the samplebank used by the soundfont.
+ - [Optional] **SampleRate**: An overriding sample rate for this sample. **Default comes from the sample file.**
+ - [Optional] **BaseNote**: An overriding root key for this sample. **Default comes from the sample file.**
+ - [Optional] **IsDD**: Whether this sample is on the Disk Drive. The sample data will come from the samplebank `SampleBankDD`. **Default is `false`.** **NOTE this is not fully implemented, it should always be `false`.**
+ - [Optional] **Cached**: Whether this sample should be added to the `usedSamples` cache. **Default is `false`.**
+
+ ---
+
+ ```xml
+
+ ```
+ ---
+
+-
+ ```xml
+
+ ```
+ Begins a list of sound effects to define for this soundfont. Sound effects correspond to simple sounds that cannot be played at different keys.
+
+ **Attributes**
+
+ N/A
+
+ **Tags**
+
+ -
+ ```xml
+
+ ```
+ Defines a single sound effect.
+
+ **Attributes**
+ - **Name**: The name of the sound effect, the name is made available in sequence files in the form `SF{n}_{name}` where `n` is the index of this soundfont and `name` is this name. For example, if `n=0` and `name=ExampleEffect` the name to use in sequence files is `SF0_ExampleEffect`.
+ - **Sample**: The name of the sample associated with this effect.
+ - [Optional] **SampleRate**: An overriding sample rate for this effect. **Default comes from the sample definition.**
+ - [Optional] **BaseNote**: An overriding root key for this effect. **Default comes from the sample definition.**
+
+ ---
+
+ ```xml
+
+ ```
+ ---
+
+-
+ ```xml
+
+ ```
+ Begins the percussion definitions for this soundfont. Percussion corresponds to the MIDI notion of percussion, where single samples are mapped across a range of keys.
+
+ **Attributes**
+
+ N/A
+
+ **Tags**
+
+ -
+ ```xml
+
+ ```
+ Defines a single percussion range.
+
+ **Attributes**
+ - **Name**: The name of this sound. Definitions are emitted for sequence files in the form `SF{n}_{name}_{note}` for every note covered by this sound.
+ - [Optional] **Note**: The key to map this sound to. Should not overlap with other definitions. **If this field is left unspecified, `NoteStart` and `NoteEnd` become required.**
+ - [Optional] **NoteStart**: The first key that is mapped to this sound. Should not overlap with other definitions. **If this field is left unspecified, `Note` becomes required. If this field is specified, `NoteEnd` must also be specified.**
+ - [Optional] **NoteEnd**: The last key that is mapped to this sound. Should not overlap with other definitions. **If this field is left unspecified, `Note` becomes required. If this field is specified, `NoteStart` must also be specified.**
+ - **Pan**: The stereo weight for this sound. Center=`64`.
+ - **Envelope**: The envelope to modulate the volume over time with. Must be defined in the `Envelopes` list.
+ - [Optional] **Release**: An override for the envelope release rate. **Default is the release rate specified in the envelope definition**
+ - **Sample**: The name of the sample to use.
+ - [Optional] **SampleRate**: An overriding sample rate for this sound. **Default comes from the sample definition.**
+ - [Optional] **BaseNote**: An overriding root key for this sound. **Default comes from the sample definition.**
+
+ ---
+
+ ```xml
+
+ ```
+ ---
+
+-
+ ```xml
+
+ ```
+ Begins the instrument definitions for this soundfont. Instruments correspond to the MIDI notion of instruments, with up to 3 samples (voices) per instrument that must map to contiguous ranges of notes.
+
+ **Attributes**
+
+ N/A
+
+ **Tags**
+
+ -
+ ```xml
+
+ ```
+ Defines an instrument.
+
+ **Attributes**
+ - **ProgramNumber**: MIDI Program Number for this instrument. Must be in the range `0 <= n <= 125`
+ - **Name**: The name of this instrument.
+ - **Envelope**: Envelope to use, identified by name.
+ - [Optional] **Release**: Release rate index override. **Default release rate comes from the chosen envelope.**
+ - **Sample**: The name of the middle sample to use for this instrument.
+ - [Optional] **SampleRate**: Sample rate override for the middle sample. **Default is sourced from the sample properties.**
+ - [Optional] **BaseNote**: Base note override for the middle sample. **Default is sourced from the sample properties.**
+ - [Optional] **RangeLo**: The largest note for SampleLo. SampleLo will be used instead of Sample for keys in the range [0, RangeLo]. **If left unspecified, SampleLo must not be specified. If specified, SampleLo must be specified.**
+ - [Optional] **SampleLo**: The name of the low sample to use for this instrument.
+ - [Optional] **SampleRateLo**: Sample rate override for the low sample. **Default is sourced from the sample properties.**
+ - [Optional] **BaseNoteLo**: Base note override for the low sample. **Default is sourced from the sample properties.**
+ - [Optional] **RangeHi**: The smallest note for SampleHi. SampleHi will be used instead of Sample for keys in the range [RangeHi, 127]. **If left unspecified, SampleHi must not be specified. If specified, SampleHi must be specified.**
+ - [Optional] **SampleHi**: The name of the high sample to use for this instrument.
+ - [Optional] **SampleRateHi**: Sample rate override for the high sample. **Default is sourced from the sample properties.**
+ - [Optional] **BaseNoteHi**: Base note override for the high sample. **Default is sourced from the sample properties.**
+
+ ---
+
+ ```xml
+
+ ```
+ ---
+
+```xml
+
+```
+---
diff --git a/docs/audio/build_flowchart.png b/docs/audio/build_flowchart.png
new file mode 100644
index 0000000000..9ef26221ee
Binary files /dev/null and b/docs/audio/build_flowchart.png differ
diff --git a/include/audio/aseq.h b/include/audio/aseq.h
index 1c66a3a2c3..8d5eb6be40 100644
--- a/include/audio/aseq.h
+++ b/include/audio/aseq.h
@@ -556,8 +556,8 @@ _RESET_SECTION
.macro .startseq name
/* Begin a sequence. */
- /* Write the sequence name into a special .name section */
- .pushsection .name, "", @note
+ /* Write the sequence name into a special .note.name section */
+ .pushsection .note.name, "", @note
.asciz "\name"
.balign 4
.popsection
diff --git a/include/libc/assert.h b/include/libc/assert.h
index 7fee0a815c..fd3015347c 100644
--- a/include/libc/assert.h
+++ b/include/libc/assert.h
@@ -3,9 +3,9 @@
// Static/compile-time assertions
-#if (__STDC_VERSION__ >= 202311L)
+#if !defined(__sgi) && (__STDC_VERSION__ >= 202311L)
// static_assert is a keyword in C23, do not define it
-#elif (__STDC_VERSION__ >= 201112L)
+#elif !defined(__sgi) && (__STDC_VERSION__ >= 201112L)
# define static_assert(cond, msg) _Static_assert(cond, msg)
#else
# ifndef GLUE
diff --git a/include/sfx.h b/include/sfx.h
index d37e333ac0..8d1fa7993a 100644
--- a/include/sfx.h
+++ b/include/sfx.h
@@ -2,6 +2,7 @@
#define SFX_H
#include "PR/ultratypes.h"
+#include "libc/assert.h"
#include "z64math.h"
/**
@@ -23,25 +24,50 @@
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;
#undef DEFINE_SFX
+// These limits are due to the way Sequence 0 is programmed. There is also a global limit of 1024 entries for every bank
+// enforced in Audio_PlayActiveSfx in sfx.c
+static_assert(NA_SE_PL_END - (NA_SE_PL_BASE + 1) <= 512, "Player Bank SFX Table is limited to 512 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) <= 512, "Environment Bank SFX Table is limited to 512 entries due to Sequence 0");
+static_assert(NA_SE_EN_END - (NA_SE_EN_BASE + 1) <= 768, "Enemy Bank SFX Table is limited to 768 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) <= 512, "Voice Bank SFX Table is limited to 512 entries due to Sequence 0");
+
typedef enum SfxPauseMenu {
/* 0 */ SFX_PAUSE_MENU_CLOSE,
/* 1 */ SFX_PAUSE_MENU_OPEN
diff --git a/linker_scripts/soundfont.ld b/linker_scripts/soundfont.ld
index d914a7de31..c480e36867 100644
--- a/linker_scripts/soundfont.ld
+++ b/linker_scripts/soundfont.ld
@@ -4,14 +4,15 @@ OUTPUT_ARCH (mips)
SECTIONS {
- .rodata :
+ .rodata ALIGN(16) :
{
*(.data*)
*(.rodata*)
. = ALIGN(16);
- __LEN__ = . - ADDR(.rodata);
}
+ __LEN__ = ABSOLUTE(SIZEOF(.rodata));
+
/DISCARD/ :
{
*(*);
diff --git a/src/audio/session_config.c b/src/audio/session_config.c
index e0309468fe..37125864fe 100644
--- a/src/audio/session_config.c
+++ b/src/audio/session_config.c
@@ -1,5 +1,10 @@
#include "global.h"
#include "buffers.h"
+#include "assets/audio/sequence_sizes.h"
+#include "assets/audio/soundfont_sizes.h"
+#define SFX_SEQ_SIZE Sequence_0_SIZE
+#define AMBIENCE_SEQ_SIZE Sequence_1_SIZE
+#define SFX_SOUNDFONTS_SIZE (Soundfont_0_SIZE + Soundfont_1_SIZE + Soundfont_2_SIZE)
static s32 sBssPad[36];
AudioContext gAudioCtx;
@@ -14,21 +19,12 @@ const s16 gAudioTatumInit[] = {
TATUMS_PER_BEAT, // gTatumsPerBeat
};
-// TODO: Extract from table?
-#define NUM_SOUNDFONTS 41
-#define SFX_SEQ_SIZE 0xC6A0
-#define AMBIENCE_SEQ_SIZE 0xFC0
-#define SOUNDFONT_0_SIZE 0x81C0
-#define SOUNDFONT_1_SIZE 0x36D0
-#define SOUNDFONT_2_SIZE 0xCE0
-
// Sizes of everything on the init pool
#define AI_BUFFERS_SIZE (AIBUF_SIZE * ARRAY_COUNT(gAudioCtx.aiBuffers))
#define SOUNDFONT_LIST_SIZE (NUM_SOUNDFONTS * sizeof(SoundFont))
// 0x19BD0
-#define PERMANENT_POOL_SIZE \
- (SFX_SEQ_SIZE + AMBIENCE_SEQ_SIZE + SOUNDFONT_0_SIZE + SOUNDFONT_1_SIZE + SOUNDFONT_2_SIZE + 0x430)
+#define PERMANENT_POOL_SIZE (SFX_SEQ_SIZE + AMBIENCE_SEQ_SIZE + SFX_SOUNDFONTS_SIZE + 0x430)
const AudioHeapInitSizes gAudioHeapInitSizes = {
ALIGN16(sizeof(gAudioHeap) - 0x100), // audio heap size
diff --git a/src/overlays/actors/ovl_Boss_02/z_boss_02.c b/src/overlays/actors/ovl_Boss_02/z_boss_02.c
index 0a6f660353..1baced1646 100644
--- a/src/overlays/actors/ovl_Boss_02/z_boss_02.c
+++ b/src/overlays/actors/ovl_Boss_02/z_boss_02.c
@@ -4,6 +4,7 @@
* Description: Twinmold
*/
+#include "prevent_bss_reordering.h"
#include "z_boss_02.h"
#include "z64rumble.h"
#include "z64shrink_window.h"
diff --git a/tools/audio/.gitignore b/tools/audio/.gitignore
index f0d3c612fd..5864deaf3c 100644
--- a/tools/audio/.gitignore
+++ b/tools/audio/.gitignore
@@ -1,5 +1,6 @@
__pycache__/
+afile_sizes
atblgen
sfpatch
sbc
diff --git a/tools/audio/Makefile b/tools/audio/Makefile
index df860ef72e..aeec49070d 100644
--- a/tools/audio/Makefile
+++ b/tools/audio/Makefile
@@ -1,4 +1,4 @@
-PROGRAMS := atblgen sfpatch sbc sfc
+PROGRAMS := afile_sizes atblgen sbc sfc sfpatch
ifeq ($(shell which xml2-config),)
$(error xml2-config not found. Did you install libxml2-dev?)
@@ -9,7 +9,7 @@ FORMAT_ARGS := -i -style=file
CC := gcc
CFLAGS := -Wall -Wextra -pedantic
-OPTFLAGS := -Og -g3
+OPTFLAGS := -O2
XML_CFLAGS := $(shell xml2-config --cflags)
XML_LDFLAGS := $(shell xml2-config --libs)
@@ -30,10 +30,11 @@ format:
$(CLANG_FORMAT) $(FORMAT_ARGS) $(shell find . -maxdepth 1 -type f -name "*.[ch]")
$(MAKE) -C sampleconv format
-atblgen_SOURCES := audio_tablegen.c samplebank.c soundfont.c xml.c util.c
-sfpatch_SOURCES := sfpatch.c util.c
-sbc_SOURCES := samplebank_compiler.c samplebank.c aifc.c xml.c util.c
-sfc_SOURCES := soundfont_compiler.c samplebank.c soundfont.c aifc.c xml.c util.c
+afile_sizes_SOURCES := afile_sizes.c util.c
+atblgen_SOURCES := audio_tablegen.c samplebank.c soundfont.c xml.c util.c
+sbc_SOURCES := samplebank_compiler.c samplebank.c aifc.c xml.c util.c
+sfc_SOURCES := soundfont_compiler.c samplebank.c soundfont.c aifc.c xml.c util.c
+sfpatch_SOURCES := sfpatch.c util.c
atblgen_CFLAGS := $(XML_CFLAGS)
sbc_CFLAGS := $(XML_CFLAGS)
diff --git a/tools/audio/README.md b/tools/audio/README.md
new file mode 100644
index 0000000000..95998dd944
--- /dev/null
+++ b/tools/audio/README.md
@@ -0,0 +1,59 @@
+# Z64 Audio Tools
+
+The Z64 Audio Tools work together to implement the full audio asset pipeline
+
+
+
+**Licensing Information**
+* The programs `atblgen`, `sampleconv`, `sbc` and `sfc` are (mostly) distributed under MPL-2.0. The VADPCM encoding and decoding portions of `sampleconv` are under CC0-1.0.
+* The programs `sfpatch` and `afile_sizes` are distributed under CC0-1.0.
+* The extraction tool is distributed under CC0-1.0.
+
+## sampleconv
+
+Converts aifc <-> aiff / wav
+
+Used in extraction and build to convert audio sample data between uncompressed mono 16-bit PCM and the compressed formats used by the audio driver.
+
+## SampleBank Compiler (sbc)
+
+Converts samplebank xml + aifc -> asm
+
+Samplebanks are converted to assembly files for building as it is easier to define the necessary absolute symbols, and they are pure unstructured data.
+
+## SoundFont Compiler (sfc)
+
+Converts soundfont & samplebank xml + aifc -> C
+
+Soundfonts are converted to C rather than assembly as it shares data structures with the audio driver code. Modifying the structures used by the driver without updating `sfc` to write them should error at compile-time rather than crash at runtime.
+
+## sfpatch
+
+`Usage: sfpatch in.elf out.elf`
+
+This tool patches the symbol table of an ELF file (`in.elf`) to make every defined symbol in the file an absolute symbol. This is a required step for building soundfonts from C source as all pointers internal to a soundfont are offset from the start of the soundfont file and not the audiobank segment as a whole. Making all defined symbols ABS symbols prevents the linker from updating their values later, ensuring they remain file-relative.
+
+## atblgen
+
+Generates various audio code tables.
+
+- Samplebank table: Specifies where in the `Audiotable` file each samplebank begins and how large it is.
+- Soundfont table: Specifies where in the `Audiobank` files each soundfont begins, how large it is, which samplebanks it uses, and how many instruments/drums/sfx it contains.
+- Sequence font table: Contains information on what soundfonts each sequence uses. Generated from the sequence object files that embed a `.note.fonts` section that holds this information.
+
+The sequence table is not generated as some things in that table are better left manually specified, such as sequence enum names and flags. This also lets us have the sequence table before assembling any sequence files which is nice for some sequence commands like `runseq`.
+
+## afile_sizes
+
+Produces header files containing binary file sizes for a given set of object files. Used to produce headers containing soundfont and sequence files and the number of each for use in code files.
+
+## extraction
+
+This collection of python files implements the extraction of audio data from a base ROM.
+
+Files that are designed to be used externally include:
+- `audio_extract.py` is the main file for audio extraction, it expects an external script to call `extract_audio_for_version` with the necessary inputs.
+- `disassemble_sequence.py` is runnable but is not used in this way in either extraction or building. It may be used to manually disassemble a sequence binary.
+- `tuning.py` is runnable but is not used that way in either extraction or building. It may be used to manually determine alternative matches for the samplerate and basenote of a sample as the extraction procedure cannot always determine these uniquely.
+
+See individual python source files for further details on their purposes.
diff --git a/tools/audio/afile_sizes.c b/tools/audio/afile_sizes.c
new file mode 100644
index 0000000000..1bd87ef483
--- /dev/null
+++ b/tools/audio/afile_sizes.c
@@ -0,0 +1,120 @@
+/* SPDX-FileCopyrightText: Copyright (C) 2024 ZeldaRET */
+/* SPDX-License-Identifier: CC0-1.0 */
+#include
+#include
+#include
+#include
+
+#include "elf32.h"
+#include "util.h"
+
+static int
+usage(const char *progname)
+{
+ fprintf(stderr,
+ // clang-format off
+ "Generates a header containing definitions for the sizes of all the input object files and a" "\n"
+ "definition for the number of input files." "\n"
+ "Usage: %s