summaryrefslogtreecommitdiff
path: root/src/code
diff options
context:
space:
mode:
authorengineer124 <47598039+engineer124@users.noreply.github.com>2022-08-15 14:39:57 -0400
committerGitHub <noreply@github.com>2022-08-15 14:39:57 -0400
commit82fe521721ecd8506e4bc5954e406db1e8de8edc (patch)
tree8c9d59f81335145084e25fa2142b9bb03cf73e6b /src/code
parent0082c299c62ca5debfbaee1ce21d67df7fb0b441 (diff)
Audio Sfx (code_801A5BD0 and selected sfx functions in code_8019AF00.c) OK and Documented (#798)
* Rename functions * code_801A5BD0 OK * PR 1, improve spacing * Rename unused struct * Rename Sfx Variables * PR Feedback, update names * Add comment * cleanup vars * Fix merge * Rework documentation, include more functions in sfx system * PR suggestions * fix AudioSfx_MuteBanks * missed enum * more cleanup * more suggestions
Diffstat (limited to 'src/code')
-rw-r--r--src/code/audio/audio_load.c4
-rw-r--r--src/code/audio/audio_playback.c6
-rw-r--r--src/code/audio/audio_seqplayer.c2
-rw-r--r--src/code/audio/audio_sfx_params.c8
-rw-r--r--src/code/audio/code_80192BE0.c10
-rw-r--r--src/code/audio/code_8019AF00.c675
-rw-r--r--src/code/audio/code_801A5BD0.c950
-rw-r--r--src/code/audio/code_801A7B10.c2
-rw-r--r--src/code/audioMgr.c2
-rw-r--r--src/code/code_80172BC0.c2
-rw-r--r--src/code/z_actor.c8
-rw-r--r--src/code/z_effect_soft_sprite.c4
-rw-r--r--src/code/z_sound_source.c4
13 files changed, 1558 insertions, 119 deletions
diff --git a/src/code/audio/audio_load.c b/src/code/audio/audio_load.c
index b4997a94e..9ebdd1d85 100644
--- a/src/code/audio/audio_load.c
+++ b/src/code/audio/audio_load.c
@@ -1208,7 +1208,7 @@ void AudioLoad_Init(void* heap, size_t heapSize) {
gAudioContext.refreshRate = 60;
}
- Audio_InitMesgQueues();
+ AudioThread_InitMesgQueues();
for (i = 0; i < ARRAY_COUNT(gAudioContext.aiBufLengths); i++) {
gAudioContext.aiBufLengths[i] = 0xA0;
@@ -1217,7 +1217,7 @@ void AudioLoad_Init(void* heap, size_t heapSize) {
gAudioContext.totalTaskCount = 0;
gAudioContext.rspTaskIndex = 0;
gAudioContext.curAiBuffferIndex = 0;
- gAudioContext.soundMode = AUDIO_MODE_STEREO;
+ gAudioContext.soundMode = SOUNDMODE_STEREO;
gAudioContext.curTask = NULL;
gAudioContext.rspTask[0].task.t.dataSize = 0;
gAudioContext.rspTask[1].task.t.dataSize = 0;
diff --git a/src/code/audio/audio_playback.c b/src/code/audio/audio_playback.c
index c7789bd36..e7f5153ac 100644
--- a/src/code/audio/audio_playback.c
+++ b/src/code/audio/audio_playback.c
@@ -34,7 +34,7 @@ void AudioPlayback_InitNoteSub(Note* note, NoteSubEu* sub, NoteSubAttributes* at
sub->bitField0.stereoStrongLeft = false;
sub->bitField0.stereoHeadsetEffects = stereoData.stereoHeadsetEffects;
sub->bitField0.usesHeadsetPanEffects = stereoData.usesHeadsetPanEffects;
- if (stereoHeadsetEffects && gAudioContext.soundMode == AUDIO_MODE_HEADSET) {
+ if (stereoHeadsetEffects && gAudioContext.soundMode == SOUNDMODE_HEADSET) {
smallPanIndex = pan >> 1;
if (smallPanIndex > 0x3F) {
smallPanIndex = 0x3F;
@@ -46,7 +46,7 @@ void AudioPlayback_InitNoteSub(Note* note, NoteSubEu* sub, NoteSubAttributes* at
volLeft = gHeadsetPanVolume[pan];
volRight = gHeadsetPanVolume[0x7F - pan];
- } else if (stereoHeadsetEffects && gAudioContext.soundMode == AUDIO_MODE_STEREO) {
+ } else if (stereoHeadsetEffects && gAudioContext.soundMode == SOUNDMODE_STEREO) {
strongLeft = strongRight = false;
sub->headsetPanRight = 0;
sub->headsetPanLeft = 0;
@@ -80,7 +80,7 @@ void AudioPlayback_InitNoteSub(Note* note, NoteSubEu* sub, NoteSubAttributes* at
break;
}
- } else if (gAudioContext.soundMode == AUDIO_MODE_MONO) {
+ } else if (gAudioContext.soundMode == SOUNDMODE_MONO) {
sub->bitField0.stereoHeadsetEffects = false;
sub->bitField0.usesHeadsetPanEffects = false;
volLeft = 0.707f; // approx 1/sqrt(2)
diff --git a/src/code/audio/audio_seqplayer.c b/src/code/audio/audio_seqplayer.c
index d504f9f3a..ebcc9a8d1 100644
--- a/src/code/audio/audio_seqplayer.c
+++ b/src/code/audio/audio_seqplayer.c
@@ -1633,7 +1633,7 @@ void AudioSeq_SequenceChannelProcessScript(SequenceChannel* channel) {
break;
case 0xA8: // channel: random range large (only cmd that differs from OoT)
- rand = Audio_NextRandom();
+ rand = AudioThread_NextRandom();
channel->unk_22 = (cmdArgs[0] == 0) ? (rand & 0xFFFF) : (rand % cmdArgs[0]);
channel->unk_22 += cmdArgs[1];
temp2 = (channel->unk_22 / 0x100) + 0x80;
diff --git a/src/code/audio/audio_sfx_params.c b/src/code/audio/audio_sfx_params.c
index 94a8f26bc..0066328b1 100644
--- a/src/code/audio/audio_sfx_params.c
+++ b/src/code/audio/audio_sfx_params.c
@@ -1,9 +1,9 @@
#include "global.h"
-#define DEFINE_SFX(_0, importance, distParam, randParam, flags2, flags1) \
- { importance, flags2, \
- ((((distParam) << SFX_PARAM_01_SHIFT) & SFX_PARAM_01_MASK) | \
- (((randParam) << SFX_PARAM_67_SHIFT) & SFX_PARAM_67_MASK) | (flags1)) },
+#define DEFINE_SFX(_0, importance, distParam, randParam, flags2, flags1) \
+ { importance, flags2, \
+ ((((distParam) << SFX_PARAM_DIST_RANGE_SHIFT) & SFX_PARAM_DIST_RANGE_MASK) | \
+ (((randParam) << SFX_PARAM_RAND_FREQ_RAISE_SHIFT) & SFX_PARAM_RAND_FREQ_RAISE_MASK) | (flags1)) },
SfxParams sEnemyBankParams[] = {
#include "tables/sfx/enemybank_table.h"
diff --git a/src/code/audio/code_80192BE0.c b/src/code/audio/code_80192BE0.c
index 20b4239da..e69f678ff 100644
--- a/src/code/audio/code_80192BE0.c
+++ b/src/code/audio/code_80192BE0.c
@@ -16,13 +16,13 @@
#pragma GLOBAL_ASM("asm/non_matchings/code/code_80192BE0/func_80193858.s")
-#pragma GLOBAL_ASM("asm/non_matchings/code/code_80192BE0/func_8019387C.s")
+#pragma GLOBAL_ASM("asm/non_matchings/code/code_80192BE0/AudioThread_QueueCmdS32.s")
-#pragma GLOBAL_ASM("asm/non_matchings/code/code_80192BE0/Audio_QueueCmdS8.s")
+#pragma GLOBAL_ASM("asm/non_matchings/code/code_80192BE0/AudioThread_QueueCmdS8.s")
#pragma GLOBAL_ASM("asm/non_matchings/code/code_80192BE0/func_801938D0.s")
-#pragma GLOBAL_ASM("asm/non_matchings/code/code_80192BE0/func_80193900.s")
+#pragma GLOBAL_ASM("asm/non_matchings/code/code_80192BE0/AudioThread_ScheduleProcessCmds.s")
#pragma GLOBAL_ASM("asm/non_matchings/code/code_80192BE0/func_80193990.s")
@@ -76,6 +76,6 @@
#pragma GLOBAL_ASM("asm/non_matchings/code/code_80192BE0/func_80194568.s")
-#pragma GLOBAL_ASM("asm/non_matchings/code/code_80192BE0/Audio_NextRandom.s")
+#pragma GLOBAL_ASM("asm/non_matchings/code/code_80192BE0/AudioThread_NextRandom.s")
-#pragma GLOBAL_ASM("asm/non_matchings/code/code_80192BE0/Audio_InitMesgQueues.s")
+#pragma GLOBAL_ASM("asm/non_matchings/code/code_80192BE0/AudioThread_InitMesgQueues.s")
diff --git a/src/code/audio/code_8019AF00.c b/src/code/audio/code_8019AF00.c
index 65c3a6de8..b896facbc 100644
--- a/src/code/audio/code_8019AF00.c
+++ b/src/code/audio/code_8019AF00.c
@@ -18,15 +18,15 @@ typedef struct {
} SfxSettings; // size = 0x9
typedef struct {
- /* 0x0 */ f32 vol;
+ /* 0x0 */ f32 volume;
/* 0x4 */ f32 freqScale;
/* 0x8 */ s8 reverb;
/* 0x9 */ s8 panSigned;
/* 0xA */ s8 stereoBits;
/* 0xB */ u8 filter;
- /* 0xC */ u8 unk_0C;
- /* 0xD */ u8 unk_0D;
-} SfxPlayerState; // size = 0xE
+ /* 0xC */ u8 combFilterGain;
+ /* 0xD */ u8 zVolume;
+} SfxChannelState; // size = 0xE
typedef enum {
/* 0x0 */ SFX_CHANNEL_PLAYER0, // SfxPlayerBank
@@ -91,7 +91,7 @@ f32* sSfxVolumeCur;
f32 sSfxVolumeTarget;
f32 sSfxVolumeRate;
u16 sSceneSeqId1;
-SfxPlayerState sSfxChannelState[16];
+SfxChannelState sSfxChannelState[16];
// Sequence bss
u8 D_801FD3A8;
@@ -154,7 +154,8 @@ OcarinaNote sScarecrowsLongSongSecondNote;
u16 sCustomSequencePc;
// Sfx Data
-u8 D_801D6600[] = {
+// If the Sfx Bank has more than 255 values (max value of u8)
+u8 gIsLargeSfxBank[] = {
true, false, true, true, false, false, true,
};
u8 D_801D6608[] = {
@@ -192,7 +193,7 @@ u8 sEnterGanonsTowerTimer = 0;
u16 sSfxVolumeDuration = 0;
// System Data
-s8 sAudioFileSelectSetting = AUDIO_FS_STEREO;
+s8 sSoundMode = SOUNDMODE_STEREO;
s8 sAudioIsWindowOpen = false;
s8 sAudioCutsceneFlag = false;
s8 sSpecReverb = 0;
@@ -2495,7 +2496,7 @@ void AudioOcarina_PlayControllerInput(u8 isOcarinaSfxSuppressedWhenCancelled) {
// Add vibrato of the ocarina note based on the x control stick
sCurOcarinaVibrato = ABS_ALT(sOcarinaInputStickRel.x) >> 2;
// Sets vibrato to io port 6
- Audio_QueueCmdS8(0x6 << 24 | SEQ_PLAYER_SFX << 16 | SFX_CHANNEL_OCARINA << 8 | 6, sCurOcarinaVibrato);
+ AudioThread_QueueCmdS8(0x6 << 24 | SEQ_PLAYER_SFX << 16 | SFX_CHANNEL_OCARINA << 8 | 6, sCurOcarinaVibrato);
} else {
// no bending or vibrato for recording state OCARINA_RECORD_SCARECROW_SPAWN
sCurOcarinaBendIndex = 0;
@@ -2507,15 +2508,16 @@ void AudioOcarina_PlayControllerInput(u8 isOcarinaSfxSuppressedWhenCancelled) {
if ((sCurOcarinaPitch != OCARINA_PITCH_NONE) && (sPrevOcarinaPitch != sCurOcarinaPitch)) {
// Sets ocarina instrument Id to io port 7, which is used
// as an index in seq 0 to get the true instrument Id
- Audio_QueueCmdS8(0x6 << 24 | SEQ_PLAYER_SFX << 16 | SFX_CHANNEL_OCARINA << 8 | 7, sOcarinaInstrumentId - 1);
+ AudioThread_QueueCmdS8(0x6 << 24 | SEQ_PLAYER_SFX << 16 | SFX_CHANNEL_OCARINA << 8 | 7,
+ sOcarinaInstrumentId - 1);
// Sets pitch to io port 5
- Audio_QueueCmdS8(0x6 << 24 | SEQ_PLAYER_SFX << 16 | SFX_CHANNEL_OCARINA << 8 | 5, sCurOcarinaPitch);
- Audio_PlaySfxGeneral(NA_SE_OC_OCARINA, &gSfxDefaultPos, 4, &sCurOcarinaBendFreq, &sDefaultOcarinaVolume,
- &gSfxDefaultReverb);
+ AudioThread_QueueCmdS8(0x6 << 24 | SEQ_PLAYER_SFX << 16 | SFX_CHANNEL_OCARINA << 8 | 5, sCurOcarinaPitch);
+ AudioSfx_PlaySfx(NA_SE_OC_OCARINA, &gSfxDefaultPos, 4, &sCurOcarinaBendFreq, &sDefaultOcarinaVolume,
+ &gSfxDefaultReverb);
} else if ((sPrevOcarinaPitch != OCARINA_PITCH_NONE) && (sCurOcarinaPitch == OCARINA_PITCH_NONE) &&
!isOcarinaSfxSuppressedWhenCancelled) {
// Stops ocarina sound when transitioning from playing to not playing a note
- Audio_StopSfxById(NA_SE_OC_OCARINA);
+ AudioSfx_StopById(NA_SE_OC_OCARINA);
}
}
}
@@ -2540,10 +2542,10 @@ void AudioOcarina_ResetAndMute(void) {
sOcarinaInputButtonStart = 0xFFFF;
AudioOcarina_PlayControllerInput(false);
- Audio_StopSfxById(NA_SE_OC_OCARINA);
+ AudioSfx_StopById(NA_SE_OC_OCARINA);
if (gAudioSpecId != 12) {
- Audio_SetSfxBanksMute(0);
+ AudioSfx_MuteBanks(0);
}
sPlaybackState = 0;
@@ -2553,7 +2555,7 @@ void AudioOcarina_ResetAndMute(void) {
sOcarinaFlags = 0;
// return to full volume for both bgm players after ocarina is finished
- Audio_ClearFlagForBgmVolumeLow(SFX_CHANNEL_OCARINA);
+ AudioSfx_RestoreBgmVolume(SFX_CHANNEL_OCARINA);
// return to full volume for all sfx channels except system & ocarina banks
Audio_SetSfxVolumeExceptSystemAndOcarinaBanks(0x7F);
}
@@ -2602,7 +2604,7 @@ u32 AudioOcarina_SetInstrument(u8 ocarinaInstrumentId) {
// lowers volume of all sfx channels except system & ocarina banks
Audio_SetSfxVolumeExceptSystemAndOcarinaBanks(0x40);
// lowers volume of bgm players while playing ocarina
- Audio_SetFlagForBgmVolumeLow(SFX_CHANNEL_OCARINA);
+ AudioSfx_LowerBgmVolume(SFX_CHANNEL_OCARINA);
}
}
}
@@ -2612,7 +2614,7 @@ void AudioOcarina_SetPlaybackSong(s8 songIndexPlusOne, u8 playbackState) {
if (songIndexPlusOne == 0) {
sPlaybackState = 0;
- Audio_StopSfxById(NA_SE_OC_OCARINA);
+ AudioSfx_StopById(NA_SE_OC_OCARINA);
return;
}
@@ -2700,7 +2702,7 @@ void AudioOcarina_PlaybackSong(void) {
sPlaybackStaffPos = 0;
sPlaybackPitch = OCARINA_PITCH_NONE;
} else {
- Audio_StopSfxById(NA_SE_OC_OCARINA);
+ AudioSfx_StopById(NA_SE_OC_OCARINA);
}
return;
} else {
@@ -2716,7 +2718,7 @@ void AudioOcarina_PlaybackSong(void) {
// Update vibrato
sNotePlaybackVibrato = sPlaybackSong[sPlaybackNotePos].vibrato;
// Sets vibrato to io port 6
- Audio_QueueCmdS8(0x6 << 24 | SEQ_PLAYER_SFX << 16 | SFX_CHANNEL_OCARINA << 8 | 6, sNotePlaybackVibrato);
+ AudioThread_QueueCmdS8(0x6 << 24 | SEQ_PLAYER_SFX << 16 | SFX_CHANNEL_OCARINA << 8 | 6, sNotePlaybackVibrato);
// Update bend
if (sNotePlaybackBend != sPlaybackSong[sPlaybackNotePos].bend) {
@@ -2746,14 +2748,14 @@ void AudioOcarina_PlaybackSong(void) {
sPlaybackStaffPos++;
// Sets ocarina instrument Id to io port 7, which is used
// as an index in seq 0 to get the true instrument Id
- Audio_QueueCmdS8(0x6 << 24 | SEQ_PLAYER_SFX << 16 | SFX_CHANNEL_OCARINA << 8 | 7,
- sOcarinaInstrumentId - 1);
- Audio_QueueCmdS8(0x6 << 24 | SEQ_PLAYER_SFX << 16 | SFX_CHANNEL_OCARINA << 8 | 5,
- sPlaybackPitch & OCARINA_BUTTON_MASK_PITCH);
- Audio_PlaySfxGeneral(NA_SE_OC_OCARINA, &gSfxDefaultPos, 4, &sRelativeNotePlaybackBend,
- &sRelativeNotePlaybackVolume, &gSfxDefaultReverb);
+ AudioThread_QueueCmdS8(0x6 << 24 | SEQ_PLAYER_SFX << 16 | SFX_CHANNEL_OCARINA << 8 | 7,
+ sOcarinaInstrumentId - 1);
+ AudioThread_QueueCmdS8(0x6 << 24 | SEQ_PLAYER_SFX << 16 | SFX_CHANNEL_OCARINA << 8 | 5,
+ sPlaybackPitch & OCARINA_BUTTON_MASK_PITCH);
+ AudioSfx_PlaySfx(NA_SE_OC_OCARINA, &gSfxDefaultPos, 4, &sRelativeNotePlaybackBend,
+ &sRelativeNotePlaybackVolume, &gSfxDefaultReverb);
} else {
- Audio_StopSfxById(NA_SE_OC_OCARINA);
+ AudioSfx_StopById(NA_SE_OC_OCARINA);
}
}
sPlaybackNotePos++;
@@ -3073,7 +3075,7 @@ void AudioOcarina_TerminaWallGenerateNotes(void) {
j = 0;
for (; i < 8; i++) {
- randomButtonIndex = Audio_NextRandom() % ARRAY_COUNT(sButtonToPitchMap);
+ randomButtonIndex = AudioThread_NextRandom() % ARRAY_COUNT(sButtonToPitchMap);
sOcarinaSongNotes[OCARINA_SONG_TERMINA_WALL][j].pitch = sButtonToPitchMap[randomButtonIndex];
sOcarinaSongNotes[OCARINA_SONG_TERMINA_WALL][j].length = 19;
sOcarinaSongNotes[OCARINA_SONG_TERMINA_WALL][j].volume = 80;
@@ -3094,7 +3096,7 @@ void AudioOcarina_TerminaWallGenerateNotes(void) {
sOcarinaSongNotes[OCARINA_SONG_TERMINA_WALL][j + 1].length = 0;
AudioOcarina_MapSongFromPitchToButton(OCARINA_SONG_TERMINA_WALL, OCARINA_SONG_TERMINA_WALL, 8);
} else {
- j = Audio_NextRandom() % ARRAY_COUNT(sOoTOcarinaSongNotes);
+ j = AudioThread_NextRandom() % ARRAY_COUNT(sOoTOcarinaSongNotes);
ocarinaNote = sOoTOcarinaSongNotes[j];
for (; ocarinaNote[i].length != 0; i++) {
@@ -3140,7 +3142,7 @@ s32 AudioOcarina_MemoryGameNextNote(void) {
return true;
}
- randomButtonIndex = Audio_NextRandom();
+ randomButtonIndex = AudioThread_NextRandom();
randomPitch = sButtonToPitchMap[randomButtonIndex % ARRAY_COUNT(sButtonToPitchMap)];
if (sOcarinaSongNotes[OCARINA_SONG_MEMORY_GAME][sOcarinaMemoryGameAppendPos - 1].pitch == randomPitch) {
@@ -3234,7 +3236,7 @@ void AudioOcarina_PlayLongScarecrowAfterCredits(void) {
break;
case 1:
- Audio_SetSfxBanksMute(0);
+ AudioSfx_MuteBanks(0);
AudioOcarina_SetInstrument(sScarecrowAfterCreditsIntrumentId);
AudioOcarina_SetPlaybackSong(OCARINA_SONG_SCARECROW_LONG + 1, 1);
sScarecrowAfterCreditsIntrumentId++;
@@ -3475,20 +3477,6 @@ void AudioOcarina_ResetStaffs(void) {
D_801D8534 = 0;
}
-s8 D_801D8B30[] = {
- 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33,
- 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55,
- 56, 56, 57, 57, 58, 58, 59, 59, 60, 60, 60, 61, 61, 61, 62, 62, 62, 63, 63, 63, 64, 64,
- 64, 65, 65, 65, 66, 66, 66, 67, 67, 67, 68, 68, 69, 69, 70, 70, 71, 71, 72, 73, 74, 75,
- 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97,
- 98, 99, 100, 101, 102, 103, 105, 107, 109, 111, 113, 115, 117, 119, 121, 123, 125, 127,
-};
-f32 sBigBellsVolume[8] = {
- 1.0f, 0.9f, 0.8f, 0.7f, 0.6f, 0.5f, 0.4f, 0.3f,
-};
-u8 sBgmPlayers[2] = { SEQ_PLAYER_BGM_MAIN, SEQ_PLAYER_BGM_SUB };
-f32 sSfxOriginalPos[] = { 0.0f, 0.0f, 0.0f };
-
#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019DFF8.s")
#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019E000.s")
@@ -3503,23 +3491,447 @@ f32 sSfxOriginalPos[] = { 0.0f, 0.0f, 0.0f };
#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019E110.s")
-#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019E14C.s")
+f32 AudioSfx_ComputeVolume(u8 bankId, u8 entryIndex) {
+ SfxBankEntry* bankEntry = &gSfxBanks[bankId][entryIndex];
+ f32 minDist;
+ f32 phi_f14;
+ f32 baseDist;
+ f32 phi_f12;
+ f32 volume; // Also acts as intermediate volumeSquared
+ s32 pad[3];
+
+ if (bankEntry->sfxParams & SFX_FLAG_VOLUME_NO_DIST) {
+ return 1.0f;
+ }
+
+ if (bankEntry->dist > 10000.0f) {
+ volume = 0.0f;
+ } else {
+ if (bankEntry->sfxParams & SFX_PARAM_DIST_RANGE_MASK_UPPER) {
+ phi_f12 = 0.35f;
+ phi_f14 = 0.65f;
+ } else {
+ phi_f12 = 0.81f;
+ phi_f14 = 0.19f;
+ }
+
+ switch (bankEntry->sfxParams & SFX_PARAM_DIST_RANGE_MASK) {
+ case 0:
+ baseDist = 500.0f;
+ break;
+
+ case 1:
+ baseDist = 666.6667f;
+ break;
+
+ case 2:
+ baseDist = 952.381f;
+ break;
+
+ case 3:
+ baseDist = 3846.154f;
+ break;
+
+ case 4:
+ baseDist = 1000.0f;
+ break;
+
+ case 5:
+ baseDist = 666.6667f;
+ break;
+
+ case 6:
+ baseDist = 500.0f;
+ break;
+
+ case 7:
+ baseDist = 400.0f;
+ break;
+ }
+
+ minDist = baseDist / 5.0f;
+
+ if (bankEntry->dist < minDist) {
+ volume = 1.0f;
+ } else if (bankEntry->dist < baseDist) {
+ volume =
+ ((((baseDist - minDist) - (bankEntry->dist - minDist)) / (baseDist - minDist)) * phi_f14) + phi_f12;
+ } else {
+ volume = (1.0f - ((bankEntry->dist - baseDist) / (10000.0f - baseDist))) * phi_f12;
+ }
+
+ volume = SQ(volume);
+ }
+
+ return volume;
+}
+
+s8 AudioSfx_ComputeReverb(u8 bankId, u8 entryIndex, u8 channelIndex) {
+ s8 distAdd = 0;
+ s32 scriptAdd = 0;
+ SfxBankEntry* entry = &gSfxBanks[bankId][entryIndex];
+ s32 reverb;
+
+ if (!(entry->sfxParams & SFX_FLAG_REVERB_NO_DIST)) {
+ if (entry->dist < 2500.0f) {
+ distAdd = *entry->posZ > 0.0f ? (entry->dist / 2500.0f) * 70.0f : (entry->dist / 2500.0f) * 91.0f;
+ } else {
+ distAdd = 70;
+ }
+ }
+
+ if (IS_SEQUENCE_CHANNEL_VALID(gAudioContext.seqPlayers[SEQ_PLAYER_SFX].channels[channelIndex])) {
+ scriptAdd = gAudioContext.seqPlayers[SEQ_PLAYER_SFX].channels[channelIndex]->soundScriptIO[1];
+ if (gAudioContext.seqPlayers[SEQ_PLAYER_SFX].channels[channelIndex]->soundScriptIO[1] < 0) {
+ scriptAdd = 0;
+ }
+ }
+
+ reverb = (*entry->reverbAdd & 0x7F) + distAdd;
+
+ if (entry->state != SFX_STATE_READY) {
+ reverb += scriptAdd;
+ }
+
+ if ((bankId != BANK_OCARINA) || (SFX_INDEX(entry->sfxId) >= 2)) {
+ reverb += sAudioEnvReverb + (sAudioCodeReverb & 0x3F) + sSpecReverb;
+ }
+
+ if (reverb > 0x7F) {
+ reverb = 0x7F;
+ }
+
+ return reverb;
+}
+
+s8 AudioSfx_ComputePanSigned(f32 x, f32 z, u8 token) {
+ f32 absX = ABS_ALT(x);
+ f32 absZ = ABS_ALT(z);
+ f32 pan;
+
+ if (absX > 8000.0f) {
+ absX = 8000.0f;
+ }
+
+ if (absZ > 8000.0f) {
+ absZ = 8000.0f;
+ }
+
+ if ((x == 0.0f) && (z == 0.0f)) {
+ pan = 0.5f;
+ } else if (absZ <= absX) {
+ pan = (16000.0f - absX) / (4.5f * (16000.0f - absZ));
+ if (x >= 0.0f) {
+ pan = 1.0f - pan;
+ }
+ } else {
+ pan = (x / (3.6f * absZ)) + 0.5f;
+ }
+
+ if ((absZ < 50.0f) && (absX < 50.0f)) {
+ pan = ((pan - 0.5f) * SQ(absX / 50.0f)) + 0.5f;
+ }
+
+ return (pan * 127.0f) + 0.5f;
+}
+
+f32 AudioSfx_ComputeFreqScale(u8 bankId, u8 entryIndex) {
+ s32 applyRandScaling = false;
+ SfxBankEntry* entry = &gSfxBanks[bankId][entryIndex];
+ f32 dist;
+ f32 freq = 1.0f;
+
+ if (entry->sfxParams & SFX_PARAM_RAND_FREQ_LOWER) {
+ freq = 1.0f - ((gAudioContext.audioRandom & 0xF) / 192.0f);
+ }
+
+ switch (bankId) {
+ case BANK_VOICE:
+ if (((entry->sfxId & 0xFF) < 0x40) && (sAudioBaseFilter2 != 0)) {
+ applyRandScaling = true;
+ } else if (((entry->sfxId & 0xFF) >= 0x40) && (sAudioExtraFilter2 != 0)) {
+ applyRandScaling = true;
+ }
+ break;
+
+ case BANK_PLAYER:
+ case BANK_ITEM:
+ if (sAudioBaseFilter2 != 0) {
+ applyRandScaling = true;
+ }
+ break;
+
+ case BANK_ENV:
+ case BANK_ENEMY:
+ if (((*entry->reverbAdd & 0x80) != 0) | (sAudioExtraFilter2 != 0)) {
+ applyRandScaling = true;
+ }
+ break;
+
+ case BANK_SYSTEM:
+ case BANK_OCARINA:
+ break;
+
+ default:
+ break;
+ }
+
+ if ((applyRandScaling == true) && !(entry->sfxParams & SFX_PARAM_RAND_FREQ_SCALE)) {
+ freq *= 1.0293 - ((gAudioContext.audioRandom & 0xF) / 144.0f);
+ }
+
+ dist = entry->dist;
+ if (!(entry->sfxParams & SFX_FLAG_VOLUME_NO_DIST) && !(entry->sfxParams & SFX_FLAG_FREQ_NO_DIST)) {
+ if (dist >= 10000.0f) {
+ freq += 0.2f;
+ } else {
+ freq += (0.2f * (dist / 10000.0f));
+ }
+ }
+
+ if ((entry->sfxParams & SFX_PARAM_RAND_FREQ_RAISE_MASK) != (0 << SFX_PARAM_RAND_FREQ_RAISE_SHIFT)) {
+ freq += (entry->randFreq / 192.0f);
+ }
+
+ return freq;
+}
+
+u8 AudioSfx_ComputeSurroundSoundFilter(f32 behindScreenZ, SfxBankEntry* entry, s8 panSigned) {
+ u8 lowPassCutoff;
+ u8 highPassCutoff;
+ u16* sfxParams;
+ f32 distParam;
+ f32 dist;
+
+ // Remnant of OoT
+ if (*entry->posZ < behindScreenZ) {
+ lowPassCutoff = 0;
+ } else {
+ lowPassCutoff = 0;
+ }
+
+ sfxParams = &entry->sfxParams;
+
+ if (*sfxParams & SFX_FLAG_SURROUND_LOWPASS_FILTER) {
+ lowPassCutoff = 0xF;
+ }
+
+ switch ((*sfxParams & SFX_PARAM_DIST_RANGE_MASK)) {
+ case 0:
+ distParam = 15.0f;
+ break;
+
+ case 1:
+ distParam = 12.0f;
+ break;
+
+ case 2:
+ distParam = 9.0f;
+ break;
+
+ case 3:
+ distParam = 6.0f;
+ break;
+
+ case 4:
+ distParam = 18.0f;
+ break;
+
+ case 5:
+ distParam = 21.0f;
+ break;
+
+ case 6:
+ distParam = 24.0f;
+ break;
+
+ case 7:
+ distParam = 27.0f;
+ break;
+
+ default:
+ break;
+ }
+
+ if (!(entry->sfxFlags & SFX_FLAG2_SURROUND_NO_HIGHPASS_FILTER)) {
+ if (entry->dist > 1923.077f) {
+ dist = 1923.077f;
+ } else {
+ dist = entry->dist;
+ }
+
+ highPassCutoff = (distParam * dist) / (2 * 1923.077f);
+ } else {
+ highPassCutoff = 0;
+ }
+
+ return (lowPassCutoff << 4) + highPassCutoff;
+}
+
+s8 AudioSfx_ComputeCombFilter(f32 posY, u16 sfxParams) {
+ s8 combFilterGain;
+
+ if (posY < 0.0f) {
+ if (posY < -625.0f) {
+ combFilterGain = -32;
+ } else {
+ combFilterGain = (s8)(((625.0f + posY) / 625.0f) * 31.0f) + 0xE0;
+ }
+ } else if (posY > 1250.0f) {
+ combFilterGain = 127;
+ } else {
+ combFilterGain = (posY / 1250.0f) * 126.0f;
+ }
+
+ return combFilterGain | 1;
+}
+
+void AudioSfx_SetProperties(u8 bankId, u8 entryIndex, u8 channelIndex) {
+ static s8 sZVolumes[] = {
+ 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33,
+ 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55,
+ 56, 56, 57, 57, 58, 58, 59, 59, 60, 60, 60, 61, 61, 61, 62, 62, 62, 63, 63, 63, 64, 64,
+ 64, 65, 65, 65, 66, 66, 66, 67, 67, 67, 68, 68, 69, 69, 70, 70, 71, 71, 72, 73, 74, 75,
+ 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97,
+ 98, 99, 100, 101, 102, 103, 105, 107, 109, 111, 113, 115, 117, 119, 121, 123, 125, 127,
+ };
+ f32 volume = 1.0f;
+ s8 volumeS8;
+ s8 reverb = 0;
+ f32 freqScale = 1.0f;
+ s8 panSigned = 0x40;
+ u8 pad;
+ u8 filter = 0;
+ s8 combFilterGain = 0;
+ s8 zVolume = -1;
+ f32 behindScreenZ;
+ u8 baseFilter = 0;
+ SfxBankEntry* entry = &gSfxBanks[bankId][entryIndex];
+ s32 pad2;
+
+ switch (bankId) {
+ case BANK_PLAYER:
+ case BANK_ITEM:
+ case BANK_ENV:
+ case BANK_ENEMY:
+ case BANK_VOICE:
+ if (sSoundMode == SOUNDMODE_SURROUND) {
+ combFilterGain = AudioSfx_ComputeCombFilter(*entry->posY, entry->sfxParams);
+ }
+ // fallthrough
+ case BANK_OCARINA:
+ entry->dist = sqrtf(entry->dist * 10.0f);
+ volume = AudioSfx_ComputeVolume(bankId, entryIndex) * *entry->volume;
+ reverb = AudioSfx_ComputeReverb(bankId, entryIndex, channelIndex);
+ panSigned = AudioSfx_ComputePanSigned(*entry->posX, *entry->posZ, entry->token);
+ freqScale = AudioSfx_ComputeFreqScale(bankId, entryIndex) * *entry->freqScale;
+
+ if (sSoundMode == SOUNDMODE_SURROUND) {
+ if (*entry->posZ >= 0.0f) {
+ if (*entry->posZ < 200.0f) {
+ zVolume = 32.0f - ((*entry->posZ / 300.0f) * 32.0f);
+ } else {
+ zVolume = 0;
+ }
+ } else if (*entry->posZ < 0.0f) {
+ if (*entry->posZ > -300.0f) {
+ zVolume = 32.0f - ((*entry->posZ / 300.0f) * 95.0f);
+ } else {
+ zVolume = 127;
+ }
+ }
+ zVolume = sZVolumes[zVolume];
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019E324.s")
+ if (sAudioBaseFilter != 0) {
+ if ((bankId == BANK_PLAYER) || (bankId == BANK_ITEM) ||
+ ((bankId == BANK_VOICE) && (((entry->sfxId & 0xFF) < 0x40) || ((entry->sfxId & 0xFF) >= 0x80)))) {
+ baseFilter = sAudioBaseFilter;
+ if (sAudioExtraFilter) {
+ reverb >>= 2;
+ }
+ }
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019E4B0.s")
+ if (((*entry->reverbAdd & 0x80) | baseFilter | sAudioExtraFilter |
+ (entry->sfxFlags & SFX_FLAG2_APPLY_LOWPASS_FILTER)) != 0) {
+ filter = ((((*entry->reverbAdd & 0x80) >> 2) | baseFilter | sAudioExtraFilter |
+ ((entry->sfxFlags & SFX_FLAG2_APPLY_LOWPASS_FILTER) >> 2)) *
+ 2);
+ filter &= 0xFF;
+ } else if ((sSoundMode == SOUNDMODE_SURROUND) && !(entry->sfxParams & SFX_FLAG_VOLUME_NO_DIST)) {
+ filter = AudioSfx_ComputeSurroundSoundFilter(behindScreenZ, entry, panSigned);
+ }
+ break;
-#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019E634.s")
+ case BANK_SYSTEM:
+ break;
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019E864.s")
+ if (sSfxChannelState[channelIndex].volume != volume) {
+ volumeS8 = (u8)(volume * 127.0f);
+ sSfxChannelState[channelIndex].volume = volume;
+ } else {
+ volumeS8 = -1;
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019EA40.s")
+ //! FAKE:
+ if (1) {}
-#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019EB2C.s")
+ // CHAN_UPD_SCRIPT_IO (slot 2, sets volume)
+ AudioThread_QueueCmdS8((0x6 << 24) | (SEQ_PLAYER_SFX << 16) | (channelIndex << 8) | 2, volumeS8);
-#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019F024.s")
+ if (sSfxChannelState[channelIndex].reverb != reverb) {
+ sSfxChannelState[channelIndex].reverb = reverb;
+ }
+ if (sSfxChannelState[channelIndex].freqScale != freqScale) {
+ sSfxChannelState[channelIndex].freqScale = freqScale;
+ }
+ if (sSfxChannelState[channelIndex].stereoBits != 0) {
+ sSfxChannelState[channelIndex].stereoBits = 0;
+ }
+ if (sSfxChannelState[channelIndex].filter != filter) {
+ sSfxChannelState[channelIndex].filter = filter;
+ }
+ if (sSfxChannelState[channelIndex].combFilterGain != combFilterGain) {
+ sSfxChannelState[channelIndex].combFilterGain = combFilterGain;
+ }
+ if (sSfxChannelState[channelIndex].zVolume != zVolume) {
+ sSfxChannelState[channelIndex].zVolume = zVolume;
+ }
+ if (sSfxChannelState[channelIndex].panSigned != panSigned) {
+ sSfxChannelState[channelIndex].panSigned = panSigned;
+ }
+}
+
+u32 AudioSfx_SetFreqAndStereoBits(u8 seqScriptValIn, SequenceChannel* channel) {
+ channel->stereo.asByte = sSfxChannelState[seqScriptValIn].stereoBits;
+ channel->freqScale = sSfxChannelState[seqScriptValIn].freqScale;
+ channel->changes.s.freqScale = true;
-#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019F05C.s")
+ return seqScriptValIn;
+}
+
+void AudioSfx_ResetSfxChannelState(void) {
+ SfxChannelState* state;
+ u8 i;
+
+ for (i = 0; i < ARRAY_COUNT(sSfxChannelState); i++) {
+ state = &sSfxChannelState[i];
+ state->volume = 1.0f;
+ state->freqScale = 1.0f;
+ state->reverb = 0;
+ state->panSigned = 0x40;
+ state->stereoBits = 0;
+ state->filter = 0xFF;
+ state->combFilterGain = 0xFF;
+ state->zVolume = 0xFF;
+ }
+
+ sSfxChannelState[SFX_CHANNEL_OCARINA].combFilterGain = 0;
+ sPrevSeqMode = SEQ_MODE_DEFAULT;
+ sAudioCodeReverb = 0;
+}
#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/play_sound.s")
@@ -3533,9 +3945,75 @@ f32 sSfxOriginalPos[] = { 0.0f, 0.0f, 0.0f };
#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019F230.s")
-#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019F258.s")
+SfxSettings* AudioSfx_AddSfxSetting(Vec3f* pos) {
+ SfxSettings* sfxSettings;
+ u8 i = 0;
+ u8 sfxSettingIndex = 0xFF;
+
+ for (; i < ARRAY_COUNT(sSfxSettings); i++) {
+ sfxSettings = &sSfxSettings[i];
+
+ if ((sfxSettings->pos == NULL) && (sfxSettingIndex == 0xFF)) {
+ sfxSettingIndex = i;
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019F300.s")
+ if (sfxSettings->pos == pos) {
+ return sfxSettings;
+ }
+ }
+
+ if (sfxSettingIndex != 0xFF) {
+ sSfxSettingsFlags |= 1 << sfxSettingIndex;
+ sfxSettings = &sSfxSettings[sfxSettingIndex];
+ sfxSettings->pos = pos;
+ return sfxSettings;
+ }
+
+ return NULL;
+}
+
+void AudioSfx_ProcessSfxSettings(void) {
+ SfxBankEntry* entry;
+ u8 sfxSettingsFlags;
+ u8 sfxSettingIndex = 0;
+ u8 bankId;
+ u8 entryIndex;
+ s32 found;
+
+ if (sSfxSettingsFlags != 0) {
+ sfxSettingsFlags = sSfxSettingsFlags;
+
+ while (sfxSettingsFlags != 0) {
+ bankId = BANK_ENV;
+ if ((sfxSettingsFlags & (1 << sfxSettingIndex))) {
+
+ found = false;
+ while ((bankId <= BANK_ENEMY) && !found) {
+ entryIndex = gSfxBanks[bankId]->next;
+
+ while (entryIndex != 0xFF) {
+ entry = &gSfxBanks[bankId][entryIndex];
+ entryIndex = 0xFF;
+ if (entry->posX == &sSfxSettings[sfxSettingIndex].pos->x) {
+ found = true;
+ } else {
+ entryIndex = entry->next;
+ }
+ }
+ bankId++;
+ }
+
+ if (!found) {
+ sSfxSettingsFlags ^= (1 << sfxSettingIndex);
+ sSfxSettings[sfxSettingIndex].pos = NULL;
+ }
+
+ sfxSettingsFlags ^= (1 << sfxSettingIndex);
+ }
+ sfxSettingIndex++;
+ }
+ }
+}
#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019F420.s")
@@ -3543,7 +4021,17 @@ f32 sSfxOriginalPos[] = { 0.0f, 0.0f, 0.0f };
#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019F540.s")
-#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019F570.s")
+void AudioSfx_LowerSfxSettingsReverb(Vec3f* pos, s8 isReverbLowered) {
+ SfxSettings* sfxSettings = AudioSfx_AddSfxSetting(pos);
+
+ if (sfxSettings != NULL) {
+ if (isReverbLowered) {
+ sfxSettings->reverbAdd = -0x80;
+ } else {
+ sfxSettings->reverbAdd = 0;
+ }
+ }
+}
#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019F5AC.s")
@@ -3585,15 +4073,15 @@ f32 sSfxOriginalPos[] = { 0.0f, 0.0f, 0.0f };
* Used for EnRiverSound
*/
void Audio_PlaySfxForRiver(Vec3f* pos, f32 freqScale) {
- if (!Audio_IsSfxPlaying(NA_SE_EV_RIVER_STREAM - SFX_FLAG)) {
+ if (!AudioSfx_IsPlaying(NA_SE_EV_RIVER_STREAM - SFX_FLAG)) {
sRiverFreqScaleLerp.value = freqScale;
} else if (freqScale != sRiverFreqScaleLerp.value) {
sRiverFreqScaleLerp.target = freqScale;
sRiverFreqScaleLerp.remainingFrames = 40;
sRiverFreqScaleLerp.step = (sRiverFreqScaleLerp.target - sRiverFreqScaleLerp.value) / 40;
}
- Audio_PlaySfxGeneral(NA_SE_EV_RIVER_STREAM - SFX_FLAG, pos, 4, &sRiverFreqScaleLerp.value, &D_801DB4B0,
- &gSfxDefaultReverb);
+ AudioSfx_PlaySfx(NA_SE_EV_RIVER_STREAM - SFX_FLAG, pos, 4, &sRiverFreqScaleLerp.value, &gSfxDefaultFreqAndVolScale,
+ &gSfxDefaultReverb);
}
/**
@@ -3601,15 +4089,15 @@ void Audio_PlaySfxForRiver(Vec3f* pos, f32 freqScale) {
* Used for Zora's River Waterfall
*/
void Audio_PlaySfxForWaterfall(Vec3f* pos, f32 freqScale) {
- if (!Audio_IsSfxPlaying(NA_SE_EV_WATER_WALL_BIG - SFX_FLAG)) {
+ if (!AudioSfx_IsPlaying(NA_SE_EV_WATER_WALL_BIG - SFX_FLAG)) {
sWaterfallFreqScaleLerp.value = freqScale;
} else if (freqScale != sWaterfallFreqScaleLerp.value) {
sWaterfallFreqScaleLerp.target = freqScale;
sWaterfallFreqScaleLerp.remainingFrames = 40;
sWaterfallFreqScaleLerp.step = (sWaterfallFreqScaleLerp.target - sWaterfallFreqScaleLerp.value) / 40;
}
- Audio_PlaySfxGeneral(NA_SE_EV_WATER_WALL_BIG - SFX_FLAG, pos, 4, &sWaterfallFreqScaleLerp.value,
- &sWaterfallFreqScaleLerp.value, &gSfxDefaultReverb);
+ AudioSfx_PlaySfx(NA_SE_EV_WATER_WALL_BIG - SFX_FLAG, pos, 4, &sWaterfallFreqScaleLerp.value,
+ &sWaterfallFreqScaleLerp.value, &gSfxDefaultReverb);
}
/**
@@ -3626,6 +4114,9 @@ void Audio_StepFreqLerp(FreqLerp* lerp) {
}
}
+f32 sBigBellsVolume[8] = {
+ 1.0f, 0.9f, 0.8f, 0.7f, 0.6f, 0.5f, 0.4f, 0.3f,
+};
#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A0124.s")
#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A0184.s")
@@ -3652,7 +4143,7 @@ void Audio_SetGanonsTowerBgmVolumeLevel(u8 ganonsTowerLevel) {
for (channelIndex = 0; channelIndex < 16; channelIndex++) {
// CHAN_UPD_PAN_UNSIGNED
- Audio_QueueCmdS8(((u8)(u32)channelIndex << 8) | 0x7000000, pan);
+ AudioThread_QueueCmdS8(((u8)(u32)channelIndex << 8) | 0x7000000, pan);
}
// Lowest room in Ganon's Tower (Entrance Room)
@@ -3710,9 +4201,9 @@ s32 Audio_SetGanonsTowerBgmVolume(u8 targetVolume) {
}
// CHAN_UPD_REVERB
- Audio_QueueCmdS8(_SHIFTL(5, 24, 8) | _SHIFTL(SEQ_PLAYER_BGM_MAIN, 16, 8) |
- _SHIFTL(channelIndex, 8, 8),
- (u8)reverb);
+ AudioThread_QueueCmdS8(_SHIFTL(5, 24, 8) | _SHIFTL(SEQ_PLAYER_BGM_MAIN, 16, 8) |
+ _SHIFTL(channelIndex, 8, 8),
+ (u8)reverb);
}
}
}
@@ -3768,7 +4259,29 @@ void Audio_UpdateRiverSoundVolumes(void) {
#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A05F0.s")
-#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A0654.s")
+void AudioSfx_SetChannelIO(Vec3f* pos, u16 sfxId, u8 ioData) {
+ u8 channelIndex = 0;
+ u8 bankId = SFX_BANK_SHIFT(sfxId);
+ u8 entryIndex;
+ u8 i;
+
+ for (i = 0; i < bankId; i++) {
+ channelIndex += gChannelsPerBank[gSfxChannelLayout][i];
+ }
+
+ for (i = 0; i < gChannelsPerBank[gSfxChannelLayout][bankId]; i++) {
+ entryIndex = gActiveSfx[bankId][i].entryIndex;
+
+ if (entryIndex != 0xFF) {
+ if ((sfxId == gSfxBanks[bankId][entryIndex].sfxId) && (&pos->x == gSfxBanks[bankId][entryIndex].posX)) {
+ AudioThread_QueueCmdS8(_SHIFTL(6, 24, 8) | _SHIFTL(SEQ_PLAYER_SFX, 16, 8) |
+ _SHIFTL(channelIndex, 8, 8) | _SHIFTL(6, 0, 8),
+ ioData);
+ }
+ }
+ channelIndex++;
+ }
+}
#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A0810.s")
@@ -3814,7 +4327,7 @@ void func_801A09D4(Vec3f* pos, f32 xzDistToPlayer) {
if (channelIndex != 9) {
Audio_QueueSeqCmd(((u32)(6) << 28) | ((u32)(SEQ_PLAYER_BGM_MAIN) << 24) | ((u32)(2) << 16) |
((u32)(channelIndex) << 8) | ((u8)(127.0f * volumeRel)));
- Audio_QueueCmdS8(0x03000000 | ((u8)((u32)channelIndex) << 8), pan);
+ AudioThread_QueueCmdS8(0x03000000 | ((u8)((u32)channelIndex) << 8), pan);
}
}
}
@@ -3837,6 +4350,7 @@ void Audio_ClearSariaBgmAtPos(Vec3f* pos) {
}
}
+u8 sBgmPlayers[2] = { SEQ_PLAYER_BGM_MAIN, SEQ_PLAYER_BGM_SUB };
void Audio_SplitBgmChannels(s8 volumeSplit);
#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/Audio_SplitBgmChannels.s")
@@ -4043,6 +4557,7 @@ void Audio_ClearSariaBgm2(void) {
#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A46F8.s")
+f32 sSfxOriginalPos[] = { 0.0f, 0.0f, 0.0f };
#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A4748.s")
#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A479C.s")
@@ -4053,11 +4568,27 @@ void Audio_ClearSariaBgm2(void) {
#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A4A28.s")
-#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A4B80.s")
+u32 Audio_SetNatureAmbienceRandomBend(u8 seqScriptValIn, SequenceChannel* channel);
+#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/Audio_SetNatureAmbienceRandomBend.s")
-#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A4C30.s")
+void Audio_Init(void) {
+ AudioLoad_Init(NULL, 0);
+}
-#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A4C54.s")
+void AudioSfx_Init(u16 fadeTimer) {
+ u8 channelIndex;
+
+ AudioThread_ScheduleProcessCmds();
+ Audio_StartSequence(SEQ_PLAYER_SFX, NA_BGM_GENERAL_SFX, 0x70, fadeTimer);
+
+ for (channelIndex = 0; channelIndex < ARRAY_COUNT(sSfxChannelState); channelIndex++) {
+ AudioThread_QueueCmdS32(0x10 << 24 | SEQ_PLAYER_SFX << 16 | ((u8)(u32)channelIndex << 8),
+ &sSfxChannelState[channelIndex]);
+ }
+
+ AudioThread_QueueCmdS32(0xE4000000, AudioSfx_SetFreqAndStereoBits);
+ AudioThread_QueueCmdS32(0xE4000001, Audio_SetNatureAmbienceRandomBend);
+}
#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A4D00.s")
diff --git a/src/code/audio/code_801A5BD0.c b/src/code/audio/code_801A5BD0.c
index 38e4ff187..4cf1147bf 100644
--- a/src/code/audio/code_801A5BD0.c
+++ b/src/code/audio/code_801A5BD0.c
@@ -1,45 +1,951 @@
#include "global.h"
-#pragma GLOBAL_ASM("asm/non_matchings/code/code_801A5BD0/Audio_SetSfxBanksMute.s")
+typedef struct {
+ /* 0x00 */ u16 sfxId;
+ /* 0x02 */ u8 token;
+ /* 0x04 */ s8* reverbAdd;
+ /* 0x08 */ Vec3f* pos;
+ /* 0x0C */ f32* freqScale;
+ /* 0x10 */ f32* volume;
+} SfxRequest; // size = 0x14
-#pragma GLOBAL_ASM("asm/non_matchings/code/code_801A5BD0/Audio_SetFlagForBgmVolumeLow.s")
+typedef struct {
+ /* 0x0 */ f32 value;
+ /* 0x4 */ f32 target;
+ /* 0x8 */ f32 step;
+ /* 0xC */ u16 remainingFrames;
+} SfxBankLerp; // size = 0x10
-#pragma GLOBAL_ASM("asm/non_matchings/code/code_801A5BD0/Audio_ClearFlagForBgmVolumeLow.s")
+typedef enum {
+ /* 0 */ SFX_RM_REQ_BY_BANK,
+ /* 1 */ SFX_RM_REQ_BY_POS_AND_BANK,
+ /* 2 */ SFX_RM_REQ_BY_POS,
+ /* 3 */ SFX_RM_REQ_BY_POS_AND_ID,
+ /* 4 */ SFX_RM_REQ_BY_TOKEN_AND_ID,
+ /* 5 */ SFX_RM_REQ_BY_ID
+} SfxRemoveRequest;
-#pragma GLOBAL_ASM("asm/non_matchings/code/code_801A5BD0/Audio_PlaySfxGeneral.s")
+SfxBankEntry sSfxPlayerBank[9];
+SfxBankEntry sSfxItemBank[12];
+SfxBankEntry sSfxEnvironmentBank[32];
+SfxBankEntry sSfxEnemyBank[20];
+SfxBankEntry sSfxSystemBank[8];
+SfxBankEntry sSfxOcarinaBank[3];
+SfxBankEntry sSfxVoiceBank[5];
+SfxRequest sSfxRequests[0x100];
+u8 sSfxBankListEnd[7];
+u8 sSfxBankFreeListStart[7];
+u8 sSfxBankUnused[7];
+ActiveSfx gActiveSfx[7][3];
+u8 sCurSfxPlayerChannelIndex;
+u8 gSfxBankMuted[7];
+SfxBankLerp sSfxBankLerp[7];
-#pragma GLOBAL_ASM("asm/non_matchings/code/code_801A5BD0/func_801A5DDC.s")
+// sSfxRequests ring buffer endpoints. read index <= write index, wrapping around mod 256.
+u8 sSfxRequestWriteIndex = 0;
+u8 sSfxRequestReadIndex = 0;
-#pragma GLOBAL_ASM("asm/non_matchings/code/code_801A5BD0/func_801A5F7C.s")
+/**
+ * Array of pointers to arrays of SfxBankEntry of sizes: 9, 12, 32, 20, 8, 3, 5
+ *
+ * 0 : Player Bank size 9
+ * 1 : Item Bank size 12
+ * 2 : Environment Bank size 32
+ * 3 : Enemy Bank size 20
+ * 4 : System Bank size 8
+ * 5 : Ocarina Bank size 3
+ * 6 : Voice Bank size 5
+ */
+SfxBankEntry* gSfxBanks[7] = {
+ sSfxPlayerBank, sSfxItemBank, sSfxEnvironmentBank, sSfxEnemyBank, sSfxSystemBank, sSfxOcarinaBank, sSfxVoiceBank,
+};
-#pragma GLOBAL_ASM("asm/non_matchings/code/code_801A5BD0/func_801A6430.s")
+u8 sSfxBankSizes[ARRAY_COUNT(gSfxBanks)] = {
+ ARRAY_COUNT(sSfxPlayerBank), ARRAY_COUNT(sSfxItemBank), ARRAY_COUNT(sSfxEnvironmentBank),
+ ARRAY_COUNT(sSfxEnemyBank), ARRAY_COUNT(sSfxSystemBank), ARRAY_COUNT(sSfxOcarinaBank),
+ ARRAY_COUNT(sSfxVoiceBank),
+};
-#pragma GLOBAL_ASM("asm/non_matchings/code/code_801A5BD0/func_801A65C8.s")
+u8 gSfxChannelLayout = 0;
+u16 sSfxChannelLowVolumeFlag = 0;
-#pragma GLOBAL_ASM("asm/non_matchings/code/code_801A5BD0/func_801A6D0C.s")
+// The center of the screen in projected coordinates.
+// Gives the impression that the sfx has no specific location
+Vec3f gSfxDefaultPos = { 0.0f, 0.0f, 0.0f };
-#pragma GLOBAL_ASM("asm/non_matchings/code/code_801A5BD0/func_801A7084.s")
+// Reused as either frequency or volume multiplicative scaling factor
+// Does not alter or change frequency or volume
+f32 gSfxDefaultFreqAndVolScale = 1.0f;
+s32 D_801DB4B4 = 0; // unused
-#pragma GLOBAL_ASM("asm/non_matchings/code/code_801A5BD0/func_801A7168.s")
+// Adds no reverb to the existing reverb
+s8 gSfxDefaultReverb = 0;
-#pragma GLOBAL_ASM("asm/non_matchings/code/code_801A5BD0/func_801A7284.s")
+void AudioSfx_MuteBanks(u16 muteMask) {
+ u8 bankId;
-#pragma GLOBAL_ASM("asm/non_matchings/code/code_801A5BD0/Audio_StopSfxByPos.s")
+ for (bankId = 0; bankId < ARRAY_COUNT(gSfxBanks); bankId++) {
+ if (muteMask & 1) {
+ gSfxBankMuted[bankId] = true;
+ } else {
+ gSfxBankMuted[bankId] = false;
+ }
+ muteMask = muteMask >> 1;
+ }
+}
-#pragma GLOBAL_ASM("asm/non_matchings/code/code_801A5BD0/func_801A7328.s")
+/**
+ * Lowers volumes of both bgm players so that sfx can be more pronounced.
+ * Each sfx channel stores its own bit to lower the volume.
+ * Only a single channel needs to request this to lower the volume.
+ */
+void AudioSfx_LowerBgmVolume(u8 channelIndex) {
+ sSfxChannelLowVolumeFlag |= (1 << channelIndex);
-#pragma GLOBAL_ASM("asm/non_matchings/code/code_801A5BD0/func_801A7484.s")
+ Audio_SetVolumeScale(SEQ_PLAYER_BGM_MAIN, 2, 0x40, 0xF);
+ Audio_SetVolumeScale(SEQ_PLAYER_BGM_SUB, 2, 0x40, 0xF);
+}
-#pragma GLOBAL_ASM("asm/non_matchings/code/code_801A5BD0/Audio_StopSfxById.s")
+/**
+ * Clears the flag for the specific channel to lower volume.
+ * If all flags are cleared, then both bgm players return to full volume
+ */
+void AudioSfx_RestoreBgmVolume(u8 channelIndex) {
+ sSfxChannelLowVolumeFlag &= ((1 << channelIndex) ^ 0xFFFF);
-#pragma GLOBAL_ASM("asm/non_matchings/code/code_801A5BD0/func_801A7720.s")
+ if (sSfxChannelLowVolumeFlag == 0) {
+ Audio_SetVolumeScale(SEQ_PLAYER_BGM_MAIN, 2, 0x7F, 0xF);
+ Audio_SetVolumeScale(SEQ_PLAYER_BGM_SUB, 2, 0x7F, 0xF);
+ }
+}
-#pragma GLOBAL_ASM("asm/non_matchings/code/code_801A5BD0/func_801A7794.s")
+/**
+ * The main function to request a sfx. All sfx requests begin here.
+ */
+void AudioSfx_PlaySfx(u16 sfxId, Vec3f* pos, u8 token, f32* freqScale, f32* volume, s8* reverbAdd) {
+ u8 i;
+ SfxRequest* reqWrite;
+ SfxRequest* reqRead;
-#pragma GLOBAL_ASM("asm/non_matchings/code/code_801A5BD0/func_801A7828.s")
+ if (!gSfxBankMuted[SFX_BANK_SHIFT(sfxId)]) {
+ reqWrite = &sSfxRequests[sSfxRequestWriteIndex];
-#pragma GLOBAL_ASM("asm/non_matchings/code/code_801A5BD0/func_801A787C.s")
+ for (i = sSfxRequestReadIndex; sSfxRequestWriteIndex != i; i++) {
+ reqRead = &sSfxRequests[i];
+ if ((reqRead->pos == pos) && (reqRead->sfxId == sfxId)) {
+ return;
+ }
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/code/code_801A5BD0/Audio_IsSfxPlaying.s")
+ reqWrite->sfxId = sfxId;
+ reqWrite->pos = pos;
+ reqWrite->token = token;
+ reqWrite->freqScale = freqScale;
+ reqWrite->volume = volume;
+ reqWrite->reverbAdd = reverbAdd;
+ sSfxRequestWriteIndex++;
+ }
+}
-#pragma GLOBAL_ASM("asm/non_matchings/code/code_801A5BD0/func_801A794C.s")
+void AudioSfx_RemoveMatchingRequests(u8 aspect, SfxBankEntry* entry) {
+ SfxRequest* req;
+ s32 remove;
+ u8 i = sSfxRequestReadIndex;
+
+ for (; i != sSfxRequestWriteIndex; i++) {
+ remove = false;
+ req = &sSfxRequests[i];
+
+ switch (aspect) {
+ case SFX_RM_REQ_BY_BANK:
+ if (SFX_BANK_MASK(req->sfxId) == SFX_BANK_MASK(entry->sfxId)) {
+ remove = true;
+ }
+ break;
+
+ case SFX_RM_REQ_BY_POS_AND_BANK:
+ if ((SFX_BANK_MASK(req->sfxId) == SFX_BANK_MASK(entry->sfxId)) && (&req->pos->x == entry->posX)) {
+ remove = true;
+ }
+ break;
+
+ case SFX_RM_REQ_BY_POS:
+ if (&req->pos->x == entry->posX) {
+ remove = true;
+ }
+ break;
+
+ case SFX_RM_REQ_BY_POS_AND_ID:
+ if ((&req->pos->x == entry->posX) && (req->sfxId == entry->sfxId)) {
+ remove = true;
+ }
+ break;
+
+ case SFX_RM_REQ_BY_TOKEN_AND_ID:
+ if ((req->token == entry->token) && (req->sfxId == entry->sfxId)) {
+ remove = true;
+ }
+ break;
+
+ case SFX_RM_REQ_BY_ID:
+ if (req->sfxId == entry->sfxId) {
+ remove = true;
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ if (remove) {
+ req->sfxId = 0;
+ }
+ }
+}
+
+void AudioSfx_ProcessRequest(void) {
+ u16 sfxId;
+ u8 channelCount;
+ u8 index;
+ SfxRequest* req = &sSfxRequests[sSfxRequestReadIndex];
+ SfxBankEntry* entry;
+ SfxParams* sfxParams;
+ s32 bankId;
+ u8 evictImportance;
+ u8 evictIndex = 0x80;
+
+ if (req->sfxId == 0) {
+ return;
+ }
+
+ bankId = SFX_BANK(req->sfxId);
+ channelCount = 0;
+ index = gSfxBanks[bankId][0].next;
+
+ // Compare the sfx request to all sfx bank entries
+ while ((index != 0xFF) && (index != 0)) {
+
+ // If an existing sfx from the same source exists in the bank, then we should either:
+ // renew if it is the same sfx, check if any sfx channels are available for that bank,
+ // interrupt that sfx and replace it with the new sfx request, or drop the new sfx request.
+ if (gSfxBanks[bankId][index].posX == &req->pos->x) {
+
+ // If the new sfx has equal importance to the existing sfx,
+ // drop the request if the existing sfx has the "SFX_FLAG_BLOCK_EQUAL_IMPORTANCE" flag.
+ // Otherwise, keep processing the new sfx request
+ if ((gSfxParams[SFX_BANK_SHIFT(req->sfxId)][SFX_INDEX(req->sfxId)].params &
+ SFX_FLAG_BLOCK_EQUAL_IMPORTANCE) &&
+ (gSfxParams[SFX_BANK_SHIFT(req->sfxId)][SFX_INDEX(req->sfxId)].importance ==
+ gSfxBanks[bankId][index].sfxImportance)) {
+ // Drop the new request
+ return;
+ }
+
+ if (gSfxBanks[bankId][index].sfxId == req->sfxId) {
+ // The new sfx is the same as the existing sfx
+ // Set channelCount to max value to reprocess the sfx
+ channelCount = gUsedChannelsPerBank[gSfxChannelLayout][bankId];
+ } else {
+ // Determine which sfx to evict based on importance if there are no more channels available
+ if (channelCount == 0) {
+ // If this is the first sfx at the same source, than store the existing sfx info into evict temps
+ evictIndex = index;
+ sfxId = gSfxBanks[bankId][index].sfxId & 0xFFFF;
+ evictImportance = gSfxParams[SFX_BANK_SHIFT(sfxId)][SFX_INDEX(sfxId)].importance;
+ } else if (gSfxBanks[bankId][index].sfxImportance < evictImportance) {
+ // If a different existing sfx is at the same source, than update the evict temps if the next
+ // existing src has lower importance than the previous existing source
+ evictIndex = index;
+ sfxId = gSfxBanks[bankId][index].sfxId & 0xFFFF;
+ evictImportance = gSfxParams[SFX_BANK_SHIFT(sfxId)][SFX_INDEX(sfxId)].importance;
+ }
+
+ channelCount++;
+
+ // There are no channels available, evict the lowest importance
+ if (channelCount == gUsedChannelsPerBank[gSfxChannelLayout][bankId]) {
+ if (gSfxParams[SFX_BANK_SHIFT(req->sfxId)][SFX_INDEX(req->sfxId)].importance >= evictImportance) {
+ index = evictIndex;
+ } else {
+ index = 0;
+ }
+ }
+ }
+
+ // Process this sfx by refreshing or replacing and existing sfx
+ if (channelCount == gUsedChannelsPerBank[gSfxChannelLayout][bankId]) {
+ sfxParams = &gSfxParams[SFX_BANK_SHIFT(req->sfxId)][SFX_INDEX(req->sfxId)];
+
+ // Interrupt existing sfx and play the new sfx instead.
+ if ((req->sfxId & SFX_FLAG_MASK) || (sfxParams->flags & SFX_FLAG2_FORCE_RESET) ||
+ (index == evictIndex)) {
+
+ // Restore bgm if the sfx about to be replaced has the right flag
+ if ((gSfxBanks[bankId][index].sfxParams & SFX_FLAG_LOWER_VOLUME_BGM) &&
+ (gSfxBanks[bankId][index].state != SFX_STATE_QUEUED)) {
+ AudioSfx_RestoreBgmVolume(gSfxBanks[bankId][index].channelIndex);
+ }
+
+ gSfxBanks[bankId][index].token = req->token;
+ gSfxBanks[bankId][index].sfxId = req->sfxId;
+ gSfxBanks[bankId][index].state = SFX_STATE_QUEUED;
+ gSfxBanks[bankId][index].freshness = 2;
+ gSfxBanks[bankId][index].freqScale = req->freqScale;
+ gSfxBanks[bankId][index].volume = req->volume;
+ gSfxBanks[bankId][index].reverbAdd = req->reverbAdd;
+ gSfxBanks[bankId][index].sfxParams = sfxParams->params;
+ gSfxBanks[bankId][index].sfxFlags = sfxParams->flags;
+ gSfxBanks[bankId][index].sfxImportance = sfxParams->importance;
+ } else if (gSfxBanks[bankId][index].state == SFX_STATE_PLAYING_ONE_FRAME) {
+ // The new sfx is "one-frame" and equals the existing sfx,
+ // continue playing the "one-frame" sfx by setting "SFX_STATE_PLAYING".
+ // This will avoid triggering deletion and get "SFX_STATE_REFRESH"
+ // The state will be set back to "SFX_STATE_PLAYING_ONE_FRAME" at the end of the cycle
+ gSfxBanks[bankId][index].state = SFX_STATE_PLAYING;
+ }
+ // Terminate loop, function is finished (nothing more is processed)
+ index = 0;
+ }
+ }
+
+ if (index != 0) {
+ index = gSfxBanks[bankId][index].next;
+ }
+ }
+
+ if ((gSfxBanks[bankId][sSfxBankFreeListStart[bankId]].next != 0xFF) && (index != 0)) {
+ // Allocate from free list
+ index = sSfxBankFreeListStart[bankId];
+
+ entry = &gSfxBanks[bankId][index];
+ entry->posX = &req->pos->x;
+ entry->posY = &req->pos->y;
+ entry->posZ = &req->pos->z;
+ entry->token = req->token;
+ entry->freqScale = req->freqScale;
+ entry->volume = req->volume;
+ entry->reverbAdd = req->reverbAdd;
+
+ sfxParams = &gSfxParams[SFX_BANK_SHIFT(req->sfxId)][SFX_INDEX(req->sfxId)];
+
+ entry->sfxParams = sfxParams->params;
+ entry->sfxFlags = sfxParams->flags;
+ entry->sfxImportance = sfxParams->importance;
+ entry->sfxId = req->sfxId;
+ entry->state = SFX_STATE_QUEUED;
+ entry->freshness = 2;
+ entry->prev = sSfxBankListEnd[bankId];
+
+ gSfxBanks[bankId][sSfxBankListEnd[bankId]].next = sSfxBankFreeListStart[bankId];
+ sSfxBankListEnd[bankId] = sSfxBankFreeListStart[bankId];
+ sSfxBankFreeListStart[bankId] = gSfxBanks[bankId][sSfxBankFreeListStart[bankId]].next;
+ gSfxBanks[bankId][sSfxBankFreeListStart[bankId]].prev = 0xFF;
+
+ entry->next = 0xFF;
+ }
+}
+
+void AudioSfx_RemoveBankEntry(u8 bankId, u8 entryIndex) {
+ SfxBankEntry* entry = &gSfxBanks[bankId][entryIndex];
+ u8 i;
+
+ if (entry->sfxParams & SFX_FLAG_LOWER_VOLUME_BGM) {
+ AudioSfx_RestoreBgmVolume(entry->channelIndex);
+ }
+
+ if (entryIndex == sSfxBankListEnd[bankId]) {
+ sSfxBankListEnd[bankId] = entry->prev;
+ } else {
+ gSfxBanks[bankId][entry->next].prev = entry->prev;
+ }
+
+ gSfxBanks[bankId][entry->prev].next = entry->next;
+ entry->next = sSfxBankFreeListStart[bankId];
+ entry->prev = 0xFF;
+ gSfxBanks[bankId][sSfxBankFreeListStart[bankId]].prev = entryIndex;
+ sSfxBankFreeListStart[bankId] = entryIndex;
+ entry->state = SFX_STATE_EMPTY;
+
+ for (i = 0; i < gChannelsPerBank[gSfxChannelLayout][bankId]; i++) {
+ if (gActiveSfx[bankId][i].entryIndex == entryIndex) {
+ gActiveSfx[bankId][i].entryIndex = 0xFF;
+ i = gChannelsPerBank[gSfxChannelLayout][bankId];
+ }
+ }
+}
+
+void AudioSfx_ChooseActiveSfx(u8 bankId) {
+ u8 numChosenSfx = 0;
+ u8 numChannels;
+ u8 entryIndex;
+ u8 i;
+ u8 j;
+ u8 k;
+ u8 sfxImportance;
+ u8 needNewSfx;
+ u8 chosenEntryIndex;
+ s32 pad;
+ SfxBankEntry* entry;
+ ActiveSfx chosenSfx[MAX_CHANNELS_PER_BANK];
+ ActiveSfx* activeSfx;
+ f32 entryPosY;
+ f32 entryPosX;
+
+ for (i = 0; i < MAX_CHANNELS_PER_BANK; i++) {
+ chosenSfx[i].priority = 0x7FFFFFFF;
+ chosenSfx[i].entryIndex = 0xFF;
+ }
+
+ entryIndex = gSfxBanks[bankId][0].next;
+ k = 0;
+
+ // Delete stale sfx and prioritize remaining sfx into the gActiveSfx arrays
+ while (entryIndex != 0xFF) {
+
+ // Update the freshness for an "all-frame" sfx if it is still queued
+ if ((gSfxBanks[bankId][entryIndex].state == SFX_STATE_QUEUED) &&
+ (gSfxBanks[bankId][entryIndex].sfxId & SFX_FLAG_MASK)) {
+ gSfxBanks[bankId][entryIndex].freshness--;
+
+ // If a "one-frame" sfx is still in "SFX_STATE_PLAYING_ONE_FRAME", then remove the sfx
+ } else if (!(gSfxBanks[bankId][entryIndex].sfxId & SFX_FLAG_MASK) &&
+ (gSfxBanks[bankId][entryIndex].state == SFX_STATE_PLAYING_ONE_FRAME)) {
+ // CHAN_UPD_SCRIPT_IO (ioPort 0, force stop sfx in seq 0)
+ AudioThread_QueueCmdS8(
+ (0x6 << 24) | (SEQ_PLAYER_SFX << 16) | (gSfxBanks[bankId][entryIndex].channelIndex << 8), 0);
+ AudioSfx_RemoveBankEntry(bankId, entryIndex);
+ }
+
+ // If a "all-frame" sfx goes 2 frames in the "queued" state
+ // (because it is too low priority), then remove the sfx
+ if (gSfxBanks[bankId][entryIndex].freshness == 0) {
+ AudioSfx_RemoveBankEntry(bankId, entryIndex);
+ } else if (gSfxBanks[bankId][entryIndex].state != SFX_STATE_EMPTY) {
+ // process the entry
+ entry = &gSfxBanks[bankId][entryIndex];
+
+ // Recompute distSq each frame since the sound's position may have changed
+ // (later converted into dist)
+ if (&gSfxDefaultPos.x == entry[0].posX) {
+ entry->dist = 0.0f;
+ } else {
+ entryPosY = *entry->posY * 1;
+ entryPosX = *entry->posX * 0.5f;
+ entry->dist = (SQ(entryPosX) + SQ(entryPosY) + SQ(*entry->posZ)) / 10.0f;
+ }
+
+ // Recompute priority, possibly based on sfx position relative to the camera.
+ // (Note that the priority is the opposite of importance; lower is more preserved)
+ sfxImportance = entry->sfxImportance;
+
+ if (entry->sfxParams & SFX_FLAG_PRIORITY_NO_DIST) {
+ // Priority is independent of distance
+ entry->priority = SQ(0xFF - sfxImportance) * SQ(76);
+ } else {
+ // Priority value increases with distance (more likely to eject)
+ if (entry->dist > 0x7FFFFFD0) {
+ // max distance
+ entry->dist = 0x70000008;
+ }
+
+ entry->priority = (u32)entry->dist + (SQ(0xFF - sfxImportance) * SQ(76));
+ if (*entry->posZ < 0.0f) {
+ entry->priority += (s32)(-*entry->posZ * 6.0f);
+ }
+ }
+
+ // Sfx is too far away, do not consider for chosen sfx
+ if (entry->dist > SQ(1e5f)) {
+
+ // If too far away and also playing, stop playing
+ if (entry->state == SFX_STATE_PLAYING) {
+ // CHAN_UPD_SCRIPT_IO (ioPort 0, force stop sfx in seq 0)
+ AudioThread_QueueCmdS8((0x6 << 24) | (SEQ_PLAYER_SFX << 16) | (entry->channelIndex << 8), 0);
+ if (entry->sfxId & SFX_FLAG_MASK) {
+ AudioSfx_RemoveBankEntry(bankId, entryIndex);
+ entryIndex = k;
+ }
+ }
+ } else {
+ // Loop through all channels allocated to a specific bank
+ // Choose which sfx from gSfxBanks to play
+ // This includes all sfx requests and sfx already playing
+ // Sort all current sfx entries in gSfxBanks by priority
+ // This is where the "active" sfx are chosen
+ numChannels = gChannelsPerBank[gSfxChannelLayout][bankId];
+
+ for (i = 0; i < numChannels; i++) {
+ // Sort all sfx entries by priority
+ if (chosenSfx[i].priority >= entry->priority) {
+ // Update the number of sfx to attampt to play
+ if (numChosenSfx < gChannelsPerBank[gSfxChannelLayout][bankId]) {
+ numChosenSfx++;
+ }
+
+ for (j = numChannels - 1; j > i; j--) {
+ chosenSfx[j].priority = chosenSfx[j - 1].priority;
+ chosenSfx[j].entryIndex = chosenSfx[j - 1].entryIndex;
+ }
+
+ chosenSfx[i].priority = entry->priority;
+ chosenSfx[i].entryIndex = entryIndex;
+ i = numChannels; // make this the last pass through the loop, here equivalent to "break"
+ }
+ }
+ }
+
+ k = entryIndex;
+ }
+
+ entryIndex = gSfxBanks[bankId][k].next;
+ }
+
+ // If a sfx is chosen, update its state
+ for (i = 0; i < numChosenSfx; i++) {
+ entry = &gSfxBanks[bankId][chosenSfx[i].entryIndex];
+
+ if (entry->state == SFX_STATE_QUEUED) {
+ // sfx is a new entry
+ entry->state = SFX_STATE_READY;
+ } else if (entry->state == SFX_STATE_PLAYING) {
+ // sfx is already playing
+ entry->state = SFX_STATE_PLAYING_REFRESH;
+ }
+ }
+
+ // Apply the chosenSfx to the activeSfx in each channel
+ numChannels = gChannelsPerBank[gSfxChannelLayout][bankId];
+ for (i = 0; i < numChannels; i++) {
+ needNewSfx = false;
+ activeSfx = &gActiveSfx[bankId][i];
+
+ // Check if a sfx is already in the channel
+ if (activeSfx->entryIndex == 0xFF) {
+ // No sfx playing in the channel
+ // Available for use
+ needNewSfx = true;
+ } else {
+ // The channel is already playing a sfx
+ // Get the entry of the sfx playing
+ entry = &gSfxBanks[bankId][activeSfx[0].entryIndex];
+
+ // Check the state of the sfx playing
+ if (entry->state == SFX_STATE_PLAYING) {
+ if (entry->sfxId & SFX_FLAG_MASK) {
+ // For "all-frames" sfx, remove the entry
+ AudioSfx_RemoveBankEntry(bankId, activeSfx->entryIndex);
+ } else {
+ // For "one-frame" sfx, reset the state to queued
+ entry->state = SFX_STATE_QUEUED;
+ entry->freshness = 0x80;
+ }
+ needNewSfx = true;
+ } else if (entry->state == SFX_STATE_EMPTY) {
+ // The sfx already in the channel is empty
+ // Can replace the sfx
+ activeSfx->entryIndex = 0xFF;
+ needNewSfx = true;
+ } else {
+ // Sfx is already playing as it should, nothing to do.
+ for (j = 0; j < numChannels; j++) {
+ if (activeSfx->entryIndex == chosenSfx[j].entryIndex) {
+ chosenSfx[j].entryIndex = 0xFF;
+ j = numChannels;
+ }
+ }
+
+ numChosenSfx--;
+ }
+ }
+
+ // enter the new sfx into the activeSfx
+ if (needNewSfx == true) {
+ for (j = 0; j < numChannels; j++) {
+ chosenEntryIndex = chosenSfx[j].entryIndex;
+ if ((chosenEntryIndex != 0xFF) &&
+ (gSfxBanks[bankId][chosenEntryIndex].state != SFX_STATE_PLAYING_REFRESH)) {
+ for (k = 0; k < numChannels; k++) {
+ if (chosenEntryIndex == gActiveSfx[bankId][k].entryIndex) {
+ needNewSfx = false;
+ k = numChannels; // "break; i.e. force for-loop to end"
+ }
+ }
+
+ if (needNewSfx == true) {
+ activeSfx->entryIndex = chosenEntryIndex;
+ chosenSfx[j].entryIndex = 0xFF;
+ j = numChannels + 1;
+ numChosenSfx--;
+ }
+ }
+ }
+ if (j == numChannels) {
+ // nothing found
+ activeSfx->entryIndex = 0xFF;
+ }
+ }
+ }
+}
+
+void AudioSfx_PlayActiveSfx(u8 bankId) {
+ u8 entryIndex;
+ SequenceChannel* channel;
+ SfxBankEntry* entry;
+ u8 i;
+ u8 ioPort5Data;
+
+ for (i = 0; i < gChannelsPerBank[gSfxChannelLayout][bankId]; i++) {
+ entryIndex = gActiveSfx[bankId][i].entryIndex;
+ // If entry is not empty
+ if (entryIndex != 0xFF) {
+ entry = &gSfxBanks[bankId][entryIndex];
+ channel = gAudioContext.seqPlayers[SEQ_PLAYER_SFX].channels[sCurSfxPlayerChannelIndex];
+
+ if (entry->state == SFX_STATE_READY) {
+ // Initialize a sfx (new sfx request)
+ entry->channelIndex = sCurSfxPlayerChannelIndex;
+ if (entry->sfxParams & SFX_FLAG_LOWER_VOLUME_BGM) {
+ AudioSfx_LowerBgmVolume(sCurSfxPlayerChannelIndex);
+ }
+
+ // Add noise that will offset the frequency of the sfx
+ if ((entry->sfxParams & SFX_PARAM_RAND_FREQ_RAISE_MASK) != (0 << SFX_PARAM_RAND_FREQ_RAISE_SHIFT)) {
+ switch (entry->sfxParams & SFX_PARAM_RAND_FREQ_RAISE_MASK) {
+ case (1 << SFX_PARAM_RAND_FREQ_RAISE_SHIFT):
+ entry->randFreq = AudioThread_NextRandom() & 0xF;
+ break;
+
+ case (2 << SFX_PARAM_RAND_FREQ_RAISE_SHIFT):
+ entry->randFreq = AudioThread_NextRandom() & 0x1F;
+ break;
+
+ case (3 << SFX_PARAM_RAND_FREQ_RAISE_SHIFT):
+ entry->randFreq = AudioThread_NextRandom() & 0x3F;
+ break;
+
+ default:
+ entry->randFreq = 0;
+ break;
+ }
+ }
+
+ // Calculate all the properties of sfx
+ AudioSfx_SetProperties(bankId, entryIndex, sCurSfxPlayerChannelIndex);
+
+ // CHAN_UPD_SCRIPT_IO (ioPort 0, enable the sfx to play in seq 0)
+ AudioThread_QueueCmdS8((0x6 << 24) | (SEQ_PLAYER_SFX << 16) | ((sCurSfxPlayerChannelIndex & 0xFF) << 8),
+ 1);
+
+ // CHAN_UPD_SCRIPT_IO (ioPort 4, write the lower bits sfx index to seq 0 so it can find the right code
+ // to execute)
+ AudioThread_QueueCmdS8((0x6 << 24) | (SEQ_PLAYER_SFX << 16) |
+ ((sCurSfxPlayerChannelIndex & 0xFF) << 8) | 4,
+ entry->sfxId & 0xFF);
+
+ // If the sfx bank has more than 255 entries (greater than a u8 can store),
+ // then store the Id in upper and lower bits
+ if (gIsLargeSfxBank[bankId]) {
+ // Store upper bits
+ ioPort5Data = ((u8)((entry->sfxId & 0x300) >> 7) + (u8)((entry->sfxId & 0xFF) >> 7));
+ } else {
+ ioPort5Data = 0;
+ }
+
+ if ((entry->sfxParams & SFX_FLAG_8) && (entry->freshness == 0x80)) {
+ ioPort5Data += 0x80;
+ }
+
+ if (D_801D6608[bankId]) {
+ // CHAN_UPD_SCRIPT_IO (ioPort 5, write the upper bits sfx index and a flag to seq 0, for banks with
+ // > 0xFF entries)
+ AudioThread_QueueCmdS8((0x6 << 24) | (SEQ_PLAYER_SFX << 16) |
+ ((sCurSfxPlayerChannelIndex & 0xFF) << 8) | 5,
+ ioPort5Data);
+ }
+
+ // Update playing state
+ if (entry->sfxId & SFX_FLAG_MASK) {
+ // "all-frames" sfx
+ entry->state = SFX_STATE_PLAYING;
+ } else {
+ // "one-frame" sfx
+ entry->state = SFX_STATE_PLAYING_ONE_FRAME;
+ }
+ } else if ((u8)channel->soundScriptIO[1] == 0xFF) {
+ // Signal from seq 0 that the sfx is finished playing. Remove entry
+ AudioSfx_RemoveBankEntry(bankId, entryIndex);
+ } else if (entry->state == SFX_STATE_PLAYING_REFRESH) {
+ // Sfx is playing but a refresh is requested
+ AudioSfx_SetProperties(bankId, entryIndex, sCurSfxPlayerChannelIndex);
+
+ // Update playing state
+ if (entry->sfxId & SFX_FLAG_MASK) {
+ // "all-frames" sfx
+ entry->state = SFX_STATE_PLAYING;
+ } else {
+ // "one-frame" sfx
+ entry->state = SFX_STATE_PLAYING_ONE_FRAME;
+ }
+ }
+ }
+
+ sCurSfxPlayerChannelIndex++;
+ }
+}
+
+void AudioSfx_StopByBank(u8 bankId) {
+ SfxBankEntry* entry;
+ s32 pad;
+ SfxBankEntry entryToRemove;
+ u8 entryIndex = gSfxBanks[bankId][0].next;
+
+ while (entryIndex != 0xFF) {
+ entry = &gSfxBanks[bankId][entryIndex];
+ if (entry->state >= SFX_STATE_PLAYING_REFRESH) {
+ AudioThread_QueueCmdS8((0x6 << 24) | (SEQ_PLAYER_SFX << 16) | ((entry->channelIndex & 0xFF) << 8), 0);
+ }
+
+ if (entry->state != SFX_STATE_EMPTY) {
+ AudioSfx_RemoveBankEntry(bankId, entryIndex);
+ }
+ entryIndex = gSfxBanks[bankId][0].next;
+ }
+
+ entryToRemove.sfxId = bankId << 12;
+ AudioSfx_RemoveMatchingRequests(SFX_RM_REQ_BY_BANK, &entryToRemove);
+}
+
+void AudioSfx_StopByPosAndBankImpl(u8 bankId, Vec3f* pos) {
+ SfxBankEntry* entry;
+ u8 entryIndex = gSfxBanks[bankId][0].next;
+ u8 prevEntryIndex = 0;
+
+ while (entryIndex != 0xFF) {
+ entry = &gSfxBanks[bankId][entryIndex];
+ if (entry->posX == &pos->x) {
+ if (entry->state >= SFX_STATE_PLAYING_REFRESH) {
+ AudioThread_QueueCmdS8((0x6 << 24) | (SEQ_PLAYER_SFX << 16) | ((entry->channelIndex & 0xFF) << 8), 0);
+ }
+
+ if (entry->state != SFX_STATE_EMPTY) {
+ AudioSfx_RemoveBankEntry(bankId, entryIndex);
+ }
+ } else {
+ prevEntryIndex = entryIndex;
+ }
+
+ entryIndex = gSfxBanks[bankId][prevEntryIndex].next;
+ }
+}
+
+void AudioSfx_StopByPosAndBank(u8 bankId, Vec3f* pos) {
+ SfxBankEntry entryToRemove;
+
+ AudioSfx_StopByPosAndBankImpl(bankId, pos);
+ entryToRemove.sfxId = bankId << 12;
+ entryToRemove.posX = &pos->x;
+ AudioSfx_RemoveMatchingRequests(SFX_RM_REQ_BY_POS_AND_BANK, &entryToRemove);
+}
+
+void AudioSfx_StopByPos(Vec3f* pos) {
+ u8 bankId;
+ SfxBankEntry entryToRemove;
+
+ for (bankId = 0; bankId < ARRAY_COUNT(gSfxBanks); bankId++) {
+ AudioSfx_StopByPosAndBankImpl(bankId, pos);
+ }
+
+ entryToRemove.posX = &pos->x;
+ AudioSfx_RemoveMatchingRequests(SFX_RM_REQ_BY_POS, &entryToRemove);
+}
+
+void AudioSfx_StopByPosAndId(Vec3f* pos, u16 sfxId) {
+ SfxBankEntry* entry;
+ u8 entryIndex = gSfxBanks[SFX_BANK(sfxId)][0].next;
+ u8 prevEntryIndex = 0;
+ SfxBankEntry entryToRemove;
+
+ while (entryIndex != 0xFF) {
+ entry = &gSfxBanks[SFX_BANK(sfxId)][entryIndex];
+ if ((entry->posX == &pos->x) && (entry->sfxId == sfxId)) {
+ if (entry->state >= SFX_STATE_PLAYING_REFRESH) {
+ AudioThread_QueueCmdS8((0x6 << 24) | (SEQ_PLAYER_SFX << 16) | ((entry->channelIndex & 0xFF) << 8), 0);
+ }
+
+ if (entry->state != SFX_STATE_EMPTY) {
+ AudioSfx_RemoveBankEntry(SFX_BANK(sfxId), entryIndex);
+ }
+ entryIndex = 0xFF;
+ } else {
+ prevEntryIndex = entryIndex;
+ }
+
+ if (entryIndex != 0xFF) {
+ entryIndex = gSfxBanks[SFX_BANK(sfxId)][prevEntryIndex].next;
+ }
+ }
+
+ entryToRemove.posX = &pos->x;
+ entryToRemove.sfxId = sfxId;
+ AudioSfx_RemoveMatchingRequests(SFX_RM_REQ_BY_POS_AND_ID, &entryToRemove);
+}
+
+void AudioSfx_StopByTokenAndId(u8 token, u16 sfxId) {
+ SfxBankEntry* entry;
+ u8 entryIndex = gSfxBanks[SFX_BANK(sfxId)][0].next;
+ u8 prevEntryIndex = 0;
+ SfxBankEntry entryToRemove;
+
+ while (entryIndex != 0xFF) {
+ entry = &gSfxBanks[SFX_BANK(sfxId)][entryIndex];
+ if ((entry->token == token) && (entry->sfxId == sfxId)) {
+ if (entry->state >= SFX_STATE_PLAYING_REFRESH) {
+ AudioThread_QueueCmdS8((0x6 << 24) | (SEQ_PLAYER_SFX << 16) | ((entry->channelIndex & 0xFF) << 8), 0);
+ }
+
+ if (entry->state != SFX_STATE_EMPTY) {
+ AudioSfx_RemoveBankEntry(SFX_BANK(sfxId), entryIndex);
+ }
+ } else {
+ prevEntryIndex = entryIndex;
+ }
+
+ if (entryIndex != 0xFF) {
+ entryIndex = gSfxBanks[SFX_BANK(sfxId)][prevEntryIndex].next;
+ }
+ }
+
+ entryToRemove.token = token;
+ entryToRemove.sfxId = sfxId;
+ AudioSfx_RemoveMatchingRequests(SFX_RM_REQ_BY_TOKEN_AND_ID, &entryToRemove);
+}
+
+void AudioSfx_StopById(u32 sfxId) {
+ SfxBankEntry* entry;
+ u8 entryIndex = gSfxBanks[SFX_BANK(sfxId)][0].next;
+ u8 prevEntryIndex = 0;
+ SfxBankEntry entryToRemove;
+
+ while (entryIndex != 0xFF) {
+ entry = &gSfxBanks[SFX_BANK(sfxId)][entryIndex];
+ if (entry->sfxId == sfxId) {
+ if (entry->state >= SFX_STATE_PLAYING_REFRESH) {
+ AudioThread_QueueCmdS8((0x6 << 24) | (SEQ_PLAYER_SFX << 16) | ((entry->channelIndex & 0xFF) << 8), 0);
+ }
+ if (entry->state != SFX_STATE_EMPTY) {
+ AudioSfx_RemoveBankEntry(SFX_BANK(sfxId), entryIndex);
+ }
+ } else {
+ prevEntryIndex = entryIndex;
+ }
+
+ entryIndex = gSfxBanks[SFX_BANK(sfxId)][prevEntryIndex].next;
+ }
+
+ entryToRemove.sfxId = sfxId;
+ AudioSfx_RemoveMatchingRequests(SFX_RM_REQ_BY_ID, &entryToRemove);
+}
+
+void AudioSfx_ProcessRequests(void) {
+ if (gAudioContext.seqPlayers[SEQ_PLAYER_SFX].enabled) {
+ while (sSfxRequestWriteIndex != sSfxRequestReadIndex) {
+ AudioSfx_ProcessRequest();
+ sSfxRequestReadIndex++;
+ }
+ }
+}
+
+/**
+ * Unused
+ */
+void AudioSfx_SetBankLerp(u8 bankId, u8 target, u16 delay) {
+ if (delay == 0) {
+ delay++;
+ }
+
+ sSfxBankLerp[bankId].target = target / 127.0f;
+ sSfxBankLerp[bankId].remainingFrames = delay;
+ sSfxBankLerp[bankId].step = ((sSfxBankLerp[bankId].value - sSfxBankLerp[bankId].target) / delay);
+}
+
+/**
+ * Unused
+ */
+void AudioSfx_StepBankLerp(u8 bankId) {
+ if (sSfxBankLerp[bankId].remainingFrames != 0) {
+ sSfxBankLerp[bankId].remainingFrames--;
+
+ if (sSfxBankLerp[bankId].remainingFrames != 0) {
+ sSfxBankLerp[bankId].value -= sSfxBankLerp[bankId].step;
+ } else {
+ sSfxBankLerp[bankId].value = sSfxBankLerp[bankId].target;
+ }
+ }
+}
+
+void AudioSfx_ProcessActiveSfx(void) {
+ u8 bankId;
+
+ if (gAudioContext.seqPlayers[SEQ_PLAYER_SFX].enabled) {
+ sCurSfxPlayerChannelIndex = 0;
+
+ for (bankId = 0; bankId < ARRAY_COUNT(gSfxBanks); bankId++) {
+ AudioSfx_ChooseActiveSfx(bankId);
+ AudioSfx_PlayActiveSfx(bankId);
+ AudioSfx_StepBankLerp(bankId);
+ }
+ }
+}
+
+u8 AudioSfx_IsPlaying(u32 sfxId) {
+ SfxBankEntry* entry;
+ u8 entryIndex = gSfxBanks[SFX_BANK(sfxId)][0].next;
+
+ while (entryIndex != 0xFF) {
+ entry = &gSfxBanks[SFX_BANK(sfxId)][entryIndex];
+ if (entry->sfxId == sfxId) {
+ return true;
+ }
+ entryIndex = entry->next;
+ }
+
+ return false;
+}
+
+void AudioSfx_Reset(void) {
+ u8 bankId;
+ u8 i;
+ u8 entryIndex;
+
+ sSfxRequestWriteIndex = 0;
+ sSfxRequestReadIndex = 0;
+ sSfxChannelLowVolumeFlag = 0;
+
+ for (bankId = 0; bankId < ARRAY_COUNT(gSfxBanks); bankId++) {
+ sSfxBankListEnd[bankId] = 0;
+ sSfxBankFreeListStart[bankId] = 1;
+ sSfxBankUnused[bankId] = 0;
+ gSfxBankMuted[bankId] = false;
+ sSfxBankLerp[bankId].value = 1.0f;
+ sSfxBankLerp[bankId].remainingFrames = 0;
+ }
+
+ for (bankId = 0; bankId < ARRAY_COUNT(gSfxBanks); bankId++) {
+ for (i = 0; i < MAX_CHANNELS_PER_BANK; i++) {
+ gActiveSfx[bankId][i].entryIndex = 0xFF;
+ }
+ }
+
+ for (bankId = 0; bankId < ARRAY_COUNT(gSfxBanks); bankId++) {
+ gSfxBanks[bankId][0].prev = 0xFF;
+ gSfxBanks[bankId][0].next = 0xFF;
+
+ for (i = 1; i < sSfxBankSizes[bankId] - 1; i++) {
+ gSfxBanks[bankId][i].prev = i - 1;
+ gSfxBanks[bankId][i].next = i + 1;
+ }
+
+ gSfxBanks[bankId][i].prev = i - 1;
+ gSfxBanks[bankId][i].next = 0xFF;
+ }
+}
diff --git a/src/code/audio/code_801A7B10.c b/src/code/audio/code_801A7B10.c
index 6d3faaeab..f2f37a013 100644
--- a/src/code/audio/code_801A7B10.c
+++ b/src/code/audio/code_801A7B10.c
@@ -1,6 +1,6 @@
#include "global.h"
-#pragma GLOBAL_ASM("asm/non_matchings/code/code_801A7B10/func_801A7B10.s")
+#pragma GLOBAL_ASM("asm/non_matchings/code/code_801A7B10/Audio_StartSequence.s")
#pragma GLOBAL_ASM("asm/non_matchings/code/code_801A7B10/func_801A7D04.s")
diff --git a/src/code/audioMgr.c b/src/code/audioMgr.c
index ee6014137..ce21bda37 100644
--- a/src/code/audioMgr.c
+++ b/src/code/audioMgr.c
@@ -78,7 +78,7 @@ void AudioMgr_ThreadEntry(void* arg) {
s16* msg = NULL;
s32 exit;
- func_801A4C30();
+ Audio_Init();
AudioLoad_SetDmaHandler(DmaMgr_DmaHandler);
func_801A4D00();
osSendMesg(&audioMgr->lockMsgQ, NULL, OS_MESG_BLOCK);
diff --git a/src/code/code_80172BC0.c b/src/code/code_80172BC0.c
index 2ea9e6c67..94b55d4df 100644
--- a/src/code/code_80172BC0.c
+++ b/src/code/code_80172BC0.c
@@ -9,7 +9,7 @@ void AudioMgr_StopAllSfxExceptSystem(void) {
for (bankIdPtr = sSfxBankIds; bankIdPtr < (sSfxBankIds + ARRAY_COUNT(sSfxBankIds)); bankIdPtr++) {
if (*bankIdPtr != BANK_SYSTEM) {
- func_801A7084(*bankIdPtr);
+ AudioSfx_StopByBank(*bankIdPtr);
}
}
}
diff --git a/src/code/z_actor.c b/src/code/z_actor.c
index 751327552..fdd334b6e 100644
--- a/src/code/z_actor.c
+++ b/src/code/z_actor.c
@@ -2127,7 +2127,8 @@ void func_800B8E58(Player* player, u16 sfxId) {
if (player->currentMask == PLAYER_MASK_GIANT) {
func_8019F170(&player->actor.projectedPos, sfxId);
} else {
- Audio_PlaySfxGeneral(sfxId, &player->actor.projectedPos, 4, &D_801DB4B0, &D_801DB4B0, &gSfxDefaultReverb);
+ AudioSfx_PlaySfx(sfxId, &player->actor.projectedPos, 4, &gSfxDefaultFreqAndVolScale,
+ &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb);
}
}
@@ -2567,7 +2568,8 @@ void func_800B9D1C(Actor* actor) {
if (sfxId != 0) {
if (actor->audioFlags & 2) {
- Audio_PlaySfxGeneral(sfxId, &actor->projectedPos, 4, &D_801DB4B0, &D_801DB4B0, &gSfxDefaultReverb);
+ AudioSfx_PlaySfx(sfxId, &actor->projectedPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale,
+ &gSfxDefaultReverb);
} else if (actor->audioFlags & 4) {
play_sound(sfxId);
} else if (actor->audioFlags & 8) {
@@ -3338,7 +3340,7 @@ Actor* Actor_Delete(ActorContext* actorCtx, Actor* actor, PlayState* play) {
actorCtx->targetContext.bgmEnemy = NULL;
}
- Audio_StopSfxByPos(&actor->projectedPos);
+ AudioSfx_StopByPos(&actor->projectedPos);
Actor_Destroy(actor, play);
newHead = Actor_RemoveFromCategory(play, actorCtx, actor);
diff --git a/src/code/z_effect_soft_sprite.c b/src/code/z_effect_soft_sprite.c
index 87f1958bd..ea8a546d6 100644
--- a/src/code/z_effect_soft_sprite.c
+++ b/src/code/z_effect_soft_sprite.c
@@ -59,11 +59,11 @@ EffectSs* EffectSS_GetTable() {
void EffectSS_Delete(EffectSs* effectSs) {
if (effectSs->flags & 2) {
- Audio_StopSfxByPos(&effectSs->pos);
+ AudioSfx_StopByPos(&effectSs->pos);
}
if (effectSs->flags & 4) {
- Audio_StopSfxByPos(&effectSs->vec);
+ AudioSfx_StopByPos(&effectSs->vec);
}
EffectSS_ResetEntry(effectSs);
diff --git a/src/code/z_sound_source.c b/src/code/z_sound_source.c
index 2cdc3ab3a..15ebd018a 100644
--- a/src/code/z_sound_source.c
+++ b/src/code/z_sound_source.c
@@ -16,7 +16,7 @@ void SoundSource_UpdateAll(PlayState* play) {
for (i = 0; i < ARRAY_COUNT(play->soundSources); i++) {
if (source->countdown != 0) {
if (DECR(source->countdown) == 0) {
- Audio_StopSfxByPos(&source->projectedPos);
+ AudioSfx_StopByPos(&source->projectedPos);
} else {
SkinMatrix_Vec3fMtxFMultXYZ(&play->viewProjectionMtxF, &source->worldPos, &source->projectedPos);
if (source->playSfxEachFrame) {
@@ -54,7 +54,7 @@ void SoundSource_Add(PlayState* play, Vec3f* worldPos, u32 duration, u16 sfxId,
// If no sound source is available, replace the sound source with the smallest remaining countdown
if (i >= ARRAY_COUNT(play->soundSources)) {
source = backupSource;
- Audio_StopSfxByPos(&source->projectedPos);
+ AudioSfx_StopByPos(&source->projectedPos);
}
source->worldPos = *worldPos;