summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorpetrie911 <69443847+petrie911@users.noreply.github.com>2024-03-01 12:57:44 -0600
committerGitHub <noreply@github.com>2024-03-01 15:57:44 -0300
commit5152d504b3539372512453ac8f6ae9f5fc1e7463 (patch)
tree7182e5aa8a2b6fe92a713e4895a9ed6f03ab350a /include
parent1bbbb3134cb97ea82d4b472c792ddb3b283645ba (diff)
audio_general, audio data import, naming lots of audio functions (#144)
* heapsort * suff * load init * split * split data * begone asm * names * names and cleanup * let's try this * woo macros * general * bgm macro * names
Diffstat (limited to 'include')
-rw-r--r--include/audioseq_cmd.h524
-rw-r--r--include/audiothread_cmd.h543
-rw-r--r--include/functions.h48
-rw-r--r--include/global.h1
-rw-r--r--include/macros.h2
-rw-r--r--include/prevent_context_reordering.h4
-rw-r--r--include/sf64audio_external.h141
-rw-r--r--include/sf64audio_provisional.h541
-rw-r--r--include/sf64object.h12
-rw-r--r--include/sf64player.h69
-rw-r--r--include/variables.h15
11 files changed, 1566 insertions, 334 deletions
diff --git a/include/audioseq_cmd.h b/include/audioseq_cmd.h
new file mode 100644
index 00000000..1f2deed3
--- /dev/null
+++ b/include/audioseq_cmd.h
@@ -0,0 +1,524 @@
+#ifndef SEQCMD_H
+#define SEQCMD_H
+
+void Audio_QueueSeqCmd(s32);
+
+// ==== Sequence Players ====
+
+typedef enum {
+ /* 0 */ SEQ_PLAYER_BGM,
+ /* 1 */ SEQ_PLAYER_FANFARE,
+ /* 2 */ SEQ_PLAYER_SFX,
+ /* 3 */ SEQ_PLAYER_VOICE
+} SequencePlayerId;
+
+// ==== Primary commands ====
+
+#define SEQCMD_OP_MASK 0xF0000000
+
+typedef enum {
+ /* 0x0 */ SEQCMD_OP_PLAY_SEQUENCE,
+ /* 0x1 */ SEQCMD_OP_STOP_SEQUENCE,
+ /* 0x2 */ SEQCMD_OP_QUEUE_SEQUENCE,
+ /* 0x3 */ SEQCMD_OP_UNQUEUE_SEQUENCE,
+ /* 0x4 */ SEQCMD_OP_SET_SEQPLAYER_VOLUME,
+ /* 0x5 */ SEQCMD_OP_SET_SEQPLAYER_FREQ,
+ /* 0x6 */ SEQCMD_OP_SET_CHANNEL_VOLUME,
+ /* 0x7 */ SEQCMD_OP_SET_SEQPLAYER_IO,
+ /* 0x8 */ SEQCMD_OP_SET_CHANNEL_IO,
+ /* 0x9 */ SEQCMD_OP_SET_CHANNEL_IO_DISABLE_MASK,
+ /* 0xA */ SEQCMD_OP_SET_CHANNEL_DISABLE_MASK,
+ /* 0xB */ SEQCMD_OP_TEMPO_CMD,
+ /* 0xC */ SEQCMD_OP_SETUP_CMD,
+ /* 0xD */ SEQCMD_OP_SET_CHANNEL_FREQ,
+ /* 0xE */ SEQCMD_OP_GLOBAL_CMD,
+ /* 0xF */ SEQCMD_OP_RESET_AUDIO_HEAP
+} SeqCmdOp;
+
+// ==== Secondary commands ====
+
+// Subset of `SEQCMD_OP_TEMPO_CMD`
+typedef enum {
+ /* 0x0 */ SEQCMD_SUB_OP_TEMPO_SET,
+ /* 0x1 */ SEQCMD_SUB_OP_TEMPO_SPEED_UP,
+ /* 0x2 */ SEQCMD_SUB_OP_TEMPO_SLOW_DOWN,
+ /* 0x3 */ SEQCMD_SUB_OP_TEMPO_SCALE,
+ /* 0x4 */ SEQCMD_SUB_OP_TEMPO_RESET
+} SeqCmdTempoCmdOp;
+
+// Subset of `SEQCMD_OP_SETUP_CMD`
+typedef enum {
+ /* 0x0 */ SEQCMD_SUB_OP_SETUP_RESTORE_SEQPLAYER_VOLUME,
+ /* 0x1 */ SEQCMD_SUB_OP_SETUP_SEQ_UNQUEUE,
+ /* 0x2 */ SEQCMD_SUB_OP_SETUP_RESTART_SEQ,
+ /* 0x3 */ SEQCMD_SUB_OP_SETUP_TEMPO_SCALE,
+ /* 0x4 */ SEQCMD_SUB_OP_SETUP_TEMPO_RESET,
+ /* 0x5 */ SEQCMD_SUB_OP_SETUP_PLAY_SEQ,
+ /* 0x6 */ SEQCMD_SUB_OP_SETUP_SET_FADE_TIMER,
+ /* 0x7 */ SEQCMD_SUB_OP_SETUP_RESTORE_SEQPLAYER_VOLUME_IF_QUEUED,
+ /* 0x8 */ SEQCMD_SUB_OP_SETUP_RESTORE_SEQPLAYER_VOLUME_WITH_SCALE_INDEX,
+ /* 0x9 */ SEQCMD_SUB_OP_SETUP_SET_CHANNEL_DISABLE_MASK,
+ /* 0xA */ SEQCMD_SUB_OP_SETUP_SET_SEQPLAYER_FREQ,
+ /* 0xE */ SEQCMD_SUB_OP_SETUP_POP_PERSISTENT_CACHE = 0xE,
+ /* 0xF */ SEQCMD_SUB_OP_SETUP_RESET_SETUP_CMDS
+} SeqCmdSetupCmdOp;
+
+// Subset of `SEQCMD_OP_GLOBAL_CMD`
+typedef enum {
+ /* 0x0 */ SEQCMD_SUB_OP_GLOBAL_SET_SOUND_MODE,
+ /* 0x1 */ SEQCMD_SUB_OP_GLOBAL_DISABLE_NEW_SEQUENCES
+} SeqCmdSubCmdOp;
+
+// ==== Audio Sequence Primary Commands ====
+
+/**
+ * Play a sequence on a given seqPlayer
+ *
+ * @param seqPlayerIndex the index of the seqPlayer to play the sequence
+ * @param fadeInDuration effect will depend on seqArg. See below
+ * @param seqArg no effect: < 0x7F, skip ahead: = 0x7F, will not play: >= 0x80 (see note)
+ * @param seqId the id of the sequence to play, see `SeqId`
+ *
+ * @note seqArg will also be stored in gActiveSeqs.seqId, any check against that seqId must also include seqArg.
+ * seqArg < 0x7F: fade in the sequence over `fadeInDuration` in units of (1/30th) seconds
+ * seqArg = 0x7F: start the sequence immediately, but begins `fadeInDuration` number of second into the sequence.
+ * seqArg >= 0x80: no sequence will play. Intended to load a soundFont asynchronously but was only half implemented
+ * (inferred from MM).
+ */
+#define SEQCMD_PLAY_SEQUENCE(seqPlayerIndex, fadeInDuration, seqArg, seqId) \
+ Audio_QueueSeqCmd((SEQCMD_OP_PLAY_SEQUENCE << 28) | ((u8)(seqPlayerIndex) << 24) | ((u8)(fadeInDuration) << 16) | \
+ ((u8)(seqArg) << 8) | (u16)(seqId))
+
+/**
+ * Stop a sequence on a given seqPlayer
+ *
+ * @param seqPlayerIndex the index of the seqPlayer to stop the sequence
+ * @param fadeOutDuration duration the sequence will fade out over
+ *
+ * @note the 0xFF in the command is not read from at all, but is common in all Stop SeqPlayer Commands
+ */
+#define SEQCMD_STOP_SEQUENCE(seqPlayerIndex, fadeOutDuration) \
+ Audio_QueueSeqCmd((SEQCMD_OP_STOP_SEQUENCE << 28) | 0xFF | ((u8)(seqPlayerIndex) << 24) | \
+ ((u8)(fadeOutDuration) << 16))
+
+#define SEQCMD_STOP_SEQUENCE_ALT(seqPlayerIndex, fadeOutDuration) \
+ Audio_QueueSeqCmd((SEQCMD_OP_STOP_SEQUENCE << 28) | 0xFF | ((u8)(fadeOutDuration) << 16) | \
+ ((u8)(seqPlayerIndex) << 24))
+/**
+ * Add a sequence to a queue of sequences associated with a given seqPlayer.
+ * If the sequence is first in queue, play the sequence
+ *
+ * @param seqPlayerIndex the index of the seqPlayer to queue the sequence
+ * @param fadeInDuration if the sequence is played, duration the sequence will fade in over
+ * @param priority priority in the queue. The highest valued priority will be queued to play first. Also used as `seqArg`.
+ * @param seqId the id of the sequence to play, see `SeqId`
+ *
+ * @note for the next sequence in the queue to play, the current sequence must be unqueued with the unqueue command
+ * @note for a priority >= 0x7F, similar effects happen as `seqArg` in the play sequence command
+ */
+#define SEQCMD_QUEUE_SEQUENCE(seqPlayerIndex, fadeInDuration, priority, seqId) \
+ Audio_QueueSeqCmd((SEQCMD_OP_QUEUE_SEQUENCE << 28) | ((u8)(seqPlayerIndex) << 24) | ((u8)(fadeInDuration) << 16) | \
+ ((u8)(priority) << 8) | (u8)(seqId))
+
+/**
+ * Remove a sequence from a queue of sequences associated with a given seqPlayer.
+ * If the sequence is first in queue, stop the sequence, and play the next one in queue if any
+ *
+ * @param seqPlayerIndex the index of the seqPlayer to queue the sequence
+ * @param fadeInDuration if the sequence is stopped, duration the sequence will fade out over, and duration the next seq will fade in over
+ * @param seqId the id of the sequence to remove, see `SeqId`
+ *
+ * @note for the next sequence in the queue to play, the current sequence must be unqueued with this command
+ */
+#define SEQCMD_UNQUEUE_SEQUENCE(seqPlayerIndex, fadeOutInDuration, seqId) \
+ Audio_QueueSeqCmd((SEQCMD_OP_UNQUEUE_SEQUENCE << 28) | ((u8)(seqPlayerIndex) << 24) | \
+ ((u8)(fadeOutInDuration) << 16) | (seqId))
+
+/**
+ * Set the volume of an entire sequence on a given seqPlayer. Fade to the volume over a specified duration
+ *
+ * @param seqPlayerIndex the index of the seqPlayer to modify
+ * @param duration duration to transition to the volume
+ * @param volume the target volume for the sequence. Ranged from 0-0xFF, with 0x7F mapping to 1.0f
+ */
+#define SEQCMD_SET_SEQPLAYER_VOLUME(seqPlayerIndex, duration, volume) \
+ Audio_QueueSeqCmd((SEQCMD_OP_SET_SEQPLAYER_VOLUME << 28) | ((u8)(seqPlayerIndex) << 24) | ((duration) << 16) | \
+ (volume))
+
+/**
+ * Scale the frequency of every channel on a given seqPlayer over a specified duration.
+ *
+ * @param seqPlayerIndex the index of the seqPlayer to modify
+ * @param duration duration to transition to the frequency
+ * @param freqScale the scaling factor to shift the pitch. Ranged from 0-0xFFFF, with 1000 mapping to 1.0f
+ *
+ * @note 2000 will double the frequency (raise an octave), 500 will halve the frequency (lower an octave).
+ * Cannot be used with `SEQCMD_SET_CHANNEL_FREQ` as they will overwrite one another.
+ */
+#define SEQCMD_SET_SEQPLAYER_FREQ(seqPlayerIndex, duration, freqScale) \
+ Audio_QueueSeqCmd((SEQCMD_OP_SET_SEQPLAYER_FREQ << 28) | ((u8)(seqPlayerIndex) << 24) | ((duration) << 16) | \
+ (freqScale))
+
+/**
+ * Scale the frequency of a specific channel on a given seqPlayer over a specified duration
+ *
+ * @param seqPlayerIndex the index of the seqPlayer to modify
+ * @param channelIndex the index of the channel to modify
+ * @param duration duration to transition to the frequency
+ * @param freqScale the scaling factor to shift the pitch. Ranged from 0-0xFFF, with 1000 mapping to 1.0f
+ *
+ * @note a frequency of 2000 will double the frequency (raise an octave), 500 will halve the frequency (lower an octave).
+ * Cannot be used with `SEQCMD_SET_SEQPLAYER_FREQ` as they will overwrite one another.
+ */
+#define SEQCMD_SET_CHANNEL_FREQ(seqPlayerIndex, channelIndex, duration, freqScale) \
+ Audio_QueueSeqCmd((SEQCMD_OP_SET_CHANNEL_FREQ << 28) | ((u8)(seqPlayerIndex) << 24) | ((duration) << 16) | \
+ ((channelIndex) << 12) | (freqScale))
+
+/**
+ * Set the volume of a specific channel on a given seqPlayer. Fade to the volume over a specified duration
+ *
+ * @param seqPlayerIndex the index of the seqPlayer to modify
+ * @param channelIndex the index of the channel to modify
+ * @param duration duration to transition to the volume
+ * @param volume the target volume for the sequence. Ranged from 0-0xFF, with 0x7F mapping to 1.0f
+ */
+#define SEQCMD_SET_CHANNEL_VOLUME(seqPlayerIndex, channelIndex, duration, volume) \
+ Audio_QueueSeqCmd((SEQCMD_OP_SET_CHANNEL_VOLUME << 28) | ((u8)(seqPlayerIndex) << 24) | ((u8)(duration) << 16) | \
+ ((u8)(channelIndex) << 8) | ((u8)volume))
+
+/**
+ * Write a value that can be read as input directly by the sequence itself. This will be set to the global
+ * ioPort, which can affect the entire sequence.
+ *
+ * @param seqPlayerIndex the index of the seqPlayer to write the input to
+ * @param ioPort the index of the array to store the input-output value
+ * @param ioData the value s8 that's written to the input-output array
+ *
+ * @note Each seqPlayer has 8 global ioPorts indexed 0-7.
+ * ioPort 0 and 1 are read-only-once, and will reset after being read by the sequence.
+ * ioPort 2-7 can be read multiple times.
+ */
+#define SEQCMD_SET_SEQPLAYER_IO(seqPlayerIndex, ioPort, ioData) \
+ Audio_QueueSeqCmd((SEQCMD_OP_SET_SEQPLAYER_IO << 28) | ((u8)(seqPlayerIndex) << 24) | ((u8)(ioPort) << 16) | \
+ (u8)(ioData))
+
+/**
+ * Write a value that can be read as input directly by the sequence itself. This will be set to the channel
+ * ioPort, which will only affect a single channel.
+ *
+ * @param seqPlayerIndex the index of the seqPlayer to write the input to
+ * @param channelIndex the index of the channel to write the input to
+ * @param ioPort the index of the array to store the input-output value
+ * @param ioData the value s8 that's written to the input-output array
+ *
+ * @note Each channel has 8 channel ioPorts indexed 0-7.
+ * ioPort 0 and 1 are read-only-once, and will reset after being read by the sequence.
+ * ioPort 2-7 can be read multiple times.
+ */
+#define SEQCMD_SET_CHANNEL_IO(seqPlayerIndex, channelIndex, ioPort, ioData) \
+ Audio_QueueSeqCmd((SEQCMD_OP_SET_CHANNEL_IO << 28) | ((u8)(seqPlayerIndex) << 24) | ((u8)(ioPort) << 16) | \
+ ((u8)(channelIndex) << 8) | (u8)(ioData))
+
+/**
+ * Disable (or reenable) specific channels from receiving input set by `SEQCMD_SET_CHANNEL_IO`
+ *
+ * @param seqPlayerIndex the index of the seqPlayer to modify
+ * @param channelMask a 16 bit mask where each bit maps to a channel. Bitflag on to disable
+ *
+ * @note using AUDIOCMD_CHANNEL_SET_IO will bypass this channelMask
+ */
+#define SEQCMD_SET_CHANNEL_IO_DISABLE_MASK(seqPlayerIndex, channelMask) \
+ Audio_QueueSeqCmd((SEQCMD_OP_SET_CHANNEL_IO_DISABLE_MASK << 28) | ((u8)(seqPlayerIndex) << 24) | (u16)(channelMask))
+
+/**
+ * Disable (or reenable) specific channels
+ *
+ * @param seqPlayerIndex the index of the seqPlayer to modify
+ * @param channelMask a 16 bit mask where each bit maps to a channel. Bitflag on to disable
+ */
+#define SEQCMD_SET_CHANNEL_DISABLE_MASK(seqPlayerIndex, channelMask) \
+ Audio_QueueSeqCmd((SEQCMD_OP_SET_CHANNEL_DISABLE_MASK << 28) | ((u8)(seqPlayerIndex) << 24) | (u16)(channelMask))
+
+// ==== Audio Sequence Tempo Commands ====
+
+/**
+ * Set the absolute tempo of a sequence on a given seqPlayer, fading over a specified duration
+ *
+ * @param seqPlayerIndex the index of the seqPlayer to modify
+ * @param duration duration to transition to the tempo
+ * @param tempoTarget the target tempo for the sequence
+ *
+ * @note the absolute tempo is constrained to a maximum of 300
+ */
+#define SEQCMD_SET_TEMPO(seqPlayerIndex, duration, tempoTarget) \
+ Audio_QueueSeqCmd((SEQCMD_OP_TEMPO_CMD << 28) | (SEQCMD_SUB_OP_TEMPO_SET << 12) | ((u8)(seqPlayerIndex) << 24) | \
+ ((u8)(duration) << 16) | (u16)(tempoTarget))
+
+/**
+ * Increase the tempo of a sequence by a relative value on a given seqPlayer over a specified duration
+ *
+ * @param seqPlayerIndex the index of the seqPlayer to modify
+ * @param duration duration to transition to the tempo
+ * @param tempoIncrease the change to add to the current tempo
+ *
+ * @note the absolute tempo is constrained to a maximum of 300
+ */
+#define SEQCMD_SPEED_UP_TEMPO(seqPlayerIndex, duration, tempoIncrease) \
+ Audio_QueueSeqCmd((SEQCMD_OP_TEMPO_CMD << 28) | (SEQCMD_SUB_OP_TEMPO_SPEED_UP << 12) | \
+ ((u8)(seqPlayerIndex) << 24) | ((u8)(duration) << 16) | (u16)(tempoIncrease))
+
+/**
+ * Decrease the tempo of a sequence by a relative value on a given seqPlayer over a specified duration
+ *
+ * @param seqPlayerIndex the index of the seqPlayer to modify
+ * @param duration duration to transition to the tempo
+ * @param tempoDecrease the change to subtract to the current tempo
+ *
+ * @note the absolute tempo is constrained to a maximum of 300
+ */
+#define SEQCMD_SLOW_DOWN_TEMPO(seqPlayerIndex, duration, tempoDecrease) \
+ Audio_QueueSeqCmd((SEQCMD_OP_TEMPO_CMD << 28) | (SEQCMD_SUB_OP_TEMPO_SLOW_DOWN << 12) | \
+ ((u8)(seqPlayerIndex) << 24) | ((u8)(duration) << 16) | (u16)(tempoDecrease))
+
+/**
+ * Scale the tempo of a sequence by a multiplicative value on a given seqPlayer over a specified duration
+ *
+ * @param seqPlayerIndex the index of the seqPlayer to modify
+ * @param duration duration to transition to the tempo
+ * @param tempoScale the scaling factor of the tempo, relative to 100
+ *
+ * @note a tempoScale of 200 will go double-time, 50 will go half-time.
+ * the absolute tempo is constrained to a maximum of 300
+ */
+#define SEQCMD_SCALE_TEMPO(seqPlayerIndex, duration, tempoScale) \
+ Audio_QueueSeqCmd((SEQCMD_OP_TEMPO_CMD << 28) | (SEQCMD_SUB_OP_TEMPO_SCALE << 12) | ((u8)(seqPlayerIndex) << 24) | \
+ ((u8)(duration) << 16) | (u16)(tempoScale))
+
+/**
+ * Reset the tempo of a sequence to the original tempo on a given seqPlayer over a specified duration
+ *
+ * @param seqPlayerIndex the index of the seqPlayer to modify
+ * @param duration duration to transition to the tempo
+ */
+#define SEQCMD_RESET_TEMPO(seqPlayerIndex, duration) \
+ Audio_QueueSeqCmd((SEQCMD_OP_TEMPO_CMD << 28) | (SEQCMD_SUB_OP_TEMPO_RESET << 12) | ((u8)(seqPlayerIndex) << 24) | \
+ ((u8)(duration) << 16))
+
+/**
+ * ==== Audio Sequence Setup Commands ====
+ *
+ * The setup commands are designed to wait to be executed.
+ * Up to 8 commands can be queued per `seqPlayerIndex`.
+ * These commands will only execute once that `seqPlayerIndex` is finished playing and is no longer enabled.
+ * They will often target a different player (`targetSeqPlayerIndex`) but not always.
+ */
+
+/**
+ * Setup a request to restore a volume on target seqPlayer once a setup seqPlayer is finished playing and disabled
+ *
+ * @param setupSeqPlayerIndex the index of the seqPlayer to wait for to be disabled
+ * @param targetSeqPlayerIndex the index of the seqPlayer to modify
+ * @param duration duration to transition to the volume
+ */
+#define SEQCMD_SETUP_RESTORE_SEQPLAYER_VOLUME(setupSeqPlayerIndex, targetSeqPlayerIndex, duration) \
+ Audio_QueueSeqCmd((SEQCMD_OP_SETUP_CMD << 28) | (SEQCMD_SUB_OP_SETUP_RESTORE_SEQPLAYER_VOLUME << 20) | \
+ ((u8)(setupSeqPlayerIndex) << 24) | ((u8)(targetSeqPlayerIndex) << 16) | ((u8)(duration) << 8))
+
+/**
+ * Setup a request to unqueue a seqPlayer once that same setup seqPlayer is finished playing and disabled
+ *
+ * @param setupSeqPlayerIndex the index of the seqPlayer to unqueue once the same seqPlayer is disabled
+ *
+ * @bug this command was misimplemented and fails to unqueue. The command relies on `gActiveSeqs.seqId` for
+ * unqueueing, but seqId is reset before being used to unqueue. A simple fix is to unqueue based on
+ * `gActiveSeqs.prevSeqId` instead.
+ */
+#define SEQCMD_SETUP_UNQUEUE_SEQUENCE(setupSeqPlayerIndex) \
+ Audio_QueueSeqCmd((SEQCMD_OP_SETUP_CMD << 28) | (SEQCMD_SUB_OP_SETUP_SEQ_UNQUEUE << 20) | \
+ ((u8)(setupSeqPlayerIndex) << 24))
+
+/**
+ * Setup a request to restart and play an active sequence currently playing on a target seqPlayer
+ * once a setup seqPlayer is finished playing and disabled
+ *
+ * @param setupSeqPlayerIndex the index of the seqPlayer to wait for to be disabled
+ * @param targetSeqPlayerIndex the index of the seqPlayer to restart its active sequence
+ */
+#define SEQCMD_SETUP_RESTART_SEQUENCE(setupSeqPlayerIndex, targetSeqPlayerIndex) \
+ Audio_QueueSeqCmd((SEQCMD_OP_SETUP_CMD << 28) | (SEQCMD_SUB_OP_SETUP_RESTART_SEQ << 20) | \
+ ((u8)(setupSeqPlayerIndex) << 24) | ((u8)(targetSeqPlayerIndex) << 16))
+
+/**
+ * Setup a request to scale the tempo of a sequence by a multiplicative value on a target seqPlayer
+ * once a setup seqPlayer is finished playing and disabled
+ *
+ * @param setupSeqPlayerIndex the index of the seqPlayer to wait for to be disabled
+ * @param targetSeqPlayerIndex the index of the seqPlayer to modify
+ * @param duration duration to transition to the tempo
+ * @param tempoScale the scaling factor of the tempo, relative to 100
+ *
+ * @note a tempoScale of 200 will go double-time, 50 will go half-time.
+ * the absolute tempo is constrained to a maximum of 300
+ */
+#define SEQCMD_SETUP_SCALE_TEMPO(setupSeqPlayerIndex, targetSeqPlayerIndex, duration, tempoScale) \
+ Audio_QueueSeqCmd((SEQCMD_OP_SETUP_CMD << 28) | (SEQCMD_SUB_OP_SETUP_TEMPO_SCALE << 20) | \
+ ((u8)(setupSeqPlayerIndex) << 24) | ((u8)(targetSeqPlayerIndex) << 16) | ((u8)(duration) << 8) | \
+ (u8)(tempoScale))
+
+/**
+ * Setup a request to reset the tempo of a sequence to the original tempo on a target seqPlayer
+ * once a setup seqPlayer is finished playing and disabled
+ *
+ * @param setupSeqPlayerIndex the index of the seqPlayer to wait for to be disabled
+ * @param targetSeqPlayerIndex the index of the seqPlayer to modify
+ * @param duration duration to transition to the tempo
+ */
+#define SEQCMD_SETUP_RESET_TEMPO(setupSeqPlayerIndex, targetSeqPlayerIndex, duration) \
+ Audio_QueueSeqCmd((SEQCMD_OP_SETUP_CMD << 28) | (SEQCMD_SUB_OP_SETUP_TEMPO_RESET << 20) | \
+ ((u8)(setupSeqPlayerIndex) << 24) | ((u8)(targetSeqPlayerIndex) << 16) | (u8)(duration))
+
+/**
+ * Setup a request to play a sequence on a target seqPlayer once a setup seqPlayer is finished playing and disabled.
+ * This command is optionally paired with `SEQCMD_SETUP_SET_FADE_IN_TIMER` to set the fade in duration
+ *
+ * @param setupSeqPlayerIndex the index of the seqPlayer to wait for to be disabled
+ * @param targetSeqPlayerIndex the index of the seqPlayer to play the sequence
+ * @param seqId the id of the sequence to play, see `SeqId`
+ */
+#define SEQCMD_SETUP_PLAY_SEQUENCE(setupSeqPlayerIndex, targetSeqPlayerIndex, seqId) \
+ Audio_QueueSeqCmd((SEQCMD_OP_SETUP_CMD << 28) | (SEQCMD_SUB_OP_SETUP_PLAY_SEQ << 20) | \
+ ((u8)(setupSeqPlayerIndex) << 24) | ((u8)(targetSeqPlayerIndex) << 16) | (u16)(seqId))
+
+/**
+ * This command is an optional command before `SEQCMD_SETUP_PLAY_SEQUENCE` to set the fade in duration
+ * (see cmd above)
+ *
+ * @param targetSeqPlayerIndex the index of the seqPlayer to play the sequence
+ * @param fadeInDuration duration the sequence will fade in over
+ */
+#define SEQCMD_SETUP_SET_FADE_IN_TIMER(targetSeqPlayerIndex, fadeInDuration) \
+ Audio_QueueSeqCmd((SEQCMD_OP_SETUP_CMD << 28) | (SEQCMD_SUB_OP_SETUP_SET_FADE_TIMER << 20) | \
+ ((u8)(targetSeqPlayerIndex) << 24) | ((u8)(fadeInDuration) << 8))
+
+/**
+ * Setup a request to restore a volume on target seqPlayer once a setup seqPlayer is finished playing and disabled.
+ * Specifically, it will only restore volume if the number of queued requests on the setup seqPlayer matches
+ * the number of sequences queued
+ *
+ * @param setupSeqPlayerIndex the index of the seqPlayer to wait for to be disabled
+ * @param targetSeqPlayerIndex the index of the seqPlayer to modify
+ * @param duration duration to transition to the volume
+ * @param numSeqRequests the number of sequence requests queued that must match the actual number of sequence requests
+ */
+#define SEQCMD_SETUP_RESTORE_SEQPLAYER_VOLUME_IF_QUEUED(setupSeqPlayerIndex, targetSeqPlayerIndex, duration, \
+ numSeqRequests) \
+ Audio_QueueSeqCmd((SEQCMD_OP_SETUP_CMD << 28) | (SEQCMD_SUB_OP_SETUP_RESTORE_SEQPLAYER_VOLUME_IF_QUEUED << 20) | \
+ ((u8)(setupSeqPlayerIndex) << 24) | ((u8)(targetSeqPlayerIndex) << 16) | ((u8)(duration) << 8) | \
+ (u8)(numSeqRequests))
+
+/**
+ * Setup a request to restore a volume on target seqPlayer once a setup seqPlayer is finished playing and disabled.
+ * Allows `scaleIndex` to be specified.
+ *
+ * @param setupSeqPlayerIndex the index of the seqPlayer to wait for to be disabled
+ * @param targetSeqPlayerIndex the index of the seqPlayer to modify
+ * @param scaleIndex the scale index of a seqPlayer
+ * @param duration duration to transition to the volume
+ */
+#define SEQCMD_SETUP_RESTORE_SEQPLAYER_VOLUME_WITH_SCALE_INDEX(setupSeqPlayerIndex, targetSeqPlayerIndex, scaleIndex, \
+ duration) \
+ Audio_QueueSeqCmd((SEQCMD_OP_SETUP_CMD << 28) | \
+ (SEQCMD_SUB_OP_SETUP_RESTORE_SEQPLAYER_VOLUME_WITH_SCALE_INDEX << 20) | \
+ ((u8)(setupSeqPlayerIndex) << 24) | ((u8)(targetSeqPlayerIndex) << 16) | \
+ ((u8)(scaleIndex) << 8) | (u8)(duration))
+
+/**
+ * Setup a request to disable (or reenable) specific channels on a target seqPlayer
+ * once a setup seqPlayer is finished playing and disabled.
+ *
+ * @param setupSeqPlayerIndex the index of the seqPlayer to wait for to be disabled
+ * @param targetSeqPlayerIndex the index of the seqPlayer to modify
+ * @param channelMask a 16 bit mask where each bit maps to a channel. Bitflag on to disable
+ */
+#define SEQCMD_SETUP_SET_CHANNEL_DISABLE_MASK(setupSeqPlayerIndex, targetSeqPlayerIndex, channelMask) \
+ Audio_QueueSeqCmd((SEQCMD_OP_SETUP_CMD << 28) | (SEQCMD_SUB_OP_SETUP_SET_CHANNEL_DISABLE_MASK << 20) | \
+ ((u8)(setupSeqPlayerIndex) << 24) | ((u8)(targetSeqPlayerIndex) << 16) | (u16)(channelMask))
+
+/**
+ * Queue a request to scale the frequency of an entire sequence on a target seqPlayer
+ * once a setup seqPlayer is finished playing and disabled.
+ *
+ * @param setupSeqPlayerIndex the index of the seqPlayer to wait for to be disabled
+ * @param targetSeqPlayerIndex the index of the seqPlayer to modify
+ * @param duration duration to transition to the frequency
+ * @param freqScale the scaling factor to shift the pitch. Ranged from 0-0xFF, with 100 mapping to 1.0f
+ *
+ * @note The base value for frequency, 100, is 10 times smaller than other frequency commands.
+ * 200 will double the frequency (raise an octave), 50 will halve the frequency (lower an octave).
+ */
+#define SEQCMD_SETUP_SET_SEQPLAYER_FREQ(setupSeqPlayerIndex, targetSeqPlayerIndex, duration, freqScale) \
+ Audio_QueueSeqCmd((SEQCMD_OP_SETUP_CMD << 28) | (SEQCMD_SUB_OP_SETUP_SET_SEQPLAYER_FREQ << 20) | \
+ ((u8)(setupSeqPlayerIndex) << 24) | ((u8)(targetSeqPlayerIndex) << 16) | ((u8)(duration) << 8) | \
+ (u8)(freqScale))
+
+/**
+ * Queue a request to discard audio data by popping an entry from the persistent caches on the audio heap,
+ * once a setup seqPlayer is finished playing and disabled.
+ *
+ * @param setupSeqPlayerIndex the index of the seqPlayer to wait for to be disabled
+ * @param tableTypeFlag All tables with the flag `(tableTypeFlag & (1 << tableType))` will be discarded. Specifically:
+ * `(tableTypeFlag & 1)` will discard the `SEQUENCE_TABLE`
+ * `(tableTypeFlag & 2)` will discard the `FONT_TABLE`
+ * `(tableTypeFlag & 4)` will discard the `SAMPLE_TABLE`
+ */
+#define SEQCMD_SETUP_POP_PERSISTENT_CACHE(setupSeqPlayerIndex, tableTypeFlag) \
+ Audio_QueueSeqCmd((SEQCMD_OP_SETUP_CMD << 28) | (SEQCMD_SUB_OP_SETUP_POP_PERSISTENT_CACHE << 20) | \
+ ((u8)(setupSeqPlayerIndex) << 24) | ((u8)tableTypeFlag))
+
+/**
+ * Discard all setup command requests on a seqPlayerIndex by resetting the setup command queue
+ *
+ * @param setupSeqPlayerIndex the index of the seqPlayer to disable all setup commands
+ */
+#define SEQCMD_RESET_SETUP_CMDS(setupSeqPlayerIndex) \
+ Audio_QueueSeqCmd((SEQCMD_OP_SETUP_CMD << 28) | (SEQCMD_SUB_OP_SETUP_RESET_SETUP_CMDS << 20) | \
+ ((u8)(setupSeqPlayerIndex) << 24))
+
+/**
+ * ==== Audio Sequence Global Commands ====
+ *
+ * The global commands will apply to the entire audio system and all 4 sequence players
+ */
+
+/**
+ * Change the sound mode of audio
+ *
+ * @param soundMode see the `SoundMode` enum
+ */
+#define SEQCMD_SET_SOUND_MODE(soundMode) \
+ Audio_QueueSeqCmd((SEQCMD_OP_GLOBAL_CMD << 28) | (SEQCMD_SUB_OP_GLOBAL_SET_SOUND_MODE << 8) | (u8)(soundMode))
+
+/**
+ * Disable (or reenable) new sequences from starting
+ *
+ * @param isDisabled true to disable, false to enable
+ *
+ * @note this does not disable the sfx player
+ */
+#define SEQCMD_DISABLE_PLAY_SEQUENCES(isDisabled) \
+ Audio_QueueSeqCmd((SEQCMD_OP_GLOBAL_CMD << 28) | (SEQCMD_SUB_OP_GLOBAL_DISABLE_NEW_SEQUENCES << 8) | \
+ (u16)(isDisabled))
+
+/**
+ * Restart the audio heap with the specified settings
+ *
+ * @param sfxChannelLayout index for different mappings between the 7 banks and the 16 channels
+ * @param specId index for the audio specifications to set high-level audio parameters
+ *
+ * @note: For sfxChannelLayout, There are 4 possible layouts indexed by 0-3.
+ * However, only index 0 is properly implemented. Other indices lead to bugs and softlocks.
+ */
+#define SEQCMD_RESET_AUDIO_HEAP(sfxChannelLayout, specId) \
+ Audio_QueueSeqCmd((SEQCMD_OP_RESET_AUDIO_HEAP << 28) | ((u8)(sfxChannelLayout) << 8) | (u8)(specId))
+
+#endif
diff --git a/include/audiothread_cmd.h b/include/audiothread_cmd.h
new file mode 100644
index 00000000..123af3aa
--- /dev/null
+++ b/include/audiothread_cmd.h
@@ -0,0 +1,543 @@
+#ifndef AUDIOTHREAD_CMD_H
+#define AUDIOTHREAD_CMD_H
+
+
+void AudioThread_QueueCmd(u32, void**);
+void AudioThread_QueueCmdF32(u32, f32);
+void AudioThread_QueueCmdS32(u32, u32);
+void AudioThread_QueueCmdS8(u32, s8);
+
+/**
+ * Audio thread commands to safely transfer information/requests/data
+ * from the external graph thread to the internal audio thread
+ */
+
+typedef enum {
+ // Channel Commands
+ /* 0x00 */ AUDIOCMD_OP_NOOP,
+ /* 0x01 */ AUDIOCMD_OP_CHANNEL_SET_VOL_SCALE,
+ /* 0x02 */ AUDIOCMD_OP_CHANNEL_SET_VOL,
+ /* 0x03 */ AUDIOCMD_OP_CHANNEL_SET_PAN,
+ /* 0x04 */ AUDIOCMD_OP_CHANNEL_SET_FREQ_SCALE,
+ /* 0x05 */ AUDIOCMD_OP_CHANNEL_SET_REVERB_VOLUME,
+ /* 0x06 */ AUDIOCMD_OP_CHANNEL_SET_IO,
+ /* 0x07 */ AUDIOCMD_OP_CHANNEL_SET_PAN_WEIGHT,
+ /* 0x08 */ AUDIOCMD_OP_CHANNEL_SET_MUTE,
+ /* 0x09 */ AUDIOCMD_OP_CHANNEL_SET_MUTE_BEHAVIOR,
+ /* 0x0A */ AUDIOCMD_OP_CHANNEL_SET_VIBRATO_DEPTH,
+ /* 0x0B */ AUDIOCMD_OP_CHANNEL_SET_VIBRATO_RATE,
+ /* 0x0C */ AUDIOCMD_OP_CHANNEL_SET_COMB_FILTER_SIZE,
+ /* 0x0D */ AUDIOCMD_OP_CHANNEL_SET_COMB_FILTER_GAIN,
+ /* 0x0E */ AUDIOCMD_OP_CHANNEL_SET_STEREO,
+ // SeqPlayer Commands
+ /* 0x41 */ AUDIOCMD_OP_SEQPLAYER_FADE_VOLUME_SCALE = 0x41,
+ /* 0x46 */ AUDIOCMD_OP_SEQPLAYER_SET_IO = 0x46,
+ /* 0x47 */ AUDIOCMD_OP_SEQPLAYER_SET_TEMPO,
+ /* 0x48 */ AUDIOCMD_OP_SEQPLAYER_SET_TRANSPOSITION,
+ /* 0x49 */ AUDIOCMD_OP_SEQPLAYER_CHANGE_TEMPO,
+ /* 0x4A */ AUDIOCMD_OP_SEQPLAYER_FADE_TO_SET_VOLUME,
+ /* 0x4B */ AUDIOCMD_OP_SEQPLAYER_FADE_TO_SCALED_VOLUME,
+ /* 0x4C */ AUDIOCMD_OP_SEQPLAYER_RESET_VOLUME,
+ /* 0x4D */ AUDIOCMD_OP_SEQPLAYER_SET_BEND,
+ /* 0x4E */ AUDIOCMD_OP_SEQPLAYER_CHANGE_TEMPO_SEQTICKS,
+ // Global Commands
+ /* 0x81 */ AUDIOCMD_OP_GLOBAL_SYNC_LOAD_SEQ_PARTS = 0x81,
+ /* 0x82 */ AUDIOCMD_OP_GLOBAL_INIT_SEQPLAYER,
+ /* 0x83 */ AUDIOCMD_OP_GLOBAL_DISABLE_SEQPLAYER,
+ /* 0x85 */ AUDIOCMD_OP_GLOBAL_INIT_SEQPLAYER_SKIP_TICKS = 0x85,
+ /* 0x90 */ AUDIOCMD_OP_GLOBAL_SET_CHANNEL_MASK = 0x90,
+ /* 0xE0 */ AUDIOCMD_OP_GLOBAL_SET_DRUM_FONT = 0xE0,
+ /* 0xE1 */ AUDIOCMD_OP_GLOBAL_SET_SFX_FONT,
+ /* 0xE2 */ AUDIOCMD_OP_GLOBAL_SET_INSTRUMENT_FONT,
+ /* 0xE3 */ AUDIOCMD_OP_GLOBAL_POP_PERSISTENT_CACHE,
+ /* 0xF0 */ AUDIOCMD_OP_GLOBAL_SET_SOUND_MODE = 0xF0,
+ /* 0xF1 */ AUDIOCMD_OP_GLOBAL_MUTE,
+ /* 0xF2 */ AUDIOCMD_OP_GLOBAL_UNMUTE,
+ /* 0xF3 */ AUDIOCMD_OP_GLOBAL_SYNC_LOAD_INSTRUMENT,
+ /* 0xF4 */ AUDIOCMD_OP_GLOBAL_ASYNC_LOAD_SAMPLE_BANK,
+ /* 0xF5 */ AUDIOCMD_OP_GLOBAL_ASYNC_LOAD_FONT,
+ /* 0xF6 */ AUDIOCMD_OP_GLOBAL_DISCARD_SEQ_FONTS,
+ /* 0xF8 */ AUDIOCMD_OP_GLOBAL_STOP_AUDIOCMDS = 0xF8,
+ /* 0xF9 */ AUDIOCMD_OP_GLOBAL_RESET_AUDIO_HEAP,
+ /* 0xFA */ AUDIOCMD_OP_GLOBAL_NOOP_1, // used but no code exists for it
+ /* 0xFB */ AUDIOCMD_OP_GLOBAL_SET_CUSTOM_UPDATE_FUNCTION,
+ /* 0xFC */ AUDIOCMD_OP_GLOBAL_ASYNC_LOAD_SEQ,
+ /* 0xFD */ AUDIOCMD_OP_GLOBAL_NOOP_2, // used but no code exists for it
+ /* 0xFE */ AUDIOCMD_OP_GLOBAL_DISABLE_ALL_SEQPLAYERS
+} AudioThreadCmdOp;
+
+// Pass to a AUDIOCMD_CHANNEL_ command in place of a channelIndex to try and apply to all channels.
+// Then uses `threadCmdChannelMask` to determine which channels to apply the command to.
+#define AUDIOCMD_ALL_CHANNELS 0xFF
+
+// ==== Audio Thread Channel Commands ====
+
+/**
+ * Set the volumeMod on a given channel
+ *
+ * @param seqPlayerIndex the index of the seqPlayer to modify
+ * @param channelIndex the index of the channel to modify
+ * @param volumeMod (f32) the volume scale for the sequence. No change in volume is 1.0f
+ */
+#define AUDIOCMD_CHANNEL_SET_VOL_SCALE(seqPlayerIndex, channelIndex, volumeMod) \
+ AudioThread_QueueCmdF32(AUDIO_MK_CMD(AUDIOCMD_OP_CHANNEL_SET_VOL_SCALE, seqPlayerIndex, channelIndex, 0), \
+ volumeMod)
+
+/**
+ * Set the volume on a given channel
+ *
+ * @param seqPlayerIndex the index of the seqPlayer to modify
+ * @param channelIndex the index of the channel to modify
+ * @param volume (f32) the target volume for the sequence. Default volume is 1.0f
+ */
+#define AUDIOCMD_CHANNEL_SET_VOL(seqPlayerIndex, channelIndex, volume) \
+ AudioThread_QueueCmdF32(AUDIO_MK_CMD(AUDIOCMD_OP_CHANNEL_SET_VOL, seqPlayerIndex, channelIndex, 0), volume)
+
+/**
+ * Set the pan
+ *
+ * @param seqPlayerIndex the index of the seqPlayer to modify
+ * @param channelIndex the index of the channel to modify
+ * @param pan (s8) the pan applied to the channel
+ */
+#define AUDIOCMD_CHANNEL_SET_PAN(seqPlayerIndex, channelIndex, pan) \
+ AudioThread_QueueCmdS8(AUDIO_MK_CMD(AUDIOCMD_OP_CHANNEL_SET_PAN, seqPlayerIndex, channelIndex, 0), pan)
+
+/**
+ * Set frequency scale
+ *
+ * @param seqPlayerIndex the index of the seqPlayer to modify
+ * @param channelIndex the index of the channel to modify
+ * @param freqMod (f32) the scaling factor to shift the pitch.
+ */
+#define AUDIOCMD_CHANNEL_SET_FREQ_SCALE(seqPlayerIndex, channelIndex, freqMod) \
+ AudioThread_QueueCmdF32(AUDIO_MK_CMD(AUDIOCMD_OP_CHANNEL_SET_FREQ_SCALE, seqPlayerIndex, channelIndex, 0), \
+ freqMod)
+
+/**
+ * Set reverb volume
+ *
+ * @param seqPlayerIndex the index of the seqPlayer to modify
+ * @param channelIndex the index of the channel to modify
+ * @param reverbVolume (s8) volume to set the reverb to (dry/wet mix)
+ */
+#define AUDIOCMD_CHANNEL_SET_REVERB_VOLUME(seqPlayerIndex, channelIndex, reverbVolume) \
+ AudioThread_QueueCmdS8(AUDIO_MK_CMD(AUDIOCMD_OP_CHANNEL_SET_REVERB_VOLUME, seqPlayerIndex, channelIndex, 0), \
+ reverbVolume)
+
+/**
+ * Write a value that can be read as input directly by the sequence itself. This will be set to the channel
+ * ioPort, which will only affect a single channel
+ *
+ * @param seqPlayerIndex the index of the seqPlayer to write the input to
+ * @param channelIndex the index of the channel to write the input to
+ * @param ioPort the index of the array to store the input-output value
+ * @param ioData (s8) the value that's written to the input-output array
+ */
+#define AUDIOCMD_CHANNEL_SET_IO(seqPlayerIndex, channelIndex, ioPort, ioData) \
+ AudioThread_QueueCmdS8(AUDIO_MK_CMD(AUDIOCMD_OP_CHANNEL_SET_IO, (seqPlayerIndex), (channelIndex), (ioPort)), \
+ (ioData))
+
+/**
+ * Set the proportion of pan that comes from the channel
+ *
+ * @param seqPlayerIndex the index of the seqPlayer to modify
+ * @param channelIndex the index of the channel to modify
+ * @param panChannelWeight (s8) proportion of pan that comes from the channel.
+ * Set to 0 for layer-only, and 128 for channel-only.
+ * As the type used is `s8` and internally cast to u8 later,
+ * pass `-128` to produce 128, or just use 127 instead
+ */
+#define AUDIOCMD_CHANNEL_SET_PAN_WEIGHT(seqPlayerIndex, channelIndex, panChannelWeight) \
+ AudioThread_QueueCmdS8(AUDIO_MK_CMD(AUDIOCMD_OP_CHANNEL_SET_PAN_WEIGHT, seqPlayerIndex, channelIndex, 0), \
+ panChannelWeight)
+
+/**
+ * Mute a specified channel. How a muted channel behaves will depend on channel mute flags
+ *
+ * @param seqPlayerIndex the index of the seqPlayer to modify
+ * @param channelIndex the index of the channel to modify
+ * @param muted (s8) set true to mute
+ */
+#define AUDIOCMD_CHANNEL_SET_MUTE(seqPlayerIndex, channelIndex, muted) \
+ AudioThread_QueueCmdS8(AUDIO_MK_CMD(AUDIOCMD_OP_CHANNEL_SET_MUTE, seqPlayerIndex, channelIndex, 0), muted)
+
+/**
+ * Set the muteBehavior for a specified channel
+ *
+ * @param seqPlayerIndex the index of the seqPlayer to modify
+ * @param channelIndex the index of the channel to modify
+ * @param muteBehavior (s8) Affected how a muted channel behaves. See `MUTE_BEHAVIOR_` macros
+ */
+#define AUDIOCMD_CHANNEL_SET_MUTE_BEHAVIOR(seqPlayerIndex, channelIndex, muteBehavior) \
+ AudioThread_QueueCmdS8(AUDIO_MK_CMD(AUDIOCMD_OP_CHANNEL_SET_MUTE_BEHAVIOR, seqPlayerIndex, channelIndex, 0), \
+ muteBehavior)
+
+/**
+ * Set the vibrato depth (also called magnitude/amplitude/extent)
+ *
+ * @param seqPlayerIndex the index of the seqPlayer to modify
+ * @param channelIndex the index of the channel to modify
+ * @param vibratoDepthTarget (s8) the vibrato depth scaled down by 1/8th
+ */
+#define AUDIOCMD_CHANNEL_SET_VIBRATO_DEPTH(seqPlayerIndex, channelIndex, vibratoDepthTarget) \
+ AudioThread_QueueCmdS8(AUDIO_MK_CMD(AUDIOCMD_OP_CHANNEL_SET_VIBRATO_DEPTH, seqPlayerIndex, channelIndex, 0), \
+ vibratoDepthTarget)
+
+/**
+ * Set the vibrato rate (freq/pitch)
+ *
+ * @param seqPlayerIndex the index of the seqPlayer to modify
+ * @param channelIndex the index of the channel to modify
+ * @param vibratoRateTarget (s8) the vibrato rate scaled down by 1/32nd
+ */
+#define AUDIOCMD_CHANNEL_SET_VIBRATO_RATE(seqPlayerIndex, channelIndex, vibratoRateTarget) \
+ AudioThread_QueueCmdS8(AUDIO_MK_CMD(AUDIOCMD_OP_CHANNEL_SET_VIBRATO_RATE, seqPlayerIndex, channelIndex, 0), \
+ vibratoRateTarget)
+
+/**
+ * Set the comb filter size
+ *
+ * @param seqPlayerIndex the index of the seqPlayer to modify
+ * @param channelIndex the index of the channel to modify
+ * @param combFilterSize (s8) delay number of sample bytes to offset and add back to itself
+ */
+#define AUDIOCMD_CHANNEL_SET_COMB_FILTER_SIZE(seqPlayerIndex, channelIndex, combFilterSize) \
+ AudioThread_QueueCmdS8(AUDIO_MK_CMD(AUDIOCMD_OP_CHANNEL_SET_COMB_FILTER_SIZE, seqPlayerIndex, channelIndex, 0), \
+ combFilterSize)
+
+/**
+ * Set the comb filter gain
+ *
+ * @param seqPlayerIndex the index of the seqPlayer to modify
+ * @param channelIndex the index of the channel to modify
+ * @param combFilterGain (u16) strength of the signal added back to itself
+ */
+#define AUDIOCMD_CHANNEL_SET_COMB_FILTER_GAIN(seqPlayerIndex, channelIndex, combFilterGain) \
+ AudioThread_QueueCmdU16(AUDIO_MK_CMD(AUDIOCMD_OP_CHANNEL_SET_COMB_FILTER_GAIN, seqPlayerIndex, channelIndex, 0), \
+ combFilterGain)
+
+/**
+ * Set the stereo bits
+ *
+ * @param seqPlayerIndex the index of the seqPlayer to modify
+ * @param channelIndex the index of the channel to modify
+ * @param stereoData (s8) bit-packed stereo information. See `StereoData`
+ */
+#define AUDIOCMD_CHANNEL_SET_STEREO(seqPlayerIndex, channelIndex, stereoData) \
+ AudioThread_QueueCmdS8(AUDIO_MK_CMD(AUDIOCMD_OP_CHANNEL_SET_STEREO, seqPlayerIndex, channelIndex, 0), stereoData)
+
+// ==== Audio Thread SeqPlayer Commands ====
+
+/**
+ * Set the fade volume scale
+ *
+ * @param seqPlayerIndex the index of the seqPlayer to modify
+ * @param fadeVolumeMod (f32) multiplicative scaling factor to apply to volume
+ */
+#define AUDIOCMD_SEQPLAYER_FADE_VOLUME_SCALE(seqPlayerIndex, fadeVolumeMod) \
+ AudioThread_QueueCmdF32(AUDIO_MK_CMD(AUDIOCMD_OP_SEQPLAYER_FADE_VOLUME_SCALE, seqPlayerIndex, 0, 0), \
+ fadeVolumeMod)
+
+/**
+ * Write a value that can be read as input directly by the sequence itself. This will be set to the global
+ * ioPort, which can affect the entire sequence
+ *
+ * @param seqPlayerIndex the index of the seqPlayer to write the input to
+ * @param ioPort the index of the array to store the input-output value
+ * @param ioData (s8) the value that's written to the input-output array
+ */
+#define AUDIOCMD_SEQPLAYER_SET_IO(seqPlayerIndex, unk, ioPort, ioData) \
+ AudioThread_QueueCmdS8(AUDIO_MK_CMD(AUDIOCMD_OP_SEQPLAYER_SET_IO, seqPlayerIndex, unk, ioPort), ioData)
+
+/**
+ * Set the tempo (bpm) of a sequence on a given seqPlayer
+ *
+ * @param seqPlayerIndex the index of the seqPlayer to modify
+ * @param tempo (s32) the tempo for the sequence, in bpm
+ */
+#define AUDIOCMD_SEQPLAYER_SET_TEMPO(seqPlayerIndex, tempo) \
+ AudioThread_QueueCmdS32(AUDIO_MK_CMD(AUDIOCMD_OP_SEQPLAYER_SET_TEMPO, seqPlayerIndex, 0, 0), tempo)
+
+/**
+ * Set the transposition
+ *
+ * @param seqPlayerIndex the index of the seqPlayer to modify
+ * @param transposition (s8) the number of semitones to increase or decrease by for all notes on the seqPlayer
+ */
+#define AUDIOCMD_SEQPLAYER_SET_TRANSPOSITION(seqPlayerIndex, transposition) \
+ AudioThread_QueueCmdS8(AUDIO_MK_CMD(AUDIOCMD_OP_SEQPLAYER_SET_TRANSPOSITION, seqPlayerIndex, 0, 0), transposition)
+
+/**
+ * Set tempoChange in bpm
+ *
+ * @param seqPlayerIndex the index of the seqPlayer to modify
+ * @param tempoChange (s32) difference in tempo to change, in bpm
+ */
+#define AUDIOCMD_SEQPLAYER_CHANGE_TEMPO(seqPlayerIndex, tempoChange) \
+ AudioThread_QueueCmdS32(AUDIO_MK_CMD(AUDIOCMD_OP_SEQPLAYER_CHANGE_TEMPO, seqPlayerIndex, 0, 0), tempoChange)
+
+/**
+ * Set tempoChange in seqTicks per minute
+ *
+ * @param seqPlayerIndex the index of the seqPlayer to modify
+ * @param tempoChange (s32) difference in tempo to change, in seqTicks per minute
+ */
+#define AUDIOCMD_SEQPLAYER_CHANGE_TEMPO_SEQTICKS(seqPlayerIndex, tempoChange) \
+ AudioThread_QueueCmdS32(AUDIO_MK_CMD(AUDIOCMD_OP_SEQPLAYER_CHANGE_TEMPO_SEQTICKS, seqPlayerIndex, 0, 0), tempoChange)
+
+/**
+ * Fade the volume to the target volume requested in the command
+ *
+ * @param seqPlayerIndex the index of the seqPlayer to modify
+ * @param fadeVolume target volume to fade to
+ * @param fadeTimer (s32) number of ticks to fade to `fadeVolume`
+ */
+#define AUDIOCMD_SEQPLAYER_FADE_TO_SET_VOLUME(seqPlayerIndex, fadeVolume, fadeTimer) \
+ AudioThread_QueueCmdS32(AUDIO_MK_CMD(AUDIOCMD_OP_SEQPLAYER_FADE_TO_SET_VOLUME, seqPlayerIndex, fadeVolume, 0), \
+ fadeTimer)
+
+/**
+ * Fade the volume to the current volume scaled by a scale factor
+ *
+ * @param seqPlayerIndex the index of the seqPlayer to modify
+ * @param fadeVolumeMod scaling factor to apply to volume to get the targetVolume
+ * @param fadeTimer (s32) number of ticks to fade to `targetVolume`
+ */
+#define AUDIOCMD_SEQPLAYER_FADE_TO_SCALED_VOLUME(seqPlayerIndex, fadeVolumeMod, fadeTimer) \
+ AudioThread_QueueCmdS32( \
+ AUDIO_MK_CMD(AUDIOCMD_OP_SEQPLAYER_FADE_TO_SCALED_VOLUME, seqPlayerIndex, fadeVolumeMod, 0), fadeTimer)
+
+/**
+ * Reset to the default volume of the seqPlayer
+ *
+ * @param seqPlayerIndex the index of the seqPlayer to modify
+ * @param fadeTimer (s32) number of ticks to fade the sequence back to its default volume
+ */
+#define AUDIOCMD_SEQPLAYER_RESET_VOLUME(seqPlayerIndex, fadeTimer) \
+ AudioThread_QueueCmdS32(AUDIO_MK_CMD(AUDIOCMD_OP_SEQPLAYER_RESET_VOLUME, seqPlayerIndex, 0, 0), fadeTimer)
+
+/**
+ * Set the bend
+ *
+ * @param seqPlayerIndex the index of the seqPlayer to modify
+ * @param bend (f32) ratio relative to 1.0f to scale channel frequencies by
+ */
+#define AUDIOCMD_SEQPLAYER_SET_BEND(seqPlayerIndex, bend) \
+ AudioThread_QueueCmdF32(AUDIO_MK_CMD(AUDIOCMD_OP_SEQPLAYER_SET_BEND, seqPlayerIndex, 0, 0), bend)
+
+// ==== Audio Thread Global Commands ====
+
+/**
+ * Synchronously load a sequence in parts
+ *
+ * @param seqId the id of the sequence to load, see `SeqId`
+ * @param flags set `& 1` to load the sequence, set `& 2` to load the soundfonts
+ */
+#define AUDIOCMD_GLOBAL_SYNC_LOAD_SEQ_PARTS(seqId, flags) \
+ AudioThread_QueueCmdS32(AUDIO_MK_CMD(AUDIOCMD_OP_GLOBAL_SYNC_LOAD_SEQ_PARTS, 0, seqId, flags), 0)
+
+/**
+ * Synchronously initialize a sequence player
+ *
+ * @param seqPlayerIndex the index of the seqPlayer to modify
+ * @param seqId the id of the sequence to play, see `SeqId`
+ * @param fadeInTimer (s32) number of ticks to fade in the sequence to the requested volume
+ */
+#define AUDIOCMD_GLOBAL_INIT_SEQPLAYER(seqPlayerIndex, seqId, fadeInTimer) \
+ AudioThread_QueueCmdS32(AUDIO_MK_CMD(AUDIOCMD_OP_GLOBAL_INIT_SEQPLAYER, seqPlayerIndex, seqId, 0), fadeInTimer)
+
+/**
+ * Disable a sequence player
+ *
+ * @param seqPlayerIndex the index of the seqPlayer to modify
+ * @param fadeOutTimer (s32) number of ticks to fade out the sequence
+ */
+#define AUDIOCMD_GLOBAL_DISABLE_SEQPLAYER(seqPlayerIndex, fadeOutTimer) \
+ AudioThread_QueueCmdS32(AUDIO_MK_CMD(AUDIOCMD_OP_GLOBAL_DISABLE_SEQPLAYER, seqPlayerIndex, 0, 0), fadeOutTimer)
+
+/**
+ * Synchronously initialize a sequence player and skip ticks,
+ * allowing the sequence to start somewhere other than the beginning of the sequences
+ *
+ * @param seqPlayerIndex the index of the seqPlayer to modify
+ * @param seqId the id of the sequence to play, see `SeqId`
+ * @param skipTicks (s32) number of ticks to skip before starting the sequence
+ */
+#define AUDIOCMD_GLOBAL_INIT_SEQPLAYER_SKIP_TICKS(seqPlayerIndex, seqId, skipTicks) \
+ AudioThread_QueueCmdS32(AUDIO_MK_CMD(AUDIOCMD_OP_GLOBAL_INIT_SEQPLAYER_SKIP_TICKS, seqPlayerIndex, seqId, 0), \
+ skipTicks)
+
+/**
+ * When processing an audio thread channel command on all channels, set which channels to process
+ *
+ * @param seqPlayerIndex the index of the seqPlayer to modify
+ * @param threadCmdChannelMask (u16) bitfield for 16 channels. Turn bit on to allow audio thread commands of type
+ * "Channel" to process that channel with `AUDIOCMD_ALL_CHANNELS` set.
+ */
+#define AUDIOCMD_GLOBAL_SET_CHANNEL_MASK(seqPlayerIndex, threadCmdChannelMask) \
+ AudioThread_QueueCmdU16(AUDIO_MK_CMD(AUDIOCMD_OP_GLOBAL_SET_CHANNEL_MASK, seqPlayerIndex, 0, 0), \
+ threadCmdChannelMask)
+
+/**
+ * Set a drum ptr within a soundfont
+ *
+ * @param fontId the id of the soundfont to set the drum in
+ * @param drumId the id of the drum to set
+ * @param drumPtr (s32) the ptr to the `Drum` struct
+ */
+#define AUDIOCMD_GLOBAL_SET_DRUM_FONT(fontId, drumId, drumPtr) \
+ AudioThread_QueueCmdS32(AUDIO_MK_CMD(AUDIOCMD_OP_GLOBAL_SET_DRUM_FONT, fontId, drumId, 0), drumPtr)
+
+/**
+ * Set a soundeffect ptr within a soundfont
+ *
+ * @param fontId the id of the soundfont to set the sound effect in
+ * @param soundEffectId the id of the sound effect to set
+ * @param soundEffectPtr (s32) the ptr to the `SoundEffect` struct
+ */
+#define AUDIOCMD_GLOBAL_SET_SFX_FONT(fontId, soundEffectId, soundEffectPtr) \
+ AudioThread_QueueCmdS32(AUDIO_MK_CMD(AUDIOCMD_OP_GLOBAL_SET_SFX_FONT, fontId, soundEffectId, 0), soundEffectPtr)
+
+/**
+ * Set an instrument ptr within a soundfont
+ *
+ * @param fontId the id of the soundfont to set the instrument in
+ * @param instId the id of the instrument to set
+ * @param instPtr (s32) the ptr to the `Instrument` struct
+ */
+#define AUDIOCMD_GLOBAL_SET_INSTRUMENT_FONT(fontId, instId, instPtr) \
+ AudioThread_QueueCmdS32(AUDIO_MK_CMD(AUDIOCMD_OP_GLOBAL_SET_INSTRUMENT_FONT, fontId, instId, 0), instPtr)
+
+/**
+ * Pop the persistent cache of the specified table
+ *
+ * @param tableType (s32) see the `SampleBankTableType` enum
+ */
+#define AUDIOCMD_GLOBAL_POP_PERSISTENT_CACHE(tableType) \
+ AudioThread_QueueCmdS32(AUDIO_MK_CMD(AUDIOCMD_OP_GLOBAL_POP_PERSISTENT_CACHE, 0, 0, 0), tableType)
+
+/**
+ * Change the sound mode of audio
+ *
+ * @param soundMode (s32) see the `SoundMode` enum
+ */
+#define AUDIOCMD_GLOBAL_SET_SOUND_MODE(soundMode) \
+ AudioThread_QueueCmdS32(AUDIO_MK_CMD(AUDIOCMD_OP_GLOBAL_SET_SOUND_MODE, 0, 0, 0), soundMode)
+
+/**
+ * Mute all sequence players
+ */
+#define AUDIOCMD_GLOBAL_MUTE() \
+ AudioThread_QueueCmdS32(AUDIO_MK_CMD(AUDIOCMD_OP_GLOBAL_MUTE, 0, 0, 0), 0)
+
+/**
+ * Unmute all sequence players
+ *
+ * @param restartNotes (s32) if set to 1, then notes with the `MUTE_BEHAVIOR_STOP_SAMPLES` flag set
+ * are marked as finished for all seqPlayers
+ */
+#define AUDIOCMD_GLOBAL_UNMUTE(restartNotes) \
+ AudioThread_QueueCmdS32(AUDIO_MK_CMD(AUDIOCMD_OP_GLOBAL_UNMUTE, 0, 0, 0), restartNotes)
+
+/**
+ * Synchronously load an instrument
+ *
+ * @param fontId the id of the soundfont to load
+ * @param instId If below 0x7F, the id of the instrument to use. If equal to 0x7F, load the drum using the drumId
+ * @param drumId the id of the drum to use
+ */
+#define AUDIOCMD_GLOBAL_SYNC_LOAD_INSTRUMENT(fontId, instId, drumId) \
+ AudioThread_QueueCmdS8(AUDIO_MK_CMD(AUDIOCMD_OP_GLOBAL_SYNC_LOAD_INSTRUMENT, fontId, instId, drumId), 0)
+
+/**
+ * Asynchronously load a sample bank
+ *
+ * @param sampleBankId the id of the samplebank to load
+ * @param retData return data from `externalLoadQueue`
+ */
+#define AUDIOCMD_GLOBAL_ASYNC_LOAD_SAMPLE_BANK(sampleBankId, retData) \
+ AudioThread_QueueCmdS8(AUDIO_MK_CMD(AUDIOCMD_OP_GLOBAL_ASYNC_LOAD_SAMPLE_BANK, sampleBankId, 0, retData), 0)
+
+/**
+ * Asynchronously load a font
+ *
+ * @param fontId the id of the soundfont to load
+ * @param retData return data from `externalLoadQueue`
+ */
+#define AUDIOCMD_GLOBAL_ASYNC_LOAD_FONT(fontId, unk, retData) \
+ AudioThread_QueueCmdS8(AUDIO_MK_CMD(AUDIOCMD_OP_GLOBAL_ASYNC_LOAD_FONT, fontId, unk, retData), 0)
+
+/**
+ * Discard sequence fonts
+ *
+ * @param seqId the id of the sequence to discard, see `SeqId`
+ */
+#define AUDIOCMD_GLOBAL_DISCARD_SEQ_FONTS(seqId) \
+ AudioThread_QueueCmdS32(AUDIO_MK_CMD(AUDIOCMD_OP_GLOBAL_DISCARD_SEQ_FONTS, 0, seqId, 0), 0)
+
+/**
+ * Stop processing all audio thread commands
+ */
+#define AUDIOCMD_GLOBAL_STOP_AUDIOCMDS() \
+ AudioThread_QueueCmdS32(AUDIO_MK_CMD(AUDIOCMD_OP_GLOBAL_STOP_AUDIOCMDS, 0, 0, 0), 0)
+
+/**
+ * Reset Audio Heap
+ *
+ * @param specId (s32) index for the audio specifications to set high-level audio parameters
+ */
+#define AUDIOCMD_GLOBAL_RESET_AUDIO_HEAP(specId) \
+ AudioThread_QueueCmdS32(AUDIO_MK_CMD(AUDIOCMD_OP_GLOBAL_RESET_AUDIO_HEAP, 0, 0, 0), specId)
+
+/**
+ * No Operation. No code exists for this OP
+ *
+ * @param arg0 No info
+ * @param arg1 No info
+ * @param arg2 No info
+ * @param data (s32) No info
+ */
+#define AUDIOCMD_GLOBAL_NOOP_1(arg0, arg1, arg2, data) \
+ AudioThread_QueueCmdS32(AUDIO_MK_CMD(AUDIOCMD_OP_GLOBAL_NOOP_1, arg0, arg1, arg2), data)
+
+/**
+ * Set a custom function that runs every audio thread update, see `AudioCustomUpdateFunction`
+ *
+ * @param functionPtr (s32) address of the function to run once every audio frame
+ */
+#define AUDIOCMD_GLOBAL_SET_CUSTOM_UPDATE_FUNCTION(functionPtr) \
+ AudioThread_QueueCmdS32(AUDIO_MK_CMD(AUDIOCMD_OP_GLOBAL_SET_CUSTOM_UPDATE_FUNCTION, 0, 0, 0), functionPtr)
+
+/**
+ * Asynchronously load a sequence
+ *
+ * @param seqId the id of the sequence to load, see `SeqId`
+ * @param retData return data from `externalLoadQueue`
+ */
+#define AUDIOCMD_GLOBAL_ASYNC_LOAD_SEQ(seqId, retData) \
+ AudioThread_QueueCmdS8(AUDIO_MK_CMD(AUDIOCMD_OP_GLOBAL_ASYNC_LOAD_SEQ, seqId, 0, retData), 0)
+
+/**
+ * No Operation. No code exists for this OP
+ *
+ * @param arg0 No info
+ * @param arg1 No info
+ * @param arg2 No info
+ * @param data (s32) No info
+ */
+#define AUDIOCMD_GLOBAL_NOOP_2(arg0, arg1, arg2, data) \
+ AudioThread_QueueCmdS32(AUDIO_MK_CMD(AUDIOCMD_OP_GLOBAL_NOOP_2, arg0, arg1, arg2), data)
+
+/**
+ * Disable all sequence players
+ *
+ * @param flags (s32) Set `& 1` to discard all sequences.
+ *
+ * @note Setting `& 3` will also only discard sampled notes, but the sequences are disabled anyway.
+ * Not setting `& 1` should make this command useless TODO: Test
+ */
+#define AUDIOCMD_GLOBAL_DISABLE_ALL_SEQPLAYERS(flags) \
+ AudioThread_QueueCmdS32(AUDIO_MK_CMD(AUDIOCMD_OP_GLOBAL_DISABLE_ALL_SEQPLAYERS, 0, 0, 0), flags)
+
+#endif
diff --git a/include/functions.h b/include/functions.h
index 60c6bcda..d993d3ba 100644
--- a/include/functions.h
+++ b/include/functions.h
@@ -7,54 +7,6 @@
#include "sf64player.h"
#include "sf64mesg.h"
-// audio
-void AudioLoad_Init(void);
-
-void func_80016A50(void);
-void func_800182F4(s32);
-void Audio_PlaySfx(u32, f32*, u8, f32*, f32*, s8*);
-void func_80019290(s32, void*);
-void func_8001A38C(u8, f32*);
-void Audio_KillSfx(f32*);
-void func_8001A55C(f32*, u32);
-void func_8001A838(u32);
-void func_8001ACDC(s32);
-void func_8001AD00(u32);
-void func_8001AE58(void);
-s32 func_8001AE78(void);
-s32 func_8001AED4(void);
-void func_8001AF40(s32);
-u8* func_8001C3EC(void);
-void func_8001C8B8(u8);
-void func_8001CA24(u8);
-void func_8001CB80(u8, u8);
-void func_8001CCDC(u8, f32 *);
-void func_8001CE28(u8, f32 *);
-void func_8001CFA8(f32);
-void func_8001D034(f32*, s32, u8);
-void func_8001D10C(f32*, u32);
-void func_8001D15C(u8);
-void func_8001D1C8(u8, u32);
-void func_8001D2FC(f32*, u16);
-void func_8001D3A0(f32*, u16);
-void func_8001D400(s8);
-void func_8001D410(s32);
-void func_8001D444(u8, u16, u8, u8);
-void func_8001D4AC(u16, u8, u8, u8);
-void func_8001D520(void);
-void func_8001D638(u8);
-void func_8001D6DC(s32);
-void func_8001DA90(u8);
-void func_8001DBD0(s32);
-void func_8001DC6C(u8, u16);
-void func_8001D8A8(u8, u8);
-void func_8001D8F4(u8);
-void func_8001DCE0(void);
-void func_8001DECC(void);
-
-SPTask* func_8001DF50(void);
-void func_8001EE00(void);
-
// fox_360
void func_8002ED60(Player*);
void func_8002E3E0(Actor*);
diff --git a/include/global.h b/include/global.h
index 18273a67..63e8d666 100644
--- a/include/global.h
+++ b/include/global.h
@@ -3,6 +3,7 @@
#include "sys.h"
+#include "sf64audio_external.h"
#include "functions.h"
#include "variables.h"
#include "context.h"
diff --git a/include/macros.h b/include/macros.h
index 1fce8c86..be6b20cc 100644
--- a/include/macros.h
+++ b/include/macros.h
@@ -27,6 +27,8 @@
#define VEC3F_SQ(vec) (SQ((vec).x) + SQ((vec).y) + SQ((vec).z))
#define DOT_XYZ(a, b) ((a).x * (b).x + (a).y * (b).y + (a).z * (b).z)
#define ABS(x) ((x) >= 0 ? (x) : -(x))
+#define ABSF(x) ((x) >= 0.0f ? (x) : -(x))
+#define ROUND(float) ((s32)((float)+0.5f))
#define RAD_TO_DEG(radians) (((radians) * 180.0f) / M_PI)
#define DEG_TO_RAD(degrees) (((degrees) / 180.0f) * M_PI)
diff --git a/include/prevent_context_reordering.h b/include/prevent_context_reordering.h
index 29b0c0b7..1bf9bd1f 100644
--- a/include/prevent_context_reordering.h
+++ b/include/prevent_context_reordering.h
@@ -1,7 +1,7 @@
#ifndef PREVENT_CONTEXT_REORDERING_H
#define PREVENT_CONTEXT_REORDERING_H
-extern int Dummyhalf;
+// extern int Dummyhalf;
struct Dummy0 {int x;};
struct Dummy1 {int x;};
struct Dummy2 {int x;};
@@ -74,7 +74,7 @@ struct Dummy68 {int x;};
struct Dummy69 {int x;};
struct Dummy70 {int x;};
struct Dummy71 {int x;};
-struct Dummy72 {int x;};
+// struct Dummy72 {int x;};
// struct Dummy73 {int x;};
// struct Dummy75 { int x; };
// struct Dummy76 { int x; };
diff --git a/include/sf64audio_external.h b/include/sf64audio_external.h
new file mode 100644
index 00000000..d6e675ee
--- /dev/null
+++ b/include/sf64audio_external.h
@@ -0,0 +1,141 @@
+#ifndef SF64_AUDIO_EXTERNAL_H
+#define SF64_AUDIO_EXTERNAL_H
+
+#include "sys.h"
+#include "audioseq_cmd.h"
+
+#define AUDIO_PLAY_SFX(sfxId, srcPos, token) (Audio_PlaySfx((sfxId),(srcPos),(token),&gDefaultMod,&gDefaultMod,&gDefaultReverb))
+#define AUDIO_PLAY_BGM(seqId) Audio_PlaySequence(SEQ_PLAYER_BGM, (seqId), 0, -1)
+
+typedef enum {
+ SEQ_ID_0,
+ SEQ_ID_1,
+ SEQ_ID_2,
+ SEQ_ID_3,
+ SEQ_ID_4,
+ SEQ_ID_5,
+ SEQ_ID_6,
+ SEQ_ID_7,
+ SEQ_ID_8,
+ SEQ_ID_9,
+ SEQ_ID_10,
+ SEQ_ID_11,
+ SEQ_ID_12,
+ SEQ_ID_13,
+ SEQ_ID_14,
+ SEQ_ID_15,
+ SEQ_ID_16,
+ SEQ_ID_17,
+ SEQ_ID_18,
+ SEQ_ID_19,
+ SEQ_ID_20,
+ SEQ_ID_21,
+ SEQ_ID_22,
+ SEQ_ID_23,
+ SEQ_ID_24,
+ SEQ_ID_25,
+ SEQ_ID_26,
+ SEQ_ID_27,
+ SEQ_ID_28,
+ SEQ_ID_29,
+ SEQ_ID_30,
+ SEQ_ID_31,
+ SEQ_ID_32,
+ SEQ_ID_33,
+ SEQ_ID_34,
+ SEQ_ID_35,
+ SEQ_ID_36,
+ SEQ_ID_37,
+ SEQ_ID_38,
+ SEQ_ID_39,
+ SEQ_ID_40,
+ SEQ_ID_41,
+ SEQ_ID_42,
+ SEQ_ID_43,
+ SEQ_ID_44,
+ SEQ_ID_45,
+ SEQ_ID_46,
+ SEQ_ID_47,
+ SEQ_ID_48,
+ SEQ_ID_49,
+ SEQ_ID_50,
+ SEQ_ID_51,
+ SEQ_ID_52,
+ SEQ_ID_53,
+ SEQ_ID_54,
+ SEQ_ID_55,
+ SEQ_ID_56,
+ SEQ_ID_57,
+ SEQ_ID_58,
+ SEQ_ID_59,
+ SEQ_ID_60,
+ SEQ_ID_61,
+ SEQ_ID_62,
+ SEQ_ID_63,
+ SEQ_ID_64,
+ SEQ_ID_65,
+ SEQ_ID_66,
+ SEQ_ID_67,
+ SEQ_ID_68,
+ SEQ_ID_69,
+} BgmSeqIds;
+
+extern f32 gDefaultSfxSource[];
+extern f32 gDefaultMod;
+extern s8 gDefaultReverb;
+
+void Audio_PlaySfx(u32 sfxId, f32* sfxSource, u8 token, f32* freqMod, f32* volMod, s8* reverbAdd);
+void Audio_KillSfxByBank(u8 bankId);
+void Audio_StopSfxByBankAndSource(u8 bankId, f32* sfxSource);
+void Audio_KillSfxByBankAndSource(u8 bankId, f32* sfxSource);
+void Audio_KillSfxBySource(f32* sfxSource);
+void Audio_KillSfxBySourceAndId(f32* sfxSource, u32 sfxId);
+void Audio_KillSfxByTokenAndId(u8 token, u32 sfxId);
+void Audio_KillSfxById(u32 sfxId);
+void Audio_PlayVoice(s32 msgId);
+void Audio_PlayVoiceWithoutBGM(u32 msgId);
+void Audio_ClearVoice(void);
+s32 Audio_GetCurrentVoice(void);
+s32 Audio_GetCurrentVoiceStatus(void);
+void func_8001AF40(u8 unkVoiceParam);
+u8* Audio_UpdateFrequencyAnalysis(void);
+void func_8001C8B8(u8 playerId);
+void func_8001CA24(u8 playerId);
+void func_8001CB80(u8 playerId, u8 arg1);
+void func_8001CCDC(u8 playerId, f32* sfxSource);
+void func_8001CE28(u8 playerId, f32* sfxSource);
+void func_8001CF60(f32* sfxSource);
+void func_8001CFA8(f32 arg0);
+void func_8001D034(f32* sfxSource, u32 sfxId, u8 semitones);
+void func_8001D0B4(f32* sfxSource, u32 sfxId, f32 freqMod);
+void func_8001D10C(f32* sfxSource, u32 sfxId);
+void func_8001D15C(u8 arg0);
+void func_8001D1C8(u8 arg0, u8 arg1);
+void func_8001D2FC(f32* sfxSource, u16 arg1);
+void func_8001D3A0(f32* sfxSource, u16 arg1);
+void Audio_SetBaseSfxReverb(s8 reverb);
+void Audio_SetBgmParam(s8 bgmParam);
+void Audio_PlaySequence(u8 seqPlayId, u16 seqId, u8 fadeinTime, u8 bgmParam);
+void Audio_PlayFanfare(u16 seqId, u8 bgmVolume, u8 bgmFadeoutTime, u8 bgmFadeinTime);
+void func_8001D520(void);
+void func_8001D638(u8 arg0);
+void func_8001D6DC(u8 arg0);
+void func_8001D8A8(u8 audioType, u8 volume);
+void Audio_PlaySoundTest(u8 enable);
+void Audio_PlaySequenceDistorted(u8 seqPlayId, u16 seqId, u16 distortion, u8 duration, u8 unused);
+void Audio_PlaySoundTestTrack(u8 trackNumber);
+void Audio_FadeOutAll(u8 fadeoutTime);
+void Audio_KillAllSfx(void);
+void Audio_SetAudioSpec(u8 unused, u16 specParam);
+void Audio_PlayBgm(u16 seqId);
+
+// used by sys or related
+void AudioLoad_Init(void);
+void func_80016A50(void);
+void Audio_InitSounds(void);
+void Audio_Update(void);
+SPTask* func_8001DF50(void);
+void func_8001EE00(void);
+
+
+#endif
diff --git a/include/sf64audio_provisional.h b/include/sf64audio_provisional.h
index 366d11b1..9613fe18 100644
--- a/include/sf64audio_provisional.h
+++ b/include/sf64audio_provisional.h
@@ -205,7 +205,7 @@ typedef struct {
typedef struct {
/* 0x00 */ Sample* sample;
- /* 0x04 */ f32 tuning; // frequency scale factor
+ /* 0x04 */ f32 tuning; // frequency modulation factor
} TunedSample; // size = 0x8
typedef struct {
@@ -314,8 +314,8 @@ typedef struct {
/* 0x01C */ f32 fadeVolume;
/* 0x020 */ f32 fadeVelocity;
/* 0x024 */ f32 volume;
- /* 0x028 */ f32 muteVolumeScale;
- /* 0x02C */ f32 fadeVolumeScale;
+ /* 0x028 */ f32 muteVolumeMod;
+ /* 0x02C */ f32 fadeVolumeMod;
/* 0x030 */ f32 appliedFadeVolume;
// /* 0x034 */ f32 bend;
/* 0x038 */ struct SequenceChannel* channels[16];
@@ -376,7 +376,7 @@ typedef struct {
/* 0x01 */ u8 gain; // Increases volume by a multiplicative scaling factor. Represented as a UQ4.4 number
/* 0x02 */ u8 pan;
/* 0x03 */ Stereo stereo;
- /* 0x04 */ f32 freqScale;
+ /* 0x04 */ f32 freqMod;
/* 0x08 */ f32 velocity;
} NoteAttributes; // size = 0xC
@@ -392,7 +392,7 @@ typedef struct SequenceChannel {
/* 0x00 */ u8 unused : 1;
union {
struct {
- /* 0x01 */ u8 freqScale : 1;
+ /* 0x01 */ u8 freqMod : 1;
/* 0x01 */ u8 volume : 1;
/* 0x01 */ u8 pan : 1;
} s;
@@ -419,11 +419,11 @@ typedef struct SequenceChannel {
/* 0x1C */ s16 instOrWave; // either 0 (none), instrument index + 1, or
// 0x80..0x83 for sawtooth/triangle/sine/square waves.
/* 0x1E */ s16 transposition;
- /* 0x20 */ f32 volumeScale;
+ /* 0x20 */ f32 volumeMod;
/* 0x24 */ f32 volume;
/* 0x28 */ s32 pan;
/* 0x2C */ f32 appliedVolume;
- /* 0x30 */ f32 freqScale;
+ /* 0x30 */ f32 freqMod;
/* 0x34 */ u8 (*dynTable)[][2];
/* 0x38 */ struct Note* noteUnused;
/* 0x3C */ struct SequenceLayer* layerUnused;
@@ -458,10 +458,10 @@ typedef struct SequenceLayer {
/* 0x18 */ AdsrSettings adsr;
/* 0x20 */ u16 portamentoTime;
/* 0x22 */ s16 transposition;
- /* 0x24 */ f32 freqScale;
+ /* 0x24 */ f32 freqMod;
/* 0x28 */ f32 velocitySquare;
/* 0x2C */ f32 noteVelocity;
- /* 0x30 */ f32 noteFreqScale;
+ /* 0x30 */ f32 noteFreqMod;
/* 0x34 */ u16 shortNoteDefaultDelay;
/* 0x36 */ u16 lastDelay;
/* 0x38 */ s16 delay;
@@ -473,7 +473,7 @@ typedef struct SequenceLayer {
/* 0x4C */ SequenceChannel *channel;
/* 0x50 */ SeqScriptState state;
/* 0x6C */ AudioListItem listItem;
- /* 0x7C */ UNK_TYPE pad7C[4];
+ /* 0x7C */ char pad7C[4];
} SequenceLayer; //size = 0x80
typedef struct {
@@ -522,9 +522,9 @@ typedef struct {
/* 0x03 */ u8 fontId;
/* 0x04 */ u8 unk_04;
/* 0x05 */ u8 stereoHeadsetEffects;
- /* 0x06 */ s16 adsrVolScaleUnused;
- /* 0x08 */ f32 portamentoFreqScale;
- /* 0x0C */ f32 vibratoFreqScale;
+ /* 0x06 */ s16 adsrVolModUnused;
+ /* 0x08 */ f32 portamentoFreqMod;
+ /* 0x0C */ f32 vibratoFreqMod;
/* 0x10 */ struct SequenceLayer* prevParentLayer;
/* 0x14 */ struct SequenceLayer* parentLayer;
/* 0x18 */ struct SequenceLayer* wantedParentLayer;
@@ -669,11 +669,12 @@ typedef struct {
/* 0x00*/ u32 nextSide;
/* 0x04*/ AudioAllocPool pool;
/* 0x14*/ AudioCacheEntry entries[2];
-} AudioTemporaryCache; // size = 0x3C
+} AudioTemporaryCache; // size = 0x2C
typedef struct {
/* 0x000*/ AudioPersistentCache persistent;
/* 0x194*/ AudioTemporaryCache temporary;
+ /* 0x1C0*/ char pad[0x10];
} AudioCache; // size = 0x1D0
typedef struct {
@@ -798,143 +799,6 @@ typedef struct {
} AudioTask; // size = 0x50
typedef struct {
- /* 0x0000 */ char unk_0000;
- /* 0x0001 */ s8 numSynthesisReverbs;
- /* 0x0002 */ u16 unk_2; // reads from audio spec unk_14, never used, always set to 0x7FFF
- /* 0x0004 */ u16 unk_4;
- /* 0x0006 */ char unk_0006[0x0A];
- /* 0x0010 */ s16* curLoadedBook;
- /* 0x0014 */ NoteSubEu* noteSubsEu;
- /* 0x0018 */ SynthesisReverb synthesisReverbs[4];
- /* 0x0B38 */ char unk_0B38[0x30];
- /* 0x0B68 */ Sample* usedSamples[128];
- /* 0x0D68 */ AudioPreloadReq preloadSampleStack[128];
- /* 0x1768 */ s32 numUsedSamples;
- /* 0x176C */ s32 preloadSampleStackTop;
- /* 0x1770 */ AudioAsyncLoad asyncLoads[0x10];
- /* 0x1CF0 */ OSMesgQueue asyncLoadUnkMediumQueue;
- /* 0x1D08 */ char unk_1D08[0x40];
- /* 0x1D48 */ AudioAsyncLoad* curUnkMediumLoad;
- /* 0x1D4C */ u32 slowLoadPos;
- /* 0x1D50 */ AudioSlowLoad slowLoads[2];
- /* 0x1E18 */ OSPiHandle* cartHandle;
- /* 0x1E1C */ OSPiHandle* driveHandle;
- /* 0x1E20 */ OSMesgQueue externalLoadQueue;
- /* 0x1E38 */ OSMesg externalLoadMsgBuf[16];
- /* 0x1E78 */ OSMesgQueue preloadSampleQueue;
- /* 0x1E90 */ OSMesg preloadSampleMsgBuf[16];
- /* 0x1ED0 */ OSMesgQueue gCurAudioFrameDmaQueue;
- /* 0x1EE8 */ OSMesg curAudioFrameDmaMsgBuf[64];
- /* 0x1FE8 */ OSIoMesg curAudioFrameDmaIoMsgBuf[64];
- /* 0x25E8 */ OSMesgQueue syncDmaQueue;
- /* 0x2600 */ OSMesg syncDmaMesg;
- /* 0x2604 */ OSIoMesg syncDmaIoMesg;
- /* 0x261C */ SampleDma* sampleDmas;
- /* 0x2620 */ u32 sampleDmaCount;
- /* 0x2624 */ u32 sampleDmaListSize1;
- /* 0x2628 */ s32 unused2628;
- /* 0x262C */ u8 sampleDmaReuseQueue1[0x100]; // read pos <= write pos, wrapping mod 256
- /* 0x272C */ u8 sampleDmaReuseQueue2[0x100];
- /* 0x282C */ u8 sampleDmaReuseQueue1RdPos; // Read position for short-lived sampleDma
- /* 0x282D */ u8 sampleDmaReuseQueue2RdPos; // Read position for long-lived sampleDma
- /* 0x282E */ u8 sampleDmaReuseQueue1WrPos; // Write position for short-lived sampleDma
- /* 0x282F */ u8 sampleDmaReuseQueue2WrPos; // Write position for long-lived sampleDma
- /* 0x2830 */ AudioTable* sequenceTable;
- /* 0x2834 */ AudioTable* soundFontTable;
- /* 0x2838 */ AudioTable* sampleBankTable;
- /* 0x283C */ u8* sequenceFontTable;
- /* 0x2840 */ u16 numSequences;
- /* 0x2844 */ SoundFont* soundFontList;
- /* 0x2848 */ AudioBufferParameters audioBufferParameters;
- /* 0x2870 */ f32 unk_2870;
- /* 0x2874 */ s32 sampleDmaBufSize1;
- /* 0x2874 */ s32 sampleDmaBufSize2;
- /* 0x287C */ char unk_287C[0x10];
- /* 0x288C */ s32 sampleDmaBufSize;
- /* 0x2890 */ s32 maxAudioCmds;
- /* 0x2894 */ s32 numNotes;
- /* 0x2898 */ s16
- maxTempo; // Maximum possible tempo (seqTicks per minute), using every tick as a seqTick to process a .seq file
- /* 0x289A */ s8 soundMode;
- /* 0x289C */ s32 totalTaskCount; // The total number of times the top-level function on the audio thread has run
- // since audio was initialized
- /* 0x28A0 */ s32 gCurAudioFrameDmaCount;
- /* 0x28A4 */ s32 rspTaskIndex;
- /* 0x28A8 */ s32 curAiBufIndex;
- /* 0x28AC */ Acmd* abiCmdBufs[2]; // Pointer to audio heap where the audio binary interface command lists (for the
- // rsp) are stored. Two lists that alternate every frame
- /* 0x28B4 */ Acmd* curAbiCmdBuf; // Pointer to the currently active abiCmdBufs
- /* 0x28B8 */ AudioTask* curTask;
- /* 0x28BC */ char unk_28BC[0x4];
- /* 0x28C0 */ AudioTask rspTask[2];
- /* 0x2960 */ f32 maxTempoTvTypeFactors; // tvType factors that impact maxTempo, in units of milliseconds/frame
- /* 0x2964 */ s32 refreshRate;
- /* 0x2968 */ s16* aiBuffers[3];
- /* 0x2974 */ s16 aiBufLengths[3];
- /* 0x297C */ u32 audioRandom;
- /* 0x2980 */ s32 audioErrorFlags;
- /* 0x2984 */ volatile u32 resetTimer;
- /* 0x2988 */ char unk_2988[0x8];
- /* 0x2990 */ AudioAllocPool
- sessionPool; // A sub-pool to main pool, contains all sub-pools and data that changes every audio reset
- /* 0x29A0 */ AudioAllocPool externalPool; // pool allocated externally to the audio heap. Never used in game
- /* 0x29B0 */ AudioAllocPool
- initPool; // A sub-pool to the main pool, contains all sub-pools and data that persists every audio reset
- /* 0x29C0 */ AudioAllocPool miscPool; // A sub-pool to the session pool.
- /* 0x29D0 */ char unk_29D0[0x20]; // probably two unused pools
- /* 0x29F0 */ AudioAllocPool cachePool; // The common pool for cache entries
- /* 0x2A00 */ AudioAllocPool
- persistentCommonPool; // A sub-pool to the cache pool, contains caches for data stored persistently
- /* 0x2A10 */ AudioAllocPool
- temporaryCommonPool; // A sub-pool to the cache pool, contains caches for data stored temporarily
- /* 0x2A20 */ AudioCache seqCache; // Cache to store sequences
- /* 0x2B30 */ AudioCache fontCache; // Cache to store soundFonts
- /* 0x2C40 */ AudioCache sampleBankCache; // Cache for loading entire sample banks
- /* 0x2D50 */ AudioAllocPool permanentPool; // Pool to store audio data that is always loaded. Used for sfxs
- /* 0x2D60 */ AudioCacheEntry permanentCache[32]; // individual entries to the permanent pool
- /* 0x2EE0 */ AudioSampleCache persistentSampleCache; // Stores individual samples persistently
- /* 0x3174 */ AudioSampleCache temporarySampleCache; // Stores individual samples temporarily
- /* 0x3408 */ AudioSessionPoolSplit sessionPoolSplit; // splits session pool into the cache pool and misc pool
- /* 0x3418 */ AudioCachePoolSplit cachePoolSplit; // splits cache pool into the persistent & temporary common pools
- /* 0x3420 */ AudioCommonPoolSplit
- persistentCommonPoolSplit; // splits persistent common pool into caches for sequences, soundFonts, sample banks
- /* 0x342C */ AudioCommonPoolSplit
- temporaryCommonPoolSplit; // splits temporary common pool into caches for sequences, soundFonts, sample banks
- /* 0x3438 */ u8 sampleFontLoadStatus[0x30];
- /* 0x3468 */ u8 fontLoadStatus[0x30];
- /* 0x3498 */ u8 seqLoadStatus[0x80];
- /* 0x3518 */ volatile u8 resetStatus;
- /* 0x3519 */ u8 specId;
- /* 0x351C */ s32 audioResetFadeOutFramesLeft;
- /* 0x3520 */ f32* adsrDecayTable; // A table on the audio heap that stores decay rates used for adsr
- /* 0x3524 */ u8* audioHeap;
- /* 0x3528 */ u32 audioHeapSize;
- /* 0x352C */ Note* notes;
- /* 0x3530 */ SequencePlayer seqPlayers[4];
- /* 0x3AB0 */ SequenceLayer sequenceLayers[64];
- /* 0x5AB0 */ SequenceChannel sequenceChannelNone;
- /* 0x5B84 */ s32 noteSubEuOffset;
- /* 0x5B88 */ AudioListItem layerFreeList;
- /* 0x5B98 */ NotePool noteFreeLists;
- /* 0x5BD8 */ u8 threadCmdWritePos;
- /* 0x5BD9 */ u8 threadCmdReadPos;
- /* 0x5BDA */ u8 threadCmdQueueFinished;
- /* 0x5BDC */ u16 threadCmdChannelMask[4]; // bitfield for 16 channels. When processing an audio thread channel
- // command on all channels, only process channels with their bit set.
- /* 0x5BE4 */ OSMesgQueue* audioResetQueueP;
- /* 0x5BE8 */ OSMesgQueue* taskStartQueueP;
- /* 0x5BEC */ OSMesgQueue* threadCmdProcQueueP;
- /* 0x5BF0 */ OSMesgQueue taskStartQueue;
- /* 0x5C08 */ OSMesgQueue threadCmdProcQueue;
- /* 0x5C20 */ OSMesgQueue audioResetQueue;
- /* 0x5C38 */ OSMesg taskStartMsgBuf[1];
- /* 0x5C3C */ OSMesg audioResetMsgBuf[1];
- /* 0x5C40 */ OSMesg threadCmdProcMsgBuf[4];
- /* 0x5C50 */ AudioCmd threadCmdBuf[0x100]; // Audio thread commands used to transfer audio requests from the graph
- // thread to the audio thread
-} AudioContext; // size = 0x6450
-
-typedef struct {
/* 0x00 */ u8 reverbVol;
/* 0x01 */ u8 gain; // Increases volume by a multiplicative scaling factor. Represented as a UQ4.4 number
/* 0x02 */ u8 pan;
@@ -974,14 +838,9 @@ typedef struct {
} SampleBankRelocInfo; // size = 0x18
typedef struct {
- Drum** drums;
- Instrument* instruments[1];
-} SoundFontData;
-
-typedef struct {
/* 0x0 */ u8 type;
/* 0x1 */ u8 unk_1;
- /* 0x2 */ u32 unk_2;
+ /* 0x2 */ u16 unk_2;
/* 0x4 */ u8 unk_4;
/* 0x5 */ u8 unk_5;
/* 0x6 */ u8 unk_6;
@@ -995,6 +854,151 @@ typedef struct {
/* 0x5 */ u8 unk_5;
} SoundTestTrack; // size: 0x6
+typedef struct {
+ /* 0x00 */ f32 *xPos;
+ /* 0x04 */ f32 *yPos;
+ /* 0x08 */ f32 *zPos;
+ /* 0x0C */ u8 token;
+ /* 0x10 */ f32 *freqMod;
+ /* 0x14 */ f32 *volMod;
+ /* 0x18 */ s8 *reverbAdd;
+ /* 0x1C */ f32 distance;
+ /* 0x20 */ u32 priority;
+ /* 0x24 */ u32 sfxId;
+ /* 0x28 */ u8 state;
+ /* 0x29 */ u8 freshness;
+ /* 0x2A */ u8 prev;
+ /* 0x2B */ u8 next;
+ /* 0x2C */ u8 channelIndex;
+} SfxBankEntry; // size = 0x30
+
+typedef struct {
+ /* 0x00 */ u32 sfxId;
+ /* 0x04 */ f32* pos;
+ /* 0x08 */ u8 token;
+ /* 0x0C */ f32* freqMod;
+ /* 0x10 */ f32* volMod;
+ /* 0x14 */ s8* reverbAdd;
+} SfxRequest; // size = 0x18
+
+typedef struct {
+ /* 0x0 */ u32 priority; // lower is more prioritized
+ /* 0x4 */ u8 entryIndex;
+} ActiveSfx; // size 0x8
+
+typedef struct {
+ /* 0x0 */ u8 seqId;
+ /* 0x1 */ u8 priority; // higher values have higher priority
+} SeqRequest; // size = 0x2
+
+typedef struct {
+ /* 0x0 */ f32 value;
+ /* 0x4 */ f32 target;
+ /* 0x8 */ f32 step;
+ /* 0xC */ u16 timer;
+} Modulation; // size 0x10
+
+typedef struct {
+ /* 0x000 */ f32 mod;
+ /* 0x004 */ f32 target;
+ /* 0x008 */ f32 step;
+ /* 0x00C */ u16 timer;
+ /* 0x00E */ u8 fadeMod[3];
+ /* 0x011 */ u8 fadeTimer;
+ /* 0x012 */ u8 fadeActive;
+} FadeModulation; // size 0x14
+
+typedef struct {
+ /* 0x00 */ Modulation volume;
+ /* 0x10 */ Modulation freq;
+} ChannelModulation; // size = 0x20
+
+typedef struct {
+ /* 0x000 */ FadeModulation mainVolume;
+ /* 0x014 */ u32 tempoCmd;
+ /* 0x018 */ u16 tempoOriginal; // stores the original tempo before modifying it (to reset back to)
+ /* 0x01C */ Modulation tempo;
+ /* 0x02C */ u32 setupCmd[5]; // a queue of cmds to execute once the player is disabled
+ /* 0x040 */ u8 setupCmdTimer; // only execute setup commands when the timer is at 0.
+ /* 0x041 */ u8 setupCmdNum; // number of setup commands requested once the player is disabled
+ /* 0x042 */ u8 setupFadeTimer;
+ /* 0x044 */ ChannelModulation channelMod[16];
+ /* 0x244 */ u16 freqModChannelFlags;
+ /* 0x246 */ u16 volChannelFlags;
+ /* 0x248 */ u16 seqId; // active seqId currently playing. Resets when sequence stops
+ /* 0x24A */ u16 prevSeqId; // last seqId played on a player. Does not reset when sequence stops
+ /* 0x24C */ u16 channelPortMask;
+ /* 0x250 */ u32 startSeqCmd; // This name comes from MM
+ /* 0x254 */ u8 isWaitingForFonts; // This name comes from MM
+} ActiveSequence; // size 0x258
+
+typedef struct {
+ /* 0x0 */ f32 volMod;
+ /* 0x4 */ f32 freqMod;
+ /* 0x8 */ s8 reverb;
+ /* 0x9 */ s8 pan;
+} SfxChannelState; // size 0xC
+
+typedef struct {
+ /* 0x0 */ u32 seqData;
+ /* 0x4 */ u16 timer;
+} DelayedSeqCmd; // size 0x08
+
+typedef struct {
+ /* 0x00 */ f32 value;
+ /* 0x04 */ f32 target;
+ /* 0x08 */ u32 timer;
+ /* 0x0C */ f32 step;
+ /* 0x10 */ u8 boost;
+ /* 0x11 */ u8 brake;
+} FrequencyLerp; // size 0x14
+
+typedef struct {
+ /* 0x00 */ FrequencyLerp freqMod[5];
+ /* 0x64 */ f32 dopplerShift;
+ /* 0x68 */ f32 totalMod;
+ /* 0x6C */ u8 form;
+ /* 0x6D */ s8 reverbAdd;
+} PlayerNoiseModulation; // size 0x70
+
+#define SEQ_HEX0(seqId) ((seqId) >> 28 & 0xFF)
+#define SEQ_HEX1(seqId) (((seqId) & (0xF << 24)) >> 24 & 0xFF)
+#define SEQ_BYTE4(seqId) ((seqId) & 0xFF)
+#define SEQ_BYTE3(seqId) (((seqId) & (0xFF << 8)) >>8 & 0xFF)
+#define SEQ_BYTE2(seqId) (((seqId) & (0xFF << 16)) >>13 & 0xFFFF)
+
+#define SFX_BANK_MASK(sfxId) ((sfxId) & (0xF << 28))
+#define SFX_STATE_MASK(sfxId) ((sfxId) & (1 << 24))
+#define SFX_RANGE_MASK(sfxId) ((sfxId) & (3 << 16))
+#define SFX_IMPORTANCE_MASK(sfxId) ((sfxId) & (0xFF << 8))
+
+#define SFX_BANK_SHIFT(sfxId) (((sfxId) >> 28) & 0xFF)
+#define SFX_STATE_SHIFT(sfxId) (((sfxId) >> 24))
+#define SFX_RANGE_SHIFT(sfxId) (((sfxId) >> 16) & 0xFF)
+#define SFX_IMPORTANCE_SHIFT(sfxId) (((sfxId) >> 8) & 0xFF)
+
+#define SFX_BANK(sfxId) SFX_BANK_SHIFT(SFX_BANK_MASK(sfxId))
+#define SFX_STATE(sfxId) SFX_STATE_SHIFT(SFX_STATE_MASK(sfxId))
+#define SFX_BIT04(sfxId) ((sfxId) & (1 << 27))
+#define SFX_BIT05(sfxId) ((sfxId) & (1 << 26))
+#define SFX_BIT06(sfxId) ((sfxId) & (1 << 25))
+#define SFX_BIT08(sfxId) ((sfxId) & (1 << 23)) // adds random variance to freqMod
+#define SFX_BIT09(sfxId) ((sfxId) & (1 << 22)) // turns off distance-dependent frequency increase
+#define SFX_BIT10(sfxId) ((sfxId) & (1 << 21)) // makes reverb increase with distance
+#define SFX_BIT11(sfxId) ((sfxId) & (1 << 20)) // makes priority independent of distance
+#define SFX_BIT12(sfxId) ((sfxId) & (1 << 19))
+#define SFX_BIT13(sfxId) ((sfxId) & (1 << 18)) // makes distance ignore z position? probably more
+#define SFX_RANGE(sfxId) SFX_RANGE_SHIFT(SFX_RANGE_MASK(sfxId))
+#define SFX_IMPORTANCE(sfxId) SFX_IMPORTANCE_SHIFT(SFX_IMPORTANCE_MASK(sfxId))
+#define SFX_INDEX(sfxId) ((sfxId) & 0xFF)
+
+#define SFX_PACK(bank, range, importance, index, state, bit4, bit5, bit6, bit8, bit9, bit10, bit11, bit12, bit13) \
+ (((bank)<<28)|((range)<<16)|((importance)<<8)|(index)|((state)<<24)|\
+ ((bit4)<<27)|((bit5)<<23)|((bit6)<<23)|((bit8)<<23)|((bit9)<<22)|\
+ ((bit10)<<21)|((bit11)<<20)|((bit12)<<19)|((bit13)<<18))
+
+void func_80008780(f32 *, s32, f32 *);
+
void AudioHeap_ResetLoadStatus(void);
void AudioHeap_DiscardFont(s32 fontId);
void AudioHeap_DiscardSequence(s32 seqId);
@@ -1065,7 +1069,7 @@ void AudioLoad_Init(void);
s32 AudioLoad_SlowLoadSample(s32 fontId, u8 instId, s8* status);
Sample* AudioLoad_GetFontSample(s32 fontId, s32 instId);
void AudioLoad_Stub_10800(void);
-void AudioLoad_FinishSlowLoad(AudioSlowLoad* arg0);
+void AudioLoad_FinishSlowLoad(AudioSlowLoad* slowLoad);
void AudioLoad_ProcessSlowLoads(s32 resetStatus);
void AudioLoad_DmaSlowCopy(AudioSlowLoad* slowLoad, s32 size);
void AudioLoad_DmaSlowCopyUnkMedium(u32 devAddr, u8* ramAddr, u32 size, s32 unkMediumParam);
@@ -1116,55 +1120,19 @@ void func_80016804(s32);
void func_800168BC(void);
-void func_80016A50(void);
-void func_800182F4(s32);
-void func_80019290(s32, void*);
-void Audio_PlaySfx(u32, f32*, u8, f32*, f32*, s8*);
-void func_8001A38C(u8, f32*);
-void func_8001A55C(f32*, u32);
-void Audio_KillSfx(f32*);
-void func_8001A838(u32);
-void func_8001ACDC(s32);
-void func_8001AD00(u32);
-void func_8001AE58(void);
-s32 func_8001AE78(void);
-s32 func_8001AED4(void);
-void func_8001AF40(s32);
-u8* func_8001C3EC(void);
-void func_8001C8B8(u8);
-void func_8001CA24(u8);
-void func_8001CB80(u8, u8);
-void func_8001CCDC(u8, f32 *);
-void func_8001CE28(u8, f32 *);
-void func_8001CFA8(f32);
-void func_8001D034(f32*, s32, u8);
-void func_8001D10C(f32*, u32);
-void func_8001D15C(u8);
-void func_8001D1C8(u8, u32);
-void func_8001D2FC(f32*, u16);
-void func_8001D3A0(f32*, u16);
-void func_8001D400(s8);
-void func_8001D410(s32);
-void func_8001D444(u8, u16, u8, u8);
-void func_8001D4AC(u16, u8, u8, u8);
-void func_8001D520(void);
-void func_8001D638(u8);
-void func_8001D6DC(s32);
-void func_8001D8A8(u8, u8);
-void func_8001D8F4(u8);
-void func_8001DA90(u8);
-void func_8001DBD0(s32);
-void func_8001DC6C(u8, u16);
-void func_8001DCE0(void);
-void func_8001DECC(void);
SPTask* func_8001DF50(void);
+void func_8001E920(void);
+OSMesg func_8001ECAC(s32 *);
+void* func_8001ED14(s32 seqId, u32* outNumFonts);
+s32 func_8001ED34(void);
+void func_8001ED8C(OSMesg);
void func_8001EE00(void);
void func_8001EE3C(void);
-extern u8 D_800C57E8[4];
+extern u8 gSamplesPerWavePeriod[4];
extern u8 gChannelsPerBank[5][5];
extern u8 gUsedChannelsPerBank[5][5];
@@ -1172,31 +1140,31 @@ extern u8 gSfxRequestWriteIndex;
extern u8 gSfxRequestReadIndex;
extern u8 gSfxChannelLayout;
extern u16 D_800C5D24;
-extern f32 gDefaultSfxPos[3];
-extern f32 gDefaultScale;
+extern f32 gDefaultSfxSource[3];
+extern f32 gDefaultMod;
extern s8 gDefaultReverb;
-extern s32 D_800C5D40;
+extern s32 gAudioFrameCounter;
extern u8 gSeqCmdWritePos;
extern u8 gSeqCmdReadPos;
extern u8 gStartSeqDisabled;
-extern u8 gSoundModeList[3];
-extern u8 D_800C5D54;
+extern u8 gSoundModeList[4];
+extern u8 sNewAudioSpecId;
extern u8 D_800C5D58;
// file split?
-extern u8 D_800C5D60;
-extern u8 D_800C5D64;
-extern u8 D_800C5D68[3];
+extern s8 sBaseReverb;
+extern s8 sAudioSpecReverb;
+extern u8 sVolumeSettings[3];
extern u8 D_800C5D6C[29][7];
-extern u8 D_800C5E38[29];
-extern s32 D_800C5E58[5];
+extern s8 D_800C5E38[29];
+extern u32 D_800C5E58[5];
// file split?
extern u8 D_800C5E70;
-extern f32 gSfxVolScale;
-extern f32 gSfxFreqScale;
+extern f32 gSfxFreqMod;
+extern f32 gSfxVolMod;
extern u8 gPlaylistIndex;
extern s32 gPlaylistTimer;
extern u8 gPlaylistCmdIndex;
@@ -1207,14 +1175,14 @@ extern PlaylistCmd gPlaylists[][100];
// file split?
extern f32 D_800C7380;
-extern s32 D_800C7384;
-extern s32 D_800C7388;
-extern u8 D_800C738C;
+extern u32 sNextVoiceId;
+extern u32 sCurrentVoiceId;
+extern u8 sSetNextVoiceId;
extern u8 D_800C7390;
-extern u8 D_800C7394;
-extern s32 D_800C7398[128];
-extern f32 D_800C7414;
-extern f32 D_800C7418[16][2];
+extern u8 sMuteBgmForVoice;
+extern s32 D_800C7398[32];
+extern f32 D_800C7418;
+extern f32 D_800C741C[32];
extern f32 D_800C749C[13];
@@ -1241,15 +1209,55 @@ extern s32 D_800C7C70;
extern u8 gCurCmdReadPos;
extern u8 gThreadCmdQueueFinished;
+extern s32 D_80145D40;
+extern f32 D_80145D48[256];
+extern f32 D_80146148[256];
+extern f32 D_80146548[515];
+extern f32 D_80146D54;
+extern f32 D_80146D58;
+extern f32 D_80146D5C;
+extern f32 D_80146D60;
+extern f32 D_80146D64;
+extern f32 D_80146D68;
+extern f32 D_80146D6C;
+extern f32 D_80146D70;
+
extern s32 D_80146D80;
extern AudioSlowLoadBuffer gSlowLoads;
-// extern AudioSlowLoad D_80146D94[2];
-extern u64 gAudioContextStart[4];
+
+extern SfxRequest gSfxRequests[256];
+extern SfxBankEntry gSfxBanks[5][20];
+extern u8 gSfxBankListEnd[5];
+extern u8 gSfxBankFreeListStart[5];
+extern u8 gSfxBankUnused[5];
+extern ActiveSfx gActiveSfx[5][8];
+extern u8 gCurSfxPlayerChannelIndex;
+extern u8 gSfxBankMuted[5];
+extern Modulation gSfxVolumeMods[5];
+extern f32 D_80149AD8[256];
+extern f32 D_80149ED8[256];
+extern f32 D_8014A2D8[384];
+extern f32 D_8014A8D8[32];
+extern u8 D_8014A958[32];
+extern SeqRequest gSeqRequests[4][5];
+extern u8 gNumSeqRequests[4];
+extern s32 gAudioSeqCmds[256];
+extern ActiveSequence gActiveSequences[4];
+extern u16 gDelayedSeqCmdFlags;
+extern DelayedSeqCmd gDelayedSeqCmds[16];
+extern SfxChannelState gSfxChannelState[16];
+extern PlayerNoiseModulation gPlayerNoise[4];
+extern f32 D_8014BA10[4];
+extern u8 D_8014BA20[4];
+extern u8 D_8014BA24[4];
+extern s32 D_8014BA28[4];
+
+extern u64 gAudioContextStart[];
extern SynthesisReverb gSynthReverbs[4];
-// 0x10
+extern u8 sAudioContextPad10[0x10]; // 0x10
extern u16 D_8014C1B0;
extern s8 D_8014C1B2;
extern s8 gNumSynthReverbs;
@@ -1259,7 +1267,7 @@ extern NoteSubEu* gNoteSubsEu;
extern AudioAllocPool gSessionPool;
extern AudioAllocPool gInitPool;
extern AudioAllocPool gMiscPool;
-// 0x20
+extern u8 gAudioContextPad20[0x20]; // 0x20
extern AudioAllocPool gCachePool;
extern AudioAllocPool gPersistentCommonPool;
extern AudioAllocPool gTemporaryCommonPool;
@@ -1283,7 +1291,7 @@ extern u8 gSeqLoadStatus[256];
extern volatile u8 gResetStatus;
extern u8 gAudioSpecId;
extern s32 gResetFadeoutFramesLeft;
-// 0x1000 gap
+extern u8 sAudioContextPad1000[0x1000];// 0x1000 gap
extern Note* gNotes;
// 0x4
extern SequencePlayer gSeqPlayers[4];
@@ -1344,11 +1352,11 @@ extern f32 gMaxTempoTvTypeFactors;
extern s32 gRefreshRate;
extern u16* gAiBuffers[3];
extern u16 gAiBuffLengths[3];
-extern UNK_TYPE gAudioRandom;
+extern u32 gAudioRandom;
extern UNK_TYPE D_80155D88;
extern volatile u32 gResetTimer;
-extern u64 gAudioContextEnd[4];
+extern u64 gAudioContextEnd[];
@@ -1358,12 +1366,83 @@ extern OSMesgQueue sThreadCmdProcQueue;
extern OSMesgQueue sAudioUnkQueue;
extern OSMesgQueue sAudioResetQueue;
extern AudioCmd gThreadCmdBuffer[256];
-extern OSMesg D_80156600[1];
-extern OSMesg D_80156608[4];
-extern OSMesg D_80156618[1];
-extern OSMesg D_8015661C[1];
-
+extern OSMesg sAudioTaskStartMsg[1];
+extern OSMesg sThreadCmdProcMsg[4];
+extern OSMesg sAudioUnkMsg[1];
+extern OSMesg sAudioResetMsg[1];
+typedef enum {
+ SEQ_ID_0,
+ SEQ_ID_1,
+ SEQ_ID_2,
+ SEQ_ID_3,
+ SEQ_ID_4,
+ SEQ_ID_5,
+ SEQ_ID_6,
+ SEQ_ID_7,
+ SEQ_ID_8,
+ SEQ_ID_9,
+ SEQ_ID_10,
+ SEQ_ID_11,
+ SEQ_ID_12,
+ SEQ_ID_13,
+ SEQ_ID_14,
+ SEQ_ID_15,
+ SEQ_ID_16,
+ SEQ_ID_17,
+ SEQ_ID_18,
+ SEQ_ID_19,
+ SEQ_ID_20,
+ SEQ_ID_21,
+ SEQ_ID_22,
+ SEQ_ID_23,
+ SEQ_ID_24,
+ SEQ_ID_25,
+ SEQ_ID_26,
+ SEQ_ID_27,
+ SEQ_ID_28,
+ SEQ_ID_29,
+ SEQ_ID_30,
+ SEQ_ID_31,
+ SEQ_ID_32,
+ SEQ_ID_33,
+ SEQ_ID_34,
+ SEQ_ID_35,
+ SEQ_ID_36,
+ SEQ_ID_37,
+ SEQ_ID_38,
+ SEQ_ID_39,
+ SEQ_ID_40,
+ SEQ_ID_41,
+ SEQ_ID_42,
+ SEQ_ID_43,
+ SEQ_ID_44,
+ SEQ_ID_45,
+ SEQ_ID_46,
+ SEQ_ID_47,
+ SEQ_ID_48,
+ SEQ_ID_49,
+ SEQ_ID_50,
+ SEQ_ID_51,
+ SEQ_ID_52,
+ SEQ_ID_53,
+ SEQ_ID_54,
+ SEQ_ID_55,
+ SEQ_ID_56,
+ SEQ_ID_57,
+ SEQ_ID_58,
+ SEQ_ID_59,
+ SEQ_ID_60,
+ SEQ_ID_61,
+ SEQ_ID_62,
+ SEQ_ID_63,
+ SEQ_ID_64,
+ SEQ_ID_65,
+ SEQ_ID_66,
+ SEQ_ID_67,
+ SEQ_ID_68,
+ SEQ_ID_69,
+} BgmSeqIds;
#endif
diff --git a/include/sf64object.h b/include/sf64object.h
index 26f0a8c1..18d90f32 100644
--- a/include/sf64object.h
+++ b/include/sf64object.h
@@ -137,7 +137,7 @@ typedef struct {
/* 0x00 */ Object obj;
/* 0x1C */ ObjectInfo info;
/* 0x40 */ char unk40[0x8];
- /* 0x48 */ f32 sfxPos[3];
+ /* 0x48 */ f32 sfxSource[3];
/* 0x54 */ f32 unk_54;
} Object_58; // size = 0x58
@@ -155,7 +155,7 @@ typedef struct {
/* 0x5C */ f32 unk_5C;
/* 0x60 */ f32 unk_60;
/* 0x64 */ Vec3f vel;
- /* 0x70 */ f32 sfxPos[3];
+ /* 0x70 */ f32 sfxSource[3];
/* 0x7C */ char pad7C[4];
} Object_80; // size = 0x80
@@ -182,7 +182,7 @@ typedef struct {
/* 0x50 */ f32 unk_50;
/* 0x54 */ f32 unk_54;
/* 0x58 */ f32 unk_58;
- /* 0x5C */ f32 sfxPos[3];
+ /* 0x5C */ f32 sfxSource[3];
/* 0x68 */ f32 scale;
} Item; // size 0x6C
@@ -206,7 +206,7 @@ typedef struct {
/* 0x78 */ s16 unk_78;
/* 0x7A */ s16 unk_7A;
/* 0x7C */ char pad7C[4];
- /* 0x80 */ f32 sfxPos[3];
+ /* 0x80 */ f32 sfxSource[3];
} Effect; // size 0x8C
typedef struct {
@@ -239,7 +239,7 @@ typedef struct {
/* 0x0D8 */ f32 fwork[50];
/* 0x1A0 */ Vec3f vwork[50];
/* 0x3F8 */ f32 unk_3F8;
- /* 0x3FC */ f32 sfxPos[3];
+ /* 0x3FC */ f32 sfxSource[3];
} Boss; // size = 0x408
#define DMG_BEAM 1
@@ -281,7 +281,7 @@ typedef struct {
/* 0x0E6 */ s16 unk_0E6;
/* 0x0E8 */ Vec3f vel;
/* 0x0F4 */ Vec3f unk_0F4;
- /* 0x100 */ f32 sfxPos[3];
+ /* 0x100 */ f32 sfxSource[3];
/* 0x10C */ f32 gravity;
/* 0x110 */ f32 scale;
/* 0x114 */ f32 fwork[30];
diff --git a/include/sf64player.h b/include/sf64player.h
index ca311b01..9daa12ff 100644
--- a/include/sf64player.h
+++ b/include/sf64player.h
@@ -16,6 +16,7 @@ typedef enum PlayerForm {
/* 2 */ FORM_BLUE_MARINE,
/* 3 */ FORM_ON_FOOT,
/* 4 */ FORM_UNK_4,
+ /*-1 */ FORM_NONE=255,
} PlayerForm;
typedef enum DrawMode {
@@ -53,25 +54,6 @@ typedef enum PlayerState1C8 {
/* 13 */ PLAYERSTATE_1C8_13,
} PlayerState1C8;
-typedef struct {
- /* 0x00 */ u8 rightState;
- /* 0x01 */ u8 leftState;
- /* 0x04 */ f32 unk_04;
- /* 0x08 */ f32 unk_08;
- /* 0x0C */ f32 unk_0C;
- /* 0x10 */ f32 unk_10;
- /* 0x14 */ f32 unk_14;
- /* 0x18 */ f32 unk_18;
- /* 0x1C */ f32 unk_1C;
- /* 0x20 */ f32 unk_20;
- /* 0x24 */ f32 unk_24;
- /* 0x28 */ f32 unk_28;
- /* 0x2C */ u8 unk_2C;
- /* 0x30 */ f32 unk_30;
- /* 0x34 */ f32 unk_34;
- /* 0x38 */ f32 unk_38;
-} WingInfo; // size = 0x3C
-
typedef enum {
/* 0 */ PLAYERSHOT_0, // single laser?
/* 1 */ PLAYERSHOT_1, // twin laser?
@@ -99,7 +81,7 @@ typedef struct {
/* 0x2C */ f32 unk_2C;
/* 0x30 */ f32 unk_30;
/* 0x34 */ f32 unk_34;
- /* 0x38 */ f32 sfxPos[3];
+ /* 0x38 */ f32 sfxSource[3];
/* 0x44 */ f32 unk_44;
/* 0x48 */ f32 unk_48;
/* 0x4C */ f32 unk_4C;
@@ -113,6 +95,38 @@ typedef struct {
/* 0x6C */ u8 bonus;
} PlayerShot; // size = 0x70
+typedef struct {
+ /* 0x00 */ u8 rightState;
+ /* 0x01 */ u8 leftState;
+ /* 0x04 */ f32 unk_04;
+ /* 0x08 */ f32 unk_08;
+ /* 0x0C */ f32 unk_0C;
+ /* 0x10 */ f32 unk_10;
+ /* 0x14 */ f32 unk_14;
+ /* 0x18 */ f32 unk_18;
+ /* 0x1C */ f32 unk_1C;
+ /* 0x20 */ f32 unk_20;
+ /* 0x24 */ f32 unk_24;
+ /* 0x28 */ f32 unk_28;
+ /* 0x2C */ u8 unk_2C;
+ /* 0x30 */ f32 unk_30;
+ /* 0x34 */ f32 unk_34;
+ /* 0x38 */ f32 unk_38;
+} WingInfo; // size = 0x3C
+
+typedef struct {
+ /* 0x00 */ u8 levelType;
+ /* 0x01 */ u8 form;
+ /* 0x04 */ f32 *srcPos;
+ /* 0x08 */ f32 *srcVel;
+ /* 0x0C */ u8 boost;
+ /* 0x0D */ u8 brake;
+ /* 0x10 */ f32 yVel;
+ /* 0x14 */ u8 bank;
+ /* 0x18 */ f32 zRot;
+ /* 0x1C */ u8 roll;
+} PlayerSfx; // size = 0x20
+
typedef struct Player {
/* 0x000 */ f32 unk_000;
/* 0x004 */ f32 unk_004;
@@ -273,18 +287,9 @@ typedef struct Player {
/* 0x2E0 */ Vec3f hit3;
/* 0x2EC */ Vec3f hit4;
/* 0x2F8 */ Vec3f jointTable[30];
- /* 0x460 */ f32 sfxPos[3];
- /* 0x460 */ f32 sfxVel[3];
- /* 0x478 */ u8 levelType;
- /* 0x479 */ u8 form2;
- /* 0x47C */ f32 *srcPos;
- /* 0x480 */ f32 *srcVel;
- /* 0x484 */ s8 boost;
- /* 0x485 */ s8 brake;
- /* 0x488 */ f32 yVel;
- /* 0x48C */ u8 unk_48C;
- /* 0x490 */ f32 unk_490;
- /* 0x494 */ u8 unk_494;
+ /* 0x460 */ f32 sfxSource[3];
+ /* 0x46C */ f32 sfxVel[3];
+ /* 0x478 */ PlayerSfx sfx;
/* 0x498 */ s32 timer_498;
/* 0x49C */ WingInfo wings;
/* 0x4D8 */ f32 unk_4D8;
diff --git a/include/variables.h b/include/variables.h
index df4016fe..95bf1fd2 100644
--- a/include/variables.h
+++ b/include/variables.h
@@ -7,21 +7,6 @@
#include "sf64object.h"
#include "sf64player.h"
-extern f32 gDefaultSfxPos[];
-extern f32 gDefaultScale;
-extern s8 gDefaultReverb;
-extern s8 gThreadCmdWritePos;
-extern s8 gThreadCmdReadPos;
-extern OSMesgQueue* gAudioTaskStartQueue;
-extern OSMesgQueue* gThreadCmdProcQueue;
-extern OSMesgQueue* gAudioUnkQueue;
-extern OSMesgQueue* gAudioResetQueue;
-
-extern OSMesg D_80156600[1];
-extern OSMesg D_80156608[4];
-extern OSMesg D_80156618[1];
-extern OSMesg D_8015661C[1];
-
// fox_360
extern s32 D_800C9B4C;