mirror of
https://github.com/izzy2lost/Starship.git
synced 2026-07-05 15:19:42 -07:00
2836 lines
107 KiB
C
2836 lines
107 KiB
C
#include "sys.h"
|
|
#include "sf64audio_provisional.h"
|
|
#include "context.h"
|
|
#include "audiothread_cmd.h"
|
|
#include "audioseq_cmd.h"
|
|
|
|
void Audio_SetModulationAndPlaySfx(f32* sfxSource, u32 sfxId, f32 freqMod);
|
|
s32 Audio_GetCurrentVoice(void);
|
|
void Audio_PlaySequence(u8, u16, u8, u8);
|
|
void Audio_PlayFanfare(u16, u8, u8, u8);
|
|
void Audio_PlaySequenceDistorted(u8, u16, u16, u8, u8);
|
|
|
|
void Audio_RestartSeqPlayers(void);
|
|
void Audio_PlayMapMenuSfx(u8);
|
|
void Audio_StartReset(u8);
|
|
|
|
static const char devstr1[] = "preload start (%d): ";
|
|
static const char devstr2[] = "%d ";
|
|
static const char devstr3[] = "\n";
|
|
static const char devstr4[] = "***** START SEQ : %d *****\n";
|
|
static const char devstr5[] = "spec change finished !!!\n";
|
|
static const char devstr6[] = "interface wait spec change finished !!!\n";
|
|
static const char devstr7[] = "********** SE Interface Buffer SE Stop %08X **********\n";
|
|
static const char devstr8[] = "MedlayStart : \n";
|
|
static const char devstr9[] = "MedlayStart : \n";
|
|
static const char devstr10[] = "MedlayStart(TuneUp) : \n";
|
|
static const char devstr11[] = "MedlayStart(cross) : \n";
|
|
static const char devstr12[] = "MedlayEnd : \n";
|
|
static const char devstr13[] = "MedlayWait : %d\n";
|
|
static const char devstr14[] = "ControlSePicth : %f %f %f \n";
|
|
static const char devstr15[] = "ChangeWarningSePara : %d %d\n";
|
|
static const char devstr16[] = "set Grp 0 port %02x \n";
|
|
static const char devstr17[] = "main BGM start %08X\n";
|
|
static const char devstr18[] = "<<<<< PlayCrossMixBgm pass !!! >>>>>\n";
|
|
static const char devstr19[] = "SetVolumeBallnce %d %d\n";
|
|
static const char devstr20[] = "START HANDLE : %d (old:%d)\n";
|
|
static const char devstr21[] = "All Sound Fade Out time:%d\n";
|
|
|
|
SfxRequest sSfxRequests[256];
|
|
SfxBankEntry sSfxBanks[5][20];
|
|
u8 sSfxBankListEnd[5];
|
|
u8 sSfxBankFreeListStart[5];
|
|
u8 sSfxBankUnused[5];
|
|
ActiveSfx sActiveSfx[5][8];
|
|
u8 sCurSfxPlayerChannelIndex;
|
|
u8 sSfxBankMuted[5];
|
|
Modulation sSfxVolumeMods[5];
|
|
f32 sAudioAnalyzerData[256];
|
|
f32 sAnalyzerBuffer1[256];
|
|
f32 sAnalyzerBuffer2[384];
|
|
f32 sNewFreqAmplitudes[32];
|
|
u8 sFreqAnalyzerBars[32];
|
|
SeqRequest sSeqRequests[SEQ_PLAYER_MAX][5];
|
|
u8 sNumSeqRequests[SEQ_PLAYER_MAX];
|
|
s32 sAudioSeqCmds[256];
|
|
ActiveSequence sActiveSequences[SEQ_PLAYER_MAX];
|
|
u16 sDelayedSeqCmdFlags;
|
|
DelayedSeqCmd sDelayedSeqCmds[16];
|
|
SfxChannelState sSfxChannelState[16];
|
|
PlayerNoiseModulation sPlayerNoise[4];
|
|
f32 sBombFreqMod[4];
|
|
u8 sBombType[4];
|
|
u8 sBombState[4];
|
|
s32 sBombStartFrame[4];
|
|
|
|
u8 sChannelsPerBank[5][5] = {
|
|
{ 3, 2, 2, 2, 2 }, { 3, 1, 2, 2, 2 }, { 3, 2, 2, 2, 3 }, { 6, 0, 2, 0, 4 }, { 0, 0, 0, 0, 0 },
|
|
};
|
|
u8 sUsedChannelsPerBank[5][5] = {
|
|
{ 3, 2, 1, 2, 3 }, { 3, 2, 1, 1, 2 }, { 3, 2, 1, 1, 3 }, { 2, 0, 1, 0, 1 }, { 0, 0, 0, 0, 0 },
|
|
};
|
|
u8 sSfxRequestWriteIndex = 0;
|
|
u8 sSfxRequestReadIndex = 0;
|
|
u8 sSfxChannelLayout = SFXCHAN_0;
|
|
u16 sChannelMuteFlags = 0;
|
|
f32 gDefaultSfxSource[3] = { 0.0f, 0.0f, 0.0f };
|
|
f32 gDefaultMod = 1.0f;
|
|
s32 D_800C5D38 = 0; // unused. perhaps a default pan?
|
|
s8 gDefaultReverb = 0;
|
|
s32 sAudioFrameCounter = 0;
|
|
u8 sSeqCmdWritePos = 0;
|
|
u8 sSeqCmdReadPos = 0;
|
|
u8 sStartSeqDisabled = 0;
|
|
u8 sSoundModeList[4] = { SOUNDMODE_STEREO, SOUNDMODE_HEADSET, SOUNDMODE_SURROUND, SOUNDMODE_MONO };
|
|
u8 sAudioSpecId = AUDIOSPEC_0;
|
|
u8 sAudioResetStatus = AUDIORESET_READY;
|
|
s32 D_800C5D5C = 0; // unused. file split?
|
|
s8 sEnvReverb = 0;
|
|
s8 sAudioSpecReverb = 0;
|
|
u8 sVolumeSettings[3] = { 99, 99, 99 };
|
|
u8 sAudioSpecInstrumentSets[29][7] = {
|
|
{ 0, 3, 4, 80, 12, 21, 255 }, { 17, 18, 15, 96, 20, 22, 255 }, { 0, 3, 5, 80, 16, 255, 0 },
|
|
{ 17, 18, 15, 96, 20, 22, 255 }, { 0, 3, 4, 80, 12, 21, 255 }, { 17, 18, 15, 96, 20, 22, 255 },
|
|
{ 0, 3, 4, 80, 12, 21, 255 }, { 17, 18, 15, 96, 20, 22, 255 }, { 0, 3, 4, 80, 12, 21, 255 },
|
|
{ 0, 3, 4, 80, 12, 21, 255 }, { 17, 18, 15, 96, 20, 22, 255 }, { 0, 3, 4, 80, 12, 21, 255 },
|
|
{ 17, 18, 95, 96, 41, 255, 0 }, { 17, 18, 15, 96, 20, 22, 255 }, { 0, 3, 5, 80, 16, 255, 0 },
|
|
{ 0, 3, 4, 80, 12, 21, 255 }, { 0, 3, 4, 80, 12, 21, 255 }, { 17, 18, 15, 96, 20, 22, 255 },
|
|
{ 0, 3, 4, 80, 12, 21, 255 }, { 0, 3, 4, 80, 12, 21, 255 }, { 0, 3, 4, 80, 12, 21, 255 },
|
|
{ 255, 0, 0, 0, 0, 0, 0 }, { 255, 0, 0, 0, 0, 0, 0 }, { 255, 0, 0, 0, 0, 0, 0 },
|
|
{ 255, 0, 0, 0, 0, 0, 0 }, { 255, 0, 0, 0, 0, 0, 0 }, { 255, 0, 0, 0, 0, 0, 0 },
|
|
{ 255, 0, 0, 0, 0, 0, 0 }, { 0, 3, 4, 80, 12, 21, 255 },
|
|
};
|
|
s8 sAudioSpecReverbAdd[29] = {
|
|
10, 0, 25, 0, 25, 0, 10, 0, 10, 35, 0, 10, 40, 0, 25, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
};
|
|
u32 sPlayerNoiseTimes[5] = { 20, 16, 10, 10, 20 };
|
|
s32 D_800C5E6C = 0; // unused. file split?
|
|
u8 D_800C5E70 = 0;
|
|
f32 sSfxFreqMod = 1.0f;
|
|
f32 sSfxVolMod = 1.0f; // never modified
|
|
u8 sPlaylistIndex = 255;
|
|
s32 sPlaylistTimer = 0;
|
|
u8 sPlaylistCmdIndex = 0;
|
|
u32 sEventSfx[] = {
|
|
NA_SE_OB_SLIDE_OPEN, NA_SE_OB_SLIDE_CLOSE,
|
|
NA_SE_OB_STEELFRAME, NA_SE_OB_HEAVY_BOUND,
|
|
NA_SE_ITEM_APPEAR, NA_SE_OB_BLOCK_APPEAR,
|
|
NA_SE_OB_ROCKWALL_UP, NA_SE_EN_UNIT_GATHERING,
|
|
NA_SE_EN_MOTOR_STOP, NA_SE_EN_MS_DASH,
|
|
NA_SE_OB_ROCK_CRASH, NA_SE_OB_ROCK_EYE_OPEN,
|
|
NA_SE_OB_SHIP_FALLDOWN, NA_SE_OB_ROCK_BOUND,
|
|
NA_SE_OB_SPEAR_PILLAR, NA_SE_OB_PILLAR_ROLL,
|
|
NA_SE_SEARCHLIGHT_MISS, NA_SE_OB_ROUTEGATE_OPEN_Q,
|
|
NA_SE_OB_ROUTEGATE_CLOSE_Q, NA_SE_OB_ROUTEGATE_OPEN_S,
|
|
NA_SE_OB_ROUTEGATE_CLOSE_S, NA_SE_OB_LIFT,
|
|
NA_SE_OB_PLATE_ROLL,
|
|
};
|
|
SoundTestTrack sSoundTestTracks[] = {
|
|
/* 0 */ { NA_BGM_OPENING, AUDIOSPEC_22 | (SFXCHAN_0 << 8), -1 },
|
|
/* 1 */ { NA_BGM_TITLE, AUDIOSPEC_23 | (SFXCHAN_0 << 8), -1 },
|
|
/* 2 */ { NA_BGM_SELECT, AUDIOSPEC_23 | (SFXCHAN_0 << 8), -1 },
|
|
/* 3 */ { NA_BGM_MAP, AUDIOSPEC_24 | (SFXCHAN_1 << 8), -1 },
|
|
/* 4 */ { NA_BGM_START_DEMO, AUDIOSPEC_0 | (SFXCHAN_0 << 8), -1 },
|
|
/* 5 */ { NA_BGM_START_DEMO_S, AUDIOSPEC_1 | (SFXCHAN_0 << 8), -1 },
|
|
/* 6 */ { NA_BGM_START_DEMO_M, AUDIOSPEC_1 | (SFXCHAN_0 << 8), -1 },
|
|
/* 7 */ { NA_BGM_ME_START_DEMO, AUDIOSPEC_1 | (SFXCHAN_0 << 8), -1 },
|
|
/* 8 */ { NA_BGM_FO_START_DEMO, AUDIOSPEC_8 | (SFXCHAN_0 << 8), -1 },
|
|
/* 9 */ { NA_BGM_STAGE_CO, AUDIOSPEC_0 | (SFXCHAN_0 << 8), -1 },
|
|
/* 10 */ { NA_BGM_STAGE_ME, AUDIOSPEC_1 | (SFXCHAN_0 << 8), -1 },
|
|
/* 11 */ { NA_BGM_STAGE_TI, AUDIOSPEC_2 | (SFXCHAN_0 << 8), -1 },
|
|
/* 12 */ { NA_BGM_STAGE_SX, AUDIOSPEC_3 | (SFXCHAN_0 << 8), -1 },
|
|
/* 13 */ { NA_BGM_STAGE_ZO, AUDIOSPEC_4 | (SFXCHAN_0 << 8), -1 },
|
|
/* 14 */ { NA_BGM_STAGE_A6, AUDIOSPEC_5 | (SFXCHAN_0 << 8), -1 },
|
|
/* 15 */ { NA_BGM_STAGE_VE1, AUDIOSPEC_6 | (SFXCHAN_0 << 8), -1 },
|
|
/* 16 */ { NA_BGM_STAGE_SY, AUDIOSPEC_7 | (SFXCHAN_0 << 8), -1 },
|
|
/* 17 */ { NA_BGM_STAGE_FO, AUDIOSPEC_8 | (SFXCHAN_0 << 8), -1 },
|
|
/* 18 */ { NA_BGM_STAGE_BO, AUDIOSPEC_10 | (SFXCHAN_0 << 8), -1 },
|
|
/* 19 */ { NA_BGM_STAGE_KA, AUDIOSPEC_11 | (SFXCHAN_0 << 8), -1 },
|
|
/* 20 */ { NA_BGM_STAGE_AQ, AUDIOSPEC_12 | (SFXCHAN_0 << 8), -1 },
|
|
/* 21 */ { NA_BGM_STAGE_WZ, AUDIOSPEC_1 | (SFXCHAN_0 << 8), -1 },
|
|
/* 22 */ { NA_BGM_KATT, AUDIOSPEC_13 | (SFXCHAN_0 << 8), -1 },
|
|
/* 23 */ { NA_BGM_BILL, AUDIOSPEC_11 | (SFXCHAN_0 << 8), -1 },
|
|
/* 24 */ { NA_BGM_BOSS_CO, AUDIOSPEC_0 | (SFXCHAN_0 << 8), -1 },
|
|
/* 25 */ { NA_BGM_BOSS_ME, AUDIOSPEC_1 | (SFXCHAN_0 << 8), 0 },
|
|
/* 26 */ { NA_BGM_BOSS_ME, AUDIOSPEC_1 | (SFXCHAN_0 << 8), -1 },
|
|
/* 27 */ { NA_BGM_REAL_BOSS, AUDIOSPEC_7 | (SFXCHAN_0 << 8), -1 },
|
|
/* 28 */ { NA_BGM_BOSS_BO, AUDIOSPEC_10 | (SFXCHAN_0 << 8), -1 },
|
|
/* 29 */ { NA_BGM_STARWOLF, AUDIOSPEC_6 | (SFXCHAN_0 << 8), -1 },
|
|
/* 30 */ { NA_BGM_COURSE_CLEAR, AUDIOSPEC_0 | (SFXCHAN_0 << 8), -1 },
|
|
/* 31 */ { NA_BGM_COURSE_FAILURE, AUDIOSPEC_0 | (SFXCHAN_0 << 8), -1 },
|
|
/* 32 */ { NA_BGM_PLAYER_DOWN, AUDIOSPEC_0 | (SFXCHAN_0 << 8), -1 },
|
|
/* 33 */ { NA_BGM_GAME_OVER, AUDIOSPEC_25 | (SFXCHAN_0 << 8), -1 },
|
|
/* 34 */ { NA_BGM_TRAINING, AUDIOSPEC_28 | (SFXCHAN_0 << 8), -1 },
|
|
/* 35 */ { NA_BGM_BATTLE, AUDIOSPEC_16 | (SFXCHAN_3 << 8), -1 },
|
|
/* 36 */ { NA_BGM_BATTLE_LAST, AUDIOSPEC_17 | (SFXCHAN_3 << 8), -1 },
|
|
/* 37 */ { NA_BGM_VS_SELECT, AUDIOSPEC_23 | (SFXCHAN_0 << 8), -1 },
|
|
/* 38 */ { NA_BGM_DASH_INTO_BASE, AUDIOSPEC_6 | (SFXCHAN_0 << 8), 0 },
|
|
/* 39 */ { NA_BGM_STAGE_ANDROSS, AUDIOSPEC_23 | (SFXCHAN_0 << 8), -1 },
|
|
/* 40 */ { NA_BGM_BOSS_ANDROSS, AUDIOSPEC_6 | (SFXCHAN_0 << 8), 0 },
|
|
/* 41 */ { NA_BGM_BOSS_ANDROSS, AUDIOSPEC_6 | (SFXCHAN_0 << 8), -1 },
|
|
/* 42 */ { NA_BGM_ANDROSS_BRAIN, AUDIOSPEC_6 | (SFXCHAN_0 << 8), -1 },
|
|
/* 43 */ { NA_BGM_ALL_CLEAR, AUDIOSPEC_6 | (SFXCHAN_0 << 8), -1 },
|
|
/* 44 */ { NA_BGM_STAFF_ROLL, AUDIOSPEC_27 | (SFXCHAN_0 << 8), -1 },
|
|
};
|
|
|
|
PlaylistCmd sPlaylists[][100] = {
|
|
{
|
|
{ 0, 0, NA_BGM_START_DEMO, 0, 255, 1620 }, { 0, 0, NA_BGM_STAGE_CO, 0, 255, 2490 },
|
|
{ 1, 0, NA_BGM_STAGE_CO, 50, 255, 50 }, { 0, 0, NA_BGM_BOSS_CO, 0, 255, 1600 },
|
|
{ 1, 0, NA_BGM_BOSS_CO, 1, 255, 50 }, { 0, 0, NA_BGM_COURSE_CLEAR, 0, 255, 1091 },
|
|
{ 1, 0, NA_BGM_COURSE_CLEAR, 100, 255, 100 }, { 0, 0, NA_BGM_ME_START_DEMO, 0, 255, 838 },
|
|
{ 0, 0, NA_BGM_STAGE_ME, 0, 255, 1584 }, { 1, 0, NA_BGM_STAGE_ME, 50, 255, 50 },
|
|
{ 0, 0, NA_BGM_BOSS_ME, 0, 0, 1620 }, { 1, 0, NA_BGM_BOSS_ME, 1, 255, 50 },
|
|
{ 0, 0, NA_BGM_REAL_BOSS, 0, 255, 1620 }, { 1, 0, NA_BGM_REAL_BOSS, 1, 255, 50 },
|
|
{ 0, 0, NA_BGM_COURSE_CLEAR, 0, 255, 1091 }, { 1, 0, NA_BGM_COURSE_CLEAR, 100, 255, 100 },
|
|
{ 0, 0, NA_BGM_FO_START_DEMO, 0, 255, 241 }, { 0, 0, NA_BGM_STAGE_FO, 0, 255, 1632 },
|
|
{ 1, 0, NA_BGM_STAGE_FO, 100, 255, 100 }, { 0, 0, NA_BGM_STARWOLF, 0, 255, 2120 },
|
|
{ 0, 0, NA_BGM_STAGE_FO, 0, 0, 450 }, { 1, 0, NA_BGM_STAGE_FO, 50, 255, 200 },
|
|
{ 0, 0, NA_BGM_COURSE_FAILURE, 0, 255, 1604 }, { 1, 0, NA_BGM_COURSE_FAILURE, 100, 255, 100 },
|
|
{ 0, 0, NA_BGM_START_DEMO_S, 0, 255, 242 }, { 0, 0, NA_BGM_STAGE_SX, 0, 255, 2291 },
|
|
{ 1, 0, NA_BGM_STAGE_SX, 50, 255, 100 }, { 0, 0, NA_BGM_BOSS_SX, 0, 255, 1600 },
|
|
{ 1, 0, NA_BGM_BOSS_SX, 1, 255, 50 }, { 2, 0, NA_BGM_BOSS_SX, 0, 255, 1600 },
|
|
{ 1, 0, NA_BGM_BOSS_SX, 1, 255, 50 }, { 0, 0, NA_BGM_COURSE_CLEAR, 0, 255, 1091 },
|
|
{ 1, 0, NA_BGM_COURSE_CLEAR, 100, 255, 100 }, { 0, 0, NA_BGM_START_DEMO_M, 0, 255, 542 },
|
|
{ 0, 0, NA_BGM_STAGE_TI, 0, 255, 1920 }, { 1, 0, NA_BGM_STAGE_TI, 50, 255, 50 },
|
|
{ 0, 0, NA_BGM_BOSS_TI, 0, 255, 1600 }, { 1, 0, NA_BGM_BOSS_TI, 1, 255, 50 },
|
|
{ 0, 0, NA_BGM_COURSE_CLEAR, 0, 255, 1091 }, { 1, 0, NA_BGM_COURSE_CLEAR, 100, 255, 100 },
|
|
{ 0, 0, NA_BGM_BO_START_DEMO, 0, 255, 241 }, { 0, 0, NA_BGM_STAGE_BO, 0, 255, 1177 },
|
|
{ 1, 0, NA_BGM_STAGE_BO, 100, 255, 100 }, { 0, 0, NA_BGM_BOSS_BO, 0, 255, 1115 },
|
|
{ 1, 0, NA_BGM_BOSS_BO, 50, 255, 50 }, { 0, 0, NA_BGM_STARWOLF, 0, 255, 2120 },
|
|
{ 1, 0, NA_BGM_STARWOLF, 1, 255, 50 }, { 0, 0, NA_BGM_PLAYER_DOWN, 0, 255, 150 },
|
|
{ 0, 0, NA_BGM_GAME_OVER, 0, 255, 1020 }, { 1, 0, NA_BGM_GAME_OVER, 100, 255, 100 },
|
|
{ 255, 0, NA_BGM_STAGE_CO, 50, 255, 50 },
|
|
},
|
|
{
|
|
{ 0, 0, NA_BGM_START_DEMO, 0, 255, 1620 },
|
|
{ 0, 0, NA_BGM_STAGE_CO, 0, 255, 2490 },
|
|
{ 1, 0, NA_BGM_STAGE_CO, 50, 255, 50 },
|
|
{ 0, 0, NA_BGM_BOSS_A_CARRIER, 0, 255, 1620 },
|
|
{ 1, 0, NA_BGM_BOSS_A_CARRIER, 1, 255, 50 },
|
|
{ 0, 0, NA_BGM_COURSE_CLEAR, 0, 255, 1091 },
|
|
{ 1, 0, NA_BGM_COURSE_CLEAR, 100, 255, 100 },
|
|
{ 0, 0, NA_BGM_START_DEMO_S, 0, 255, 242 },
|
|
{ 0, 0, NA_BGM_STAGE_SY, 0, 255, 2096 },
|
|
{ 1, 0, NA_BGM_STAGE_SY, 50, 255, 50 },
|
|
{ 0, 0, NA_BGM_BOSS_SY, 0, 2, 1600 },
|
|
{ 1, 0, NA_BGM_BOSS_SY, 1, 255, 50 },
|
|
{ 0, 0, NA_BGM_REAL_BOSS, 0, 255, 1600 },
|
|
{ 1, 0, NA_BGM_REAL_BOSS, 1, 255, 50 },
|
|
{ 0, 0, NA_BGM_COURSE_CLEAR, 0, 255, 1091 },
|
|
{ 1, 0, NA_BGM_COURSE_CLEAR, 100, 255, 100 },
|
|
{ 0, 0, NA_BGM_KA_START_DEMO, 0, 255, 241 },
|
|
{ 0, 0, NA_BGM_STAGE_KA, 0, 255, 2184 },
|
|
{ 1, 0, NA_BGM_STAGE_KA, 1, 255, 100 },
|
|
{ 0, 0, NA_BGM_BOSS_KA, 0, 1, 1115 },
|
|
{ 1, 0, NA_BGM_BOSS_KA, 50, 255, 100 },
|
|
{ 0, 0, NA_BGM_COURSE_CLEAR, 0, 255, 1091 },
|
|
{ 1, 0, NA_BGM_COURSE_CLEAR, 100, 255, 100 },
|
|
{ 0, 0, NA_BGM_SO_START_DEMO, 0, 255, 250 },
|
|
{ 0, 0, NA_BGM_STAGE_SO, 0, 255, 1096 },
|
|
{ 3, 0, NA_BGM_BILL, 0, 255, 1000 },
|
|
{ 1, 0, NA_BGM_STAGE_SO, 50, 255, 50 },
|
|
{ 0, 0, NA_BGM_BOSS_SO, 0, 255, 1600 },
|
|
{ 1, 0, NA_BGM_BOSS_SO, 1, 255, 50 },
|
|
{ 0, 0, NA_BGM_COURSE_CLEAR, 0, 255, 1091 },
|
|
{ 1, 0, NA_BGM_COURSE_CLEAR, 100, 255, 100 },
|
|
{ 0, 0, NA_BGM_START_DEMO_S, 0, 255, 260 },
|
|
{ 0, 0, NA_BGM_STAGE_MA, 0, 255, 1920 },
|
|
{ 1, 0, NA_BGM_STAGE_MA, 50, 255, 50 },
|
|
{ 0, 0, NA_BGM_BOSS_MA, 0, 255, 1600 },
|
|
{ 1, 0, NA_BGM_BOSS_MA, 1, 255, 50 },
|
|
{ 0, 0, NA_BGM_COURSE_CLEAR, 0, 255, 1091 },
|
|
{ 1, 0, NA_BGM_COURSE_CLEAR, 100, 255, 100 },
|
|
{ 0, 0, NA_BGM_BO_START_DEMO, 0, 255, 241 },
|
|
{ 0, 0, NA_BGM_STAGE_BO, 0, 255, 1177 },
|
|
{ 1, 0, NA_BGM_STAGE_BO, 100, 255, 100 },
|
|
{ 0, 0, NA_BGM_BOSS_BO, 0, 255, 1115 },
|
|
{ 1, 0, NA_BGM_BOSS_BO, 50, 255, 50 },
|
|
{ 0, 0, NA_BGM_STARWOLF, 0, 255, 2120 },
|
|
{ 1, 0, NA_BGM_STARWOLF, 1, 255, 50 },
|
|
{ 0, 0, NA_BGM_COURSE_CLEAR, 0, 255, 1091 },
|
|
{ 1, 0, NA_BGM_COURSE_CLEAR, 100, 255, 100 },
|
|
{ 0, 0, NA_BGM_STAGE_VE1, 0, 255, 1671 },
|
|
{ 1, 0, NA_BGM_STAGE_VE1, 50, 255, 50 },
|
|
{ 0, 0, NA_BGM_BOSS_VE, 0, 255, 1600 },
|
|
{ 1, 0, NA_BGM_BOSS_VE, 1, 255, 50 },
|
|
{ 0, 0, NA_BGM_DASH_INTO_BASE, 0, 0, 176 },
|
|
{ 0, 0, NA_BGM_STAGE_ANDROSS, 0, 255, 588 },
|
|
{ 0, 0, NA_BGM_BOSS_ANDROSS, 0, 0, 2420 },
|
|
{ 1, 0, NA_BGM_BOSS_ANDROSS, 10, 255, 50 },
|
|
{ 0, 0, NA_BGM_BOSS_ANDROSS, 0, 255, 1200 },
|
|
{ 1, 0, NA_BGM_BOSS_ANDROSS, 1, 255, 150 },
|
|
{ 0, 0, NA_BGM_ALL_CLEAR, 0, 255, 1091 },
|
|
{ 1, 0, NA_BGM_ALL_CLEAR, 80, 255, 160 },
|
|
{ 0, 0, NA_BGM_STAFF_ROLL, 0, 255, 9500 },
|
|
{ 255, 0, NA_BGM_STAGE_CO, 50, 255, 50 },
|
|
{ 0 },
|
|
{ 0 },
|
|
{ 0 },
|
|
{ 0 },
|
|
{ 0 },
|
|
{ 0 },
|
|
{ 0 },
|
|
{ 0 },
|
|
{ 0 },
|
|
{ 0 },
|
|
{ 0 },
|
|
{ 0 },
|
|
{ 0 },
|
|
{ 0 },
|
|
{ 0 },
|
|
{ 0 },
|
|
{ 0 },
|
|
{ 0 },
|
|
{ 0 },
|
|
{ 0 },
|
|
{ 0 },
|
|
{ 0 },
|
|
{ 0 },
|
|
{ 0 },
|
|
{ 0 },
|
|
{ 0 },
|
|
{ 0 },
|
|
{ 0 },
|
|
{ 0 },
|
|
{ 0 },
|
|
{ 0 },
|
|
{ 0 },
|
|
{ 0 },
|
|
{ 0 },
|
|
{ 0 },
|
|
{ 0 },
|
|
{ 0 },
|
|
{ 0 },
|
|
{ 0 },
|
|
},
|
|
{
|
|
{ 0, 0, NA_BGM_START_DEMO, 0, 255, 1620 }, { 0, 0, NA_BGM_STAGE_CO, 0, 255, 2490 },
|
|
{ 1, 0, NA_BGM_STAGE_CO, 50, 255, 50 }, { 0, 0, NA_BGM_BOSS_A_CARRIER, 0, 255, 1620 },
|
|
{ 1, 0, NA_BGM_BOSS_A_CARRIER, 1, 255, 50 }, { 0, 0, NA_BGM_COURSE_CLEAR, 0, 255, 1091 },
|
|
{ 1, 0, NA_BGM_COURSE_CLEAR, 100, 255, 100 }, { 0, 0, NA_BGM_START_DEMO_S, 0, 255, 260 },
|
|
{ 0, 0, NA_BGM_STAGE_SY, 0, 255, 2096 }, { 1, 0, NA_BGM_STAGE_SY, 50, 255, 50 },
|
|
{ 0, 0, NA_BGM_BOSS_SY, 0, 2, 1590 }, { 1, 0, NA_BGM_BOSS_SY, 1, 255, 50 },
|
|
{ 0, 0, NA_BGM_REAL_BOSS, 0, 255, 1600 }, { 1, 0, NA_BGM_REAL_BOSS, 1, 255, 50 },
|
|
{ 0, 0, NA_BGM_COURSE_CLEAR, 0, 255, 1091 }, { 1, 0, NA_BGM_COURSE_CLEAR, 100, 255, 100 },
|
|
{ 0, 0, NA_BGM_START_DEMO_S, 0, 255, 260 }, { 0, 0, NA_BGM_STAGE_AQ, 0, 255, 2400 },
|
|
{ 1, 0, NA_BGM_STAGE_AQ, 150, 255, 200 }, { 0, 0, NA_BGM_BOSS_AQ, 0, 1, 1590 },
|
|
{ 1, 0, NA_BGM_BOSS_AQ, 1, 255, 50 }, { 0, 0, NA_BGM_COURSE_CLEAR, 0, 255, 1091 },
|
|
{ 1, 0, NA_BGM_COURSE_CLEAR, 100, 255, 100 }, { 0, 0, NA_BGM_START_DEMO_S, 0, 255, 260 },
|
|
{ 0, 0, NA_BGM_STAGE_ZO, 0, 255, 1005 }, { 3, 0, NA_BGM_KATT, 0, 255, 1000 },
|
|
{ 1, 0, NA_BGM_STAGE_ZO, 50, 255, 100 }, { 0, 0, NA_BGM_BOSS_ZO, 0, 255, 1600 },
|
|
{ 1, 0, NA_BGM_BOSS_ZO, 1, 255, 50 }, { 0, 0, NA_BGM_COURSE_CLEAR, 0, 255, 1091 },
|
|
{ 1, 0, NA_BGM_COURSE_CLEAR, 100, 255, 100 }, { 0, 0, NA_BGM_SZ_START_DEMO, 0, 255, 241 },
|
|
{ 0, 0, NA_BGM_STAGE_SZ, 0, 255, 1632 }, { 1, 0, NA_BGM_STAGE_SZ, 50, 255, 100 },
|
|
{ 0, 0, NA_BGM_BOSS_SZ, 0, 1, 1310 }, { 3, 0, NA_BGM_KATT, 0, 255, 500 },
|
|
{ 1, 0, NA_BGM_BOSS_SZ, 1, 255, 50 }, { 0, 0, NA_BGM_COURSE_CLEAR, 0, 255, 1091 },
|
|
{ 1, 0, NA_BGM_COURSE_CLEAR, 100, 255, 100 }, { 0, 0, NA_BGM_A6_START_DEMO, 0, 255, 241 },
|
|
{ 0, 0, NA_BGM_STAGE_A6, 0, 255, 1906 }, { 1, 0, NA_BGM_STAGE_A6, 50, 255, 100 },
|
|
{ 0, 0, NA_BGM_BOSS_A6, 0, 1, 1590 }, { 1, 0, NA_BGM_BOSS_A6, 1, 255, 50 },
|
|
{ 0, 0, NA_BGM_COURSE_CLEAR, 0, 255, 1091 }, { 1, 0, NA_BGM_COURSE_CLEAR, 100, 255, 100 },
|
|
{ 0, 0, NA_BGM_STARWOLF, 0, 255, 2120 }, { 1, 0, NA_BGM_STARWOLF, 30, 255, 150 },
|
|
{ 0, 0, NA_BGM_DASH_INTO_BASE, 0, 0, 176 }, { 0, 0, NA_BGM_STAGE_ANDROSS, 0, 255, 588 },
|
|
{ 0, 0, NA_BGM_BOSS_ANDROSS, 0, 0, 2392 }, { 1, 0, NA_BGM_BOSS_ANDROSS, 10, 255, 50 },
|
|
{ 0, 0, NA_BGM_ANDROSS_BRAIN, 0, 255, 1700 }, { 1, 0, NA_BGM_BOSS_ANDROSS, 10, 255, 250 },
|
|
{ 0, 0, NA_BGM_BOSS_A6, 0, 255, 1600 }, { 1, 0, NA_BGM_BOSS_A6, 1, 255, 50 },
|
|
{ 0, 0, NA_BGM_ALL_CLEAR, 0, 255, 1091 }, { 1, 0, NA_BGM_ALL_CLEAR, 80, 255, 160 },
|
|
{ 0, 0, NA_BGM_STAFF_ROLL, 0, 255, 9250 }, { 255, 0, NA_BGM_STAGE_CO, 50, 255, 50 },
|
|
},
|
|
{
|
|
{ 0, 0, NA_BGM_START_DEMO, 0, 255, 1620 }, { 0, 0, NA_BGM_STAGE_CO, 0, 255, 2490 },
|
|
{ 1, 0, NA_BGM_STAGE_CO, 50, 255, 50 }, { 0, 0, NA_BGM_BOSS_CO, 0, 255, 1600 },
|
|
{ 1, 0, NA_BGM_BOSS_CO, 1, 255, 50 }, { 0, 0, NA_BGM_COURSE_CLEAR, 0, 255, 1091 },
|
|
{ 1, 0, NA_BGM_COURSE_CLEAR, 100, 255, 100 }, { 0, 0, NA_BGM_ME_START_DEMO, 0, 255, 838 },
|
|
{ 0, 0, NA_BGM_STAGE_ME, 0, 255, 1584 }, { 1, 0, NA_BGM_STAGE_ME, 150, 255, 150 },
|
|
{ 0, 0, NA_BGM_STAGE_WZ, 0, 255, 1635 }, { 1, 0, NA_BGM_STAGE_WZ, 150, 255, 150 },
|
|
{ 0, 0, NA_BGM_KA_START_DEMO, 0, 255, 241 }, { 0, 0, NA_BGM_STAGE_KA, 0, 255, 2184 },
|
|
{ 1, 0, NA_BGM_STAGE_KA, 1, 255, 100 }, { 0, 0, NA_BGM_BOSS_KA, 0, 1, 1115 },
|
|
{ 1, 0, NA_BGM_BOSS_KA, 50, 255, 100 }, { 0, 0, NA_BGM_COURSE_FAILURE, 0, 255, 1604 },
|
|
{ 1, 0, NA_BGM_COURSE_FAILURE, 100, 255, 100 }, { 0, 0, NA_BGM_START_DEMO_S, 0, 255, 242 },
|
|
{ 0, 0, NA_BGM_STAGE_SX, 0, 255, 1291 }, { 3, 0, NA_BGM_BILL, 0, 255, 1000 },
|
|
{ 1, 0, NA_BGM_STAGE_SX, 50, 255, 100 }, { 0, 0, NA_BGM_STAGE_WZ, 0, 255, 1635 },
|
|
{ 1, 0, NA_BGM_STAGE_WZ, 150, 255, 150 }, { 0, 0, NA_BGM_SZ_START_DEMO, 0, 255, 241 },
|
|
{ 0, 0, NA_BGM_STAGE_SZ, 0, 255, 1632 }, { 1, 0, NA_BGM_STAGE_SZ, 50, 255, 100 },
|
|
{ 0, 0, NA_BGM_BOSS_SZ, 0, 1, 1115 }, { 1, 0, NA_BGM_BOSS_SZ, 1, 255, 50 },
|
|
{ 0, 0, NA_BGM_COURSE_CLEAR, 0, 255, 1091 }, { 1, 0, NA_BGM_COURSE_CLEAR, 100, 255, 100 },
|
|
{ 0, 0, NA_BGM_A6_START_DEMO, 0, 255, 241 }, { 0, 0, NA_BGM_STAGE_A6, 0, 255, 1906 },
|
|
{ 1, 0, NA_BGM_STAGE_A6, 50, 255, 100 }, { 0, 0, NA_BGM_BOSS_A6, 0, 1, 1590 },
|
|
{ 1, 0, NA_BGM_BOSS_A6, 1, 255, 50 }, { 0, 0, NA_BGM_PLAYER_DOWN, 0, 255, 150 },
|
|
{ 0, 0, NA_BGM_GAME_OVER, 0, 255, 1020 }, { 1, 0, NA_BGM_GAME_OVER, 100, 255, 100 },
|
|
{ 255, 0, NA_BGM_STAGE_CO, 50, 255, 50 },
|
|
},
|
|
{
|
|
{ 0, 0, NA_BGM_OPENING, 0, 255, 2926 },
|
|
{ 0, 0, NA_BGM_TITLE, 0, 255, 1251 },
|
|
{ 1, 0, NA_BGM_TITLE, 200, 255, 200 },
|
|
{ 0, 0, NA_BGM_SELECT, 0, 255, 1636 },
|
|
{ 1, 0, NA_BGM_SELECT, 200, 255, 200 },
|
|
{ 0, 0, NA_BGM_MAP, 0, 255, 1560 },
|
|
{ 1, 0, NA_BGM_MAP, 200, 255, 200 },
|
|
{ 0, 0, NA_BGM_START_DEMO, 0, 255, 1618 },
|
|
{ 0, 0, NA_BGM_START_DEMO_S, 0, 255, 242 },
|
|
{ 0, 0, NA_BGM_START_DEMO_M, 0, 255, 582 },
|
|
{ 0, 0, NA_BGM_ME_START_DEMO, 0, 255, 868 },
|
|
{ 0, 0, NA_BGM_FO_START_DEMO, 0, 255, 281 },
|
|
{ 0, 0, NA_BGM_STAGE_CO, 0, 255, 2490 },
|
|
{ 1, 0, NA_BGM_STAGE_CO, 200, 255, 200 },
|
|
{ 0, 0, NA_BGM_STAGE_ME, 0, 255, 1584 },
|
|
{ 1, 0, NA_BGM_STAGE_ME, 200, 255, 200 },
|
|
{ 0, 0, NA_BGM_STAGE_TI, 0, 255, 1920 },
|
|
{ 1, 0, NA_BGM_STAGE_TI, 200, 255, 200 },
|
|
{ 0, 0, NA_BGM_STAGE_SX, 0, 255, 2290 },
|
|
{ 1, 0, NA_BGM_STAGE_SX, 200, 255, 200 },
|
|
{ 0, 0, NA_BGM_STAGE_ZO, 0, 255, 2005 },
|
|
{ 1, 0, NA_BGM_STAGE_ZO, 200, 255, 200 },
|
|
{ 0, 0, NA_BGM_STAGE_A6, 0, 255, 1905 },
|
|
{ 1, 0, NA_BGM_STAGE_A6, 200, 255, 200 },
|
|
{ 0, 0, NA_BGM_STAGE_VE1, 0, 255, 1671 },
|
|
{ 1, 0, NA_BGM_STAGE_VE1, 200, 255, 200 },
|
|
{ 0, 0, NA_BGM_STAGE_SY, 0, 255, 2095 },
|
|
{ 1, 0, NA_BGM_STAGE_SY, 200, 255, 200 },
|
|
{ 0, 0, NA_BGM_STAGE_FO, 0, 255, 1632 },
|
|
{ 1, 0, NA_BGM_STAGE_FO, 200, 255, 200 },
|
|
{ 0, 0, NA_BGM_STAGE_KA, 0, 255, 2184 },
|
|
{ 1, 0, NA_BGM_STAGE_KA, 200, 255, 200 },
|
|
{ 0, 0, NA_BGM_STAGE_AQ, 0, 255, 2400 },
|
|
{ 1, 0, NA_BGM_STAGE_AQ, 200, 255, 200 },
|
|
{ 0, 0, NA_BGM_STAGE_WZ, 0, 255, 1635 },
|
|
{ 1, 0, NA_BGM_STAGE_WZ, 200, 255, 200 },
|
|
{ 0, 0, NA_BGM_KATT, 0, 255, 389 },
|
|
{ 0, 0, NA_BGM_BILL, 0, 255, 268 },
|
|
{ 0, 0, NA_BGM_BOSS_CO, 0, 255, 1598 },
|
|
{ 1, 0, NA_BGM_BOSS_CO, 200, 255, 200 },
|
|
{ 0, 0, NA_BGM_BOSS_ME, 0, 0, 1470 },
|
|
{ 1, 0, NA_BGM_BOSS_ME, 200, 255, 200 },
|
|
{ 0, 0, NA_BGM_BOSS_ME, 0, 255, 1470 },
|
|
{ 1, 0, NA_BGM_BOSS_ME, 200, 255, 200 },
|
|
{ 0, 0, NA_BGM_REAL_BOSS, 0, 255, 1311 },
|
|
{ 1, 0, NA_BGM_REAL_BOSS, 200, 255, 200 },
|
|
{ 0, 0, NA_BGM_BOSS_BO, 0, 255, 1115 },
|
|
{ 1, 0, NA_BGM_BOSS_BO, 200, 255, 200 },
|
|
{ 0, 0, NA_BGM_STARWOLF, 0, 255, 2120 },
|
|
{ 1, 0, NA_BGM_STARWOLF, 200, 255, 200 },
|
|
{ 0, 0, NA_BGM_COURSE_CLEAR, 0, 255, 1091 },
|
|
{ 1, 0, NA_BGM_COURSE_CLEAR, 200, 255, 200 },
|
|
{ 0, 0, NA_BGM_COURSE_FAILURE, 0, 255, 1604 },
|
|
{ 1, 0, NA_BGM_COURSE_FAILURE, 200, 255, 200 },
|
|
{ 0, 0, NA_BGM_PLAYER_DOWN, 0, 255, 200 },
|
|
{ 0, 0, NA_BGM_GAME_OVER, 0, 255, 1020 },
|
|
{ 1, 0, NA_BGM_GAME_OVER, 200, 255, 200 },
|
|
{ 0, 0, NA_BGM_TRAINING, 0, 255, 900 },
|
|
{ 1, 0, NA_BGM_TRAINING, 200, 255, 200 },
|
|
{ 0, 0, NA_BGM_VS_SELECT, 0, 255, 665 },
|
|
{ 1, 0, NA_BGM_VS_SELECT, 200, 255, 200 },
|
|
{ 0, 0, NA_BGM_BATTLE, 0, 255, 1647 },
|
|
{ 1, 0, NA_BGM_BATTLE, 200, 255, 200 },
|
|
{ 0, 0, NA_BGM_BATTLE_LAST, 0, 255, 1667 },
|
|
{ 1, 0, NA_BGM_BATTLE_LAST, 200, 255, 200 },
|
|
{ 0, 0, NA_BGM_DASH_INTO_BASE, 0, 0, 176 },
|
|
{ 0, 0, NA_BGM_STAGE_ANDROSS, 0, 255, 588 },
|
|
{ 1, 0, NA_BGM_STAGE_ANDROSS, 200, 255, 200 },
|
|
{ 0, 0, NA_BGM_BOSS_ANDROSS, 0, 0, 2391 },
|
|
{ 1, 0, NA_BGM_BOSS_ANDROSS, 200, 255, 200 },
|
|
{ 0, 0, NA_BGM_BOSS_ANDROSS, 0, 255, 2391 },
|
|
{ 1, 0, NA_BGM_BOSS_ANDROSS, 200, 255, 200 },
|
|
{ 0, 0, NA_BGM_ANDROSS_BRAIN, 0, 255, 1700 },
|
|
{ 1, 0, NA_BGM_ANDROSS_BRAIN, 200, 255, 200 },
|
|
{ 0, 0, NA_BGM_ALL_CLEAR, 0, 255, 1459 },
|
|
{ 1, 0, NA_BGM_ALL_CLEAR, 200, 255, 200 },
|
|
{ 0, 0, NA_BGM_STAFF_ROLL, 0, 255, 9250 },
|
|
{ 1, 0, NA_BGM_STAFF_ROLL, 200, 255, 200 },
|
|
{ 255, 0, NA_BGM_STAGE_CO, 50, 255, 50 },
|
|
},
|
|
};
|
|
|
|
s32 D_800C737C = 0; // unused. file split?
|
|
f32 D_800C7380 = 1.0f; // unused/
|
|
u32 sNextVoiceId = 0;
|
|
u32 sCurrentVoiceId = 0;
|
|
u8 sSetNextVoiceId = 0;
|
|
u8 sUnkVoiceParam = 0;
|
|
u8 sMuteBgmForVoice = 0;
|
|
|
|
void Audio_dummy_80016A50(void) {
|
|
}
|
|
|
|
f32 Audio_GetSfxFalloff(u8 bankId, u8 entryIndex) {
|
|
f32 cutoff;
|
|
f32 midDist;
|
|
f32 distance;
|
|
f32 falloff;
|
|
f32 midrange;
|
|
f32 range;
|
|
|
|
if (sSfxBanks[bankId][entryIndex].sfxId & SFX_FLAG_22) {
|
|
return 1.0f;
|
|
}
|
|
distance = sSfxBanks[bankId][entryIndex].distance;
|
|
if (distance > 33000.0f) {
|
|
falloff = 0.0f;
|
|
} else {
|
|
switch ((sSfxBanks[bankId][entryIndex].sfxId & SFX_RANGE_MASK)) {
|
|
default:
|
|
range = 33000.0f / 20.0f;
|
|
break;
|
|
case 1 << SFX_RANGE_SHIFT:
|
|
range = 33000.0f / 15.0f;
|
|
break;
|
|
case 2 << SFX_RANGE_SHIFT:
|
|
range = 33000.0f / 10.5f;
|
|
break;
|
|
case 3 << SFX_RANGE_SHIFT:
|
|
range = 33000.0f / 5.2f;
|
|
break;
|
|
}
|
|
cutoff = range / 5.0f;
|
|
if (distance < range / 5.0f) {
|
|
falloff = 1.0f;
|
|
} else if (distance < range) {
|
|
midDist = range - cutoff;
|
|
midrange = distance - cutoff;
|
|
falloff = (((midDist - midrange) / midDist) * 0.19f) + 0.81f;
|
|
} else {
|
|
falloff = (1.0f - ((distance - range) / (33000.0f - range))) * 0.81f;
|
|
}
|
|
falloff = SQ(falloff);
|
|
}
|
|
return falloff;
|
|
}
|
|
|
|
s8 Audio_GetSfxReverb(u8 bankId, u8 entryIndex, u8 channelId) {
|
|
s32 totalReverb;
|
|
s8 distReverb = 0;
|
|
s8 scriptReverb = 0;
|
|
|
|
if (!(sSfxBanks[bankId][entryIndex].sfxId & SFX_FLAG_21)) {
|
|
if (sSfxBanks[bankId][entryIndex].distance < (33000.0f / 4.0f)) {
|
|
distReverb = (sSfxBanks[bankId][entryIndex].distance / (33000.0f / 4.0f)) * 40.0f;
|
|
} else {
|
|
distReverb = 40;
|
|
}
|
|
}
|
|
if (IS_SEQUENCE_CHANNEL_VALID(gSeqPlayers[SEQ_PLAYER_SFX].channels[channelId])) {
|
|
scriptReverb = gSeqPlayers[SEQ_PLAYER_SFX].channels[channelId]->seqScriptIO[6];
|
|
}
|
|
if (scriptReverb == -1) {
|
|
scriptReverb = 0;
|
|
}
|
|
totalReverb = *sSfxBanks[bankId][entryIndex].reverbAdd + distReverb + scriptReverb + sEnvReverb + sAudioSpecReverb;
|
|
totalReverb = MIN(127, totalReverb);
|
|
return totalReverb;
|
|
}
|
|
|
|
s8 Audio_GetSfxPan(f32 xPos, f32 zPos, u8 mode) {
|
|
if (sSfxChannelLayout != SFXCHAN_3) {
|
|
f32 absx = ABSF(xPos);
|
|
f32 absz = ABSF(zPos);
|
|
f32 pan;
|
|
|
|
if ((absx < 1.0f) && (absz < 1.0f)) {
|
|
return 64;
|
|
}
|
|
absx = MIN(1200.0f, absx);
|
|
absz = MIN(1200.0f, absz);
|
|
|
|
if ((xPos == 0) && (zPos == 0)) {
|
|
pan = 0.5f;
|
|
} else if ((xPos >= 0.f) && (absz <= absx)) {
|
|
pan = 1.0f - ((2400.0f - absx) / (10.0f * (2400.0f - absz)));
|
|
} else if ((xPos < 0.0f) && (absz <= absx)) {
|
|
pan = (2400.0f - absx) / (10.0f * (2400.0f - absz));
|
|
} else {
|
|
pan = (xPos / (2.5f * absz)) + 0.5f;
|
|
}
|
|
return ROUND(pan * 127.0f);
|
|
} else if (mode != 4) {
|
|
return ((mode & 1) * 127);
|
|
}
|
|
return 64;
|
|
}
|
|
|
|
f32 Audio_GetSfxFreqMod(u8 bankId, u8 entryIndex) {
|
|
f32 distance;
|
|
f32 freqMod = 1.0f;
|
|
|
|
if (sSfxBanks[bankId][entryIndex].sfxId & SFX_FLAG_23) {
|
|
freqMod -= ((gAudioRandom % 16) / 192.0f);
|
|
}
|
|
distance = sSfxBanks[bankId][entryIndex].distance;
|
|
if (!(sSfxBanks[bankId][entryIndex].sfxId & SFX_FLAG_22)) {
|
|
if (distance >= 33000.0f) {
|
|
freqMod += 0.2f;
|
|
} else {
|
|
freqMod += 0.2f * (distance / 33000.0f);
|
|
}
|
|
}
|
|
if ((sSfxChannelLayout != SFXCHAN_0) && (sSfxBanks[bankId][entryIndex].token & 2)) {
|
|
freqMod *= 1.1f;
|
|
}
|
|
return freqMod;
|
|
}
|
|
|
|
void Audio_SetSfxProperties(u8 bankId, u8 entryIndex, u8 channelId) {
|
|
f32 volumeMod = 1.0f;
|
|
s8 reverb = 0;
|
|
f32 freqMod = 1.0f;
|
|
s8 pan = 64;
|
|
SfxBankEntry* entry = &sSfxBanks[bankId][entryIndex];
|
|
|
|
switch (bankId) {
|
|
case SFX_BANK_PLAYER:
|
|
case SFX_BANK_1:
|
|
case SFX_BANK_2:
|
|
case SFX_BANK_3:
|
|
if (entry->state == 2) {
|
|
AUDIOCMD_CHANNEL_SET_IO(SEQ_PLAYER_SFX, channelId, 1, gLevelType);
|
|
}
|
|
if ((entry->sfxId & SFX_FLAG_18) && (*entry->zPos > 0.0f)) {
|
|
f32 yScaled = *entry->yPos / 2.5f;
|
|
|
|
entry->distance = SQ(*entry->xPos) + SQ(yScaled);
|
|
}
|
|
entry->distance = sqrtf(entry->distance);
|
|
volumeMod = Audio_GetSfxFalloff(bankId, entryIndex) * *entry->volMod * sSfxVolumeMods[bankId].value;
|
|
reverb = Audio_GetSfxReverb(bankId, entryIndex, channelId);
|
|
freqMod = Audio_GetSfxFreqMod(bankId, entryIndex) * *entry->freqMod;
|
|
if (!((bankId == SFX_BANK_PLAYER) && ((-200.0f < *entry->zPos) && (*entry->zPos < 200.0f)) &&
|
|
(sSfxChannelLayout != SFXCHAN_3))) {
|
|
pan = Audio_GetSfxPan(*entry->xPos, *entry->zPos, entry->token);
|
|
}
|
|
break;
|
|
case SFX_BANK_SYSTEM:
|
|
if (sSfxChannelLayout == SFXCHAN_3) {
|
|
if (entry->token != 4) {
|
|
pan = (entry->token & 1) * 127;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
if (volumeMod != sSfxChannelState[channelId].volMod) {
|
|
AUDIOCMD_CHANNEL_SET_VOL_SCALE(SEQ_PLAYER_SFX, channelId, volumeMod);
|
|
sSfxChannelState[channelId].volMod = volumeMod;
|
|
}
|
|
if (reverb != sSfxChannelState[channelId].reverb) {
|
|
AUDIOCMD_CHANNEL_SET_REVERB_VOLUME(SEQ_PLAYER_SFX, channelId, reverb);
|
|
sSfxChannelState[channelId].reverb = reverb;
|
|
}
|
|
if (freqMod != sSfxChannelState[channelId].freqMod) {
|
|
AUDIOCMD_CHANNEL_SET_FREQ_SCALE(SEQ_PLAYER_SFX, channelId, freqMod);
|
|
sSfxChannelState[channelId].freqMod = freqMod;
|
|
}
|
|
if (pan != sSfxChannelState[channelId].pan) {
|
|
AUDIOCMD_CHANNEL_SET_PAN(SEQ_PLAYER_SFX, channelId, pan);
|
|
sSfxChannelState[channelId].pan = pan;
|
|
}
|
|
}
|
|
|
|
f32 Audio_UpdateDopplerShift(f32* srcPos, f32* srcVel, f32 soundSpeed, f32* curDopplerShift) {
|
|
f32 xVel;
|
|
f32 zVel;
|
|
f32 xPos;
|
|
f32 zPos;
|
|
f32 xzDist;
|
|
f32 xPosNext;
|
|
f32 zPosNext;
|
|
f32 xzDistNext;
|
|
f32 step;
|
|
f32 newShift;
|
|
f32 relativeSpeed;
|
|
f32 targetDopplerShift;
|
|
s32 pad;
|
|
|
|
#ifdef AVOID_UB
|
|
if ((srcPos == NULL) || (srcVel == NULL) || (curDopplerShift == NULL)) {
|
|
return 0.0f;
|
|
}
|
|
#endif
|
|
|
|
xPos = srcPos[0];
|
|
zPos = srcPos[2];
|
|
xVel = srcVel[0];
|
|
zVel = srcVel[2];
|
|
xzDist = sqrtf(SQ(xPos) + SQ(zPos));
|
|
xPosNext = xPos + xVel;
|
|
zPosNext = zPos + zVel;
|
|
xzDistNext = sqrtf(SQ(xPosNext) + SQ(zPosNext));
|
|
relativeSpeed = (xzDist - xzDistNext) / soundSpeed;
|
|
targetDopplerShift = 1.0f / (1.0f - relativeSpeed);
|
|
|
|
step = targetDopplerShift - *curDopplerShift;
|
|
newShift = *curDopplerShift;
|
|
if (step != 0.0f) {
|
|
if (step > 0.2f) {
|
|
newShift += 0.2f;
|
|
} else if (step < -0.2f) {
|
|
newShift -= 0.2f;
|
|
} else {
|
|
newShift += step;
|
|
}
|
|
}
|
|
*curDopplerShift = newShift;
|
|
|
|
if (newShift > 4.0f) {
|
|
newShift = 4.0f;
|
|
} else if (newShift < 0.1f) {
|
|
newShift = 0.1f;
|
|
}
|
|
|
|
return newShift;
|
|
}
|
|
|
|
void Audio_LoadInstruments(void) {
|
|
u8 i;
|
|
|
|
for (i = 0; sAudioSpecInstrumentSets[sAudioSpecId][i] != 0xFF; i++) {
|
|
AUDIOCMD_GLOBAL_SYNC_LOAD_INSTRUMENT(0, sAudioSpecInstrumentSets[sAudioSpecId][i], 0);
|
|
}
|
|
}
|
|
|
|
void Audio_LoadAquasSequence(void) {
|
|
if (sAudioSpecId == AUDIOSPEC_12) {
|
|
AUDIOCMD_GLOBAL_SYNC_LOAD_SEQ_PARTS(NA_BGM_STAGE_AQ, 0);
|
|
}
|
|
}
|
|
|
|
void Audio_ResetSfxChannelState(void) {
|
|
u8 i;
|
|
|
|
sEnvReverb = 0;
|
|
sAudioSpecReverb = sAudioSpecReverbAdd[sAudioSpecId];
|
|
for (i = 0; i < 16; i++) {
|
|
sSfxChannelState[i].volMod = 1.0f;
|
|
sSfxChannelState[i].freqMod = 1.0f;
|
|
sSfxChannelState[i].reverb = 0;
|
|
sSfxChannelState[i].pan = 64;
|
|
}
|
|
}
|
|
|
|
void Audio_StartSequence(u8 seqPlayId, u8 seqId, u8 seqArgs, u16 fadeInTime) {
|
|
u8 i;
|
|
s32 pad;
|
|
|
|
if (!sStartSeqDisabled || (seqPlayId == SEQ_PLAYER_SFX)) {
|
|
AUDIOCMD_GLOBAL_INIT_SEQPLAYER((u32) seqPlayId, (u32) seqId, 0, fadeInTime);
|
|
sActiveSequences[seqPlayId].prevSeqId = sActiveSequences[seqPlayId].seqId = seqId | ((seqArgs) << 8);
|
|
if (sActiveSequences[seqPlayId].mainVolume.mod != 1.0f) {
|
|
AUDIOCMD_SEQPLAYER_FADE_VOLUME_SCALE((u32) seqPlayId, sActiveSequences[seqPlayId].mainVolume.mod);
|
|
}
|
|
sActiveSequences[seqPlayId].tempo.timer = 0;
|
|
sActiveSequences[seqPlayId].tempoOriginal = 0;
|
|
sActiveSequences[seqPlayId].tempoCmd = 0;
|
|
for (i = 0; i < 16; i++) {
|
|
sActiveSequences[seqPlayId].channelMod[i].volume.value = 1.0f;
|
|
sActiveSequences[seqPlayId].channelMod[i].volume.timer = 0;
|
|
sActiveSequences[seqPlayId].channelMod[i].freq.value = 1.0f;
|
|
sActiveSequences[seqPlayId].channelMod[i].freq.timer = 0;
|
|
}
|
|
sActiveSequences[seqPlayId].volChannelFlags = sActiveSequences[seqPlayId].freqModChannelFlags = 0;
|
|
}
|
|
}
|
|
|
|
void Audio_StopSequence(u8 seqPlayId, u16 fadeOutTime) {
|
|
AUDIOCMD_GLOBAL_DISABLE_SEQPLAYER(seqPlayId, fadeOutTime);
|
|
sActiveSequences[seqPlayId].seqId = SEQ_ID_NONE;
|
|
}
|
|
|
|
void Audio_ProcessSeqCmd(u32 seqCmd) {
|
|
u16 flag;
|
|
u16 channelDisableMask;
|
|
u16 fadeTimer;
|
|
u16 val;
|
|
s32 priority;
|
|
u8 i; // sp63
|
|
u8 specId;
|
|
u8 oldSpecId;
|
|
u8 ioPort;
|
|
u8 channel;
|
|
u8 found;
|
|
u8 muteFlag;
|
|
u8 duration;
|
|
u8 seqNumber;
|
|
u8 subOp;
|
|
u8 seqPlayId;
|
|
u8 seqArgs;
|
|
u8* tempptr; // sp54
|
|
u8* tempPtr2;
|
|
u32 sp4C;
|
|
|
|
seqPlayId = (seqCmd & 0x0F000000) >> 0x18;
|
|
switch ((seqCmd >> 0x1C) & 0xFF) {
|
|
case SEQCMD_OP_PLAY_SEQUENCE:
|
|
seqNumber = seqCmd & 0xFF;
|
|
seqArgs = (seqCmd & 0xFF00) >> 8;
|
|
fadeTimer = (seqCmd & 0xFF0000) >> 13;
|
|
if (!sActiveSequences[seqPlayId].isWaitingForFonts) {
|
|
if (seqArgs < 0x80) {
|
|
Audio_StartSequence(seqPlayId, seqNumber, seqArgs, fadeTimer);
|
|
} else {
|
|
sActiveSequences[seqPlayId].startSeqCmd = seqCmd & ~0x8000;
|
|
sActiveSequences[seqPlayId].isWaitingForFonts = true;
|
|
Audio_StopSequence(seqPlayId, 1);
|
|
if (sActiveSequences[seqPlayId].prevSeqId != SEQ_ID_NONE) {
|
|
tempptr = AudioThread_GetFontsForSequence(seqNumber, &sp4C);
|
|
tempPtr2 = AudioThread_GetFontsForSequence(sActiveSequences[seqPlayId].prevSeqId & 0xFF, &sp4C);
|
|
if (tempptr[0] != tempPtr2[0]) {
|
|
AUDIOCMD_GLOBAL_DISCARD_SEQ_FONTS(seqNumber);
|
|
}
|
|
}
|
|
AUDIOCMD_GLOBAL_ASYNC_LOAD_FONT(seqNumber, 20, (s8) (seqPlayId + 1));
|
|
}
|
|
}
|
|
break;
|
|
case SEQCMD_OP_STOP_SEQUENCE:
|
|
fadeTimer = (seqCmd & 0xFF0000) >> 13;
|
|
Audio_StopSequence(seqPlayId, fadeTimer);
|
|
return;
|
|
case SEQCMD_OP_QUEUE_SEQUENCE:
|
|
seqNumber = seqCmd & 0xFF;
|
|
seqArgs = (seqCmd & 0xFF00) >> 8;
|
|
fadeTimer = (seqCmd & 0xFF0000) >> 13;
|
|
priority = seqArgs;
|
|
for (i = 0; i < sNumSeqRequests[seqPlayId]; i++) {
|
|
if (seqNumber == sSeqRequests[seqPlayId][i].seqId) {
|
|
if (i == 0) {
|
|
Audio_StartSequence(seqPlayId, seqNumber, seqArgs, fadeTimer);
|
|
}
|
|
return;
|
|
}
|
|
}
|
|
found = sNumSeqRequests[seqPlayId];
|
|
for (i = 0; i < sNumSeqRequests[seqPlayId]; i++) {
|
|
if (seqArgs >= sSeqRequests[seqPlayId][i].priority) {
|
|
found = i;
|
|
i = sNumSeqRequests[seqPlayId];
|
|
}
|
|
}
|
|
if ((found != sNumSeqRequests[seqPlayId]) || (found == 0)) {
|
|
if (sNumSeqRequests[seqPlayId] < 5) {
|
|
sNumSeqRequests[seqPlayId]++;
|
|
}
|
|
for (i = sNumSeqRequests[seqPlayId] - 1; i != found; i--) {
|
|
sSeqRequests[seqPlayId][i].priority = sSeqRequests[seqPlayId][i - 1].priority;
|
|
sSeqRequests[seqPlayId][i].seqId = sSeqRequests[seqPlayId][i - 1].seqId;
|
|
}
|
|
sSeqRequests[seqPlayId][found].priority = seqArgs;
|
|
sSeqRequests[seqPlayId][found].seqId = seqNumber;
|
|
}
|
|
if (found == 0) {
|
|
Audio_StartSequence(seqPlayId, seqNumber, seqArgs, fadeTimer);
|
|
}
|
|
break;
|
|
case SEQCMD_OP_UNQUEUE_SEQUENCE:
|
|
fadeTimer = (seqCmd & 0xFF0000) >> 0xD;
|
|
found = sNumSeqRequests[seqPlayId];
|
|
for (i = 0; i < sNumSeqRequests[seqPlayId]; i++) {
|
|
seqNumber = seqCmd & 0xFF;
|
|
if (sSeqRequests[seqPlayId][i].seqId == seqNumber) {
|
|
found = i;
|
|
i = sNumSeqRequests[seqPlayId];
|
|
}
|
|
}
|
|
if (found != sNumSeqRequests[seqPlayId]) {
|
|
for (i = found; i < sNumSeqRequests[seqPlayId] - 1; i++) {
|
|
sSeqRequests[seqPlayId][i].priority = sSeqRequests[seqPlayId][i + 1].priority;
|
|
sSeqRequests[seqPlayId][i].seqId = sSeqRequests[seqPlayId][i + 1].seqId;
|
|
}
|
|
sNumSeqRequests[seqPlayId]--;
|
|
}
|
|
if (found == 0) {
|
|
Audio_StopSequence(seqPlayId, fadeTimer);
|
|
if (sNumSeqRequests[seqPlayId] != 0) {
|
|
|
|
Audio_StartSequence(seqPlayId, sSeqRequests[seqPlayId][0].seqId,
|
|
sSeqRequests[seqPlayId][0].priority, fadeTimer);
|
|
}
|
|
}
|
|
break;
|
|
case SEQCMD_OP_SET_SEQPLAYER_VOLUME:
|
|
val = seqCmd & 0xFF;
|
|
duration = (seqCmd & 0xFF0000) >> 0xF;
|
|
|
|
if (duration == 0) {
|
|
duration++;
|
|
}
|
|
sActiveSequences[seqPlayId].mainVolume.target = val / 127.0f;
|
|
if (sActiveSequences[seqPlayId].mainVolume.mod != sActiveSequences[seqPlayId].mainVolume.target) {
|
|
sActiveSequences[seqPlayId].mainVolume.step =
|
|
(sActiveSequences[seqPlayId].mainVolume.mod - sActiveSequences[seqPlayId].mainVolume.target) /
|
|
duration;
|
|
sActiveSequences[seqPlayId].mainVolume.timer = duration;
|
|
}
|
|
break;
|
|
case SEQCMD_OP_SET_SEQPLAYER_FREQ:
|
|
val = (seqCmd & 0xFFFF);
|
|
duration = (seqCmd & 0xFF0000) >> 0xF;
|
|
|
|
if (duration == 0) {
|
|
duration++;
|
|
}
|
|
for (i = 0; i < 16; i++) {
|
|
sActiveSequences[seqPlayId].channelMod[i].freq.target = val / 1000.0f;
|
|
sActiveSequences[seqPlayId].channelMod[i].freq.step =
|
|
(sActiveSequences[seqPlayId].channelMod[i].freq.value -
|
|
sActiveSequences[seqPlayId].channelMod[i].freq.target) /
|
|
duration;
|
|
sActiveSequences[seqPlayId].channelMod[i].freq.timer = duration;
|
|
}
|
|
sActiveSequences[seqPlayId].freqModChannelFlags = 0xFFFF;
|
|
break;
|
|
case SEQCMD_OP_SET_CHANNEL_VOLUME:
|
|
val = (seqCmd & 0xFF);
|
|
channel = (seqCmd & 0xF00) >> 8;
|
|
duration = (seqCmd & 0xFF0000) >> 0xF;
|
|
|
|
if (duration == 0) {
|
|
duration++;
|
|
}
|
|
|
|
sActiveSequences[seqPlayId].channelMod[channel].volume.target = val / 127.0f;
|
|
if (sActiveSequences[seqPlayId].channelMod[channel].volume.value !=
|
|
sActiveSequences[seqPlayId].channelMod[channel].volume.target) {
|
|
sActiveSequences[seqPlayId].channelMod[channel].volume.step =
|
|
(sActiveSequences[seqPlayId].channelMod[channel].volume.value -
|
|
sActiveSequences[seqPlayId].channelMod[channel].volume.target) /
|
|
duration;
|
|
sActiveSequences[seqPlayId].channelMod[channel].volume.timer = duration;
|
|
sActiveSequences[seqPlayId].freqModChannelFlags |= 1 << channel;
|
|
}
|
|
break;
|
|
case SEQCMD_OP_SET_SEQPLAYER_IO:
|
|
val = seqCmd & 0xFF;
|
|
ioPort = ((seqCmd & 0xFF0000) >> 0x10); // may be misnamed
|
|
AUDIOCMD_SEQPLAYER_SET_IO(seqPlayId, ioPort, val);
|
|
break;
|
|
case SEQCMD_OP_SET_CHANNEL_IO:
|
|
val = seqCmd & 0xFF;
|
|
channel = (seqCmd & 0xF00) >> 8;
|
|
|
|
ioPort = (seqCmd & 0xFF0000) >> 0x10;
|
|
if (!(sActiveSequences[seqPlayId].channelPortMask & (1 << channel))) {
|
|
AUDIOCMD_CHANNEL_SET_IO(seqPlayId, (u32) channel, ioPort, val);
|
|
}
|
|
break;
|
|
case SEQCMD_OP_SET_CHANNEL_IO_DISABLE_MASK:
|
|
channelDisableMask = seqCmd & 0xFFFF;
|
|
sActiveSequences[seqPlayId].channelPortMask = channelDisableMask;
|
|
break;
|
|
case SEQCMD_OP_SET_CHANNEL_DISABLE_MASK:
|
|
channelDisableMask = seqCmd & 0xFFFF;
|
|
|
|
flag = 1;
|
|
for (i = 0; i < 16; i++) {
|
|
AUDIOCMD_CHANNEL_SET_MUTE(seqPlayId, (u32) i, (channelDisableMask & flag) ? 1 : 0);
|
|
flag <<= 1;
|
|
}
|
|
break;
|
|
case SEQCMD_OP_TEMPO_CMD:
|
|
sActiveSequences[seqPlayId].tempoCmd = seqCmd;
|
|
break;
|
|
case SEQCMD_OP_SETUP_CMD:
|
|
subOp = (seqCmd & 0xF00000) >> 20;
|
|
if (subOp != SEQCMD_SUB_OP_SETUP_RESET_SETUP_CMDS) {
|
|
found = sActiveSequences[seqPlayId].setupCmdNum++;
|
|
if (found < 5) {
|
|
sActiveSequences[seqPlayId].setupCmd[found] = seqCmd;
|
|
sActiveSequences[seqPlayId].setupCmdTimer = 2;
|
|
}
|
|
} else {
|
|
sActiveSequences[seqPlayId].setupCmdNum = 0;
|
|
}
|
|
break;
|
|
case SEQCMD_OP_GLOBAL_CMD:
|
|
val = seqCmd & 0xFF;
|
|
subOp = (seqCmd & 0xF00) >> 8;
|
|
|
|
switch (subOp) {
|
|
case SEQCMD_SUB_OP_GLOBAL_SET_SOUND_MODE:
|
|
AUDIOCMD_GLOBAL_SET_SOUND_MODE(sSoundModeList[val]);
|
|
break;
|
|
case SEQCMD_SUB_OP_GLOBAL_DISABLE_NEW_SEQUENCES:
|
|
sStartSeqDisabled = val & 1;
|
|
break;
|
|
}
|
|
break;
|
|
case SEQCMD_OP_RESET_AUDIO_HEAP:
|
|
specId = seqCmd & 0xFF;
|
|
sSfxChannelLayout = (seqCmd & 0xFF00) >> 8;
|
|
oldSpecId = sAudioSpecId;
|
|
sAudioSpecId = specId;
|
|
|
|
if (oldSpecId != specId) {
|
|
AudioThread_ResetAudioHeap(specId);
|
|
Audio_StartReset(oldSpecId);
|
|
AUDIOCMD_GLOBAL_STOP_AUDIOCMDS();
|
|
|
|
} else {
|
|
Audio_StopSequence(SEQ_PLAYER_BGM, 1);
|
|
Audio_StopSequence(SEQ_PLAYER_FANFARE, 1);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
void Audio_QueueSeqCmd(s32 seqCmd) {
|
|
sAudioSeqCmds[sSeqCmdWritePos] = seqCmd;
|
|
sSeqCmdWritePos++;
|
|
}
|
|
|
|
void Audio_ProcessSeqCmds(void) {
|
|
while (sSeqCmdWritePos != sSeqCmdReadPos) {
|
|
Audio_ProcessSeqCmd(sAudioSeqCmds[sSeqCmdReadPos++]);
|
|
}
|
|
}
|
|
|
|
u16 Audio_GetActiveSeqId(u8 seqPlayId) {
|
|
if (!gSeqPlayers[seqPlayId].enabled) {
|
|
return 0xFFFF;
|
|
}
|
|
return sActiveSequences[seqPlayId].seqId;
|
|
}
|
|
|
|
s32 Audio_SeqCmdNotQueued(s32 seqCmd) {
|
|
s32 notFound = true;
|
|
u8 i;
|
|
|
|
for (i = sSeqCmdReadPos; i < sSeqCmdWritePos; i++) {
|
|
if (seqCmd == sAudioSeqCmds[i]) {
|
|
notFound = false;
|
|
i = sSeqCmdWritePos;
|
|
}
|
|
}
|
|
return notFound;
|
|
}
|
|
|
|
s32 Audio_SeqCmdValueNotQueued(s32 cmdVal, s32 cmdMask) {
|
|
s32 notFound = true;
|
|
u8 i;
|
|
|
|
for (i = sSeqCmdReadPos; i < sSeqCmdWritePos; i++) {
|
|
if (cmdVal == (sAudioSeqCmds[i] & cmdMask)) {
|
|
notFound = false;
|
|
i = sSeqCmdWritePos;
|
|
}
|
|
}
|
|
return notFound;
|
|
}
|
|
|
|
void Audio_ResetSequenceRequests(u8 seqPlayId) {
|
|
sNumSeqRequests[seqPlayId] = 0;
|
|
}
|
|
|
|
// unused
|
|
void Audio_DisableSetupOp(u8 seqPlayId, u8 opcode) {
|
|
u8 i;
|
|
|
|
for (i = 0; i < sActiveSequences[seqPlayId].setupCmdNum; i++) {
|
|
u8 setupOp = ((sActiveSequences[seqPlayId].setupCmd[i] & 0xF00000) >> 20);
|
|
|
|
if (setupOp == opcode) {
|
|
sActiveSequences[seqPlayId].setupCmd[i] = 0xFF000000; // 0 duration volume reset on SEQ_PLAYER_BGM
|
|
}
|
|
}
|
|
}
|
|
|
|
void Audio_SetSequenceFade(u8 seqPlayId, u8 fadeModId, u8 fadeMod, u8 fadeTime) {
|
|
sActiveSequences[seqPlayId].mainVolume.fadeMod[fadeModId] = fadeMod;
|
|
sActiveSequences[seqPlayId].mainVolume.fadeTimer = fadeTime;
|
|
sActiveSequences[seqPlayId].mainVolume.fadeActive = true;
|
|
}
|
|
|
|
void Audio_UpdateActiveSequences(void) {
|
|
u8 seqPlayId;
|
|
u8 i;
|
|
u8 tempoTimer;
|
|
u8 channelId;
|
|
u16 tempoTarget;
|
|
u16 prevTempo;
|
|
u16 seqId;
|
|
u8 tempoOp;
|
|
u8 setupSeqPlayId;
|
|
u8 val1;
|
|
u8 setupOp;
|
|
u8 val2;
|
|
u8 temp2;
|
|
s32 temp;
|
|
u32 cmd;
|
|
f32 fadeMod;
|
|
u32 out;
|
|
s32 pad1;
|
|
s32 pad2;
|
|
|
|
for (seqPlayId = 0; seqPlayId < SEQ_PLAYER_MAX; seqPlayId++) {
|
|
if (sActiveSequences[seqPlayId].isWaitingForFonts) {
|
|
switch ((s32) AudioThread_GetAsyncLoadStatus(&out)) {
|
|
case SEQ_PLAYER_BGM + 1:
|
|
case SEQ_PLAYER_FANFARE + 1:
|
|
case SEQ_PLAYER_SFX + 1:
|
|
case SEQ_PLAYER_VOICE + 1:
|
|
sActiveSequences[seqPlayId].isWaitingForFonts = false;
|
|
Audio_ProcessSeqCmd(sActiveSequences[seqPlayId].startSeqCmd);
|
|
break;
|
|
}
|
|
}
|
|
if (sActiveSequences[seqPlayId].mainVolume.fadeActive) {
|
|
fadeMod = 1.0f;
|
|
for (i = 0; i < 3; i++) {
|
|
fadeMod *= sActiveSequences[seqPlayId].mainVolume.fadeMod[i] / 127.0f;
|
|
}
|
|
SEQCMD_SET_SEQPLAYER_VOLUME(seqPlayId, sActiveSequences[seqPlayId].mainVolume.fadeTimer,
|
|
(u8) (fadeMod * 127.0f));
|
|
sActiveSequences[seqPlayId].mainVolume.fadeActive = false;
|
|
}
|
|
if (sActiveSequences[seqPlayId].mainVolume.timer != 0) {
|
|
sActiveSequences[seqPlayId].mainVolume.timer--;
|
|
if (sActiveSequences[seqPlayId].mainVolume.timer != 0) {
|
|
sActiveSequences[seqPlayId].mainVolume.mod -= sActiveSequences[seqPlayId].mainVolume.step;
|
|
} else {
|
|
sActiveSequences[seqPlayId].mainVolume.mod = sActiveSequences[seqPlayId].mainVolume.target;
|
|
}
|
|
AUDIOCMD_SEQPLAYER_FADE_VOLUME_SCALE((u32) seqPlayId, sActiveSequences[seqPlayId].mainVolume.mod);
|
|
}
|
|
if (sActiveSequences[seqPlayId].tempoCmd != 0) {
|
|
cmd = sActiveSequences[seqPlayId].tempoCmd;
|
|
temp = cmd & 0xFFF;
|
|
temp2 = (cmd & 0xFF0000) >> 0xF;
|
|
tempoTimer = temp2;
|
|
tempoTarget = temp;
|
|
|
|
if (temp2 == 0) {
|
|
tempoTimer = temp2 + 1;
|
|
}
|
|
if (gSeqPlayers[seqPlayId].enabled) {
|
|
prevTempo = gSeqPlayers[seqPlayId].tempo / 48;
|
|
tempoOp = ((cmd & 0xF000) >> 0xC);
|
|
|
|
switch (tempoOp) {
|
|
case SEQCMD_SUB_OP_TEMPO_SPEED_UP:
|
|
tempoTarget = tempoTarget + prevTempo;
|
|
break;
|
|
case SEQCMD_SUB_OP_TEMPO_SLOW_DOWN:
|
|
if (tempoTarget < prevTempo) {
|
|
tempoTarget = prevTempo - tempoTarget;
|
|
}
|
|
break;
|
|
case SEQCMD_SUB_OP_TEMPO_SCALE:
|
|
tempoTarget = prevTempo * (tempoTarget / 100.0f);
|
|
break;
|
|
case SEQCMD_SUB_OP_TEMPO_RESET:
|
|
if (sActiveSequences[seqPlayId].tempoOriginal != 0) {
|
|
tempoTarget = sActiveSequences[seqPlayId].tempoOriginal;
|
|
} else {
|
|
tempoTarget = prevTempo;
|
|
}
|
|
break;
|
|
}
|
|
if (tempoTarget > 300) {
|
|
tempoTarget = 300;
|
|
}
|
|
if (!sActiveSequences[seqPlayId].tempoOriginal) {
|
|
sActiveSequences[seqPlayId].tempoOriginal = prevTempo;
|
|
}
|
|
sActiveSequences[seqPlayId].tempo.target = tempoTarget;
|
|
sActiveSequences[seqPlayId].tempo.value = (s32) gSeqPlayers[seqPlayId].tempo / 48;
|
|
|
|
sActiveSequences[seqPlayId].tempo.step =
|
|
(sActiveSequences[seqPlayId].tempo.value - sActiveSequences[seqPlayId].tempo.target) / tempoTimer;
|
|
sActiveSequences[seqPlayId].tempo.timer = tempoTimer;
|
|
sActiveSequences[seqPlayId].tempoCmd = 0;
|
|
}
|
|
}
|
|
if (sActiveSequences[seqPlayId].tempo.timer != 0) {
|
|
sActiveSequences[seqPlayId].tempo.timer--;
|
|
if (sActiveSequences[seqPlayId].tempo.timer != 0) {
|
|
sActiveSequences[seqPlayId].tempo.value -= sActiveSequences[seqPlayId].tempo.step;
|
|
} else {
|
|
sActiveSequences[seqPlayId].tempo.value = sActiveSequences[seqPlayId].tempo.target;
|
|
}
|
|
AUDIOCMD_SEQPLAYER_SET_TEMPO((u32) seqPlayId, (s32) sActiveSequences[seqPlayId].tempo.value);
|
|
}
|
|
if (sActiveSequences[seqPlayId].volChannelFlags != 0) {
|
|
for (channelId = 0; channelId < 16; channelId++) {
|
|
if (sActiveSequences[seqPlayId].channelMod[channelId].volume.timer != 0) {
|
|
sActiveSequences[seqPlayId].channelMod[channelId].volume.timer--;
|
|
if (sActiveSequences[seqPlayId].channelMod[channelId].volume.timer) {
|
|
sActiveSequences[seqPlayId].channelMod[channelId].volume.value -=
|
|
sActiveSequences[seqPlayId].channelMod[channelId].volume.step;
|
|
} else {
|
|
sActiveSequences[seqPlayId].channelMod[channelId].volume.value =
|
|
sActiveSequences[seqPlayId].channelMod[channelId].volume.target;
|
|
sActiveSequences[seqPlayId].volChannelFlags ^= 1 << channelId;
|
|
}
|
|
AUDIOCMD_CHANNEL_SET_VOL_SCALE((u32) seqPlayId, (u32) channelId,
|
|
sActiveSequences[seqPlayId].channelMod[channelId].volume.value);
|
|
}
|
|
}
|
|
}
|
|
if (sActiveSequences[seqPlayId].freqModChannelFlags != 0) {
|
|
for (channelId = 0; channelId < 16; channelId++) {
|
|
if (sActiveSequences[seqPlayId].channelMod[channelId].freq.timer != 0) {
|
|
sActiveSequences[seqPlayId].channelMod[channelId].freq.timer--;
|
|
if (sActiveSequences[seqPlayId].channelMod[channelId].freq.timer != 0) {
|
|
sActiveSequences[seqPlayId].channelMod[channelId].freq.value -=
|
|
sActiveSequences[seqPlayId].channelMod[channelId].freq.step;
|
|
} else {
|
|
sActiveSequences[seqPlayId].channelMod[channelId].freq.value =
|
|
sActiveSequences[seqPlayId].channelMod[channelId].freq.target;
|
|
sActiveSequences[seqPlayId].freqModChannelFlags ^= 1 << channelId;
|
|
}
|
|
AUDIOCMD_CHANNEL_SET_FREQ_SCALE((u32) seqPlayId, (u32) channelId,
|
|
sActiveSequences[seqPlayId].channelMod[channelId].freq.value);
|
|
}
|
|
}
|
|
}
|
|
if (sActiveSequences[seqPlayId].setupCmdNum == 0) {
|
|
continue;
|
|
}
|
|
if (!Audio_SeqCmdValueNotQueued(SEQCMD_OP_RESET_AUDIO_HEAP << 28, SEQCMD_OP_MASK)) {
|
|
sActiveSequences[seqPlayId].setupCmdNum = 0;
|
|
break;
|
|
}
|
|
if (sActiveSequences[seqPlayId].setupCmdTimer != 0) {
|
|
sActiveSequences[seqPlayId].setupCmdTimer--;
|
|
} else if (!gSeqPlayers[seqPlayId].enabled) {
|
|
for (i = 0; i < sActiveSequences[seqPlayId].setupCmdNum; i++) {
|
|
setupOp = (sActiveSequences[seqPlayId].setupCmd[i] & 0xF00000) >> 20;
|
|
|
|
setupSeqPlayId = (sActiveSequences[seqPlayId].setupCmd[i] & 0xF0000) >> 16;
|
|
val2 = (sActiveSequences[seqPlayId].setupCmd[i] & 0xFF00) >> 8;
|
|
val1 = sActiveSequences[seqPlayId].setupCmd[i] & 0xFF;
|
|
switch (setupOp) {
|
|
case SEQCMD_SUB_OP_SETUP_RESTORE_SEQPLAYER_VOLUME:
|
|
Audio_SetSequenceFade(setupSeqPlayId, 1, 127, val2);
|
|
break;
|
|
case SEQCMD_SUB_OP_SETUP_SEQ_UNQUEUE:
|
|
SEQCMD_UNQUEUE_SEQUENCE(seqPlayId, 0, sActiveSequences[seqPlayId].seqId);
|
|
break;
|
|
case SEQCMD_SUB_OP_SETUP_RESTART_SEQ:
|
|
SEQCMD_PLAY_SEQUENCE(setupSeqPlayId, 1, 0, sActiveSequences[setupSeqPlayId].seqId);
|
|
sActiveSequences[setupSeqPlayId].mainVolume.fadeActive = true;
|
|
sActiveSequences[setupSeqPlayId].mainVolume.fadeMod[1] = 127;
|
|
break;
|
|
case SEQCMD_SUB_OP_SETUP_TEMPO_SCALE:
|
|
SEQCMD_SCALE_TEMPO(setupSeqPlayId, val2, val1);
|
|
break;
|
|
case SEQCMD_SUB_OP_SETUP_TEMPO_RESET:
|
|
SEQCMD_RESET_TEMPO(setupSeqPlayId, val1);
|
|
break;
|
|
case SEQCMD_SUB_OP_SETUP_PLAY_SEQ:
|
|
seqId = sActiveSequences[seqPlayId].setupCmd[i] & 0xFFFF;
|
|
SEQCMD_PLAY_SEQUENCE(setupSeqPlayId, sActiveSequences[setupSeqPlayId].setupFadeTimer, 0, seqId);
|
|
Audio_SetSequenceFade(setupSeqPlayId, 1, 127, 0);
|
|
sActiveSequences[setupSeqPlayId].setupFadeTimer = 0;
|
|
break;
|
|
case SEQCMD_SUB_OP_SETUP_SET_FADE_TIMER:
|
|
sActiveSequences[seqPlayId].setupFadeTimer = val2;
|
|
break;
|
|
}
|
|
}
|
|
sActiveSequences[seqPlayId].setupCmdNum = 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
void Audio_SetDelayedSeqCmd(u32 seqCmd, u16 delay) {
|
|
u8 opcode = (seqCmd >> 0x1C);
|
|
|
|
sDelayedSeqCmds[opcode].seqData = seqCmd;
|
|
sDelayedSeqCmds[opcode].timer = delay;
|
|
sDelayedSeqCmdFlags |= 1 << opcode;
|
|
}
|
|
|
|
void Audio_UpdateDelayedSeqCmds(void) {
|
|
u8 opcode = 0;
|
|
u16 flag = 1;
|
|
u16 delayedCmdFlags = sDelayedSeqCmdFlags;
|
|
|
|
while (delayedCmdFlags) {
|
|
if (delayedCmdFlags & flag) {
|
|
if (sDelayedSeqCmds[opcode].timer != 0) {
|
|
sDelayedSeqCmds[opcode].timer--;
|
|
} else {
|
|
Audio_QueueSeqCmd(sDelayedSeqCmds[opcode].seqData);
|
|
sDelayedSeqCmdFlags ^= flag;
|
|
}
|
|
delayedCmdFlags ^= flag;
|
|
}
|
|
opcode++;
|
|
flag <<= 1;
|
|
}
|
|
}
|
|
|
|
u8 Audio_HandleReset(void) {
|
|
if (sAudioResetStatus != AUDIORESET_READY) {
|
|
if (sAudioResetStatus == AUDIORESET_WAIT) {
|
|
if (AudioThread_ResetComplete() == true) {
|
|
sAudioResetStatus = AUDIORESET_READY;
|
|
AUDIOCMD_SEQPLAYER_SET_IO(SEQ_PLAYER_SFX, 0, sSfxChannelLayout);
|
|
Audio_RestartSeqPlayers();
|
|
}
|
|
} else if (sAudioResetStatus == AUDIORESET_BLOCK) {
|
|
while (AudioThread_ResetComplete() != true) {
|
|
;
|
|
}
|
|
sAudioResetStatus = AUDIORESET_READY;
|
|
AUDIOCMD_SEQPLAYER_SET_IO(SEQ_PLAYER_SFX, 0, sSfxChannelLayout);
|
|
Audio_RestartSeqPlayers();
|
|
}
|
|
}
|
|
return sAudioResetStatus;
|
|
}
|
|
|
|
void Audio_ResetActiveSequences(void) {
|
|
u8 i;
|
|
|
|
for (i = 0; i < 4; i++) {
|
|
sNumSeqRequests[i] = 0;
|
|
sActiveSequences[i].seqId = SEQ_ID_NONE;
|
|
sActiveSequences[i].prevSeqId = SEQ_ID_NONE;
|
|
sActiveSequences[i].tempo.timer = 0;
|
|
sActiveSequences[i].tempoOriginal = 0;
|
|
sActiveSequences[i].tempoCmd = 0;
|
|
sActiveSequences[i].channelPortMask = 0;
|
|
sActiveSequences[i].setupCmdNum = 0;
|
|
sActiveSequences[i].setupFadeTimer = 0;
|
|
sActiveSequences[i].freqModChannelFlags = 0;
|
|
sActiveSequences[i].volChannelFlags = 0;
|
|
sActiveSequences[i].mainVolume.fadeMod[2] = 127;
|
|
}
|
|
}
|
|
|
|
void Audio_ResetActiveSequencesAndVolume(void) {
|
|
u8 i;
|
|
|
|
for (i = 0; i < 4; i++) {
|
|
sActiveSequences[i].mainVolume.mod = 1.0f;
|
|
sActiveSequences[i].mainVolume.timer = 0;
|
|
sActiveSequences[i].mainVolume.fadeActive = false;
|
|
sActiveSequences[i].mainVolume.fadeMod[0] = 127;
|
|
sActiveSequences[i].mainVolume.fadeMod[1] = 127;
|
|
sActiveSequences[i].mainVolume.fadeMod[2] = 127;
|
|
}
|
|
Audio_ResetActiveSequences();
|
|
}
|
|
|
|
void Audio_SetSfxBanksMute(u16 muteFlags) {
|
|
u8 i;
|
|
|
|
for (i = 0; i < 5; i++) {
|
|
sSfxBankMuted[i] = (muteFlags & 1) ? true : false;
|
|
muteFlags = muteFlags >> 1;
|
|
}
|
|
}
|
|
|
|
void Audio_ClearBGMMute(u8 channelIndex) {
|
|
sChannelMuteFlags &= (1 << channelIndex) ^ 0xFFFF;
|
|
if (sChannelMuteFlags == 0) {
|
|
Audio_SetSequenceFade(SEQ_PLAYER_BGM, 2, 127, 15);
|
|
}
|
|
}
|
|
|
|
void Audio_PlaySfx(u32 sfxId, f32* sfxSource, u8 token, f32* freqMod, f32* volMod, s8* reverbAdd) {
|
|
if (sSfxBankMuted[SFX_BANK_ALT(sfxId)] == 0) {
|
|
SfxRequest* request = &sSfxRequests[sSfxRequestWriteIndex];
|
|
|
|
request->sfxId = sfxId;
|
|
request->source = sfxSource;
|
|
request->token = token;
|
|
request->freqMod = freqMod;
|
|
request->volMod = volMod;
|
|
request->reverbAdd = reverbAdd;
|
|
sSfxRequestWriteIndex++;
|
|
}
|
|
}
|
|
|
|
void Audio_RemoveMatchingSfxRequests(u8 aspect, SfxBankEntry* data) {
|
|
u8 i = sSfxRequestReadIndex;
|
|
|
|
for (i; i != sSfxRequestWriteIndex; i++) {
|
|
s32 found = false;
|
|
SfxRequest* request = &sSfxRequests[i];
|
|
|
|
switch (aspect) {
|
|
case 0:
|
|
if ((request->sfxId & SFX_BANK_MASK) == (data->sfxId & SFX_BANK_MASK)) {
|
|
found = true;
|
|
}
|
|
break;
|
|
case 1:
|
|
if (((request->sfxId & SFX_BANK_MASK) == (data->sfxId & SFX_BANK_MASK)) &&
|
|
(&request->source[0] == data->xPos)) {
|
|
found = true;
|
|
}
|
|
break;
|
|
case 2:
|
|
if (&request->source[0] == data->xPos) {
|
|
found = true;
|
|
}
|
|
break;
|
|
case 3:
|
|
if ((&request->source[0] == data->xPos) && (request->sfxId == data->sfxId)) {
|
|
found = true;
|
|
}
|
|
break;
|
|
case 4:
|
|
if ((request->token == data->token) && (request->sfxId == data->sfxId)) {
|
|
found = true;
|
|
}
|
|
break;
|
|
case 5:
|
|
if (request->sfxId == data->sfxId) {
|
|
found = true;
|
|
}
|
|
break;
|
|
}
|
|
if (found) {
|
|
request->sfxId = NA_SE_NONE;
|
|
}
|
|
}
|
|
}
|
|
|
|
void Audio_ProcessSfxRequest(void) {
|
|
SfxRequest* request = &sSfxRequests[sSfxRequestReadIndex];
|
|
u8 next;
|
|
s32 bankId;
|
|
u8 evict;
|
|
u32 sfxId;
|
|
u8 count;
|
|
SfxBankEntry* entry;
|
|
|
|
if (request->sfxId == NA_SE_NONE) {
|
|
return;
|
|
}
|
|
bankId = SFX_BANK(request->sfxId);
|
|
next = sSfxBanks[bankId][0].next;
|
|
count = 0;
|
|
while ((next != 0xFF) && (next != 0)) {
|
|
if (&request->source[0] == sSfxBanks[bankId][next].xPos) {
|
|
if (request->sfxId == sSfxBanks[bankId][next].sfxId) {
|
|
count = sUsedChannelsPerBank[sSfxChannelLayout][bankId];
|
|
} else {
|
|
if (count == 0) {
|
|
evict = next;
|
|
sfxId = sSfxBanks[bankId][next].sfxId;
|
|
} else if ((sSfxBanks[bankId][next].sfxId & SFX_IMPORT_MASK) < (sfxId & SFX_IMPORT_MASK)) {
|
|
evict = next;
|
|
sfxId = sSfxBanks[bankId][next].sfxId;
|
|
}
|
|
count++;
|
|
if (count == sUsedChannelsPerBank[sSfxChannelLayout][bankId]) {
|
|
if ((request->sfxId & SFX_IMPORT_MASK) >= (sfxId & SFX_IMPORT_MASK)) {
|
|
next = evict;
|
|
} else {
|
|
next = 0;
|
|
}
|
|
}
|
|
}
|
|
if (count == sUsedChannelsPerBank[sSfxChannelLayout][bankId]) {
|
|
if ((request->sfxId & SFX_FLAG_27) || (request->sfxId & SFX_FLAG_18) || (next == evict)) {
|
|
if ((sSfxBanks[bankId][next].sfxId & SFX_FLAG_19) && (sSfxBanks[bankId][next].state != 1)) {
|
|
Audio_ClearBGMMute(sSfxBanks[bankId][next].channelIndex);
|
|
}
|
|
sSfxBanks[bankId][next].token = request->token;
|
|
sSfxBanks[bankId][next].sfxId = request->sfxId;
|
|
sSfxBanks[bankId][next].state = SFX_STATE(request->sfxId);
|
|
sSfxBanks[bankId][next].freshness = 2;
|
|
sSfxBanks[bankId][next].freqMod = request->freqMod;
|
|
sSfxBanks[bankId][next].volMod = request->volMod;
|
|
sSfxBanks[bankId][next].reverbAdd = request->reverbAdd;
|
|
}
|
|
next = 0;
|
|
}
|
|
}
|
|
if (next != 0) {
|
|
next = sSfxBanks[bankId][next].next;
|
|
}
|
|
}
|
|
if ((sSfxBanks[bankId][sSfxBankFreeListStart[bankId]].next != 0xFF) && (next != 0)) {
|
|
next = sSfxBankFreeListStart[bankId];
|
|
entry = &sSfxBanks[bankId][next];
|
|
entry->xPos = &request->source[0];
|
|
entry->yPos = &request->source[1];
|
|
entry->zPos = &request->source[2];
|
|
entry->token = request->token;
|
|
entry->freqMod = request->freqMod;
|
|
entry->volMod = request->volMod;
|
|
entry->reverbAdd = request->reverbAdd;
|
|
entry->sfxId = request->sfxId;
|
|
entry->state = SFX_STATE(request->sfxId);
|
|
entry->freshness = 2;
|
|
|
|
entry->prev = sSfxBankListEnd[bankId];
|
|
|
|
sSfxBanks[bankId][sSfxBankListEnd[bankId]].next = sSfxBankFreeListStart[bankId];
|
|
sSfxBankListEnd[bankId] = sSfxBankFreeListStart[bankId];
|
|
sSfxBankFreeListStart[bankId] = sSfxBanks[bankId][sSfxBankFreeListStart[bankId]].next;
|
|
sSfxBanks[bankId][sSfxBankFreeListStart[bankId]].prev = 0xFF;
|
|
|
|
entry->next = 0xFF;
|
|
}
|
|
}
|
|
|
|
void Audio_RemoveSfxBankEntry(u8 bankId, u8 entryIndex) {
|
|
SfxBankEntry* sfxBank = sSfxBanks[bankId];
|
|
s32 pad;
|
|
|
|
if (sfxBank[entryIndex].sfxId & SFX_FLAG_19) {
|
|
Audio_ClearBGMMute(sfxBank[entryIndex].channelIndex);
|
|
}
|
|
if (entryIndex == sSfxBankListEnd[bankId]) {
|
|
sSfxBankListEnd[bankId] = sfxBank[entryIndex].prev;
|
|
} else {
|
|
sfxBank[sfxBank[entryIndex].next].prev = sfxBank[entryIndex].prev;
|
|
}
|
|
sfxBank[sfxBank[entryIndex].prev].next = sfxBank[entryIndex].next;
|
|
sfxBank[entryIndex].next = sSfxBankFreeListStart[bankId];
|
|
sfxBank[entryIndex].prev = 0xFF;
|
|
|
|
sfxBank[sSfxBankFreeListStart[bankId]].prev = entryIndex;
|
|
sSfxBankFreeListStart[bankId] = entryIndex;
|
|
sfxBank[entryIndex].state = 0;
|
|
}
|
|
|
|
void Audio_ChooseActiveSfx(u8 bankId) {
|
|
u8 numChosenSfx = 0;
|
|
u8 numChannels;
|
|
u8 k;
|
|
u8 i;
|
|
SfxBankEntry* entry;
|
|
ActiveSfx* activeSfx;
|
|
f32 maxRangeSq;
|
|
f32 yScaled;
|
|
ActiveSfx chosenSfx[8];
|
|
u8 chosenEntryIndex;
|
|
u8 j;
|
|
u8 entryIndex;
|
|
u8 needNewSfx;
|
|
s32 importance;
|
|
|
|
for (i = 0; i < 8; i++) {
|
|
chosenSfx[i].priority = INT32_MAX;
|
|
chosenSfx[i].entryIndex = 0xFF;
|
|
}
|
|
entryIndex = sSfxBanks[bankId][0].next;
|
|
k = 0;
|
|
while (entryIndex != 0xFF) {
|
|
if ((sSfxBanks[bankId][entryIndex].state == 1) &&
|
|
((sSfxBanks[bankId][entryIndex].sfxId & SFX_FLAG_27) == SFX_FLAG_27)) {
|
|
sSfxBanks[bankId][entryIndex].freshness--;
|
|
}
|
|
if (sSfxBanks[bankId][entryIndex].freshness == 0) {
|
|
Audio_RemoveSfxBankEntry(bankId, entryIndex);
|
|
} else if (sSfxBanks[bankId][entryIndex].state != 0) {
|
|
entry = &sSfxBanks[bankId][entryIndex];
|
|
|
|
if (&entry->xPos[0] == gDefaultSfxSource) {
|
|
entry->distance = 0.0f;
|
|
} else {
|
|
yScaled = *entry->yPos / 2.5f;
|
|
entry->distance = SQ(*entry->xPos) + SQ(yScaled) + SQ(*entry->zPos);
|
|
}
|
|
importance = SFX_IMPORT(entry->sfxId);
|
|
if (entry->sfxId & SFX_FLAG_20) {
|
|
entry->priority = SQ(0xFF - importance) * SQ(76);
|
|
} else {
|
|
entry->priority = (u32) entry->distance + SQ(0xFF - importance) * SQ(76);
|
|
if (*entry->zPos > 0.0f) {
|
|
entry->priority += (s32) (*entry->zPos * 6.0f);
|
|
}
|
|
}
|
|
if (SFX_RANGE(entry->sfxId) != 0) {
|
|
maxRangeSq = SQ(33000.0f) / SQ((s32) SFX_RANGE(entry->sfxId));
|
|
} else {
|
|
maxRangeSq = SQ(100000.0f);
|
|
}
|
|
if (entry->distance > maxRangeSq) {
|
|
if (entry->state == 4) {
|
|
AUDIOCMD_CHANNEL_SET_IO(2, entry->channelIndex, 0, 0);
|
|
if (entry->sfxId & SFX_FLAG_27) {
|
|
Audio_RemoveSfxBankEntry(bankId, entryIndex);
|
|
entryIndex = k;
|
|
}
|
|
}
|
|
} else {
|
|
numChannels = sChannelsPerBank[sSfxChannelLayout][bankId];
|
|
for (i = 0; i < numChannels; i++) {
|
|
if (chosenSfx[i].priority >= entry->priority) {
|
|
if (numChosenSfx < sChannelsPerBank[sSfxChannelLayout][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;
|
|
}
|
|
}
|
|
}
|
|
k = entryIndex;
|
|
}
|
|
entryIndex = sSfxBanks[bankId][k].next;
|
|
}
|
|
|
|
for (i = 0; i < numChosenSfx; i++) {
|
|
if (sSfxBanks[bankId][chosenSfx[i].entryIndex].state == 1) {
|
|
sSfxBanks[bankId][chosenSfx[i].entryIndex].state = 2;
|
|
} else if (sSfxBanks[bankId][chosenSfx[i].entryIndex].state == 4) {
|
|
sSfxBanks[bankId][chosenSfx[i].entryIndex].state = 3;
|
|
}
|
|
}
|
|
numChannels = sChannelsPerBank[sSfxChannelLayout][bankId];
|
|
for (i = 0; i < numChannels; i++) {
|
|
activeSfx = &sActiveSfx[bankId][i];
|
|
needNewSfx = 0;
|
|
if (activeSfx->entryIndex == 0xFF) {
|
|
needNewSfx = 1;
|
|
} else if (sSfxBanks[bankId][activeSfx->entryIndex].state == 4) {
|
|
if (sSfxBanks[bankId][activeSfx->entryIndex].sfxId & SFX_FLAG_27) {
|
|
Audio_RemoveSfxBankEntry(bankId, activeSfx->entryIndex);
|
|
} else {
|
|
sSfxBanks[bankId][activeSfx->entryIndex].state = 1;
|
|
}
|
|
needNewSfx = 1;
|
|
} else if (sSfxBanks[bankId][activeSfx->entryIndex].state == 0) {
|
|
activeSfx->entryIndex = 0xFF;
|
|
needNewSfx = 1;
|
|
} else {
|
|
for (j = 0; j < numChannels; j++) {
|
|
if (activeSfx->entryIndex == chosenSfx[j].entryIndex) {
|
|
chosenSfx[j].entryIndex = 0xFF;
|
|
j = numChannels;
|
|
}
|
|
}
|
|
numChosenSfx--;
|
|
}
|
|
|
|
if (needNewSfx == 1) {
|
|
for (j = 0; j < numChannels; j++) {
|
|
chosenEntryIndex = chosenSfx[j].entryIndex;
|
|
if ((chosenEntryIndex != 0xFF) && (sSfxBanks[bankId][chosenEntryIndex].state != 3)) {
|
|
for (k = 0; k < numChannels; k++) {
|
|
if (chosenEntryIndex == sActiveSfx[bankId][k].entryIndex) {
|
|
needNewSfx = 0;
|
|
k = numChannels;
|
|
}
|
|
}
|
|
if (needNewSfx == 1) {
|
|
activeSfx->entryIndex = chosenEntryIndex;
|
|
chosenSfx[j].entryIndex = 0xFF;
|
|
j = numChannels + 1;
|
|
numChosenSfx--;
|
|
}
|
|
}
|
|
}
|
|
if (j == numChannels) {
|
|
activeSfx->entryIndex = 0xFF;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void Audio_PlayActiveSfx(u8 bankId) {
|
|
u8 i;
|
|
|
|
for (i = 0; i < sChannelsPerBank[sSfxChannelLayout][bankId]; i++) {
|
|
u8 entryIndex = sActiveSfx[bankId][i].entryIndex;
|
|
|
|
if (entryIndex != 0xFF) {
|
|
SfxBankEntry* entry = &sSfxBanks[bankId][entryIndex];
|
|
SequenceChannel* channel = gSeqPlayers[SEQ_PLAYER_SFX].channels[sCurSfxPlayerChannelIndex];
|
|
s32 pad;
|
|
|
|
if (entry->state == 2) {
|
|
entry->channelIndex = sCurSfxPlayerChannelIndex;
|
|
if (entry->sfxId & SFX_FLAG_19) {
|
|
sChannelMuteFlags |= 1 << sCurSfxPlayerChannelIndex;
|
|
Audio_SetSequenceFade(SEQ_PLAYER_BGM, 2, 64, 15);
|
|
}
|
|
Audio_SetSfxProperties(bankId, entryIndex, sCurSfxPlayerChannelIndex);
|
|
AUDIOCMD_CHANNEL_SET_IO(SEQ_PLAYER_SFX, sCurSfxPlayerChannelIndex, 0, 1);
|
|
AUDIOCMD_CHANNEL_SET_IO(SEQ_PLAYER_SFX, sCurSfxPlayerChannelIndex, 4, SFX_INDEX(entry->sfxId) & 0xFF);
|
|
entry->state = 4;
|
|
} else if ((u8) channel->seqScriptIO[7] == 0x80) {
|
|
AUDIOCMD_CHANNEL_SET_IO(SEQ_PLAYER_SFX, sCurSfxPlayerChannelIndex, 7, 0);
|
|
Audio_RemoveSfxBankEntry(bankId, entryIndex);
|
|
} else if (entry->state == 3) {
|
|
Audio_SetSfxProperties(bankId, entryIndex, sCurSfxPlayerChannelIndex);
|
|
entry->state = 4;
|
|
}
|
|
}
|
|
sCurSfxPlayerChannelIndex++;
|
|
}
|
|
}
|
|
|
|
void Audio_KillSfxByBank(u8 bankId) {
|
|
SfxBankEntry* entry;
|
|
u8 next = sSfxBanks[bankId][0].next;
|
|
|
|
SfxBankEntry cmp;
|
|
|
|
while (next != 0xFF) {
|
|
entry = &sSfxBanks[bankId][next];
|
|
if (entry->state >= 3) {
|
|
AUDIOCMD_CHANNEL_SET_IO(2, entry->channelIndex, 0, 0);
|
|
}
|
|
if (entry->state != 0) {
|
|
Audio_RemoveSfxBankEntry(bankId, next);
|
|
}
|
|
next = sSfxBanks[bankId][0].next;
|
|
}
|
|
cmp.sfxId = bankId << SFX_BANK_SHIFT;
|
|
Audio_RemoveMatchingSfxRequests(0, &cmp);
|
|
}
|
|
|
|
void Audio_StopSfxByBankAndSource(u8 bankId, f32* sfxSource) {
|
|
SfxBankEntry* entry;
|
|
u8 curIndex = 0;
|
|
u8 nextIndex = sSfxBanks[bankId][0].next;
|
|
|
|
while (nextIndex != 0xFF) {
|
|
entry = &sSfxBanks[bankId][nextIndex];
|
|
if (entry->xPos == sfxSource) {
|
|
if (entry->state >= 3) {
|
|
AUDIOCMD_CHANNEL_SET_IO(SEQ_PLAYER_SFX, entry->channelIndex, 0, 0);
|
|
}
|
|
if (entry->state != 0) {
|
|
Audio_RemoveSfxBankEntry(bankId, nextIndex);
|
|
}
|
|
} else {
|
|
curIndex = nextIndex;
|
|
}
|
|
nextIndex = sSfxBanks[bankId][curIndex].next;
|
|
}
|
|
}
|
|
|
|
void Audio_KillSfxByBankAndSource(u8 bankId, f32* sfxSource) {
|
|
SfxBankEntry cmp;
|
|
|
|
Audio_StopSfxByBankAndSource(bankId, sfxSource);
|
|
cmp.sfxId = bankId << SFX_BANK_SHIFT;
|
|
cmp.xPos = sfxSource;
|
|
Audio_RemoveMatchingSfxRequests(1, &cmp);
|
|
}
|
|
|
|
void Audio_KillSfxBySource(f32* sfxSource) {
|
|
u8 i;
|
|
SfxBankEntry cmp;
|
|
|
|
for (i = 0; i < 5; i++) {
|
|
Audio_StopSfxByBankAndSource(i, sfxSource);
|
|
}
|
|
cmp.xPos = sfxSource;
|
|
Audio_RemoveMatchingSfxRequests(2, &cmp);
|
|
}
|
|
|
|
void Audio_KillSfxBySourceAndId(f32* sfxSource, u32 sfxId) {
|
|
u32 bankId = SFX_BANK(sfxId);
|
|
u8 next = sSfxBanks[bankId][0].next;
|
|
u8 current = 0;
|
|
SfxBankEntry cmp;
|
|
|
|
while (next != 0xFF) {
|
|
if ((sSfxBanks[bankId][next].xPos == sfxSource) && (sSfxBanks[bankId][next].sfxId == sfxId)) {
|
|
if (sSfxBanks[bankId][next].state >= 3) {
|
|
AUDIOCMD_CHANNEL_SET_IO(SEQ_PLAYER_SFX, sSfxBanks[bankId][next].channelIndex, 0, 0);
|
|
}
|
|
if (sSfxBanks[bankId][next].state != 0) {
|
|
Audio_RemoveSfxBankEntry(bankId, next);
|
|
}
|
|
next = 0xFF;
|
|
} else {
|
|
current = next;
|
|
}
|
|
if (next != 0xFF) {
|
|
next = sSfxBanks[bankId][current].next;
|
|
}
|
|
}
|
|
cmp.sfxId = sfxId;
|
|
cmp.xPos = sfxSource;
|
|
Audio_RemoveMatchingSfxRequests(3, &cmp);
|
|
}
|
|
|
|
void Audio_KillSfxByTokenAndId(u8 token, u32 sfxId) {
|
|
u32 bankId = SFX_BANK(sfxId);
|
|
u8 next = sSfxBanks[bankId][0].next;
|
|
u8 current = 0;
|
|
SfxBankEntry cmp;
|
|
|
|
while (next != 0xFF) {
|
|
if ((sSfxBanks[bankId][next].token == token) && (sSfxBanks[bankId][next].sfxId == sfxId)) {
|
|
if (sSfxBanks[bankId][next].state >= 3) {
|
|
AUDIOCMD_CHANNEL_SET_IO(SEQ_PLAYER_SFX, sSfxBanks[bankId][next].channelIndex, 0, 0);
|
|
}
|
|
if (sSfxBanks[bankId][next].state != 0) {
|
|
Audio_RemoveSfxBankEntry(bankId, next);
|
|
}
|
|
} else {
|
|
current = next;
|
|
}
|
|
if (next != 0xFF) {
|
|
next = sSfxBanks[bankId][current].next;
|
|
}
|
|
}
|
|
cmp.token = token;
|
|
cmp.sfxId = sfxId;
|
|
Audio_RemoveMatchingSfxRequests(4, &cmp);
|
|
}
|
|
|
|
void Audio_KillSfxById(u32 sfxId) {
|
|
u32 bankId = SFX_BANK(sfxId);
|
|
u8 next = sSfxBanks[bankId][0].next;
|
|
u8 current = 0;
|
|
SfxBankEntry cmp;
|
|
|
|
while (next != 0xFF) {
|
|
if (sfxId == sSfxBanks[bankId][next].sfxId) {
|
|
if (sSfxBanks[bankId][next].state >= 3) {
|
|
AUDIOCMD_CHANNEL_SET_IO(SEQ_PLAYER_SFX, sSfxBanks[bankId][next].channelIndex, 0, 0);
|
|
}
|
|
if (sSfxBanks[bankId][next].state != 0) {
|
|
Audio_RemoveSfxBankEntry(bankId, next);
|
|
}
|
|
} else {
|
|
current = next;
|
|
}
|
|
next = sSfxBanks[bankId][current].next;
|
|
}
|
|
cmp.sfxId = sfxId;
|
|
Audio_RemoveMatchingSfxRequests(5, &cmp);
|
|
}
|
|
|
|
void Audio_ProcessSfxRequests(void) {
|
|
while (sSfxRequestWriteIndex != sSfxRequestReadIndex) {
|
|
Audio_ProcessSfxRequest();
|
|
sSfxRequestReadIndex++;
|
|
}
|
|
}
|
|
|
|
void Audio_SetSfxVolumeMod(u8 bankId, u8 target, u16 timer) {
|
|
Modulation* scale = &sSfxVolumeMods[bankId];
|
|
|
|
if (timer == 0) {
|
|
timer++;
|
|
}
|
|
|
|
scale->target = target / 127.0f;
|
|
scale->timer = timer;
|
|
scale->step = (scale->value - scale->target) / timer;
|
|
}
|
|
|
|
void Audio_UpdateSfxVolumeMod(u8 bankId) {
|
|
Modulation* scale = &sSfxVolumeMods[bankId];
|
|
|
|
if (scale->timer != 0) {
|
|
scale->timer--;
|
|
if (scale->timer != 0) {
|
|
scale->value -= scale->step;
|
|
} else {
|
|
scale->value = scale->target;
|
|
}
|
|
}
|
|
}
|
|
|
|
void Audio_PlayAllSfx(void) {
|
|
u8 bankId;
|
|
|
|
if (IS_SEQUENCE_CHANNEL_VALID(gSeqPlayers[SEQ_PLAYER_SFX].channels[0])) {
|
|
sCurSfxPlayerChannelIndex = 0;
|
|
for (bankId = 0; bankId < ARRAY_COUNT(sSfxBanks); bankId++) {
|
|
Audio_ChooseActiveSfx(bankId);
|
|
Audio_PlayActiveSfx(bankId);
|
|
Audio_UpdateSfxVolumeMod(bankId);
|
|
}
|
|
}
|
|
}
|
|
|
|
void Audio_ResetSfx(void) {
|
|
u8 i;
|
|
u8 j;
|
|
|
|
sSfxRequestWriteIndex = 0;
|
|
sSfxRequestReadIndex = 0;
|
|
sChannelMuteFlags = 0;
|
|
for (i = 0; i < 5; i++) {
|
|
sSfxBankListEnd[i] = 0;
|
|
sSfxBankFreeListStart[i] = 1;
|
|
sSfxBankUnused[i] = 0;
|
|
sSfxBankMuted[i] = 0;
|
|
sSfxVolumeMods[i].value = 1.0f;
|
|
sSfxVolumeMods[i].timer = 0;
|
|
}
|
|
for (i = 0; i < 5; i++) {
|
|
for (j = 0; j < 8; j++) {
|
|
sActiveSfx[i][j].entryIndex = 0xFF;
|
|
}
|
|
}
|
|
for (i = 0; i < 5; i++) {
|
|
sSfxBanks[i][0].prev = 0xFF;
|
|
sSfxBanks[i][0].next = 0xFF;
|
|
for (j = 1; j < 19; j++) {
|
|
sSfxBanks[i][j].prev = j - 1;
|
|
sSfxBanks[i][j].next = j + 1;
|
|
}
|
|
sSfxBanks[i][j].prev = j - 1;
|
|
sSfxBanks[i][j].next = 0xFF;
|
|
}
|
|
}
|
|
|
|
void Audio_PlayVoice(s32 msgId) {
|
|
sCurrentVoiceId = sNextVoiceId = msgId;
|
|
sSetNextVoiceId = true;
|
|
}
|
|
|
|
void Audio_PlayVoiceWithoutBGM(u32 msgId) {
|
|
sMuteBgmForVoice = true;
|
|
Audio_SetSequenceFade(SEQ_PLAYER_BGM, 2, 64, 15);
|
|
Audio_PlayVoice(msgId);
|
|
}
|
|
|
|
void Audio_UpdateVoice(void) {
|
|
s8 voiceBank;
|
|
u16 voiceId;
|
|
u8 voiceIdHi;
|
|
u8 voiceIdLo;
|
|
|
|
if (sSetNextVoiceId) {
|
|
voiceBank = sNextVoiceId / 1000;
|
|
voiceId = sNextVoiceId % 1000;
|
|
voiceIdHi = voiceId / 256;
|
|
voiceIdLo = voiceId % 256;
|
|
AUDIOCMD_CHANNEL_SET_IO(SEQ_PLAYER_VOICE, 15, 0, 1);
|
|
AUDIOCMD_CHANNEL_SET_IO(SEQ_PLAYER_VOICE, 15, 4, voiceBank);
|
|
AUDIOCMD_CHANNEL_SET_IO(SEQ_PLAYER_VOICE, 15, 5, voiceIdHi);
|
|
AUDIOCMD_CHANNEL_SET_IO(SEQ_PLAYER_VOICE, 15, 6, voiceIdLo);
|
|
sSetNextVoiceId = false;
|
|
} else if ((sMuteBgmForVoice) && (Audio_GetCurrentVoice() == 0)) {
|
|
Audio_SetSequenceFade(SEQ_PLAYER_BGM, 2, 127, 15);
|
|
sMuteBgmForVoice = false;
|
|
}
|
|
}
|
|
|
|
void Audio_ClearVoice(void) {
|
|
sCurrentVoiceId = 0;
|
|
sNextVoiceId = 1;
|
|
sSetNextVoiceId = true;
|
|
}
|
|
|
|
s32 Audio_GetCurrentVoice(void) {
|
|
if (!IS_SEQUENCE_CHANNEL_VALID(gSeqPlayers[SEQ_PLAYER_VOICE].channels[15])) {
|
|
return 0;
|
|
}
|
|
if (gSeqPlayers[SEQ_PLAYER_VOICE].channels[15]->seqScriptIO[1] == 1) {
|
|
if (sCurrentVoiceId < 4) {
|
|
return 0;
|
|
} else {
|
|
return sCurrentVoiceId;
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
s32 Audio_GetCurrentVoiceStatus(void) {
|
|
SequenceChannel* channel = gSeqPlayers[SEQ_PLAYER_VOICE].channels[15];
|
|
SequenceLayer* layer = channel->layers[0];
|
|
|
|
if (!IS_SEQUENCE_CHANNEL_VALID(channel) || (layer == NULL) || (channel->seqScriptIO[1] != 1)) {
|
|
return 0;
|
|
}
|
|
if (layer->note != NULL) {
|
|
if (layer != layer->note->playbackState.parentLayer) {
|
|
return 2;
|
|
} else {
|
|
return 1;
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
void Audio_SetUnkVoiceParam(u8 unkVoiceParam) {
|
|
sUnkVoiceParam = unkVoiceParam;
|
|
}
|
|
|
|
void Audio_UpdateUnkVoiceParam(void) {
|
|
if (sUnkVoiceParam != 0xFF) {
|
|
AUDIOCMD_CHANNEL_SET_IO(SEQ_PLAYER_VOICE, 14, 0, sUnkVoiceParam);
|
|
sUnkVoiceParam = 0xFF;
|
|
}
|
|
}
|
|
|
|
void Audio_ResetPlayerFreqMods(void) {
|
|
u8 i;
|
|
u8 j;
|
|
|
|
for (i = 0; i < 4; i++) {
|
|
for (j = 0; j < 5; j++) {
|
|
sPlayerNoise[i].freqMod[j].value = 1.0f;
|
|
sPlayerNoise[i].freqMod[j].timer = 0;
|
|
sPlayerNoise[i].freqMod[j].boost = 0;
|
|
sPlayerNoise[i].freqMod[j].brake = 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
void Audio_UpdateArwingNoise(u8 playerId) {
|
|
f32 freqMod;
|
|
u8 i;
|
|
|
|
if (gPlayer[playerId].sfx.boost) {
|
|
sPlayerNoise[playerId].freqMod[0].target = 1.5f;
|
|
sPlayerNoise[playerId].freqMod[0].timer = 18;
|
|
sPlayerNoise[playerId].freqMod[0].step =
|
|
(sPlayerNoise[playerId].freqMod[0].target - sPlayerNoise[playerId].freqMod[0].value) / 18;
|
|
sPlayerNoise[playerId].freqMod[0].boost = true;
|
|
} else if (sPlayerNoise[playerId].freqMod[0].boost) {
|
|
sPlayerNoise[playerId].freqMod[0].boost = false;
|
|
sPlayerNoise[playerId].freqMod[0].timer = 1;
|
|
}
|
|
if (gPlayer[playerId].sfx.brake) {
|
|
sPlayerNoise[playerId].freqMod[0].target = 0.65f;
|
|
sPlayerNoise[playerId].freqMod[0].timer = 20;
|
|
sPlayerNoise[playerId].freqMod[0].step =
|
|
(sPlayerNoise[playerId].freqMod[0].target - sPlayerNoise[playerId].freqMod[0].value) / 20;
|
|
sPlayerNoise[playerId].freqMod[0].brake = true;
|
|
} else if (sPlayerNoise[playerId].freqMod[0].brake) {
|
|
sPlayerNoise[playerId].freqMod[0].brake = false;
|
|
sPlayerNoise[playerId].freqMod[0].timer = 1;
|
|
}
|
|
if ((gPlayer[playerId].sfx.bank != 0) && (gPlayer[playerId].sfx.zRot < 45.0f)) {
|
|
sPlayerNoise[playerId].freqMod[2].target = 1.25f;
|
|
sPlayerNoise[playerId].freqMod[2].timer = 10;
|
|
sPlayerNoise[playerId].freqMod[2].step =
|
|
(sPlayerNoise[playerId].freqMod[2].target - sPlayerNoise[playerId].freqMod[2].value) / 10;
|
|
}
|
|
if (gPlayer[playerId].sfx.roll != 0) {
|
|
AUDIO_PLAY_SFX(NA_SE_ROLLING_AIR, gPlayer[playerId].sfx.srcPos, playerId);
|
|
sPlayerNoise[playerId].freqMod[1].target = 1.65f;
|
|
sPlayerNoise[playerId].freqMod[1].timer = 8;
|
|
sPlayerNoise[playerId].freqMod[1].step =
|
|
(sPlayerNoise[playerId].freqMod[1].target - sPlayerNoise[playerId].freqMod[1].value) / 8;
|
|
}
|
|
if (ABS(gPlayer[playerId].sfx.yVel) > 2.0f) {
|
|
sPlayerNoise[playerId].freqMod[3].target = 1.25f;
|
|
sPlayerNoise[playerId].freqMod[3].timer = 15;
|
|
sPlayerNoise[playerId].freqMod[3].step =
|
|
(sPlayerNoise[playerId].freqMod[3].target - sPlayerNoise[playerId].freqMod[3].value) / 15;
|
|
sPlayerNoise[playerId].freqMod[3].boost = true;
|
|
} else if (sPlayerNoise[playerId].freqMod[3].boost) {
|
|
sPlayerNoise[playerId].freqMod[3].boost = false;
|
|
sPlayerNoise[playerId].freqMod[3].timer = 1;
|
|
}
|
|
if (sPlayerNoise[playerId].freqMod[4].timer == 0) {
|
|
sPlayerNoise[playerId].freqMod[4].target = (((f32) (gAudioRandom % 0x10000) / 32768.0) * 0.15f) + 1.0f - 0.15f;
|
|
sPlayerNoise[playerId].freqMod[4].timer = 16 + (gAudioRandom >> 27);
|
|
sPlayerNoise[playerId].freqMod[4].step =
|
|
(sPlayerNoise[playerId].freqMod[4].target - sPlayerNoise[playerId].freqMod[3].value) /
|
|
sPlayerNoise[playerId].freqMod[4].timer;
|
|
}
|
|
for (i = 0; i < 5; i++) {
|
|
if (sPlayerNoise[playerId].freqMod[i].timer != 0) {
|
|
sPlayerNoise[playerId].freqMod[i].timer--;
|
|
sPlayerNoise[playerId].freqMod[i].value += sPlayerNoise[playerId].freqMod[i].step;
|
|
if ((sPlayerNoise[playerId].freqMod[i].timer == 0) && (sPlayerNoise[playerId].freqMod[i].target != 1.0f)) {
|
|
sPlayerNoise[playerId].freqMod[i].target = 1.0f;
|
|
sPlayerNoise[playerId].freqMod[i].timer = sPlayerNoiseTimes[i];
|
|
sPlayerNoise[playerId].freqMod[i].step =
|
|
(1.0f - sPlayerNoise[playerId].freqMod[i].value) / sPlayerNoiseTimes[i];
|
|
}
|
|
}
|
|
}
|
|
freqMod = 1.0f;
|
|
for (i = 0; i < 5; i++) {
|
|
freqMod *= sPlayerNoise[playerId].freqMod[i].value;
|
|
}
|
|
if (freqMod >= 4.0f) {
|
|
freqMod = 4.0f;
|
|
}
|
|
sPlayerNoise[playerId].totalMod = freqMod;
|
|
}
|
|
|
|
void Audio_UpdateLandmasterNoise(u8 playerId) {
|
|
f32 freqMod;
|
|
u8 i;
|
|
|
|
if ((gPlayer[playerId].sfx.bank != 0) && (gPlayer[playerId].sfx.zRot < 45.0f)) {
|
|
sPlayerNoise[playerId].freqMod[2].timer = 10;
|
|
sPlayerNoise[playerId].freqMod[2].target = 1.25f;
|
|
sPlayerNoise[playerId].freqMod[2].step = (1.25f - sPlayerNoise[playerId].freqMod[2].value) / 10;
|
|
}
|
|
if (gPlayer[playerId].sfx.roll != 0) {
|
|
sPlayerNoise[playerId].freqMod[1].timer = 8;
|
|
sPlayerNoise[playerId].freqMod[1].target = 1.65f;
|
|
sPlayerNoise[playerId].freqMod[1].step = (1.65f - sPlayerNoise[playerId].freqMod[1].value) / 8;
|
|
}
|
|
if (ABS(gPlayer[playerId].sfx.yVel) > 2.0f) {
|
|
sPlayerNoise[playerId].freqMod[3].target = 1.25f;
|
|
sPlayerNoise[playerId].freqMod[3].timer = 15;
|
|
sPlayerNoise[playerId].freqMod[3].boost = true;
|
|
sPlayerNoise[playerId].freqMod[3].step = (1.25f - sPlayerNoise[playerId].freqMod[3].value) / 15;
|
|
} else if (sPlayerNoise[playerId].freqMod[3].boost) {
|
|
sPlayerNoise[playerId].freqMod[3].boost = false;
|
|
sPlayerNoise[playerId].freqMod[3].timer = 1;
|
|
}
|
|
for (i = 0; i < 5; i++) {
|
|
if (sPlayerNoise[playerId].freqMod[i].timer != 0) {
|
|
sPlayerNoise[playerId].freqMod[i].timer--;
|
|
sPlayerNoise[playerId].freqMod[i].value += sPlayerNoise[playerId].freqMod[i].step;
|
|
if ((sPlayerNoise[playerId].freqMod[i].timer == 0) && (sPlayerNoise[playerId].freqMod[i].target != 1.0f)) {
|
|
sPlayerNoise[playerId].freqMod[i].target = 1.0f;
|
|
sPlayerNoise[playerId].freqMod[i].timer = sPlayerNoiseTimes[i];
|
|
sPlayerNoise[playerId].freqMod[i].step =
|
|
(1.0f - sPlayerNoise[playerId].freqMod[i].value) / sPlayerNoiseTimes[i];
|
|
}
|
|
}
|
|
}
|
|
freqMod = 1.0f;
|
|
for (i = 0; i < 5; i++) {
|
|
freqMod *= sPlayerNoise[playerId].freqMod[i].value;
|
|
}
|
|
if (ABS(gPlayer[playerId].pos.y) < 600.0f) {
|
|
freqMod += (gPlayer[playerId].pos.y / 600.0f);
|
|
} else {
|
|
freqMod += 1.0f;
|
|
}
|
|
if (gPlayer[playerId].baseSpeed > 25.0f) {
|
|
freqMod += 0.5f;
|
|
} else if (gPlayer[playerId].baseSpeed < 5.0f) {
|
|
freqMod -= 0.5f;
|
|
} else {
|
|
freqMod += (gPlayer[playerId].baseSpeed - 15.0f) * 0.05f;
|
|
}
|
|
if (freqMod > 2.0f) {
|
|
freqMod = 2.0f;
|
|
}
|
|
sPlayerNoise[playerId].totalMod = freqMod;
|
|
}
|
|
|
|
void Audio_UpdateBlueMarineNoise(u8 playerId) {
|
|
u8 i;
|
|
f32 freqMod;
|
|
|
|
if ((gPlayer[playerId].sfx.bank != 0) && (gPlayer[playerId].sfx.zRot < 45.0f)) {
|
|
sPlayerNoise[playerId].freqMod[2].timer = 10;
|
|
sPlayerNoise[playerId].freqMod[2].target = 1.1f;
|
|
sPlayerNoise[playerId].freqMod[2].step = (1.1f - sPlayerNoise[playerId].freqMod[2].value) / 10;
|
|
}
|
|
if (gPlayer[playerId].sfx.roll != 0) {
|
|
AUDIO_PLAY_SFX(NA_SE_MAR_ROLLING_AIR, gPlayer[playerId].sfx.srcPos, playerId);
|
|
sPlayerNoise[playerId].freqMod[1].timer = 8;
|
|
sPlayerNoise[playerId].freqMod[1].target = 1.2f;
|
|
sPlayerNoise[playerId].freqMod[1].step = (1.2f - sPlayerNoise[playerId].freqMod[1].value) / 8;
|
|
}
|
|
if (ABS(gPlayer[playerId].sfx.yVel) > 2.0f) {
|
|
sPlayerNoise[playerId].freqMod[3].timer = 15;
|
|
sPlayerNoise[playerId].freqMod[3].boost = true;
|
|
sPlayerNoise[playerId].freqMod[3].target = 1.12f;
|
|
sPlayerNoise[playerId].freqMod[3].step = (1.12f - sPlayerNoise[playerId].freqMod[3].value) / 15;
|
|
} else if (sPlayerNoise[playerId].freqMod[3].boost) {
|
|
sPlayerNoise[playerId].freqMod[3].boost = false;
|
|
sPlayerNoise[playerId].freqMod[3].timer = 1;
|
|
}
|
|
for (i = 0; i < 5; i++) {
|
|
if (sPlayerNoise[playerId].freqMod[i].timer != 0) {
|
|
sPlayerNoise[playerId].freqMod[i].timer--;
|
|
sPlayerNoise[playerId].freqMod[i].value += sPlayerNoise[playerId].freqMod[i].step;
|
|
if ((sPlayerNoise[playerId].freqMod[i].timer == 0) && (sPlayerNoise[playerId].freqMod[i].target != 1.0f)) {
|
|
sPlayerNoise[playerId].freqMod[i].target = 1.0f;
|
|
sPlayerNoise[playerId].freqMod[i].timer = sPlayerNoiseTimes[i];
|
|
sPlayerNoise[playerId].freqMod[i].step =
|
|
(1.0f - sPlayerNoise[playerId].freqMod[i].value) / sPlayerNoiseTimes[i];
|
|
}
|
|
}
|
|
}
|
|
freqMod = 1.0f;
|
|
|
|
for (i = 0; i < 5; i++) {
|
|
freqMod *= sPlayerNoise[playerId].freqMod[i].value;
|
|
}
|
|
if (freqMod > 2.0f) {
|
|
freqMod = 2.0f;
|
|
}
|
|
sPlayerNoise[playerId].totalMod = freqMod;
|
|
}
|
|
|
|
void Audio_UpdatePlayerFreqMod(void) {
|
|
u8 playerId;
|
|
|
|
#ifdef AVOID_UB
|
|
for (playerId = 0; playerId < gCamCount; playerId++) {
|
|
#else
|
|
for (playerId = 0; playerId < 4; playerId++) {
|
|
#endif
|
|
switch (sPlayerNoise[playerId].form) {
|
|
case FORM_ARWING:
|
|
Audio_UpdateArwingNoise(playerId);
|
|
sPlayerNoise[playerId].totalMod *=
|
|
Audio_UpdateDopplerShift(gPlayer[playerId].sfx.srcPos, gPlayer[playerId].sfx.srcVel, 150.0f,
|
|
&sPlayerNoise[playerId].dopplerShift);
|
|
break;
|
|
case FORM_LANDMASTER:
|
|
Audio_UpdateLandmasterNoise(playerId);
|
|
break;
|
|
case FORM_BLUE_MARINE:
|
|
Audio_UpdateBlueMarineNoise(playerId);
|
|
break;
|
|
case FORM_NONE:
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
void Audio_UpdatePlayerReverb(void) {
|
|
u8 playerId;
|
|
|
|
for (playerId = 0; playerId < 4; playerId++) {
|
|
if ((sPlayerNoise[playerId].form == FORM_ARWING) && (gPlayer[playerId].sfx.levelType == LEVELTYPE_PLANET)) {
|
|
if (gPlayer[playerId].pos.y < 150.0f) {
|
|
sPlayerNoise[playerId].reverbAdd = (150.0f - gPlayer[playerId].pos.y) * 0.53f;
|
|
} else {
|
|
sPlayerNoise[playerId].reverbAdd = 0;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void Audio_UpdatePlayerNoise(void) {
|
|
Audio_UpdatePlayerFreqMod();
|
|
Audio_UpdatePlayerReverb();
|
|
}
|
|
|
|
void Audio_ResetVoicesAndPlayers(void) {
|
|
u8 playerId;
|
|
|
|
Audio_ResetPlayerFreqMods();
|
|
for (playerId = 0; playerId < 4; playerId++) {
|
|
sPlayerNoise[playerId].form = FORM_NONE;
|
|
sPlayerNoise[playerId].reverbAdd = 0;
|
|
sPlayerNoise[playerId].totalMod = 1.0f;
|
|
sPlayerNoise[playerId].dopplerShift = 1.0f;
|
|
sBombState[playerId] = 0;
|
|
sBombStartFrame[playerId] = 0;
|
|
}
|
|
sSfxFreqMod = 1.0f;
|
|
sSfxVolMod = 1.0f;
|
|
sNextVoiceId = 0;
|
|
sCurrentVoiceId = 0;
|
|
sSetNextVoiceId = 0;
|
|
sMuteBgmForVoice = 0;
|
|
sPlaylistIndex = 0xFF;
|
|
}
|
|
|
|
void Audio_ProcessPlaylist(void) {
|
|
PlaylistCmd* cmd;
|
|
u32 temp;
|
|
u32 temp2;
|
|
u32 temp1;
|
|
u32 temp5;
|
|
|
|
if (sPlaylistIndex != 0xFF) {
|
|
if (sPlaylistTimer == 0) {
|
|
cmd = &sPlaylists[sPlaylistIndex][sPlaylistCmdIndex];
|
|
switch (cmd->opCode) {
|
|
case 0:
|
|
Audio_PlaySequence(cmd->seqPlayId, cmd->seqId & 0xFF, 0, cmd->bgmParam);
|
|
sPlaylistTimer = sPlaylists[sPlaylistIndex][sPlaylistCmdIndex].timer;
|
|
sPlaylistCmdIndex++;
|
|
break;
|
|
case 1:
|
|
SEQCMD_STOP_SEQUENCE_ALT(cmd->seqPlayId, cmd->fadeoutTime);
|
|
sPlaylistTimer = sPlaylists[sPlaylistIndex][sPlaylistCmdIndex].timer;
|
|
sPlaylistCmdIndex++;
|
|
break;
|
|
case 2:
|
|
Audio_PlaySequenceDistorted(cmd->seqPlayId, cmd->seqId & 0xFF, 1121, 25, cmd->bgmParam);
|
|
sPlaylistTimer = sPlaylists[sPlaylistIndex][sPlaylistCmdIndex].timer;
|
|
sPlaylistCmdIndex++;
|
|
break;
|
|
case 3:
|
|
Audio_PlayFanfare(cmd->seqId & 0xFF, 20, 10, 10);
|
|
sPlaylistTimer = sPlaylists[sPlaylistIndex][sPlaylistCmdIndex].timer;
|
|
sPlaylistCmdIndex++;
|
|
break;
|
|
case 0xFF:
|
|
sPlaylistIndex = 0xFF;
|
|
break;
|
|
}
|
|
} else {
|
|
sPlaylistTimer--;
|
|
}
|
|
}
|
|
}
|
|
|
|
void Audio_AnalyzeFrequencies(f32* buffer0, f32* buffer1, s32 length, f32* buffer2) {
|
|
f32 temp_ft0;
|
|
f32 var_fs0;
|
|
f32* buff0fromStart;
|
|
f32* buf2half2;
|
|
f32* buf2half3;
|
|
f32* buff1half1;
|
|
f32* buff0FromEnd;
|
|
f32* buff1half2;
|
|
s32 half;
|
|
s32 i;
|
|
s32 size;
|
|
|
|
size = 1 << length;
|
|
half = size >> 1;
|
|
|
|
// Initialize buffer 2 if it is the wrong size for this calculation
|
|
if (size != (s32) buffer2[0]) {
|
|
buf2half2 = &buffer2[half];
|
|
buf2half3 = &buf2half2[half];
|
|
var_fs0 = 0.0f;
|
|
temp_ft0 = D_PI / (2 * size);
|
|
for (i = 0; i < half; i++) {
|
|
*buf2half2++ = (__cosf(var_fs0) - __sinf(var_fs0)) * 0.707107f; // approx 1/sqrt(2)
|
|
*buf2half3++ = (__cosf(var_fs0) + __sinf(var_fs0)) * 0.707107f; // approx 1/sqrt(2)
|
|
var_fs0 += temp_ft0;
|
|
}
|
|
}
|
|
|
|
buff0fromStart = buffer0;
|
|
buff0FromEnd = &buffer0[size - 1];
|
|
buff1half1 = buffer1;
|
|
buff1half2 = &buffer1[half];
|
|
|
|
// Copy even entries of buffer 0 into the first half of buffer 1. Copy odd entries into the second half in reverse
|
|
// order
|
|
for (i = 0; i < half; i++) {
|
|
*buff1half1++ = *buff0fromStart;
|
|
*buff1half2++ = *buff0FromEnd;
|
|
buff0fromStart += 2;
|
|
buff0FromEnd -= 2;
|
|
}
|
|
|
|
// reset the buffer pointers
|
|
buff0FromEnd = &buffer0[size - 1];
|
|
buff0fromStart = buffer0;
|
|
buf2half2 = &buffer2[half];
|
|
buf2half3 = &buf2half2[half];
|
|
buff1half1 = buffer1;
|
|
|
|
// FFT buffer 1 using buffer 2
|
|
func_80008780(buffer1, length, buffer2);
|
|
|
|
// handle i = 0 case
|
|
buff0fromStart[0] = buff1half1[0];
|
|
buff0fromStart[half] = buff1half1[half];
|
|
|
|
// advance buffer pointers
|
|
buf2half2++;
|
|
buf2half3++;
|
|
buff0fromStart++;
|
|
buff1half1++;
|
|
|
|
// second half of buffer 1 in reverse order this time
|
|
buff1half2 = &buffer1[size - 1];
|
|
|
|
// convert to real amplitudes
|
|
for (i = 1; i < half; i++) {
|
|
*buff0fromStart++ = (*buf2half2 * *buff1half1) + (*buf2half3 * *buff1half2);
|
|
*buff0FromEnd-- = (*buf2half3 * *buff1half1) - (*buf2half2 * *buff1half2);
|
|
buff1half1++;
|
|
buf2half3++;
|
|
buf2half2++;
|
|
buff1half2--;
|
|
}
|
|
}
|
|
|
|
u8* Audio_UpdateFrequencyAnalysis(void) {
|
|
s32 fmax;
|
|
s32 i1;
|
|
s32 fmin;
|
|
s32 i2;
|
|
s32 i3;
|
|
s32 fbin;
|
|
s16* aiData;
|
|
s32 pad;
|
|
static s32 sFreqBins[] = {
|
|
0, 1, 2, 3, 4, 6, 7, 8, 9, 10, 11, 12, 14, 16, 19, 22,
|
|
26, 31, 37, 44, 54, 68, 88, 108, 138, 163, 188, 208, 222, 234, 242, 246,
|
|
};
|
|
static f32 sFreqGain = 17.0f;
|
|
static f32 sFreqAmplitudes[32] = {
|
|
0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
|
|
0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
|
|
};
|
|
|
|
Audio_ProcessPlaylist();
|
|
// clang-format off
|
|
aiData = gAiBuffers[gCurAiBuffIndex];\
|
|
for(i3 = 0; i3 < 256; i3++) {\
|
|
sAudioAnalyzerData[i3] = *aiData++;
|
|
}
|
|
// clang-format on
|
|
Audio_AnalyzeFrequencies(sAudioAnalyzerData, sAnalyzerBuffer1, 8, sAnalyzerBuffer2);
|
|
fmin = 0;
|
|
for (i1 = 0; i1 < 32; i1++) {
|
|
fmax = sFreqBins[i1] + 1;
|
|
for (fbin = fmin; fbin < fmax; fbin++) {
|
|
if (sAudioAnalyzerData[fbin] > 0.0f) {
|
|
sNewFreqAmplitudes[i1] += sAudioAnalyzerData[fbin];
|
|
} else {
|
|
sNewFreqAmplitudes[i1] -= sAudioAnalyzerData[fbin];
|
|
}
|
|
}
|
|
fmin = fbin;
|
|
}
|
|
for (i2 = 0; i2 < 32; i2++) {
|
|
sNewFreqAmplitudes[i2] /= 8;
|
|
}
|
|
for (i3 = 0; i3 < 32; i3++) {
|
|
sNewFreqAmplitudes[i3] = (sNewFreqAmplitudes[i3] / 32768.0f) * sFreqGain;
|
|
if (sNewFreqAmplitudes[i3] > 1.0f) {
|
|
sNewFreqAmplitudes[i3] = 1.0f;
|
|
}
|
|
sFreqAmplitudes[i3] = sFreqAmplitudes[i3] * 0.75f + 0.25f * sNewFreqAmplitudes[i3];
|
|
sFreqAnalyzerBars[i3] = sFreqAmplitudes[i3] * 255.0f;
|
|
}
|
|
return sFreqAnalyzerBars;
|
|
}
|
|
|
|
void Audio_StartPlayerNoise(u8 playerId) {
|
|
u32 sfxId = NA_SE_NONE;
|
|
|
|
sPlayerNoise[playerId].form = gPlayer[playerId].sfx.form;
|
|
Audio_ResetPlayerFreqMods();
|
|
switch (sPlayerNoise[playerId].form) {
|
|
case FORM_ARWING:
|
|
if (gPlayer[playerId].sfx.levelType == LEVELTYPE_SPACE) {
|
|
sfxId = NA_SE_ARWING_ENGIN_SPC;
|
|
} else {
|
|
sfxId = NA_SE_ARWING_ENGIN_GRD;
|
|
}
|
|
break;
|
|
case FORM_LANDMASTER:
|
|
sfxId = NA_SE_TANK_ENGIN;
|
|
break;
|
|
case FORM_BLUE_MARINE:
|
|
sfxId = NA_SE_MARINE_ENGINE00;
|
|
Audio_PlaySfx(NA_SE_SUBMARINE_ATM, gPlayer[playerId].sfx.srcPos, playerId, &gDefaultMod, &gDefaultMod,
|
|
&sPlayerNoise[playerId].reverbAdd);
|
|
break;
|
|
}
|
|
if (sfxId != NA_SE_NONE) {
|
|
Audio_PlaySfx(sfxId, gPlayer[playerId].sfx.srcPos, playerId, &sPlayerNoise[playerId].totalMod, &gDefaultMod,
|
|
&sPlayerNoise[playerId].reverbAdd);
|
|
}
|
|
}
|
|
|
|
void Audio_StopPlayerNoise(u8 playerId) {
|
|
u32 sfxId = NA_SE_NONE;
|
|
|
|
switch (sPlayerNoise[playerId].form) {
|
|
case FORM_ARWING:
|
|
if (gPlayer[playerId].sfx.levelType == LEVELTYPE_SPACE) {
|
|
sfxId = NA_SE_ARWING_ENGIN_SPC;
|
|
} else {
|
|
sfxId = NA_SE_ARWING_ENGIN_GRD;
|
|
}
|
|
Audio_KillSfxBySourceAndId(gPlayer[playerId].sfx.srcPos, NA_SE_SPLASH_LEVEL_S);
|
|
break;
|
|
case FORM_LANDMASTER:
|
|
sfxId = NA_SE_TANK_ENGIN;
|
|
break;
|
|
case FORM_BLUE_MARINE:
|
|
sfxId = NA_SE_MARINE_ENGINE00;
|
|
Audio_KillSfxBySourceAndId(gPlayer[playerId].sfx.srcPos, NA_SE_SUBMARINE_ATM);
|
|
break;
|
|
}
|
|
sPlayerNoise[playerId].form = FORM_NONE;
|
|
if (sfxId != NA_SE_NONE) {
|
|
Audio_KillSfxBySourceAndId(gPlayer[playerId].sfx.srcPos, sfxId);
|
|
}
|
|
}
|
|
|
|
void Audio_InitBombSfx(u8 playerId, u8 type) {
|
|
sBombStartFrame[playerId] = sAudioFrameCounter;
|
|
switch (type) {
|
|
case 1:
|
|
sBombFreqMod[playerId] = 1.0f;
|
|
sBombType[playerId] = 1;
|
|
break;
|
|
case 2:
|
|
sBombFreqMod[playerId] = 1.5f;
|
|
sBombType[playerId] = 2;
|
|
break;
|
|
default:
|
|
case 0:
|
|
sBombFreqMod[playerId] = 0.75f;
|
|
sBombType[playerId] = 0;
|
|
break;
|
|
}
|
|
if (sBombState[playerId] != 1) {
|
|
Audio_PlaySfx(NA_SE_BOMB_CHARGE, gPlayer[playerId].sfx.srcPos, playerId, &sBombFreqMod[playerId], &gDefaultMod,
|
|
&sPlayerNoise[playerId].reverbAdd);
|
|
sBombState[playerId] = 1;
|
|
}
|
|
}
|
|
|
|
void Audio_PlayBombFlightSfx(u8 playerId, f32* sfxSource) {
|
|
if (sBombState[playerId] != 0) {
|
|
switch (sBombType[playerId]) {
|
|
case 1:
|
|
sBombFreqMod[playerId] = 1.2f;
|
|
break;
|
|
case 2:
|
|
sBombFreqMod[playerId] = 1.5f;
|
|
break;
|
|
default:
|
|
case 0:
|
|
sBombFreqMod[playerId] = 1.0f;
|
|
break;
|
|
}
|
|
Audio_KillSfxBySourceAndId(gPlayer[playerId].sfx.srcPos, NA_SE_BOMB_CHARGE);
|
|
Audio_PlaySfx(NA_SE_SMART_BOMB_SHOT, sfxSource, playerId, &sBombFreqMod[playerId], &gDefaultMod,
|
|
&sPlayerNoise[playerId].reverbAdd);
|
|
sBombState[playerId] = 2;
|
|
}
|
|
}
|
|
|
|
void Audio_PlayBombExplodeSfx(u8 playerId, f32* sfxSource) {
|
|
u32 sfxId;
|
|
|
|
if (sBombState[playerId] != 0) {
|
|
switch (sBombType[playerId]) {
|
|
case 1:
|
|
sfxId = NA_SE_BOMB_EXPLODE1;
|
|
break;
|
|
case 2:
|
|
sfxId = NA_SE_BOMB_EXPLODE2;
|
|
break;
|
|
default:
|
|
case 0:
|
|
sfxId = NA_SE_BOMB_EXPLODE0;
|
|
break;
|
|
}
|
|
Audio_KillSfxByTokenAndId(playerId, NA_SE_SMART_BOMB_SHOT);
|
|
AUDIO_PLAY_SFX(sfxId, sfxSource, playerId);
|
|
sBombState[playerId] = 0;
|
|
}
|
|
}
|
|
|
|
void Audio_StartEngineNoise(f32* sfxSource) {
|
|
u32 sfxId = (gPlayer[0].sfx.levelType == LEVELTYPE_SPACE) ? NA_SE_ARWING_ENGINE_FS : NA_SE_ARWING_ENGINE_FG;
|
|
|
|
AUDIO_PLAY_SFX(sfxId, sfxSource, 0);
|
|
}
|
|
|
|
void Audio_StopEngineNoise(f32* sfxSource) {
|
|
u32 sfxId = (gPlayer[0].sfx.levelType == LEVELTYPE_SPACE) ? NA_SE_ARWING_ENGINE_FS : NA_SE_ARWING_ENGINE_FG;
|
|
|
|
Audio_KillSfxBySourceAndId(sfxSource, sfxId);
|
|
}
|
|
|
|
void Audio_SetSfxSpeedModulation(f32 vel) {
|
|
f32 speed = ABS(vel);
|
|
|
|
if (speed < 6.0f) {
|
|
speed = 6.0f;
|
|
} else if (speed > 30.0f) {
|
|
speed = 30.0f;
|
|
}
|
|
|
|
sSfxFreqMod = ((speed - 18.0f) / 24.0f) + 1.0f;
|
|
}
|
|
|
|
void Audio_SetTransposeAndPlaySfx(f32* sfxSource, u32 sfxId, u8 semitones) {
|
|
f32 semitoneMods[] = {
|
|
1.0f, 1.059f, 1.122f, 1.189f, 1.26f, 1.335f, 1.414f, 1.498f, 1.587f, 1.682f, 1.782f, 1.888f, 2.0f,
|
|
};
|
|
|
|
if (semitones > 12) {
|
|
semitones = 12;
|
|
}
|
|
Audio_SetModulationAndPlaySfx(sfxSource, sfxId, semitoneMods[semitones]);
|
|
}
|
|
|
|
void Audio_SetModulationAndPlaySfx(f32* sfxSource, u32 sfxId, f32 freqMod) {
|
|
sSfxFreqMod = freqMod;
|
|
Audio_PlaySfx(sfxId, sfxSource, 0, &sSfxFreqMod, &gDefaultMod, &gDefaultReverb);
|
|
}
|
|
|
|
void Audio_PlaySfxModulated(f32* sfxSource, u32 sfxId) {
|
|
Audio_PlaySfx(sfxId, sfxSource, 0, &sSfxFreqMod, &sSfxVolMod, &gDefaultReverb);
|
|
}
|
|
|
|
void Audio_SetSfxMapModulation(u8 fMod) {
|
|
if (fMod < 12) {
|
|
sSfxFreqMod = (fMod / 11.0f) + 0.5f;
|
|
} else {
|
|
sSfxFreqMod = 1.5f;
|
|
}
|
|
}
|
|
|
|
void Audio_SetHeatAlarmParams(u8 shields, u8 heightParam) {
|
|
// height param is (s32) height / 100 - 1, clamped to [0, 5]
|
|
u8 alarmVolume;
|
|
u8 heightVolume;
|
|
|
|
// modifies tempo
|
|
AUDIOCMD_CHANNEL_SET_IO(SEQ_PLAYER_SFX, 9, 2, 8 + (shields >> 2));
|
|
AUDIOCMD_CHANNEL_SET_IO(SEQ_PLAYER_SFX, 10, 2, 8 + (shields >> 2));
|
|
AUDIOCMD_CHANNEL_SET_IO(SEQ_PLAYER_SFX, 11, 2, 8 + (shields >> 2));
|
|
|
|
// modifies frequency
|
|
AUDIOCMD_CHANNEL_SET_IO(SEQ_PLAYER_SFX, 9, 1, 19 - (heightParam * 3));
|
|
AUDIOCMD_CHANNEL_SET_IO(SEQ_PLAYER_SFX, 10, 1, 19 - (heightParam * 3));
|
|
AUDIOCMD_CHANNEL_SET_IO(SEQ_PLAYER_SFX, 11, 1, 19 - (heightParam * 3));
|
|
|
|
alarmVolume = 68 - (shields >> 3);
|
|
heightVolume = 80 - (heightParam * 10);
|
|
if (heightVolume > alarmVolume) {
|
|
alarmVolume = heightVolume;
|
|
}
|
|
AUDIOCMD_CHANNEL_SET_IO(SEQ_PLAYER_SFX, 9, 3, alarmVolume);
|
|
AUDIOCMD_CHANNEL_SET_IO(SEQ_PLAYER_SFX, 10, 3, alarmVolume);
|
|
AUDIOCMD_CHANNEL_SET_IO(SEQ_PLAYER_SFX, 11, 3, alarmVolume);
|
|
}
|
|
|
|
void Audio_PlayEventSfx(f32* sfxSource, u16 eventSfxId) {
|
|
if ((sEventSfx[eventSfxId] & SFX_BANK_MASK) != (SFX_BANK_SYSTEM << SFX_BANK_SHIFT)) {
|
|
AUDIO_PLAY_SFX(sEventSfx[eventSfxId], sfxSource, 0);
|
|
} else {
|
|
AUDIO_PLAY_SFX(sEventSfx[eventSfxId], gDefaultSfxSource, 0);
|
|
}
|
|
}
|
|
|
|
void Audio_StopEventSfx(f32* sfxSource, u16 eventSfxId) {
|
|
if ((sEventSfx[eventSfxId] & SFX_BANK_MASK) != (SFX_BANK_SYSTEM << SFX_BANK_SHIFT)) {
|
|
Audio_KillSfxBySourceAndId(sfxSource, sEventSfx[eventSfxId]);
|
|
} else {
|
|
Audio_KillSfxBySourceAndId(gDefaultSfxSource, sEventSfx[eventSfxId]);
|
|
}
|
|
}
|
|
|
|
void Audio_SetEnvSfxReverb(s8 reverb) {
|
|
sEnvReverb = reverb;
|
|
}
|
|
|
|
void Audio_SetBgmParam(s8 bgmParam) {
|
|
SEQCMD_SET_SEQPLAYER_IO(SEQ_PLAYER_BGM, 0, bgmParam);
|
|
}
|
|
|
|
void Audio_PlaySequence(u8 seqPlayId, u16 seqId, u8 fadeinTime, u8 bgmParam) {
|
|
SEQCMD_SET_SEQPLAYER_IO(seqPlayId, 0, bgmParam);
|
|
SEQCMD_PLAY_SEQUENCE(seqPlayId, fadeinTime, 0, seqId);
|
|
}
|
|
|
|
void Audio_PlayFanfare(u16 seqId, u8 bgmVolume, u8 bgmFadeoutTime, u8 bgmFadeinTime) {
|
|
if (Audio_GetActiveSeqId(SEQ_PLAYER_BGM) != NA_BGM_PLAYER_DOWN) {
|
|
Audio_SetSequenceFade(SEQ_PLAYER_BGM, 1, bgmVolume, bgmFadeoutTime);
|
|
SEQCMD_SETUP_RESTORE_SEQPLAYER_VOLUME(SEQ_PLAYER_FANFARE, SEQ_PLAYER_BGM, bgmFadeinTime);
|
|
SEQCMD_PLAY_SEQUENCE(SEQ_PLAYER_FANFARE, 0, 0, seqId);
|
|
}
|
|
}
|
|
|
|
void Audio_PlayDeathSequence(void) {
|
|
u8 i;
|
|
|
|
if (sAudioSpecId == AUDIOSPEC_24) {
|
|
Audio_ClearVoice();
|
|
Audio_PlayMapMenuSfx(0);
|
|
AUDIO_PLAY_SFX(NA_SE_ARWING_EXPLOSION, gDefaultSfxSource, 4);
|
|
SEQCMD_SET_SEQPLAYER_VOLUME(SEQ_PLAYER_BGM, 5, 30);
|
|
SEQCMD_SETUP_RESTORE_SEQPLAYER_VOLUME(SEQ_PLAYER_FANFARE, SEQ_PLAYER_BGM, 30);
|
|
SEQCMD_PLAY_SEQUENCE(SEQ_PLAYER_FANFARE, 0, 0, NA_BGM_PLAYER_DOWN);
|
|
} else {
|
|
for (i = 0; i < 5; i++) {
|
|
Audio_KillSfxByBank(i);
|
|
}
|
|
AUDIOCMD_GLOBAL_UNMUTE(true);
|
|
AUDIO_PLAY_SFX(NA_SE_ARWING_EXPLOSION, gDefaultSfxSource, 4);
|
|
SEQCMD_STOP_SEQUENCE(SEQ_PLAYER_BGM, 0);
|
|
SEQCMD_STOP_SEQUENCE(SEQ_PLAYER_FANFARE, 0);
|
|
SEQCMD_PLAY_SEQUENCE(SEQ_PLAYER_BGM, 0, 0, NA_BGM_PLAYER_DOWN);
|
|
}
|
|
}
|
|
|
|
void Audio_PlayPauseSfx(u8 active) {
|
|
if (active) {
|
|
AUDIO_PLAY_SFX(NA_SE_PAUSE_ON, gDefaultSfxSource, 4);
|
|
AUDIOCMD_GLOBAL_MUTE();
|
|
} else {
|
|
AUDIO_PLAY_SFX(NA_SE_PAUSE_ON, gDefaultSfxSource, 4);
|
|
AUDIOCMD_GLOBAL_UNMUTE(false);
|
|
}
|
|
}
|
|
|
|
void Audio_PlayMapMenuSfx(u8 active) {
|
|
if (active) {
|
|
AUDIO_PLAY_SFX(NA_SE_MAP_WINDOW_OPEN, gDefaultSfxSource, 4);
|
|
AUDIOCMD_GLOBAL_MUTE();
|
|
} else {
|
|
AUDIO_PLAY_SFX(NA_SE_MAP_WINDOW_CLOSE, gDefaultSfxSource, 4);
|
|
AUDIOCMD_GLOBAL_UNMUTE(false);
|
|
}
|
|
}
|
|
|
|
void Audio_RestoreVolumeSettings(u8 audioType) {
|
|
s8 volume = ((sVolumeSettings[audioType] * 127) / 99) % 128U;
|
|
u8 i;
|
|
|
|
switch (audioType) {
|
|
case AUDIO_TYPE_MUSIC:
|
|
Audio_SetSequenceFade(SEQ_PLAYER_BGM, 0, volume, 1);
|
|
Audio_SetSequenceFade(SEQ_PLAYER_FANFARE, 0, volume, 1);
|
|
break;
|
|
case AUDIO_TYPE_SFX:
|
|
for (i = 0; i < 15; i++) {
|
|
AUDIOCMD_CHANNEL_SET_VOL(SEQ_PLAYER_SFX, (u32) i, volume / 127.0f);
|
|
}
|
|
break;
|
|
case AUDIO_TYPE_VOICE:
|
|
AUDIOCMD_CHANNEL_SET_VOL(SEQ_PLAYER_VOICE, 15, volume / 127.0f);
|
|
break;
|
|
}
|
|
}
|
|
|
|
void Audio_SetVolume(u8 audioType, u8 volume) {
|
|
if (volume > 99) {
|
|
volume = 99;
|
|
}
|
|
sVolumeSettings[audioType] = volume;
|
|
Audio_RestoreVolumeSettings(audioType);
|
|
}
|
|
|
|
void Audio_PlaySoundTest(u8 enable) {
|
|
switch (enable) {
|
|
case false:
|
|
AUDIO_PLAY_BGM(NA_BGM_SELECT);
|
|
Audio_PlayVoice(1);
|
|
Audio_KillSfxById(NA_SE_VOLUME_TEST);
|
|
Audio_KillSfxById(NA_SE_ARWING_ENGIN_GRD);
|
|
break;
|
|
case true:
|
|
AUDIO_PLAY_BGM(NA_BGM_VOLUME_TEST);
|
|
Audio_PlayVoice(2);
|
|
AUDIO_PLAY_SFX(NA_SE_VOLUME_TEST, gDefaultSfxSource, 0);
|
|
AUDIO_PLAY_SFX(NA_SE_ARWING_ENGIN_GRD, gDefaultSfxSource, 0);
|
|
break;
|
|
}
|
|
}
|
|
|
|
void Audio_PlaySequenceDistorted(u8 seqPlayId, u16 seqId, u16 distortion, u8 fadeinTime, u8 unused) {
|
|
u8 tempoDistortion = (distortion / 10);
|
|
|
|
Audio_PlaySequence(seqPlayId, seqId & ~SEQ_FLAG, 0, -1);
|
|
SEQCMD_SET_SEQPLAYER_FREQ(seqPlayId, fadeinTime, distortion);
|
|
SEQCMD_SCALE_TEMPO(seqPlayId, fadeinTime, tempoDistortion);
|
|
}
|
|
|
|
void Audio_PlaySoundTestTrack(u8 trackNumber) {
|
|
u16 sp26;
|
|
u8 sp25;
|
|
|
|
if ((trackNumber >= 45) && (trackNumber < 50)) {
|
|
SEQCMD_STOP_SEQUENCE(SEQ_PLAYER_BGM, 1);
|
|
SEQCMD_STOP_SEQUENCE(SEQ_PLAYER_FANFARE, 1);
|
|
sPlaylistIndex = trackNumber - 45;
|
|
sPlaylistCmdIndex = 0;
|
|
sPlaylistTimer = 0;
|
|
} else if (trackNumber >= 50) {
|
|
AUDIO_PLAY_SFX(NA_SE_ERROR, gDefaultSfxSource, 4);
|
|
} else {
|
|
sPlaylistIndex = 0xFF;
|
|
sp26 = sSoundTestTracks[trackNumber].seqId & 0xFF;
|
|
sp25 = sSoundTestTracks[trackNumber].bgmParam;
|
|
SEQCMD_STOP_SEQUENCE(D_800C5E70 ^ 1, 5);
|
|
Audio_PlaySequence(D_800C5E70, sp26, 0, sp25);
|
|
D_800C5E70 ^= 1;
|
|
}
|
|
}
|
|
|
|
void Audio_FadeOutAll(u8 fadeoutTime) {
|
|
SEQCMD_SET_SEQPLAYER_VOLUME(SEQ_PLAYER_BGM, fadeoutTime, 0);
|
|
SEQCMD_SET_SEQPLAYER_VOLUME(SEQ_PLAYER_FANFARE, fadeoutTime, 0);
|
|
SEQCMD_SET_SEQPLAYER_VOLUME(SEQ_PLAYER_SFX, fadeoutTime, 0);
|
|
SEQCMD_SET_SEQPLAYER_VOLUME(SEQ_PLAYER_VOICE, fadeoutTime, 0);
|
|
}
|
|
|
|
void Audio_KillAllSfx(void) {
|
|
u8 i;
|
|
|
|
for (i = 0; i < 5; i++) {
|
|
Audio_KillSfxByBank(i);
|
|
}
|
|
}
|
|
|
|
void Audio_SetAudioSpec(u8 unused, u16 specParam) {
|
|
u8 sfxChannelLayout = ((specParam & 0xFF00) >> 8);
|
|
u8 specId = specParam & 0xFF;
|
|
|
|
SEQCMD_RESET_AUDIO_HEAP(sfxChannelLayout, specId);
|
|
}
|
|
|
|
// unused
|
|
void Audio_PlayBgm(u16 seqId) {
|
|
SEQCMD_PLAY_SEQUENCE(SEQ_PLAYER_BGM, 1, 0, seqId);
|
|
}
|
|
|
|
void Audio_InitSounds(void) {
|
|
Audio_ResetVoicesAndPlayers();
|
|
Audio_ResetSfxChannelState();
|
|
Audio_ResetActiveSequencesAndVolume();
|
|
Audio_ResetSfx();
|
|
Audio_StartSequence(SEQ_PLAYER_VOICE, NA_BGM_VO, -1, 1);
|
|
Audio_StartSequence(SEQ_PLAYER_SFX, NA_BGM_SE, -1, 10);
|
|
}
|
|
|
|
void Audio_RestartSeqPlayers(void) {
|
|
s32 pad1;
|
|
s32 pad2;
|
|
u16 fadeIn = 1;
|
|
|
|
Audio_StartSequence(SEQ_PLAYER_VOICE, NA_BGM_VO, -1, 1);
|
|
if (sAudioSpecId == AUDIOSPEC_12) {
|
|
fadeIn = 360;
|
|
} else if (sAudioSpecId < AUDIOSPEC_23) {
|
|
fadeIn = 90;
|
|
}
|
|
Audio_StartSequence(SEQ_PLAYER_SFX, NA_BGM_SE, -1, fadeIn);
|
|
Audio_LoadInstruments();
|
|
Audio_LoadAquasSequence();
|
|
SEQCMD_SET_SEQPLAYER_VOLUME(SEQ_PLAYER_SFX, 0, 127);
|
|
SEQCMD_SET_SEQPLAYER_VOLUME(SEQ_PLAYER_VOICE, 0, 127);
|
|
AudioThread_ScheduleProcessCmds();
|
|
AUDIOCMD_GLOBAL_STOP_AUDIOCMDS();
|
|
AUDIOCMD_GLOBAL_STOP_AUDIOCMDS();
|
|
AUDIOCMD_GLOBAL_STOP_AUDIOCMDS();
|
|
Audio_RestoreVolumeSettings(AUDIO_TYPE_MUSIC);
|
|
Audio_RestoreVolumeSettings(AUDIO_TYPE_SFX);
|
|
Audio_RestoreVolumeSettings(AUDIO_TYPE_VOICE);
|
|
}
|
|
|
|
void Audio_StartReset(u8 oldSpecId) {
|
|
if (oldSpecId == AUDIOSPEC_16) {
|
|
if ((sAudioSpecId == AUDIOSPEC_22) || (sAudioSpecId == AUDIOSPEC_23)) {
|
|
sAudioResetStatus = AUDIORESET_BLOCK;
|
|
}
|
|
} else if ((oldSpecId == AUDIOSPEC_28) && (sAudioSpecId == AUDIOSPEC_23)) {
|
|
sAudioResetStatus = AUDIORESET_BLOCK;
|
|
} else {
|
|
sAudioResetStatus = AUDIORESET_WAIT;
|
|
}
|
|
AUDIOCMD_GLOBAL_UNMUTE(true);
|
|
Audio_ResetVoicesAndPlayers();
|
|
Audio_ResetSfxChannelState();
|
|
Audio_ResetActiveSequences();
|
|
Audio_ResetSfx();
|
|
}
|
|
|
|
void Audio_Update(void) {
|
|
if (Audio_HandleReset() == AUDIORESET_READY) {
|
|
Audio_ProcessSfxRequests();
|
|
Audio_ProcessSeqCmds();
|
|
Audio_PlayAllSfx();
|
|
Audio_UpdatePlayerNoise();
|
|
Audio_UpdateVoice();
|
|
Audio_UpdateUnkVoiceParam();
|
|
Audio_UpdateActiveSequences();
|
|
Audio_UpdateDelayedSeqCmds();
|
|
AudioThread_ScheduleProcessCmds();
|
|
}
|
|
sAudioFrameCounter++;
|
|
}
|